浏览代码

Referal System

1Day 3 年之前
父节点
当前提交
378187aea0

+ 5 - 0
app/Classes/Settings/Misc.php

@@ -37,6 +37,8 @@ class Misc
             'mailencryption' => 'nullable|string',
             'mailfromadress' => 'nullable|string',
             'mailfromname' => 'nullable|string',
+            'enable_referral' => 'nullable|string',
+            'referral_reward' => 'nullable|numeric',
         ]);
 
         if ($validator->fails()) {
@@ -69,6 +71,9 @@ class Misc
             "SETTINGS::MAIL:ENCRYPTION" => "mailencryption",
             "SETTINGS::MAIL:FROM_ADDRESS" => "mailfromadress",
             "SETTINGS::MAIL:FROM_NAME" => "mailfromname",
+            "SETTINGS::REFERRAL::ENABLED" => "enable_referral",
+            "SETTINGS::REFERRAL::REWARD" => "referral_reward"
+
 
         ];
 

+ 16 - 2
app/Http/Controllers/Admin/UserController.php

@@ -8,6 +8,7 @@ use App\Http\Controllers\Controller;
 use App\Models\Settings;
 use App\Models\User;
 use App\Notifications\DynamicNotification;
+use Illuminate\Support\Facades\DB;
 use Spatie\QueryBuilder\QueryBuilder;
 use Exception;
 use Illuminate\Contracts\Foundation\Application;
@@ -52,8 +53,18 @@ class UserController extends Controller
      */
     public function show(User $user)
     {
+        //QUERY ALL REFERRALS A USER HAS
+        //i am not proud of this at all.
+            $allReferals = array();
+            $referrals = DB::table("user_referrals")->where("referral_id","=",$user->id)->get();
+            foreach($referrals as $referral){
+                array_push($allReferals, $allReferals["id"] = User::query()->findOrFail($referral->registered_user_id));
+            }
+            array_pop($allReferals);
+
         return view('admin.users.show')->with([
-            'user' => $user
+            'user' => $user,
+            'referrals' => $allReferals
         ]);
     }
 
@@ -258,6 +269,9 @@ class UserController extends Controller
             ->addColumn('servers', function (User $user) {
                 return $user->servers->count();
             })
+            ->addColumn('referrals', function (User $user) {
+                return DB::table('user_referrals')->where("referral_id","=",$user->id)->count();
+            })
             ->addColumn('discordId', function (User $user) {
                 return $user->discordUser ? $user->discordUser->id : '';
             })
@@ -307,7 +321,7 @@ class UserController extends Controller
             ->orderColumn('last_seen', function ($query) {
                 $query->orderBy('last_seen', "desc");
             })
-            ->rawColumns(['avatar', 'name', 'credits', 'role', 'usage', 'actions', 'last_seen'])
+            ->rawColumns(['avatar', 'name', 'credits', 'role', 'usage', 'referrals', 'actions', 'last_seen'])
             ->make(true);
     }
 }

+ 35 - 0
app/Http/Controllers/Auth/RegisterController.php

@@ -6,9 +6,13 @@ use App\Classes\Pterodactyl;
 use App\Http\Controllers\Controller;
 use App\Models\Settings;
 use App\Models\User;
+use App\Notifications\ReferralNotification;
 use App\Providers\RouteServiceProvider;
+use Carbon\Carbon;
 use Illuminate\Foundation\Auth\RegistersUsers;
 use Illuminate\Support\Facades\App;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Hash;
 use Illuminate\Support\Facades\Validator;
 use Illuminate\Support\Str;
@@ -78,6 +82,18 @@ class RegisterController extends Controller
         return Validator::make($data, $validationRules);
     }
 
