2020-04-29 17:15:54 +00:00
< ? php
2020-10-10 16:30:26 +00:00
/*
* Copyright © 2020 Miguel Nogueira
*
* This file is part of Raspberry Staff Manager .
*
* Raspberry Staff Manager is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Raspberry Staff Manager is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with Raspberry Staff Manager . If not , see < https :// www . gnu . org / licenses />.
*/
2020-04-29 17:15:54 +00:00
namespace App\Http\Controllers ;
2020-05-08 07:10:25 +00:00
use App\Application ;
2020-06-26 23:32:33 +00:00
use App\Events\ApplicationDeniedEvent ;
use App\Notifications\ApplicationMoved ;
2020-10-10 16:30:26 +00:00
use App\Notifications\NewApplicant ;
use App\Response ;
use App\User ;
use App\Vacancy ;
use ContextAwareValidator ;
2020-04-29 17:15:54 +00:00
use Illuminate\Http\Request ;
2020-05-08 07:10:25 +00:00
use Illuminate\Support\Facades\Auth ;
2020-06-26 23:32:33 +00:00
use Illuminate\Support\Facades\Log ;
2020-04-29 17:15:54 +00:00
class ApplicationController extends Controller
{
2021-01-29 16:56:29 +00:00
private function processOSLinebreaks ( array $structuredResponses )
{
$processedResponses = $structuredResponses ;
foreach ( $structuredResponses as $responseKey => $response )
{
// We can't use nl2br because it preserves the line breaks and doesn't include all line breaks used by other operating systems
$originalResponse = $response [ 'response' ];
$processedResponses [ $responseKey ][ 'response' ] = str_replace ([ " \r \n " , " \r " , " \n " ], " <br/> " , $originalResponse );
}
return $processedResponses ;
}
2020-12-07 17:48:15 +00:00
private function canVote ( $votes ) : bool
2020-05-29 23:20:39 +00:00
{
$allvotes = collect ([]);
2020-10-10 16:30:26 +00:00
foreach ( $votes as $vote ) {
if ( $vote -> userID == Auth :: user () -> id ) {
2020-05-29 23:20:39 +00:00
$allvotes -> push ( $vote );
}
}
2020-06-26 23:32:33 +00:00
return ( $allvotes -> count () == 1 ) ? false : true ;
2020-05-29 23:20:39 +00:00
}
2020-04-30 15:38:54 +00:00
2020-05-11 15:44:47 +00:00
public function showUserApps ()
2020-04-30 15:38:54 +00:00
{
2020-05-11 15:44:47 +00:00
return view ( 'dashboard.user.applications' )
-> with ( 'applications' , Auth :: user () -> applications );
2020-04-30 15:55:14 +00:00
}
2020-07-16 20:21:28 +00:00
public function showUserApp ( Request $request , Application $application )
2020-05-22 02:49:16 +00:00
{
2020-06-26 23:32:33 +00:00
$this -> authorize ( 'view' , $application );
2020-10-10 16:30:26 +00:00
if ( ! is_null ( $application )) {
2020-05-22 02:49:16 +00:00
return view ( 'dashboard.user.viewapp' )
-> with (
[
'application' => $application ,
2020-06-26 23:32:33 +00:00
'comments' => $application -> comments ,
2021-01-29 16:56:29 +00:00
'structuredResponses' => % this -> processOSLinebreaks ( json_decode ( $application -> response -> responseData , true )),
2020-05-22 02:49:16 +00:00
'formStructure' => $application -> response -> form ,
2020-05-29 23:20:39 +00:00
'vacancy' => $application -> response -> vacancy ,
2020-10-10 16:30:26 +00:00
'canVote' => $this -> canVote ( $application -> votes ),
2020-05-22 02:49:16 +00:00
]
);
2020-10-10 16:30:26 +00:00
} else {
2020-05-22 02:49:16 +00:00
$request -> session () -> flash ( 'error' , 'The application you requested could not be found.' );
}
return redirect () -> back ();
}
2020-07-11 01:43:59 +00:00
public function showAllApps ()
{
2020-07-16 20:21:28 +00:00
$this -> authorize ( 'viewAny' , Application :: class );
2020-07-11 01:43:59 +00:00
return view ( 'dashboard.appmanagement.all' )
-> with ( 'applications' , Application :: paginate ( 6 ));
}
2020-05-08 05:06:24 +00:00
public function renderApplicationForm ( Request $request , $vacancySlug )
{
2020-06-26 23:32:33 +00:00
// FIXME: Get rid of references to first(), this is a wonky query
2020-05-08 05:06:24 +00:00
$vacancyWithForm = Vacancy :: with ( 'forms' ) -> where ( 'vacancySlug' , $vacancySlug ) -> get ();
2020-06-26 23:32:33 +00:00
$firstVacancy = $vacancyWithForm -> first ();
2020-10-10 16:30:26 +00:00
if ( ! $vacancyWithForm -> isEmpty () && $firstVacancy -> vacancyCount !== 0 && $firstVacancy -> vacancyStatus == 'OPEN' ) {
2020-05-08 05:06:24 +00:00
return view ( 'dashboard.application-rendering.apply' )
-> with ([
'vacancy' => $vacancyWithForm -> first (),
2020-10-10 16:30:26 +00:00
'preprocessedForm' => json_decode ( $vacancyWithForm -> first () -> forms -> formStructure , true ),
2020-05-08 05:06:24 +00:00
]);
2020-10-10 16:30:26 +00:00
} else {
2020-06-26 23:32:33 +00:00
abort ( 404 , 'The application you\'re looking for could not be found or it is currently unavailable.' );
2020-05-08 05:06:24 +00:00
}
}
2020-05-08 07:10:25 +00:00
public function saveApplicationAnswers ( Request $request , $vacancySlug )
{
$vacancy = Vacancy :: with ( 'forms' ) -> where ( 'vacancySlug' , $vacancySlug ) -> get ();
2020-10-10 16:30:26 +00:00
if ( $vacancy -> first () -> vacancyCount == 0 || $vacancy -> first () -> vacancyStatus !== 'OPEN' ) {
$request -> session () -> flash ( 'error' , 'This application is unavailable.' );
2020-06-26 23:32:33 +00:00
2020-10-10 16:30:26 +00:00
return redirect () -> back ();
2020-06-26 23:32:33 +00:00
}
2020-05-08 07:10:25 +00:00
Log :: info ( 'Processing new application!' );
$formStructure = json_decode ( $vacancy -> first () -> forms -> formStructure , true );
2020-07-16 20:21:28 +00:00
$responseValidation = ContextAwareValidator :: getResponseValidator ( $request -> all (), $formStructure );
2020-05-08 07:10:25 +00:00
Log :: info ( 'Built response & validator structure!' );
2020-10-10 16:30:26 +00:00
if ( ! $responseValidation -> get ( 'validator' ) -> fails ()) {
2020-05-08 07:10:25 +00:00
$response = Response :: create ([
'responseFormID' => $vacancy -> first () -> forms -> id ,
'associatedVacancyID' => $vacancy -> first () -> id , // Since a form can be used by multiple vacancies, we can only know which specific vacancy this response ties to by using a vacancy ID
2020-10-10 16:30:26 +00:00
'responseData' => $responseValidation -> get ( 'responseStructure' ),
2020-05-08 07:10:25 +00:00
]);
2020-10-10 16:30:26 +00:00
Log :: info ( 'Registered form response for user ' . Auth :: user () -> name . ' for vacancy ' . $vacancy -> first () -> vacancyName );
2020-05-08 07:10:25 +00:00
2020-06-26 23:32:33 +00:00
$application = Application :: create ([
2020-05-08 07:10:25 +00:00
'applicantUserID' => Auth :: user () -> id ,
'applicantFormResponseID' => $response -> id ,
'applicationStatus' => 'STAGE_SUBMITTED' ,
]);
2020-10-10 16:30:26 +00:00
Log :: info ( 'Submitted application for user ' . Auth :: user () -> name . ' with response ID' . $response -> id );
2020-05-08 07:10:25 +00:00
2020-10-10 16:30:26 +00:00
foreach ( User :: all () as $user ) {
if ( $user -> hasRole ( 'admin' )) {
$user -> notify (( new NewApplicant ( $application , $vacancy -> first ())) -> delay ( now () -> addSeconds ( 10 )));
}
2020-06-26 23:32:33 +00:00
}
2020-05-08 07:10:25 +00:00
$request -> session () -> flash ( 'success' , 'Thank you for your application! It will be reviewed as soon as possible.' );
2020-10-10 16:30:26 +00:00
2020-05-22 02:49:16 +00:00
return redirect () -> to ( route ( 'showUserApps' ));
2020-10-10 16:30:26 +00:00
} else {
Log :: warning ( 'Application form for ' . Auth :: user () -> name . ' contained errors, resetting!' );
2020-05-08 07:10:25 +00:00
$request -> session () -> flash ( 'error' , 'There are one or more errors in your application. Please make sure none of your fields are empty, since they are all required.' );
}
return redirect () -> back ();
}
2020-05-22 02:49:16 +00:00
2020-09-02 19:52:56 +00:00
public function updateApplicationStatus ( Request $request , Application $application , $newStatus )
2020-05-22 02:49:16 +00:00
{
2020-06-27 18:15:33 +00:00
$this -> authorize ( 'update' , Application :: class );
2020-05-22 02:49:16 +00:00
2020-10-10 16:30:26 +00:00
switch ( $newStatus ) {
2020-07-16 20:21:28 +00:00
case 'deny' :
2020-05-22 02:49:16 +00:00
2020-07-16 20:21:28 +00:00
event ( new ApplicationDeniedEvent ( $application ));
break ;
2020-05-22 02:49:16 +00:00
2020-07-16 20:21:28 +00:00
case 'interview' :
2020-10-10 16:30:26 +00:00
Log :: info ( 'User ' . Auth :: user () -> name . ' has moved application ID ' . $application -> id . 'to interview stage' );
2020-07-16 20:21:28 +00:00
$request -> session () -> flash ( 'success' , 'Application moved to interview stage! (:' );
$application -> setStatus ( 'STAGE_INTERVIEW' );
2020-06-26 23:32:33 +00:00
2020-07-16 20:21:28 +00:00
$application -> user -> notify ( new ApplicationMoved ());
break ;
2020-05-22 02:49:16 +00:00
2020-07-16 20:21:28 +00:00
default :
$request -> session () -> flash ( 'error' , 'There are no suitable statuses to update to. Do not mess with the URL.' );
2020-05-22 02:49:16 +00:00
}
return redirect () -> back ();
}
2020-07-12 16:01:33 +00:00
public function delete ( Request $request , Application $application )
{
2020-10-10 16:30:26 +00:00
$this -> authorize ( 'delete' , $application );
$application -> delete (); // observers will run, cleaning it up
2020-07-12 16:01:33 +00:00
2020-10-10 16:30:26 +00:00
$request -> session () -> flash ( 'success' , 'Application deleted. Comments, appointments and responses have also been deleted.' );
2020-07-16 20:21:28 +00:00
2020-10-10 16:30:26 +00:00
return redirect () -> back ();
2020-07-12 16:01:33 +00:00
}
2020-04-29 17:15:54 +00:00
}