Repository: jijunair/laravel-referral Branch: main Commit: 3fab42b5fe5b Files: 18 Total size: 29.7 KB Directory structure: gitextract_ks4k398i/ ├── .github/ │ └── ISSUE_TEMPLATE/ │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── composer.json ├── config/ │ └── referral.php ├── database/ │ └── migrations/ │ └── 2023_05_28_135232_create_referrals_table.php ├── routes/ │ └── web.php ├── src/ │ ├── Controllers/ │ │ └── ReferralController.php │ ├── Models/ │ │ └── Referral.php │ ├── Providers/ │ │ └── ReferralServiceProvider.php │ └── Traits/ │ └── Referrable.php └── tests/ └── ReferralControllerTest.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- **Before creating a new bug report** Please check if there isn't a similar issue on [the issue tracker](https://github.com/jijunair/laravel-referral/issues) or in [the discussions](https://github.com/jijunair/laravel-referral/discussions). **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior. **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .gitignore ================================================ /vendor/ node_modules/ npm-debug.log yarn-error.log # Laravel 4 specific bootstrap/compiled.php app/storage/ # Laravel 5 & Lumen specific public/storage public/hot # Laravel 5 & Lumen specific with changed public path public_html/storage public_html/hot storage/*.key .env Homestead.yaml Homestead.json /.vagrant .phpunit.result.cache ================================================ FILE: CHANGELOG.md ================================================ # Changelog All notable changes to the "jijunair/laravel-referral" package will be documented in this file. ## [1.0.0] - 2023-07-14 ### Added - Initial release of the "jijunair/laravel-referral" package. [1.0.0]: https://github.com/jijunair/laravel-referral/releases/tag/v1.0.0 ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at . All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to Laravel Referral Package Thank you for your interest in contributing to the Laravel Referral Package! We welcome your contributions and appreciate your efforts to improve the project. Please follow these guidelines when contributing: - Report any issues or bugs on the [GitHub issue tracker](https://github.com/jijunair/laravel-referral/issues). - Submit bug fixes or new features by forking the repository, making changes, and opening a pull request against the `main` branch. - Follow the project's coding standards, including the PSR-12 coding style. - Be open to feedback and respond to any questions or suggestions from the maintainers. We value your contributions and appreciate your help in making the Laravel Referral Package even better! ## License By contributing to the Laravel Referral Package, you agree that your contributions will be licensed under the project's [MIT](LICENSE) license. Thank you for your contributions! ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2023 Jiju Nair Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

Heading of Laravel Referral

Latest Version on Packagist Total Downloads License