+    /**
+     * Create a unique Referral Code for User
+     * @return string
+     */
+    protected function createReferralCode(){
+        $referralcode = STR::random(8);
+        if (User::where('referral_code', '=', $referralcode)->exists()) {
+            $this->createReferralCode();
+        }
+        return $referralcode;
+    }
+
     /**
      * Create a new user instance after a valid registration.
      *
@@ -92,6 +108,8 @@ class RegisterController extends Controller
             'credits'      => config('SETTINGS::USER:INITIAL_CREDITS', 150),
             'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
             'password'     => Hash::make($data['password']),
+            'referral_code' => $this->createReferralCode(),
+
         ]);
 
         $response = Pterodactyl::client()->post('/application/users', [
@@ -116,7 +134,24 @@ class RegisterController extends Controller
             'pterodactyl_id' => $response->json()['attributes']['id']
         ]);
 
+        //INCREMENT REFERRAL-USER CREDITS
+        if(!empty($data['referral_code'])){
+            $ref_code = $data['referral_code'];
+            $new_user = $user->id;
+            if($ref_user = User::query()->where('referral_code', '=', $ref_code)->first()) {
+                $ref_user->increment('credits', config("SETTINGS::REFERRAL::REWARD"));
+                $ref_user->notify(new ReferralNotification($ref_user->id,$new_user));
+
+                //INSERT INTO USER_REFERRALS TABLE
+                DB::table('user_referrals')->insert([
+                    'referral_id' => $ref_user->id,
+                    'registered_user_id' => $user->id,
+                    'created_at' =>  Carbon::now(),
+                    'updated_at' => Carbon::now()
+                ]);
+            }
 
+        }
 
         return $user;
     }

+ 2 - 1
app/Models/User.php

@@ -60,7 +60,8 @@ class User extends Authenticatable implements MustVerifyEmail
         'pterodactyl_id',
         'discord_verified_at',
         'avatar',
-        'suspended'
+        'suspended',
+        'referral_code'
     ];
 
     /**

+ 59 - 0
app/Notifications/ReferralNotification.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Notifications;
+
+use App\Models\User;
+use Illuminate\Bus\Queueable;
+use Illuminate\Notifications\Notification;
+use Illuminate\Support\Facades\Auth;
+
+class ReferralNotification extends Notification
+
+{
+    use Queueable;
+    /**
+     * @var User
+     */
+    private $user;
+
+    /**
+     * Create a new notification instance.
+     *
+     * @param User $user
+     */
+    public function __construct(int $user, int $ref_user)
+    {
+        $this->user = User::findOrFail($user);
+        $this->ref_user = User::findOrFail($ref_user);
+    }
+
+    /**
+     * Get the notification's delivery channels.
+     *
+     * @param mixed $notifiable
+     * @return array
+     */
+    public function via($notifiable)
+    {
+        return ['database'];
+    }
+
+    /**
+     * Get the array representation of the notification.
+     *
+     * @param mixed $notifiable
+     * @return array
+     */
+    public function toArray($notifiable)
+    {
+        return [
+            'title' => __("Someone registered using your Code!"),
+            'content' => "
+                <p>You received ".config('SETTINGS::REFERRAL::REWARD')." ".config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME')."</p>
+                <p>because ".$this->ref_user->name." registered with your Referral-Code!</p>
+                <p>Thank you very much for supporting us!.</p>
+                <p>".config('app.name', 'Laravel')."</p>
+            ",
+        ];
+    }
+}

+ 53 - 0
database/migrations/2022_06_02_081655_referral_code.php

@@ -0,0 +1,53 @@
+<?php
+
+use App\Models\User;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Support\Str;
+
+class ReferralCode extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->string('referral_code')->lenght(8)->nullable();
+        });
+
+        $existing_user = User::where('referral_code', '')->get();
+
+        foreach ($existing_user as $user) {
+            $random = STR::random(8);
+            if (User::where('referral_code', '=', $random)->doesntExist()) {
+                DB::table("users")
+                    ->where("id", "=", $user->id)
+                    ->update(['referral_code' => $random]);
+            }else{
+                $random = STR::random(8);
+                DB::table("users")
+                    ->where("id", "=", $user->id)
+                    ->update(['referral_code' => $random]);
+            }
+        }
+    }
+
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->dropColumn('referral_code');
+        });
+    }
+
+}

+ 35 - 0
database/migrations/2022_06_02_091921_table-user-referrals.php

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class TableUserReferrals extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('user_referrals', function (Blueprint $table) {
+            $table->unsignedBigInteger('referral_id');
+            $table->unsignedBigInteger('registered_user_id');
+            $table->foreign('referral_id')->references('id')->on('users');
+            $table->foreign('registered_user_id')->references('id')->on('users');
+            $table->timestamps();
+        });
+
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('user_referrals');
+    }
+}

+ 14 - 0
database/seeders/Seeds/SettingsSeeder.php

@@ -465,5 +465,19 @@ class SettingsSeeder extends Seeder
             'type'  => 'string',
             'description'  => 'Mailer From Name'
         ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::REFERRAL::ENABLED',
