[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Before creating a new bug report**\nPlease 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).\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior.\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".gitignore",
    "content": "/vendor/\nnode_modules/\nnpm-debug.log\nyarn-error.log\n\n# Laravel 4 specific\nbootstrap/compiled.php\napp/storage/\n\n# Laravel 5 & Lumen specific\npublic/storage\npublic/hot\n\n# Laravel 5 & Lumen specific with changed public path\npublic_html/storage\npublic_html/hot\n\nstorage/*.key\n.env\nHomestead.yaml\nHomestead.json\n/.vagrant\n.phpunit.result.cache\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to the \"jijunair/laravel-referral\" package will be documented in this file.\n\n## [1.0.0] - 2023-07-14\n\n### Added\n- Initial release of the \"jijunair/laravel-referral\" package.\n\n[1.0.0]: https://github.com/jijunair/laravel-referral/releases/tag/v1.0.0\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\n.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Laravel Referral Package\n\nThank 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:\n\n- Report any issues or bugs on the [GitHub issue tracker](https://github.com/jijunair/laravel-referral/issues).\n- Submit bug fixes or new features by forking the repository, making changes, and opening a pull request against the `main` branch.\n- Follow the project's coding standards, including the PSR-12 coding style.\n- Be open to feedback and respond to any questions or suggestions from the maintainers.\n\nWe value your contributions and appreciate your help in making the Laravel Referral Package even better!\n\n## License\n\nBy contributing to the Laravel Referral Package, you agree that your contributions will be licensed under the project's [MIT](LICENSE) license.\n\nThank you for your contributions!\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 Jiju Nair\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "\n<p align=\"center\">\n    <img src=\"/images/header.jpeg\" width=\"600\" alt=\"Heading of Laravel Referral\">\n    <p align=\"center\">\n        <a href=\"https://packagist.org/packages/jijunair/laravel-referral\"><img alt=\"Latest Version on Packagist\" src=\"https://img.shields.io/packagist/v/jijunair/laravel-referral.svg?style=flat-square\"></a>\n        <a href=\"https://packagist.org/packages/jijunair/laravel-referral\"><img alt=\"Total Downloads\" src=\"https://img.shields.io/packagist/dt/jijunair/laravel-referral\"></a>\n        <a href=\"https://packagist.org/packages/jijunair/laravel-referral\"><img alt=\"License\" src=\"https://img.shields.io/github/license/jijunair/laravel-referral\"></a>\n    </p>\n</p>\n\n\nThe **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.  \n\n## Key Features  \n✅ Generate unique referral codes for users  \n✅ Track referrals and associate them with users  \n✅ Retrieve referrers and their referred users  \n✅ Customizable referral code length, cookie tracking, and redirection  \n✅ Simple trait-based integration with your `User` model\n\n\n- [Installation](#installation)\n    - [Configuration](#configuration)\n    - [Migration](#migration)\n    - [Add Trait](#add-trait)\n- [Usage](#usage)\n    - [Generate Referral Accounts for Existing Users](#generate-referral-accounts-for-existing-users)\n    - [Get the Referrer of a User](#get-the-referrer-of-a-user)\n    - [Get Referrer by Referral Code](#get-referrer-by-referral-code)\n    - [Check if a User has a Referral Account](#check-if-a-user-has-a-referral-account)\n    - [Create a Referral Account for a User](#create-a-referral-account-for-a-user)\n    - [Get All Referrals of a User](#get-all-referrals-of-a-user)\n    - [Get the Referral Link of a User](#get-the-referral-link-of-a-user)\n- [Changelog](#changelog)\n- [Contribution](#contributing)\n- [License](#license)\n\n## Installation\n\nYou can install the package via Composer by running the following command:\n\n```bash\ncomposer require jijunair/laravel-referral\n```\n\n#### Configuration\nThe 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:\n```php\nphp artisan vendor:publish --provider=\"Jijunair\\LaravelReferral\\Providers\\ReferralServiceProvider\"\n```\nAfter publishing, you can find the configuration file at config/referral.php.\n\n| Configuration Key   | Description                                                                                                   |\n|---------------------|---------------------------------------------------------------------------------------------------------------|\n| `cookie_name`       | The name of the cookie that tracks referrals.                                                          |\n| `cookie_expiry`     | How long the referral cookie will be valid. (Default: 1 year)                            |\n| `route_prefix`      | The prefix used for referral links.                                                     |\n| `ref_code_prefix`   | The prefix added to the unique referral code for each user.                                         |\n| `redirect_route`    | The page where users will go after clicking on a referral link.                                              |\n| `user_model`        | The model class for the user.                                                                 |\n| `referral_length`   | The length of the referral code for each user. (Default: 8 characters)                                |\n\nThese 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!\n\n\n#### Migration\nAfter the config and migration have been published and configured, you can create the tables for this package by running:\n```php\n php artisan migrate\n```\n\n#### Add Trait\nAdd the necessary trait to your User model:\n```php\nuse Jijunair\\LaravelReferral\\Traits\\Referrable;\n\nclass User extends Model\n{\n    use Referrable;\n}\n```\n\n## Usage\n\n#### Generate Referral Accounts for Existing Users\nTo generate referral accounts for existing users, you can visit the following URL:\n```plaintext\nhttp://localhost:8000/generate-ref-accounts\n```\nThis will generate referral codes for all existing users in your application.<br><br>\n\n#### Get the Referrer of a User\nTo get the referrer of a user, you can use the following code:\n```php\nuse Illuminate\\Support\\Facades\\Auth;\n\n$user = Auth::user();\n$referrer = $user->referralAccount->referrer;\n```\nThis retrieves the referrer associated with the user.<br><br>\n\n#### Get Referrer by Referral Code\nTo get the referrer by referral code, you can use the following code:\n```php\nuse Jijunair\\LaravelReferral\\Models\\Referral;\nuse Illuminate\\Support\\Facades\\Cookie;\n\n$referralCode = Cookie::get(config('referral.cookie_name'));\n$referrer = Referral::userByReferralCode($referralCode);\n\n```\nThis retrieves the referrer based on the referral code stored in the cookie.<br><br>\n\n#### Check if a User has a Referral Account\nTo check if a user has a referral account, you can use the following code:\n```php\n$user->hasReferralAccount();\n```\nThis returns `true` if the user has a referral account, and `false` otherwise.<br><br>\n\n#### Create a Referral Account for a User\nTo create a referral account for a user, you can use the following code:\n```php\n$user->createReferralAccount($referrer->id);\n```\nThis associates the user with the provided referrer by creating a referral account.<br><br>\n\n#### Get All Referrals of a User\nTo get all referrals under a user, you can use the following code:\n```php\n$referrals = $user->referrals;\n```\nThis retrieves all the referrals associated with the user.<br><br>\n\n#### Get the Referral Link of a User\nTo get the referral link of a user, you can use the following code:\n```php\n$referralLink = $user->getReferralLink();\n```\nThis returns the referral link associated with the user.\n\n## Changelog\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\nThank 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.\n\n## License\nThe Laravel Referral Package is open-source software licensed under the [MIT](LICENSE) license.\n\n\n\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nPlease refer to the following table to see the currently supported versions of the Laravel Referral Package with security updates:\n\n| Version | Supported          |\n| ------- | ------------------ |\n| 1.0.x   | :white_check_mark: |\n\nNote: It is highly recommended to use the latest stable version whenever possible.\n\n## Reporting a Vulnerability\n\nTo report a security vulnerability, please follow these steps:\n\n1. Go to the [GitHub Issues](https://github.com/jijunair/laravel-referral/issues) page of the this repository.\n2. Click on the \"New Issue\" button.\n3. Provide a clear and descriptive title for the vulnerability report.\n4. In the issue description, include detailed information about the vulnerability, including steps to reproduce and potential impact.\n5. If possible, include any relevant code snippets or examples.\n6. Submit the issue.\n\nWe 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.\n\nThank you for helping us maintain a secure package!\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"jijunair/laravel-referral\",\n    \"description\": \"Laravel package for a referral system\",\n    \"keywords\": [\n        \"jijunair\",\n        \"laravel\",\n        \"referral\",\n        \"affiliate\",\n        \"package\",\n        \"laravel-referral\",\n        \"referral-system\",\n        \"user-referral\"\n    ],\n    \"homepage\": \"https://github.com/jijunair/laravel-referral\",\n    \"type\": \"library\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Jiju Nair\",\n            \"email\": \"hello@jijunair.com\"\n        }\n    ],\n    \"require\": {\n        \"php\": \"^7.2|^7.3|^7.4|^8.0|^8.1|^8.2\",\n        \"illuminate/database\": \"^8.0|^9.0|^10.0|^11.0|^12.0\",\n        \"illuminate/auth\": \"^8.0|^9.0|^10.0|^11.0|^12.0\"\n    },\n    \"require-dev\": {\n        \"phpunit/phpunit\": \"^9.4|^10.0|^11.0|^12.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"prefer-stable\": true,\n    \"autoload\": {\n        \"psr-4\": {\n            \"Jijunair\\\\LaravelReferral\\\\\": \"src\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Jijunair\\\\LaravelReferral\\\\Tests\\\\\": \"tests\"\n        }\n    },\n    \"extra\": {\n        \"laravel\": {\n            \"providers\": [\n                \"Jijunair\\\\LaravelReferral\\\\Providers\\\\ReferralServiceProvider\"\n            ]\n        }\n    }\n}\n"
  },
  {
    "path": "config/referral.php",
    "content": "<?php\n\nreturn [\n    /*\n    |--------------------------------------------------------------------------\n    | Referral System Configuration\n    |--------------------------------------------------------------------------\n    |\n    | This file contains the configuration options for the referral system.\n    |\n    */\n    // The name of the referral cookie\n    'cookie_name' => 'mysite_ref',\n\n    // Expiry time for the referral cookie in minutes\n    'cookie_expiry' => 525600, // 1 year\n\n    // The prefix used for referral links\n    'route_prefix' => 'save20',\n\n    // The prefix used for referral code\n    'ref_code_prefix' => 'ref_',\n\n    // The route where users will be redirected after clicking on a referral link\n    'redirect_route' => 'orders.create',\n\n    // The model class for the user\n    'user_model' => 'App\\Models\\User',\n\n    // The length of the referral code generated for each user\n    'referral_length' => 8,\n];\n"
  },
  {
    "path": "database/migrations/2023_05_28_135232_create_referrals_table.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migrations\\Migration;\n\nclass CreateReferralsTable extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create('referrals', function (Blueprint $table) {\n            \n            $table->id();\n            $table->unsignedBigInteger('user_id');\n            $table->string('referral_code')->unique();\n            $table->unsignedBigInteger('referrer_id')->nullable();\n            $table->timestamps();\n\n            $table->foreign('referrer_id')->references('id')->on('users')->onDelete('set null');\n            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');\n\n            $table->index('referral_code');\n            $table->index('user_id');\n            $table->index('referrer_id');\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::dropIfExists('referrals');\n    }\n}\n"
  },
  {
    "path": "routes/web.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Jijunair\\LaravelReferral\\Controllers\\ReferralController;\n\n\nRoute::middleware('web')->group(function () {\n    Route::get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer'])\n        ->name('referralLink');\n\n    Route::get('generate-ref-accounts', [ReferralController::class, 'createReferralCodeForExistingUsers'])\n        ->name('generateReferralCodes');\n});\n"
  },
  {
    "path": "src/Controllers/ReferralController.php",
    "content": "<?php\n\nnamespace Jijunair\\LaravelReferral\\Controllers;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Support\\Facades\\Cookie;\n\nclass ReferralController extends Controller\n{\n    /**\n     * Assign a referral code to the user.\n     *\n     * @param  string  $referralCode\n     * @return RedirectResponse\n     */\n    public function assignReferrer($referralCode)\n    {\n        $refCookieName = config('referral.cookie_name');\n        $refCookieExpiry = config('referral.cookie_expiry');\n        if (Cookie::has($refCookieName)) {\n            // Referral code cookie already exists, redirect to configured route\n            return redirect()->route(config('referral.redirect_route'));\n        } else {\n            // Create a referral code cookie and redirect to configured route\n            $ck = Cookie::make($refCookieName, $referralCode, $refCookieExpiry);\n            return redirect()->route(config('referral.redirect_route'))->withCookie($ck);\n        }\n    }\n\n    /**\n     * Generate referral codes for existing users.\n     *\n     * @return JsonResponse\n     */\n    public function createReferralCodeForExistingUsers()\n    {\n        $userModel = resolve(config('referral.user_model'));\n        $users = $userModel::cursor();\n\n        foreach ($users as $user) {\n            if (!$user->hasReferralAccount()) {\n                $user->createReferralAccount();\n            }\n        }\n\n        return response()->json(['message' => 'Referral codes generated for existing users.']);\n    }\n}\n"
  },
  {
    "path": "src/Models/Referral.php",
    "content": "<?php\n\nnamespace Jijunair\\LaravelReferral\\Models;\n\nuse Illuminate\\Support\\Facades\\App;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Referral extends Model\n{\n    /**\n     * The attributes that are mass assignable.\n     *\n     * @var array\n     */\n    protected $fillable = [\n        'user_id', 'referral_code', 'referrer_id'\n    ];\n\n    /**\n     * Get the user associated with the referral.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\n     */\n    public function user()\n    {\n        return $this->belongsTo(config('referral.user_model'), 'user_id');\n    }\n\n    /**\n     * Get the referrer associated with the referral.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\n     */\n    public function referrer()\n    {\n        return $this->belongsTo(config('referral.user_model'), 'referrer_id');\n    }\n\n    /**\n     * Retrieve the user by referral code.\n     *\n     * @param  string  $code\n     * @return mixed|null\n     */\n    public static function userByReferralCode($code)\n    {\n        $referrer = self::where('referral_code',$code)->first();\n        if ($referrer) {\n            return App::make(config('referral.user_model'))->find($referrer->user_id);\n        }\n        return null;\n        \n    }\n}\n"
  },
  {
    "path": "src/Providers/ReferralServiceProvider.php",
    "content": "<?php\n\nnamespace Jijunair\\LaravelReferral\\Providers;\n\nuse Illuminate\\Support\\ServiceProvider;\n\nclass ReferralServiceProvider extends ServiceProvider\n{\n    /**\n     * Register package services.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        // Merge the package's configuration file with the application's configuration\n        $this->mergeConfigFrom(__DIR__.'/../../config/referral.php', 'referral');\n    }\n\n    /**\n     * Bootstrap package services.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        // Load package migrations\n        $this->loadMigrationsFrom(__DIR__.'/../../database/migrations');\n\n        if ($this->app->runningInConsole()) {\n            // Publish package's configuration file\n            $this->publishes([\n                __DIR__.'/../../config/referral.php' => config_path('referral.php'),\n            ], 'laravel-referral-config');\n\n            // Publish package's migration files\n            $this->publishes([\n                __DIR__.'/../../database/migrations' => database_path('migrations'),\n            ], 'laravel-referral-migrations');\n        }\n\n        // Load package's routes\n        $this->loadRoutesFrom(__DIR__.'/../../routes/web.php');\n        \n        // Bind the ReferralController to the application container\n        $this->app->bind('Jijunair\\LaravelReferral\\Controllers\\ReferralController', function ($app) {\n            return new \\Jijunair\\LaravelReferral\\Controllers\\ReferralController();\n        });\n    }\n}\n"
  },
  {
    "path": "src/Traits/Referrable.php",
    "content": "<?php\n\nnamespace Jijunair\\LaravelReferral\\Traits;\n\nuse Illuminate\\Support\\Str;\nuse Jijunair\\LaravelReferral\\Models\\Referral;\n\ntrait Referrable\n{\n    /**\n     * Get the referrals associated with the user.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany\n     */\n    public function referrals()\n    {\n        return $this->hasMany(Referral::class, 'referrer_id');\n    }\n\n    /**\n     * Get the referral account of the user.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\n     */\n    public function referralAccount()\n    {\n        return $this->belongsTo(Referral::class, 'id', 'user_id');\n    }\n\n    /**\n     * Check if the user has a referral account.\n     *\n     * @return bool\n     */\n    public function hasReferralAccount()\n    {\n        return !is_null($this->referralAccount);\n    }\n\n    /**\n     * Get the referral link for the user.\n     *\n     * @return string\n     */\n    public function getReferralLink()\n    {\n        if ($this->hasReferralAccount()) {\n            return url('/') . \"/\" . config('referral.route_prefix') . \"/\" . $this->getReferralCode();\n        }\n        return \"\";\n    }\n\n    /**\n     * Get the referral code of the user's referral account.\n     *\n     * @return string|null\n     */\n    public function getReferralCode()\n    {\n        if ($this->hasReferralAccount()) {\n            return $this->referralAccount->referral_code;\n        }\n        \n        return null;\n    }\n\n    /**\n     * Create a referral account for the user.\n     *\n     * @param  int|null  $referrerID\n     * @return void\n     */\n    public function createReferralAccount(int $referrerID = NULL)\n    {\n\n        $prefix = config('referral.ref_code_prefix');\n        $length = config('referral.referral_length');\n        $referralCode = $this->generateUniqueReferralCode($prefix, $length);\n\n        $ref = new Referral;\n        $ref->user_id = $this->getKey();\n        $ref->referrer_id = $referrerID;\n        $ref->referral_code = $referralCode;\n        $ref->save();\n    }\n\n    /**\n     * Generate a unique referral code.\n     *\n     * @param  string  $prefix\n     * @param  int  $length\n     * @return string\n     */\n    private function generateUniqueReferralCode($prefix, $length)\n    {\n        $prefix = strtolower($prefix);\n        // Generate an initial referral code\n        $code = $prefix . strtolower(Str::random($length));\n\n        // Check if the generated code already exists in the database\n        while (Referral::where('referral_code', $code)->exists()) {\n            // If code already exists, generate a new one until a unique code is found\n            $code = $prefix . strtolower(Str::random($length));\n        }\n        \n        return $code;\n    }\n}\n"
  },
  {
    "path": "tests/ReferralControllerTest.php",
    "content": "<?php\n\nuse Tests\\TestCase;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\Cookie;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\n\nclass ReferralControllerTest extends TestCase\n{\n    use RefreshDatabase;\n\n    public function testAssignReferrerWithExistingCookie()\n    {\n        // Create a dummy referral code\n        $referralCode = 'ABC123';\n\n        // Set a dummy referral code cookie\n        Cookie::queue(config('referral.cookie_name'), $referralCode);\n\n        // Define the route for assigning a referrer\n        Route::middleware('web')->get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer'])\n            ->name('referralLink');\n\n        // Call the route with the referral code\n        $response = $this->get(route('referralLink', ['referralCode' => $referralCode]));\n\n        // Assert that the response redirects to the configured route\n        $response->assertRedirect(config('referral.redirect_route'));\n    }\n\n    public function testAssignReferrerWithoutExistingCookie()\n    {\n        // Create a dummy referral code\n        $referralCode = 'ABC123';\n\n        // Define the route for assigning a referrer\n        Route::middleware('web')->get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer'])\n            ->name('referralLink');\n\n        // Call the route with the referral code\n        $response = $this->get(route('referralLink', ['referralCode' => $referralCode]));\n\n        // Assert that the response redirects to the configured route\n        $response->assertRedirect(config('referral.redirect_route'));\n\n        // Assert that the referral code cookie has been set\n        $this->assertTrue(Cookie::has(config('referral.cookie_name')));\n    }\n\n    public function testCreateReferralCodeForExistingUsers()\n    {\n        // Create some dummy users\n        $users = factory(config('referral.user_model'), 5)->create();\n\n        // Define the route for generating referral codes for existing users\n        Route::middleware('web')->get('generate-ref-accounts', [ReferralController::class, 'createReferralCodeForExistingUsers'])\n            ->name('generateReferralCodes');\n\n        // Call the route to generate referral codes for existing users\n        $response = $this->get(route('generateReferralCodes'));\n\n        // Assert that the response is a JSON response\n        $response->assertJson(['message' => 'Referral codes generated for existing users.']);\n\n        // Assert that referral codes have been created for all existing users\n        foreach ($users as $user) {\n            $this->assertTrue($user->hasReferralAccount());\n            $this->assertNotNull($user->getReferralCode());\n        }\n    }\n}\n"
  }
]