Fixes and cleanup for user pending/registration calls

This commit is contained in:
Nabeel Shahzad
2017-12-22 16:32:21 -06:00
parent 81ac281d9f
commit babdca627e
16 changed files with 237 additions and 60 deletions

View File

@@ -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;
}
}

View 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;
}
}

View File

@@ -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);

View File

@@ -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)
{
}
}
}

View File

@@ -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]);
}
}

View File

@@ -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
View 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]);
}
}

View File

@@ -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;
}
}

View File

@@ -57,6 +57,10 @@ class User extends Authenticatable
'balance' => 'double',
];
public static $rules = [
];
public function getPilotIdAttribute($value)
{
$length = setting('pilots.id_length');

View File

@@ -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));
}
}

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -8,5 +8,5 @@ Visit your account now!
@endcomponent
Thanks,<br>
{{ config('app.name') }}
Management, {{ config('app.name') }}
@endcomponent

View 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