Compare commits

..

1 Commits

Author SHA1 Message Date
Nabeel Shahzad
18206f4601 Update the meta link to include query strings 2021-06-10 19:29:25 -04:00
271 changed files with 26448 additions and 16608 deletions

View File

@@ -15,10 +15,7 @@ declare -a remove_files=(
.idea
.travis
docker
node_modules
vendor/willdurand/geocoder/tests
_ide_helper.php
.env
.dockerignore
.dpl
.editorconfig
@@ -26,7 +23,6 @@ declare -a remove_files=(
.eslintrc
.php_cs
.php_cs.cache
.php-cs-fixer.php
.phpstorm.meta.php
.styleci.yml
.phpunit.result.cache
@@ -41,8 +37,9 @@ declare -a remove_files=(
phpvms.iml
Procfile
phpstan.neon
symfony.lock
node_modules
composer.phar
vendor/willdurand/geocoder/tests
)
for file in "${remove_files[@]}"; do
@@ -73,22 +70,14 @@ mkdir -p storage/framework/views
cd /tmp
echo "Current directory contents"
ls -al $BASE_DIR
echo "Parent directory contents"
ls -al $BASE_DIR/../
echo "Calling find"
find $BASE_DIR/../ -type d -maxdepth 2
tar -czf $TAR_NAME -C $BASE_DIR --xform 's:^\./::' . [--show-transformed-names|--show-stored-names]
tar -czf $TAR_NAME -C $BASE_DIR .
sha256sum $TAR_NAME >"$TAR_NAME.sha256"
cd $BASE_DIR;
zip -r $ZIP_NAME ./
zip -r $ZIP_NAME *
sha256sum $ZIP_NAME >"$ZIP_NAME.sha256"
mv $ZIP_NAME /tmp
mv "$ZIP_NAME.sha256" /tmp

View File

@@ -2,12 +2,12 @@ name: 'Build'
on: ['push', 'pull_request', 'workflow_dispatch', 'release']
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-18.04
if: github.repository == 'nabeelio/phpvms'
strategy:
fail-fast: true
matrix:
php-versions: ['7.3', '7.4', '8.0', '8.1']
php-versions: ['7.3', '7.4', '8.0']
name: PHP ${{ matrix.php-versions }}
env:
extensions: intl, pcov, mbstring
@@ -78,8 +78,7 @@ jobs:
- name: Run Tests
run: |
export PHP_CS_FIXER_IGNORE_ENV=1
vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php -v --dry-run --diff --using-cache=no
vendor/bin/php-cs-fixer fix --config=.php_cs -v --dry-run --diff --using-cache=no
vendor/bin/phpunit --debug --verbose
# This runs after all of the tests, run have run. Creates a cleaned up version of the
@@ -117,6 +116,7 @@ jobs:
- name: 'Install Release Dependencies'
run: |
rm -rf vendor
sudo npm i tar-to-zip -g
composer install --no-dev --prefer-dist --no-interaction --verbose
sudo chmod +x ./.github/scripts/*
@@ -179,6 +179,7 @@ jobs:
- name: 'Install Release Dependencies'
run: |
rm -rf vendor
sudo npm i tar-to-zip -g
composer install --no-dev --prefer-dist --no-interaction --verbose
sudo chmod +x ./.github/scripts/*

1
.gitignore vendored
View File

@@ -76,4 +76,3 @@ error_log
/config.php
/config.bak.php
/VERSION
sync.sh

View File

@@ -1,69 +0,0 @@
<?php
declare(strict_types=1);
/*
* This file is part of PHP CS Fixer.
*
* (c) Fabien Potencier <fabien@symfony.com>
* Dariusz Rumiński <dariusz.ruminski@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
$header = <<<'EOF'
This file is part of PHP CS Fixer.
(c) Fabien Potencier <fabien@symfony.com>
Dariusz Rumiński <dariusz.ruminski@gmail.com>
This source file is subject to the MIT license that is bundled
with this source code in the file LICENSE.
EOF;
$finder = PhpCsFixer\Finder::create()
->ignoreVCSIgnored(true)
->exclude('tests/data')
->exclude('storage')
->exclude('resources')
->in(__DIR__)
->append([
__DIR__.'/dev-tools/doc.php',
// __DIR__.'/php-cs-fixer', disabled, as we want to be able to run bootstrap file even on lower PHP version, to show nice message
__FILE__,
])
;
$config = new PhpCsFixer\Config();
$config
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'strict_param' => true,
'no_php4_constructor' => true,
'no_extra_blank_lines' => true,
'no_superfluous_elseif' => true,
'single_line_comment_style' => false,
'simple_to_complex_string_variable' => true,
'array_syntax' => [
'syntax' => 'short',
],
'binary_operator_spaces' => [
'operators' => [
'=>' => 'align_single_space_minimal'
]
],
/*
'blank_line_before_statement' => [
'statements' => [
'declare',
'for',
'return',
'throw',
'try',
],
],
*/
])
->setFinder($finder);
return $config;

37
.php_cs Normal file
View File

@@ -0,0 +1,37 @@
<?php
$finder = PhpCsFixer\Finder::create()
->in('app')
->in('config');
return PhpCsFixer\Config::create()
->setHideProgress(true)
->setUsingCache(false)
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'strict_param' => true,
'no_php4_constructor' => true,
'no_extra_blank_lines' => true,
'no_superfluous_elseif' => true,
'single_line_comment_style' => false,
'simple_to_complex_string_variable' => true,
'array_syntax' => [
'syntax' => 'short',
],
'binary_operator_spaces' => [
'align_double_arrow' => true,
],
/*
'blank_line_before_statement' => [
'statements' => [
'declare',
'for',
'return',
'throw',
'try',
],
],
*/
])
->setFinder($finder);

View File

@@ -1,11 +1,8 @@
FROM php:8.0.9-fpm-alpine3.14
FROM php:7.4-fpm-alpine
WORKDIR /var/www/
# Setup composer
COPY --from=composer:2.1.5 /usr/bin/composer /usr/local/bin/composer
RUN apk add gmp-dev icu-dev zlib-dev libpng-dev libzip-dev zip
RUN apk add gmp-dev icu-dev zlib-dev libpng-dev
RUN curl --silent --show-error https://getcomposer.org/installer | php
# Copy any config files in
@@ -19,19 +16,17 @@ RUN docker-php-ext-install \
pdo_mysql \
gd \
gmp \
bcmath \
opcache \
zip && \
docker-php-ext-enable pdo_mysql opcache bcmath zip
opcache && \
docker-php-ext-enable pdo_mysql opcache
COPY . /var/www/
RUN composer install \
RUN php composer.phar install \
--ignore-platform-reqs \
--no-interaction \
--no-plugins \
--no-scripts \
--prefer-dist
#RUN chown -R www-data:www-data /var/www
RUN chown -R www-data:www-data /var/www
EXPOSE 9000

View File

@@ -1,3 +1,5 @@
BSD 3-Clause License
Copyright (c) 2017, phpvms - http://www.phpvms.net
All rights reserved.
@@ -15,9 +17,6 @@ modification, are permitted provided that the following conditions are met:
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
* A "powered by phpvms" is required in page footers, unless the license has
purchased to omit it.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

View File

@@ -82,6 +82,10 @@ test:
phpcs:
@vendor/bin/php-cs-fixer fix --config=.php_cs -v --diff --diff-format=udiff --dry-run
#.PHONY: phpstan
#phpstan:
# vendor/bin/phpstan analyse -c phpstan.neon -v --level 2 app
.PHONY: replay-acars
replay-acars:
#@php artisan phpvms:replay AAL10,AAL3113,BAW172,DAL988,FIN6,MSR986 --manual
@@ -91,6 +95,11 @@ replay-acars:
sass-watch:
sass --watch public/assets/admin/sass/paper-dashboard.scss:public/assets/admin/css/paper-dashboard.css
.PHONY: schema
schema:
#php artisan infyom:scaffold Aircraft --fieldsFile=database/schema/aircraft.json
echo ""
.PHONY: deploy-package
deploy-package:
./.travis/deploy_script.sh
@@ -102,7 +111,7 @@ reset-installer:
.PHONY: docker-test
docker-test:
@docker compose -f docker-compose.yml -f docker-compose.local.yml up
@docker-compose -f docker-compose.yml -f docker-compose.local.yml up
.PHONY: docker-clean
docker-clean:

View File

@@ -22,11 +22,7 @@ class ProcessQueue extends Command
'--stop-when-empty' => null,
]);
$jobOutput = trim(Artisan::output());
if (!empty($jobOutput)) {
Log::info($jobOutput);
}
Log::info(Artisan::output());
///** @var App\Support\WorkCommand $queueWorker */
//$queueWorker = new App\Support\WorkCommand(app('queue.worker'), app('cache.store'));

View File

@@ -1,90 +0,0 @@
<?php
/**
* This runs any of the cron tasks that are set to run according to the Laravel schedule
*/
namespace App\Console;
use App\Console\Cron\FifteenMinute;
use App\Console\Cron\FiveMinute;
use App\Console\Cron\Hourly;
use App\Console\Cron\JobQueue;
use App\Console\Cron\Monthly;
use App\Console\Cron\Nightly;
use App\Console\Cron\ThirtyMinute;
use App\Console\Cron\Weekly;
use App\Contracts\Command;
use Illuminate\Console\Scheduling\Schedule;
class Cron
{
/** @var Schedule */
private $scheduler;
/**
* @var string[] The cron tasks which get called/run
*/
private $cronTasks = [
JobQueue::class,
FiveMinute::class,
FifteenMinute::class,
ThirtyMinute::class,
Hourly::class,
Nightly::class,
Weekly::class,
Monthly::class,
];
/**
* @var array Stores the instantiated cron tasks
*/
private $cronRunners = [];
/**
* @param Schedule $scheduler
*/
public function __construct(Schedule $scheduler)
{
$this->scheduler = $scheduler;
foreach ($this->cronTasks as $task) {
/** @var Command $cronTask */
$cronTask = app($task);
$signature = $cronTask->getSignature();
if (empty($signature)) {
continue;
}
$this->cronRunners[$signature] = $cronTask;
}
}
/**
* Try to figure out which commands are supposed to run right now
*
* @return array string of tasks that were run
*/
public function run(): array
{
$events = $this->scheduler->dueEvents(app());
if (empty($events)) {
return [];
}
$run = [];
/** @var \Illuminate\Console\Scheduling\Event $event */
foreach ($events as $event) {
foreach ($this->cronRunners as $signature => $task) {
if (!str_contains($event->command, $signature)) {
continue;
}
$task->callEvent();
$run[] = $signature;
}
}
return $run;
}
}

View File

@@ -1,26 +0,0 @@
<?php
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Events\CronFifteenMinute;
/**
* The actual cron tasks are in app/Cron
*/
class FifteenMinute extends CronCommand
{
protected $signature = 'cron:fifteen';
protected $description = 'Run the 15 minute cron tasks';
protected $schedule;
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
event(new CronFifteenMinute());
}
}

View File

@@ -1,29 +0,0 @@
<?php
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Events\CronFiveMinute;
/**
* This just calls the CronNightly event, so all of the
* listeners, etc can just be called to run those tasks
*
* The actual cron tasks are in app/Cron
*/
class FiveMinute extends CronCommand
{
protected $signature = 'cron:five';
protected $description = 'Run the 5 minute cron tasks';
protected $schedule;
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
event(new CronFiveMinute());
}
}

View File

@@ -2,14 +2,14 @@
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Contracts\Command;
use App\Events\CronHourly;
/**
* This just calls the CronHourly event, so all of the
* listeners, etc can just be called to run those tasks
*/
class Hourly extends CronCommand
class Hourly extends Command
{
protected $signature = 'cron:hourly';
protected $description = 'Run the hourly cron tasks';
@@ -17,11 +17,7 @@ class Hourly extends CronCommand
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
$this->redirectLoggingToFile('cron');
event(new CronHourly());
}
}

View File

@@ -2,14 +2,14 @@
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Contracts\Command;
use Illuminate\Support\Facades\Artisan;
/**
* This just calls the CronHourly event, so all of the
* listeners, etc can just be called to run those tasks
*/
class JobQueue extends CronCommand
class JobQueue extends Command
{
protected $signature = 'cron:queue';
protected $description = 'Run the cron queue tasks';
@@ -17,16 +17,9 @@ class JobQueue extends CronCommand
public function handle(): void
{
$this->callEvent();
$queueOutput = trim(Artisan::output());
if (!empty($queueOutput)) {
$this->info($queueOutput);
}
}
public function callEvent()
{
$this->redirectLoggingToFile('cron');
Artisan::call('queue:cron');
$this->info(Artisan::output());
}
}

View File

@@ -2,7 +2,7 @@
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Contracts\Command;
use App\Events\CronMonthly;
/**
@@ -11,7 +11,7 @@ use App\Events\CronMonthly;
*
* The actual cron tasks are in app/Cron
*/
class Monthly extends CronCommand
class Monthly extends Command
{
protected $signature = 'cron:monthly';
protected $description = 'Run the monthly cron tasks';
@@ -19,11 +19,7 @@ class Monthly extends CronCommand
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
$this->redirectLoggingToFile('cron');
event(new CronMonthly());
}
}

View File

@@ -2,7 +2,7 @@
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Contracts\Command;
use App\Events\CronNightly;
/**
@@ -11,7 +11,7 @@ use App\Events\CronNightly;
*
* The actual cron tasks are in app/Cron
*/
class Nightly extends CronCommand
class Nightly extends Command
{
protected $signature = 'cron:nightly';
protected $description = 'Run the nightly cron tasks';
@@ -19,11 +19,7 @@ class Nightly extends CronCommand
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
$this->redirectLoggingToFile('cron');
event(new CronNightly());
}
}

View File

@@ -1,26 +0,0 @@
<?php
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Events\CronThirtyMinute;
/**
* The actual cron tasks are in app/Cron
*/
class ThirtyMinute extends CronCommand
{
protected $signature = 'cron:thirty';
protected $description = 'Run the 30 minute cron tasks';
protected $schedule;
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
event(new CronThirtyMinute());
}
}

View File

@@ -2,7 +2,7 @@
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Contracts\Command;
use App\Events\CronWeekly;
/**
@@ -11,7 +11,7 @@ use App\Events\CronWeekly;
*
* The actual cron tasks are in app/Cron
*/
class Weekly extends CronCommand
class Weekly extends Command
{
protected $signature = 'cron:weekly';
protected $description = 'Run the weekly cron tasks';
@@ -19,11 +19,7 @@ class Weekly extends CronCommand
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
$this->redirectLoggingToFile('cron');
event(new CronWeekly());
}
}

View File

