307 lines
8.8 KiB
PHP
307 lines
8.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Contracts\Controller;
|
|
use App\Enums\AcarsType;
|
|
use App\Events\AcarsUpdate;
|
|
use App\Exceptions\PirepCancelled;
|
|
use App\Exceptions\PirepNotFound;
|
|
use App\Http\Requests\Acars\EventRequest;
|
|
use App\Http\Requests\Acars\LogRequest;
|
|
use App\Http\Requests\Acars\PositionRequest;
|
|
use App\Http\Resources\AcarsRouteResource;
|
|
use App\Http\Resources\PirepResource;
|
|
use App\Models\Acars;
|
|
use App\Models\Pirep;
|
|
use App\Services\GeoService;
|
|
use Carbon\Carbon;
|
|
use DateTime;
|
|
use Illuminate\Database\QueryException;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
|
|
|
class AcarsController extends Controller
|
|
{
|
|
/**
|
|
* AcarsController constructor.
|
|
*/
|
|
public function __construct(
|
|
private readonly GeoService $geoSvc
|
|
) {}
|
|
|
|
/**
|
|
* Check if a PIREP is cancelled
|
|
*
|
|
*
|
|
* @throws PirepCancelled
|
|
*/
|
|
protected function checkCancelled(Pirep $pirep): void
|
|
{
|
|
if ($pirep->cancelled) {
|
|
throw new PirepCancelled($pirep);
|
|
}
|
|
}
|
|
|
|
protected function findPirepOrFail(string $id): Pirep
|
|
{
|
|
$pirep = Pirep::find($id);
|
|
|
|
if (empty($pirep)) {
|
|
throw new PirepNotFound($id);
|
|
}
|
|
|
|
return $pirep;
|
|
}
|
|
|
|
/**
|
|
* Get all the active PIREPs
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function live_flights()
|
|
{
|
|
$pireps = Pirep::activeFlights(setting('acars.live_time'))->get()->filter(
|
|
fn (Pirep $pirep): bool => $pirep->position !== null
|
|
);
|
|
|
|
return PirepResource::collection($pireps);
|
|
}
|
|
|
|
/**
|
|
* Return all of the flights (as points) in GeoJSON format
|
|
*/
|
|
public function pireps_geojson(Request $request): JsonResponse
|
|
{
|
|
$pireps = Pirep::activeFlights(setting('acars.live_time'))->get();
|
|
$positions = $this->geoSvc->getFeatureForLiveFlights($pireps);
|
|
|
|
return response()->json([
|
|
'data' => $positions,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Return the GeoJSON for the ACARS line
|
|
*/
|
|
public function acars_geojson(string $pirep_id, Request $request): JsonResponse
|
|
{
|
|
$pirep = $this->findPirepOrFail($pirep_id);
|
|
|
|
$geodata = $this->geoSvc->getFeatureFromAcars($pirep);
|
|
|
|
return response()->json([
|
|
'data' => $geodata,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Return the routes for the ACARS line
|
|
*/
|
|
public function acars_get(string $id, Request $request): AcarsRouteResource
|
|
{
|
|
$this->findPirepOrFail($id);
|
|
|
|
$acars = Acars::query()
|
|
->with('pirep')
|
|
->forPirep($id)
|
|
->flightPath()
|
|
->orderedBySimTime()
|
|
->get();
|
|
|
|
return new AcarsRouteResource($acars);
|
|
}
|
|
|
|
/**
|
|
* Post ACARS updates for a PIREP
|
|
*
|
|
*
|
|
* @throws PirepCancelled
|
|
* @throws BadRequestHttpException
|
|
*/
|
|
public function acars_store(string $id, PositionRequest $request): JsonResponse
|
|
{
|
|
// Check if the status is cancelled...
|
|
$pirep = $this->findPirepOrFail($id);
|
|
|
|
$this->checkCancelled($pirep);
|
|
|
|
/*Log::debug(
|
|
'Posting ACARS update (user: '.Auth::user()->ident.', 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 (isset($position['altitude'])) {
|
|
if (!isset($position['altitude_agl'])) {
|
|
$position['altitude_agl'] = $position['altitude'];
|
|
}
|
|
|
|
if (!isset($position['altitude_msl'])) {
|
|
$position['altitude_msl'] = $position['altitude'];
|
|
}
|
|
|
|
unset($position['altitude']);
|
|
}
|
|
|
|
if (isset($position['sim_time'])) {
|
|
if ($position['sim_time'] instanceof DateTime) {
|
|
$position['sim_time'] = Carbon::instance($position['sim_time']);
|
|
} else {
|
|
$position['sim_time'] = Carbon::createFromTimeString($position['sim_time']);
|
|
}
|
|
}
|
|
|
|
if (isset($position['created_at'])) {
|
|
if ($position['created_at'] instanceof DateTime) {
|
|
$position['created_at'] = Carbon::instance($position['created_at']);
|
|
} else {
|
|
$position['created_at'] = Carbon::createFromTimeString($position['created_at']);
|
|
}
|
|
}
|
|
|
|
try {
|
|
DB::transaction(function () use ($position): void {
|
|
if (!empty($position['id'])) {
|
|
Acars::updateOrInsert(
|
|
['id' => $position['id']],
|
|
$position
|
|
);
|
|
} else {
|
|
Acars::create($position);
|
|
}
|
|
});
|
|
|
|
$count++;
|
|
} catch (QueryException $ex) {
|
|
Log::info('Error on adding ACARS position: '.$ex->getMessage());
|
|
}
|
|
}
|
|
|
|
// Change the PIREP status if it's as SCHEDULED before
|
|
/*if ($pirep->status === PirepStatus::INITIATED) {
|
|
$pirep->status = PirepStatus::AIRBORNE;
|
|
}*/
|
|
|
|
$pirep->save();
|
|
|
|
// Post a new update for this ACARS position
|
|
event(new AcarsUpdate($pirep, $pirep->position));
|
|
|
|
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.
|
|
*
|
|
*
|
|
* @throws PirepCancelled
|
|
* @throws BadRequestHttpException
|
|
*/
|
|
public function acars_logs(string $id, LogRequest $request): JsonResponse
|
|
{
|
|
// Check if the status is cancelled...
|
|
$pirep = $this->findPirepOrFail($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;
|
|
|
|
if (isset($log['sim_time'])) {
|
|
$log['sim_time'] = Carbon::createFromTimeString($log['sim_time']);
|
|
}
|
|
|
|
if (isset($log['created_at'])) {
|
|
$log['created_at'] = Carbon::createFromTimeString($log['created_at']);
|
|
}
|
|
|
|
try {
|
|
DB::transaction(function () use ($log): void {
|
|
if (isset($log['id'])) {
|
|
Acars::updateOrInsert(
|
|
['id' => $log['id']],
|
|
$log
|
|
);
|
|
} else {
|
|
Acars::create($log);
|
|
}
|
|
});
|
|
|
|
$count++;
|
|
} catch (QueryException $ex) {
|
|
Log::info('Error on adding ACARS log: '.$ex->getMessage());
|
|
}
|
|
}
|
|
|
|
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.
|
|
*
|
|
*
|
|
* @throws PirepCancelled
|
|
* @throws BadRequestHttpException
|
|
*/
|
|
public function acars_events(string $id, EventRequest $request): JsonResponse
|
|
{
|
|
// Check if the status is cancelled...
|
|
$pirep = $this->findPirepOrFail($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'];
|
|
|
|
if (isset($log['sim_time'])) {
|
|
$log['sim_time'] = Carbon::createFromTimeString($log['sim_time']);
|
|
}
|
|
|
|
if (isset($log['created_at'])) {
|
|
$log['created_at'] = Carbon::createFromTimeString($log['created_at']);
|
|
}
|
|
|
|
try {
|
|
DB::transaction(function () use ($log): void {
|
|
if (isset($log['id'])) {
|
|
Acars::updateOrInsert(
|
|
['id' => $log['id']],
|
|
$log
|
|
);
|
|
} else {
|
|
Acars::create($log);
|
|
}
|
|
});
|
|
|
|
$count++;
|
|
} catch (QueryException $ex) {
|
|
Log::info('Error on adding ACARS event: '.$ex->getMessage());
|
|
}
|
|
}
|
|
|
|
return $this->message($count.' logs added', $count);
|
|
}
|
|
}
|