+        ], [
+            'value' =>"true",
+            'type'  => 'string',
+            'description'  => 'Enable or disable the referral system'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::REFERRAL::REWARD',
+        ], [
+            'value' =>100,
+            'type'  => 'integer',
+            'description'  => 'Credit reward a user should receive when a user registers with his referral code'
+        ]);
     }
 }

+ 26 - 0
resources/views/admin/settings/tabs/misc.blade.php

@@ -184,7 +184,33 @@
                     </div>
                 </div>
             </div>
+            <div class="col-md-3 px-3">
+                <div class="row mb-2">
+                    <div class="col text-center">
+                        <h1>Referral</h1>
+                    </div>
+                </div>
 
+                <div class="custom-control mb-3 p-0">
+                    <div class="col m-0 p-0 d-flex justify-content-between align-items-center">
+                        <div>
+                            <input value="true" id="enable_referral" name="enable_referral"
+                                   {{ config('SETTINGS::REFERRAL::ENABLED') == 'true' ? 'checked' : '' }}
+                                   type="checkbox">
+                            <label for="enable_referral">{{ __('Enable Referral') }} </label>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="form-group mb-3">
+                    <div class="custom-control p-0">
+                        <label for="referral_reward">{{ __('Referral reward in') }} {{ config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME', 'Credits') }}:</label>
+                        <input x-model="referral_reward" id="referral_reward" name="referral_reward"
+                               type="number" value="{{ config('SETTINGS::REFERRAL::REWARD') }}"
+                               class="form-control @error('referral_reward') is-invalid @enderror">
+                    </div>
+                </div>
+            </div>
 
         </div>
         <div class="row">

+ 2 - 0
resources/views/admin/users/index.blade.php

@@ -47,6 +47,7 @@
                             <th>{{__('Email')}}</th>
                             <th>{{CREDITS_DISPLAY_NAME}}</th>
                             <th>{{__('Servers')}}</th>
+                            <th>{{__("Referrals")}}</th>
                             <th>{{__('Verified')}}</th>
                             <th>{{__('Last seen')}}</th>
                             <th></th>
@@ -90,6 +91,7 @@
                     {data: 'email', name: 'users.email'},
                     {data: 'credits' , name : 'users.credits'},
                     {data: 'servers' , sortable : false},
+                    {data: 'referrals'},
                     {data: 'verified' , sortable : false},
                     {data: 'last_seen'},
                     {data: 'actions' , sortable : false},

+ 29 - 0
resources/views/admin/users/show.blade.php

@@ -244,8 +244,37 @@
                     @include('admin.servers.table' , ['filter' => '?user=' . $user->id])
 
                 </div>
+
             </div>
+                <div class="card">
+                    <div class="card-header">
+                        <h5 class="card-title"><i class="fas fa-user-check mr-2"></i>{{__('Referals')}}</h5>
+                    </div>
+                    <div class="card-body table-responsive">
+
+
+                        @foreach($referrals as $referral)
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>User ID: {{$referral->id}}</label>
+                                </div>
+                                <div class="col-lg-4">
+                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                           <i class="fas fa-user-check mr-2"></i><a href="{{route("admin.users.show",$referral->id)}}">{{$referral->name}}</a>
+                                       </span>
+                                </div>
+                                <div class="col-lg-4">
+                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                           <i class="fas fa-clock mr-2"></i>{{$referral->created_at->diffForHumans()}}
+                                       </span>
+                                </div>
+                            </div>
+                        </div>
+                        @endforeach
+                    </div>
 
+                </div>
 
         </div>
         <!-- END CUSTOM CONTENT -->

+ 10 - 1
resources/views/auth/register.blade.php

@@ -91,7 +91,16 @@
                             </div>
                         </div>
                     </div>
-
+                    @if(config('SETTINGS::REFERRAL::ENABLED') == "true")
+                        <div class="input-group mb-3">
+                            <input type="text" value="{{ \Request::get('ref') }}" class="form-control" name="referral_code" placeholder="{{__('Referral code')}} ( {{__("optional")}} )">
+                            <div class="input-group-append">
+                                <div class="input-group-text">
+                                    <span class="fas fa-user-check"></span>
+                                </div>
+                            </div>
+                        </div>
+                    @endif
                     <div class="input-group mb-3">
                         {!! htmlFormSnippet() !!}
                         @error('g-recaptcha-response')

+ 58 - 37
resources/views/profile/index.blade.php

@@ -12,7 +12,7 @@
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
-                                href="{{ route('profile.index') }}">{{ __('Profile') }}</a>
+                                                       href="{{ route('profile.index') }}">{{ __('Profile') }}</a>
                         </li>
                     </ol>
                 </div>
@@ -33,7 +33,7 @@
                             </h5>
                             {{ __('You have not yet verified your email address') }}
                             <a class="text-primary"
-                                href="{{ route('verification.send') }}">{{ __('Click here to resend verification email') }}</a>
+                               href="{{ route('verification.send') }}">{{ __('Click here to resend verification email') }}</a>
                             <br>
                             {{ __('Please contact support If you didnt receive your verification email.') }}
 
@@ -43,16 +43,18 @@
                     @if (is_null(Auth::user()->discordUser) && strtolower($force_discord_verification) == 'true')
                         @if (!empty(config('SETTINGS::DISCORD:CLIENT_ID')) && !empty(config('SETTINGS::DISCORD:CLIENT_SECRET')))
                             <div class="alert alert-warning p-2 m-2">
-                                <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
+                                <h5>
+                                    <i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
                                 </h5>
                                 {{ __('You have not yet verified your discord account') }}
                                 <a class="text-primary"
-                                    href="{{ route('auth.redirect') }}">{{ __('Login with discord') }}</a> <br>
+                                   href="{{ route('auth.redirect') }}">{{ __('Login with discord') }}</a> <br>
                                 {{ __('Please contact support If you face any issues.') }}
                             </div>
                         @else
                             <div class="alert alert-danger p-2 m-2">
-                                <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
+                                <h5>
+                                    <i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
                                 </h5>
                                 {{ __('Due to system settings you are required to verify your discord account!') }} <br>
                                 {{ __('It looks like this hasnt been set-up correctly! Please contact support.') }}'
@@ -72,9 +74,10 @@
                             <div class="row">
                                 <div class="col-12 col-sm-auto mb-4">
                                     <div class="slim rounded-circle  border-secondary border text-gray-dark"
-                                        data-label="Change your avatar" data-max-file-size="3"
-                                        data-save-initial-image="true" style="width: 140px;height:140px; cursor: pointer"
-                                        data-size="140,140">
+                                         data-label="Change your avatar" data-max-file-size="3"
+                                         data-save-initial-image="true"
+                                         style="width: 140px;height:140px; cursor: pointer"
+                                         data-size="140,140">
                                         <img src="{{ $user->getAvatar() }}" alt="avatar">
                                     </div>
                                 </div>
@@ -84,10 +87,11 @@
                                         <p class="mb-0">{{ $user->email }}
                                             @if ($user->hasVerifiedEmail())
                                                 <i data-toggle="popover" data-trigger="hover" data-content="Verified"
-                                                    class="text-success fas fa-check-circle"></i>
+                                                   class="text-success fas fa-check-circle"></i>
                                             @else
-                                                <i data-toggle="popover" data-trigger="hover" data-content="Not verified"
-                                                    class="text-danger fas fa-exclamation-circle"></i>
+                                                <i data-toggle="popover" data-trigger="hover"
+                                                   data-content="Not verified"
+                                                   class="text-danger fas fa-exclamation-circle"></i>
                                             @endif
 
                                         </p>
@@ -95,8 +99,23 @@
                                             <span class="badge badge-primary"><i
                                                     class="fa fa-coins mr-2"></i>{{ $user->Credits() }}</span>
                                         </div>
+
+
+                                        <div class="mt-1">
+                                            @if(config('SETTINGS::REFERRAL::ENABLED') == "true" && $user->role != "member")
+                                                <span class="badge badge-success"><i
+                                                        class="fa fa-user-check mr-2"></i>
+                                                    {{_("Referral URL")}} : {{route("register")}}?ref={{$user->referral_code}}</span>
+                                            @else
+                                                <span class="badge badge-warning"><i
+                                                        class="fa fa-user-check mr-2"></i>
+                                                    {{_("Make a purchase to reveal your referral-URL")}}</span>
+                                            @endif
+                                        </div>
+
                                     </div>
 
+
                                     <div class="text-center text-sm-right"><span
                                             class="badge badge-secondary">{{ $user->role }}</span>
                                         <div class="text-muted">
@@ -107,7 +126,7 @@
                             </div>
                             <ul class="nav nav-tabs">
                                 <li class="nav-item"><a href="javasript:void(0)"
-                                        class="active nav-link">{{ __('Settings') }}</a>
+                                                        class="active nav-link">{{ __('Settings') }}</a>
                                 </li>
                             </ul>
                             <div class="tab-content pt-3">
@@ -123,22 +142,22 @@
                                                             </span>
                                                         @endforeach
                                                     @endif
-                                                        @if( $errors->has('pterodactyl_error_status') )
-                                                            @foreach( $errors->get('pterodactyl_error_status') as $err )
-                                                                <span class="text-danger" role="alert">
+                                                    @if( $errors->has('pterodactyl_error_status') )
+                                                        @foreach( $errors->get('pterodactyl_error_status') as $err )
+                                                            <span class="text-danger" role="alert">
                                                                     <small><strong>{{ $err }}</strong></small>
                                                                 </span>
-                                                            @endforeach
-                                                        @endif
+                                                        @endforeach
+                                                    @endif
                                                     <div class="form-group"><label>{{__('Name')}}</label> <input
                                                             class="form-control @error('name') is-invalid @enderror"
                                                             type="text" name="name" placeholder="{{ $user->name }}"
                                                             value="{{ $user->name }}">
 
                                                         @error('name')
-                                                            <div class="invalid-feedback">
-                                                                {{ $message }}
-                                                            </div>
+                                                        <div class="invalid-feedback">
+                                                            {{ $message }}
+                                                        </div>
                                                         @enderror
                                                     </div>
                                                 </div>
@@ -151,9 +170,9 @@
                                                             value="{{ $user->email }}">
 
                                                         @error('email')
-                                                            <div class="invalid-feedback">
-                                                                {{ $message }}
-                                                            </div>
+                                                        <div class="invalid-feedback">
+                                                            {{ $message }}
+                                                        </div>
                                                         @enderror
                                                     </div>
                                                 </div>
@@ -169,12 +188,13 @@
                                                         <label>{{ __('Current Password') }}</label>
                                                         <input
                                                             class="form-control @error('current_password') is-invalid @enderror"
-                                                            name="current_password" type="password" placeholder="••••••">
+                                                            name="current_password" type="password"
+                                                            placeholder="••••••">
 
                                                         @error('current_password')
-                                                            <div class="invalid-feedback">
-                                                                {{ $message }}
-                                                            </div>
+                                                        <div class="invalid-feedback">
+                                                            {{ $message }}
+                                                        </div>
                                                         @enderror
                                                     </div>
                                                 </div>
@@ -187,9 +207,9 @@
                                                             name="new_password" type="password" placeholder="••••••">
 
                                                         @error('new_password')
-                                                            <div class="invalid-feedback">
-                                                                {{ $message }}
-                                                            </div>
+                                                        <div class="invalid-feedback">
+                                                            {{ $message }}
+                                                        </div>
                                                         @enderror
                                                     </div>
                                                 </div>
@@ -204,9 +224,9 @@
                                                             placeholder="••••••">
 
                                                         @error('new_password_confirmation')
-                                                            <div class="invalid-feedback">
-                                                                {{ $message }}
-                                                            </div>
+                                                        <div class="invalid-feedback">
+                                                            {{ $message }}
+                                                        </div>
                                                         @enderror
                                                     </div>
                                                 </div>
@@ -245,9 +265,10 @@
                                                                     </p>
                                                                 </div>
                                                                 <div class="p-3"><img width="100px"
-                                                                        height="100px" class="rounded-circle"
-                                                                        src="{{ $user->discordUser->getAvatar() }}"
-                                                                        alt="avatar"></div>
+                                                                                      height="100px"
+                                                                                      class="rounded-circle"
+                                                                                      src="{{ $user->discordUser->getAvatar() }}"
+                                                                                      alt="avatar"></div>
                                                             </div>
                                                             <div class="small-box-footer">
                                                                 <a href="{{ route('auth.redirect') }}">
@@ -265,7 +286,7 @@
                                     <div class="row">
                                         <div class="col d-flex justify-content-end">
                                             <button class="btn btn-primary"
-                                                type="submit">{{ __('Save Changes') }}</button>
+                                                    type="submit">{{ __('Save Changes') }}</button>
                                         </div>
                                     </div>