@@ -2,13 +2,10 @@
namespace App\Console;
use App\Console\Cron\FifteenMinute;
use App\Console\Cron\FiveMinute;
use App\Console\Cron\Hourly;
use App\Console\Cron\JobQueue;
use App\Console\Cron\Monthly;
use App\Console\Cron\Nightly;
use App\Console\Cron\ThirtyMinute;
use App\Console\Cron\Weekly;
use App\Services\CronService;
use Illuminate\Console\Scheduling\Schedule;
@@ -36,16 +33,10 @@ class Kernel extends ConsoleKernel
->withoutOverlapping();
}
/*
* NOTE: IF MORE TASKS ARE ADDED, THEY ALSO MUST BE ADDED TO THE CRON.PHP
*/
$schedule->command(FiveMinute::class)->everyFiveMinutes();
$schedule->command(FifteenMinute::class)->everyFifteenMinutes();
$schedule->command(ThirtyMinute::class)->everyThirtyMinutes();
$schedule->command(Nightly::class)->dailyAt('01:00');
$schedule->command(Hourly::class)->hourly();
$schedule->command(Weekly::class)->weeklyOn(0);
$schedule->command(Monthly::class)->monthlyOn(1);
$schedule->command(Hourly::class)->hourly();
// When spatie-backups runs
/*if (config('backup.backup.enabled', false) === true) {

View File

@@ -29,16 +29,6 @@ abstract class Command extends \Illuminate\Console\Command
}*/
}
/**
* Return the signature of the command
*
* @return string
*/
public function getSignature(): string
{
return $this->signature;
}
/**
* Splice the logger and replace the active handlers with the handlers from the
* a stack in config/logging.php

View File

@@ -87,17 +87,16 @@ abstract class Controller extends \Illuminate\Routing\Controller
*
* @return \Illuminate\Http\JsonResponse
*/
public function message($message, $count = null, $attrs = [])
public function message($message, $count = null)
{
$ret = [
$attrs = [
'message' => $message,
'attrs' => $attrs,
];
if ($count !== null) {
$ret['count'] = $count;
$attrs['count'] = $count;
}
return response()->json($ret);
return response()->json($attrs);
}
}

View File

@@ -1,20 +0,0 @@
<?php
namespace App\Contracts;
abstract class CronCommand extends Command
{
/**
* @return mixed
*/
abstract public function callEvent();
/**
* Adjust the logging depending on where we're running from
*/
public function __construct()
{
parent::__construct();
$this->redirectLoggingToFile('cron');
}
}

View File

@@ -166,36 +166,10 @@ class ImportExport
return [];
}
if (strpos($split_values[0], '?') !== false) {
// This contains the query string, which turns it into a multi-level array
$query_str = explode('?', $split_values[0]);
$parent = trim($query_str[0]);
$children = [];
$kvp = explode('&', trim($query_str[1]));
foreach ($kvp as $items) {
if (!$items) {
continue;
}
$this->kvpToArray($items, $children);
}
$ret[$parent] = $children;
return $ret;
}
// This is not a query string, return it back untouched
return [$split_values[0]];
}
foreach ($split_values as $value) {
$value = trim($value);
if ($value === '') {
continue;
}
// This isn't in the query string format, so it's
// just a straight key-value pair set
if (strpos($value, '?') === false) {

View File

@@ -2,6 +2,7 @@
namespace App\Contracts;
use App\Notifications\Channels\Discord\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -25,4 +26,24 @@ class Notification extends \Illuminate\Notifications\Notification implements Sho
$this->channels = $notif_config[$klass];*/
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
*
* @return array
*/
/*public function via($notifiable)
{
return $this->channels;
}*/
/**
* @return DiscordMessage|null
*/
public function toDiscordChannel($notifiable): ?DiscordMessage
{
return null;
}
}

View File

@@ -20,7 +20,7 @@ class ClearExpiredSimbrief extends Listener
}
/**
* @param CronHourly $event
* @param \App\Events\CronNightly $event
*/
public function handle(CronHourly $event): void
{

View File

@@ -5,7 +5,6 @@ namespace App\Cron\Hourly;
use App\Contracts\Listener;
use App\Events\CronHourly;
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
use App\Models\Pirep;
use App\Services\PirepService;
use Carbon\Carbon;
@@ -39,10 +38,7 @@ class DeletePireps extends Listener
protected function deletePireps(int $expire_time_hours, int $state)
{
$dt = Carbon::now('UTC')->subHours($expire_time_hours);
$pireps = Pirep::where('created_at', '<', $dt)
->where(['state' => $state])
->where('status', '<>', PirepStatus::PAUSED)
->get();
$pireps = Pirep::where('created_at', '<', $dt)->where(['state' => $state])->get();
/** @var PirepService $pirepSvc */
$pirepSvc = app(PirepService::class);

View File

@@ -6,7 +6,6 @@ use App\Contracts\Listener;
use App\Events\CronHourly;
use App\Events\PirepCancelled;
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
use App\Models\Pirep;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
@@ -32,9 +31,7 @@ class RemoveExpiredLiveFlights extends Listener
$date = Carbon::now('UTC')->subHours(setting('acars.live_time'));
$pireps = Pirep::where('updated_at', '<', $date)
->where('state', PirepState::IN_PROGRESS)
->where('status', '<>', PirepStatus::PAUSED)
->get();
foreach ($pireps as $pirep) {
event(new PirepCancelled($pirep));
Log::info('Cron: Deleting Expired Live PIREP id='.$pirep->id.', state='.PirepState::label($pirep->state));

View File

@@ -1,53 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddTypeRatingTables extends Migration
{
public function up()
{
if (!Schema::hasTable('typeratings')) {
Schema::create('typeratings', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('type');
$table->string('description')->nullable();
$table->string('image_url')->nullable();
$table->boolean('active')->default(true);
$table->timestamps();
$table->unique('id');
$table->unique('name');
});
}
if (!Schema::hasTable('typerating_user')) {
Schema::create('typerating_user', function (Blueprint $table) {
$table->unsignedInteger('typerating_id');
$table->unsignedInteger('user_id');
$table->primary(['typerating_id', 'user_id']);
$table->index(['typerating_id', 'user_id']);
});
}
if (!Schema::hasTable('typerating_subfleet')) {
Schema::create('typerating_subfleet', function (Blueprint $table) {
$table->unsignedInteger('typerating_id');
$table->unsignedInteger('subfleet_id');
$table->primary(['typerating_id', 'subfleet_id']);
$table->index(['typerating_id', 'subfleet_id']);
});
}
}
public function down()
{
Schema::dropIfExists('typeratings');
Schema::dropIfExists('typerating_user');
Schema::dropIfExists('typerating_subfleet');
}
}

View File

@@ -1,15 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddHubToAircraft extends Migration
{
public function up()
{
Schema::table('aircraft', function (Blueprint $table) {
$table->string('hub_id', 5)->nullable()->after('airport_id');
});
}
}

View File

@@ -1,15 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateAwardsAddActive extends Migration
{
public function up()
{
Schema::table('awards', function (Blueprint $table) {
$table->boolean('active')->default(true)->nullable()->after('ref_model_params');
});
}
}

View File

@@ -1,15 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateUsersAddNotes extends Migration
{
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->mediumText('notes')->nullable()->after('remember_token');
});
}
}

View File

@@ -36,8 +36,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb1
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
@@ -55,8 +54,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb2
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
@@ -74,8 +72,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb3
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
@@ -93,8 +90,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb34
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
@@ -112,8 +108,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb35
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
@@ -131,8 +126,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb36
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
@@ -150,8 +144,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb37
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
@@ -169,8 +162,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb38
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
@@ -188,8 +180,7 @@ acars:
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: 9aAN4mxlK9zb39
pirep_id: b68R5gwVzpVe
- pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'

View File

@@ -34,28 +34,6 @@ airports:
lon: -97.6698889
hub: 1
ground_handling_cost: 100
- id: KHPN
iata: HPN
icao: KHPN
name: Westchester County Airport
location: White Plains
country: United States
timezone: America/New_York
lat: 41.067
lon: -73.7076
hub: 1
ground_handling_cost: 100
- id: KLGA
iata: LGA
icao: KLGA
name: La Guardia Airport
location: New York, New York, USA
country: United States
timezone: America/New_York
lat: 40.7772
lon: -73.8726
hub: 1
ground_handling_cost: 250
- id: KJFK
iata: JFK
icao: KJFK
@@ -470,21 +448,6 @@ flights:
- id: flightid_1
airline_id: 1
flight_number: 100
dpt_airport_id: KHPN
arr_airport_id: KJFK
route: DCT CMK V374 DENNA V44 BELTT/N0346F140 V44 DPK DCT
distance: 113
level: 110
dpt_time: 6PM CST
arr_time: 11PM EST
flight_time: 240
flight_type: J
load_factor: 100
created_at: NOW
updated_at: NOW
- id: flightid_2
airline_id: 1
flight_number: 101
dpt_airport_id: KAUS
arr_airport_id: KJFK
route: KAUS SID TNV J87 IAH J2 LCH J22 MEI J239 ATL J52 AJFEB J14 BYJAC Q60 JAXSN J14 COLIN J61 HUBBS J55 SIE STAR KJFK
@@ -586,21 +549,6 @@ flights:
visible: 1
created_at: now
updated_at: now
- id: flightid_4
airline_id: 1
flight_number: 100
dpt_airport_id: KHPN
arr_airport_id: KLGA
route: DCT CMK V374 DENNA V44 BELTT/N0346F140 V44 DPK DCT
distance: 75
level: 110
dpt_time: 6PM CST
arr_time: 11PM EST
flight_time: 240
flight_type: J
load_factor: 100
created_at: NOW
updated_at: NOW
flight_fields:
- name: Departure Terminal

File diff suppressed because one or more lines are too long

View File

@@ -42,9 +42,6 @@
- name: ranks
display_name: Ranks
description: Create/edit ranks
- name: typeratings
display_name: Type Ratings
description: Create/edit type ratings
- name: users
display_name: Users
description: Create/edit users

View File

@@ -137,13 +137,6 @@
options: ''
type: int
description: 'Initial zoom level on the map'
- key: acars.update_interval
name: 'Refresh Interval'
group: acars
value: 60
options: ''
type: int
description: 'How often the live map updates its data'
- key: airports.default_ground_handling_cost
name: 'Default Ground Handling Cost'
group: airports
@@ -290,14 +283,7 @@
value: true
options: ''
type: boolean
description: 'Aircraft restricted to user''s rank'
- key: pireps.restrict_aircraft_to_typerating
name: 'Restrict Aircraft by Type Ratings'
group: pireps
value: false
options: ''
type: boolean
description: 'Aircraft restricted to user type ratings'
description: 'Aircraft that can be flown are restricted to a user''s rank'
- key: pireps.only_aircraft_at_dpt_airport
name: 'Restrict Aircraft At Departure'
group: pireps
@@ -333,13 +319,6 @@
options: ''
type: int
description: 'The length of a pilot''s ID'
- key: pilots.id_code
name: 'Pilot ID Code'
group: pilots
value: ''
options: ''
type: text
description: 'Fixed ICAO code for pilot IDs'
- key: pilots.auto_accept
name: 'Auto Accept New Pilot'
group: pilots
@@ -410,41 +389,6 @@
options: ''
type: text
description: The Discord Webhook URL for private notifications
- key: notifications.discord_pirep_status
name: Discord Pirep Messages (Public)
group: notifications
value: true
options: ''
type: boolean
description: Pirep status messages (Only key events are being sent)
- key: notifications.mail_pirep_admin
name: Pirep Filed (Admin)
group: notifications
value: true
options: ''
type: boolean
description: Pirep filed mails sent to admins
- key: notifications.mail_pirep_user_ack
name: Pirep Accepted (Pilot)
group: notifications
value: true
options: ''
type: boolean
description: Pirep Accepted mails sent to pilots
- key: notifications.mail_pirep_user_rej
name: Pirep Rejected (Pilot)
group: notifications
value: true
options: ''
type: boolean
description: Pirep Rejected mails sent to pilots
- key: notifications.mail_news
name: News Mails
group: notifications
value: true
options: ''
type: boolean
description: News mails sent to all members
- key: 'cron.random_id'
name: 'Cron Randomized ID'
group: 'cron'

View File

@@ -1,9 +0,0 @@
<?php
namespace App\Events;
use App\Contracts\Event;
class CronFifteenMinute extends Event
{
}

View File

@@ -1,9 +0,0 @@
<?php
namespace App\Events;
use App\Contracts\Event;
class CronFiveMinute extends Event
{
}

View File

@@ -1,9 +0,0 @@
<?php
namespace App\Events;
use App\Contracts\Event;
class CronThirtyMinute extends Event
{
}

View File

@@ -1,39 +0,0 @@
<?php
namespace App\Events;
use App\Contracts\Event;
use App\Models\Pirep;
/**
* This event is dispatched when the fares for a flight report
* are collected. Your listeners should return a list of Fare
* models. Don't call save on the model!
*
* Example return:
*
* new Fare([
* 'name' => '', # displayed as the memo
* 'type' => [INTEGER], # from FareType enum class
* 'price' => [DECIMAL],
* 'cost' => [DECIMAL], # optional
* 'notes' => '', # used as Transaction Group
* ]);
*
* The event caller will check the 'type' to make sure that it
* will filter out fares that only apply to the current process
*
* The event will have a copy of the PIREP model, if it's applicable
*/
class Fares extends Event
{
public $pirep;
/**
* @param Pirep|null $pirep
*/
public function __construct(Pirep $pirep = null)
{
$this->pirep = $pirep;
}
}

View File

@@ -1,43 +0,0 @@
<?php
namespace App\Exceptions;
class BidNotFound extends AbstractHttpException
{
private $bid_id;
public function __construct($bid_id)
{
$this->bid_id = $bid_id;
parent::__construct(
404,
'The bid '.$bid_id.' was not found'
);
}
/**
* Return the RFC 7807 error type (without the URL root)
*/
public function getErrorType(): string
{
return 'bid-not-found';
}
/**
* Get the detailed error string
*/
public function getErrorDetails(): string
{
return $this->getMessage();
}
/**
* Return an array with the error details, merged with the RFC7807 response
*/
public function getErrorMetadata(): array
{
return [
'bid_id' => $this->bid_id,
];
}
}

View File