The **Laravel Referral** package (`jijunair/laravel-referral`) is a powerful and easy-to-use package for adding referral system functionality to your Laravel applications. With this package, you can effortlessly generate referral codes, track user referrals, and reward users based on their referrals. ## Key Features ✅ Generate unique referral codes for users ✅ Track referrals and associate them with users ✅ Retrieve referrers and their referred users ✅ Customizable referral code length, cookie tracking, and redirection ✅ Simple trait-based integration with your `User` model - [Installation](#installation) - [Configuration](#configuration) - [Migration](#migration) - [Add Trait](#add-trait) - [Usage](#usage) - [Generate Referral Accounts for Existing Users](#generate-referral-accounts-for-existing-users) - [Get the Referrer of a User](#get-the-referrer-of-a-user) - [Get Referrer by Referral Code](#get-referrer-by-referral-code) - [Check if a User has a Referral Account](#check-if-a-user-has-a-referral-account) - [Create a Referral Account for a User](#create-a-referral-account-for-a-user) - [Get All Referrals of a User](#get-all-referrals-of-a-user) - [Get the Referral Link of a User](#get-the-referral-link-of-a-user) - [Changelog](#changelog) - [Contribution](#contributing) - [License](#license) ## Installation You can install the package via Composer by running the following command: ```bash composer require jijunair/laravel-referral ``` #### Configuration The package provides a configuration file that allows you to customize its behavior. You should publish the migration and the config/referral.php config file with: ```php php artisan vendor:publish --provider="Jijunair\LaravelReferral\Providers\ReferralServiceProvider" ``` After publishing, you can find the configuration file at config/referral.php. | Configuration Key | Description | |---------------------|---------------------------------------------------------------------------------------------------------------| | `cookie_name` | The name of the cookie that tracks referrals. | | `cookie_expiry` | How long the referral cookie will be valid. (Default: 1 year) | | `route_prefix` | The prefix used for referral links. | | `ref_code_prefix` | The prefix added to the unique referral code for each user. | | `redirect_route` | The page where users will go after clicking on a referral link. | | `user_model` | The model class for the user. | | `referral_length` | The length of the referral code for each user. (Default: 8 characters) | These configuration options help customize the behavior of the referral system in your Laravel application. Feel free to adjust these values according to your preferences and requirements! #### Migration After the config and migration have been published and configured, you can create the tables for this package by running: ```php php artisan migrate ``` #### Add Trait Add the necessary trait to your User model: ```php use Jijunair\LaravelReferral\Traits\Referrable; class User extends Model { use Referrable; } ``` ## Usage #### Generate Referral Accounts for Existing Users To generate referral accounts for existing users, you can visit the following URL: ```plaintext http://localhost:8000/generate-ref-accounts ``` This will generate referral codes for all existing users in your application.

#### Get the Referrer of a User To get the referrer of a user, you can use the following code: ```php use Illuminate\Support\Facades\Auth; $user = Auth::user(); $referrer = $user->referralAccount->referrer; ``` This retrieves the referrer associated with the user.

#### Get Referrer by Referral Code To get the referrer by referral code, you can use the following code: ```php use Jijunair\LaravelReferral\Models\Referral; use Illuminate\Support\Facades\Cookie; $referralCode = Cookie::get(config('referral.cookie_name')); $referrer = Referral::userByReferralCode($referralCode); ``` This retrieves the referrer based on the referral code stored in the cookie.

#### Check if a User has a Referral Account To check if a user has a referral account, you can use the following code: ```php $user->hasReferralAccount(); ``` This returns `true` if the user has a referral account, and `false` otherwise.

#### Create a Referral Account for a User To create a referral account for a user, you can use the following code: ```php $user->createReferralAccount($referrer->id); ``` This associates the user with the provided referrer by creating a referral account.

#### Get All Referrals of a User To get all referrals under a user, you can use the following code: ```php $referrals = $user->referrals; ``` This retrieves all the referrals associated with the user.

