From 4fa024045d2d15cb565a4b1cfb6ba791bca50726 Mon Sep 17 00:00:00 2001 From: Nabeel Shahzad Date: Wed, 9 May 2018 12:45:24 -0500 Subject: [PATCH] refactorings of pirep/acars api calls; separate field calls --- app/Http/Controllers/Api/AcarsController.php | 184 +++++++++++- app/Http/Controllers/Api/PirepController.php | 288 ++++++------------- app/Http/Requests/Acars/CommentRequest.php | 2 +- app/Http/Requests/Acars/EventRequest.php | 3 +- app/Http/Requests/Acars/FieldsRequest.php | 22 ++ app/Http/Requests/Acars/FileRequest.php | 3 +- app/Http/Requests/Acars/LogRequest.php | 3 +- app/Http/Requests/Acars/PositionRequest.php | 21 +- app/Http/Requests/Acars/PrefileRequest.php | 15 +- app/Http/Requests/Acars/RouteRequest.php | 3 +- app/Http/Requests/Acars/UpdateRequest.php | 3 +- app/Http/Resources/Pirep.php | 3 +- app/Http/Resources/PirepFieldCollection.php | 22 ++ app/Interfaces/FormRequest.php | 28 ++ app/Models/Acars.php | 5 + app/Models/Pirep.php | 5 + app/Routes/api.php | 16 +- composer.json | 3 +- composer.lock | 143 ++++++--- tests/AcarsTest.php | 43 +-- 20 files changed, 527 insertions(+), 288 deletions(-) create mode 100644 app/Http/Requests/Acars/FieldsRequest.php create mode 100644 app/Http/Resources/PirepFieldCollection.php create mode 100644 app/Interfaces/FormRequest.php diff --git a/app/Http/Controllers/Api/AcarsController.php b/app/Http/Controllers/Api/AcarsController.php index 47529a6f..7e06ce07 100644 --- a/app/Http/Controllers/Api/AcarsController.php +++ b/app/Http/Controllers/Api/AcarsController.php @@ -2,10 +2,24 @@ namespace App\Http\Controllers\Api; +use App\Exceptions\PirepCancelled; +use App\Http\Requests\Acars\EventRequest; +use App\Http\Requests\Acars\LogRequest; +use App\Http\Requests\Acars\PositionRequest; +use App\Http\Resources\AcarsRoute as AcarsRouteResource; use App\Interfaces\Controller; +use App\Models\Acars; +use App\Models\Enums\AcarsType; +use App\Models\Enums\PirepStatus; +use App\Models\Pirep; use App\Repositories\AcarsRepository; +use App\Repositories\PirepRepository; use App\Services\GeoService; +use App\Services\PirepService; +use Auth; +use Carbon\Carbon; use Illuminate\Http\Request; +use Log; /** * Class AcarsController @@ -14,19 +28,39 @@ use Illuminate\Http\Request; class AcarsController extends Controller { private $acarsRepo, - $geoSvc; + $geoSvc, + $pirepRepo, + $pirepSvc; /** * AcarsController constructor. - * @param GeoService $geoSvc * @param AcarsRepository $acarsRepo + * @param GeoService $geoSvc + * @param PirepRepository $pirepRepo + * @param PirepService $pirepSvc */ public function __construct( + AcarsRepository $acarsRepo, GeoService $geoSvc, - AcarsRepository $acarsRepo + PirepRepository $pirepRepo, + PirepService $pirepSvc ) { $this->geoSvc = $geoSvc; $this->acarsRepo = $acarsRepo; + $this->pirepRepo = $pirepRepo; + $this->pirepSvc = $pirepSvc; + } + + /** + * Check if a PIREP is cancelled + * @param $pirep + * @throws \App\Exceptions\PirepCancelled + */ + protected function checkCancelled(Pirep $pirep) + { + if (!$pirep->allowedUpdates()) { + throw new PirepCancelled(); + } } /** @@ -43,4 +77,148 @@ class AcarsController extends Controller 'Content-type' => 'application/json' ]); } + + /** + * Return the GeoJSON for the ACARS line + * @param $pirep_id + * @param Request $request + * @return \Illuminate\Contracts\Routing\ResponseFactory + */ + public function acars_geojson($pirep_id, Request $request) + { + $pirep = Pirep::find($pirep_id); + $geodata = $this->geoSvc->getFeatureFromAcars($pirep); + + return response(\json_encode($geodata), 200, [ + 'Content-Type' => 'application/json', + ]); + } + + /** + * Return the routes for the ACARS line + * @param $id + * @param Request $request + * @return AcarsRouteResource + */ + public function acars_get($id, Request $request) + { + $this->pirepRepo->find($id); + + return new AcarsRouteResource(Acars::where([ + 'pirep_id' => $id, + 'type' => AcarsType::FLIGHT_PATH + ])->orderBy('created_at', 'asc')->get()); + } + + /** + * Post ACARS updates for a PIREP + * @param $id + * @param PositionRequest $request + * @return \Illuminate\Http\JsonResponse + * @throws \App\Exceptions\PirepCancelled + * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException + */ + public function acars_store($id, PositionRequest $request) + { + # Check if the status is cancelled... + $pirep = Pirep::find($id); + $this->checkCancelled($pirep); + + Log::debug( + 'Posting ACARS update (user: '.Auth::user()->pilot_id.', pirep id :'.$id.'): ', + $request->post() + ); + + $count = 0; + $positions = $request->post('positions'); + foreach ($positions as $position) { + $position['pirep_id'] = $id; + $position['type'] = AcarsType::FLIGHT_PATH; + + if (array_key_exists('sim_time', $position)) { + $position['sim_time'] = Carbon::createFromTimeString($position['sim_time']); + } + + if (array_key_exists('created_at', $position)) { + $position['created_at'] = Carbon::createFromTimeString($position['created_at']); + } + + $update = Acars::create($position); + $update->save(); + + ++$count; + } + + # Change the PIREP status if it's as SCHEDULED before + if ($pirep->status === PirepStatus::INITIATED) { + $pirep->status = PirepStatus::AIRBORNE; + } + + $pirep->save(); + + return $this->message($count.' positions added', $count); + } + + /** + * Post ACARS LOG update for a PIREP. These updates won't show up on the map + * But rather in a log file. + * @param $id + * @param LogRequest $request + * @return \Illuminate\Http\JsonResponse + * @throws \App\Exceptions\PirepCancelled + * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException + */ + public function acars_logs($id, LogRequest $request) + { + # Check if the status is cancelled... + $pirep = Pirep::find($id); + $this->checkCancelled($pirep); + + Log::debug('Posting ACARS log, PIREP: '.$id, $request->post()); + + $count = 0; + $logs = $request->post('logs'); + foreach ($logs as $log) { + $log['pirep_id'] = $id; + $log['type'] = AcarsType::LOG; + + $acars = Acars::create($log); + $acars->save(); + ++$count; + } + + return $this->message($count.' logs added', $count); + } + + /** + * Post ACARS LOG update for a PIREP. These updates won't show up on the map + * But rather in a log file. + * @param $id + * @param EventRequest $request + * @return \Illuminate\Http\JsonResponse + * @throws \App\Exceptions\PirepCancelled + * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException + */ + public function acars_events($id, EventRequest $request) + { + # Check if the status is cancelled... + $pirep = Pirep::find($id); + $this->checkCancelled($pirep); + + Log::debug('Posting ACARS event, PIREP: '.$id, $request->post()); + + $count = 0; + $logs = $request->post('events'); + foreach ($logs as $log) { + $log['pirep_id'] = $id; + $log['type'] = AcarsType::LOG; + $log['log'] = $log['event']; + + $acars = Acars::create($log); + $acars->save(); + ++$count; + } + + return $this->message($count.' logs added', $count); + } } diff --git a/app/Http/Controllers/Api/PirepController.php b/app/Http/Controllers/Api/PirepController.php index fcc47050..3c13475d 100644 --- a/app/Http/Controllers/Api/PirepController.php +++ b/app/Http/Controllers/Api/PirepController.php @@ -7,10 +7,8 @@ use App\Exceptions\AircraftPermissionDenied; use App\Exceptions\PirepCancelled; use App\Exceptions\UserNotAtAirport; use App\Http\Requests\Acars\CommentRequest; -use App\Http\Requests\Acars\EventRequest; +use App\Http\Requests\Acars\FieldsRequest; use App\Http\Requests\Acars\FileRequest; -use App\Http\Requests\Acars\LogRequest; -use App\Http\Requests\Acars\PositionRequest; use App\Http\Requests\Acars\PrefileRequest; use App\Http\Requests\Acars\RouteRequest; use App\Http\Requests\Acars\UpdateRequest; @@ -18,6 +16,7 @@ use App\Http\Resources\AcarsRoute as AcarsRouteResource; use App\Http\Resources\JournalTransaction as JournalTransactionResource; use App\Http\Resources\Pirep as PirepResource; use App\Http\Resources\PirepComment as PirepCommentResource; +use App\Http\Resources\PirepFieldCollection; use App\Interfaces\Controller; use App\Models\Acars; use App\Models\Enums\AcarsType; @@ -31,7 +30,6 @@ use App\Repositories\JournalRepository; use App\Repositories\PirepRepository; use App\Services\FareService; use App\Services\Finance\PirepFinanceService; -use App\Services\GeoService; use App\Services\PirepService; use App\Services\UserService; use Auth; @@ -48,7 +46,6 @@ class PirepController extends Controller private $acarsRepo, $fareSvc, $financeSvc, - $geoSvc, $journalRepo, $pirepRepo, $pirepSvc, @@ -59,7 +56,6 @@ class PirepController extends Controller * @param AcarsRepository $acarsRepo * @param FareService $fareSvc * @param PirepFinanceService $financeSvc - * @param GeoService $geoSvc * @param JournalRepository $journalRepo * @param PirepRepository $pirepRepo * @param PirepService $pirepSvc @@ -69,7 +65,6 @@ class PirepController extends Controller AcarsRepository $acarsRepo, FareService $fareSvc, PirepFinanceService $financeSvc, - GeoService $geoSvc, JournalRepository $journalRepo, PirepRepository $pirepRepo, PirepService $pirepSvc, @@ -78,13 +73,28 @@ class PirepController extends Controller $this->acarsRepo = $acarsRepo; $this->fareSvc = $fareSvc; $this->financeSvc = $financeSvc; - $this->geoSvc = $geoSvc; $this->journalRepo = $journalRepo; $this->pirepRepo = $pirepRepo; $this->pirepSvc = $pirepSvc; $this->userSvc = $userSvc; } + /** + * Parse any PIREP added in + * @param Request $request + * @return array|null|string + */ + protected function parsePirep(Request $request) + { + $attrs = $request->input(); + + if (array_key_exists('created_at', $attrs)) { + $attrs['created_at'] = Carbon::createFromTimeString($attrs['created_at']); + } + + return $attrs; + } + /** * Check if a PIREP is cancelled * @param $pirep @@ -97,35 +107,6 @@ class PirepController extends Controller } } - /** - * Get all the active PIREPs - * @param $id - * @return PirepResource - */ - public function index() - { - $active = []; - $pireps = $this->acarsRepo->getPositions(); - foreach($pireps as $pirep) { - if(!$pirep->position) { - continue; - } - - $active[] = $pirep; - } - - return PirepResource::collection(collect($active)); - } - - /** - * @param $id - * @return PirepResource - */ - public function get($id) - { - return new PirepResource($this->pirepRepo->find($id)); - } - /** * @param $pirep * @param Request $request @@ -171,6 +152,34 @@ class PirepController extends Controller $this->fareSvc->saveForPirep($pirep, $fares); } + /** + * Get all the active PIREPs + * @return mixed + */ + public function index() + { + $active = []; + $pireps = $this->acarsRepo->getPositions(); + foreach($pireps as $pirep) { + if(!$pirep->position) { + continue; + } + + $active[] = $pirep; + } + + return PirepResource::collection(collect($active)); + } + + /** + * @param $pirep_id + * @return PirepResource + */ + public function get($pirep_id) + { + return new PirepResource($this->pirepRepo->find($pirep_id)); + } + /** * Create a new PIREP and place it in a "inprogress" and "prefile" state * Once ACARS updates are being processed, then it can go into an 'ENROUTE' @@ -190,7 +199,7 @@ class PirepController extends Controller $user = Auth::user(); - $attrs = $request->post(); + $attrs = $this->parsePirep($request); $attrs['user_id'] = $user->id; $attrs['source'] = PirepSource::ACARS; $attrs['state'] = PirepState::IN_PROGRESS; @@ -250,7 +259,7 @@ class PirepController extends Controller * Once ACARS updates are being processed, then it can go into an 'ENROUTE' * status, and whatever other statuses may be defined * - * @param $id + * @param $pirep_id * @param UpdateRequest $request * @return PirepResource * @throws \App\Exceptions\PirepCancelled @@ -258,16 +267,16 @@ class PirepController extends Controller * @throws \Prettus\Validator\Exceptions\ValidatorException * @throws \Exception */ - public function update($id, UpdateRequest $request) + public function update($pirep_id, UpdateRequest $request) { Log::info('PIREP Update, user '.Auth::id()); Log::info($request->getContent()); $user = Auth::user(); - $pirep = Pirep::find($id); + $pirep = Pirep::find($pirep_id); $this->checkCancelled($pirep); - $attrs = $request->post(); + $attrs = $this->parsePirep($request); $attrs['user_id'] = Auth::id(); # If aircraft is being changed, see if this user is allowed to fly this aircraft @@ -280,7 +289,7 @@ class PirepController extends Controller } } - $pirep = $this->pirepRepo->update($attrs, $id); + $pirep = $this->pirepRepo->update($attrs, $pirep_id); $this->updateFields($pirep, $request); $this->updateFares($pirep, $request); @@ -289,7 +298,7 @@ class PirepController extends Controller /** * File the PIREP - * @param $id + * @param $pirep_id * @param FileRequest $request * @return PirepResource * @throws \App\Exceptions\PirepCancelled @@ -297,17 +306,17 @@ class PirepController extends Controller * @throws \Illuminate\Database\Eloquent\ModelNotFoundException * @throws \Exception */ - public function file($id, FileRequest $request) + public function file($pirep_id, FileRequest $request) { Log::info('PIREP file, user '.Auth::id(), $request->post()); $user = Auth::user(); # Check if the status is cancelled... - $pirep = Pirep::find($id); + $pirep = Pirep::find($pirep_id); $this->checkCancelled($pirep); - $attrs = $request->post(); + $attrs = $this->parsePirep($request); # If aircraft is being changed, see if this user is allowed to fly this aircraft if (array_key_exists('aircraft_id', $attrs) @@ -323,7 +332,7 @@ class PirepController extends Controller $attrs['status'] = PirepStatus::ARRIVED; $attrs['submitted_at'] = Carbon::now('UTC'); - $pirep = $this->pirepRepo->update($attrs, $id); + $pirep = $this->pirepRepo->update($attrs, $pirep_id); try { $pirep = $this->pirepSvc->create($pirep); @@ -347,174 +356,29 @@ class PirepController extends Controller /** * Cancel the PIREP - * @param $id + * @param $pirep_id * @param Request $request * @return PirepResource * @throws \Prettus\Validator\Exceptions\ValidatorException */ - public function cancel($id, Request $request) + public function cancel($pirep_id, Request $request) { Log::info('PIREP Cancel, user '.Auth::id(), $request->post()); $pirep = $this->pirepRepo->update([ 'state' => PirepState::CANCELLED, 'status' => PirepStatus::CANCELLED, - ], $id); + ], $pirep_id); return new PirepResource($pirep); } - /** - * Return the GeoJSON for the ACARS line - * @param $id - * @param Request $request - * @return \Illuminate\Contracts\Routing\ResponseFactory - */ - public function acars_geojson($id, Request $request) - { - $pirep = Pirep::find($id); - $geodata = $this->geoSvc->getFeatureFromAcars($pirep); - - return response(\json_encode($geodata), 200, [ - 'Content-Type' => 'application/json', - ]); - } - - /** - * Return the routes for the ACARS line - * @param $id - * @param Request $request - * @return AcarsRouteResource - */ - public function acars_get($id, Request $request) - { - $this->pirepRepo->find($id); - - return new AcarsRouteResource(Acars::where([ - 'pirep_id' => $id, - 'type' => AcarsType::FLIGHT_PATH - ])->orderBy('created_at', 'asc')->get()); - } - - /** - * Post ACARS updates for a PIREP - * @param $id - * @param PositionRequest $request - * @return \Illuminate\Http\JsonResponse - * @throws \App\Exceptions\PirepCancelled - * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException - */ - public function acars_store($id, PositionRequest $request) - { - # Check if the status is cancelled... - $pirep = Pirep::find($id); - $this->checkCancelled($pirep); - - Log::debug( - 'Posting ACARS update (user: '.Auth::user()->pilot_id.', pirep id :'.$id.'): ', - $request->post() - ); - - $count = 0; - $positions = $request->post('positions'); - foreach ($positions as $position) { - $position['pirep_id'] = $id; - $position['type'] = AcarsType::FLIGHT_PATH; - - if(array_key_exists('sim_time', $position)) { - $position['sim_time'] = Carbon::createFromTimeString($position['sim_time']); - } - - if (array_key_exists('created_at', $position)) { - $position['created_at'] = Carbon::createFromTimeString($position['created_at']); - } - - $update = Acars::create($position); - $update->save(); - - ++$count; - } - - # Change the PIREP status if it's as SCHEDULED before - if ($pirep->status === PirepStatus::INITIATED) { - $pirep->status = PirepStatus::AIRBORNE; - } - - $pirep->save(); - - return $this->message($count.' positions added', $count); - } - - /** - * Post ACARS LOG update for a PIREP. These updates won't show up on the map - * But rather in a log file. - * @param $id - * @param LogRequest $request - * @return \Illuminate\Http\JsonResponse - * @throws \App\Exceptions\PirepCancelled - * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException - */ - public function acars_logs($id, LogRequest $request) - { - # Check if the status is cancelled... - $pirep = Pirep::find($id); - $this->checkCancelled($pirep); - - Log::debug('Posting ACARS log, PIREP: '.$id, $request->post()); - - $count = 0; - $logs = $request->post('logs'); - foreach ($logs as $log) { - $log['pirep_id'] = $id; - $log['type'] = AcarsType::LOG; - - $acars = Acars::create($log); - $acars->save(); - ++$count; - } - - return $this->message($count.' logs added', $count); - } - - /** - * Post ACARS LOG update for a PIREP. These updates won't show up on the map - * But rather in a log file. - * @param $id - * @param EventRequest $request - * @return \Illuminate\Http\JsonResponse - * @throws \App\Exceptions\PirepCancelled - * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException - */ - public function acars_events($id, EventRequest $request) - { - # Check if the status is cancelled... - $pirep = Pirep::find($id); - $this->checkCancelled($pirep); - - Log::debug('Posting ACARS event, PIREP: '.$id, $request->post()); - - $count = 0; - $logs = $request->post('events'); - foreach ($logs as $log) { - $log['pirep_id'] = $id; - $log['type'] = AcarsType::LOG; - $log['log'] = $log['event']; - - $acars = Acars::create($log); - $acars->save(); - ++$count; - } - - return $this->message($count.' logs added', $count); - } - /** * Add a new comment * @param $id - * @param Request $request * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection */ - public function comments_get($id, Request $request) + public function comments_get($id) { $pirep = Pirep::find($id); return PirepCommentResource::collection($pirep->comments); @@ -543,14 +407,40 @@ class PirepController extends Controller return new PirepCommentResource($comment); } + /** + * Get all of the fields for a PIREP + * @param $pirep_id + * @return PirepFieldCollection + */ + public function fields_get($pirep_id) + { + $pirep = Pirep::find($pirep_id); + return new PirepFieldCollection($pirep->fields); + } + + /** + * Set any fields for a PIREP + * @param string $pirep_id + * @param FieldsRequest $request + * @return PirepFieldCollection + */ + public function fields_post($pirep_id, FieldsRequest $request) + { + $pirep = Pirep::find($pirep_id); + $this->checkCancelled($pirep); + + $this->updateFields($pirep, $request); + + return new PirepFieldCollection($pirep->fields); + } + /** * @param $id - * @param Request $request * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection * @throws \UnexpectedValueException * @throws \InvalidArgumentException */ - public function finances_get($id, Request $request) + public function finances_get($id) { $pirep = Pirep::find($id); $transactions = $this->journalRepo->getAllForObject($pirep); diff --git a/app/Http/Requests/Acars/CommentRequest.php b/app/Http/Requests/Acars/CommentRequest.php index 9954c2af..a80013d0 100644 --- a/app/Http/Requests/Acars/CommentRequest.php +++ b/app/Http/Requests/Acars/CommentRequest.php @@ -2,7 +2,7 @@ namespace App\Http\Requests\Acars; -use Illuminate\Foundation\Http\FormRequest; +use App\Interfaces\FormRequest; /** * Class FileRequest diff --git a/app/Http/Requests/Acars/EventRequest.php b/app/Http/Requests/Acars/EventRequest.php index c5175c9f..a0e8614b 100644 --- a/app/Http/Requests/Acars/EventRequest.php +++ b/app/Http/Requests/Acars/EventRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests\Acars; +use App\Interfaces\FormRequest; use App\Models\Pirep; use Auth; -use Illuminate\Foundation\Http\FormRequest; /** * Class EventRequest @@ -19,7 +19,6 @@ class EventRequest extends FormRequest public function authorize() { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); - return $pirep->user_id === Auth::id(); } diff --git a/app/Http/Requests/Acars/FieldsRequest.php b/app/Http/Requests/Acars/FieldsRequest.php new file mode 100644 index 00000000..fc220e17 --- /dev/null +++ b/app/Http/Requests/Acars/FieldsRequest.php @@ -0,0 +1,22 @@ + 'required|array', + ]; + } +} diff --git a/app/Http/Requests/Acars/FileRequest.php b/app/Http/Requests/Acars/FileRequest.php index c4dbdc05..54055fe5 100644 --- a/app/Http/Requests/Acars/FileRequest.php +++ b/app/Http/Requests/Acars/FileRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests\Acars; +use App\Interfaces\FormRequest; use App\Models\Pirep; use Auth; -use Illuminate\Foundation\Http\FormRequest; /** * Class FileRequest @@ -15,7 +15,6 @@ class FileRequest extends FormRequest public function authorize() { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); - return $pirep->user_id === Auth::id(); } diff --git a/app/Http/Requests/Acars/LogRequest.php b/app/Http/Requests/Acars/LogRequest.php index a2a94431..7adeb309 100644 --- a/app/Http/Requests/Acars/LogRequest.php +++ b/app/Http/Requests/Acars/LogRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests\Acars; +use App\Interfaces\FormRequest; use App\Models\Pirep; use Auth; -use Illuminate\Foundation\Http\FormRequest; /** * Class LogRequest @@ -15,7 +15,6 @@ class LogRequest extends FormRequest public function authorize() { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); - return $pirep->user_id === Auth::id(); } diff --git a/app/Http/Requests/Acars/PositionRequest.php b/app/Http/Requests/Acars/PositionRequest.php index 736d57ff..d2623a6e 100644 --- a/app/Http/Requests/Acars/PositionRequest.php +++ b/app/Http/Requests/Acars/PositionRequest.php @@ -2,9 +2,10 @@ namespace App\Http\Requests\Acars; +use App\Interfaces\FormRequest; +use App\Models\Acars; use App\Models\Pirep; use Auth; -use Illuminate\Foundation\Http\FormRequest; /** * Class PositionRequest @@ -12,13 +13,28 @@ use Illuminate\Foundation\Http\FormRequest; */ class PositionRequest extends FormRequest { + /** + * @return bool + */ public function authorize() { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); - return $pirep->user_id === Auth::id(); } + /** + * @return array + */ + /*public function sanitize() + { + return [ + 'positions.*.sim_time' => Acars::$sanitize['sim_time'], + ]; + }*/ + + /** + * @return array + */ public function rules() { $rules = [ @@ -35,6 +51,7 @@ class PositionRequest extends FormRequest 'positions.*.fuel' => 'nullable|numeric', 'positions.*.fuel_flow' => 'nullable|numeric', 'positions.*.log' => 'nullable', + 'positions.*.sim_time' => 'nullable|date', 'positions.*.created_at' => 'nullable|date', ]; diff --git a/app/Http/Requests/Acars/PrefileRequest.php b/app/Http/Requests/Acars/PrefileRequest.php index d01f9313..fdbf2722 100644 --- a/app/Http/Requests/Acars/PrefileRequest.php +++ b/app/Http/Requests/Acars/PrefileRequest.php @@ -2,7 +2,8 @@ namespace App\Http\Requests\Acars; -use Illuminate\Foundation\Http\FormRequest; +use App\Interfaces\FormRequest; +use App\Models\Pirep; /** * Class PrefileRequest @@ -10,11 +11,17 @@ use Illuminate\Foundation\Http\FormRequest; */ class PrefileRequest extends FormRequest { - public function authorize() + /** + * @return array|void + */ + /*public function sanitize() { - return true; - } + return Pirep::$sanitize; + }*/ + /** + * @return array + */ public function rules() { $rules = [ diff --git a/app/Http/Requests/Acars/RouteRequest.php b/app/Http/Requests/Acars/RouteRequest.php index 9500cf2c..f50821b2 100644 --- a/app/Http/Requests/Acars/RouteRequest.php +++ b/app/Http/Requests/Acars/RouteRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests\Acars; +use App\Interfaces\FormRequest; use App\Models\Pirep; use Auth; -use Illuminate\Foundation\Http\FormRequest; /** * Class RouteRequest @@ -15,7 +15,6 @@ class RouteRequest extends FormRequest public function authorize() { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); - return $pirep->user_id === Auth::id(); } diff --git a/app/Http/Requests/Acars/UpdateRequest.php b/app/Http/Requests/Acars/UpdateRequest.php index 49b86c35..4a1d7985 100644 --- a/app/Http/Requests/Acars/UpdateRequest.php +++ b/app/Http/Requests/Acars/UpdateRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests\Acars; +use App\Interfaces\FormRequest; use App\Models\Pirep; use Auth; -use Illuminate\Foundation\Http\FormRequest; /** * Class UpdateRequest @@ -15,7 +15,6 @@ class UpdateRequest extends FormRequest public function authorize() { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); - return $pirep->user_id === Auth::id(); } diff --git a/app/Http/Resources/Pirep.php b/app/Http/Resources/Pirep.php index cd43304e..2e00a55a 100644 --- a/app/Http/Resources/Pirep.php +++ b/app/Http/Resources/Pirep.php @@ -58,7 +58,8 @@ class Pirep extends Resource 'curr_airport_id' => $this->user->curr_airport_id, ]; - $pirep['fields'] = $this->fields; + # format to kvp + $pirep['fields'] = new PirepFieldCollection($this->fields); return $pirep; } diff --git a/app/Http/Resources/PirepFieldCollection.php b/app/Http/Resources/PirepFieldCollection.php new file mode 100644 index 00000000..7456c75b --- /dev/null +++ b/app/Http/Resources/PirepFieldCollection.php @@ -0,0 +1,22 @@ +collection as $field) { + $obj[$field->name] = $field->value; + } + + return $obj; + } +} diff --git a/app/Interfaces/FormRequest.php b/app/Interfaces/FormRequest.php new file mode 100644 index 00000000..4402e905 --- /dev/null +++ b/app/Interfaces/FormRequest.php @@ -0,0 +1,28 @@ + 'required', ]; + /*public static $sanitize = [ + 'sim_time' => 'carbon', + 'created_at' => '', + ];*/ + /** * Return a new Length unit so conversions can be made * @return int|Distance diff --git a/app/Models/Pirep.php b/app/Models/Pirep.php index 9f947e9f..ab5c8f60 100644 --- a/app/Models/Pirep.php +++ b/app/Models/Pirep.php @@ -133,6 +133,11 @@ class Pirep extends Model 'route' => 'nullable', ]; + /*public static $sanitize = [ + 'dpt_airport_id' => 'trim|uppercase', + 'arr_airport_id' => 'trim|uppercase', + ];*/ + /** * Get the flight ident, e.,g JBU1900 * @return string diff --git a/app/Routes/api.php b/app/Routes/api.php index e266a9ff..0d76f2e7 100755 --- a/app/Routes/api.php +++ b/app/Routes/api.php @@ -7,7 +7,7 @@ Route::group([], function () { Route::get('acars', 'AcarsController@index'); Route::get('pireps', 'PirepController@index'); Route::get('pireps/{pirep_id}', 'PirepController@get'); - Route::get('pireps/{pirep_id}/acars/geojson', 'PirepController@acars_geojson'); + Route::get('pireps/{pirep_id}/acars/geojson', 'AcarsController@acars_geojson'); Route::get('news', 'NewsController@index'); Route::get('status', 'StatusController@status'); @@ -45,6 +45,10 @@ Route::group(['middleware' => ['api.auth']], function () { Route::post('pireps/{pirep_id}/comments', 'PirepController@comments_post'); Route::delete('pireps/{pirep_id}/cancel', 'PirepController@cancel'); + Route::get('pireps/{pirep_id}/fields', 'PirepController@fields_get'); + Route::post('pireps/{pirep_id}/fields', 'PirepController@fields_post'); + + Route::get('pireps/{pirep_id}/finances', 'PirepController@finances_get'); Route::post('pireps/{pirep_id}/finances/recalculate', 'PirepController@finances_recalculate'); @@ -54,12 +58,12 @@ Route::group(['middleware' => ['api.auth']], function () { Route::get('pireps/{pirep_id}/comments', 'PirepController@comments_get'); - Route::get('pireps/{pirep_id}/acars/position', 'PirepController@acars_get'); - Route::post('pireps/{pirep_id}/acars/position', 'PirepController@acars_store'); - Route::post('pireps/{pirep_id}/acars/positions', 'PirepController@acars_store'); + Route::get('pireps/{pirep_id}/acars/position', 'AcarsController@acars_get'); + Route::post('pireps/{pirep_id}/acars/position', 'AcarsController@acars_store'); + Route::post('pireps/{pirep_id}/acars/positions', 'AcarsController@acars_store'); - Route::post('pireps/{pirep_id}/acars/events', 'PirepController@acars_events'); - Route::post('pireps/{pirep_id}/acars/logs', 'PirepController@acars_logs'); + Route::post('pireps/{pirep_id}/acars/events', 'AcarsController@acars_events'); + Route::post('pireps/{pirep_id}/acars/logs', 'AcarsController@acars_logs'); Route::get('settings', 'SettingsController@index'); diff --git a/composer.json b/composer.json index bbc3a5f7..505b82f0 100755 --- a/composer.json +++ b/composer.json @@ -39,7 +39,8 @@ "igaster/laravel-theme": "^2.0", "anhskohbo/no-captcha": "^3.0", "league/csv": "^9.1", - "intervention/image": "^2.4" + "intervention/image": "^2.4", + "waavi/sanitizer": "^1.0" }, "require-dev": { "phpunit/phpunit": "~7.0", diff --git a/composer.lock b/composer.lock index 71f1116d..b70c576d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "e93a00b9cd2f0f627a64144801cd58d4", + "content-hash": "cdbd47e5570d8787f6b54d22950466b7", "packages": [ { "name": "akaunting/money", @@ -168,7 +168,7 @@ "Arrilot\\Widgets\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -223,7 +223,7 @@ "Cache\\Adapter\\Common\\": "" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -291,7 +291,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -353,7 +353,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -408,7 +408,7 @@ "Cache\\TagInterop\\": "" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -527,7 +527,7 @@ "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -868,7 +868,7 @@ "src/functions_include.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -923,7 +923,7 @@ "src/functions_include.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -985,7 +985,7 @@ "Hashids\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -1190,7 +1190,7 @@ "Irazasyed\\LaravelGAMP\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -1237,7 +1237,7 @@ "Jackiedo\\Timezonelist\\": "src/Jackiedo/Timezonelist" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -1290,7 +1290,7 @@ "stubs/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -1341,7 +1341,7 @@ "Joshbrw\\LaravelModuleInstaller\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -1433,7 +1433,7 @@ "src/Laracasts/Flash/functions.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -1910,7 +1910,7 @@ "League\\ISO3166\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -2103,7 +2103,7 @@ "VaCentral\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -2370,7 +2370,7 @@ "Http\\Discovery\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -2423,7 +2423,7 @@ "PhpUnitsOfMeasure\\": "source/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -2546,7 +2546,7 @@ "PragmaRX\\Yaml\\Tests\\": "tests/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -2607,7 +2607,7 @@ "Prettus\\Repository\\": "src/Prettus/Repository/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -2696,7 +2696,7 @@ "Psr\\Cache\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -2960,7 +2960,7 @@ "Ramsey\\Uuid\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -3243,7 +3243,7 @@ "Spatie\\Pjax\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -4469,7 +4469,7 @@ "TheIconic\\Tracking\\GoogleAnalytics\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -4514,7 +4514,7 @@ "TijsVerkoyen\\CssToInlineStyles\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -4555,7 +4555,7 @@ "Tivie\\OS\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "APACHE 2.0" ], @@ -4673,7 +4673,7 @@ "src/vierbergenlars/SemVer/internal.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -4741,6 +4741,65 @@ ], "time": "2016-09-01T10:05:43+00:00" }, + { + "name": "waavi/sanitizer", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/Waavi/Sanitizer.git", + "reference": "b4ed59fe1f87e130f38f1461b90350c916eb5931" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Waavi/Sanitizer/zipball/b4ed59fe1f87e130f38f1461b90350c916eb5931", + "reference": "b4ed59fe1f87e130f38f1461b90350c916eb5931", + "shasum": "" + }, + "require": { + "illuminate/support": "~5.3", + "nesbot/carbon": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Waavi\\Sanitizer\\Laravel\\SanitizerServiceProvider" + ], + "aliases": { + "Sanitizer": "Waavi\\Sanitizer\\Laravel\\Facade" + } + } + }, + "autoload": { + "psr-4": { + "Waavi\\Sanitizer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Wallace San Paulo", + "email": "info@waavi.com" + } + ], + "description": "Data sanitizer and Laravel 5 form requests with input sanitation.", + "keywords": [ + "input", + "input filter", + "input sanitation", + "input sanitizer", + "laravel", + "sanitation", + "transform input" + ], + "time": "2018-01-09T15:11:39+00:00" + }, { "name": "webpatser/laravel-uuid", "version": "3.0.1", @@ -4778,7 +4837,7 @@ "Webpatser\\Uuid": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -4834,7 +4893,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -4905,7 +4964,7 @@ "Barryvdh\\LaravelIdeHelper\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -5159,7 +5218,7 @@ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -5216,7 +5275,7 @@ "Whoops\\": "src/Whoops/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -5421,7 +5480,7 @@ "JakubOnderka\\PhpConsoleColor": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "BSD-2-Clause" ], @@ -5465,7 +5524,7 @@ "JakubOnderka\\PhpConsoleHighlighter": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -5625,7 +5684,7 @@ "src/DeepCopy/deep_copy.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -6408,7 +6467,7 @@ ] } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], @@ -6730,7 +6789,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -6821,7 +6880,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -6871,7 +6930,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -7165,7 +7224,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -7715,7 +7774,7 @@ "Webmozart\\Assert\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "http://packagist.org/downloads/", "license": [ "MIT" ], diff --git a/tests/AcarsTest.php b/tests/AcarsTest.php index 282e96e0..90e611bb 100644 --- a/tests/AcarsTest.php +++ b/tests/AcarsTest.php @@ -314,8 +314,7 @@ class AcarsTest extends TestCase * Check the fields */ $this->assertHasKeys($pirep, ['fields']); - $this->assertEquals('custom_field', $pirep['fields'][0]['name']); - $this->assertEquals('custom_value', $pirep['fields'][0]['value']); + $this->assertEquals('custom_value', $pirep['fields']['custom_field']); $this->assertHasKeys($pirep['planned_distance'], ['mi', 'nmi', 'km']); @@ -323,17 +322,14 @@ class AcarsTest extends TestCase * Update the custom field */ $uri = '/api/pireps/'.$pirep_id.'/update'; - $this->post( - $uri, - [ - 'fields' => [ - 'custom_field' => 'custom_value_changed', - ], - ] - ); + $this->post($uri, [ + 'fields' => [ + 'custom_field' => 'custom_value_changed', + ], + ]); $pirep = $this->getPirep($pirep_id); - $this->assertEquals('custom_value_changed', $pirep['fields'][0]['value']); + $this->assertEquals('custom_value_changed', $pirep['fields']['custom_field']); /** * Add some position updates @@ -376,6 +372,18 @@ class AcarsTest extends TestCase $this->assertEquals(round($acars['lat'], 2), round($body[0]['lat'], 2)); $this->assertEquals(round($acars['lon'], 2), round($body[0]['lon'], 2)); + # Update fields standalone + $uri = '/api/pireps/' . $pirep_id . '/fields'; + $response = $this->post($uri, [ + 'fields' => [ + 'Departure Gate' => 'G26', + ], + ]); + + $response->assertStatus(200); + $body = $response->json('data'); + $this->assertEquals('G26', $body['Departure Gate']); + # File the PIREP now $uri = '/api/pireps/'.$pirep_id.'/file'; $response = $this->post($uri, []); @@ -384,14 +392,11 @@ class AcarsTest extends TestCase $response = $this->post($uri, ['flight_time' => '1:30']); $response->assertStatus(400); // invalid flight time - $response = $this->post( - $uri, - [ - 'flight_time' => 130, - 'fuel_used' => 8000.19, - 'distance' => 400, - ] - ); + $response = $this->post($uri, [ + 'flight_time' => 130, + 'fuel_used' => 8000.19, + 'distance' => 400, + ]); $response->assertStatus(200); $body = $response->json();