@@ -79,7 +79,6 @@ class AircraftController extends Controller
{
return view('admin.aircraft.create', [
'airports' => $this->airportRepo->selectBoxList(),
'hubs' => $this->airportRepo->selectBoxList(true, true),
'subfleets' => Subfleet::all()->pluck('name', 'id'),
'statuses' => AircraftStatus::select(false),
'subfleet_id' => $request->query('subfleet'),
@@ -144,7 +143,6 @@ class AircraftController extends Controller
return view('admin.aircraft.edit', [
'aircraft' => $aircraft,
'airports' => $this->airportRepo->selectBoxList(),
'hubs' => $this->airportRepo->selectBoxList(true, true),
'subfleets' => Subfleet::all()->pluck('name', 'id'),
'statuses' => AircraftStatus::select(false),
]);

View File

@@ -38,7 +38,7 @@ class AirlinesController extends Controller
public function index(Request $request)
{
$this->airlineRepo->pushCriteria(new RequestCriteria($request));
$airlines = $this->airlineRepo->orderby('name', 'asc')->get();
$airlines = $this->airlineRepo->all();
return view('admin.airlines.index', [
'airlines' => $airlines,

View File

@@ -300,18 +300,14 @@ class FlightController extends Controller
public function export(Request $request)
{
$exporter = app(ExportService::class);
$where = [];
$file_name = 'flights.csv';
if ($request->input('airline_id')) {
$airline_id = $request->input('airline_id');
$where['airline_id'] = $airline_id;
$file_name = 'flights-'.$airline_id.'.csv';
}
$flights = $this->flightRepo->where($where)->orderBy('airline_id')->orderBy('flight_number')->orderBy('route_code')->orderBy('route_leg')->get();
$flights = $this->flightRepo->all();
$path = $exporter->exportFlights($flights);
return response()->download($path, $file_name, ['content-type' => 'text/csv'])->deleteFileAfterSend(true);
return response()
->download($path, 'flights.csv', [
'content-type' => 'text/csv',
])
->deleteFileAfterSend(true);
}
/**

View File

@@ -9,7 +9,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
class ModulesController extends Controller
@@ -30,7 +29,6 @@ class ModulesController extends Controller
{
$modules = $this->moduleSvc->getAllModules();
$new_modules = $this->moduleSvc->scan();
return view('admin.modules.index', [
'modules' => $modules,
'new_modules' => $new_modules,
@@ -99,14 +97,7 @@ class ModulesController extends Controller
*/
public function enable(Request $request)
{
$moduleName = $request->input('name');
try {
$this->moduleSvc->addModule($moduleName);
} catch (\Exception $e) {
Log::error('Error activating module '.$moduleName);
}
$this->moduleSvc->addModule($request->input('name'));
return redirect(route('admin.modules.index'));
}

View File

@@ -9,7 +9,6 @@ use App\Models\Enums\PirepSource;
use App\Models\Enums\PirepState;
use App\Models\Pirep;
use App\Models\PirepComment;
use App\Models\PirepFare;
use App\Repositories\AircraftRepository;
use App\Repositories\AirlineRepository;
use App\Repositories\AirportRepository;
@@ -152,10 +151,10 @@ class PirepController extends Controller
$count = $request->input($field_name);
}
$fares[] = new PirepFare([
$fares[] = [
'fare_id' => $fare->id,
'count' => $count,
]);
];
}
$this->fareSvc->saveForPirep($pirep, $fares);

View File

@@ -17,7 +17,6 @@ use App\Repositories\AircraftRepository;
use App\Repositories\FareRepository;
use App\Repositories\RankRepository;
use App\Repositories\SubfleetRepository;
use App\Repositories\TypeRatingRepository;
use App\Services\ExportService;
use App\Services\FareService;
use App\Services\FleetService;
@@ -37,29 +36,26 @@ class SubfleetController extends Controller
private $importSvc;
private $rankRepo;
private $subfleetRepo;
private $typeratingRepo;
/**
* SubfleetController constructor.
*
* @param AircraftRepository $aircraftRepo
* @param FareRepository $fareRepo
* @param FareService $fareSvc
* @param FleetService $fleetSvc
* @param ImportService $importSvc
* @param RankRepository $rankRepo
* @param SubfleetRepository $subfleetRepo
* @param TypeRatingRepository $typeratingRepo
* @param AircraftRepository $aircraftRepo
* @param FleetService $fleetSvc
* @param FareRepository $fareRepo
* @param FareService $fareSvc
* @param ImportService $importSvc
* @param RankRepository $rankRepo
* @param SubfleetRepository $subfleetRepo
*/
public function __construct(
AircraftRepository $aircraftRepo,
FleetService $fleetSvc,
FareRepository $fareRepo,
FareService $fareSvc,
FleetService $fleetSvc,
ImportService $importSvc,
RankRepository $rankRepo,
SubfleetRepository $subfleetRepo,
TypeRatingRepository $typeratingRepo
SubfleetRepository $subfleetRepo
) {
$this->aircraftRepo = $aircraftRepo;
$this->fareRepo = $fareRepo;
@@ -68,7 +64,48 @@ class SubfleetController extends Controller
$this->importSvc = $importSvc;
$this->rankRepo = $rankRepo;
$this->subfleetRepo = $subfleetRepo;
$this->typeratingRepo = $typeratingRepo;
}
/**
* Get the ranks that are available to the subfleet
*
* @param $subfleet
*
* @return array
*/
protected function getAvailRanks($subfleet)
{
$retval = [];
$all_ranks = $this->rankRepo->all();
$avail_ranks = $all_ranks->except($subfleet->ranks->modelKeys());
foreach ($avail_ranks as $rank) {
$retval[$rank->id] = $rank->name;
}
return $retval;
}
/**
* Get all the fares that haven't been assigned to a given subfleet
*
* @param mixed $subfleet
*
* @return array
*/
protected function getAvailFares($subfleet)
{
$retval = [];
$all_fares = $this->fareRepo->all();
$avail_fares = $all_fares->except($subfleet->fares->modelKeys());
foreach ($avail_fares as $fare) {
$retval[$fare->id] = $fare->name.
' (price: '.$fare->price.
', type: '.FareType::label($fare->type).
', cost: '.$fare->cost.
', capacity: '.$fare->capacity.')';
}
return $retval;
}
/**
@@ -83,7 +120,7 @@ class SubfleetController extends Controller
public function index(Request $request)
{
$this->subfleetRepo->with(['airline'])->pushCriteria(new RequestCriteria($request));
$subfleets = $this->subfleetRepo->orderby('name', 'asc')->get();
$subfleets = $this->subfleetRepo->all();
return view('admin.subfleets.index', [
'subfleets' => $subfleets,
@@ -115,8 +152,8 @@ class SubfleetController extends Controller
{
$input = $request->all();
$subfleet = $this->subfleetRepo->create($input);
Flash::success('Subfleet saved successfully.');
Flash::success('Subfleet saved successfully.');
return redirect(route('admin.subfleets.edit', [$subfleet->id]));
}
@@ -135,12 +172,10 @@ class SubfleetController extends Controller
if (empty($subfleet)) {
Flash::error('Subfleet not found');
return redirect(route('admin.subfleets.index'));
}
$avail_fares = $this->getAvailFares($subfleet);
return view('admin.subfleets.show', [
'subfleet' => $subfleet,
'avail_fares' => $avail_fares,
@@ -157,27 +192,24 @@ class SubfleetController extends Controller
public function edit($id)
{
$subfleet = $this->subfleetRepo
->with(['fares', 'ranks', 'typeratings'])
->with(['fares', 'ranks'])
->findWithoutFail($id);
if (empty($subfleet)) {
Flash::error('Subfleet not found');
return redirect(route('admin.subfleets.index'));
}
$avail_fares = $this->getAvailFares($subfleet);
$avail_ranks = $this->getAvailRanks($subfleet);
$avail_ratings = $this->getAvailTypeRatings($subfleet);
return view('admin.subfleets.edit', [
'airlines' => Airline::all()->pluck('name', 'id'),
'hubs' => Airport::where('hub', 1)->pluck('name', 'id'),
'fuel_types' => FuelType::labels(),
'avail_fares' => $avail_fares,
'avail_ranks' => $avail_ranks,
'avail_ratings' => $avail_ratings,
'subfleet' => $subfleet,
'airlines' => Airline::all()->pluck('name', 'id'),
'hubs' => Airport::where('hub', 1)->pluck('name', 'id'),
'fuel_types' => FuelType::labels(),
'avail_fares' => $avail_fares,
'avail_ranks' => $avail_ranks,
'subfleet' => $subfleet,
]);
}
@@ -197,13 +229,12 @@ class SubfleetController extends Controller
if (empty($subfleet)) {
Flash::error('Subfleet not found');
return redirect(route('admin.subfleets.index'));
}
$this->subfleetRepo->update($request->all(), $id);
Flash::success('Subfleet updated successfully.');
Flash::success('Subfleet updated successfully.');
return redirect(route('admin.subfleets.index'));
}
@@ -220,7 +251,6 @@ class SubfleetController extends Controller
if (empty($subfleet)) {
Flash::error('Subfleet not found');
return redirect(route('admin.subfleets.index'));
}
@@ -229,13 +259,12 @@ class SubfleetController extends Controller
$aircraft = $this->aircraftRepo->findWhere(['subfleet_id' => $id], ['id']);
if ($aircraft->count() > 0) {
Flash::error('There are aircraft still assigned to this subfleet, you can\'t delete it!')->important();
return redirect(route('admin.subfleets.index'));
}
$this->subfleetRepo->delete($id);
Flash::success('Subfleet deleted successfully.');
Flash::success('Subfleet deleted successfully.');
return redirect(route('admin.subfleets.index'));
}
@@ -252,8 +281,11 @@ class SubfleetController extends Controller
$subfleets = $this->subfleetRepo->all();
$path = $exporter->exportSubfleets($subfleets);
return response()->download($path, 'subfleets.csv', ['content-type' => 'text/csv'])->deleteFileAfterSend(true);
return response()
->download($path, 'subfleets.csv', [
'content-type' => 'text/csv',
])
->deleteFileAfterSend(true);
}
/**
@@ -280,64 +312,77 @@ class SubfleetController extends Controller
}
/**
* Get all the fares that haven't been assigned to a given subfleet
* @param Subfleet $subfleet
*
* @param mixed $subfleet
*
* @return array
* @return mixed
*/
protected function getAvailFares($subfleet)
protected function return_ranks_view(?Subfleet $subfleet)
{
$retval = [];
$all_fares = $this->fareRepo->all();
$avail_fares = $all_fares->except($subfleet->fares->modelKeys());
foreach ($avail_fares as $fare) {
$retval[$fare->id] = $fare->name.
' (price: '.$fare->price.
', type: '.FareType::label($fare->type).
', cost: '.$fare->cost.
', capacity: '.$fare->capacity.')';
}
$subfleet->refresh();
return $retval;
$avail_ranks = $this->getAvailRanks($subfleet);
return view('admin.subfleets.ranks', [
'subfleet' => $subfleet,
'avail_ranks' => $avail_ranks,
]);
}
/**
* Get the ranks that are available to the subfleet
* @param Subfleet $subfleet
*
* @param $subfleet
*
* @return array
* @return mixed
*/
protected function getAvailRanks($subfleet)
protected function return_fares_view(?Subfleet $subfleet)
{
$retval = [];
$all_ranks = $this->rankRepo->all();
$avail_ranks = $all_ranks->except($subfleet->ranks->modelKeys());
foreach ($avail_ranks as $rank) {
$retval[$rank->id] = $rank->name;
}
$subfleet->refresh();
return $retval;
$avail_fares = $this->getAvailFares($subfleet);
return view('admin.subfleets.fares', [
'subfleet' => $subfleet,
'avail_fares' => $avail_fares,
]);
}
/**
* Get the type ratings that are available to the subfleet
* Operations for associating ranks to the subfleet
*
* @param $subfleet
* @param $id
* @param Request $request
*
* @return array
* @return mixed
*/
protected function getAvailTypeRatings($subfleet)
public function ranks($id, Request $request)
{
$retval = [];
$all_ratings = $this->typeratingRepo->all();
$avail_ratings = $all_ratings->except($subfleet->typeratings->modelKeys());
foreach ($avail_ratings as $tr) {
$retval[$tr->id] = $tr->name.' ('.$tr->type.')';
$subfleet = $this->subfleetRepo->findWithoutFail($id);
if (empty($subfleet)) {
return $this->return_ranks_view($subfleet);
}
return $retval;
if ($request->isMethod('get')) {
return $this->return_ranks_view($subfleet);
}
/*
* update specific rank data
*/
if ($request->isMethod('post')) {
$rank = $this->rankRepo->find($request->input('rank_id'));
$this->fleetSvc->addSubfleetToRank($subfleet, $rank);
} elseif ($request->isMethod('put')) {
$override = [];
$rank = $this->rankRepo->find($request->input('rank_id'));
$override[$request->name] = $request->value;
$this->fleetSvc->addSubfleetToRank($subfleet, $rank, $override);
} // dissassociate fare from teh aircraft
elseif ($request->isMethod('delete')) {
$rank = $this->rankRepo->find($request->input('rank_id'));
$this->fleetSvc->removeSubfleetFromRank($subfleet, $rank);
}
$subfleet->save();
return $this->return_ranks_view($subfleet);
}
/**
@@ -353,54 +398,6 @@ class SubfleetController extends Controller
]);
}
/**
* @param Subfleet $subfleet
*
* @return mixed
*/
protected function return_fares_view(?Subfleet $subfleet)
{
$subfleet->refresh();
$avail_fares = $this->getAvailFares($subfleet);
return view('admin.subfleets.fares', [
'subfleet' => $subfleet,
'avail_fares' => $avail_fares,
]);
}
/**
* @param Subfleet $subfleet
*
* @return mixed
*/
protected function return_ranks_view(?Subfleet $subfleet)
{
$subfleet->refresh();
$avail_ranks = $this->getAvailRanks($subfleet);
return view('admin.subfleets.ranks', [
'subfleet' => $subfleet,
'avail_ranks' => $avail_ranks,
]);
}
/**
* @param Subfleet $subfleet
*
* @return mixed
*/
protected function return_typeratings_view(?Subfleet $subfleet)
{
$subfleet->refresh();
$avail_ratings = $this->getAvailTypeRatings($subfleet);
return view('admin.subfleets.type_ratings', [
'subfleet' => $subfleet,
'avail_ratings' => $avail_ratings,
]);
}
/**
* Operations for associating ranks to the subfleet
*
@@ -482,79 +479,4 @@ class SubfleetController extends Controller
return $this->return_fares_view($subfleet);
}
/**
* Operations for associating ranks to the subfleet
*
* @param $id
* @param Request $request
*
* @return mixed
*/
public function ranks($id, Request $request)
{
$subfleet = $this->subfleetRepo->findWithoutFail($id);
if (empty($subfleet)) {
return $this->return_ranks_view($subfleet);
}
if ($request->isMethod('get')) {
return $this->return_ranks_view($subfleet);
}
// associate rank with the subfleet
if ($request->isMethod('post')) {
$rank = $this->rankRepo->find($request->input('rank_id'));
$this->fleetSvc->addSubfleetToRank($subfleet, $rank);
} // override definitions
elseif ($request->isMethod('put')) {
$override = [];
$rank = $this->rankRepo->find($request->input('rank_id'));
$override[$request->name] = $request->value;
$this->fleetSvc->addSubfleetToRank($subfleet, $rank, $override);
} // dissassociate rank from the subfleet
elseif ($request->isMethod('delete')) {
$rank = $this->rankRepo->find($request->input('rank_id'));
$this->fleetSvc->removeSubfleetFromRank($subfleet, $rank);
}
$subfleet->save();
return $this->return_ranks_view($subfleet);
}
/**
* Operations for associating type ratings to the subfleet
*
* @param $id
* @param Request $request
*
* @return mixed
*/
public function typeratings($id, Request $request)
{
$subfleet = $this->subfleetRepo->findWithoutFail($id);
if (empty($subfleet)) {
return $this->return_typeratings_view($subfleet);
}
if ($request->isMethod('get')) {
return $this->return_typeratings_view($subfleet);
}
// associate subfleet with type rating
if ($request->isMethod('post')) {
$typerating = $this->typeratingRepo->find($request->input('typerating_id'));
$this->fleetSvc->addSubfleetToTypeRating($subfleet, $typerating);
} // dissassociate subfleet from the type rating
elseif ($request->isMethod('delete')) {
$typerating = $this->typeratingRepo->find($request->input('typerating_id'));
$this->fleetSvc->removeSubfleetFromTypeRating($subfleet, $typerating);
}
$subfleet->save();
return $this->return_typeratings_view($subfleet);
}
}

View File

@@ -1,167 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Contracts\Controller;
use App\Http\Requests\CreateTypeRatingRequest;
use App\Http\Requests\UpdateTypeRatingRequest;
use App\Repositories\SubfleetRepository;
use App\Repositories\TypeRatingRepository;
use App\Services\FleetService;
use Cache;
use Illuminate\Http\Request;
use Laracasts\Flash\Flash;
use Prettus\Repository\Criteria\RequestCriteria;
class TypeRatingController extends Controller
{
private $fleetSvc;
private $subfleetRepo;
private $typeratingRepo;
public function __construct(
FleetService $fleetSvc,
SubfleetRepository $subfleetRepo,
TypeRatingRepository $typeratingRepo
) {
$this->fleetSvc = $fleetSvc;
$this->subfleetRepo = $subfleetRepo;
$this->typeratingRepo = $typeratingRepo;
}
public function index(Request $request)
{
$this->typeratingRepo->pushCriteria(new RequestCriteria($request));
$typeratings = $this->typeratingRepo->orderby('type', 'asc')->get();
return view('admin.typeratings.index', [
'typeratings' => $typeratings,
]);
}
public function create()
{
return view('admin.typeratings.create');
}
public function store(CreateTypeRatingRequest $request)
{
$input = $request->all();
$model = $this->typeratingRepo->create($input);
Flash::success('Type Rating saved successfully.');
return redirect(route('admin.typeratings.edit', [$model->id]));
}
public function show($id)
{
$typerating = $this->typeratingRepo->findWithoutFail($id);
if (empty($typerating)) {
Flash::error('Type Rating not found');
return redirect(route('admin.typeratings.index'));
}
return view('admin.typeratings.show', [
'typerating' => $typerating,
]);
}
public function edit($id)
{
$typerating = $this->typeratingRepo->findWithoutFail($id);
if (empty($typerating)) {
Flash::error('Type Rating not found');
return redirect(route('admin.typeratings.index'));
}
$avail_subfleets = $this->getAvailSubfleets($typerating);
return view('admin.typeratings.edit', [
'typerating' => $typerating,
'avail_subfleets' => $avail_subfleets,
]);
}
public function update($id, UpdateTypeRatingRequest $request)
{
$typerating = $this->typeratingRepo->findWithoutFail($id);
if (empty($typerating)) {
Flash::error('Type Rating not found');
return redirect(route('admin.typeratings.index'));
}
$typerating = $this->typeratingRepo->update($request->all(), $id);
// Cache::forget(config('cache.keys.RANKS_PILOT_LIST.key'));
Flash::success('Type Rating updated successfully.');
return redirect(route('admin.typeratings.index'));
}
public function destroy($id)
{
$typerating = $this->typeratingRepo->findWithoutFail($id);
if (empty($typerating)) {
Flash::error('Type Rating not found');
return redirect(route('admin.typeratings.index'));
}
$this->typeratingRepo->delete($id);
Flash::success('Type Rating deleted successfully.');
return redirect(route('admin.typeratings.index'));
}
protected function getAvailSubfleets($typerating)
{
$retval = [];
$all_subfleets = $this->subfleetRepo->all();
$avail_subfleets = $all_subfleets->except($typerating->subfleets->modelKeys());
foreach ($avail_subfleets as $subfleet) {
$retval[$subfleet->id] = $subfleet->name.' (Airline: '.$subfleet->airline->code.')';
}
return $retval;
}
protected function return_subfleet_view($typerating)
{
$avail_subfleets = $this->getAvailSubfleets($typerating);
return view('admin.typeratings.subfleets', [
'typerating' => $typerating,
'avail_subfleets' => $avail_subfleets,
]);
}
public function subfleets($id, Request $request)
{
$typerating = $this->typeratingRepo->findWithoutFail($id);
if (empty($typerating)) {
Flash::error('Type Rating not found!');
return redirect(route('admin.typeratings.index'));
}
// add subfleet to type rating
if ($request->isMethod('post')) {
$subfleet = $this->subfleetRepo->find($request->input('subfleet_id'));
$this->fleetSvc->addSubfleetToTypeRating($subfleet, $typerating);
}
// remove subfleet from type rating
elseif ($request->isMethod('delete')) {
$subfleet = $this->subfleetRepo->find($request->input('subfleet_id'));
$this->fleetSvc->removeSubfleetFromTypeRating($subfleet, $typerating);
}
return $this->return_subfleet_view($typerating);
}
}

View File

@@ -12,7 +12,6 @@ use App\Repositories\AirlineRepository;
use App\Repositories\AirportRepository;
use App\Repositories\PirepRepository;
use App\Repositories\RoleRepository;
use App\Repositories\TypeRatingRepository;
use App\Repositories\UserRepository;
use App\Services\UserService;
use App\Support\Timezonelist;
@@ -31,27 +30,24 @@ class UserController extends Controller
private $airportRepo;
private $pirepRepo;
private $roleRepo;
private $typeratingRepo;
private $userRepo;
private $userSvc;
/**
* UserController constructor.
*
* @param AirlineRepository $airlineRepo
* @param AirportRepository $airportRepo
* @param PirepRepository $pirepRepo
* @param RoleRepository $roleRepo
* @param TypeRatingRepository $typeratingRepo
* @param UserRepository $userRepo
* @param UserService $userSvc
* @param AirlineRepository $airlineRepo
* @param AirportRepository $airportRepo
* @param PirepRepository $pirepRepo
* @param RoleRepository $roleRepo
* @param UserRepository $userRepo
* @param UserService $userSvc
*/
public function __construct(
AirlineRepository $airlineRepo,
AirportRepository $airportRepo,
PirepRepository $pirepRepo,
RoleRepository $roleRepo,
TypeRatingRepository $typeratingRepo,
UserRepository $userRepo,
UserService $userSvc
) {
@@ -59,7 +55,6 @@ class UserController extends Controller
$this->airportRepo = $airportRepo;
$this->pirepRepo = $pirepRepo;
$this->roleRepo = $roleRepo;
$this->typeratingRepo = $typeratingRepo;
$this->userSvc = $userSvc;
$this->userRepo = $userRepo;
}
@@ -154,7 +149,7 @@ class UserController extends Controller
public function edit($id)
{
$user = $this->userRepo
->with(['awards', 'fields', 'rank', 'typeratings'])
->with(['awards', 'fields', 'rank'])
->findWithoutFail($id);
if (empty($user)) {
@@ -174,19 +169,17 @@ class UserController extends Controller
$airlines = $this->airlineRepo->selectBoxList();
$airports = $this->airportRepo->selectBoxList(false);
$roles = $this->roleRepo->selectBoxList(false, true);
$avail_ratings = $this->getAvailTypeRatings($user);
return view('admin.users.edit', [
'user' => $user,
'pireps' => $pireps,
'country' => new ISO3166(),
'countries' => $countries,
'timezones' => Timezonelist::toArray(),
'airports' => $airports,
'airlines' => $airlines,
'ranks' => Rank::all()->pluck('name', 'id'),
'roles' => $roles,
'avail_ratings' => $avail_ratings,
'user' => $user,
'pireps' => $pireps,
'country' => new ISO3166(),
'countries' => $countries,
'timezones' => Timezonelist::toArray(),
'airports' => $airports,
'airlines' => $airlines,
'ranks' => Rank::all()->pluck('name', 'id'),
'roles' => $roles,
]);
}
@@ -267,7 +260,6 @@ class UserController extends Controller
$user = $this->userRepo->findWithoutFail($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('admin.users.index'));
}
@@ -291,7 +283,6 @@ class UserController extends Controller
$userAward = UserAward::where(['user_id' => $id, 'award_id' => $award_id]);
if (empty($userAward)) {
Flash::error('The user award could not be found');
return redirect()->back();
}
@@ -320,73 +311,4 @@ class UserController extends Controller
return redirect(route('admin.users.edit', [$id]));
}
/**
* Get the type ratings that are available to the user
*
* @param $user
*
* @return array
*/
protected function getAvailTypeRatings($user)
{
$retval = [];
$all_ratings = $this->typeratingRepo->all();
$avail_ratings = $all_ratings->except($user->typeratings->modelKeys());
foreach ($avail_ratings as $tr) {
$retval[$tr->id] = $tr->name.' ('.$tr->type.')';
}
return $retval;
}
/**
* @param User $user
*
* @return mixed
*/
protected function return_typeratings_view(?User $user)
{
$user->refresh();
$avail_ratings = $this->getAvailTypeRatings($user);
return view('admin.users.type_ratings', [
'user' => $user,
'avail_ratings' => $avail_ratings,
]);
}
/**
* Operations for associating type ratings to the user
*
* @param $id
* @param Request $request
*
* @return mixed
*/
public function typeratings($id, Request $request)
{
$user = $this->userRepo->findWithoutFail($id);
if (empty($user)) {
return $this->return_typeratings_view($user);
}
if ($request->isMethod('get')) {
return $this->return_typeratings_view($user);
}
// associate user with type rating
if ($request->isMethod('post')) {
$typerating = $this->typeratingRepo->find($request->input('typerating_id'));
$this->userSvc->addUserToTypeRating($user, $typerating);
} // dissassociate user from the type rating
elseif ($request->isMethod('delete')) {
$typerating = $this->typeratingRepo->find($request->input('typerating_id'));
$this->userSvc->removeUserFromTypeRating($user, $typerating);
}
$user->save();
return $this->return_typeratings_view($user);
}
}

View File

@@ -148,10 +148,10 @@ class AcarsController extends Controller
$pirep = Pirep::find($id);
$this->checkCancelled($pirep);
/*Log::debug(
Log::debug(
'Posting ACARS update (user: '.Auth::user()->ident.', pirep id :'.$id.'): ',
$request->post()
);*/
);
$count = 0;
$positions = $request->post('positions');
@@ -193,9 +193,9 @@ class AcarsController extends Controller
}
// Change the PIREP status if it's as SCHEDULED before
/*if ($pirep->status === PirepStatus::INITIATED) {
if ($pirep->status === PirepStatus::INITIATED) {
$pirep->status = PirepStatus::AIRBORNE;
}*/
}
$pirep->save();
@@ -223,7 +223,7 @@ class AcarsController extends Controller
$pirep = Pirep::find($id);
$this->checkCancelled($pirep);
// Log::debug('Posting ACARS log, PIREP: '.$id, $request->post());
Log::debug('Posting ACARS log, PIREP: '.$id, $request->post());
$count = 0;
$logs = $request->post('logs');