#### Get the Referral Link of a User To get the referral link of a user, you can use the following code: ```php $referralLink = $user->getReferralLink(); ``` This returns the referral link associated with the user. ## Changelog Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. ## Contributing Thank you for considering contributing to the Laravel Referral Package! If you have any suggestions, bug reports, or pull requests, please feel free to open an issue or submit a pull request on the GitHub repository. ## License The Laravel Referral Package is open-source software licensed under the [MIT](LICENSE) license. ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Supported Versions Please refer to the following table to see the currently supported versions of the Laravel Referral Package with security updates: | Version | Supported | | ------- | ------------------ | | 1.0.x | :white_check_mark: | Note: It is highly recommended to use the latest stable version whenever possible. ## Reporting a Vulnerability To report a security vulnerability, please follow these steps: 1. Go to the [GitHub Issues](https://github.com/jijunair/laravel-referral/issues) page of the this repository. 2. Click on the "New Issue" button. 3. Provide a clear and descriptive title for the vulnerability report. 4. In the issue description, include detailed information about the vulnerability, including steps to reproduce and potential impact. 5. If possible, include any relevant code snippets or examples. 6. Submit the issue. We will review your vulnerability report as soon as possible and provide updates on its progress. We appreciate your responsible disclosure of security vulnerabilities and your contribution to the security of this package. Thank you for helping us maintain a secure package! ================================================ FILE: composer.json ================================================ { "name": "jijunair/laravel-referral", "description": "Laravel package for a referral system", "keywords": [ "jijunair", "laravel", "referral", "affiliate", "package", "laravel-referral", "referral-system", "user-referral" ], "homepage": "https://github.com/jijunair/laravel-referral", "type": "library", "license": "MIT", "authors": [ { "name": "Jiju Nair", "email": "hello@jijunair.com" } ], "require": { "php": "^7.2|^7.3|^7.4|^8.0|^8.1|^8.2", "illuminate/database": "^8.0|^9.0|^10.0|^11.0|^12.0", "illuminate/auth": "^8.0|^9.0|^10.0|^11.0|^12.0" }, "require-dev": { "phpunit/phpunit": "^9.4|^10.0|^11.0|^12.0" }, "minimum-stability": "dev", "prefer-stable": true, "autoload": { "psr-4": { "Jijunair\\LaravelReferral\\": "src" } }, "autoload-dev": { "psr-4": { "Jijunair\\LaravelReferral\\Tests\\": "tests" } }, "extra": { "laravel": { "providers": [ "Jijunair\\LaravelReferral\\Providers\\ReferralServiceProvider" ] } } } ================================================ FILE: config/referral.php ================================================ 'mysite_ref', // Expiry time for the referral cookie in minutes 'cookie_expiry' => 525600, // 1 year // The prefix used for referral links 'route_prefix' => 'save20', // The prefix used for referral code 'ref_code_prefix' => 'ref_', // The route where users will be redirected after clicking on a referral link 'redirect_route' => 'orders.create', // The model class for the user 'user_model' => 'App\Models\User', // The length of the referral code generated for each user 'referral_length' => 8, ]; ================================================ FILE: database/migrations/2023_05_28_135232_create_referrals_table.php ================================================ id(); $table->unsignedBigInteger('user_id'); $table->string('referral_code')->unique(); $table->unsignedBigInteger('referrer_id')->nullable(); $table->timestamps(); $table->foreign('referrer_id')->references('id')->on('users')->onDelete('set null'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->index('referral_code'); $table->index('user_id'); $table->index('referrer_id'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('referrals'); } } ================================================ FILE: routes/web.php ================================================ group(function () { Route::get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer']) ->name('referralLink'); Route::get('generate-ref-accounts', [ReferralController::class, 'createReferralCodeForExistingUsers']) ->name('generateReferralCodes'); }); ================================================ FILE: src/Controllers/ReferralController.php ================================================ route(config('referral.redirect_route')); } else { // Create a referral code cookie and redirect to configured route $ck = Cookie::make($refCookieName, $referralCode, $refCookieExpiry); return redirect()->route(config('referral.redirect_route'))->withCookie($ck); } } /** * Generate referral codes for existing users. * * @return JsonResponse */ public function createReferralCodeForExistingUsers() { $userModel = resolve(config('referral.user_model')); $users = $userModel::cursor(); foreach ($users as $user) { if (!$user->hasReferralAccount()) { $user->createReferralAccount(); } } return response()->json(['message' => 'Referral codes generated for existing users.']); } } ================================================ FILE: src/Models/Referral.php ================================================ belongsTo(config('referral.user_model'), 'user_id'); } /** * Get the referrer associated with the referral. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function referrer() { return $this->belongsTo(config('referral.user_model'), 'referrer_id'); } /** * Retrieve the user by referral code. * * @param string $code * @return mixed|null */ public static function userByReferralCode($code) { $referrer = self::where('referral_code',$code)->first(); if ($referrer) { return App::make(config('referral.user_model'))->find($referrer->user_id); } return null; } } ================================================ FILE: src/Providers/ReferralServiceProvider.php ================================================ mergeConfigFrom(__DIR__.'/../../config/referral.php', 'referral'); } /** * Bootstrap package services. * * @return void */ public function boot() { // Load package migrations $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); if ($this->app->runningInConsole()) { // Publish package's configuration file $this->publishes([ __DIR__.'/../../config/referral.php' => config_path('referral.php'), ], 'laravel-referral-config'); // Publish package's migration files $this->publishes([ __DIR__.'/../../database/migrations' => database_path('migrations'), ], 'laravel-referral-migrations'); } // Load package's routes $this->loadRoutesFrom(__DIR__.'/../../routes/web.php'); // Bind the ReferralController to the application container $this->app->bind('Jijunair\LaravelReferral\Controllers\ReferralController', function ($app) { return new \Jijunair\LaravelReferral\Controllers\ReferralController(); }); } } ================================================ FILE: src/Traits/Referrable.php ================================================ hasMany(Referral::class, 'referrer_id'); } /** * Get the referral account of the user. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function referralAccount() { return $this->belongsTo(Referral::class, 'id', 'user_id'); } /** * Check if the user has a referral account. * * @return bool */ public function hasReferralAccount() { return !is_null($this->referralAccount); } /** * Get the referral link for the user. * * @return string */ public function getReferralLink() { if ($this->hasReferralAccount()) { return url('/') . "/" . config('referral.route_prefix') . "/" . $this->getReferralCode(); } return ""; } /** * Get the referral code of the user's referral account. * * @return string|null */ public function getReferralCode() { if ($this->hasReferralAccount()) { return $this->referralAccount->referral_code; } return null; } /** * Create a referral account for the user. * * @param int|null $referrerID * @return void */ public function createReferralAccount(int $referrerID = NULL) { $prefix = config('referral.ref_code_prefix'); $length = config('referral.referral_length'); $referralCode = $this->generateUniqueReferralCode($prefix, $length); $ref = new Referral; $ref->user_id = $this->getKey(); $ref->referrer_id = $referrerID; $ref->referral_code = $referralCode; $ref->save(); } /** * Generate a unique referral code. * * @param string $prefix * @param int $length * @return string */ private function generateUniqueReferralCode($prefix, $length) { $prefix = strtolower($prefix); // Generate an initial referral code $code = $prefix . strtolower(Str::random($length)); // Check if the generated code already exists in the database while (Referral::where('referral_code', $code)->exists()) { // If code already exists, generate a new one until a unique code is found $code = $prefix . strtolower(Str::random($length)); } return $code; } } ================================================ FILE: tests/ReferralControllerTest.php ================================================ get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer']) ->name('referralLink'); // Call the route with the referral code $response = $this->get(route('referralLink', ['referralCode' => $referralCode])); // Assert that the response redirects to the configured route $response->assertRedirect(config('referral.redirect_route')); } public function testAssignReferrerWithoutExistingCookie() { // Create a dummy referral code $referralCode = 'ABC123'; // Define the route for assigning a referrer Route::middleware('web')->get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer']) ->name('referralLink'); // Call the route with the referral code $response = $this->get(route('referralLink', ['referralCode' => $referralCode])); // Assert that the response redirects to the configured route $response->assertRedirect(config('referral.redirect_route')); // Assert that the referral code cookie has been set $this->assertTrue(Cookie::has(config('referral.cookie_name'))); } public function testCreateReferralCodeForExistingUsers() { // Create some dummy users $users = factory(config('referral.user_model'), 5)->create(); // Define the route for generating referral codes for existing users Route::middleware('web')->get('generate-ref-accounts', [ReferralController::class, 'createReferralCodeForExistingUsers']) ->name('generateReferralCodes'); // Call the route to generate referral codes for existing users $response = $this->get(route('generateReferralCodes')); // Assert that the response is a JSON response $response->assertJson(['message' => 'Referral codes generated for existing users.']); // Assert that referral codes have been created for all existing users foreach ($users as $user) { $this->assertTrue($user->hasReferralAccount()); $this->assertNotNull($user->getReferralCode()); } } }