Fixes and cleanup for user pending/registration calls
This commit is contained in:
@@ -7,14 +7,19 @@ use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
|
||||
/**
|
||||
* Event triggered when a user's state changes
|
||||
* @package App\Events
|
||||
*/
|
||||
class UserStateChanged
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public $user;
|
||||
public $old_state, $user;
|
||||
|
||||
public function __construct(User $user)
|
||||
public function __construct(User $user, $old_state)
|
||||
{
|
||||
$this->old_state = $old_state;
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
||||
|
||||
29
app/Events/UserStatsChanged.php
Normal file
29
app/Events/UserStatsChanged.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
|
||||
class UserStatsChanged
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public $stat_name,
|
||||
$old_value,
|
||||
$user;
|
||||
|
||||
/*
|
||||
* When a user's stats change. Stats changed match the field name:
|
||||
* flights
|
||||
* rank
|
||||
*/
|
||||
public function __construct(User $user, $stat_name, $old_value)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->stat_name = $stat_name;
|
||||
$this->old_value = $old_value;
|
||||
}
|
||||
}
|
||||
@@ -2,26 +2,29 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use DB;
|
||||
use Hash;
|
||||
use Log;
|
||||
use Flash;
|
||||
use Response;
|
||||
use Jackiedo\Timezonelist\Facades\Timezonelist;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Http\Requests\CreateUserRequest;
|
||||
use App\Http\Requests\UpdateUserRequest;
|
||||
use App\Repositories\UserRepository;
|
||||
use DB;
|
||||
use Hash;
|
||||
use Illuminate\Http\Request;
|
||||
use Flash;
|
||||
use Jackiedo\Timezonelist\Facades\Timezonelist;
|
||||
use Response;
|
||||
use App\Services\UserService;
|
||||
|
||||
use App\Models\Airport;
|
||||
use App\Models\Airline;
|
||||
use App\Models\Rank;
|
||||
use App\Models\Role;
|
||||
|
||||
|
||||
class UserController extends BaseController
|
||||
{
|
||||
/** @var UserRepository */
|
||||
private $userRepo;
|
||||
private $userRepo,
|
||||
$userSvc;
|
||||
|
||||
/**
|
||||
* UserController constructor.
|
||||
@@ -29,18 +32,18 @@ class UserController extends BaseController
|
||||
* @param UserRepository $userRepo
|
||||
*/
|
||||
public function __construct(
|
||||
UserRepository $userRepo
|
||||
UserRepository $userRepo,
|
||||
UserService $userSvc
|
||||
) {
|
||||
$this->userSvc = $userSvc;
|
||||
$this->userRepo = $userRepo;
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$users = $this->userRepo->searchCriteria($request, false)->paginate();
|
||||
/*$this->userRepo->pushCriteria(new RequestCriteria($request));
|
||||
$users = $this->userRepo
|
||||
$users = $this->userRepo->searchCriteria($request, false)
|
||||
->orderBy('created_at', 'desc')
|
||||
->paginate();*/
|
||||
->paginate();
|
||||
|
||||
return view('admin.users.index', [
|
||||
'users' => $users,
|
||||
@@ -146,8 +149,15 @@ class UserController extends BaseController
|
||||
$req_data['password'] = Hash::make($req_data['password']);
|
||||
}
|
||||
|
||||
$original_user_state = $user->state;
|
||||
|
||||
$user = $this->userRepo->update($req_data, $id);
|
||||
|
||||
if($original_user_state !== $user->state) {
|
||||
$this->userSvc->changeUserState($user, $original_user_state);
|
||||
}
|
||||
|
||||
# Delete all of the roles and then re-attach the valid ones
|
||||
DB::table('role_user')->where('user_id',$id)->delete();
|
||||
foreach ($request->input('roles') as $key => $value) {
|
||||
$user->attachRole($value);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Events\UserStateChanged;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
@@ -34,10 +35,45 @@ class EmailEventListener
|
||||
. ', sending active email');
|
||||
|
||||
if($event->user->state === PilotState::ACTIVE) {
|
||||
Mail::to($event->user->email)->send(new \App\Mail\UserRegistered($event->user));
|
||||
$email = new \App\Mail\UserRegistered(
|
||||
$event->user,
|
||||
'Welcome to ' . config('app.name') . '!'
|
||||
);
|
||||
|
||||
Mail::to($event->user->email)->send($email);
|
||||
} else if($event->user->state === PilotState::PENDING) {
|
||||
Mail::to($event->user->email)->send(new \App\Mail\UserPending($event->user));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a user's state changes, send an email out
|
||||
* @param UserStateChanged $event
|
||||
*/
|
||||
public function onUserStateChange(UserStateChanged $event)
|
||||
{
|
||||
if ($event->old_state === PilotState::PENDING) {
|
||||
if ($event->user->state === PilotState::ACTIVE)
|
||||
{
|
||||
$email = new \App\Mail\UserRegistered(
|
||||
$event->user,
|
||||
'Your registration has been accepted!'
|
||||
);
|
||||
|
||||
Mail::to($event->user->email)->send($email);
|
||||
}
|
||||
|
||||
else if ($event->user->state === PilotState::REJECTED)
|
||||
{
|
||||
$email = new \App\Mail\UserRejected($event->user);
|
||||
Mail::to($event->user->email)->send($email);
|
||||
}
|
||||
}
|
||||
|
||||
# TODO: Other state transitions
|
||||
elseif ($event->old_state === PilotState::ACTIVE)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,30 +3,27 @@
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class UserPending extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private $user;
|
||||
private $subject,
|
||||
$user;
|
||||
|
||||
public function __construct(User $user)
|
||||
public function __construct(User $user, $subject=null)
|
||||
{
|
||||
$this->subject = $subject ?: 'Your registration is pending!';
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->markdown('emails.user.pending')
|
||||
->subject($this->subject)
|
||||
->with(['user' => $this->user]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,23 +12,19 @@ class UserRegistered extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private $user;
|
||||
private $subject,
|
||||
$user;
|
||||
|
||||
public function __construct(User $user)
|
||||
public function __construct(User $user, $subject=null)
|
||||
{
|
||||
$this->subject = $subject;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->markdown('emails.user.registered')
|
||||
->with([
|
||||
'user' => $this->user,
|
||||
]);
|
||||
->subject($this->subject)
|
||||
->with(['user' => $this->user]);
|
||||
}
|
||||
}
|
||||
|
||||
29
app/Mail/UserRejected.php
Normal file
29
app/Mail/UserRejected.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class UserRejected extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private $subject,
|
||||
$user;
|
||||
|
||||
public function __construct(User $user, $subject=null)
|
||||
{
|
||||
$this->subject = $subject ?: 'Your registration has been denied';
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
return $this->markdown('emails.user.rejected')
|
||||
->subject($this->subject)
|
||||
->with(['user' => $this->user]);
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ namespace App\Models\Enums;
|
||||
/**
|
||||
* Class EnumBase
|
||||
* @package App\Models\Enums
|
||||
* TODO: Implement lang translations for enum labels
|
||||
*/
|
||||
class EnumBase
|
||||
{
|
||||
@@ -29,4 +28,17 @@ class EnumBase
|
||||
return trans(static::$labels[$value]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the (translated) labels
|
||||
*/
|
||||
public static function labels()
|
||||
{
|
||||
$labels = [];
|
||||
foreach(static::$labels as $key => $label) {
|
||||
$labels[$key] = trans($label);
|
||||
}
|
||||
|
||||
return $labels;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,10 @@ class User extends Authenticatable
|
||||
'balance' => 'double',
|
||||
];
|
||||
|
||||
public static $rules = [
|
||||
|
||||
];
|
||||
|
||||
public function getPilotIdAttribute($value)
|
||||
{
|
||||
$length = setting('pilots.id_length');
|
||||
|
||||
@@ -10,7 +10,7 @@ use App\Models\PirepFieldValues;
|
||||
use App\Events\PirepAccepted;
|
||||
use App\Events\PirepFiled;
|
||||
use App\Events\PirepRejected;
|
||||
use App\Events\UserStateChanged;
|
||||
use App\Events\UserStatsChanged;
|
||||
|
||||
use App\Repositories\PirepRepository;
|
||||
use Log;
|
||||
@@ -202,6 +202,6 @@ class PIREPService extends BaseService
|
||||
$pilot->last_pirep_id = $pirep->id;
|
||||
$pilot->save();
|
||||
|
||||
event(new UserStateChanged($pilot));
|
||||
event(new UserStatsChanged($pilot));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,23 +2,20 @@
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Events\UserRegistered;
|
||||
use App\Facades\Utils;
|
||||
use App\Models\Enums\PilotState;
|
||||
use App\Models\User;
|
||||
use App\Models\Rank;
|
||||
use App\Models\Role;
|
||||
|
||||
use App\Events\UserRegistered;
|
||||
use App\Events\UserStateChanged;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use App\Events\UserStatsChanged;
|
||||
use App\Models\Enums\PilotState;
|
||||
|
||||
class UserService extends BaseService
|
||||
{
|
||||
|
||||
/**
|
||||
* Register a pilot
|
||||
* Register a pilot. Also attaches the initial roles
|
||||
* required, and then triggers the UserRegistered event
|
||||
* @param User $user
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -37,7 +34,7 @@ class UserService extends BaseService
|
||||
$role = Role::where('name', 'user')->first();
|
||||
$user->attachRole($role);
|
||||
|
||||
# Let's check their rank
|
||||
# Let's check their rank and where they should start
|
||||
$this->calculatePilotRank($user);
|
||||
|
||||
$user->refresh();
|
||||
@@ -47,35 +44,76 @@ class UserService extends BaseService
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the user's state. PENDING to ACCEPTED, etc
|
||||
* Send out an email
|
||||
* @param User $user
|
||||
* @param $old_state
|
||||
* @return User
|
||||
*/
|
||||
public function changeUserState(User $user, $old_state): User
|
||||
{
|
||||
if($user->state === $old_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info('User ' . $user->pilot_id . ' state changing from '
|
||||
. PilotState::label($old_state) . ' to '
|
||||
. PilotState::label($user->state));
|
||||
|
||||
event(new UserStateChanged($user, $old_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the number of flights a user has. Triggers
|
||||
* UserStatsChanged event
|
||||
* @param User $user
|
||||
* @param int $count
|
||||
* @return User
|
||||
*/
|
||||
public function adjustFlightCount(User $user, int $count): User
|
||||
{
|
||||
$user->refresh();
|
||||
$old_value = $user->flights;
|
||||
$user->flights += $count;
|
||||
$user->save();
|
||||
|
||||
event(new UserStateChanged($user));
|
||||
event(new UserStatsChanged($user, 'flights', $old_value));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a user's flight times
|
||||
* @param User $user
|
||||
* @param int $minutes
|
||||
* @return User
|
||||
*/
|
||||
public function adjustFlightTime(User $user, int $minutes): User
|
||||
{
|
||||
$user->refresh();
|
||||
$user->flight_time += $minutes;
|
||||
$user->save();
|
||||
|
||||
event(new UserStateChanged($user));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See if a pilot's rank has change. Triggers the UserStatsChanged event
|
||||
* @param User $user
|
||||
* @return User
|
||||
*/
|
||||
public function calculatePilotRank(User $user): User
|
||||
{
|
||||
$user->refresh();
|
||||
$old_rank = $user->rank;
|
||||
$original_rank_id = $user->rank_id;
|
||||
$pilot_hours = Utils::minutesToHours($user->flight_time);
|
||||
|
||||
# TODO: Cache
|
||||
$ranks = Rank::where('auto_promote', true)->orderBy('hours', 'asc')->get();
|
||||
$ranks = Rank::where('auto_promote', true)
|
||||
->orderBy('hours', 'asc')->get();
|
||||
|
||||
foreach ($ranks as $rank) {
|
||||
if($rank->hours > $pilot_hours) {
|
||||
@@ -85,10 +123,23 @@ class UserService extends BaseService
|
||||
}
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
event(new UserStateChanged($user));
|
||||
// Only trigger the event/update if there's been a change
|
||||
if($user->rank_id !== $original_rank_id) {
|
||||
$user->save();
|
||||
$user->refresh();
|
||||
event(new UserStatsChanged($user, 'rank', $old_rank));
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recount/update all of the stats for a user
|
||||
* @param User $user
|
||||
* @return User
|
||||
*/
|
||||
public function recalculateStats(User $user): User
|
||||
{
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +50,9 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6">
|
||||
{!! Form::label('active', 'Active:') !!}
|
||||
{!! Form::label('state', 'State:') !!}
|
||||
<label class="checkbox-inline">
|
||||
{!! Form::hidden('active', 0, false) !!}
|
||||
{!! Form::checkbox('active', 1, null) !!}
|
||||
{!! Form::select('state', PilotState::labels(), null, ['class' => 'form-control select2']) !!}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@section('title', 'Users')
|
||||
@section('actions')
|
||||
<li><a href="{!! route('admin.users.index') !!}?search=state:0">
|
||||
<i class="ti-plus"></i>{!! PilotState::label(PilotState::PENDING) !!}</a>
|
||||
<i class="ti-user"></i>{!! PilotState::label(PilotState::PENDING) !!}</a>
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
You will be notified as soon as your account is approved!
|
||||
|
||||
Thanks,<br>
|
||||
{{ config('app.name') }}
|
||||
Management, {{ config('app.name') }}
|
||||
@endcomponent
|
||||
|
||||
@@ -8,5 +8,5 @@ Visit your account now!
|
||||
@endcomponent
|
||||
|
||||
Thanks,<br>
|
||||
{{ config('app.name') }}
|
||||
Management, {{ config('app.name') }}
|
||||
@endcomponent
|
||||
|
||||
9
resources/views/emails/user/rejected.blade.php
Normal file
9
resources/views/emails/user/rejected.blade.php
Normal file
@@ -0,0 +1,9 @@
|
||||
@component('mail::message')
|
||||
# Hi {!! $user->name !!},
|
||||
|
||||
Your registration to our airline was denied. Please contact
|
||||
an administrator with any questions you may have.
|
||||
|
||||
Thanks,<br>
|
||||
Management, {{ config('app.name') }}
|
||||
@endcomponent
|
||||
Reference in New Issue
Block a user