View File

@@ -30,9 +30,9 @@ class AirlineController extends Controller
*/
public function index(Request $request)
{
$airlines = $this->airlineRepo->whereOrder(['active' => true], 'name')->paginate();
$airports = $this->airlineRepo->whereOrder(['active' => true], 'name')->get();
return AirlineResource::collection($airlines);
return AirlineResource::collection($airports);
}
/**

View File

@@ -2,10 +2,10 @@
namespace App\Http\Controllers\Api;
use App\Console\Cron;
use App\Contracts\Controller;
use App\Exceptions\CronInvalid;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
class MaintenanceController extends Controller
{
@@ -24,12 +24,12 @@ class MaintenanceController extends Controller
throw new CronInvalid();
}
$cron = app(Cron::class);
$run = $cron->run();
$output = '';
Artisan::call('schedule:run');
$output .= trim(Artisan::output());
return response()->json([
'count' => count($run),
'tasks' => $run,
return response([
'content' => $output,
]);
}
}

View File

@@ -25,7 +25,6 @@ use App\Models\Pirep;
use App\Models\PirepComment;
use App\Models\PirepFare;
use App\Models\PirepFieldValue;
use App\Models\User;
use App\Repositories\JournalRepository;
use App\Repositories\PirepRepository;
use App\Services\Finance\PirepFinanceService;
@@ -236,12 +235,8 @@ class PirepController extends Controller
Log::info('PIREP Update, user '.Auth::id());
Log::info($request->getContent());
/** @var User $user */
$user = Auth::user();
/** @var Pirep $pirep */
$pirep = Pirep::find($pirep_id);
$this->checkCancelled($pirep);
$attrs = $this->parsePirep($request);
@@ -283,7 +278,6 @@ class PirepController extends Controller
{
Log::info('PIREP file, user '.Auth::id(), $request->post());
/** @var User $user */
$user = Auth::user();
// Check if the status is cancelled...
@@ -334,18 +328,16 @@ class PirepController extends Controller
*
* @throws \Prettus\Validator\Exceptions\ValidatorException
*
* @return mixed
* @return PirepResource
*/
public function cancel($pirep_id, Request $request)
{
Log::info('PIREP '.$pirep_id.' Cancel, user '.Auth::id(), $request->post());
Log::info('PIREP Cancel, user '.Auth::id(), $request->post());
$pirep = Pirep::find($pirep_id);
if (!empty($pirep)) {
$this->pirepSvc->cancel($pirep);
}
$this->pirepSvc->cancel($pirep);
return $this->message('PIREP '.$pirep_id.' cancelled');
return new PirepResource($pirep);
}
/**

View File

@@ -3,8 +3,6 @@
namespace App\Http\Controllers\Api;
use App\Contracts\Controller;
use App\Exceptions\BidNotFound;
use App\Exceptions\Unauthorized;
use App\Exceptions\UserNotFound;
use App\Http\Resources\Bid as BidResource;
use App\Http\Resources\Pirep as PirepResource;
@@ -146,32 +144,6 @@ class UserController extends Controller
return BidResource::collection($bids);
}
/**
* Get a particular bid for a user
*
* @param $bid_id
* @param \Illuminate\Http\Request $request
*
* @return \App\Http\Resources\Bid
*/
public function get_bid($bid_id, Request $request)
{
/** @var \App\Models\User $user */
$user = Auth::user();
// Return the current bid
$bid = $this->bidSvc->getBid($user, $bid_id);
if ($bid === null) {
throw new BidNotFound($bid_id);
}
if ($bid->user_id !== $user->id) {
throw new Unauthorized(new \Exception('Bid not not belong to authenticated user'));
}
return new BidResource($bid);
}
/**
* Return the fleet that this user is allowed to
*

View File

@@ -62,7 +62,7 @@ class RegisterController extends Controller
{
$airports = $this->airportRepo->selectBoxList(false, setting('pilots.home_hubs_only'));
$airlines = $this->airlineRepo->selectBoxList();
$userFields = UserField::where(['show_on_registration' => true, 'active' => true])->get();
$userFields = UserField::where(['show_on_registration' => true])->get();
return view('auth.register', [
'airports' => $airports,
@@ -138,7 +138,7 @@ class RegisterController extends Controller
Log::info('User registered: ', $user->toArray());
$userFields = UserField::where(['show_on_registration' => true, 'active' => true])->get();
$userFields = UserField::all();
foreach ($userFields as $field) {
$field_name = 'field_'.$field->slug;
UserFieldValue::updateOrCreate([

View File

@@ -35,23 +35,22 @@ class AirportController extends Controller
public function show($id, Request $request)
{
$id = strtoupper($id);
$with_flights = ['airline', 'arr_airport', 'dpt_airport'];
$airport = $this->airportRepo->with('files')->where('id', $id)->first();
$airport = $this->airportRepo->where('id', $id)->first();
if (!$airport) {
Flash::error('Airport not found!');
return redirect(route('frontend.dashboard.index'));
}
$inbound_flights = $this->flightRepo
->with($with_flights)
->with(['dpt_airport', 'arr_airport', 'airline'])
->findWhere([
'arr_airport_id' => $id,
'active' => 1,
])->all();
$outbound_flights = $this->flightRepo
->with($with_flights)
->with(['dpt_airport', 'arr_airport', 'airline'])
->findWhere([
'dpt_airport_id' => $id,
'active' => 1,

View File

@@ -28,15 +28,14 @@ class DashboardController extends Controller
*/
public function index()
{
//dd(config('backup'));
$last_pirep = null;
$with_pirep = ['aircraft', 'arr_airport', 'comments', 'dpt_airport'];
/** @var \App\Models\User $user */
$user = Auth::user();
$user->loadMissing('journal');
try {
$last_pirep = $this->pirepRepo->with($with_pirep)->find($user->last_pirep_id);
$last_pirep = $this->pirepRepo->find($user->last_pirep_id);
} catch (\Exception $e) {
}

View File

@@ -41,25 +41,22 @@ class DownloadController extends Controller
$klass = new $class();
$obj = $klass->find($id);
// Check if the object is there first
if (isset($obj)) {
$category = explode('\\', $class);
$category = end($category);
$category = explode('\\', $class);
$category = end($category);
if ($category == 'Aircraft' && $airlines > 1) {
$group_name = $category.' > '.$obj->subfleet->airline->name.' '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Aircraft') {
$group_name = $category.' > '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Airport') {
$group_name = $category.' > '.$obj->icao.' : '.$obj->name.' ('.$obj->country.')';
} elseif ($category == 'Subfleet' && $airlines > 1) {
$group_name = $category.' > '.$obj->airline->name.' '.$obj->name;
} else {
$group_name = $category.' > '.$obj->name;
}
$regrouped_files[$group_name] = $files;
if ($category == 'Aircraft' && $airlines > 1) {
$group_name = $category.' > '.$obj->subfleet->airline->name.' '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Aircraft') {
$group_name = $category.' > '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Airport') {
$group_name = $category.' > '.$obj->icao.' : '.$obj->name.' ('.$obj->country.')';
} elseif ($category == 'Subfleet' && $airlines > 1) {
$group_name = $category.' > '.$obj->airline->name.' '.$obj->name;
} else {
$group_name = $category.' > '.$obj->name;
}
$regrouped_files[$group_name] = $files;
}
ksort($regrouped_files, SORT_STRING);

View File

@@ -13,7 +13,6 @@ use App\Repositories\FlightRepository;
use App\Repositories\SubfleetRepository;
use App\Repositories\UserRepository;
use App\Services\GeoService;
use App\Services\ModuleService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
@@ -26,7 +25,6 @@ class FlightController extends Controller
private $airlineRepo;
private $airportRepo;
private $flightRepo;
private $moduleSvc;
private $subfleetRepo;
private $geoSvc;
private $userRepo;
@@ -36,7 +34,6 @@ class FlightController extends Controller
* @param AirportRepository $airportRepo
* @param FlightRepository $flightRepo
* @param GeoService $geoSvc
* @param ModuleService $moduleSvc
* @param SubfleetRepository $subfleetRepo
* @param UserRepository $userRepo
*/
@@ -45,7 +42,6 @@ class FlightController extends Controller
AirportRepository $airportRepo,
FlightRepository $flightRepo,
GeoService $geoSvc,
ModuleService $moduleSvc,
SubfleetRepository $subfleetRepo,
UserRepository $userRepo
) {
@@ -53,7 +49,6 @@ class FlightController extends Controller
$this->airportRepo = $airportRepo;
$this->flightRepo = $flightRepo;
$this->geoSvc = $geoSvc;
$this->moduleSvc = $moduleSvc;
$this->subfleetRepo = $subfleetRepo;
$this->userRepo = $userRepo;
}
@@ -88,7 +83,6 @@ class FlightController extends Controller
/** @var \App\Models\User $user */
$user = Auth::user();
$user->loadMissing('current_airport');
if (setting('pilots.restrict_to_company')) {
$where['airline_id'] = $user->airline_id;
@@ -114,12 +108,7 @@ class FlightController extends Controller
// Get only used Flight Types for the search form
// And filter according to settings
$usedtypes = Flight::select('flight_type')
->where($where)
->groupby('flight_type')
->orderby('flight_type')
->get();
$usedtypes = Flight::select('flight_type')->where($where)->groupby('flight_type')->orderby('flight_type', 'asc')->get();
// Build collection with type codes and labels
$flight_types = collect('', '');
foreach ($usedtypes as $ftype) {
@@ -128,28 +117,18 @@ class FlightController extends Controller
$flights = $this->flightRepo->searchCriteria($request)
->with([
'airline',
'alt_airport',
'arr_airport',
'dpt_airport',
'subfleets.airline',
'arr_airport',
'airline',
'simbrief' => function ($query) use ($user) {
$query->where('user_id', $user->id);
}, ])
->orderBy('flight_number')
->orderBy('route_leg')
->orderBy('flight_number', 'asc')
->orderBy('route_leg', 'asc')
->paginate();
$saved_flights = [];
$bids = Bid::where('user_id', Auth::id())->get();
foreach ($bids as $bid) {
if (!$bid->flight) {
$bid->delete();
continue;
}
$saved_flights[$bid->flight_id] = $bid->id;
}
$saved_flights = Bid::where('user_id', Auth::id())
->pluck('flight_id')->toArray();
return view('flights.index', [
'user' => $user,
@@ -166,7 +145,6 @@ class FlightController extends Controller
'subfleet_id' => $request->input('subfleet_id'),
'simbrief' => !empty(setting('simbrief.api_key')),
'simbrief_bids' => setting('simbrief.only_bids'),
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]);
}
@@ -193,7 +171,7 @@ class FlightController extends Controller
}
$flights->add($bid->flight);
$saved_flights[$bid->flight_id] = $bid->id;
$saved_flights[] = $bid->flight->id;
}
return view('flights.bids', [
@@ -205,7 +183,6 @@ class FlightController extends Controller
'subfleets' => $this->subfleetRepo->selectBoxList(true),
'simbrief' => !empty(setting('simbrief.api_key')),
'simbrief_bids' => setting('simbrief.only_bids'),
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]);
}
@@ -218,19 +195,7 @@ class FlightController extends Controller
*/
public function show($id)
{
$user_id = Auth::id();
$with_flight = [
'airline',
'alt_airport',
'arr_airport',
'dpt_airport',
'subfleets.airline',
'simbrief' => function ($query) use ($user_id) {
$query->where('user_id', $user_id);
},
];
$flight = $this->flightRepo->with($with_flight)->find($id);
$flight = $this->flightRepo->find($id);
if (empty($flight)) {
Flash::error('Flight not found!');
return redirect(route('frontend.dashboard.index'));
@@ -238,14 +203,9 @@ class FlightController extends Controller
$map_features = $this->geoSvc->flightGeoJson($flight);
// See if the user has a bid for this flight
$bid = Bid::where(['user_id' => $user_id, 'flight_id' => $flight->id])->first();
return view('flights.show', [
'flight' => $flight,
'map_features' => $map_features,
'bid' => $bid,
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]);
}
}

