├── LICENSE ├── README.md ├── composer.json ├── config └── referral.php ├── database └── migrations │ └── add_referral_to_users_table.php └── src ├── Http └── Middleware │ └── CheckReferral.php ├── ReferralServiceProvider.php └── Traits └── UserReferral.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Zhengchao Pu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # laravel-referral 2 | 3 | A Referral System With Laravel 4 | 5 | [![StyleCI](https://styleci.io/repos/115917817/shield?branch=master)](https://styleci.io/repos/115917817) 6 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/questocat/laravel-referral/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/questocat/laravel-referral/?branch=master) 7 | [![Build Status](https://scrutinizer-ci.com/g/questocat/laravel-referral/badges/build.png?b=master)](https://scrutinizer-ci.com/g/questocat/laravel-referral/build-status/master) 8 | [![Packagist](https://img.shields.io/packagist/l/doctrine/orm.svg)](https://packagist.org/packages/questocat/laravel-referral) 9 | 10 | ## Installation 11 | 12 | Via [Composer](https://getcomposer.org) to add the package to your project's dependencies: 13 | 14 | ```bash 15 | $ composer require questocat/laravel-referral 16 | ``` 17 | 18 | First add service providers into the config/app.php 19 | 20 | ```php 21 | \Questocat\Referral\ReferralServiceProvider::class, 22 | ``` 23 | 24 | Publish the migrations 25 | 26 | ```bash 27 | $ php artisan vendor:publish --provider="Questocat\Referral\ReferralServiceProvider" --tag="migrations" 28 | ``` 29 | 30 | Publish the config 31 | 32 | ```bash 33 | $ php artisan vendor:publish --provider="Questocat\Referral\ReferralServiceProvider" --tag="config" 34 | ``` 35 | 36 | ## Setup the model 37 | 38 | Add UserReferral Trait to your User model. 39 | 40 | ```php 41 | use Questocat\Referral\Traits\UserReferral 42 | 43 | class User extends Model 44 | { 45 | use UserReferral; 46 | } 47 | ``` 48 | 49 | ## Usage 50 | 51 | Assigning CheckReferral Middleware To Routes. 52 | 53 | ```php 54 | // Within App\Http\Kernel Class... 55 | 56 | protected $routeMiddleware = [ 57 | 'referral' => \Questocat\Referral\Http\Middleware\CheckReferral::class, 58 | ]; 59 | ``` 60 | 61 | Once the middleware has been defined in the HTTP kernel, you may use the middleware method to assign middleware to a route: 62 | 63 | ```php 64 | Route::get('/', 'HomeController@index')->middleware('referral'); 65 | ``` 66 | 67 | Now you can create the user: 68 | 69 | ```php 70 | $user = new App\User(); 71 | $user->name = 'zhengchaopu'; 72 | $user->password = bcrypt('password'); 73 | $user->email = 'zhengchaopu@gmail.com'; 74 | $user->save(); 75 | 76 | // Or 77 | 78 | $data = [ 79 | 'name' => 'zhengchaopu', 80 | 'password' => bcrypt('password'), 81 | 'email' => 'zhengchaopu@gmail.com', 82 | ]; 83 | 84 | App\User::create($data); 85 | ``` 86 | 87 | Get the referral link: 88 | 89 | ```php 90 | $user = App\User::findOrFail(1); 91 | 92 | {{ $user->getReferralLink() }} 93 | ``` 94 | 95 | 96 | ## License 97 | 98 | Licensed under the [MIT license](https://github.com/questocat/laravel-referral/blob/master/LICENSE). 99 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "questocat/laravel-referral", 3 | "description": "A Referral System With Laravel", 4 | "keywords": ["referral", "referral-system", "affiliate-tracking"], 5 | "license": "MIT", 6 | "authors": [{ 7 | "name": "questocat", 8 | "email": "zhengchaopu@gmail.com" 9 | }], 10 | "require": { 11 | "php": ">=7.0" 12 | }, 13 | "require-dev": { 14 | "laravel/laravel": "^5.5", 15 | "mockery/mockery": "~0.9", 16 | "phpunit/phpunit": "~4.0|~5.0" 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "Questocat\\Referral\\": "src/" 21 | } 22 | }, 23 | "autoload-dev": { 24 | "psr-4": { 25 | "Tests\\": "tests/" 26 | } 27 | }, 28 | "extra": { 29 | "laravel": { 30 | "providers": [ 31 | "Questocat\\Referral\\ReferralServiceProvider" 32 | ] 33 | } 34 | }, 35 | "repositories": { 36 | "packagist": { 37 | "type": "composer", 38 | "url": "https://packagist.phpcomposer.com" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /config/referral.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | * Model class name of users. 15 | */ 16 | 'user_model' => 'App\User', 17 | 18 | /* 19 | * The length of referral code. 20 | */ 21 | 'referral_length' => 5, 22 | ]; 23 | -------------------------------------------------------------------------------- /database/migrations/add_referral_to_users_table.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | use Illuminate\Database\Migrations\Migration; 13 | use Illuminate\Database\Schema\Blueprint; 14 | use Illuminate\Support\Facades\Schema; 15 | 16 | class AddReferralToUsersTable extends Migration 17 | { 18 | /** 19 | * Run the migrations. 20 | */ 21 | public function up() 22 | { 23 | Schema::table('users', function (Blueprint $table) { 24 | $table->string('referred_by')->nullable()->index(); 25 | $table->string('affiliate_id')->unique(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | */ 32 | public function down() 33 | { 34 | Schema::table('users', function (Blueprint $table) { 35 | $table->dropColumn('referred_by'); 36 | $table->dropColumn('affiliate_id'); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Http/Middleware/CheckReferral.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Questocat\Referral\Http\Middleware; 13 | 14 | use Closure; 15 | 16 | class CheckReferral 17 | { 18 | public function handle($request, Closure $next) 19 | { 20 | if ($request->hasCookie('referral')) { 21 | return $next($request); 22 | } 23 | 24 | if (($ref = $request->query('ref')) && app(config('referral.user_model', 'App\User'))->referralExists($ref)) { 25 | return redirect($request->fullUrl())->withCookie(cookie()->forever('referral', $ref)); 26 | } 27 | 28 | return $next($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/ReferralServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Questocat\Referral; 13 | 14 | use Illuminate\Support\ServiceProvider; 15 | 16 | class ReferralServiceProvider extends ServiceProvider 17 | { 18 | /** 19 | * Indicates if loading of the provider is deferred. 20 | * 21 | * @var bool 22 | */ 23 | protected $defer = false; 24 | 25 | /** 26 | * Bootstrap the application events. 27 | */ 28 | public function boot() 29 | { 30 | $this->setupConfig(); 31 | $this->setupMigrations(); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function register() 38 | { 39 | } 40 | 41 | /** 42 | * Setup the config. 43 | */ 44 | protected function setupConfig() 45 | { 46 | $source = realpath(__DIR__.'/../config/referral.php'); 47 | 48 | $this->publishes([ 49 | $source => config_path('referral.php'), 50 | ], 'config'); 51 | 52 | $this->mergeConfigFrom($source, 'referral'); 53 | } 54 | 55 | /** 56 | * Setup the migrations. 57 | */ 58 | protected function setupMigrations() 59 | { 60 | $timestamp = date('Y_m_d_His'); 61 | $migrationsSource = realpath(__DIR__.'/../database/migrations/add_referral_to_users_table.php'); 62 | $migrationsTarget = database_path("/migrations/{$timestamp}_add_referral_to_users_table.php"); 63 | 64 | $this->publishes([ 65 | $migrationsSource => $migrationsTarget, 66 | ], 'migrations'); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Traits/UserReferral.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Questocat\Referral\Traits; 13 | 14 | use Illuminate\Database\Eloquent\Builder; 15 | use Illuminate\Support\Facades\Cookie; 16 | use Illuminate\Support\Str; 17 | 18 | trait UserReferral 19 | { 20 | public function getReferralLink() 21 | { 22 | return url('/').'/?ref='.$this->affiliate_id; 23 | } 24 | 25 | public static function scopeReferralExists(Builder $query, $referral) 26 | { 27 | return $query->whereAffiliateId($referral)->exists(); 28 | } 29 | 30 | protected static function boot() 31 | { 32 | parent::boot(); 33 | 34 | static::creating(function ($model) { 35 | if ($referredBy = Cookie::get('referral')) { 36 | $model->referred_by = $referredBy; 37 | } 38 | 39 | $model->affiliate_id = self::generateReferral(); 40 | }); 41 | } 42 | 43 | protected static function generateReferral() 44 | { 45 | $length = config('referral.referral_length', 5); 46 | 47 | do { 48 | $referral = Str::random($length); 49 | } while (static::referralExists($referral)); 50 | 51 | return $referral; 52 | } 53 | } 54 | --------------------------------------------------------------------------------