forked from miguel456/rbrecruiter
Beta version
This commit is too large to list all changes.
This commit is contained in:
@@ -15,6 +15,8 @@ class Application extends Model
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\User', 'applicantUserID', 'id');
|
||||
@@ -35,6 +37,12 @@ class Application extends Model
|
||||
return $this->belongsToMany('App\Vote', 'votes_has_application');
|
||||
}
|
||||
|
||||
|
||||
public function comments()
|
||||
{
|
||||
return $this->hasMany('App\Comment', 'applicationID', 'id');
|
||||
}
|
||||
|
||||
public function setStatus($status)
|
||||
{
|
||||
return $this->update([
|
||||
|
@@ -16,6 +16,7 @@ class Appointment extends Model
|
||||
|
||||
public function application()
|
||||
{
|
||||
// FIXME: Possible bug here, where laravel looks for the wrong column in the applications table.
|
||||
return $this->belongsTo('App\Application', 'id', 'applicationID');
|
||||
}
|
||||
|
||||
|
25
app/Ban.php
Normal file
25
app/Ban.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Ban extends Model
|
||||
{
|
||||
|
||||
public $fillable = [
|
||||
|
||||
'userID',
|
||||
'reason',
|
||||
'bannedUntil',
|
||||
'userAgent',
|
||||
'authorUserID'
|
||||
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\User', 'userID', 'id');
|
||||
}
|
||||
|
||||
}
|
26
app/Comment.php
Normal file
26
app/Comment.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Comment extends Model
|
||||
{
|
||||
|
||||
protected $fillable = [
|
||||
'authorID',
|
||||
'applicationID',
|
||||
'text'
|
||||
];
|
||||
|
||||
public function application()
|
||||
{
|
||||
return $this->belongsTo('App\Application', 'applicationID', 'id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\User', 'authorID', 'id');
|
||||
}
|
||||
|
||||
}
|
@@ -96,6 +96,9 @@ class CountVotes extends Command
|
||||
$this->info('✓ Dispatched promotion event for applicant ' . $application->user->name);
|
||||
if (!$this->option('dryrun'))
|
||||
{
|
||||
$application->response->vacancy->vacancyCount -= 1;
|
||||
$application->response->vacancy->save();
|
||||
|
||||
event(new ApplicationApprovedEvent(Application::find($application->id)));
|
||||
}
|
||||
else
|
||||
|
@@ -4,6 +4,7 @@ namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use App\Jobs\CleanBans;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
@@ -27,7 +28,11 @@ class Kernel extends ConsoleKernel
|
||||
// $schedule->command('inspire')->hourly();
|
||||
|
||||
$schedule->command('vote:evaluate')
|
||||
->everyFiveMinutes();
|
||||
->daily();
|
||||
// Production value: Every day
|
||||
|
||||
$schedule->job(new CleanBans)
|
||||
->daily();
|
||||
// Production value: Every day
|
||||
}
|
||||
|
||||
|
42
app/CustomFacades/IP.php
Normal file
42
app/CustomFacades/IP.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\CustomFacades;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class IP
|
||||
{
|
||||
|
||||
/**
|
||||
* Looks up information on a specified IP address. Caches results automatically.
|
||||
* @param string $IP IP address to lookup
|
||||
* @return object
|
||||
*/
|
||||
public function lookup(string $IP): object
|
||||
{
|
||||
|
||||
if (empty($IP))
|
||||
{
|
||||
throw new LogicException(__METHOD__ . 'is missing parameter IP!');
|
||||
}
|
||||
|
||||
$params = [
|
||||
'apiKey' => config('general.keys.ipapi.apikey'),
|
||||
'ip' => $IP
|
||||
];
|
||||
|
||||
// TODO: Maybe unwrap this? Methods are chained here
|
||||
|
||||
return json_decode(Cache::remember($IP, 3600, function() use ($IP)
|
||||
{
|
||||
return Http::get(config('general.urls.ipapi.ipcheck'), [
|
||||
'apiKey' => config('general.keys.ipapi.apikey'),
|
||||
'ip' => $IP
|
||||
])->body();
|
||||
}));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
36
app/Events/NewApplicationEvent.php
Normal file
36
app/Events/NewApplicationEvent.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class NewApplicationEvent
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
}
|
36
app/Events/UserBannedEvent.php
Normal file
36
app/Events/UserBannedEvent.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
use App\User;
|
||||
use App\Ban;
|
||||
|
||||
class UserBannedEvent
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
|
||||
public $user;
|
||||
|
||||
public $ban;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user, Ban $ban)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->ban = $ban;
|
||||
}
|
||||
|
||||
}
|
13
app/Facades/IP.php
Normal file
13
app/Facades/IP.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class IP extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'ipInformationFacade';
|
||||
}
|
||||
}
|
13
app/Facades/UUID.php
Normal file
13
app/Facades/UUID.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class UUID extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'uuidConversionFacade';
|
||||
}
|
||||
}
|
@@ -3,13 +3,20 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Application;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Response;
|
||||
use App\Vacancy;
|
||||
use App\User;
|
||||
|
||||
use App\Events\ApplicationDeniedEvent;
|
||||
use App\Notifications\NewApplicant;
|
||||
use App\Notifications\ApplicationMoved;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ApplicationController extends Controller
|
||||
{
|
||||
@@ -21,15 +28,15 @@ class ApplicationController extends Controller
|
||||
{
|
||||
if ($vote->userID == Auth::user()->id)
|
||||
{
|
||||
Log::debug('Match');
|
||||
$allvotes->push($vote);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $allvotes->count() == 1;
|
||||
return ($allvotes->count() == 1) ? false : true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function showUserApps()
|
||||
{
|
||||
|
||||
@@ -37,16 +44,22 @@ class ApplicationController extends Controller
|
||||
->with('applications', Auth::user()->applications);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function showUserApp(Request $request, $applicationID)
|
||||
{
|
||||
$application = Application::find($applicationID);
|
||||
|
||||
$this->authorize('view', $application);
|
||||
|
||||
if (!is_null($application))
|
||||
{
|
||||
return view('dashboard.user.viewapp')
|
||||
->with(
|
||||
[
|
||||
'application' => $application,
|
||||
'comments' => $application->comments,
|
||||
'structuredResponses' => json_decode($application->response->responseData, true),
|
||||
'formStructure' => $application->response->form,
|
||||
'vacancy' => $application->response->vacancy,
|
||||
@@ -63,6 +76,8 @@ class ApplicationController extends Controller
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function showAllPendingApps()
|
||||
{
|
||||
return view('dashboard.appmanagement.outstandingapps')
|
||||
@@ -70,6 +85,9 @@ class ApplicationController extends Controller
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function showPendingInterview()
|
||||
{
|
||||
$applications = Application::with('appointment', 'user')->get();
|
||||
@@ -109,6 +127,8 @@ class ApplicationController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function showPeerReview()
|
||||
{
|
||||
return view('dashboard.appmanagement.peerreview')
|
||||
@@ -116,11 +136,16 @@ class ApplicationController extends Controller
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function renderApplicationForm(Request $request, $vacancySlug)
|
||||
{
|
||||
// FIXME: Get rid of references to first(), this is a wonky query
|
||||
$vacancyWithForm = Vacancy::with('forms')->where('vacancySlug', $vacancySlug)->get();
|
||||
|
||||
if (!$vacancyWithForm->isEmpty())
|
||||
$firstVacancy = $vacancyWithForm->first();
|
||||
|
||||
if (!$vacancyWithForm->isEmpty() && $firstVacancy->vacancyCount !== 0 && $firstVacancy->vacancyStatus == 'OPEN')
|
||||
{
|
||||
|
||||
return view('dashboard.application-rendering.apply')
|
||||
@@ -133,15 +158,25 @@ class ApplicationController extends Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
abort(404, 'We\'re ssssorry, but the application form you\'re looking for could not be found.');
|
||||
abort(404, 'The application you\'re looking for could not be found or it is currently unavailable.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function saveApplicationAnswers(Request $request, $vacancySlug)
|
||||
{
|
||||
$vacancy = Vacancy::with('forms')->where('vacancySlug', $vacancySlug)->get();
|
||||
|
||||
if ($vacancy->first()->vacancyCount == 0 || $vacancy->first()->vacancyStatus !== 'OPEN')
|
||||
{
|
||||
|
||||
$request->session()->flash('error', 'This application is unavailable.');
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
Log::info('Processing new application!');
|
||||
|
||||
$formStructure = json_decode($vacancy->first()->forms->formStructure, true);
|
||||
@@ -179,7 +214,7 @@ class ApplicationController extends Controller
|
||||
|
||||
Log::info('Registered form response for user ' . Auth::user()->name . ' for vacancy ' . $vacancy->first()->vacancyName);
|
||||
|
||||
Application::create([
|
||||
$application = Application::create([
|
||||
'applicantUserID' => Auth::user()->id,
|
||||
'applicantFormResponseID' => $response->id,
|
||||
'applicationStatus' => 'STAGE_SUBMITTED',
|
||||
@@ -187,6 +222,14 @@ class ApplicationController extends Controller
|
||||
|
||||
Log::info('Submitted application for user ' . Auth::user()->name . ' with response ID' . $response->id);
|
||||
|
||||
foreach(User::all() as $user)
|
||||
{
|
||||
if ($user->hasRole('admin'))
|
||||
{
|
||||
$user->notify((new NewApplicant($application, $vacancy->first()))->delay(now()->addSeconds(10)));
|
||||
}
|
||||
}
|
||||
|
||||
$request->session()->flash('success', 'Thank you for your application! It will be reviewed as soon as possible.');
|
||||
return redirect()->to(route('showUserApps'));
|
||||
}
|
||||
@@ -210,15 +253,15 @@ class ApplicationController extends Controller
|
||||
{
|
||||
case 'deny':
|
||||
|
||||
Log::info('User ' . Auth::user()->name . ' has denied application ID ' . $application->id);
|
||||
$request->session()->flash('success', 'Application denied.');
|
||||
$application->setStatus('DENIED');
|
||||
event(new ApplicationDeniedEvent($application));
|
||||
break;
|
||||
|
||||
case 'interview':
|
||||
Log::info('User ' . Auth::user()->name . ' has moved application ID ' . $application->id . 'to interview stage');
|
||||
$request->session()->flash('success', 'Application moved to interview stage! (:');
|
||||
$application->setStatus('STAGE_INTERVIEW');
|
||||
|
||||
$application->user->notify(new ApplicationMoved());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@@ -7,6 +7,8 @@ use App\Http\Requests\SaveNotesRequest;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Appointment;
|
||||
use App\Notifications\ApplicationMoved;
|
||||
use App\Notifications\AppointmentScheduled;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -47,7 +49,8 @@ class AppointmentController extends Controller
|
||||
'datetime' => $appointmentDate->toDateTimeString(),
|
||||
'scheduled' => now()
|
||||
]);
|
||||
|
||||
|
||||
$app->user->notify(new AppointmentScheduled($appointment));
|
||||
$request->session()->flash('success', 'Appointment successfully scheduled @ ' . $appointmentDate->toDateTimeString());
|
||||
|
||||
}
|
||||
@@ -70,10 +73,12 @@ class AppointmentController extends Controller
|
||||
|
||||
if (!is_null($application))
|
||||
{
|
||||
// NOTE: This is a little confusing, refactor
|
||||
$application->appointment->appointmentStatus = (in_array($status, $validStatuses)) ? strtoupper($status) : 'SCHEDULED';
|
||||
$application->appointment->save();
|
||||
|
||||
$application->setStatus('STAGE_PEERAPPROVAL');
|
||||
$application->user->notify(new ApplicationMoved());
|
||||
|
||||
$request->session()->flash('success', 'Interview finished! Staff members can now vote on it.');
|
||||
}
|
||||
|
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\User;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
@@ -19,7 +21,9 @@ class LoginController extends Controller
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesUsers;
|
||||
use AuthenticatesUsers {
|
||||
attemptLogin as protected originalAttemptLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
@@ -37,4 +41,29 @@ class LoginController extends Controller
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
// We can't customise the error message, since that would imply overriding the login method, which is large.
|
||||
// Also, the user should never know that they're banned.
|
||||
public function attemptLogin(Request $request)
|
||||
{
|
||||
$user = User::where('email', $request->email)->first();
|
||||
|
||||
if ($user)
|
||||
{
|
||||
$isBanned = $user->isBanned();
|
||||
if ($isBanned)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->originalAttemptLogin($request);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->originalAttemptLogin($request);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -43,6 +43,21 @@ class RegisterController extends Controller
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
public function showRegistrationForm()
|
||||
{
|
||||
$users = User::where('originalIP', \request()->ip())->get();
|
||||
|
||||
foreach($users as $user)
|
||||
{
|
||||
if ($user && $user->isBanned())
|
||||
{
|
||||
abort(403, 'You do not have permission to access this page.');
|
||||
}
|
||||
}
|
||||
|
||||
return view('auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
@@ -78,15 +93,10 @@ class RegisterController extends Controller
|
||||
'originalIP' => request()->ip()
|
||||
]);
|
||||
|
||||
Profile::create([
|
||||
|
||||
'profileShortBio' => 'Write a one-liner about you here!',
|
||||
'profileAboutMe' => 'Tell us a bit about you.',
|
||||
'socialLinks' => '{}',
|
||||
'userID' => $user->id
|
||||
|
||||
]);
|
||||
// It's not the registration controller's concern to create a profile for the user,
|
||||
// so this code has been moved to it's respective observer, following the separation of concerns pattern.
|
||||
|
||||
$user->assignRole('user');
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
91
app/Http/Controllers/BanController.php
Normal file
91
app/Http/Controllers/BanController.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Ban;
|
||||
use App\User;
|
||||
use App\Events\UserBannedEvent;
|
||||
use App\Http\Requests\BanUserRequest;
|
||||
|
||||
class BanController extends Controller
|
||||
{
|
||||
|
||||
public function insert(BanUserRequest $request, User $user)
|
||||
{
|
||||
|
||||
if ($user->is(Auth::user()))
|
||||
{
|
||||
$request->session()->flash('error', 'You can\'t ban yourself!');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
if (is_null($user->bans))
|
||||
{
|
||||
|
||||
$reason = $request->reason;
|
||||
$duration = strtolower($request->durationOperator);
|
||||
$durationOperand = $request->durationOperand;
|
||||
|
||||
|
||||
if (!empty($duration))
|
||||
{
|
||||
$expiryDate = now();
|
||||
|
||||
switch($duration)
|
||||
{
|
||||
case 'days':
|
||||
$expiryDate->addDays($duration);
|
||||
break;
|
||||
|
||||
case 'weeks':
|
||||
$expiryDate->addWeeks($duration);
|
||||
break;
|
||||
|
||||
case 'months':
|
||||
$expiryDate->addMonths($duration);
|
||||
break;
|
||||
|
||||
case 'years':
|
||||
$expiryDate->addYears($duration);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$ban = Ban::create([
|
||||
'userID' => $user->id,
|
||||
'reason' => $request->reason,
|
||||
'bannedUntil' => $expiryDate->toDateTimeString() ?? null,
|
||||
'userAgent' => "Unknown",
|
||||
'authorUserID' => Auth::user()->id
|
||||
]);
|
||||
|
||||
event(new UserBannedEvent($user, $ban));
|
||||
$request->session()->flash('success', 'User banned successfully! Ban ID: #' . $ban->id);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$request->session()->flash('error', 'User already banned!');
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
public function delete(Request $request, User $user)
|
||||
{
|
||||
if (!is_null($user->bans))
|
||||
{
|
||||
$user->bans->delete();
|
||||
$request->session()->flash('success', 'User unbanned successfully!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$request->session()->flash('error', 'This user isn\'t banned!');
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
68
app/Http/Controllers/CommentController.php
Normal file
68
app/Http/Controllers/CommentController.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Http\Requests\NewCommentRequest;
|
||||
|
||||
use App\Comment;
|
||||
use App\Application;
|
||||
use App\Notifications\NewComment;
|
||||
use App\User;
|
||||
|
||||
class CommentController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function insert(NewCommentRequest $request, Application $application)
|
||||
{
|
||||
// Type hinting makes laravel automatically validate everything
|
||||
|
||||
$comment = Comment::create([
|
||||
'authorID' => Auth::user()->id,
|
||||
'applicationID' => $application->id,
|
||||
'text' => $request->comment
|
||||
]);
|
||||
|
||||
if ($comment)
|
||||
{
|
||||
|
||||
foreach (User::all() as $user)
|
||||
{
|
||||
if ($user->isStaffMember())
|
||||
{
|
||||
$user->notify(new NewComment($comment, $application));
|
||||
}
|
||||
}
|
||||
|
||||
$request->session()->flash('success', 'Comment posted! (:');
|
||||
}
|
||||
else
|
||||
{
|
||||
$request->session()->flash('error', 'Something went wrong while posting your comment!');
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
public function delete(Request $request, Comment $comment)
|
||||
{
|
||||
if (Auth::user()->is($comment->user) || Auth::user()->hasRole('admin'))
|
||||
{
|
||||
$comment->delete();
|
||||
$request->session()->flash('success', 'Comment deleted!');
|
||||
}
|
||||
|
||||
$request->session()->flash('error', 'You do not have permission to delete this comment!');
|
||||
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Vacancy;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
@@ -17,7 +18,13 @@ class HomeController extends Controller
|
||||
// TODO: Relationships for Applications, Users and Responses
|
||||
// Also prevent apps if user already has one in the space of 30d
|
||||
// Display apps in the relevant menus
|
||||
|
||||
$positions = DB::table('vacancies')
|
||||
->where('vacancyStatus', 'OPEN')
|
||||
->where('vacancyCount', '!=', 0)
|
||||
->get();
|
||||
|
||||
return view('home')
|
||||
->with('positions', Vacancy::where('vacancyStatus', 'OPEN')->get());
|
||||
->with('positions', $positions);
|
||||
}
|
||||
}
|
||||
|
@@ -5,15 +5,20 @@ namespace App\Http\Controllers;
|
||||
use App\Http\Requests\ProfileSave;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Profile;
|
||||
use App\User;
|
||||
use App\Facades\IP;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
public function showProfile()
|
||||
{
|
||||
|
||||
$socialMediaProfiles = json_decode(Auth::user()->profile->socialLinks, true);
|
||||
$socialLinks = Auth::user()->profile->socialLinks ?? "[]";
|
||||
$socialMediaProfiles = json_decode($socialLinks, true);
|
||||
|
||||
return view('dashboard.user.profile.userprofile')
|
||||
->with([
|
||||
@@ -26,11 +31,56 @@ class ProfileController extends Controller
|
||||
|
||||
}
|
||||
|
||||
// Route model binding
|
||||
public function showSingleProfile(Request $request, User $user)
|
||||
{
|
||||
|
||||
$socialMediaProfiles = json_decode($user->profile->socialLinks, true);
|
||||
$createdDate = Carbon::parse($user->created_at);
|
||||
|
||||
$systemRoles = Role::all()->pluck('name')->all();
|
||||
$userRoles = $user->roles->pluck('name')->all();
|
||||
|
||||
$roleList = [];
|
||||
|
||||
|
||||
foreach($systemRoles as $role)
|
||||
{
|
||||
if (in_array($role, $userRoles))
|
||||
{
|
||||
$roleList[$role] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$roleList[$role] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Auth::user()->is($user) || Auth::user()->can('profiles.view.others'))
|
||||
{
|
||||
return view('dashboard.user.profile.displayprofile')
|
||||
->with([
|
||||
'profile' => $user->profile,
|
||||
'github' => $socialMediaProfiles['links']['github'] ?? 'UpdateMe',
|
||||
'twitter' => $socialMediaProfiles['links']['twitter'] ?? 'UpdateMe',
|
||||
'insta' => $socialMediaProfiles['links']['insta'] ?? 'UpdateMe',
|
||||
'discord' => $socialMediaProfiles['links']['discord'] ?? 'UpdateMe#12345',
|
||||
'since' => $createdDate->englishMonth . " " . $createdDate->year,
|
||||
'ipInfo' => IP::lookup($user->originalIP),
|
||||
'roles' => $roleList
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
abort(403, 'You cannot view someone else\'s profile.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function saveProfile(ProfileSave $request)
|
||||
{
|
||||
// TODO: Implement profile security policy for logged in users
|
||||
|
||||
$profile = Profile::find(Auth::user()->id);
|
||||
// TODO: Switch to route model binding
|
||||
$profile = User::find(Auth::user()->id)->profile;
|
||||
$social = [];
|
||||
|
||||
if (!is_null($profile))
|
||||
@@ -57,7 +107,7 @@ class ProfileController extends Controller
|
||||
$profile->avatarPreference = $avatarPref;
|
||||
$profile->socialLinks = json_encode($social);
|
||||
|
||||
$profile->save();
|
||||
$newProfile = $profile->save();
|
||||
|
||||
$request->session()->flash('success', 'Profile settings saved successfully.');
|
||||
|
||||
|
@@ -5,23 +5,117 @@ namespace App\Http\Controllers;
|
||||
use App\Http\Requests\ChangeEmailRequest;
|
||||
use App\Http\Requests\ChangePasswordRequest;
|
||||
use App\Http\Requests\FlushSessionsRequest;
|
||||
use App\Http\Requests\DeleteUserRequest;
|
||||
use App\Http\Requests\SearchPlayerRequest;
|
||||
use App\Http\Requests\UpdateUserRequest;
|
||||
|
||||
use App\User;
|
||||
use App\Ban;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Facades\UUID;
|
||||
use App\Notifications\EmailChanged;
|
||||
use App\Notifications\ChangedPassword;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
|
||||
public function showStaffMembers()
|
||||
{
|
||||
return view('dashboard.administration.staff-members');
|
||||
|
||||
$staffRoles = [
|
||||
'reviewer',
|
||||
'hiringManager',
|
||||
'admin'
|
||||
]; // TODO: Un-hardcode this, move to config/roles.php
|
||||
|
||||
if (Auth::user()->can('admin.stafflist'))
|
||||
{
|
||||
$users = User::with('roles')->get();
|
||||
$staffMembers = collect([]);
|
||||
|
||||
foreach($users as $user)
|
||||
{
|
||||
if (empty($user->roles))
|
||||
{
|
||||
Log::debug($user->role->name);
|
||||
Log::debug('Staff list: User without role detected; Ignoring');
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach($user->roles as $role)
|
||||
{
|
||||
if (in_array($role->name, $staffRoles))
|
||||
{
|
||||
$staffMembers->push($user);
|
||||
continue 2; // Skip directly to the next user instead of comparing more roles for the current user
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view('dashboard.administration.staff-members')
|
||||
->with([
|
||||
'users' => $staffMembers
|
||||
]);
|
||||
}
|
||||
|
||||
abort(403, 'Forbidden');
|
||||
}
|
||||
|
||||
public function showPlayers()
|
||||
{
|
||||
return view('dashboard.administration.players');
|
||||
$users = User::with('roles')->get();
|
||||
$players = collect([]);
|
||||
|
||||
foreach($users as $user)
|
||||
{
|
||||
// TODO: Might be problematic if we don't check if the role is user
|
||||
if (count($user->roles) == 1)
|
||||
{
|
||||
$players->push($user);
|
||||
}
|
||||
}
|
||||
|
||||
if (Auth::user()->can('admin.userlist'))
|
||||
{
|
||||
return view('dashboard.administration.players')
|
||||
->with([
|
||||
'users' => $players,
|
||||
'bannedUserCount' => Ban::all()->count()
|
||||
]);
|
||||
}
|
||||
|
||||
abort(403, 'Forbidden');
|
||||
}
|
||||
|
||||
|
||||
public function showPlayersLike(SearchPlayerRequest $request)
|
||||
{
|
||||
$searchTerm = $request->searchTerm;
|
||||
|
||||
$matchingUsers = User::query()
|
||||
->where('name', 'LIKE', "%{$searchTerm}%")
|
||||
->orWhere('email', 'LIKE', "%{$searchTerm}%")
|
||||
->get();
|
||||
|
||||
if (!$matchingUsers->isEmpty())
|
||||
{ $request->session()->flash('success', 'There were ' . $matchingUsers->count() . ' user(s) matching your search.');
|
||||
|
||||
return view('dashboard.administration.players')
|
||||
->with([
|
||||
'users' => $matchingUsers,
|
||||
'bannedUserCount' => Ban::all()->count()
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$request->session()->flash('error', 'Your search term did not return any results.');
|
||||
return redirect(route('registeredPlayerList'));
|
||||
}
|
||||
}
|
||||
|
||||
public function showAccount()
|
||||
@@ -62,9 +156,9 @@ class UserController extends Controller
|
||||
'userID' => $user->id,
|
||||
'timestamp' => now()
|
||||
]);
|
||||
Auth::logout();
|
||||
$user->notify(new ChangedPassword());
|
||||
|
||||
// After logout, the user gets caught by the auth filter, and it automatically redirects back to the previous page
|
||||
Auth::logout();
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
@@ -84,6 +178,7 @@ class UserController extends Controller
|
||||
'userID' => $user->id,
|
||||
'timestamp' => now()
|
||||
]);
|
||||
$user->notify(new EmailChanged());
|
||||
|
||||
$request->session()->flash('success', 'Your email address has been changed!');
|
||||
}
|
||||
@@ -95,4 +190,88 @@ class UserController extends Controller
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function delete(DeleteUserRequest $request, User $user)
|
||||
{
|
||||
if ($request->confirmPrompt == 'DELETE ACCOUNT')
|
||||
{
|
||||
$user->delete();
|
||||
$request->session()->flash('success','User deleted successfully. PII has been erased.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$request->session()->flash('error', 'Wrong confirmation text! Try again.');
|
||||
}
|
||||
|
||||
|
||||
return redirect()->route('registeredPlayerList');
|
||||
}
|
||||
|
||||
public function update(UpdateUserRequest $request, User $user)
|
||||
{
|
||||
|
||||
// Mass update would not be possible here without extra code, making route model binding useless
|
||||
$user->email = $request->email;
|
||||
$user->name = $request->name;
|
||||
$user->uuid = $request->uuid;
|
||||
|
||||
$existingRoles = Role::all()
|
||||
->pluck('name')
|
||||
->all();
|
||||
|
||||
$roleDiff = array_diff($existingRoles, $request->roles);
|
||||
|
||||
// Adds roles that were selected. Removes roles that aren't selected if the user has them.
|
||||
foreach($roleDiff as $deselectedRole)
|
||||
{
|
||||
if ($user->hasRole($deselectedRole) && $deselectedRole !== 'user')
|
||||
{
|
||||
$user->removeRole($deselectedRole);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($request->roles as $role)
|
||||
{
|
||||
if (!$user->hasRole($role))
|
||||
{
|
||||
$user->assignRole($role);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$user->save();
|
||||
$request->session()->flash('success', 'User updated successfully!');
|
||||
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
public function terminate(Request $request, User $user)
|
||||
{
|
||||
$this->authorize('terminate', Auth::user());
|
||||
|
||||
if (!$user->isStaffMember() || $user->is(Auth::user()))
|
||||
{
|
||||
$request->session()->flash('error', 'You cannot terminate this user.');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
foreach ($user->roles as $role)
|
||||
{
|
||||
if ($role->name == 'user')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$user->removeRole($role->name);
|
||||
}
|
||||
|
||||
Log::info('User ' . $user->name . ' has just been demoted.');
|
||||
$request->session()->flash('success', 'User terminated successfully.');
|
||||
|
||||
//TODO: Dispatch event
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
@@ -2,9 +2,12 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Form;
|
||||
use App\Http\Requests\VacancyRequest;
|
||||
use App\Vacancy;
|
||||
use App\User;
|
||||
use App\Form;
|
||||
|
||||
use App\Notifications\VacancyClosed;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@@ -68,6 +71,13 @@ class VacancyController extends Controller
|
||||
$vacancy->close();
|
||||
$message = "Position successfully closed!";
|
||||
|
||||
foreach(User::all() as $user)
|
||||
{
|
||||
if ($user->isStaffMember())
|
||||
{
|
||||
$user->notify(new VacancyClosed($vacancy));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@@ -63,6 +63,7 @@ class Kernel extends HttpKernel
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'eligibility' => \App\Http\Middleware\ApplicationEligibility::class,
|
||||
'usernameUUID' => \App\Http\Middleware\UsernameUUID::class
|
||||
'usernameUUID' => \App\Http\Middleware\UsernameUUID::class,
|
||||
'forcelogout' => \App\Http\Middleware\ForceLogoutMiddleware::class
|
||||
];
|
||||
}
|
||||
|
39
app/Http/Middleware/Bancheck.php
Normal file
39
app/Http/Middleware/Bancheck.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\View;
|
||||
|
||||
class Bancheck
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$userIP = $request->ip();
|
||||
$anonymousUser = User::where('ipAddress', $userIP)->get();
|
||||
|
||||
|
||||
if (Auth::check() && Auth::user()->isBanned())
|
||||
{
|
||||
View::share('isBanned', true);
|
||||
}
|
||||
elseif(!$anonymousUser->isEmpty() && User::find($anonymousUser->id)->isBanned())
|
||||
{
|
||||
View::share('isBanned', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
View::share('isBanned', false);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
29
app/Http/Middleware/ForceLogoutMiddleware.php
Normal file
29
app/Http/Middleware/ForceLogoutMiddleware.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ForceLogoutMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (Auth::user()->isBanned())
|
||||
{
|
||||
Auth::logout();
|
||||
|
||||
$request->session()->flash('error', 'Error: Your session has been forcefully terminated. Please try again in a few days.');
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
34
app/Http/Requests/BanUserRequest.php
Normal file
34
app/Http/Requests/BanUserRequest.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
|
||||
class BanUserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::user()->hasRole('admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'reason' => 'required|string',
|
||||
'durationOperand' => 'nullable|integer',
|
||||
'durationOperator' => 'nullable|string'
|
||||
];
|
||||
}
|
||||
}
|
31
app/Http/Requests/DeleteUserRequest.php
Normal file
31
app/Http/Requests/DeleteUserRequest.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class DeleteUserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::user()->hasRole('admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'confirmPrompt' => 'required|string'
|
||||
];
|
||||
}
|
||||
}
|
33
app/Http/Requests/NewCommentRequest.php
Normal file
33
app/Http/Requests/NewCommentRequest.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
|
||||
class NewCommentRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// TODO: Switch to permission checking when there are comment permission nodes
|
||||
return Auth::user()->hasAnyRole('reviewer', 'hiringManager', 'admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'comment' => 'required|string|max:600|min:20'
|
||||
];
|
||||
}
|
||||
}
|
31
app/Http/Requests/SearchPlayerRequest.php
Normal file
31
app/Http/Requests/SearchPlayerRequest.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class SearchPlayerRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::user()->can('admin.userlist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'searchTerm' => 'required|string|max:17' // max user char limit set by Mojang
|
||||
];
|
||||
}
|
||||
}
|
34
app/Http/Requests/UpdateUserRequest.php
Normal file
34
app/Http/Requests/UpdateUserRequest.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UpdateUserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::user()->hasRole('admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email',
|
||||
'name' => 'required|string',
|
||||
'uuid' => 'required|max:32|min:32',
|
||||
'roles' => 'required_without_all'
|
||||
];
|
||||
}
|
||||
}
|
56
app/Jobs/CleanBans.php
Normal file
56
app/Jobs/CleanBans.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Ban;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class CleanBans implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
|
||||
public $bans;
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
Log::debug('Running automatic ban cleaner...');
|
||||
$bans = Ban::all();
|
||||
|
||||
if (!is_null($bans))
|
||||
{
|
||||
foreach($this->bans as $ban)
|
||||
{
|
||||
$bannedUntil = Carbon::parse($ban->bannedUntil);
|
||||
|
||||
if ($bannedUntil->equalTo(now()))
|
||||
{
|
||||
Log::debug('Deleted ban ' . $ban->id . ' belonging to ' . $ban->user->name);
|
||||
$ban->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Events\ApplicationDeniedEvent;
|
||||
use App\Notifications\ApplicationDenied;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -30,6 +31,7 @@ class DenyUser
|
||||
$event->application->setStatus('DENIED');
|
||||
Log::info('User ' . $event->application->user->name . ' just had their application denied.');
|
||||
|
||||
// Also dispatch other notifications
|
||||
$event->application->user->notify(new ApplicationDenied($event->application));
|
||||
|
||||
}
|
||||
}
|
||||
|
46
app/Listeners/OnUserBanned.php
Normal file
46
app/Listeners/OnUserBanned.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Events\UserBannedEvent;
|
||||
use App\Notifications\UserBanned;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\User;
|
||||
|
||||
class OnUserBanned
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param object $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(UserBannedEvent $event)
|
||||
{
|
||||
|
||||
Log::warning("User " . $event->user->name . " has just been banned from the site!");
|
||||
|
||||
foreach(User::all() as $user)
|
||||
{
|
||||
if ($user->isStaffMember())
|
||||
{
|
||||
$user->notify((new UserBanned($event->user, $event->ban))->delay(now()->addSeconds(10)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -7,6 +7,9 @@ use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
|
||||
use App\User;
|
||||
use App\Notifications\NewUser;
|
||||
|
||||
class OnUserRegistration
|
||||
{
|
||||
/**
|
||||
@@ -29,5 +32,13 @@ class OnUserRegistration
|
||||
{
|
||||
// TODO: Send push notification to online admins via browser (w/ pusher)
|
||||
Log::info('User ' . $event->user->name . ' has just registered for an account.');
|
||||
|
||||
foreach(User::all() as $user)
|
||||
{
|
||||
if ($user->hasRole('admin'))
|
||||
{
|
||||
$user->notify(new NewUser($event->user));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ namespace App\Listeners;
|
||||
|
||||
use App\Events\ApplicationApprovedEvent;
|
||||
use App\StaffProfile;
|
||||
use App\Notifications\ApplicationApproved;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -37,11 +38,15 @@ class PromoteUser
|
||||
'memberNotes' => 'Approved by staff members. Welcome them to the team!'
|
||||
]);
|
||||
|
||||
$event->application->user->assignRole('reviewer');
|
||||
|
||||
Log::info('User ' . $event->application->user->name . ' has just been promoted!', [
|
||||
'newRank' => $event->application->response->vacancy->permissionGroupName,
|
||||
'staffProfileID' => $staffProfile->id
|
||||
]);
|
||||
// TODO: Dispatch alert email and notifications for the user and staff members
|
||||
|
||||
$event->application->user->notify(new ApplicationApproved($event->application));
|
||||
// note: Also notify staff
|
||||
// TODO: Also assign new app role based on the permission group name
|
||||
|
||||
}
|
||||
|
93
app/Notifications/ApplicationApproved.php
Normal file
93
app/Notifications/ApplicationApproved.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use App\Application;
|
||||
|
||||
class ApplicationApproved extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
public $application;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Application $application)
|
||||
{
|
||||
$this->application = $application;
|
||||
}
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail', 'slack'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - ' . $this->application->response->vacancy->vacancyName . ' application approved')
|
||||
->line('<br />')
|
||||
->line('Congratulations! Our Staff team has reviewed your application today, and your application has been approved.')
|
||||
->line('You have just received the Reviewer role, which allows you to view and vote on other applications.')
|
||||
->line('Your in-game rank should be updated network-wide in the next few minutes, allowing you to perform staff duties.')
|
||||
->line('Please join a voice channel when possible for your training meeting, if this has been mentioned by your interviewer.')
|
||||
->line('<br />')
|
||||
->line('Good luck and welcome aboard!')
|
||||
->action('Sign in', url(route('login')))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
public function toSlack($notifiable)
|
||||
{
|
||||
|
||||
$url = route('showSingleProfile', ['user' => $notifiable->id]);
|
||||
$roles = implode(', ', $notifiable->roles->pluck('name')->all());
|
||||
|
||||
return (new SlackMessage)
|
||||
->success()
|
||||
->content('A user has been approved on the team. Welcome aboard!')
|
||||
->attachment(function($attachment) use ($notifiable, $url, $roles){
|
||||
$attachment->title('New staff member')
|
||||
->fields([
|
||||
'Name' => $notifiable->name,
|
||||
'Email' => $notifiable->email,
|
||||
'Roles' => $roles
|
||||
])
|
||||
->action('View profile', $url);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
85
app/Notifications/ApplicationDenied.php
Normal file
85
app/Notifications/ApplicationDenied.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use App\Application;
|
||||
|
||||
class ApplicationDenied extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
|
||||
public $application;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Application $application)
|
||||
{
|
||||
$this->application = $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail', 'slack'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - ' . $this->application->response->vacancy->vacancyName . ' application denied')
|
||||
->line('Your most recent application has been denied.')
|
||||
->line('Our review team denies applications for several reasons, including poor answers.')
|
||||
->line('Please review your application and try again in 30 days.')
|
||||
->action('Review application', url(route('showUserApp', ['id' => $this->application->id])))
|
||||
->line('Better luck next time!');
|
||||
}
|
||||
|
||||
|
||||
public function toSlack($notifiable)
|
||||
{
|
||||
$notifiableName = $notifiable->name;
|
||||
|
||||
return (new SlackMessage)
|
||||
->error()
|
||||
->content('An application has just been denied.')
|
||||
->attachment(function($attachment) use ($notifiableName){
|
||||
$attachment->title('Application denied!')
|
||||
->content($notifiableName . '\'s application has just been denied. They can try again in 30 days.');
|
||||
});
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
64
app/Notifications/ApplicationMoved.php
Normal file
64
app/Notifications/ApplicationMoved.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class ApplicationMoved extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - Application Updated')
|
||||
->line('Your most recent application has been moved up a stage.')
|
||||
->line('This means our team has reviewed it and an interview will be scheduled ASAP.')
|
||||
->action('Sign in', url(route('login')))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
64
app/Notifications/AppointmentFinished.php
Normal file
64
app/Notifications/AppointmentFinished.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class AppointmentFinished extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - Appointment completed')
|
||||
->line('Your appointment has been marked as completed!')
|
||||
->line('Please allow an additional day for your application to be fully processed.')
|
||||
->action('View applications', url(route('showUserApps')))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
71
app/Notifications/AppointmentScheduled.php
Normal file
71
app/Notifications/AppointmentScheduled.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
use App\Appointment;
|
||||
|
||||
class AppointmentScheduled extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
|
||||
protected $appointment;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Appointment $appointment)
|
||||
{
|
||||
$this->appointment = $appointment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - Interview scheduled')
|
||||
->line('A voice interview has been scheduled for you @ ' . $this->appointment->appointmentDate . '.')
|
||||
->line('With the following details: ' . $this->appointment->appointmentDescription)
|
||||
->line('This meeting will take place @ ' . $this->appointment->appointmentLocation . '. You will receive an email soon with details on how to join this meeting.')
|
||||
->line('You are expected to show up at least 5 minutes before the scheduled date.')
|
||||
->action('Sign in', url(route('login')))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
64
app/Notifications/ChangedPassword.php
Normal file
64
app/Notifications/ChangedPassword.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class ChangedPassword extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - Account password changed')
|
||||
->line('The password for the account registered to this email address has just been changed.')
|
||||
->line('If this was not you, please contact an administrator immediately.')
|
||||
->action('Sign in', url(route('login')))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
63
app/Notifications/EmailChanged.php
Normal file
63
app/Notifications/EmailChanged.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class EmailChanged extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - Email address changed')
|
||||
->line('The email address for your account has just been updated, either by you or an administrator.')
|
||||
->action('Sign in', url(route('login')))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
98
app/Notifications/NewApplicant.php
Normal file
98
app/Notifications/NewApplicant.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use App\Application;
|
||||
use App\Vacancy;
|
||||
|
||||
class NewApplicant extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
|
||||
protected $application;
|
||||
|
||||
|
||||
protected $vacancy;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Application $application, Vacancy $vacancy)
|
||||
{
|
||||
$this->application = $application;
|
||||
$this->vacancy = $vacancy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['slack'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - New application')
|
||||
->line('Someone has just applied for a position. Check it out!')
|
||||
->line('You are receiving this because you\'re a staff member at ' . config('app.name') . '.')
|
||||
->action('View Application', url(route('showUserApp', ['id' => $this->application->id])))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
|
||||
public function toSlack($notifiable)
|
||||
{
|
||||
|
||||
$vacancyDetails = [];
|
||||
$vacancyDetails['name'] = $this->vacancy->vacancyName;
|
||||
$vacancyDetails['slots'] = $this->vacancy->vacancyCount;
|
||||
|
||||
$url = route('showUserApp', ['id' => $this->application->id]);
|
||||
$applicant = $this->application->user->name;
|
||||
|
||||
return (new SlackMessage)
|
||||
->success()
|
||||
->content('Notice: New application coming through. Please review as soon as possible.')
|
||||
->attachment(function($attachment) use ($vacancyDetails, $url, $applicant){
|
||||
$attachment->title('Application details')
|
||||
->fields([
|
||||
'Applied for' => $vacancyDetails['name'],
|
||||
'Avaiable positions' => $vacancyDetails['slots'],
|
||||
'Applicant' => $applicant
|
||||
])
|
||||
->action('Review application', $url);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
69
app/Notifications/NewComment.php
Normal file
69
app/Notifications/NewComment.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use App\Comment;
|
||||
use App\Application;
|
||||
|
||||
class NewComment extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
|
||||
protected $application;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Comment $comment, Application $application)
|
||||
{
|
||||
$this->application = $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - New comment')
|
||||
->line('Someone has just posted a new comment on an application you follow.')
|
||||
->line('You\'re receiving this email because you\'ve voted/commented on this application.')
|
||||
->action('Check it out', url(route('showUserApp', ['id' => $this->application->id])))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
100
app/Notifications/NewUser.php
Normal file
100
app/Notifications/NewUser.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
|
||||
use App\User;
|
||||
use App\Facades\UUID;
|
||||
|
||||
class NewUser extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ($notifiable->isStaffMember())
|
||||
? ['slack', 'mail']
|
||||
: ['mail'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - New user')
|
||||
->line($this->user->name . ' has just registered to our site.')
|
||||
->line('You are receiving this email because you opted to receive new user notifications.')
|
||||
->action('View profile', url(route('showSingleProfile', ['user' => $this->user->id])))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
public function toSlack($notifiable)
|
||||
{
|
||||
$user = [];
|
||||
|
||||
$user['name'] = $this->user->name;
|
||||
$user['email'] = $this->user->email;
|
||||
$user['username'] = UUID::toUsername($this->user->uuid);
|
||||
|
||||
$date = \Carbon\Carbon::parse($this->user->created_at);
|
||||
$user['created_at'] = $date->englishMonth . ' ' . $date->day . ' ' . $date->year;
|
||||
|
||||
return (new SlackMessage)
|
||||
->success()
|
||||
->content('A new user has signed up!')
|
||||
->attachment(function($attachment) use ($user){
|
||||
|
||||
$attachment->title('User details')
|
||||
->fields([
|
||||
'Email address' => $user['email'],
|
||||
'Name' => $user['name'],
|
||||
'Minecraft Username' => $user['username'],
|
||||
'Registration date' => $user['created_at']
|
||||
]);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
71
app/Notifications/UserBanned.php
Normal file
71
app/Notifications/UserBanned.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
use App\User;
|
||||
use App\Ban;
|
||||
|
||||
class UserBanned extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
protected $user;
|
||||
|
||||
protected $ban;
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user, Ban $ban)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->ban = $ban;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail']; // slack
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->line('Hello, ')
|
||||
->line('Moderators have just banned user ' . $this->user->name . ' for ' . $this->ban->reason)
|
||||
->line('This ban will remain in effect until ' . $this->ban->bannedUntil . '.')
|
||||
->action('View profile', url(route('showSingleProfile', ['user' => $this->user->id])))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
68
app/Notifications/VacancyClosed.php
Normal file
68
app/Notifications/VacancyClosed.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
use App\Vacancy;
|
||||
|
||||
class VacancyClosed extends Notification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
protected $vacancy;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Vacancy $vacancy)
|
||||
{
|
||||
$this->vacancy = $vacancy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->from(config('notification.sender.address'), config('notification.sender.name'))
|
||||
->subject(config('app.name') . ' - Vacancy Closed')
|
||||
->line('The vacancy ' . $this->vacancy->vacancyName . ', with ' . $this->vacancy->vacancyCount . ' remaining slots, has just been closed.')
|
||||
->line('Please be aware that this position may be deleted/reopened any time.')
|
||||
->action('View positions', url(route('showPositions')))
|
||||
->line('Thank you!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
116
app/Observers/UserObserver.php
Normal file
116
app/Observers/UserObserver.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Profile;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UserObserver
|
||||
{
|
||||
/**
|
||||
* Handle the user "created" event.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function created(User $user)
|
||||
{
|
||||
Profile::create([
|
||||
|
||||
'profileShortBio' => 'Write a one-liner about you here!',
|
||||
'profileAboutMe' => 'Tell us a bit about you.',
|
||||
'socialLinks' => '{}',
|
||||
'userID' => $user->id
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the user "updated" event.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function updated(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function deleting(User $user)
|
||||
{
|
||||
$user->profile()->delete();
|
||||
Log::debug('Referential integrity cleanup: Deleted profile!');
|
||||
$applications = $user->applications;
|
||||
|
||||
if (!$applications->isEmpty())
|
||||
{
|
||||
Log::debug('RIC: Now trying to delete applications and responses...');
|
||||
foreach($applications as $application)
|
||||
{
|
||||
$application->response()->delete();
|
||||
$votes = $application->votes;
|
||||
|
||||
foreach ($votes as $vote)
|
||||
{
|
||||
Log::debug('RIC: Deleting and detaching vote ' . $vote->id);
|
||||
$vote->application()->detach($application->id);
|
||||
$vote->delete();
|
||||
}
|
||||
|
||||
if (!is_null($application->appointment))
|
||||
{
|
||||
Log::debug('RIC: Deleting appointment!');
|
||||
$application->appointment()->delete();
|
||||
}
|
||||
|
||||
if (!$application->comments->isEmpty())
|
||||
{
|
||||
Log::debug('RIC: Deleting comments!');
|
||||
foreach($application->comments as $comment)
|
||||
{
|
||||
$comment->delete();
|
||||
}
|
||||
}
|
||||
Log::debug('RIC: Deleting application ' . $application->id);
|
||||
$application->delete();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Log::debug('RIC: Cleanup done!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the user "deleted" event.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function deleted(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the user "restored" event.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function restored(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the user "force deleted" event.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function forceDeleted(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
33
app/Policies/ApplicationPolicy.php
Normal file
33
app/Policies/ApplicationPolicy.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Application;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
use App\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class ApplicationPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Create a new policy instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function view(User $user, Application $application)
|
||||
{
|
||||
if ($user->is($application->user) && $user->can('applications.view.own') || $user->can('applications.view.all'))
|
||||
{
|
||||
return Response::allow();
|
||||
}
|
||||
|
||||
return Response::deny('You are not authorised to view this application');
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Profile;
|
||||
use App\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
@@ -16,6 +17,11 @@ class ProfilePolicy
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
public function edit(User $user, Profile $profile)
|
||||
{
|
||||
return $user->is($profile->user);
|
||||
}
|
||||
}
|
||||
|
41
app/Policies/UserPolicy.php
Normal file
41
app/Policies/UserPolicy.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Create a new policy instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function edit(User $authUser, User $user)
|
||||
{
|
||||
return $authUser->is($user) || $authUser->hasRole('admin');
|
||||
}
|
||||
|
||||
public function viewStaff(User $user)
|
||||
{
|
||||
return $user->can('admin.stafflist');
|
||||
}
|
||||
|
||||
public function viewPlayers(User $user)
|
||||
{
|
||||
return $user->can('admin.userlist');
|
||||
}
|
||||
|
||||
public function terminate(User $authUser)
|
||||
{
|
||||
return $authUser->hasRole('admin');
|
||||
}
|
||||
}
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Observers\UserObserver;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
@@ -25,5 +27,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
public function boot()
|
||||
{
|
||||
Schema::defaultStringLength(191);
|
||||
User::observe(UserObserver::class);
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Http\Controllers\ProfileController;
|
||||
use App\Policies\ProfilePolicy;
|
||||
use App\Policies\UserPolicy;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
@@ -14,6 +18,9 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Model' => 'App\Policies\ModelPolicy',
|
||||
'App\Application' => 'App\Policies\ApplicationPolicy',
|
||||
ProfileController::class => ProfilePolicy::class,
|
||||
User::class => UserPolicy::class
|
||||
];
|
||||
|
||||
/**
|
||||
|
@@ -25,6 +25,9 @@ class EventServiceProvider extends ServiceProvider
|
||||
],
|
||||
'App\Events\ApplicationDeniedEvent' => [
|
||||
'App\Listeners\DenyUser'
|
||||
],
|
||||
'App\Events\UserBannedEvent' => [
|
||||
'App\Listeners\OnUserBanned'
|
||||
]
|
||||
];
|
||||
|
||||
|
33
app/Providers/IPInfoProvider.php
Normal file
33
app/Providers/IPInfoProvider.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use App;
|
||||
|
||||
class IPInfoProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
App::bind('ipInformationFacade', function(){
|
||||
|
||||
return new App\CustomFacades\IP();
|
||||
|
||||
});
|
||||
}
|
||||
}
|
@@ -31,7 +31,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
|
||||
Route::model('user', \App\User::class);
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
|
33
app/Providers/UUIDConversionProvider.php
Normal file
33
app/Providers/UUIDConversionProvider.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use App;
|
||||
|
||||
class UUIDConversionProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
App::bind('uuidConversionFacade', function(){
|
||||
|
||||
return new App\UUID\UUID();
|
||||
|
||||
});
|
||||
}
|
||||
}
|
@@ -12,6 +12,7 @@ class Response extends Model
|
||||
'responseData'
|
||||
];
|
||||
|
||||
|
||||
public function form()
|
||||
{
|
||||
return $this->hasOne('App\Form', 'id', 'responseFormID');
|
||||
|
53
app/UUID/UUID.php
Normal file
53
app/UUID/UUID.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
namespace App\UUID;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UUID
|
||||
{
|
||||
|
||||
// Caching would not be needed here since this method won't be used in pages that loop over a collection of usernames.
|
||||
public function toUUID($username)
|
||||
{
|
||||
if (is_null($username))
|
||||
{
|
||||
throw new \LogicException('Argument username for ' . __METHOD__ . ' cannot be null!');
|
||||
}
|
||||
|
||||
$response = json_decode(Http::post(config('general.urls.mojang.api') . '/profiles/minecraft', [
|
||||
$username
|
||||
])->body(), true);
|
||||
|
||||
return $response[0]['id'];
|
||||
}
|
||||
|
||||
// Note: Caching could simply be assigning the username to it's UUID, however, to make this work, we'd need to loop over all cache items, which would be slighly ineffective
|
||||
public function toUsername($uuid)
|
||||
{
|
||||
|
||||
if (is_null($uuid))
|
||||
{
|
||||
throw new \LogicException('Argument uuid for ' . __METHOD__ . ' cannot be null!');
|
||||
}
|
||||
|
||||
$shortUUID = substr($uuid, 0, 8);
|
||||
$username = Cache::remember('uuid_' . $shortUUID, now()->addDays(30), function() use ($shortUUID, $uuid) {
|
||||
|
||||
$response = json_decode(Http::get(config('general.urls.mojang.session') . '/session/minecraft/profile/' . $uuid)->body(), true);
|
||||
|
||||
Log::debug('Caching ' . $shortUUID . 'for thirty days');
|
||||
return $response['name'];
|
||||
|
||||
});
|
||||
|
||||
return $username;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
34
app/User.php
34
app/User.php
@@ -5,10 +5,13 @@ namespace App;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use Notifiable;
|
||||
use HasRoles;
|
||||
//use MustVerifyEmail;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@@ -37,6 +40,8 @@ class User extends Authenticatable
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
|
||||
//
|
||||
public function applications()
|
||||
{
|
||||
return $this->hasMany('App\Application', 'applicantUserID', 'id');
|
||||
@@ -52,4 +57,33 @@ class User extends Authenticatable
|
||||
return $this->hasOne('App\Profile', 'userID', 'id');
|
||||
}
|
||||
|
||||
public function bans()
|
||||
{
|
||||
return $this->hasOne('App\Ban', 'userID', 'id');
|
||||
}
|
||||
|
||||
public function comments()
|
||||
{
|
||||
return $this->hasMany('App\Comment', 'authorID', 'id');
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function isBanned()
|
||||
{
|
||||
return !$this->bans()->get()->isEmpty();
|
||||
}
|
||||
|
||||
|
||||
public function isStaffMember()
|
||||
{
|
||||
return $this->hasAnyRole('reviewer', 'admin', 'hiringManager');
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function routeNotificationForSlack($notification)
|
||||
{
|
||||
return config('slack.webhook.integrationURL');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user