View File

@@ -16,7 +16,7 @@ class HomeController extends Controller
public function index()
{
try {
$users = User::with('home_airport')->where('state', '!=', UserState::DELETED)->orderBy('created_at', 'desc')->take(4)->get();
$users = User::where('state', '!=', UserState::DELETED)->orderBy('created_at', 'desc')->take(4)->get();
} catch (\PDOException $e) {
Log::emergency($e);
return view('system/errors/database_error', [

View File

@@ -91,12 +91,8 @@ class PirepController extends Controller
*/
public function aircraftList($add_blank = false)
{
$user = Auth::user();
$user_loc = filled($user->curr_airport_id) ? $user->curr_airport_id : $user->home_airport_id;
$location_check = setting('pireps.only_aircraft_at_dpt_airport', false);
$aircraft = [];
$subfleets = $this->userSvc->getAllowableSubfleets($user);
$subfleets = $this->userSvc->getAllowableSubfleets(Auth::user());
if ($add_blank) {
$aircraft[''] = '';
@@ -104,9 +100,7 @@ class PirepController extends Controller
foreach ($subfleets as $subfleet) {
$tmp = [];
foreach ($subfleet->aircraft->when($location_check, function ($query) use ($user_loc) {
return $query->where('airport_id', $user_loc);
}) as $ac) {
foreach ($subfleet->aircraft as $ac) {
$tmp[$ac->id] = $ac['name'].' - '.$ac['registration'];
}
@@ -188,7 +182,7 @@ class PirepController extends Controller
$where = [['user_id', $user->id]];
$where[] = ['state', '<>', PirepState::CANCELLED];
$with = ['aircraft', 'airline', 'arr_airport', 'comments', 'dpt_airport'];
$with = ['airline', 'aircraft', 'dpt_airport', 'arr_airport', 'fares', 'comments'];
$this->pirepRepo->with($with)
->pushCriteria(new WhereCriteria($request, $where));
@@ -207,20 +201,7 @@ class PirepController extends Controller
*/
public function show($id)
{
$with = [
'acars_logs',
'aircraft.airline',
'airline.journal',
'arr_airport',
'comments',
'dpt_airport',
'fares.fare',
'transactions',
'simbrief',
'user.rank',
];
$pirep = $this->pirepRepo->with($with)->find($id);
$pirep = $this->pirepRepo->with(['simbrief'])->find($id);
if (empty($pirep)) {
Flash::error('Pirep not found');
return redirect(route('frontend.pirep.index'));

View File

@@ -80,19 +80,22 @@ class ProfileController extends Controller
public function show($id)
{
/** @var \App\Models\User $user */
$with = ['airline', 'awards', 'current_airport', 'fields.field', 'home_airport', 'last_pirep', 'rank', 'typeratings'];
$user = User::with($with)->where('id', $id)->first();
$user = User::with(['awards', 'fields', 'fields.field'])
->where('id', $id)
->first();
if (empty($user)) {
Flash::error('User not found!');
return redirect(route('frontend.dashboard.index'));
}
$airports = $this->airportRepo->all();
$userFields = $this->userRepo->getUserFields($user, true);
return view('profile.index', [
'user' => $user,
'userFields' => $userFields,
'airports' => $airports,
'acars' => $this->acarsEnabled(),
]);
}
@@ -109,7 +112,9 @@ class ProfileController extends Controller
public function edit(Request $request)
{
/** @var \App\Models\User $user */
$user = User::with('fields.field')->where('id', Auth::id())->first();
$user = User::with(['fields', 'fields.field'])
->where('id', Auth::user()->id)
->first();
if (empty($user)) {
Flash::error('User not found!');
@@ -118,7 +123,7 @@ class ProfileController extends Controller
$airlines = $this->airlineRepo->selectBoxList();
$airports = $this->airportRepo->selectBoxList(false, setting('pilots.home_hubs_only'));
$userFields = $this->userRepo->getUserFields($user);
$userFields = $this->userRepo->getUserFields($user, true);
return view('profile.edit', [
'user' => $user,

View File

@@ -4,7 +4,6 @@ namespace App\Http\Controllers\Frontend;
use App\Exceptions\AssetNotFound;
use App\Models\Aircraft;
use App\Models\Bid;
use App\Models\Enums\AircraftState;
use App\Models\Enums\AircraftStatus;
use App\Models\Enums\FareType;
@@ -15,7 +14,6 @@ use App\Models\SimBrief;
use App\Models\User;
use App\Repositories\FlightRepository;
use App\Services\FareService;
use App\Services\ModuleService;
use App\Services\SimBriefService;
use App\Services\UserService;
use Exception;
@@ -26,20 +24,17 @@ class SimBriefController
{
private $fareSvc;
private $flightRepo;
private $moduleSvc;
private $simBriefSvc;
private $userSvc;
public function __construct(
FareService $fareSvc,
FlightRepository $flightRepo,
ModuleService $moduleSvc,
SimBriefService $simBriefSvc,
UserService $userSvc
) {
$this->fareSvc = $fareSvc;
$this->flightRepo = $flightRepo;
$this->moduleSvc = $moduleSvc;
$this->simBriefSvc = $simBriefSvc;
$this->userSvc = $userSvc;
}
@@ -62,7 +57,7 @@ class SimBriefController
$aircraft_id = $request->input('aircraft_id');
/** @var Flight $flight */
$flight = $this->flightRepo->with(['airline', 'arr_airport', 'dpt_airport', 'fares', 'subfleets'])->find($flight_id);
$flight = $this->flightRepo->with(['fares', 'subfleets'])->find($flight_id);
if (!$flight) {
flash()->error('Unknown flight');
@@ -80,39 +75,45 @@ class SimBriefController
// No aircraft selected, show selection form
if (!$aircraft_id) {
// Get user's allowed subfleets and intersect it with flight subfleets
// so we will have a proper list which the user is allowed to fly
$user_subfleets = $this->userSvc->getAllowableSubfleets($user)->pluck('id')->toArray();
$flight_subfleets = $flight->subfleets->pluck('id')->toArray();
$subfleet_ids = filled($flight_subfleets) ? array_intersect($user_subfleets, $flight_subfleets) : $user_subfleets;
// Prepare variables for single aircraft query
$where = [];
$where['state'] = AircraftState::PARKED;
$where['status'] = AircraftStatus::ACTIVE;
if (setting('pireps.only_aircraft_at_dpt_airport')) {
$where['airport_id'] = $flight->dpt_airport_id;
// If no subfleets defined for flight get them from user
if ($flight->subfleets->count() > 0) {
$subfleets = $flight->subfleets;
} else {
$subfleets = $this->userSvc->getAllowableSubfleets($user);
}
$withCount = ['simbriefs' => function ($query) {
$query->whereNull('pirep_id');
}];
// Build an array of subfleet id's from the subfleets collection
$sf_ids = $subfleets->map(function ($subfleets) {
return collect($subfleets->toArray())
->only(['id'])
->all();
});
// Build proper aircraft collection considering all possible settings
// Flight subfleets, user subfleet restrictions, pirep restrictions, simbrief blocking etc
$aircraft = Aircraft::withCount($withCount)->where($where)
->when(setting('simbrief.block_aircraft'), function ($query) {
return $query->having('simbriefs_count', 0);
})->whereIn('subfleet_id', $subfleet_ids)
->orderby('icao')->orderby('registration')
->get();
// Now we can build a proper aircrafts collection
// Contents will be either members of flight->subfleets
// or members of user's allowable subfleets
$aircrafts = Aircraft::whereIn('subfleet_id', $sf_ids)
->where('state', AircraftState::PARKED)
->where('status', AircraftStatus::ACTIVE)
->orderby('icao')
->orderby('registration')
->get();
if (setting('pireps.only_aircraft_at_dpt_airport')) {
$aircrafts = $aircrafts->where('airport_id', $flight->dpt_airport_id);
}
if (setting('simbrief.block_aircraft')) {
// Build a list of aircraft_id's being used for active sb packs
$sb_aircraft = SimBrief::whereNotNull('flight_id')->pluck('aircraft_id');
// Filter aircraft list to non used/blocked ones
$aircrafts = $aircrafts->whereNotIn('id', $sb_aircraft);
}
return view('flights.simbrief_aircraft', [
'flight' => $flight,
'aircrafts' => $aircraft,
'aircrafts' => $aircrafts,
'subfleets' => $subfleets,
]);
}
@@ -129,7 +130,7 @@ class SimBriefController
// SimBrief profile does not exists and everything else is ok
// Select aircraft which will be used for calculations and details
/** @var Aircraft $aircraft */
$aircraft = Aircraft::with(['airline'])->where('id', $aircraft_id)->first();
$aircraft = Aircraft::where('id', $aircraft_id)->first();
// Figure out the proper fares to use for this flight/aircraft
$all_fares = $this->fareSvc->getFareWithOverrides($aircraft->subfleet->fares, $flight->fares);
@@ -224,7 +225,7 @@ class SimBriefController
// Show the main simbrief form
return view('flights.simbrief_form', [
'user' => $user,
'user' => Auth::user(),
'flight' => $flight,
'aircraft' => $aircraft,
'pax_weight' => $pax_weight,
@@ -252,11 +253,7 @@ class SimBriefController
*/
public function briefing($id)
{
/** @var User $user */
$user = Auth::user();
/** @var SimBrief $simbrief */
$simbrief = SimBrief::with(['flight.airline', 'pirep.airline'])->find($id);
$simbrief = SimBrief::find($id);
if (!$simbrief) {
flash()->error('SimBrief briefing not found');
return redirect(route('frontend.flights.index'));
@@ -269,18 +266,11 @@ class SimBriefController
$equipment = substr($str, $wc + 1, $tr - 2);
$transponder = substr($str, $tr + 1);
// See if a bid exists for this flight
$bid = Bid::where(['user_id' => $user->id, 'flight_id' => $simbrief->flight_id])->first();
return view('flights.simbrief_briefing', [
'user' => $user,
'simbrief' => $simbrief,
'wakecat' => $wakecat,
'equipment' => $equipment,
'transponder' => $transponder,
'bid' => $bid,
'flight' => $simbrief->flight,
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
'simbrief' => $simbrief,
'wakecat' => $wakecat,
'equipment' => $equipment,
'transponder' => $transponder,
]);
}

View File

@@ -30,9 +30,6 @@ class UserController extends Controller
*/
public function index(Request $request)
{
$with = ['airline', 'current_airport', 'fields.field', 'home_airport', 'rank'];
$with_count = ['awards'];
$where = [];
if (setting('pilots.hide_inactive')) {
@@ -46,8 +43,7 @@ class UserController extends Controller
}
$users = $this->userRepo
->withCount($with_count)
->with($with)
->with(['airline', 'current_airport'])
->orderBy('pilot_id', 'asc')
->paginate();

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Http\Requests;
use App\Contracts\FormRequest;
use App\Models\Typerating;
class CreateTypeRatingRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return Typerating::$rules;
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Http\Requests;
use App\Contracts\FormRequest;
use App\Models\Typerating;
class UpdateTypeRatingRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return Typerating::$rules;
}
}

View File

@@ -4,16 +4,6 @@ namespace App\Http\Resources;
use App\Contracts\Resource;
/**
* @mixin \App\Models\Aircraft
*/
class Aircraft extends Resource
{
public function toArray($request)
{
$res = parent::toArray($request);
$res['ident'] = $this->ident;
return $res;
}
}

View File

@@ -60,7 +60,7 @@ class AwardHandler extends Listener
*/
public function checkForAwards($user)
{
$awards = Award::where('active', 1)->get();
$awards = Award::all();
foreach ($awards as $award) {
$klass = $award->getReference($award, $user);
if ($klass) {

View File

@@ -4,8 +4,6 @@ namespace App\Listeners;
use App\Contracts\Listener;
use App\Events\Expenses;
use App\Models\Enums\ExpenseType;
use App\Models\Expense;
class ExpenseListener extends Listener
{
@@ -25,7 +23,7 @@ class ExpenseListener extends Listener
// The transaction group is how it will show as a line item
/*$expenses[] = new Expense([
'type' => ExpenseType::FLIGHT,
'amount' => 150, # $150
'amount' => 15000, # $150
'transaction_group' => '',
'charge_to_user' => true|false
]);*/

View File

@@ -1,39 +0,0 @@
<?php
namespace App\Listeners;
use App\Contracts\Listener;
use App\Events\Fares;
use App\Models\Enums\FareType;
use App\Models\Fare;
class FareListener extends Listener
{
/**
* Return a list of additional fares/income items
*
* @param Fares $event
*
* @return mixed
*/
public function handle(Fares $event)
{
$fares = [];
// This is an example of a fare to return
// You have the pirep on $event->pirep and any associated data
// Cost may be skipped at all if not needed
// Notes will be used as transaction group and it is how it will show as a line item
/*
$fares[] = new Fare([
'name' => 'Duty Free Sales',
'type' => FareType::PASSENGER,
'price' => 985,
'cost' => 126,
'notes' => 'InFlight Sales',
]);
*/
return $fares;
}
}

View File

@@ -7,13 +7,11 @@ use App\Models\Enums\AircraftStatus;
use App\Models\Traits\ExpensableTrait;
use App\Models\Traits\FilesTrait;
use Carbon\Carbon;
use Znck\Eloquent\Traits\BelongsToThrough;
/**
* @property int id
* @property mixed subfleet_id
* @property string airport_id The apt where the aircraft is
* @property string hub_id The apt where the aircraft is based
* @property string ident
* @property string name
* @property string icao
@@ -23,7 +21,6 @@ use Znck\Eloquent\Traits\BelongsToThrough;
* @property float zfw
* @property string hex_code
* @property Airport airport
* @property Airport hub
* @property Subfleet subfleet
* @property int status
* @property int state
@@ -34,14 +31,12 @@ class Aircraft extends Model
{
use ExpensableTrait;
use FilesTrait;
use BelongsToThrough;
public $table = 'aircraft';
protected $fillable = [
'subfleet_id',
'airport_id',
'hub_id',
'iata',
'icao',
'name',
@@ -105,46 +100,14 @@ class Aircraft extends Model
$this->attributes['icao'] = strtoupper($icao);
}
/**
* Return the landing time in carbon format if provided
*
* @return Carbon|null
*/
public function getLandingTimeAttribute()
{
if (array_key_exists('landing_time', $this->attributes) && filled($this->attributes['landing_time'])) {
return new Carbon($this->attributes['landing_time']);
}
}
/**
* foreign keys
*/
public function airline()
{
return $this->belongsToThrough(Airline::class, Subfleet::class);
}
public function airport()
{
return $this->belongsTo(Airport::class, 'airport_id');
}
public function hub()
{
return $this->hasOne(Airport::class, 'id', 'hub_id');
}
public function pireps()
{
return $this->hasMany(Pirep::class, 'aircraft_id');
}
public function simbriefs()
{
return $this->hasMany(SimBrief::class, 'aircraft_id');
}
public function subfleet()
{
return $this->belongsTo(Subfleet::class, 'subfleet_id');

View File

@@ -103,11 +103,6 @@ class Airline extends Model
return $this->hasMany(Subfleet::class, 'airline_id');
}
public function aircraft()
{
return $this->hasManyThrough(Aircraft::class, Subfleet::class);
}
public function flights()
{
return $this->belongsTo(Flight::class, 'airline_id');

View File

@@ -21,7 +21,6 @@ class Award extends Model
'image_url',
'ref_model',
'ref_model_params',
'active',
];
public static $rules = [
@@ -30,7 +29,6 @@ class Award extends Model
'image_url' => 'nullable',
'ref_model' => 'required',
'ref_model_params' => 'nullable',
'active' => 'nullable',
];
/**

View File

@@ -6,12 +6,10 @@ use App\Contracts\Model;
use Carbon\Carbon;
/**
* @property int user_id
* @property string user_id
* @property string flight_id
* @property Carbon created_at
* @property Carbon updated_at
* @property Flight flight
* @property User user
*/
class Bid extends Model
{

View File

@@ -7,7 +7,6 @@ use App\Contracts\Enum;
class AircraftStatus extends Enum
{
public const ACTIVE = 'A';
public const MAINTENANCE = 'M';
public const STORED = 'S';
public const RETIRED = 'R';
public const SCRAPPED = 'C';
@@ -15,7 +14,6 @@ class AircraftStatus extends Enum
public static $labels = [
self::ACTIVE => 'aircraft.status.active',
self::MAINTENANCE => 'aircraft.status.maintenance',
self::STORED => 'aircraft.status.stored',
self::RETIRED => 'aircraft.status.retired',
self::SCRAPPED => 'aircraft.status.scrapped',

View File

@@ -4,6 +4,9 @@ namespace App\Models\Enums;
use App\Contracts\Enum;
/**
* Class PirepState
*/
class PirepState extends Enum
{
public const IN_PROGRESS = 0; // flight is ongoing
@@ -13,7 +16,6 @@ class PirepState extends Enum
public const DELETED = 4;
public const DRAFT = 5;
public const REJECTED = 6;
public const PAUSED = 7;
protected static $labels = [
self::IN_PROGRESS => 'pireps.state.in_progress',
@@ -23,6 +25,5 @@ class PirepState extends Enum
self::DELETED => 'pireps.state.deleted',
self::DRAFT => 'pireps.state.draft',
self::REJECTED => 'pireps.state.rejected',
self::PAUSED => 'pireps.state.paused',
];
}

View File

@@ -34,7 +34,6 @@ class PirepStatus extends Enum
public const ARRIVED = 'ONB'; // On block
public const CANCELLED = 'DX';
public const EMERG_DESCENT = 'EMG';
public const PAUSED = 'PSD';
protected static $labels = [
self::INITIATED => 'pireps.status.initialized',
@@ -60,6 +59,5 @@ class PirepStatus extends Enum
self::ARRIVED => 'pireps.status.arrived',
self::CANCELLED => 'pireps.status.cancelled',
self::EMERG_DESCENT => 'pireps.status.emerg_decent',
self::PAUSED => 'pireps.status.paused',
];
}

View File

@@ -24,7 +24,6 @@ use Illuminate\Support\Collection;
* @property Collection subfleets
* @property int days
* @property int distance
* @property int planned_distance
* @property int flight_time
* @property string route
* @property string dpt_time
@@ -137,19 +136,19 @@ class Flight extends Model
}
/**
* Get the flight ident, e.,g JBU1900/C.nn/L.yy
* Get the flight ident, e.,g JBU1900
*/
public function getIdentAttribute(): string
{
$flight_id = optional($this->airline)->code;
$flight_id = $this->airline->code;
$flight_id .= $this->flight_number;
if (filled($this->route_code)) {
$flight_id .= '/C.'.$this->route_code;
$flight_id .= '-'.$this->route_code;
}
if (filled($this->route_leg)) {
$flight_id .= '/L.'.$this->route_leg;
$flight_id .= '-'.$this->route_leg;
}
return $flight_id;

View File

@@ -195,39 +195,41 @@ class Pirep extends Model
/**
* Create a new PIREP from a SimBrief instance
*
* @param \App\Models\SimBrief $simbrief
* @param \App\Models\SimBrief $simBrief
*
* @return \App\Models\Pirep
*/
public static function fromSimBrief(SimBrief $simbrief): self
public static function fromSimBrief(SimBrief $simBrief): self
{
return new self([
'flight_id' => $simbrief->flight->id,
'airline_id' => $simbrief->flight->airline_id,
'flight_number' => $simbrief->flight->flight_number,
'route_code' => $simbrief->flight->route_code,
'route_leg' => $simbrief->flight->route_leg,
'dpt_airport_id' => $simbrief->flight->dpt_airport_id,
'arr_airport_id' => $simbrief->flight->arr_airport_id,
'route' => $simbrief->xml->getRouteString(),
'level' => $simbrief->xml->getFlightLevel(),
'flight_id' => $simBrief->flight->id,
'airline_id' => $simBrief->flight->airline_id,
'flight_number' => $simBrief->flight->flight_number,
'route_code' => $simBrief->flight->route_code,
'route_leg' => $simBrief->flight->route_leg,
'dpt_airport_id' => $simBrief->flight->dpt_airport_id,
'arr_airport_id' => $simBrief->flight->arr_airport_id,
'route' => $simBrief->xml->getRouteString(),
'level' => $simBrief->xml->getFlightLevel(),
]);
}
/**
* Get the flight ident, e.,g JBU1900/C.nn/L.yy
* Get the flight ident, e.,g JBU1900
*
* @return string
*/
public function getIdentAttribute(): string
{
$flight_id = optional($this->airline)->code;
$flight_id .= $this->flight_number;
//$flight_id = $this->airline->code;
$flight_id = $this->flight_number;
if (filled($this->route_code)) {
$flight_id .= '/C.'.$this->route_code;
$flight_id .= '/C'.$this->route_code;
}
if (filled($this->route_leg)) {
$flight_id .= '/L.'.$this->route_leg;
$flight_id .= '/L'.$this->route_leg;
}
return $flight_id;

View File

@@ -41,10 +41,6 @@ class SimBrief extends Model
'updated_at',
];
protected $casts = [
'user_id' => 'integer',
];
/** @var \App\Models\SimBriefXML Store a cached version of the XML object */
private $xml_instance;
@@ -96,12 +92,13 @@ class SimBrief extends Model
public function flight()
{
return $this->belongsTo(Flight::class, 'flight_id');
}
if (!empty($this->attributes['flight_id'])) {
return $this->belongsTo(Flight::class, 'flight_id');
}
public function pirep()
{
return $this->belongsTo(Pirep::class, 'pirep_id');
if (!empty($this->attributes['pirep_id'])) {
return $this->belongsTo(Pirep::class, 'pirep_id');
}
}
public function user()

View File

@@ -107,9 +107,4 @@ class Subfleet extends Model
return $this->belongsToMany(Rank::class, 'subfleet_rank')
->withPivot('acars_pay', 'manual_pay');
}
public function typeratings()
{
return $this->belongsToMany(Typerating::class, 'typerating_subfleet', 'subfleet_id', 'typerating_id');
}
}

View File

@@ -1,37 +0,0 @@
<?php
namespace App\Models;
use App\Contracts\Model;
class Typerating extends Model
{
public $table = 'typeratings';
protected $fillable = [
'name',
'type',
'description',
'image_url',
'active',
];
// Validation
public static $rules = [
'name' => 'required',
'type' => 'required',
'description' => 'nullable',
'image_url' => 'nullable',
];
// Relationships
public function subfleets()
{
return $this->belongsToMany(Subfleet::class, 'typerating_subfleet', 'typerating_id', 'subfleet_id');
}
public function users()
{
return $this->belongsToMany(User::class, 'typerating_user', 'typerating_id', 'user_id');
}
}

View File

@@ -7,7 +7,6 @@ use App\Models\Traits\JournalTrait;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laratrust\Traits\LaratrustUserTrait;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
/**
* @property int id
@@ -43,7 +42,6 @@ use Staudenmeir\EloquentHasManyDeep\HasRelationships;
* @property UserFieldValue[] fields
* @property Role[] roles
* @property Subfleet[] subfleets
* @property TypeRating[] typeratings
*
* @mixin \Illuminate\Database\Eloquent\Builder
* @mixin \Illuminate\Notifications\Notifiable
@@ -54,7 +52,6 @@ class User extends Authenticatable
use JournalTrait;
use LaratrustUserTrait;
use Notifiable;
use HasRelationships;
public $table = 'users';
@@ -88,7 +85,6 @@ class User extends Authenticatable
'toc_accepted',
'opt_in',
'last_ip',
'notes',
'created_at',
'updated_at',
];
@@ -98,14 +94,10 @@ class User extends Authenticatable
*/
protected $hidden = [
'api_key',
'email',
'name',
'discord_id',
'discord_private_channel_id',
'password',
'last_ip',
'remember_token',
'notes',
];
protected $casts = [
@@ -133,9 +125,8 @@ class User extends Authenticatable
public function getIdentAttribute(): string
{
$length = setting('pilots.id_length');
$ident_code = filled(setting('pilots.id_code')) ? setting('pilots.id_code') : optional($this->airline)->icao;
return $ident_code.str_pad($this->pilot_id, $length, '0', STR_PAD_LEFT);
return $this->airline->icao.str_pad($this->pilot_id, $length, '0', STR_PAD_LEFT);
}
/**
@@ -154,7 +145,7 @@ class User extends Authenticatable
$first_name = $name_parts[0];
$last_name = $name_parts[$count - 1];
return $first_name.' '.mb_substr($last_name, 0, 1);
return $first_name.' '.$last_name[0];
}
/**
@@ -200,7 +191,8 @@ class User extends Authenticatable
{
$default = config('gravatar.default');
$uri = config('gravatar.url').md5(strtolower(trim($this->email))).'?d='.urlencode($default);
$uri = config('gravatar.url')
.md5(strtolower(trim($this->email))).'?d='.urlencode($default);
if ($size !== null) {
$uri .= '&s='.$size;
@@ -273,14 +265,4 @@ class User extends Authenticatable
{
return $this->belongsTo(Rank::class, 'rank_id');
}
public function typeratings()
{
return $this->belongsToMany(Typerating::class, 'typerating_user', 'user_id', 'typerating_id');
}
public function rated_subfleets()
{
return $this->hasManyDeep(Subfleet::class, ['typerating_user', Typerating::class, 'typerating_subfleet']);
}
}

View File

@@ -22,14 +22,6 @@ class UserFieldValue extends Model
public static $rules = [];
/**
* Return related field's name along with field values
*/
public function getNameAttribute(): string
{
return optional($this->field)->name;
}
/**
* Foreign Keys
*/

View File

@@ -11,16 +11,14 @@ use Carbon\Carbon;
*/
class DiscordMessage
{
const COLOR_SUCCESS = '0B6623';
const COLOR_WARNING = 'FD6A02';
const COLOR_ERROR = 'ED2939';
const COLOR_SUCCESS = '#0B6623';
const COLOR_WARNING = '#FD6A02';
const COLOR_ERROR = '#ED2939';
public $webhook_url;
protected $title;
protected $url;
protected $thumbnail = [];
protected $image = [];
protected $description;
protected $timestamp;
protected $footer;
@@ -28,43 +26,30 @@ class DiscordMessage
protected $author = [];
protected $fields = [];
// Supply the webhook URL that this should be going to
/**
* Supply the webhook URL that this should be going to
*/
public function webhook(string $url): self
{
$this->webhook_url = $url;
return $this;
}
// Title of the embed
/**
* Title of the notification
*/
public function title(string $title): self
{
$this->title = $title;
return $this;
}
// URL of the Title
public function url(string $url): self
{
$this->url = $url;
return $this;
}
// Thumbnail image (placed right side of embed)
// ['url' => '']
public function thumbnail(array $thumbnail): self
{
$this->thumbnail = $thumbnail;
return $this;
}
// Main image (placed bottom of embed)
// ['url' => '']
public function image(array $image): self
{
$this->image = $image;
return $this;
}
/**
* @param array|string $descriptionLines
*/
@@ -78,15 +63,22 @@ class DiscordMessage
return $this;
}
// Author details
// ['name' => '', 'url' => '', 'icon_url' => '']
/**
* Set the author information:
* [
* 'name' => '',
* 'url' => '',
* 'icon_url' => '',
*/
public function author(array $author): self
{
$this->author = $author;
return $this;
}
// Fields
/**
* Set the fields
*/
public function fields(array $fields): self
{
$this->fields = [];
@@ -107,45 +99,32 @@ class DiscordMessage
return $this;
}
// Fixed Success Color
public function success(): self
{
$this->color = hexdec('0B6623'); // static::COLOR_SUCCESS;
$this->color = static::COLOR_SUCCESS;
return $this;
}
// Fixed Warning
public function warning(): self
{
$this->color = hexdec('FD6A02'); // static::COLOR_WARNING;
$this->color = static::COLOR_WARNING;
return $this;
}
// Fixed Error
public function error(): self
{
$this->color = hexdec('ED2939'); // static::COLOR_ERROR;
return $this;
}
// Custom Color
public function color(string $embed_color): self
{
$this->color = hexdec($embed_color);
$this->color = static::COLOR_ERROR;
return $this;
}
public function toArray(): array
{
$embeds = [
'type' => 'rich',
'color' => $this->color,
'title' => $this->title,
'url' => $this->url,
'thumbnail' => $this->thumbnail,
'type' => 'rich',
'description' => $this->description,
'author' => $this->author,
'image' => $this->image,
'timestamp' => Carbon::now('UTC'),
];

View File

@@ -20,23 +20,14 @@ class DiscordWebhook
public function send($notifiable, Notification $notification)
{
$message = $notification->toDiscordChannel($notifiable);
if ($message === null) {
//Log::debug('Discord notifications not configured, skipping');
if ($message === null || empty($message->webhook_url)) {
Log::debug('Discord notifications not configured, skipping');
return;
}
$webhook_url = $message->webhook_url;
if (empty($webhook_url)) {
$webhook_url = setting('notifications.discord_private_webhook_url');
if (empty($webhook_url)) {
//Log::debug('Discord notifications not configured, skipping');
return;
}
}
try {
$data = $message->toArray();
$this->httpClient->post($webhook_url, $data);
$this->httpClient->post($message->webhook_url, $data);
} catch (RequestException $e) {
$request = Psr7\Message::toString($e->getRequest());
$response = Psr7\Message::toString($e->getResponse());

View File

@@ -4,6 +4,8 @@ namespace App\Notifications\Messages;
use App\Contracts\Notification;
use App\Models\User;
use App\Notifications\Channels\Discord\DiscordMessage;
use App\Notifications\Channels\Discord\DiscordWebhook;
use App\Notifications\Channels\MailChannel;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -30,21 +32,32 @@ class AdminUserRegistered extends Notification implements ShouldQueue
);
}
/**
* @param $notifiable
*
* @return string[]
*/
public function via($notifiable)
{
return ['mail'];
return ['mail', DiscordWebhook::class];
}
/**
* @param $notifiable
* Send a Discord notification
*
* @return array
* @param User $pirep
* @param mixed $user
*
* @return DiscordMessage|null
*/
public function toDiscordChannel($user): ?DiscordMessage
{
if (empty(setting('notifications.discord_private_webhook_url'))) {
return null;
}
$dm = new DiscordMessage();
return $dm->webhook(setting('notifications.discord_private_webhook_url'))
->success()
->title('New User Registered: '.$user->ident)
->fields([]);
}
public function toArray($notifiable)
{
return [

View File

@@ -1,58 +0,0 @@
<?php
namespace App\Notifications\Messages\Broadcast;
use App\Contracts\Notification;
use App\Models\News;
use App\Notifications\Channels\Discord\DiscordMessage;
use Illuminate\Contracts\Queue\ShouldQueue;
class NewsAdded extends Notification implements ShouldQueue
{
private $news;
public function __construct(News $news)
{
parent::__construct();
$this->news = $news;
}
public function via($notifiable)
{
return ['discord_webhook'];
}
/**
* @param News $news
*
* @return DiscordMessage|null
*/
public function toDiscordChannel($news): ?DiscordMessage
{
$dm = new DiscordMessage();
return $dm->webhook(setting('notifications.discord_public_webhook_url'))
->success()
->title('News: '.$news->subject)
->author([
'name' => $news->user->ident.' - '.$news->user->name_private,
'url' => '',
'icon_url' => $news->user->resolveAvatarUrl(),
])
->description($news->body);
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
*
* @return array
*/
public function toArray($notifiable)
{
return [
'news_id' => $this->news->id,
];
}
}

View File

@@ -1,74 +0,0 @@
<?php
namespace App\Notifications\Messages\Broadcast;
use App\Contracts\Notification;
use App\Models\User;
use App\Notifications\Channels\Discord\DiscordMessage;
use App\Notifications\Channels\MailChannel;
use Illuminate\Contracts\Queue\ShouldQueue;
/**
* Send a message to a Discord channel that a user was registered
*/
class UserRegistered extends Notification implements ShouldQueue
{
use MailChannel;
private $user;
/**
* Create a new notification instance.
*
* @param \App\Models\User $user
*/
public function __construct(User $user)
{
parent::__construct();
$this->user = $user;
}
/**
* @param $notifiable
*
* @return string[]
*/
public function via($notifiable)
{
return ['discord_webhook'];
}
/**
* Send a Discord notification
*
* @param $notifiable
*
* @return DiscordMessage|null
*/
public function toDiscordChannel($notifiable): ?DiscordMessage
{
$dm = new DiscordMessage();
return $dm->webhook(setting('notifications.discord_private_webhook_url'))
->success()
->title('New User Registered: '.$this->user->ident)
->author([
'name' => $this->user->ident.' - '.$this->user->name_private,
'url' => '',
'icon_url' => $this->user->resolveAvatarUrl(),
])
->fields([]);
}
/**
* @param $notifiable
*
* @return array
*/
public function toArray($notifiable)
{
return [
'user_id' => $this->user->id,
];
}
}

View File

@@ -1,53 +0,0 @@
<?php
namespace App\Notifications\Messages;
use App\Contracts\Notification;
use App\Models\Pirep;
use App\Notifications\Channels\MailChannel;
use Illuminate\Contracts\Queue\ShouldQueue;
class PirepFiled extends Notification implements ShouldQueue
{
use MailChannel;
private $pirep;
/**
* Create a new notification instance.
*
* @param \App\Models\Pirep $pirep
*/
public function __construct(Pirep $pirep)
{
parent::__construct();
$this->pirep = $pirep;
$this->setMailable(
'New PIREP Submitted',
'notifications.mail.admin.pirep.submitted',
['pirep' => $this->pirep]
);
}
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
*
* @return array
*/
public function toArray($notifiable)
{
return [
'pirep_id' => $this->pirep->id,
'user_id' => $this->pirep->user_id,
];
}
}

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Notifications\Messages\Broadcast;
namespace App\Notifications\Messages;
use App\Contracts\Notification;
use App\Models\Pirep;
@@ -48,9 +48,9 @@ class PirepPrefiled extends Notification implements ShouldQueue
return null;
}
$title = 'Flight '.$pirep->ident.' Prefiled';
$title = 'Flight '.$pirep->airline->code.$pirep->ident.' Prefiled';
$fields = [
'Flight' => $pirep->ident,
'Flight' => $pirep->airline->code.$pirep->ident,
'Departure Airport' => $pirep->dpt_airport_id,
'Arrival Airport' => $pirep->arr_airport_id,
'Equipment' => $pirep->aircraft->ident,

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Notifications\Messages\Broadcast;
namespace App\Notifications\Messages;
use App\Contracts\Notification;
use App\Models\Enums\PirepStatus;
@@ -44,7 +44,6 @@ class PirepStatusChanged extends Notification implements ShouldQueue
PirepStatus::LANDED => 'has landed',
PirepStatus::ARRIVED => 'has arrived',
PirepStatus::CANCELLED => 'is cancelled',
PirepStatus::PAUSED => 'is paused',
PirepStatus::EMERG_DESCENT => 'in emergency descent',
];
@@ -77,12 +76,14 @@ class PirepStatusChanged extends Notification implements ShouldQueue
return null;
}
$title = 'Flight '.$pirep->ident.' '.self::$verbs[$pirep->status];
$title = 'Flight '.$pirep->airline->code.$pirep->ident.' '.self::$verbs[$pirep->status];
$fields = [
'Dep.Airport' => $pirep->dpt_airport_id,
'Arr.Airport' => $pirep->arr_airport_id,
'Equipment' => $pirep->aircraft->ident,
'Flight Time' => Time::minutesToTimeString($pirep->flight_time),
'Flight' => $pirep->airline->code.$pirep->ident,
'Departure Airport' => $pirep->dpt_airport_id,
'Arrival Airport' => $pirep->arr_airport_id,
'Equipment' => $pirep->aircraft->ident,
'Flight Time' => Time::minutesToTimeString($pirep->flight_time),
];
// Show the distance, but include the planned distance if it's been set
@@ -100,38 +101,25 @@ class PirepStatusChanged extends Notification implements ShouldQueue
$planned_distance = new Distance($pirep->planned_distance, $unit);
$pd = $planned_distance[$planned_distance->unit];
$fields['Distance'] .= '/'.$pd;
} catch (NonNumericValue|NonStringUnitName $e) {
} catch (NonNumericValue | NonStringUnitName $e) {
}
}
$fields['Distance'] .= ' '.$planned_distance->unit;
} catch (NonNumericValue|NonStringUnitName $e) {
} catch (NonNumericValue | NonStringUnitName $e) {
}
}
// User avatar, somehow $pirep->user->resolveAvatarUrl() is not being accepted by Discord as thumbnail
$user_avatar = !empty($pirep->user->avatar) ? $pirep->user->avatar->url : $pirep->user->gravatar(256);
// Proper coloring for the messages
// Pirep Filed > success, normals > warning, non-normals > error
$danger_types = [
PirepStatus::GRND_RTRN,
PirepStatus::DIVERTED,
PirepStatus::CANCELLED,
PirepStatus::PAUSED,
PirepStatus::EMERG_DESCENT,
];
$color = in_array($pirep->status, $danger_types, true) ? 'ED2939' : 'FD6A02';
$dm = new DiscordMessage();
return $dm->webhook(setting('notifications.discord_public_webhook_url'))
->color($color)
->success()
->title($title)
->description($pirep->user->discord_id ? 'Flight by <@'.$pirep->user->discord_id.'>' : '')
->thumbnail(['url' => $user_avatar])
->url(route('frontend.pireps.show', [$pirep->id]))
->author([
'name' => $pirep->user->ident.' - '.$pirep->user->name_private,
'url' => route('frontend.profile.show', [$pirep->user_id]),
'name' => $pirep->user->ident.' - '.$pirep->user->name_private,
'url' => route('frontend.profile.show', [$pirep->user_id]),
'icon_url' => $pirep->user->resolveAvatarUrl(),
])
->fields($fields);
}

View File

@@ -1,18 +1,22 @@
<?php
namespace App\Notifications\Messages\Broadcast;
namespace App\Notifications\Messages;
use App\Contracts\Notification;
use App\Models\Pirep;
use App\Notifications\Channels\Discord\DiscordMessage;
use App\Notifications\Channels\Discord\DiscordWebhook;
use App\Notifications\Channels\MailChannel;
use App\Support\Units\Distance;
use App\Support\Units\Time;
use Illuminate\Contracts\Queue\ShouldQueue;
use PhpUnitsOfMeasure\Exception\NonNumericValue;
use PhpUnitsOfMeasure\Exception\NonStringUnitName;
class PirepFiled extends Notification implements ShouldQueue
class PirepSubmitted extends Notification implements ShouldQueue
{
use MailChannel;
private $pirep;
/**
@@ -25,11 +29,17 @@ class PirepFiled extends Notification implements ShouldQueue
parent::__construct();
$this->pirep = $pirep;
$this->setMailable(
'New PIREP Submitted',
'notifications.mail.admin.pirep.submitted',
['pirep' => $this->pirep]
);
}
public function via($notifiable)
{
return ['discord_webhook'];
return ['mail', DiscordWebhook::class];
}
/**
@@ -41,40 +51,42 @@ class PirepFiled extends Notification implements ShouldQueue
*/
public function toDiscordChannel($pirep): ?DiscordMessage
{
$title = 'Flight '.$pirep->ident.' Filed';
if (empty(setting('notifications.discord_public_webhook_url'))) {
return null;
}
$title = 'Flight '.$pirep->airline->code.$pirep->ident.' Filed';
$fields = [
'Dep.Airport' => $pirep->dpt_airport_id,
'Arr.Airport' => $pirep->arr_airport_id,
'Equipment' => $pirep->aircraft->ident,
'Flight Time' => Time::minutesToTimeString($pirep->flight_time),
'Flight' => $pirep->airline->code.$pirep->ident,
'Departure Airport' => $pirep->dpt_airport_id,
'Arrival Airport' => $pirep->arr_airport_id,
'Equipment' => $pirep->aircraft->ident,
'Flight Time (Planned)' => Time::minutesToTimeString($pirep->planned_flight_time),
];
if ($pirep->distance) {
if ($pirep->planned_distance) {
try {
$distance = new Distance(
$pirep->distance,
$planned_distance = new Distance(
$pirep->planned_distance,
config('phpvms.internal_units.distance')
);
$pd = $distance[$distance->unit].' '.$distance->unit;
$fields['Distance'] = $pd;
} catch (NonNumericValue|NonStringUnitName $e) {
$pd = $planned_distance[$planned_distance->unit].' '.$planned_distance->unit;
$fields['Distance (Planned)'] = $pd;
} catch (NonNumericValue | NonStringUnitName $e) {
}
}
// User avatar, somehow $pirep->user->resolveAvatarUrl() is not being accepted by Discord as thumbnail
$user_avatar = !empty($pirep->user->avatar) ? $pirep->user->avatar->url : $pirep->user->gravatar(256);
$dm = new DiscordMessage();
return $dm->webhook(setting('notifications.discord_public_webhook_url'))
->success()
->title($title)
->description($pirep->user->discord_id ? 'Flight by <@'.$pirep->user->discord_id.'>' : '')
->thumbnail(['url' => $user_avatar])
->image(['url' => $pirep->airline->logo])
->url(route('frontend.pireps.show', [$pirep->id]))
->author([
'name' => $pirep->user->ident.' - '.$pirep->user->name_private,
'url' => route('frontend.profile.show', [$pirep->user_id]),
'name' => $pirep->user->ident.' - '.$pirep->user->name_private,
'url' => route('frontend.profile.show', [$pirep->user_id]),
'icon_url' => $pirep->user->resolveAvatarUrl(),
])
->fields($fields);
}

View File

@@ -11,7 +11,6 @@ use App\Events\PirepRejected;
use App\Events\PirepStatusChange;
use App\Events\UserRegistered;
use App\Events\UserStateChanged;
use App\Models\Enums\PirepStatus;
use App\Models\Enums\UserState;
use App\Models\User;
use App\Notifications\Messages\UserRejected;
@@ -59,8 +58,8 @@ class NotificationEventsHandler extends Listener
}
try {
// $this->notifyUser($user, $notification);
Notification::send([$user], $notification);
$this->notifyUser($user, $notification);
// Notification::send([$user], $notification);
} catch (Exception $e) {
Log::emergency('Error emailing admin ('.$user->email.'). Error='.$e->getMessage());
}
@@ -135,10 +134,10 @@ class NotificationEventsHandler extends Listener
*/
$this->notifyAdmins(new Messages\AdminUserRegistered($event->user));
/*
* Broadcast notifications
/**
* Discord and other notifications
*/
Notification::send([$event->user], new Messages\Broadcast\UserRegistered($event->user));
Notification::send([$event->user], new Messages\AdminUserRegistered($event->user));
}
/**
@@ -162,42 +161,21 @@ class NotificationEventsHandler extends Listener
}
/**
* Prefile notification. Disabled intentionally, No need to send it to Discord
* Prefile notification
*/
public function onPirepPrefile(PirepPrefiled $event): void
{
Log::info('NotificationEvents::onPirepPrefile: '.$event->pirep->id.' prefiled');
/*
* Broadcast notifications
*/
// Notification::send([$event->pirep], new Messages\Broadcast\PirepPrefiled($event->pirep));
Notification::send([$event->pirep], new Messages\PirepPrefiled($event->pirep));
}
/**
* Status Change notification.
* Reduced the messages (Boarding, Pushback, TakeOff, Landing and non-normals only)
* If needed array can be tied to a setting at admin side for further customization
* Status Change notification
*/
public function onPirepStatusChange(PirepStatusChange $event): void
{
Log::info('NotificationEvents::onPirepStatusChange: '.$event->pirep->id.' status changed');
$message_types = [
PirepStatus::BOARDING,
PirepStatus::PUSHBACK_TOW,
PirepStatus::GRND_RTRN,
PirepStatus::TAKEOFF,
PirepStatus::LANDED,
PirepStatus::DIVERTED,
PirepStatus::CANCELLED,
PirepStatus::PAUSED,
PirepStatus::EMERG_DESCENT,
];
if (setting('notifications.discord_pirep_status', true) && in_array($event->pirep->status, $message_types, true)) {
Notification::send([$event->pirep], new Messages\Broadcast\PirepStatusChanged($event->pirep));
}
Log::info('NotificationEvents::onPirepStatusChange: '.$event->pirep->id.' prefiled');
Notification::send([$event->pirep], new Messages\PirepStatusChanged($event->pirep));
}
/**
@@ -208,14 +186,8 @@ class NotificationEventsHandler extends Listener
public function onPirepFile(PirepFiled $event): void
{
Log::info('NotificationEvents::onPirepFile: '.$event->pirep->id.' filed');
if (setting('notifications.mail_pirep_admin', true)) {
$this->notifyAdmins(new Messages\PirepFiled($event->pirep));
}
/*
* Broadcast notifications
*/
Notification::send([$event->pirep], new Messages\Broadcast\PirepFiled($event->pirep));
$this->notifyAdmins(new Messages\PirepSubmitted($event->pirep));
Notification::send([$event->pirep], new Messages\PirepSubmitted($event->pirep));
}
/**
@@ -225,10 +197,8 @@ class NotificationEventsHandler extends Listener
*/
public function onPirepAccepted(PirepAccepted $event): void
{
if (setting('notifications.mail_pirep_user_ack', true)) {
Log::info('NotificationEvents::onPirepAccepted: '.$event->pirep->id.' accepted');
$this->notifyUser($event->pirep->user, new Messages\PirepAccepted($event->pirep));
}
Log::info('NotificationEvents::onPirepAccepted: '.$event->pirep->id.' accepted');
$this->notifyUser($event->pirep->user, new Messages\PirepAccepted($event->pirep));
}
/**
@@ -238,10 +208,8 @@ class NotificationEventsHandler extends Listener
*/
public function onPirepRejected(PirepRejected $event): void
{
if (setting('notifications.mail_pirep_user_rej', true)) {
Log::info('NotificationEvents::onPirepRejected: '.$event->pirep->id.' rejected');
$this->notifyUser($event->pirep->user, new Messages\PirepRejected($event->pirep));
}
Log::info('NotificationEvents::onPirepRejected: '.$event->pirep->id.' rejected');
$this->notifyUser($event->pirep->user, new Messages\PirepRejected($event->pirep));
}
/**
@@ -252,13 +220,7 @@ class NotificationEventsHandler extends Listener
public function onNewsAdded(NewsAdded $event): void
{
Log::info('NotificationEvents::onNewsAdded');
if (setting('notifications.mail_news', true)) {
$this->notifyAllUsers(new Messages\NewsAdded($event->news));
}
/*
* Broadcast notifications
*/
Notification::send([$event->news], new Messages\Broadcast\NewsAdded($event->news));
$this->notifyAllUsers(new Messages\NewsAdded($event->news));
Notification::send([$event->news], new Messages\NewsAdded($event->news));
}
}

View File

@@ -2,12 +2,10 @@
namespace App\Providers;
use App\Notifications\Channels\Discord\DiscordWebhook;
use App\Services\ModuleService;
use App\Support\ThemeViewFinder;
use App\Support\Utils;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
@@ -17,13 +15,8 @@ class AppServiceProvider extends ServiceProvider
public function boot(): void
{
Schema::defaultStringLength(191);
Paginator::useBootstrap();
View::share('moduleSvc', app(ModuleService::class));
Notification::extend('discord_webhook', function ($app) {
return app(DiscordWebhook::class);
});
}
/**

View File

@@ -12,12 +12,9 @@ use App\Cron\Nightly\PilotLeave;
use App\Cron\Nightly\RecalculateBalances;
use App\Cron\Nightly\RecalculateStats;
use App\Cron\Nightly\SetActiveFlights;
use App\Events\CronFifteenMinute;
use App\Events\CronFiveMinute;
use App\Events\CronHourly;
use App\Events\CronMonthly;
use App\Events\CronNightly;
use App\Events\CronThirtyMinute;
use App\Events\CronWeekly;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@@ -27,15 +24,6 @@ use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvi
class CronServiceProvider extends ServiceProvider
{
protected $listen = [
CronFiveMinute::class => [],
CronFifteenMinute::class => [],
CronThirtyMinute::class => [],
CronHourly::class => [
DeletePireps::class,
RemoveExpiredBids::class,
RemoveExpiredLiveFlights::class,
ClearExpiredSimbrief::class,
],
CronNightly::class => [
ApplyExpenses::class,
RecalculateBalances::class,
@@ -44,10 +32,19 @@ class CronServiceProvider extends ServiceProvider
RecalculateStats::class,
NewVersionCheck::class,
],
CronWeekly::class => [
],
CronMonthly::class => [
\App\Cron\Monthly\ApplyExpenses::class,
],
CronHourly::class => [
DeletePireps::class,
RemoveExpiredBids::class,
RemoveExpiredLiveFlights::class,
ClearExpiredSimbrief::class,
],
];
}

View File

@@ -3,13 +3,11 @@
namespace App\Providers;
use App\Events\Expenses;
use App\Events\Fares;
use App\Events\PirepFiled;
use App\Events\UserStatsChanged;
use App\Listeners\AwardHandler;
use App\Listeners\BidEventHandler;
use App\Listeners\ExpenseListener;
use App\Listeners\FareListener;
use App\Listeners\FinanceEventHandler;
use App\Listeners\PirepEventsHandler;
use App\Listeners\UserStateListener;
@@ -27,10 +25,6 @@ class EventServiceProvider extends ServiceProvider
ExpenseListener::class,
],
Fares::class => [
FareListener::class,
],
PirepFiled::class => [
UserStateListener::class,
],

View File

@@ -376,21 +376,6 @@ class RouteServiceProvider extends ServiceProvider
], 'settings', 'SettingsController@update')
->name('settings.update')->middleware('ability:admin,settings');
// Type Ratings
Route::resource('typeratings', 'TypeRatingController')->middleware('ability:admin,typeratings');
Route::match([
'get',
'post',
'put',
'delete',
], 'typeratings/{id}/subfleets', 'TypeRatingController@subfleets')->middleware('ability:admin,typeratings');
Route::match([
'get',
'post',
'put',
'delete',
], 'typeratings/{id}/users', 'TypeRatingController@users')->middleware('ability:admin,typeratings');
// maintenance
Route::match(['get'], 'maintenance', 'MaintenanceController@index')
->name('maintenance.index')->middleware('ability:admin,maintenance');
@@ -441,13 +426,6 @@ class RouteServiceProvider extends ServiceProvider
'delete',
], 'subfleets/{id}/ranks', 'SubfleetController@ranks')->middleware('ability:admin,fleet');
Route::match([
'get',
'post',
'put',
'delete',
], 'subfleets/{id}/typeratings', 'SubfleetController@typeratings')->middleware('ability:admin,fleet');
Route::resource('subfleets', 'SubfleetController')->middleware('ability:admin,fleet');
/**
@@ -461,13 +439,6 @@ class RouteServiceProvider extends ServiceProvider
Route::resource('users', 'UserController')->middleware('ability:admin,users');
Route::match([
'get',
'post',
'put',
'delete',
], 'users/{id}/typeratings', 'UserController@typeratings')->middleware('ability:admin,users');
// defaults
Route::get('', ['uses' => 'DashboardController@index'])
->middleware('update_pending', 'ability:admin,admin-access');
@@ -613,10 +584,6 @@ class RouteServiceProvider extends ServiceProvider
Route::get('user/fleet', 'UserController@fleet');
Route::get('user/pireps', 'UserController@pireps');
Route::get('bids', 'UserController@bids');
Route::get('bids/{id}', 'UserController@get_bid');
Route::get('user/bids/{id}', 'UserController@get_bid');
Route::get('user/bids', 'UserController@bids');
Route::put('user/bids', 'UserController@bids');
Route::post('user/bids', 'UserController@bids');

View File

@@ -69,11 +69,11 @@ class AcarsRepository extends Repository
->where(['state' => PirepState::IN_PROGRESS]);
if ($live_time !== null && $live_time > 0) {
$st = Carbon::now()->subHours($live_time);
$q = $q->where('updated_at', '>=', $st);
$st = Carbon::now('UTC')->subHours($live_time);
$q = $q->whereDate('created_at', '>=', $st);
}
$q = $q->orderBy('updated_at', 'desc');
$q = $q->orderBy('created_at', 'desc');
return $q->get();
}

View File

@@ -18,10 +18,8 @@ class FlightRepository extends Repository implements CacheableInterface
protected $fieldSearchable = [
'arr_airport_id',
'callsign',
'distance',
'dpt_airport_id',
'flight_time',
'flight_type',
'flight_number' => 'like',
'route_code' => 'like',
@@ -96,10 +94,6 @@ class FlightRepository extends Repository implements CacheableInterface
$where['flight_number'] = $request->input('flight_number');
}
if ($request->filled('callsign')) {
$where['callsign'] = $request->input('callsign');
}
if ($request->filled('flight_type') && $request->input('flight_type') !== '0') {
$where['flight_type'] = $request->input('flight_type');
}
@@ -134,16 +128,6 @@ class FlightRepository extends Repository implements CacheableInterface
$where[] = ['distance', '<=', $request->input('dlt')];
}
// Time, greater than
if ($request->filled('tgt')) {
$where[] = ['flight_time', '>=', $request->input('tgt')];
}
// Time, less than
if ($request->filled('tlt')) {
$where[] = ['flight_time', '<=', $request->input('tlt')];
}
// Do a special query for finding the child subfleets
if ($request->filled('subfleet_id')) {
$relations['subfleets'] = [

Some files were not shown because too many files have changed in this diff Show More