Compare commits

..

3 Commits

Author SHA1 Message Date
Nabeel Shahzad
c97977de9a Include all enums in aliases 2021-01-25 17:07:11 -05:00
Nabeel Shahzad
bda1a91117 Return null on empty value 2021-01-25 17:03:48 -05:00
Nabeel Shahzad
3f92191126 Tests for the CSV import fix
#1007
2021-01-25 16:49:32 -05:00
497 changed files with 59090 additions and 54779 deletions

View File

@@ -23,7 +23,6 @@ declare -a remove_files=(
.eslintrc .eslintrc
.php_cs .php_cs
.php_cs.cache .php_cs.cache
.php-cs-fixer.php
.phpstorm.meta.php .phpstorm.meta.php
.styleci.yml .styleci.yml
.phpunit.result.cache .phpunit.result.cache
@@ -31,7 +30,6 @@ declare -a remove_files=(
intellij_style.xml intellij_style.xml
config.php config.php
docker-compose.yml docker-compose.yml
docker-compose.local.yml
Makefile Makefile
phpcs.xml phpcs.xml
phpunit.xml phpunit.xml
@@ -71,25 +69,13 @@ mkdir -p storage/framework/views
cd /tmp cd /tmp
echo "Current directory contents"
ls -al $BASE_DIR
echo "Parent directory contents"
ls -al $BASE_DIR/../ ls -al $BASE_DIR/../
echo "Calling find" tar -czf $TAR_NAME -C $BASE_DIR .
find $BASE_DIR/../ -type d -maxdepth 2
tar -czf $TAR_NAME -C $BASE_DIR --xform 's:^\./::' . [--show-transformed-names|--show-stored-names]
sha256sum $TAR_NAME >"$TAR_NAME.sha256" sha256sum $TAR_NAME >"$TAR_NAME.sha256"
tar2zip $TAR_NAME
cd $BASE_DIR;
zip -r $ZIP_NAME ./
sha256sum $ZIP_NAME >"$ZIP_NAME.sha256" sha256sum $ZIP_NAME >"$ZIP_NAME.sha256"
mv $ZIP_NAME /tmp
mv "$ZIP_NAME.sha256" /tmp
ls -al /tmp ls -al /tmp
echo "Moving to dist" echo "Moving to dist"

View File

@@ -1,3 +1,7 @@
<?php
exit();
?>
APP_ENV="dev" APP_ENV="dev"
APP_KEY="base64:zdgcDqu9PM8uGWCtMxd74ZqdGJIrnw812oRMmwDF6KY=" APP_KEY="base64:zdgcDqu9PM8uGWCtMxd74ZqdGJIrnw812oRMmwDF6KY="
APP_URL="http://localhost" APP_URL="http://localhost"
@@ -8,7 +12,7 @@ APP_LOCALE="en"
PHPVMS_INSTALLED="true" PHPVMS_INSTALLED="true"
APP_LOG="daily" APP_LOG="daily"
LOG_LEVEL="debug" APP_LOG_LEVEL="debug"
APP_LOG_MAX_FILES="3" APP_LOG_MAX_FILES="3"
DB_CONNECTION="mysql" DB_CONNECTION="mysql"

View File

@@ -2,12 +2,12 @@ name: 'Build'
on: ['push', 'pull_request', 'workflow_dispatch', 'release'] on: ['push', 'pull_request', 'workflow_dispatch', 'release']
jobs: jobs:
build: build:
runs-on: ubuntu-20.04 runs-on: ubuntu-18.04
if: github.repository == 'nabeelio/phpvms' if: github.repository == 'nabeelio/phpvms'
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
php-versions: ['7.3', '7.4', '8.0', '8.1'] php-versions: ['7.3', '7.4']
name: PHP ${{ matrix.php-versions }} name: PHP ${{ matrix.php-versions }}
env: env:
extensions: intl, pcov, mbstring extensions: intl, pcov, mbstring
@@ -41,6 +41,7 @@ jobs:
with: with:
path: ${{ steps.composer-cache.outputs.dir }} path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
# Configure PHP # Configure PHP
- name: Setup PHP - name: Setup PHP
@@ -70,6 +71,7 @@ jobs:
php --version php --version
mysql --version mysql --version
# Downgrade composer version to 1.x # Downgrade composer version to 1.x
composer self-update --1
composer install --dev --no-interaction --verbose composer install --dev --no-interaction --verbose
cp .github/scripts/env.php env.php cp .github/scripts/env.php env.php
cp .github/scripts/phpunit.xml phpunit.xml cp .github/scripts/phpunit.xml phpunit.xml
@@ -78,8 +80,7 @@ jobs:
- name: Run Tests - name: Run Tests
run: | run: |
export PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix --config=.php_cs -v --dry-run --diff --using-cache=no
vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php -v --dry-run --diff --using-cache=no
vendor/bin/phpunit --debug --verbose vendor/bin/phpunit --debug --verbose
# This runs after all of the tests, run have run. Creates a cleaned up version of the # This runs after all of the tests, run have run. Creates a cleaned up version of the
@@ -117,6 +118,8 @@ jobs:
- name: 'Install Release Dependencies' - name: 'Install Release Dependencies'
run: | run: |
rm -rf vendor rm -rf vendor
sudo npm i tar-to-zip -g
composer self-update --1
composer install --no-dev --prefer-dist --no-interaction --verbose composer install --no-dev --prefer-dist --no-interaction --verbose
sudo chmod +x ./.github/scripts/* sudo chmod +x ./.github/scripts/*
@@ -179,6 +182,8 @@ jobs:
- name: 'Install Release Dependencies' - name: 'Install Release Dependencies'
run: | run: |
rm -rf vendor rm -rf vendor
sudo npm i tar-to-zip -g
composer self-update --1
composer install --no-dev --prefer-dist --no-interaction --verbose composer install --no-dev --prefer-dist --no-interaction --verbose
sudo chmod +x ./.github/scripts/* sudo chmod +x ./.github/scripts/*

2
.gitignore vendored
View File

@@ -74,6 +74,4 @@ error_log
.sass-cache .sass-cache
.DS_Store .DS_Store
/config.php /config.php
/config.bak.php
/VERSION /VERSION
sync.sh

View File

@@ -28,8 +28,6 @@ RedirectMatch 403 ^/composer.phar
RedirectMatch 403 ^/env.php.*?$ RedirectMatch 403 ^/env.php.*?$
RedirectMatch 403 ^/env.php RedirectMatch 403 ^/env.php
RedirectMatch 403 ^/env.php$ RedirectMatch 403 ^/env.php$
RedirectMatch 403 ^/config.php$
RedirectMatch 403 ^/config.bak.php$
RedirectMatch 403 ^/Makefile RedirectMatch 403 ^/Makefile
RedirectMatch 403 ^/package.json RedirectMatch 403 ^/package.json
RedirectMatch 403 ^/package-lock.json RedirectMatch 403 ^/package-lock.json

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);

4
.shift
View File

@@ -1,4 +0,0 @@
This file was added by Shift #54503 in order to open a
Pull Request since no other commits were made.
You should remove this file.

View File

@@ -1,11 +1,8 @@
FROM php:8.0.9-fpm-alpine3.14 FROM php:7.4-fpm-alpine
WORKDIR /var/www/ WORKDIR /var/www/
# Setup composer RUN apk add gmp-dev
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 curl --silent --show-error https://getcomposer.org/installer | php RUN curl --silent --show-error https://getcomposer.org/installer | php
# Copy any config files in # Copy any config files in
@@ -15,23 +12,17 @@ RUN ln -sf /dev/stderr /var/log/fpm-error.log
RUN docker-php-ext-install \ RUN docker-php-ext-install \
calendar \ calendar \
intl \
pdo_mysql \ pdo_mysql \
gd \
gmp \ gmp \
bcmath \ opcache && \
opcache \ docker-php-ext-enable pdo_mysql opcache
zip && \
docker-php-ext-enable pdo_mysql opcache bcmath zip
COPY . /var/www/ COPY . /var/www/
RUN composer install \ RUN php composer.phar install \
--ignore-platform-reqs \ --ignore-platform-reqs \
--no-interaction \ --no-interaction \
--no-plugins \ --no-plugins \
--no-scripts \ --no-scripts \
--prefer-dist --prefer-dist
#RUN chown -R www-data:www-data /var/www
EXPOSE 9000 EXPOSE 9000

View File

@@ -1,3 +1,5 @@
BSD 3-Clause License
Copyright (c) 2017, phpvms - http://www.phpvms.net Copyright (c) 2017, phpvms - http://www.phpvms.net
All rights reserved. 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 contributors may be used to endorse or promote products derived from
this software without specific prior written permission. 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" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

View File

@@ -82,6 +82,10 @@ test:
phpcs: phpcs:
@vendor/bin/php-cs-fixer fix --config=.php_cs -v --diff --diff-format=udiff --dry-run @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 .PHONY: replay-acars
replay-acars: replay-acars:
#@php artisan phpvms:replay AAL10,AAL3113,BAW172,DAL988,FIN6,MSR986 --manual #@php artisan phpvms:replay AAL10,AAL3113,BAW172,DAL988,FIN6,MSR986 --manual
@@ -91,6 +95,11 @@ replay-acars:
sass-watch: sass-watch:
sass --watch public/assets/admin/sass/paper-dashboard.scss:public/assets/admin/css/paper-dashboard.css 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 .PHONY: deploy-package
deploy-package: deploy-package:
./.travis/deploy_script.sh ./.travis/deploy_script.sh
@@ -100,9 +109,17 @@ reset-installer:
@php artisan database:create --reset @php artisan database:create --reset
@php artisan migrate:refresh --seed @php artisan migrate:refresh --seed
.PHONY: docker-test .PHONY: docker
docker-test: docker:
@docker compose -f docker-compose.yml -f docker-compose.local.yml up @mkdir -p $(CURR_PATH)/tmp/mysql
-docker rm -f phpvms
docker build -t phpvms .
docker run --name=phpvms \
-v $(CURR_PATH):/var/www/ \
-v $(CURR_PATH)/tmp/mysql:/var/lib/mysql \
-p 8080:80 \
phpvms
.PHONY: docker-clean .PHONY: docker-clean
docker-clean: docker-clean:

View File

@@ -30,16 +30,15 @@ A full distribution, with all of the composer dependencies, is available at this
[View installation details](https://docs.phpvms.net/installation/installation) [View installation details](https://docs.phpvms.net/installation/installation)
## Development Environment with Docker ## Development Environment
A full development environment can be brought up using Docker, without having to install composer/npm locally A full development environment can be brought up using Docker:
```bash ```bash
make docker-test composer install
yarn install
# **OR** with docker-compose directly docker-compose build
docker-compose up
docker-compose -f docker-compose.yml -f docker-compose.local.yml up
``` ```
Then go to `http://localhost`. If you're using dnsmasq, the `app` container is listening on `phpvms.test`, or you can add to your `/etc/hosts` file: Then go to `http://localhost`. If you're using dnsmasq, the `app` container is listening on `phpvms.test`, or you can add to your `/etc/hosts` file:
@@ -48,8 +47,6 @@ Then go to `http://localhost`. If you're using dnsmasq, the `app` container is l
127.0.0.1 phpvms.test 127.0.0.1 phpvms.test
``` ```
The `docker-compose.local.yml` overrides the `app` section in `docker-compose.yml`. The standard `docker-compose.yml` can be used if you want to deploy from the image, or as a template for your own Dockerized deployments.
### Building JS/CSS assets ### Building JS/CSS assets
Yarn is required, run: Yarn is required, run:

View File

@@ -4,9 +4,9 @@ namespace App\Console\Commands;
use App; use App;
use App\Contracts\Command; use App\Contracts\Command;
use App\Services\Installer\ConfigService;
use App\Services\Installer\SeederService; use App\Services\Installer\SeederService;
use DatabaseSeeder; use DatabaseSeeder;
use Modules\Installer\Services\ConfigService;
/** /**
* Create the config files * Create the config files
@@ -81,13 +81,13 @@ class CreateConfigs extends Command
$this->info('Regenerating the config files'); $this->info('Regenerating the config files');
$cfgSvc->createConfigFiles([ $cfgSvc->createConfigFiles([
'APP_ENV' => 'dev', 'APP_ENV' => 'dev',
'SITE_NAME' => $this->argument('name'), 'SITE_NAME' => $this->argument('name'),
'DB_CONNECTION' => 'mysql', 'DB_CONN' => 'mysql',
'DB_HOST' => $this->argument('db_host'), 'DB_HOST' => $this->argument('db_host'),
'DB_DATABASE' => $this->argument('db_name'), 'DB_NAME' => $this->argument('db_name'),
'DB_USERNAME' => $this->argument('db_user'), 'DB_USER' => $this->argument('db_user'),
'DB_PASSWORD' => $this->argument('db_pass'), 'DB_PASS' => $this->argument('db_pass'),
]); ]);
$this->info('Config files generated!'); $this->info('Config files generated!');

View File

@@ -79,9 +79,9 @@ class DevInstall extends Command
$this->info('Regenerating the config files'); $this->info('Regenerating the config files');
$cfgSvc->createConfigFiles([ $cfgSvc->createConfigFiles([
'APP_ENV' => 'dev', 'APP_ENV' => 'dev',
'SITE_NAME' => 'phpvms test', 'SITE_NAME' => 'phpvms test',
'DB_CONNECTION' => 'sqlite', 'DB_CONN' => 'sqlite',
]); ]);
$this->info('Config files generated!'); $this->info('Config files generated!');

View File

@@ -1,32 +0,0 @@
<?php
namespace App\Console\Commands;
use App;
use App\Contracts\Command;
class EmailTest extends Command
{
protected $signature = 'phpvms:email-test';
protected $description = 'Send a test notification to admins';
/**
* Run dev related commands
*
* @throws \Symfony\Component\HttpFoundation\File\Exception\FileException
*/
public function handle()
{
/** @var App\Notifications\NotificationEventsHandler $eventHandler */
$eventHandler = app(App\Notifications\NotificationEventsHandler::class);
$news = new App\Models\News();
$news->user_id = 1;
$news->subject = 'Test News';
$news->body = 'Test Body';
$news->save();
$newsEvent = new App\Events\NewsAdded($news);
$eventHandler->onNewsAdded($newsEvent);
}
}

View File

@@ -1,38 +0,0 @@
<?php
namespace App\Console\Commands;
use App;
use App\Contracts\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
class ProcessQueue extends Command
{
protected $signature = 'queue:cron';
protected $description = 'Process the queue from a cron job';
/**
* Run the queue tasks
*/
public function handle()
{
Artisan::call('queue:work', [
'--sansdaemon' => null,
'--stop-when-empty' => null,
]);
Log::info(Artisan::output());
///** @var App\Support\WorkCommand $queueWorker */
//$queueWorker = new App\Support\WorkCommand(app('queue.worker'), app('cache.store'));
//$queueWorker->setInput($queueWorker->createInputFromArguments([]));
//$queueWorker->handle();
/*$output = $this->call('queue:work', [
'--stop-when-empty' => null,
]);
Log::info($output);*/
}
}

View File

@@ -1,25 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Contracts\Command;
use App\Services\Installer\ConfigService;
/**
* Command to rewrite the config files
*/
class RewriteConfigs extends Command
{
protected $signature = 'phpvms:rewrite-configs';
protected $description = 'Rewrite the config files';
/**
* Run dev related commands
*/
public function handle()
{
/** @var ConfigService $configSvc */
$configSvc = app(ConfigService::class);
$configSvc->rewriteConfigFiles();
}
}

View File

@@ -1,25 +0,0 @@
<?php
namespace App\Console\Cron;
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 Command
{
protected $signature = 'cron:queue';
protected $description = 'Run the cron queue tasks';
protected $schedule;
public function handle(): void
{
$this->redirectLoggingToFile('cron');
Artisan::call('queue:cron');
$this->info(Artisan::output());
}
}

View File

@@ -3,7 +3,6 @@
namespace App\Console; namespace App\Console;
use App\Console\Cron\Hourly; use App\Console\Cron\Hourly;
use App\Console\Cron\JobQueue;
use App\Console\Cron\Monthly; use App\Console\Cron\Monthly;
use App\Console\Cron\Nightly; use App\Console\Cron\Nightly;
use App\Console\Cron\Weekly; use App\Console\Cron\Weekly;
@@ -14,11 +13,7 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel class Kernel extends ConsoleKernel
{ {
/** /**
* Define the application's command schedule. How this works... according to the command * Define the application's command schedule.
* time, an event gets send out with the appropriate time (e.g, hourly sends an hourly event)
*
* Then the CronServiceProvider has the list of cronjobs which then run according to the events
* and then calls those at the proper times.
* *
* @param \Illuminate\Console\Scheduling\Schedule $schedule * @param \Illuminate\Console\Scheduling\Schedule $schedule
* *
@@ -26,26 +21,16 @@ class Kernel extends ConsoleKernel
*/ */
protected function schedule(Schedule $schedule): void protected function schedule(Schedule $schedule): void
{ {
// If not using the queue worker then run those via cron
if (!config('queue.worker', false)) {
$schedule->command(JobQueue::class)
->everyMinute()
->withoutOverlapping();
}
$schedule->command(Nightly::class)->dailyAt('01:00'); $schedule->command(Nightly::class)->dailyAt('01:00');
$schedule->command(Weekly::class)->weeklyOn(0); $schedule->command(Weekly::class)->weeklyOn(0);
$schedule->command(Monthly::class)->monthlyOn(1); $schedule->command(Monthly::class)->monthlyOn(1);
$schedule->command(Hourly::class)->hourly(); $schedule->command(Hourly::class)->hourly();
// When spatie-backups runs // When spatie-backups runs
/*if (config('backup.backup.enabled', false) === true) { $schedule->command('backup:clean')->daily()->at('01:00');
$schedule->command('backup:clean')->daily()->at('01:00'); $schedule->command('backup:run')->daily()->at('02:00');
$schedule->command('backup:run')->daily()->at('02:00');
}*/
// Update the last time the cron was run // Update the last time the cron was run
/** @var CronService $cronSvc */
$cronSvc = app(CronService::class); $cronSvc = app(CronService::class);
$cronSvc->updateLastRunTime(); $cronSvc->updateLastRunTime();
} }

View File

@@ -24,9 +24,9 @@ abstract class Command extends \Illuminate\Console\Command
parent::__construct(); parent::__construct();
// Running in the console but not in the tests // Running in the console but not in the tests
/*if (app()->runningInConsole() && env('APP_ENV') !== 'testing') { if (app()->runningInConsole() && env('APP_ENV') !== 'testing') {
$this->redirectLoggingToFile('stdout'); $this->redirectLoggingToFile('stdout');
}*/ }
} }
/** /**

View File

@@ -166,36 +166,10 @@ class ImportExport
return []; 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]]; return [$split_values[0]];
} }
foreach ($split_values as $value) { foreach ($split_values as $value) {
$value = trim($value);
if ($value === '') {
continue;
}
// This isn't in the query string format, so it's // This isn't in the query string format, so it's
// just a straight key-value pair set // just a straight key-value pair set
if (strpos($value, '?') === false) { if (strpos($value, '?') === false) {

View File

@@ -12,24 +12,13 @@ abstract class Metar
{ {
/** /**
* Implement retrieving the METAR - return the METAR string. Needs to be protected, * Implement retrieving the METAR - return the METAR string. Needs to be protected,
* since this shouldn't be directly called. Call `metar($icao)`. If not implemented, * since this shouldn't be directly called. Call `get_metar($icao)` instead
* return a blank string
* *
* @param $icao * @param $icao
* *
* @return mixed * @return mixed
*/ */
abstract protected function get_metar($icao): string; abstract protected function metar($icao): string;
/**
* Implement retrieving the TAF - return the string. Call `taf($icao)`. If not implemented,
* return a blank string
*
* @param $icao
*
* @return mixed
*/
abstract protected function get_taf($icao): string;
/** /**
* Download the METAR, wrap in caching * Download the METAR, wrap in caching
@@ -38,9 +27,9 @@ abstract class Metar
* *
* @return string * @return string
*/ */
public function metar($icao): string public function get_metar($icao): string
{ {
$cache = config('cache.keys.METAR_WEATHER_LOOKUP'); $cache = config('cache.keys.WEATHER_LOOKUP');
$key = $cache['key'].$icao; $key = $cache['key'].$icao;
if (Cache::has($key)) { if (Cache::has($key)) {
@@ -51,7 +40,7 @@ abstract class Metar
} }
try { try {
$raw_metar = $this->get_metar($icao); $raw_metar = $this->metar($icao);
} catch (\Exception $e) { } catch (\Exception $e) {
Log::error('Error getting METAR: '.$e->getMessage(), $e->getTrace()); Log::error('Error getting METAR: '.$e->getMessage(), $e->getTrace());
return ''; return '';
@@ -63,37 +52,4 @@ abstract class Metar
return $raw_metar; return $raw_metar;
} }
/**
* Download the TAF, wrap in caching
*
* @param $icao
*
* @return string
*/
public function taf($icao): string
{
$cache = config('cache.keys.TAF_WEATHER_LOOKUP');
$key = $cache['key'].$icao;
if (Cache::has($key)) {
$taf = Cache::get($key);
if ($taf !== '') {
return $taf;
}
}
try {
$taf = $this->get_taf($icao);
} catch (\Exception $e) {
Log::error('Error getting TAF: '.$e->getMessage(), $e->getTrace());
return '';
}
if ($taf !== '') {
Cache::put($key, $taf, $cache['time']);
}
return $taf;
}
} }

View File

@@ -2,9 +2,9 @@
namespace App\Contracts; namespace App\Contracts;
use App\Notifications\Channels\Discord\DiscordMessage;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;
class Notification extends \Illuminate\Notifications\Notification implements ShouldQueue class Notification extends \Illuminate\Notifications\Notification implements ShouldQueue
{ {
@@ -17,14 +17,14 @@ class Notification extends \Illuminate\Notifications\Notification implements Sho
{ {
// Look in the notifications.channels config and see where this particular // Look in the notifications.channels config and see where this particular
// notification can go. Map it to $channels // notification can go. Map it to $channels
/*$klass = static::class; $klass = static::class;
$notif_config = config('notifications.channels', []); $notif_config = config('notifications.channels', []);
if (!array_key_exists($klass, $notif_config)) { if (!array_key_exists($klass, $notif_config)) {
Log::error('Notification type '.$klass.' missing from notifications config, defaulting to mail'); Log::error('Notification type '.$klass.' missing from notifications config, defaulting to mail');
return; return;
} }
$this->channels = $notif_config[$klass];*/ $this->channels = $notif_config[$klass];
} }
/** /**
@@ -34,16 +34,8 @@ class Notification extends \Illuminate\Notifications\Notification implements Sho
* *
* @return array * @return array
*/ */
/*public function via($notifiable) public function via($notifiable)
{ {
return $this->channels; return $this->channels;
}*/
/**
* @return DiscordMessage|null
*/
public function toDiscordChannel($notifiable): ?DiscordMessage
{
return null;
} }
} }

View File

@@ -2,14 +2,11 @@
namespace App\Contracts; namespace App\Contracts;
use Exception;
use Illuminate\Validation\Validator; use Illuminate\Validation\Validator;
use function is_array;
use Prettus\Repository\Eloquent\BaseRepository; use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Exceptions\RepositoryException;
/** /**
* @mixin BaseRepository * @mixin \Prettus\Repository\Eloquent\BaseRepository
*/ */
abstract class Repository extends BaseRepository abstract class Repository extends BaseRepository
{ {
@@ -23,8 +20,8 @@ abstract class Repository extends BaseRepository
{ {
try { try {
return $this->find($id, $columns); return $this->find($id, $columns);
} catch (Exception $e) { } catch (\Exception $e) {
return null; return;
} }
} }
@@ -35,7 +32,11 @@ abstract class Repository extends BaseRepository
*/ */
public function validate($values) public function validate($values)
{ {
$validator = Validator::make($values, $this->model()->rules); $validator = Validator::make(
$values,
$this->model()->rules
);
if ($validator->fails()) { if ($validator->fails()) {
return $validator->messages(); return $validator->messages();
} }
@@ -49,8 +50,6 @@ abstract class Repository extends BaseRepository
* @param int $count * @param int $count
* @param string $sort_by created_at (default) or updated_at * @param string $sort_by created_at (default) or updated_at
* *
* @throws RepositoryException
*
* @return mixed * @return mixed
*/ */
public function recent($count = null, $sort_by = 'created_at') public function recent($count = null, $sort_by = 'created_at')
@@ -72,7 +71,7 @@ abstract class Repository extends BaseRepository
return $this->scopeQuery(function ($query) use ($where, $sort_by, $order_by) { return $this->scopeQuery(function ($query) use ($where, $sort_by, $order_by) {
$q = $query->where($where); $q = $query->where($where);
// See if there are multi-column sorts // See if there are multi-column sorts
if (is_array($sort_by)) { if (\is_array($sort_by)) {
foreach ($sort_by as $key => $sort) { foreach ($sort_by as $key => $sort) {
$q = $q->orderBy($key, $sort); $q = $q->orderBy($key, $sort);
} }
@@ -99,7 +98,7 @@ abstract class Repository extends BaseRepository
return $this->scopeQuery(function ($query) use ($col, $values, $sort_by, $order_by) { return $this->scopeQuery(function ($query) use ($col, $values, $sort_by, $order_by) {
$q = $query->whereNotIn($col, $values); $q = $query->whereNotIn($col, $values);
// See if there are multi-column sorts // See if there are multi-column sorts
if (is_array($sort_by)) { if (\is_array($sort_by)) {
foreach ($sort_by as $key => $sort) { foreach ($sort_by as $key => $sort) {
$q = $q->orderBy($key, $sort); $q = $q->orderBy($key, $sort);
} }
@@ -119,7 +118,7 @@ abstract class Repository extends BaseRepository
* @param array $columns * @param array $columns
* @param string $method * @param string $method
* *
* @throws RepositoryException * @throws \Prettus\Repository\Exceptions\RepositoryException
* *
* @return mixed * @return mixed
*/ */

View File

@@ -2,10 +2,7 @@
namespace App\Contracts; namespace App\Contracts;
use App\Support\Resources\CustomAnonymousResourceCollection;
use App\Support\Resources\CustomPaginatedResourceResponse;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Pagination\AbstractPaginator;
/** /**
* Base class for a resource/response * Base class for a resource/response
@@ -29,28 +26,4 @@ class Resource extends JsonResource
} }
} }
} }
/**
* Customize the response to exclude all the extra data that isn't used. Based on:
* https://gist.github.com/derekphilipau/4be52164a69ce487dcd0673656d280da
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function toResponse($request)
{
return $this->resource instanceof AbstractPaginator
? (new CustomPaginatedResourceResponse($this))->toResponse($request)
: parent::toResponse($request);
}
public static function collection($resource)
{
return tap(new CustomAnonymousResourceCollection($resource, static::class), function ($collection) {
if (property_exists(static::class, 'preserveKeys')) {
$collection->preserveKeys = (new static([]))->preserveKeys === true;
}
});
}
} }

View File

@@ -1,56 +0,0 @@
<?php
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;
use Illuminate\Support\Facades\Log;
/**
* Remove cancelled/deleted PIREPs. Look for PIREPs that were created before the setting time
* (e.g, 12 hours ago) and are marked with the
*/
class DeletePireps extends Listener
{
/**
* Delete old rejected PIREPs
*
* @param CronHourly $event
*
* @throws \Exception
*/
public function handle(CronHourly $event): void
{
$this->deletePireps(setting('pireps.delete_rejected_hours'), PirepState::REJECTED);
$this->deletePireps(setting('pireps.delete_cancelled_hours'), PirepState::CANCELLED);
}
/**
* Look for and delete PIREPs which match the criteria
*
* @param int $expire_time_hours The time in hours to look for PIREPs
* @param int $state The PirepState enum value
*/
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();
/** @var PirepService $pirepSvc */
$pirepSvc = app(PirepService::class);
/** @var Pirep $pirep */
foreach ($pireps as $pirep) {
Log::info('Cron: Deleting PIREP id='.$pirep->id.', state='.PirepState::label($state));
$pirepSvc->delete($pirep);
}
}
}

View File

@@ -25,7 +25,7 @@ class RemoveExpiredBids extends Listener
return; return;
} }
$date = Carbon::now('UTC')->subHours(setting('bids.expire_time')); $date = Carbon::now()->subHours(setting('bids.expire_time'));
Bid::where('created_at', '<', $date)->delete(); Bid::whereDate('created_at', '<', $date)->delete();
} }
} }

View File

@@ -4,11 +4,9 @@ namespace App\Cron\Hourly;
use App\Contracts\Listener; use App\Contracts\Listener;
use App\Events\CronHourly; use App\Events\CronHourly;
use App\Events\PirepCancelled;
use App\Models\Enums\PirepState; use App\Models\Enums\PirepState;
use App\Models\Pirep; use App\Models\Pirep;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
/** /**
* Remove expired live flights * Remove expired live flights
@@ -28,15 +26,9 @@ class RemoveExpiredLiveFlights extends Listener
return; return;
} }
$date = Carbon::now('UTC')->subHours(setting('acars.live_time')); $date = Carbon::now()->subHours(setting('acars.live_time'));
$pireps = Pirep::where('updated_at', '<', $date) Pirep::whereDate('updated_at', '<', $date)
->where('state', PirepState::IN_PROGRESS) ->where('state', PirepState::IN_PROGRESS)
->get(); ->delete();
foreach ($pireps as $pirep) {
event(new PirepCancelled($pirep));
Log::info('Cron: Deleting Expired Live PIREP id='.$pirep->id.', state='.PirepState::label($pirep->state));
$pirep->delete();
}
} }
} }

View File

@@ -6,7 +6,6 @@ use App\Contracts\Listener;
use App\Events\CronMonthly; use App\Events\CronMonthly;
use App\Models\Enums\ExpenseType; use App\Models\Enums\ExpenseType;
use App\Services\Finance\RecurringFinanceService; use App\Services\Finance\RecurringFinanceService;
use Illuminate\Support\Facades\Log;
/** /**
* Go through and apply any finances that are daily * Go through and apply any finances that are daily
@@ -36,7 +35,6 @@ class ApplyExpenses extends Listener
*/ */
public function handle(CronMonthly $event): void public function handle(CronMonthly $event): void
{ {
Log::info('Monthly: Applying monthly expenses');
$this->financeSvc->processExpenses(ExpenseType::MONTHLY); $this->financeSvc->processExpenses(ExpenseType::MONTHLY);
} }
} }

View File

@@ -6,7 +6,6 @@ use App\Contracts\Listener;
use App\Events\CronNightly; use App\Events\CronNightly;
use App\Models\Enums\ExpenseType; use App\Models\Enums\ExpenseType;
use App\Services\Finance\RecurringFinanceService; use App\Services\Finance\RecurringFinanceService;
use Illuminate\Support\Facades\Log;
/** /**
* Go through and apply any finances that are daily * Go through and apply any finances that are daily
@@ -36,7 +35,6 @@ class ApplyExpenses extends Listener
*/ */
public function handle(CronNightly $event): void public function handle(CronNightly $event): void
{ {
Log::info('Nightly: Applying daily expenses');
$this->financeSvc->processExpenses(ExpenseType::DAILY); $this->financeSvc->processExpenses(ExpenseType::DAILY);
} }
} }

View File

@@ -1,11 +1,10 @@
<?php <?php
namespace App\Cron\Hourly; namespace App\Cron\Nightly;
use App\Contracts\Listener; use App\Contracts\Listener;
use App\Events\CronHourly; use App\Events\CronNightly;
use App\Services\SimBriefService; use App\Services\SimBriefService;
use Illuminate\Support\Facades\Log;
/** /**
* Clear any expired SimBrief flight briefs that aren't attached to a PIREP * Clear any expired SimBrief flight briefs that aren't attached to a PIREP
@@ -22,9 +21,8 @@ class ClearExpiredSimbrief extends Listener
/** /**
* @param \App\Events\CronNightly $event * @param \App\Events\CronNightly $event
*/ */
public function handle(CronHourly $event): void public function handle(CronNightly $event): void
{ {
Log::info('Hourly: Removing expired Simbrief entries');
$this->simbriefSvc->removeExpiredEntries(); $this->simbriefSvc->removeExpiredEntries();
} }
} }

View File

@@ -5,8 +5,10 @@ namespace App\Cron\Nightly;
use App\Contracts\Listener; use App\Contracts\Listener;
use App\Events\CronNightly; use App\Events\CronNightly;
use App\Services\VersionService; use App\Services\VersionService;
use Illuminate\Support\Facades\Log;
/**
* Determine if any pilots should be set to ON LEAVE status
*/
class NewVersionCheck extends Listener class NewVersionCheck extends Listener
{ {
private $versionSvc; private $versionSvc;
@@ -26,7 +28,6 @@ class NewVersionCheck extends Listener
*/ */
public function handle(CronNightly $event): void public function handle(CronNightly $event): void
{ {
Log::info('Nightly: Checking for new version');
$this->versionSvc->isNewVersionAvailable(); $this->versionSvc->isNewVersionAvailable();
} }
} }

View File

@@ -4,8 +4,10 @@ namespace App\Cron\Nightly;
use App\Contracts\Listener; use App\Contracts\Listener;
use App\Events\CronNightly; use App\Events\CronNightly;
use App\Models\Enums\UserState;
use App\Models\User;
use App\Services\UserService; use App\Services\UserService;
use Illuminate\Support\Facades\Log; use Carbon\Carbon;
/** /**
* Determine if any pilots should be set to ON LEAVE status * Determine if any pilots should be set to ON LEAVE status
@@ -16,8 +18,6 @@ class PilotLeave extends Listener
/** /**
* PilotLeave constructor. * PilotLeave constructor.
*
* @param UserService $userSvc
*/ */
public function __construct(UserService $userSvc) public function __construct(UserService $userSvc)
{ {
@@ -34,9 +34,13 @@ class PilotLeave extends Listener
*/ */
public function handle(CronNightly $event): void public function handle(CronNightly $event): void
{ {
Log::info('Cron: Running pilot leave check'); if (setting('pilots.auto_leave_days') === 0) {
$users = $this->userSvc->findUsersOnLeave(); return;
Log::info('Found '.count($users).' users on leave'); }
$date = Carbon::now()->subDay(setting('pilots.auto_leave_days'));
$users = User::where('status', UserState::ACTIVE)
->whereDate('updated_at', '<', $date);
foreach ($users as $user) { foreach ($users as $user) {
Log::info('Setting user '.$user->ident.' to ON LEAVE status'); Log::info('Setting user '.$user->ident.' to ON LEAVE status');

View File

@@ -35,7 +35,7 @@ class RecalculateBalances extends Listener
*/ */
public function handle(CronNightly $event): void public function handle(CronNightly $event): void
{ {
Log::info('Nightly: Recalculating balances'); Log::info('Recalculating balances');
$journals = Journal::all(); $journals = Journal::all();
foreach ($journals as $journal) { foreach ($journals as $journal) {

View File

@@ -32,10 +32,10 @@ class RecalculateStats extends Listener
*/ */
public function handle(CronNightly $event): void public function handle(CronNightly $event): void
{ {
Log::info('Nightly: Recalculating user stats'); Log::info('Recalculating user stats');
$this->userSvc->recalculateAllUserStats(); $this->userSvc->recalculateAllUserStats();
Log::info('Nightly: Recalcuating aircraft status'); Log::info('Recalcuating aircraft status');
$this->aircraftSvc->recalculateStats(); $this->aircraftSvc->recalculateStats();
} }
} }

View File

@@ -19,8 +19,6 @@ class SetActiveFlights extends Listener
*/ */
public function handle(CronNightly $event): void public function handle(CronNightly $event): void
{ {
Log::info('Nightly: Setting active flights');
$this->checkFlights(); $this->checkFlights();
} }

View File

@@ -11,7 +11,7 @@ if (!function_exists('createFactoryICAO')) {
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$max = strlen($characters) - 1; $max = strlen($characters) - 1;
$string = ''; $string = '';
for ($i = 0; $i < 5; $i++) { for ($i = 0; $i < 4; $i++) {
try { try {
$string .= $characters[random_int(0, $max)]; $string .= $characters[random_int(0, $max)];
} catch (Exception $e) { } catch (Exception $e) {

View File

@@ -1,20 +1,17 @@
<?php <?php
use App\Models\Journal;
use Carbon\Carbon;
use Faker\Generator as Faker; use Faker\Generator as Faker;
use Ramsey\Uuid\Uuid;
$factory->define(App\Models\JournalTransaction::class, function (Faker $faker) { $factory->define(App\Models\JournalTransactions::class, function (Faker $faker) {
return [ return [
'transaction_group' => Uuid::uuid4()->toString(), 'transaction_group' => \Ramsey\Uuid\Uuid::uuid4()->toString(),
'journal_id' => function () { 'journal_id' => function () {
return factory(Journal::class)->create()->id; return factory(\App\Models\Journal::class)->create()->id;
}, },
'credit' => $faker->numberBetween(100, 10000), 'credit' => $faker->numberBetween(100, 10000),
'debit' => $faker->numberBetween(100, 10000), 'debit' => $faker->numberBetween(100, 10000),
'currency' => 'USD', 'currency' => 'USD',
'memo' => $faker->sentence(6), 'memo' => $faker->sentence(6),
'post_date' => Carbon::now('UTC'), 'post_date' => \Carbon\Carbon::now(),
]; ];
}); });

View File

@@ -1,13 +0,0 @@
<?php
use Faker\Generator as Faker;
$factory->define(App\Models\Role::class, function (Faker $faker) {
return [
'id' => null,
'name' => $faker->name,
'display_name' => $faker->name,
'read_only' => false,
'disable_activity_checks' => $faker->boolean(),
];
});

View File

@@ -1,18 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Change the vertical speed for the acars table to a double
*/
class ChangeAcarsVsType extends Migration
{
public function up()
{
Schema::table('acars', function (Blueprint $table) {
$table->float('vs')->change()->default(0.0)->nullable();
});
}
}

View File

@@ -1,19 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Bring the sessions table in line with the latest
*/
class UpdateSessionsTable extends Migration
{
public function up()
{
Schema::table('sessions', function (Blueprint $table) {
$table->index('user_id');
$table->index('last_activity');
});
}
}

View File

@@ -1,21 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Add a `fuel_onboard` column for recording what is left in tanks
*/
class AircraftAddFuelonboard extends Migration
{
public function up()
{
Schema::table('aircraft', function (Blueprint $table) {
$table->unsignedDecimal('fuel_onboard')
->nullable()
->default(0.0)
->after('zfw');
});
}
}

View File

@@ -1,20 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Add a SimBrief Type to subfleet
*/
class AddSbtypeToSubfleets extends Migration
{
public function up()
{
Schema::table('subfleets', function (Blueprint $table) {
$table->string('simbrief_type', 20)
->nullable()
->after('type');
});
}
}

View File

@@ -1,24 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Add a hub to the subfleet is
*/
class AddAircraftToSimbrief extends Migration
{
public function up()
{
Schema::table('simbrief', function (Blueprint $table) {
$table->unsignedInteger('aircraft_id')
->nullable()
->after('pirep_id');
// Temp column to hold the calculated fare data for the API
// Remove this once the prefile to acars feature is completed
$table->mediumText('fare_data')->nullable()->after('ofp_xml');
});
}
}

View File

@@ -1,19 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Add a hub to the subfleet is
*/
class AddKvpTable extends Migration
{
public function up()
{
Schema::create('kvp', function (Blueprint $table) {
$table->string('key')->index();
$table->string('value');
});
}
}

View File

@@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddDisableactivitychecksToRoles extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('roles', function (Blueprint $table) {
$table->boolean('disable_activity_checks')
->default(false)
->after('read_only');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('roles', function (Blueprint $table) {
$table->dropColumn('disable_activity_checks');
});
}
}

View File

@@ -1,19 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
class RemoveSettingRemoveBidOnAccept extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
DB::table('settings')
->where(['key' => 'pireps.remove_bid_on_accept'])
->delete();
}
}

View File

@@ -1,30 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Add a `anumeric_callsign` column for Alphanumeric Callsign to be assigned for a flight
* Exp DLH78BF, THY8EA, OGE1978
* According to FAA and EASA, callsigns must be maximum 7 chars in which first 3 chars is
* airline ICAO code remaining rest can be used freely according to airline's choices
*/
class FlightsAddAlphanumericCallsign extends Migration
{
public function up()
{
Schema::table('flights', function (Blueprint $table) {
$table->string('callsign', 4)
->nullable()
->after('flight_number');
});
}
public function down()
{
Schema::table('flights', function (Blueprint $table) {
$table->dropColumn('callsign');
});
}
}

View File

@@ -1,21 +0,0 @@
<?php
use App\Contracts\Migration;
use App\Services\Installer\ConfigService;
/**
* Migrate the configuration files
*/
class MigrateConfigs extends Migration
{
public function up()
{
/** @var ConfigService $configSvc */
$configSvc = app(ConfigService::class);
$configSvc->rewriteConfigFiles();
}
public function down()
{
}
}

View File

@@ -1,26 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Increase Airport ICAO size to 5 chars
* https://github.com/nabeelio/phpvms/issues/1052
*/
class IncreaseIcaoSizes extends Migration
{
public function up()
{
Schema::table('airports', function (Blueprint $table) {
$table->string('iata', 5)->change();
$table->string('icao', 5)->change();
});
Schema::table('pireps', function (Blueprint $table) {
$table->string('dpt_airport_id', 5)->change();
$table->string('arr_airport_id', 5)->change();
$table->string('alt_airport_id', 5)->change();
});
}
}

View File

@@ -1,19 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
class RemoveSettingSimbriefExpireDays extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
DB::table('settings')
->where(['key' => 'simbrief.expire_days'])
->delete();
}
}

View File

@@ -1,32 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class DiscordFields extends Migration
{
public function up()
{
// Delete the old Discord fields and then a webhook will get added
DB::table('settings')
->where(['key' => 'notifications.discord_api_key'])
->delete();
DB::table('settings')
->where(['key' => 'notifications.discord_public_channel_id'])
->delete();
DB::table('settings')
->where(['key' => 'notifications.discord_public_channel_id'])
->delete();
// Add a field to the user to enter their own Discord ID
Schema::table('users', function (Blueprint $table) {
$table->string('discord_id')
->default('')
->after('rank_id');
});
}
}

View File

@@ -1,18 +0,0 @@
<?php
use App\Contracts\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class DiscordPrivateChannelId extends Migration
{
public function up()
{
// Add a field to the user to enter their own Discord ID
Schema::table('users', function (Blueprint $table) {
$table->string('discord_private_channel_id')
->default('')
->after('discord_id');
});
}
}

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,5 +1,519 @@
acars: acars:
- pirep_id: b68R5gwVzpVe - id: aM8QpMPEB15e
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.934117958358'
lon: '-76.77856721815'
heading: '124'
altitude: '8.1663703232199'
vs: '0'
gs: '0.0064996252497234'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: eZ6VJ3xj8vge
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.934117498661'
lon: '-76.778566516289'
heading: '124'
altitude: '8.1664622222087'
vs: '0'
gs: '0'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: bo2QqDLl2lLa
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.933884143334'
lon: '-76.778210172233'
heading: '124'
altitude: '8.1707802663933'
vs: '0'
gs: '14.419195209695'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: aM8QpM4qV2Be
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.933705349611'
lon: '-76.777936938059'
heading: '124'
altitude: '8.170089899507'
vs: '0'
gs: '15.392330039049'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: dR6oxR9qjoOd
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.933130691906'
lon: '-76.777152737985'
heading: '158'
altitude: '8.1683570286331'
vs: '0'
gs: '10.450467475023'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: erkRwJODRvEa
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.932580370289'
lon: '-76.777450200122'
heading: '221'
altitude: '8.1695896791822'
vs: '0'
gs: '12.932334300694'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: b2kv53VMy7Ad
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.932012550651'
lon: '-76.778009113329'
heading: '296'
altitude: '8.1683852467213'
vs: '0'
gs: '10.502719192825'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: eXDoE14JxAve
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.932052237309'
lon: '-76.778111495187'
heading: '290'
altitude: '8.1719753739837'
vs: '0'
gs: '12.643743277153'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: b68R5gZ5YyOe
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.932664026837'
lon: '-76.779705339967'
heading: '293'
altitude: '8.2203963962548'
vs: '0'
gs: '64.870244840054'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: bqxYvGNN5N0a
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.934300220408'
lon: '-76.783954914814'
heading: '293'
altitude: '8.3302468103811'
vs: '0'
gs: '122.78529244208'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: en5rpBKw514d
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.935736496556'
lon: '-76.78765616448'
heading: '293'
altitude: '49.554739665916'
vs: '21'
gs: '146.79677958636'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: erkRwJA29l2a
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '17.976972983585'
lon: '-76.896548114872'
heading: '297'
altitude: '6228.684012199'
vs: '62'
gs: '281.03976876098'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: dR6oxR3r5nwd
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.061360208405'
lon: '-77.056156629983'
heading: '301'
altitude: '12522.331716891'
vs: '25'
gs: '371.70833265547'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: e1wr82J877Zb
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.17373613295'
lon: '-77.260347185993'
heading: '301'
altitude: '16802.15636323'
vs: '43'
gs: '421.37353688139'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: bqxYvGyExN2a
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.193907285814'
lon: '-77.29810465405'
heading: '297'
altitude: '17395.953175647'
vs: '40'
gs: '425.98105291451'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: aQW0wQDQk5Md
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.648921231143'
lon: '-78.014696613517'
heading: '323'
altitude: '37108.124381987'
vs: '22'
gs: '438.52028383384'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: e9rQ5lk3p63a
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.796585259338'
lon: '-78.194734005052'
heading: '260'
altitude: '39718.178225504'
vs: '19'
gs: '432.41969107334'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: aQW0wQP8vZqd
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.660552760063'
lon: '-78.407597067994'
heading: '242'
altitude: '40998.775690971'
vs: '-25'
gs: '449.51695639627'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: bqxYvGKgp32a
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.592775999582'
lon: '-78.638711340118'
heading: '298'
altitude: '41060.297106821'
vs: '0'
gs: '427.14806185954'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: bqxYvGg2r02a
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.718367591656'
lon: '-78.840980459275'
heading: '284'
altitude: '41065.55293844'
vs: '1'
gs: '424.89060056552'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: e0RV61wPj53b
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.77448809677'
lon: '-79.082727467209'
heading: '283'
altitude: '41069.809333539'
vs: '0'
gs: '425.02780492483'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: dwpmBOo3wWwe
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.813031600863'
lon: '-79.249543355636'
heading: '283'
altitude: '41072.545805172'
vs: '0'
gs: '425.04687332464'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: ejRqlxXoZPle
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.840653974635'
lon: '-79.370042672541'
heading: '283'
altitude: '40396.200981621'
vs: '-16'
gs: '428.08364925851'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: eVOPBYw4q9Xa
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.868358744495'
lon: '-79.491434926253'
heading: '283'
altitude: '39399.093383161'
vs: '-16'
gs: '427.57826037174'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: aOYyrOmVPzEd
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.896191929474'
lon: '-79.613169477385'
heading: '284'
altitude: '36491.730092364'
vs: '-55'
gs: '429.74732238829'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: dL98oLQgyzje
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.9242378342'
lon: '-79.736368411294'
heading: '284'
altitude: '32998.644142986'
vs: '-61'
gs: '434.90864533098'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: e9rQ5lqD2o8a
pirep_id: b68R5gwVzpVe
type: '0'
nav_type: null
order: '0'
name: null
log: null
lat: '18.952608029755'
lon: '-79.861339775352'
heading: '284'
altitude: '29069.168636089'
vs: '-68'
gs: '441.90475491564'
transponder: null
autopilot: null
fuel_flow: null
sim_time: now
created_at: 'now'
updated_at: 'now'
- id: av2oANWY1vma
pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
order: '0' order: '0'
@@ -36,7 +550,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb1 - id: e1wr82gp8zGb
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
@@ -55,7 +569,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb2 - id: dG65jDL2gK0b
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
@@ -74,7 +588,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb3 - id: epYQ0ENmyvXa
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
@@ -93,7 +607,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb34 - id: erkRwJPrVoEa
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
@@ -112,7 +626,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb35 - id: e1wr82gZXqZb
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
@@ -131,7 +645,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb36 - id: eER95AJ4XLga
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
@@ -150,7 +664,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb37 - id: dPNZvP0O0Gza
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
@@ -169,7 +683,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb38 - id: aQW0wQYVm2Yd
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null
@@ -188,7 +702,7 @@ acars:
sim_time: now sim_time: now
created_at: 'now' created_at: 'now'
updated_at: 'now' updated_at: 'now'
- id: 9aAN4mxlK9zb39 - id: eXDoE11x32We
pirep_id: b68R5gwVzpVe pirep_id: b68R5gwVzpVe
type: '0' type: '0'
nav_type: null nav_type: null

View File

@@ -34,17 +34,6 @@ airports:
lon: -97.6698889 lon: -97.6698889
hub: 1 hub: 1
ground_handling_cost: 100 ground_handling_cost: 100
- id: KPHN
iata: HPN
icao: KPHN
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: KJFK - id: KJFK
iata: JFK iata: JFK
icao: KJFK icao: KJFK
@@ -130,8 +119,8 @@ aircraft:
- -
id: 1 id: 1
subfleet_id: 1 subfleet_id: 1
icao: B744 icao: null
iata: 744 iata: null
airport_id: KJFK airport_id: KJFK
landing_time: '2020-10-23 07:50:16' landing_time: '2020-10-23 07:50:16'
name: 'Boeing 747-438' name: 'Boeing 747-438'
@@ -147,8 +136,8 @@ aircraft:
- -
id: 2 id: 2
subfleet_id: 2 subfleet_id: 2
icao: B777 icao: null
iata: 777 iata: null
airport_id: LGRP airport_id: LGRP
landing_time: null landing_time: null
name: 'Boeing 777-200' name: 'Boeing 777-200'
@@ -164,8 +153,8 @@ aircraft:
- -
id: 3 id: 3
subfleet_id: 1 subfleet_id: 1
icao: B744 icao: null
iata: 744 iata: null
airport_id: KAUS airport_id: KAUS
landing_time: '2020-10-24 08:50:13' landing_time: '2020-10-24 08:50:13'
name: 'Boeing 747-412' name: 'Boeing 747-412'
@@ -181,8 +170,8 @@ aircraft:
- -
id: 4 id: 4
subfleet_id: 1 subfleet_id: 1
icao: B744 icao: null
iata: 744 iata: null
airport_id: KAUS airport_id: KAUS
landing_time: null landing_time: null
name: 'Boeing 747-436 RETIRED' name: 'Boeing 747-436 RETIRED'
@@ -198,7 +187,7 @@ aircraft:
- -
id: 5 id: 5
subfleet_id: 4 subfleet_id: 4
icao: 'A320' icao: A320
iata: '320' iata: '320'
airport_id: EGLL airport_id: EGLL
landing_time: null landing_time: null
@@ -459,21 +448,6 @@ flights:
- id: flightid_1 - id: flightid_1
airline_id: 1 airline_id: 1
flight_number: 100 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 dpt_airport_id: KAUS
arr_airport_id: KJFK 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 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

File diff suppressed because one or more lines are too long

View File

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

View File

@@ -54,13 +54,6 @@
options: '' options: ''
type: text type: text
description: 'Enter your Google Analytics Tracking ID' description: 'Enter your Google Analytics Tracking ID'
- key: general.record_user_ip
name: 'Record user IP address'
group: general
value: true
options: ''
type: boolean
description: Record the user's IP address on register/login
- key: units.currency - key: units.currency
name: 'Currency' name: 'Currency'
group: units group: units
@@ -137,13 +130,6 @@
options: '' options: ''
type: int type: int
description: 'Initial zoom level on the map' 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 - key: airports.default_ground_handling_cost
name: 'Default Ground Handling Cost' name: 'Default Ground Handling Cost'
group: airports group: airports
@@ -158,20 +144,6 @@
options: options:
type: text type: text
description: If an airport's Jet A Fuel Cost isn't added, set this value by default description: If an airport's Jet A Fuel Cost isn't added, set this value by default
- key: airports.default_100ll_fuel_cost
name: 'Default 100LL Fuel Cost'
group: airports
value: 0.9
options:
type: text
description: If an airport's 100LL Fuel Cost isn't added, set this value by default
- key: airports.default_mogas_fuel_cost
name: 'Default MOGAS Fuel Cost'
group: airports
value: 0.8
options:
type: text
description: If an airport's MOGAS Fuel Cost isn't added, set this value by default
- key: bids.disable_flight_on_bid - key: bids.disable_flight_on_bid
name: 'Disable flight on bid' name: 'Disable flight on bid'
group: bids group: bids
@@ -208,12 +180,12 @@
type: number type: number
description: 'How much the load factor can vary per-flight' description: 'How much the load factor can vary per-flight'
- key: simbrief.api_key - key: simbrief.api_key
name: 'Simbrief API Key' name: 'SimBrief API Key'
group: simbrief group: simbrief
value: '' value: ''
options: '' options: ''
type: string type: string
description: 'Your Simbrief API key' description: 'Your SimBrief API key'
- key: simbrief.only_bids - key: simbrief.only_bids
name: 'Only allow for bids' name: 'Only allow for bids'
group: simbrief group: simbrief
@@ -221,62 +193,13 @@
options: '' options: ''
type: boolean type: boolean
description: 'Only allow briefs to be created for bidded flights' description: 'Only allow briefs to be created for bidded flights'
- key: simbrief.expire_hours - key: simbrief.expire_days
name: 'Simbrief Expire Time' name: 'SimBrief Expire Time'
group: simbrief group: simbrief
value: 6 value: 5
options: '' options: ''
type: number type: number
description: 'Hours after how long to remove unused briefs' description: 'Days after how long to remove unused briefs'
- key: simbrief.noncharter_pax_weight
name: 'Non-Charter Passenger Weight'
group: simbrief
value: 185
options: ''
type: number
description: 'Passenger weight for non-charter flights excluding baggage (lbs)'
- key: simbrief.noncharter_baggage_weight
name: 'Non-Charter Baggage Weight'
group: simbrief
value: 35
options: ''
type: number
description: 'Passenger baggage weight for non-charter flights (lbs)'
- key: simbrief.charter_pax_weight
name: 'Charter Passenger Weight'
group: simbrief
value: 168
options: ''
type: number
description: 'Passenger weight for charter flights excluding baggage (lbs)'
- key: simbrief.charter_baggage_weight
name: 'Charter Baggage Weight'
group: simbrief
value: 28
options: ''
type: number
description: 'Passenger baggage weight for charter flights (lbs)'
- key: simbrief.callsign
name: 'Use ATC Callsign'
group: simbrief
value: false
options: ''
type: boolean
description: 'Use pilot ident as Simbrief ATC Callsign'
- key: simbrief.name_private
name: 'Use Privatized Name at OFPs'
group: simbrief
value: false
options: ''
type: boolean
description: 'Use privatized user name as SimBrief OFP captain name'
- key: simbrief.block_aircraft
name: 'Restrict Aircraft'
group: simbrief
value: false
options: ''
type: boolean
description: 'When enabled, an aircraft can only be used for one active SimBrief OFP and Flight/Pirep'
- key: pireps.duplicate_check_time - key: pireps.duplicate_check_time
name: 'PIREP duplicate time check' name: 'PIREP duplicate time check'
group: pireps group: pireps
@@ -290,14 +213,7 @@
value: true value: true
options: '' options: ''
type: boolean type: boolean
description: 'Aircraft restricted to user''s rank' description: 'Aircraft that can be flown are restricted to a 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'
- key: pireps.only_aircraft_at_dpt_airport - key: pireps.only_aircraft_at_dpt_airport
name: 'Restrict Aircraft At Departure' name: 'Restrict Aircraft At Departure'
group: pireps group: pireps
@@ -305,27 +221,13 @@
options: '' options: ''
type: boolean type: boolean
description: 'Only allow aircraft that are at the departure airport' description: 'Only allow aircraft that are at the departure airport'
- key: pireps.advanced_fuel - key: pireps.remove_bid_on_accept
name: 'Advanced Fuel Calculations' name: 'Remove bid on accept'
group: pireps group: pireps
value: false value: false
options: '' options: ''
type: boolean type: boolean
description: 'Enables remaining fuel amounts to be considered for fuel expenses' description: 'When a PIREP is accepted, remove the bid, if it exists'
- key: pireps.delete_cancelled_hours
name: 'Delete cancelled PIREPs'
group: pireps
value: 12
options: ''
type: int
description: 'The time in hours to delete a cancelled PIREP'
- key: pireps.delete_rejected_hours
name: 'Delete rejected PIREPs'
group: pireps
value: 12
options: ''
type: int
description: 'The time in hours to delete a rejected PIREP'
- key: pilots.id_length - key: pilots.id_length
name: 'Pilot ID Length' name: 'Pilot ID Length'
group: pilots group: pilots
@@ -389,23 +291,17 @@
options: '' options: ''
type: boolean type: boolean
description: 'Count transfer hours in calculations, like ranks and the total hours' description: 'Count transfer hours in calculations, like ranks and the total hours'
- key: notifications.discord_public_webhook_url - key: notifications.discord_api_key
name: Discord Public Webhook URL name: Discord API token
group: notifications group: notifications
value: '' value: ''
options: '' options: ''
type: text type: text
description: The Discord Webhook URL for public notifications description: Discord API token for notifications
- key: notifications.discord_private_webhook_url - key: 'notifications.discord_public_channel_id'
name: Discord Private Webhook URL name: 'Discord Public Channel ID'
group: notifications group: 'notifications'
value: '' value: ''
options: '' options: ''
type: text type: 'text'
description: The Discord Webhook URL for private notifications description: 'Discord public channel ID for broadcasat notifications'
- key: 'cron.random_id'
name: 'Cron Randomized ID'
group: 'cron'
value: ''
type: 'hidden'
description: ''

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,16 +0,0 @@
<?php
namespace App\Events;
use App\Contracts\Event;
use App\Models\Pirep;
class PirepStateChange extends Event
{
public $pirep;
public function __construct(Pirep $pirep)
{
$this->pirep = $pirep;
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Events;
use App\Contracts\Event;
use App\Models\Pirep;
/**
* Status change like Boarding, Taxi, etc
*/
class PirepStatusChange extends Event
{
public $pirep;
public function __construct(Pirep $pirep)
{
$this->pirep = $pirep;
}
}

View File

@@ -1,38 +0,0 @@
<?php
namespace App\Exceptions;
use App\Models\Aircraft;
class AircraftNotAvailable extends AbstractHttpException
{
public const MESSAGE = 'The aircraft is not available for flight';
private $aircraft;
public function __construct(Aircraft $aircraft)
{
$this->aircraft = $aircraft;
parent::__construct(
400,
static::MESSAGE
);
}
public function getErrorType(): string
{
return 'aircraft-not-available';
}
public function getErrorDetails(): string
{
return $this->getMessage();
}
public function getErrorMetadata(): array
{
return [
'aircraft_id' => $this->aircraft->id,
];
}
}

View File

@@ -1,37 +0,0 @@
<?php
namespace App\Exceptions;
class CronInvalid extends AbstractHttpException
{
public const MESSAGE = 'Cron ID is disabled or invalid';
public function __construct()
{
parent::__construct(400, static::MESSAGE);
}
/**
* Return the RFC 7807 error type (without the URL root)
*/
public function getErrorType(): string
{
return 'cron-invalid';
}
/**
* 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 [];
}
}

View File

@@ -1,44 +0,0 @@
<?php
namespace App\Exceptions;
use App\Models\Pirep;
class PirepError extends AbstractHttpException
{
private $pirep;
private $error;
public function __construct(Pirep $pirep, string $error)
{
$this->error = $error;
$this->pirep = $pirep;
parent::__construct(400, $error);
}
/**
* Return the RFC 7807 error type (without the URL root)
*/
public function getErrorType(): string
{
return 'pirep-error';
}
/**
* 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 [
'pirep_id' => $this->pirep->id,
];
}
}

View File

@@ -1,44 +0,0 @@
<?php
namespace App\Exceptions;
/**
* Prefile Error
*
* If listening to the prefile event message, use `throw new PrefileError("message message");`
* to abort the prefile process and send the message up to ACARS
*/
class PrefileError extends AbstractHttpException
{
private $error;
public function __construct(string $error)
{
$this->error = $error;
parent::__construct(400, $error);
}
/**
* Return the RFC 7807 error type (without the URL root)
*/
public function getErrorType(): string
{
return 'prefile-error';
}
/**
* 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 [];
}
}

View File

@@ -1,38 +0,0 @@
<?php
namespace App\Exceptions;
class UserNotFound extends AbstractHttpException
{
public function __construct()
{
parent::__construct(
404,
'User not found'
);
}
/**
* Return the RFC 7807 error type (without the URL root)
*/
public function getErrorType(): string
{
return 'user-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 [];
}
}

View File

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

View File

@@ -186,13 +186,13 @@ class AwardController extends Controller
{ {
$award = $this->awardRepository->findWithoutFail($id); $award = $this->awardRepository->findWithoutFail($id);
if (empty($award)) { if (empty($award)) {
Flash::error('Award not found'); Flash::error('Fare not found');
return redirect(route('admin.awards.index')); return redirect(route('admin.awards.index'));
} }
$this->awardRepository->delete($id); $this->awardRepository->delete($id);
Flash::success('Award deleted successfully.'); Flash::success('Fare deleted successfully.');
return redirect(route('admin.awards.index')); return redirect(route('admin.awards.index'));
} }

View File

@@ -115,7 +115,7 @@ class FlightController extends Controller
$avail_fleets = $all_aircraft->except($flight->subfleets->modelKeys()); $avail_fleets = $all_aircraft->except($flight->subfleets->modelKeys());
foreach ($avail_fleets as $ac) { foreach ($avail_fleets as $ac) {
$retval[$ac->id] = '['.$ac->airline->icao.']&nbsp;'.$ac->type.' - '.$ac->name; $retval[$ac->id] = $ac->type.' - '.$ac->name;
} }
return $retval; return $retval;
@@ -152,7 +152,7 @@ class FlightController extends Controller
{ {
return view('admin.flights.create', [ return view('admin.flights.create', [
'flight' => null, 'flight' => null,
'days' => 0, 'days' => [],
'flight_fields' => $this->flightFieldRepo->all(), 'flight_fields' => $this->flightFieldRepo->all(),
'airlines' => $this->airlineRepo->selectBoxList(), 'airlines' => $this->airlineRepo->selectBoxList(),
'airports' => $this->airportRepo->selectBoxList(true, false), 'airports' => $this->airportRepo->selectBoxList(true, false),
@@ -300,18 +300,14 @@ class FlightController extends Controller
public function export(Request $request) public function export(Request $request)
{ {
$exporter = app(ExportService::class); $exporter = app(ExportService::class);
$flights = $this->flightRepo->all();
$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)->get();
$path = $exporter->exportFlights($flights); $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

@@ -6,36 +6,35 @@ use App\Contracts\Controller;
use App\Repositories\KvpRepository; use App\Repositories\KvpRepository;
use App\Services\CronService; use App\Services\CronService;
use App\Services\VersionService; use App\Services\VersionService;
use App\Support\Utils; use Codedge\Updater\UpdaterManager;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Laracasts\Flash\Flash; use Laracasts\Flash\Flash;
use Nwidart\Modules\Facades\Module;
class MaintenanceController extends Controller class MaintenanceController extends Controller
{ {
private $cronSvc; private $cronSvc;
private $kvpRepo; private $kvpRepo;
private $updateManager;
private $versionSvc; private $versionSvc;
public function __construct( public function __construct(
CronService $cronSvc, CronService $cronSvc,
KvpRepository $kvpRepo, KvpRepository $kvpRepo,
UpdaterManager $updateManager,
VersionService $versionSvc VersionService $versionSvc
) { ) {
$this->cronSvc = $cronSvc; $this->cronSvc = $cronSvc;
$this->kvpRepo = $kvpRepo; $this->kvpRepo = $kvpRepo;
$this->updateManager = $updateManager;
$this->versionSvc = $versionSvc; $this->versionSvc = $versionSvc;
} }
public function index() public function index()
{ {
// Get the cron URL
$cron_id = setting('cron.random_id');
$cron_url = empty($cron_id) ? 'Not enabled' : url(route('api.maintenance.cron', $cron_id));
return view('admin.maintenance.index', [ return view('admin.maintenance.index', [
'cron_url' => $cron_url,
'cron_path' => $this->cronSvc->getCronExecString(), 'cron_path' => $this->cronSvc->getCronExecString(),
'cron_problem_exists' => $this->cronSvc->cronProblemExists(), 'cron_problem_exists' => $this->cronSvc->cronProblemExists(),
'new_version' => $this->kvpRepo->get('new_version_available', false), 'new_version' => $this->kvpRepo->get('new_version_available', false),
@@ -102,31 +101,20 @@ class MaintenanceController extends Controller
} }
/** /**
* Enable the cron, or if it's enabled, change the ID that is used * Update the phpVMS install
* *
* @param Request $request * @param \Illuminate\Http\Request $request
*/
public function cron_enable(Request $request)
{
$id = Utils::generateNewId(24);
setting_save('cron.random_id', $id);
Flash::success('Web cron refreshed!');
return redirect(route('admin.maintenance.index'));
}
/**
* Disable the web cron
*
* @param Request $request
* *
* @return mixed * @return mixed
*/ */
public function cron_disable(Request $request) public function update(Request $request)
{ {
setting_save('cron.random_id', ''); $new_version_tag = $this->kvpRepo->get('latest_version_tag');
Log::info('Attempting to update to '.$new_version_tag);
Flash::success('Web cron disabled!'); $module = Module::find('updater');
return redirect(route('admin.maintenance.index')); $module->enable();
return redirect('/update/downloader');
} }
} }

View File

@@ -9,7 +9,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Routing\Redirector; use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View; use Illuminate\View\View;
class ModulesController extends Controller class ModulesController extends Controller
@@ -30,7 +29,6 @@ class ModulesController extends Controller
{ {
$modules = $this->moduleSvc->getAllModules(); $modules = $this->moduleSvc->getAllModules();
$new_modules = $this->moduleSvc->scan(); $new_modules = $this->moduleSvc->scan();
return view('admin.modules.index', [ return view('admin.modules.index', [
'modules' => $modules, 'modules' => $modules,
'new_modules' => $new_modules, 'new_modules' => $new_modules,
@@ -99,14 +97,7 @@ class ModulesController extends Controller
*/ */
public function enable(Request $request) public function enable(Request $request)
{ {
$moduleName = $request->input('name'); $this->moduleSvc->addModule($request->input('name'));
try {
$this->moduleSvc->addModule($moduleName);
} catch (\Exception $e) {
Log::error('Error activating module '.$moduleName);
}
return redirect(route('admin.modules.index')); 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\Enums\PirepState;
use App\Models\Pirep; use App\Models\Pirep;
use App\Models\PirepComment; use App\Models\PirepComment;
use App\Models\PirepFare;
use App\Repositories\AircraftRepository; use App\Repositories\AircraftRepository;
use App\Repositories\AirlineRepository; use App\Repositories\AirlineRepository;
use App\Repositories\AirportRepository; use App\Repositories\AirportRepository;
@@ -101,7 +100,7 @@ class PirepController extends Controller
$tmp[$ac->id] = $ac['name'].' - '.$ac['registration']; $tmp[$ac->id] = $ac['name'].' - '.$ac['registration'];
} }
$aircraft[$subfleet->type] = $tmp; $aircraft[$subfleet->name] = $tmp;
} }
return $aircraft; return $aircraft;
@@ -152,10 +151,10 @@ class PirepController extends Controller
$count = $request->input($field_name); $count = $request->input($field_name);
} }
$fares[] = new PirepFare([ $fares[] = [
'fare_id' => $fare->id, 'fare_id' => $fare->id,
'count' => $count, 'count' => $count,
]); ];
} }
$this->fareSvc->saveForPirep($pirep, $fares); $this->fareSvc->saveForPirep($pirep, $fares);
@@ -395,10 +394,10 @@ class PirepController extends Controller
return redirect(route('admin.pireps.index')); return redirect(route('admin.pireps.index'));
} }
$this->pirepSvc->delete($pirep); $this->pirepRepo->delete($id);
Flash::success('Pirep deleted successfully.'); Flash::success('Pirep deleted successfully.');
return redirect()->back(); return redirect(route('admin.pireps.index'));
} }
/** /**

View File

@@ -62,7 +62,7 @@ class SettingsController extends Controller
*/ */
public function index() public function index()
{ {
$settings = Setting::where('type', '!=', 'hidden')->orderBy('order')->get(); $settings = Setting::orderBy('order', 'asc')->get();
$settings = $settings->groupBy('group'); $settings = $settings->groupBy('group');
return view('admin.settings.index', [ return view('admin.settings.index', [

View File

@@ -17,7 +17,6 @@ use App\Repositories\AircraftRepository;
use App\Repositories\FareRepository; use App\Repositories\FareRepository;
use App\Repositories\RankRepository; use App\Repositories\RankRepository;
use App\Repositories\SubfleetRepository; use App\Repositories\SubfleetRepository;
use App\Repositories\TypeRatingRepository;
use App\Services\ExportService; use App\Services\ExportService;
use App\Services\FareService; use App\Services\FareService;
use App\Services\FleetService; use App\Services\FleetService;
@@ -37,29 +36,26 @@ class SubfleetController extends Controller
private $importSvc; private $importSvc;
private $rankRepo; private $rankRepo;
private $subfleetRepo; private $subfleetRepo;
private $typeratingRepo;
/** /**
* SubfleetController constructor. * SubfleetController constructor.
* *
* @param AircraftRepository $aircraftRepo * @param AircraftRepository $aircraftRepo
* @param FareRepository $fareRepo * @param FleetService $fleetSvc
* @param FareService $fareSvc * @param FareRepository $fareRepo
* @param FleetService $fleetSvc * @param FareService $fareSvc
* @param ImportService $importSvc * @param ImportService $importSvc
* @param RankRepository $rankRepo * @param RankRepository $rankRepo
* @param SubfleetRepository $subfleetRepo * @param SubfleetRepository $subfleetRepo
* @param TypeRatingRepository $typeratingRepo
*/ */
public function __construct( public function __construct(
AircraftRepository $aircraftRepo, AircraftRepository $aircraftRepo,
FleetService $fleetSvc,
FareRepository $fareRepo, FareRepository $fareRepo,
FareService $fareSvc, FareService $fareSvc,
FleetService $fleetSvc,
ImportService $importSvc, ImportService $importSvc,
RankRepository $rankRepo, RankRepository $rankRepo,
SubfleetRepository $subfleetRepo, SubfleetRepository $subfleetRepo
TypeRatingRepository $typeratingRepo
) { ) {
$this->aircraftRepo = $aircraftRepo; $this->aircraftRepo = $aircraftRepo;
$this->fareRepo = $fareRepo; $this->fareRepo = $fareRepo;
@@ -68,7 +64,48 @@ class SubfleetController extends Controller
$this->importSvc = $importSvc; $this->importSvc = $importSvc;
$this->rankRepo = $rankRepo; $this->rankRepo = $rankRepo;
$this->subfleetRepo = $subfleetRepo; $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;
} }
/** /**
@@ -115,8 +152,8 @@ class SubfleetController extends Controller
{ {
$input = $request->all(); $input = $request->all();
$subfleet = $this->subfleetRepo->create($input); $subfleet = $this->subfleetRepo->create($input);
Flash::success('Subfleet saved successfully.');
Flash::success('Subfleet saved successfully.');
return redirect(route('admin.subfleets.edit', [$subfleet->id])); return redirect(route('admin.subfleets.edit', [$subfleet->id]));
} }
@@ -135,12 +172,10 @@ class SubfleetController extends Controller
if (empty($subfleet)) { if (empty($subfleet)) {
Flash::error('Subfleet not found'); Flash::error('Subfleet not found');
return redirect(route('admin.subfleets.index')); return redirect(route('admin.subfleets.index'));
} }
$avail_fares = $this->getAvailFares($subfleet); $avail_fares = $this->getAvailFares($subfleet);
return view('admin.subfleets.show', [ return view('admin.subfleets.show', [
'subfleet' => $subfleet, 'subfleet' => $subfleet,
'avail_fares' => $avail_fares, 'avail_fares' => $avail_fares,
@@ -157,27 +192,24 @@ class SubfleetController extends Controller
public function edit($id) public function edit($id)
{ {
$subfleet = $this->subfleetRepo $subfleet = $this->subfleetRepo
->with(['fares', 'ranks', 'typeratings']) ->with(['fares', 'ranks'])
->findWithoutFail($id); ->findWithoutFail($id);
if (empty($subfleet)) { if (empty($subfleet)) {
Flash::error('Subfleet not found'); Flash::error('Subfleet not found');
return redirect(route('admin.subfleets.index')); return redirect(route('admin.subfleets.index'));
} }
$avail_fares = $this->getAvailFares($subfleet); $avail_fares = $this->getAvailFares($subfleet);
$avail_ranks = $this->getAvailRanks($subfleet); $avail_ranks = $this->getAvailRanks($subfleet);
$avail_ratings = $this->getAvailTypeRatings($subfleet);
return view('admin.subfleets.edit', [ return view('admin.subfleets.edit', [
'airlines' => Airline::all()->pluck('name', 'id'), 'airlines' => Airline::all()->pluck('name', 'id'),
'hubs' => Airport::where('hub', 1)->pluck('name', 'id'), 'hubs' => Airport::where('hub', 1)->pluck('name', 'id'),
'fuel_types' => FuelType::labels(), 'fuel_types' => FuelType::labels(),
'avail_fares' => $avail_fares, 'avail_fares' => $avail_fares,
'avail_ranks' => $avail_ranks, 'avail_ranks' => $avail_ranks,
'avail_ratings' => $avail_ratings, 'subfleet' => $subfleet,
'subfleet' => $subfleet,
]); ]);
} }
@@ -197,13 +229,12 @@ class SubfleetController extends Controller
if (empty($subfleet)) { if (empty($subfleet)) {
Flash::error('Subfleet not found'); Flash::error('Subfleet not found');
return redirect(route('admin.subfleets.index')); return redirect(route('admin.subfleets.index'));
} }
$this->subfleetRepo->update($request->all(), $id); $this->subfleetRepo->update($request->all(), $id);
Flash::success('Subfleet updated successfully.');
Flash::success('Subfleet updated successfully.');
return redirect(route('admin.subfleets.index')); return redirect(route('admin.subfleets.index'));
} }
@@ -220,7 +251,6 @@ class SubfleetController extends Controller
if (empty($subfleet)) { if (empty($subfleet)) {
Flash::error('Subfleet not found'); Flash::error('Subfleet not found');
return redirect(route('admin.subfleets.index')); return redirect(route('admin.subfleets.index'));
} }
@@ -229,13 +259,12 @@ class SubfleetController extends Controller
$aircraft = $this->aircraftRepo->findWhere(['subfleet_id' => $id], ['id']); $aircraft = $this->aircraftRepo->findWhere(['subfleet_id' => $id], ['id']);
if ($aircraft->count() > 0) { if ($aircraft->count() > 0) {
Flash::error('There are aircraft still assigned to this subfleet, you can\'t delete it!')->important(); Flash::error('There are aircraft still assigned to this subfleet, you can\'t delete it!')->important();
return redirect(route('admin.subfleets.index')); return redirect(route('admin.subfleets.index'));
} }
$this->subfleetRepo->delete($id); $this->subfleetRepo->delete($id);
Flash::success('Subfleet deleted successfully.');
Flash::success('Subfleet deleted successfully.');
return redirect(route('admin.subfleets.index')); return redirect(route('admin.subfleets.index'));
} }
@@ -252,8 +281,11 @@ class SubfleetController extends Controller
$subfleets = $this->subfleetRepo->all(); $subfleets = $this->subfleetRepo->all();
$path = $exporter->exportSubfleets($subfleets); $path = $exporter->exportSubfleets($subfleets);
return response()
return response()->download($path, 'subfleets.csv', ['content-type' => 'text/csv'])->deleteFileAfterSend(true); ->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 mixed
*
* @return array
*/ */
protected function getAvailFares($subfleet) protected function return_ranks_view(?Subfleet $subfleet)
{ {
$retval = []; $subfleet->refresh();
$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; $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 mixed
*
* @return array
*/ */
protected function getAvailRanks($subfleet) protected function return_fares_view(?Subfleet $subfleet)
{ {
$retval = []; $subfleet->refresh();
$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; $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 = []; $subfleet = $this->subfleetRepo->findWithoutFail($id);
$all_ratings = $this->typeratingRepo->all(); if (empty($subfleet)) {
$avail_ratings = $all_ratings->except($subfleet->typeratings->modelKeys()); return $this->return_ranks_view($subfleet);
foreach ($avail_ratings as $tr) {
$retval[$tr->id] = $tr->name.' ('.$tr->type.')';
} }
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 * Operations for associating ranks to the subfleet
* *
@@ -482,79 +479,4 @@ class SubfleetController extends Controller
return $this->return_fares_view($subfleet); 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,168 +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->all();
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.');
// Cache::forget(config('cache.keys.RANKS_PILOT_LIST.key'));
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

@@ -6,13 +6,12 @@ use App\Contracts\Controller;
use App\Http\Requests\CreateUserRequest; use App\Http\Requests\CreateUserRequest;
use App\Http\Requests\UpdateUserRequest; use App\Http\Requests\UpdateUserRequest;
use App\Models\Rank; use App\Models\Rank;
use App\Models\Role;
use App\Models\User; use App\Models\User;
use App\Models\UserAward; use App\Models\UserAward;
use App\Repositories\AirlineRepository; use App\Repositories\AirlineRepository;
use App\Repositories\AirportRepository; use App\Repositories\AirportRepository;
use App\Repositories\PirepRepository; use App\Repositories\PirepRepository;
use App\Repositories\RoleRepository;
use App\Repositories\TypeRatingRepository;
use App\Repositories\UserRepository; use App\Repositories\UserRepository;
use App\Services\UserService; use App\Services\UserService;
use App\Support\Timezonelist; use App\Support\Timezonelist;
@@ -30,36 +29,28 @@ class UserController extends Controller
private $airlineRepo; private $airlineRepo;
private $airportRepo; private $airportRepo;
private $pirepRepo; private $pirepRepo;
private $roleRepo;
private $typeratingRepo;
private $userRepo; private $userRepo;
private $userSvc; private $userSvc;
/** /**
* UserController constructor. * UserController constructor.
* *
* @param AirlineRepository $airlineRepo * @param AirlineRepository $airlineRepo
* @param AirportRepository $airportRepo * @param AirportRepository $airportRepo
* @param PirepRepository $pirepRepo * @param PirepRepository $pirepRepo
* @param RoleRepository $roleRepo * @param UserRepository $userRepo
* @param TypeRatingRepository $typeratingRepo * @param UserService $userSvc
* @param UserRepository $userRepo
* @param UserService $userSvc
*/ */
public function __construct( public function __construct(
AirlineRepository $airlineRepo, AirlineRepository $airlineRepo,
AirportRepository $airportRepo, AirportRepository $airportRepo,
PirepRepository $pirepRepo, PirepRepository $pirepRepo,
RoleRepository $roleRepo,
TypeRatingRepository $typeratingRepo,
UserRepository $userRepo, UserRepository $userRepo,
UserService $userSvc UserService $userSvc
) { ) {
$this->airlineRepo = $airlineRepo; $this->airlineRepo = $airlineRepo;
$this->airportRepo = $airportRepo; $this->airportRepo = $airportRepo;
$this->pirepRepo = $pirepRepo; $this->pirepRepo = $pirepRepo;
$this->roleRepo = $roleRepo;
$this->typeratingRepo = $typeratingRepo;
$this->userSvc = $userSvc; $this->userSvc = $userSvc;
$this->userRepo = $userRepo; $this->userRepo = $userRepo;
} }
@@ -97,7 +88,6 @@ class UserController extends Controller
->mapWithKeys(function ($item, $key) { ->mapWithKeys(function ($item, $key) {
return [strtolower($item['alpha2']) => $item['name']]; return [strtolower($item['alpha2']) => $item['name']];
}); });
$roles = $this->roleRepo->selectBoxList(false, true);
return view('admin.users.create', [ return view('admin.users.create', [
'user' => null, 'user' => null,
@@ -108,7 +98,7 @@ class UserController extends Controller
'countries' => $countries, 'countries' => $countries,
'airports' => $airports, 'airports' => $airports,
'ranks' => Rank::all()->pluck('name', 'id'), 'ranks' => Rank::all()->pluck('name', 'id'),
'roles' => $roles, 'roles' => Role::all()->pluck('name', 'id'),
]); ]);
} }
@@ -154,7 +144,7 @@ class UserController extends Controller
public function edit($id) public function edit($id)
{ {
$user = $this->userRepo $user = $this->userRepo
->with(['awards', 'fields', 'rank', 'typeratings']) ->with(['awards', 'fields', 'rank'])
->findWithoutFail($id); ->findWithoutFail($id);
if (empty($user)) { if (empty($user)) {
@@ -173,20 +163,17 @@ class UserController extends Controller
$airlines = $this->airlineRepo->selectBoxList(); $airlines = $this->airlineRepo->selectBoxList();
$airports = $this->airportRepo->selectBoxList(false); $airports = $this->airportRepo->selectBoxList(false);
$roles = $this->roleRepo->selectBoxList(false, true);
$avail_ratings = $this->getAvailTypeRatings($user);
return view('admin.users.edit', [ return view('admin.users.edit', [
'user' => $user, 'user' => $user,
'pireps' => $pireps, 'pireps' => $pireps,
'country' => new ISO3166(), 'country' => new ISO3166(),
'countries' => $countries, 'countries' => $countries,
'timezones' => Timezonelist::toArray(), 'timezones' => Timezonelist::toArray(),
'airports' => $airports, 'airports' => $airports,
'airlines' => $airlines, 'airlines' => $airlines,
'ranks' => Rank::all()->pluck('name', 'id'), 'ranks' => Rank::all()->pluck('name', 'id'),
'roles' => $roles, 'roles' => Role::all()->pluck('name', 'id'),
'avail_ratings' => $avail_ratings,
]); ]);
} }
@@ -265,13 +252,15 @@ class UserController extends Controller
public function destroy($id) public function destroy($id)
{ {
$user = $this->userRepo->findWithoutFail($id); $user = $this->userRepo->findWithoutFail($id);
if (empty($user)) { if (empty($user)) {
Flash::error('User not found'); Flash::error('User not found');
return redirect(route('admin.users.index')); return redirect(route('admin.users.index'));
} }
$this->userSvc->removeUser($user); $this->userRepo->delete($id);
Flash::success('User deleted successfully.'); Flash::success('User deleted successfully.');
return redirect(route('admin.users.index')); return redirect(route('admin.users.index'));
@@ -291,7 +280,6 @@ class UserController extends Controller
$userAward = UserAward::where(['user_id' => $id, 'award_id' => $award_id]); $userAward = UserAward::where(['user_id' => $id, 'award_id' => $award_id]);
if (empty($userAward)) { if (empty($userAward)) {
Flash::error('The user award could not be found'); Flash::error('The user award could not be found');
return redirect()->back(); return redirect()->back();
} }
@@ -320,73 +308,4 @@ class UserController extends Controller
return redirect(route('admin.users.edit', [$id])); 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); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
/*Log::debug( Log::debug(
'Posting ACARS update (user: '.Auth::user()->ident.', pirep id :'.$id.'): ', 'Posting ACARS update (user: '.Auth::user()->ident.', pirep id :'.$id.'): ',
$request->post() $request->post()
);*/ );
$count = 0; $count = 0;
$positions = $request->post('positions'); $positions = $request->post('positions');
@@ -193,9 +193,9 @@ class AcarsController extends Controller
} }
// Change the PIREP status if it's as SCHEDULED before // 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->status = PirepStatus::AIRBORNE;
}*/ }
$pirep->save(); $pirep->save();
@@ -223,7 +223,7 @@ class AcarsController extends Controller
$pirep = Pirep::find($id); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
// Log::debug('Posting ACARS log, PIREP: '.$id, $request->post()); Log::debug('Posting ACARS log, PIREP: '.$id, $request->post());
$count = 0; $count = 0;
$logs = $request->post('logs'); $logs = $request->post('logs');

View File

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

View File

@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Exceptions\AssetNotFound; use App\Exceptions\AssetNotFound;
use App\Exceptions\Unauthorized;
use App\Http\Resources\Flight as FlightResource; use App\Http\Resources\Flight as FlightResource;
use App\Http\Resources\Navdata as NavdataResource; use App\Http\Resources\Navdata as NavdataResource;
use App\Models\SimBrief; use App\Models\SimBrief;

View File

@@ -1,35 +0,0 @@
<?php
namespace App\Http\Controllers\Api;
use App\Contracts\Controller;
use App\Exceptions\CronInvalid;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
class MaintenanceController extends Controller
{
/**
* Run the cron job from the web
*
* @param Request $request
* @param string $id The ID passed in for the cron
*
* @return mixed
*/
public function cron(Request $request, string $id)
{
$cron_id = setting('cron.random_id');
if (empty($cron_id) || $id !== $cron_id) {
throw new CronInvalid();
}
$output = '';
Artisan::call('schedule:run');
$output .= trim(Artisan::output());
return response([
'content' => $output,
]);
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers\Api; namespace App\Http\Controllers\Api;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Events\PirepPrefiled;
use App\Events\PirepUpdated; use App\Events\PirepUpdated;
use App\Exceptions\AircraftPermissionDenied; use App\Exceptions\AircraftPermissionDenied;
use App\Exceptions\PirepCancelled; use App\Exceptions\PirepCancelled;
@@ -23,11 +24,10 @@ use App\Models\Enums\PirepFieldSource;
use App\Models\Enums\PirepSource; use App\Models\Enums\PirepSource;
use App\Models\Pirep; use App\Models\Pirep;
use App\Models\PirepComment; use App\Models\PirepComment;
use App\Models\PirepFare; use App\Repositories\AcarsRepository;
use App\Models\PirepFieldValue;
use App\Models\User;
use App\Repositories\JournalRepository; use App\Repositories\JournalRepository;
use App\Repositories\PirepRepository; use App\Repositories\PirepRepository;
use App\Services\FareService;
use App\Services\Finance\PirepFinanceService; use App\Services\Finance\PirepFinanceService;
use App\Services\PirepService; use App\Services\PirepService;
use App\Services\UserService; use App\Services\UserService;
@@ -38,6 +38,8 @@ use Illuminate\Support\Facades\Log;
class PirepController extends Controller class PirepController extends Controller
{ {
private $acarsRepo;
private $fareSvc;
private $financeSvc; private $financeSvc;
private $journalRepo; private $journalRepo;
private $pirepRepo; private $pirepRepo;
@@ -45,6 +47,8 @@ class PirepController extends Controller
private $userSvc; private $userSvc;
/** /**
* @param AcarsRepository $acarsRepo
* @param FareService $fareSvc
* @param PirepFinanceService $financeSvc * @param PirepFinanceService $financeSvc
* @param JournalRepository $journalRepo * @param JournalRepository $journalRepo
* @param PirepRepository $pirepRepo * @param PirepRepository $pirepRepo
@@ -52,12 +56,16 @@ class PirepController extends Controller
* @param UserService $userSvc * @param UserService $userSvc
*/ */
public function __construct( public function __construct(
AcarsRepository $acarsRepo,
FareService $fareSvc,
PirepFinanceService $financeSvc, PirepFinanceService $financeSvc,
JournalRepository $journalRepo, JournalRepository $journalRepo,
PirepRepository $pirepRepo, PirepRepository $pirepRepo,
PirepService $pirepSvc, PirepService $pirepSvc,
UserService $userSvc UserService $userSvc
) { ) {
$this->acarsRepo = $acarsRepo;
$this->fareSvc = $fareSvc;
$this->financeSvc = $financeSvc; $this->financeSvc = $financeSvc;
$this->journalRepo = $journalRepo; $this->journalRepo = $journalRepo;
$this->pirepRepo = $pirepRepo; $this->pirepRepo = $pirepRepo;
@@ -94,7 +102,7 @@ class PirepController extends Controller
/** /**
* Check if a PIREP is cancelled * Check if a PIREP is cancelled
* *
* @param Pirep $pirep * @param $pirep
* *
* @throws \App\Exceptions\PirepCancelled * @throws \App\Exceptions\PirepCancelled
*/ */
@@ -106,52 +114,50 @@ class PirepController extends Controller
} }
/** /**
* @param $pirep
* @param Request $request * @param Request $request
*
* @return PirepFieldValue[]
*/ */
protected function getFields(Request $request): ?array protected function updateFields($pirep, Request $request)
{ {
if (!$request->filled('fields')) { if (!$request->filled('fields')) {
return []; return;
} }
$pirep_fields = []; $pirep_fields = [];
foreach ($request->input('fields') as $field_name => $field_value) { foreach ($request->input('fields') as $field_name => $field_value) {
$pirep_fields[] = new PirepFieldValue([ $pirep_fields[] = [
'name' => $field_name, 'name' => $field_name,
'value' => $field_value, 'value' => $field_value,
'source' => PirepFieldSource::ACARS, 'source' => PirepFieldSource::ACARS,
]); ];
} }
return $pirep_fields; $this->pirepSvc->updateCustomFields($pirep->id, $pirep_fields);
} }
/** /**
* Save the fares * Save the fares
* *
* @param $pirep
* @param Request $request * @param Request $request
* *
* @throws \Exception * @throws \Exception
*
* @return PirepFare[]
*/ */
protected function getFares(Request $request): ?array protected function updateFares($pirep, Request $request)
{ {
if (!$request->filled('fares')) { if (!$request->filled('fares')) {
return []; return;
} }
$fares = []; $fares = [];
foreach ($request->post('fares') as $fare) { foreach ($request->post('fares') as $fare) {
$fares[] = new PirepFare([ $fares[] = [
'fare_id' => $fare['id'], 'fare_id' => $fare['id'],
'count' => $fare['count'], 'count' => $fare['count'],
]); ];
} }
return $fares; $this->fareSvc->saveForPirep($pirep, $fares);
} }
/** /**
@@ -168,7 +174,6 @@ class PirepController extends Controller
'comments', 'comments',
'flight', 'flight',
'simbrief', 'simbrief',
'position',
'user', 'user',
]; ];
@@ -206,13 +211,16 @@ class PirepController extends Controller
$attrs = $this->parsePirep($request); $attrs = $this->parsePirep($request);
$attrs['source'] = PirepSource::ACARS; $attrs['source'] = PirepSource::ACARS;
$fields = $this->getFields($request); $pirep = $this->pirepSvc->prefile($user, $attrs);
$fares = $this->getFares($request);
$pirep = $this->pirepSvc->prefile($user, $attrs, $fields, $fares);
Log::info('PIREP PREFILED'); Log::info('PIREP PREFILED');
Log::info($pirep->id); Log::info($pirep->id);
$this->updateFields($pirep, $request);
$this->updateFares($pirep, $request);
event(new PirepPrefiled($pirep));
return $this->get($pirep->id); return $this->get($pirep->id);
} }
@@ -236,12 +244,8 @@ class PirepController extends Controller
Log::info('PIREP Update, user '.Auth::id()); Log::info('PIREP Update, user '.Auth::id());
Log::info($request->getContent()); Log::info($request->getContent());
/** @var User $user */
$user = Auth::user(); $user = Auth::user();
/** @var Pirep $pirep */
$pirep = Pirep::find($pirep_id); $pirep = Pirep::find($pirep_id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
$attrs = $this->parsePirep($request); $attrs = $this->parsePirep($request);
@@ -257,9 +261,9 @@ class PirepController extends Controller
} }
} }
$fields = $this->getFields($request); $pirep = $this->pirepRepo->update($attrs, $pirep_id);
$fares = $this->getFares($request); $this->updateFields($pirep, $request);
$pirep = $this->pirepSvc->update($pirep_id, $attrs, $fields, $fares); $this->updateFares($pirep, $request);
event(new PirepUpdated($pirep)); event(new PirepUpdated($pirep));
@@ -283,7 +287,6 @@ class PirepController extends Controller
{ {
Log::info('PIREP file, user '.Auth::id(), $request->post()); Log::info('PIREP file, user '.Auth::id(), $request->post());
/** @var User $user */
$user = Auth::user(); $user = Auth::user();
// Check if the status is cancelled... // Check if the status is cancelled...
@@ -303,13 +306,11 @@ class PirepController extends Controller
} }
try { try {
$fields = $this->getFields($request); $pirep = $this->pirepSvc->file($pirep, $attrs);
$fares = $this->getFares($request); $this->updateFields($pirep, $request);
$pirep = $this->pirepSvc->file($pirep, $attrs, $fields, $fares); $this->updateFares($pirep, $request);
} catch (\Exception $e) { } catch (\Exception $e) {
Log::error($e); Log::error($e);
throw $e;
} }
// See if there there is any route data posted // See if there there is any route data posted
@@ -338,7 +339,7 @@ class PirepController extends Controller
*/ */
public function cancel($pirep_id, Request $request) 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); $pirep = Pirep::find($pirep_id);
$this->pirepSvc->cancel($pirep); $this->pirepSvc->cancel($pirep);
@@ -411,8 +412,7 @@ class PirepController extends Controller
$pirep = Pirep::find($pirep_id); $pirep = Pirep::find($pirep_id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
$fields = $this->getFields($request); $this->updateFields($pirep, $request);
$this->pirepSvc->updateCustomFields($pirep_id, $fields);
return new PirepFieldCollection($pirep->fields); return new PirepFieldCollection($pirep->fields);
} }

View File

@@ -3,8 +3,6 @@
namespace App\Http\Controllers\Api; namespace App\Http\Controllers\Api;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Exceptions\Unauthorized;
use App\Exceptions\UserNotFound;
use App\Http\Resources\Bid as BidResource; use App\Http\Resources\Bid as BidResource;
use App\Http\Resources\Pirep as PirepResource; use App\Http\Resources\Pirep as PirepResource;
use App\Http\Resources\Subfleet as SubfleetResource; use App\Http\Resources\Subfleet as SubfleetResource;
@@ -93,10 +91,6 @@ class UserController extends Controller
public function get($id) public function get($id)
{ {
$user = $this->userSvc->getUser($id); $user = $this->userSvc->getUser($id);
if ($user === null) {
throw new UserNotFound();
}
return new UserResource($user); return new UserResource($user);
} }
@@ -112,11 +106,7 @@ class UserController extends Controller
*/ */
public function bids(Request $request) public function bids(Request $request)
{ {
$user_id = $this->getUserId($request); $user = $this->userSvc->getUser($this->getUserId($request));
$user = $this->userSvc->getUser($user_id);
if ($user === null) {
throw new UserNotFound();
}
// Add a bid // Add a bid
if ($request->isMethod('PUT') || $request->isMethod('POST')) { if ($request->isMethod('PUT') || $request->isMethod('POST')) {
@@ -145,28 +135,6 @@ class UserController extends Controller
return BidResource::collection($bids); 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->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 * Return the fleet that this user is allowed to
* *
@@ -177,10 +145,6 @@ class UserController extends Controller
public function fleet(Request $request) public function fleet(Request $request)
{ {
$user = $this->userRepo->find($this->getUserId($request)); $user = $this->userRepo->find($this->getUserId($request));
if ($user === null) {
throw new UserNotFound();
}
$subfleets = $this->userSvc->getAllowableSubfleets($user); $subfleets = $this->userSvc->getAllowableSubfleets($user);
return SubfleetResource::collection($subfleets); return SubfleetResource::collection($subfleets);

View File

@@ -5,7 +5,6 @@ namespace App\Http\Controllers\Auth;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Exceptions\PilotIdNotFound; use App\Exceptions\PilotIdNotFound;
use App\Models\Enums\UserState; use App\Models\Enums\UserState;
use App\Models\User;
use App\Services\UserService; use App\Services\UserService;
use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -105,16 +104,14 @@ class LoginController extends Controller
*/ */
protected function sendLoginResponse(Request $request) protected function sendLoginResponse(Request $request)
{ {
/** @var User $user */
$user = Auth::user(); $user = Auth::user();
if (setting('general.record_user_ip', true)) { $user->last_ip = $request->ip();
$user->last_ip = $request->ip(); $user->save();
$user->save();
}
if ($user->state !== UserState::ACTIVE && $user->state !== UserState::ON_LEAVE) { if ($user->state !== UserState::ACTIVE && $user->state !== UserState::ON_LEAVE) {
Log::info('Trying to login '.$user->ident.', state '.UserState::label($user->state)); Log::info('Trying to login '.$user->ident.', state '
.UserState::label($user->state));
// Log them out // Log them out
$this->guard()->logout(); $this->guard()->logout();

View File

@@ -62,7 +62,7 @@ class RegisterController extends Controller
{ {
$airports = $this->airportRepo->selectBoxList(false, setting('pilots.home_hubs_only')); $airports = $this->airportRepo->selectBoxList(false, setting('pilots.home_hubs_only'));
$airlines = $this->airlineRepo->selectBoxList(); $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', [ return view('auth.register', [
'airports' => $airports, 'airports' => $airports,
@@ -119,16 +119,11 @@ class RegisterController extends Controller
* *
* @return User * @return User
*/ */
protected function create(Request $request): User protected function create(array $opts)
{ {
// Default options // Default options
$opts = $request->all();
$opts['password'] = Hash::make($opts['password']); $opts['password'] = Hash::make($opts['password']);
if (setting('general.record_user_ip', true)) {
$opts['last_ip'] = $request->ip();
}
// Convert transfer hours into minutes // Convert transfer hours into minutes
if (isset($opts['transfer_time'])) { if (isset($opts['transfer_time'])) {
$opts['transfer_time'] *= 60; $opts['transfer_time'] *= 60;
@@ -138,7 +133,7 @@ class RegisterController extends Controller
Log::info('User registered: ', $user->toArray()); Log::info('User registered: ', $user->toArray());
$userFields = UserField::where(['show_on_registration' => true, 'active' => true])->get(); $userFields = UserField::all();
foreach ($userFields as $field) { foreach ($userFields as $field) {
$field_name = 'field_'.$field->slug; $field_name = 'field_'.$field->slug;
UserFieldValue::updateOrCreate([ UserFieldValue::updateOrCreate([
@@ -163,7 +158,7 @@ class RegisterController extends Controller
{ {
$this->validator($request->all())->validate(); $this->validator($request->all())->validate();
$user = $this->create($request); $user = $this->create($request->all());
if ($user->state === UserState::PENDING) { if ($user->state === UserState::PENDING) {
return view('auth.pending'); return view('auth.pending');
} }

View File

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

View File

@@ -29,14 +29,10 @@ class DashboardController extends Controller
public function index() public function index()
{ {
$last_pirep = null; $last_pirep = null;
$with_pirep = ['aircraft', 'arr_airport', 'comments', 'dpt_airport'];
/** @var \App\Models\User $user */
$user = Auth::user(); $user = Auth::user();
$user->loadMissing('journal');
try { 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) { } catch (\Exception $e) {
} }

View File

@@ -3,7 +3,6 @@
namespace App\Http\Controllers\Frontend; namespace App\Http\Controllers\Frontend;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Models\Airline;
use App\Models\File; use App\Models\File;
use Auth; use Auth;
use Flash; use Flash;
@@ -19,7 +18,6 @@ class DownloadController extends Controller
*/ */
public function index() public function index()
{ {
$airlines = Airline::where('active', 1)->count();
$files = File::orderBy('ref_model', 'asc')->get(); $files = File::orderBy('ref_model', 'asc')->get();
/** /**
@@ -41,28 +39,19 @@ class DownloadController extends Controller
$klass = new $class(); $klass = new $class();
$obj = $klass->find($id); $obj = $klass->find($id);
// Check if the object is there first $category = explode('\\', $class);
if (isset($obj)) { $category = end($category);
$category = explode('\\', $class);
$category = end($category);
if ($category == 'Aircraft' && $airlines > 1) { if ($category == 'Aircraft') {
$group_name = $category.' > '.$obj->subfleet->airline->name.' '.$obj->icao.' '.$obj->registration; $group_name = $category.' > '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Aircraft') { } elseif ($category == 'Airport') {
$group_name = $category.' > '.$obj->icao.' '.$obj->registration; $group_name = $category.' > '.$obj->icao.' : '.$obj->name.' ('.$obj->country.')';
} elseif ($category == 'Airport') { } else {
$group_name = $category.' > '.$obj->icao.' : '.$obj->name.' ('.$obj->country.')'; $group_name = $category.' > '.$obj->name;
} 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); $regrouped_files[$group_name] = $files;
}
return view('downloads.index', [ return view('downloads.index', [
'grouped_files' => $regrouped_files, 'grouped_files' => $regrouped_files,
@@ -70,7 +59,7 @@ class DownloadController extends Controller
} }
/** /**
* Show the application dashboard * Show the application dashboard.
* *
* @param string $id * @param string $id
* *

View File

@@ -5,7 +5,6 @@ namespace App\Http\Controllers\Frontend;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Models\Bid; use App\Models\Bid;
use App\Models\Enums\FlightType; use App\Models\Enums\FlightType;
use App\Models\Flight;
use App\Repositories\AirlineRepository; use App\Repositories\AirlineRepository;
use App\Repositories\AirportRepository; use App\Repositories\AirportRepository;
use App\Repositories\Criteria\WhereCriteria; use App\Repositories\Criteria\WhereCriteria;
@@ -13,7 +12,6 @@ use App\Repositories\FlightRepository;
use App\Repositories\SubfleetRepository; use App\Repositories\SubfleetRepository;
use App\Repositories\UserRepository; use App\Repositories\UserRepository;
use App\Services\GeoService; use App\Services\GeoService;
use App\Services\ModuleService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@@ -26,7 +24,6 @@ class FlightController extends Controller
private $airlineRepo; private $airlineRepo;
private $airportRepo; private $airportRepo;
private $flightRepo; private $flightRepo;
private $moduleSvc;
private $subfleetRepo; private $subfleetRepo;
private $geoSvc; private $geoSvc;
private $userRepo; private $userRepo;
@@ -36,7 +33,6 @@ class FlightController extends Controller
* @param AirportRepository $airportRepo * @param AirportRepository $airportRepo
* @param FlightRepository $flightRepo * @param FlightRepository $flightRepo
* @param GeoService $geoSvc * @param GeoService $geoSvc
* @param ModuleService $moduleSvc
* @param SubfleetRepository $subfleetRepo * @param SubfleetRepository $subfleetRepo
* @param UserRepository $userRepo * @param UserRepository $userRepo
*/ */
@@ -45,7 +41,6 @@ class FlightController extends Controller
AirportRepository $airportRepo, AirportRepository $airportRepo,
FlightRepository $flightRepo, FlightRepository $flightRepo,
GeoService $geoSvc, GeoService $geoSvc,
ModuleService $moduleSvc,
SubfleetRepository $subfleetRepo, SubfleetRepository $subfleetRepo,
UserRepository $userRepo UserRepository $userRepo
) { ) {
@@ -53,7 +48,6 @@ class FlightController extends Controller
$this->airportRepo = $airportRepo; $this->airportRepo = $airportRepo;
$this->flightRepo = $flightRepo; $this->flightRepo = $flightRepo;
$this->geoSvc = $geoSvc; $this->geoSvc = $geoSvc;
$this->moduleSvc = $moduleSvc;
$this->subfleetRepo = $subfleetRepo; $this->subfleetRepo = $subfleetRepo;
$this->userRepo = $userRepo; $this->userRepo = $userRepo;
} }
@@ -88,7 +82,6 @@ class FlightController extends Controller
/** @var \App\Models\User $user */ /** @var \App\Models\User $user */
$user = Auth::user(); $user = Auth::user();
$user->loadMissing('current_airport');
if (setting('pilots.restrict_to_company')) { if (setting('pilots.restrict_to_company')) {
$where['airline_id'] = $user->airline_id; $where['airline_id'] = $user->airline_id;
@@ -112,61 +105,29 @@ class FlightController extends Controller
Log::emergency($e); Log::emergency($e);
} }
// 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();
// Build collection with type codes and labels
$flight_types = collect('', '');
foreach ($usedtypes as $ftype) {
$flight_types->put($ftype->flight_type, FlightType::label($ftype->flight_type));
}
$flights = $this->flightRepo->searchCriteria($request) $flights = $this->flightRepo->searchCriteria($request)
->with([ ->with(['dpt_airport', 'arr_airport', 'airline'])
'airline', ->orderBy('flight_number', 'asc')
'alt_airport', ->orderBy('route_leg', 'asc')
'arr_airport',
'dpt_airport',
'subfleets.airline',
'simbrief' => function ($query) use ($user) {
$query->where('user_id', $user->id);
}, ])
->orderBy('flight_number')
->orderBy('route_leg')
->paginate(); ->paginate();
$saved_flights = []; $saved_flights = Bid::where('user_id', Auth::id())
$bids = Bid::where('user_id', Auth::id())->get(); ->pluck('flight_id')->toArray();
foreach ($bids as $bid) {
if (!$bid->flight) {
$bid->delete();
continue;
}
$saved_flights[$bid->flight_id] = $bid->id;
}
return view('flights.index', [ return view('flights.index', [
'user' => $user,
'airlines' => $this->airlineRepo->selectBoxList(true), 'airlines' => $this->airlineRepo->selectBoxList(true),
'airports' => $this->airportRepo->selectBoxList(true), 'airports' => $this->airportRepo->selectBoxList(true),
'flights' => $flights, 'flights' => $flights,
'saved' => $saved_flights, 'saved' => $saved_flights,
'subfleets' => $this->subfleetRepo->selectBoxList(true), 'subfleets' => $this->subfleetRepo->selectBoxList(true),
'flight_number' => $request->input('flight_number'), 'flight_number' => $request->input('flight_number'),
'flight_types' => $flight_types, 'flight_types' => FlightType::select(true),
'flight_type' => $request->input('flight_type'), 'flight_type' => $request->input('flight_type'),
'arr_icao' => $request->input('arr_icao'), 'arr_icao' => $request->input('arr_icao'),
'dep_icao' => $request->input('dep_icao'), 'dep_icao' => $request->input('dep_icao'),
'subfleet_id' => $request->input('subfleet_id'), 'subfleet_id' => $request->input('subfleet_id'),
'simbrief' => !empty(setting('simbrief.api_key')), 'simbrief' => !empty(setting('simbrief.api_key')),
'simbrief_bids' => setting('simbrief.only_bids'), 'simbrief_bids' => setting('simbrief.only_bids'),
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]); ]);
} }
@@ -186,18 +147,11 @@ class FlightController extends Controller
$flights = collect(); $flights = collect();
$saved_flights = []; $saved_flights = [];
foreach ($user->bids as $bid) { foreach ($user->bids as $bid) {
// Remove any invalid bids (flight doesn't exist or something)
if (!$bid->flight) {
$bid->delete();
continue;
}
$flights->add($bid->flight); $flights->add($bid->flight);
$saved_flights[$bid->flight_id] = $bid->id; $saved_flights[] = $bid->flight->id;
} }
return view('flights.bids', [ return view('flights.bids', [
'user' => $user,
'airlines' => $this->airlineRepo->selectBoxList(true), 'airlines' => $this->airlineRepo->selectBoxList(true),
'airports' => $this->airportRepo->selectBoxList(true), 'airports' => $this->airportRepo->selectBoxList(true),
'flights' => $flights, 'flights' => $flights,
@@ -205,7 +159,6 @@ class FlightController extends Controller
'subfleets' => $this->subfleetRepo->selectBoxList(true), 'subfleets' => $this->subfleetRepo->selectBoxList(true),
'simbrief' => !empty(setting('simbrief.api_key')), 'simbrief' => !empty(setting('simbrief.api_key')),
'simbrief_bids' => setting('simbrief.only_bids'), 'simbrief_bids' => setting('simbrief.only_bids'),
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]); ]);
} }
@@ -218,19 +171,7 @@ class FlightController extends Controller
*/ */
public function show($id) public function show($id)
{ {
$user_id = Auth::id(); $flight = $this->flightRepo->find($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);
if (empty($flight)) { if (empty($flight)) {
Flash::error('Flight not found!'); Flash::error('Flight not found!');
return redirect(route('frontend.dashboard.index')); return redirect(route('frontend.dashboard.index'));
@@ -238,14 +179,9 @@ class FlightController extends Controller
$map_features = $this->geoSvc->flightGeoJson($flight); $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', [ return view('flights.show', [
'flight' => $flight, 'flight' => $flight,
'map_features' => $map_features, 'map_features' => $map_features,
'bid' => $bid,
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]); ]);
} }
} }

View File

@@ -3,7 +3,6 @@
namespace App\Http\Controllers\Frontend; namespace App\Http\Controllers\Frontend;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Models\Enums\UserState;
use App\Models\User; use App\Models\User;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@@ -16,7 +15,7 @@ class HomeController extends Controller
public function index() public function index()
{ {
try { try {
$users = User::with('home_airport')->where('state', '!=', UserState::DELETED)->orderBy('created_at', 'desc')->take(4)->get(); $users = User::orderBy('created_at', 'desc')->take(4)->get();
} catch (\PDOException $e) { } catch (\PDOException $e) {
Log::emergency($e); Log::emergency($e);
return view('system/errors/database_error', [ return view('system/errors/database_error', [

View File

@@ -7,9 +7,8 @@ use App\Http\Requests\CreatePirepRequest;
use App\Http\Requests\UpdatePirepRequest; use App\Http\Requests\UpdatePirepRequest;
use App\Models\Enums\PirepSource; use App\Models\Enums\PirepSource;
use App\Models\Enums\PirepState; use App\Models\Enums\PirepState;
use App\Models\Fare; use App\Models\Enums\PirepStatus;
use App\Models\Pirep; use App\Models\Pirep;
use App\Models\PirepFare;
use App\Models\SimBrief; use App\Models\SimBrief;
use App\Models\User; use App\Models\User;
use App\Repositories\AircraftRepository; use App\Repositories\AircraftRepository;
@@ -91,12 +90,8 @@ class PirepController extends Controller
*/ */
public function aircraftList($add_blank = false) 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 = []; $aircraft = [];
$subfleets = $this->userSvc->getAllowableSubfleets($user); $subfleets = $this->userSvc->getAllowableSubfleets(Auth::user());
if ($add_blank) { if ($add_blank) {
$aircraft[''] = ''; $aircraft[''] = '';
@@ -104,13 +99,11 @@ class PirepController extends Controller
foreach ($subfleets as $subfleet) { foreach ($subfleets as $subfleet) {
$tmp = []; $tmp = [];
foreach ($subfleet->aircraft->when($location_check, function ($query) use ($user_loc) { foreach ($subfleet->aircraft as $ac) {
return $query->where('airport_id', $user_loc);
}) as $ac) {
$tmp[$ac->id] = $ac['name'].' - '.$ac['registration']; $tmp[$ac->id] = $ac['name'].' - '.$ac['registration'];
} }
$aircraft[$subfleet->type] = $tmp; $aircraft[$subfleet->name] = $tmp;
} }
return $aircraft; return $aircraft;
@@ -119,18 +112,19 @@ class PirepController extends Controller
/** /**
* Save any custom fields found * Save any custom fields found
* *
* @param Pirep $pirep
* @param Request $request * @param Request $request
*/ */
protected function saveCustomFields(Request $request): array protected function saveCustomFields(Pirep $pirep, Request $request)
{ {
$fields = []; $custom_fields = [];
$pirep_fields = $this->pirepFieldRepo->all(); $pirep_fields = $this->pirepFieldRepo->all();
foreach ($pirep_fields as $field) { foreach ($pirep_fields as $field) {
if (!$request->filled($field->slug)) { if (!$request->filled($field->slug)) {
continue; continue;
} }
$fields[] = [ $custom_fields[] = [
'name' => $field->name, 'name' => $field->name,
'slug' => $field->slug, 'slug' => $field->slug,
'value' => $request->input($field->slug), 'value' => $request->input($field->slug),
@@ -138,9 +132,8 @@ class PirepController extends Controller
]; ];
} }
Log::info('PIREP Custom Fields', $fields); Log::info('PIREP Custom Fields', $custom_fields);
$this->pirepSvc->updateCustomFields($pirep->id, $custom_fields);
return $fields;
} }
/** /**
@@ -166,10 +159,10 @@ class PirepController extends Controller
$count = $request->input($field_name); $count = $request->input($field_name);
} }
$fares[] = new PirepFare([ $fares[] = [
'fare_id' => $fare->id, 'fare_id' => $fare->id,
'count' => $count, 'count' => $count,
]); ];
} }
$this->fareSvc->saveForPirep($pirep, $fares); $this->fareSvc->saveForPirep($pirep, $fares);
@@ -188,7 +181,7 @@ class PirepController extends Controller
$where = [['user_id', $user->id]]; $where = [['user_id', $user->id]];
$where[] = ['state', '<>', PirepState::CANCELLED]; $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) $this->pirepRepo->with($with)
->pushCriteria(new WhereCriteria($request, $where)); ->pushCriteria(new WhereCriteria($request, $where));
@@ -207,20 +200,7 @@ class PirepController extends Controller
*/ */
public function show($id) public function show($id)
{ {
$with = [ $pirep = $this->pirepRepo->with(['simbrief'])->find($id);
'acars_logs',
'aircraft.airline',
'airline.journal',
'arr_airport',
'comments',
'dpt_airport',
'fares.fare',
'transactions',
'simbrief',
'user.rank',
];
$pirep = $this->pirepRepo->with($with)->find($id);
if (empty($pirep)) { if (empty($pirep)) {
Flash::error('Pirep not found'); Flash::error('Pirep not found');
return redirect(route('frontend.pirep.index')); return redirect(route('frontend.pirep.index'));
@@ -231,7 +211,6 @@ class PirepController extends Controller
return view('pireps.show', [ return view('pireps.show', [
'pirep' => $pirep, 'pirep' => $pirep,
'map_features' => $map_features, 'map_features' => $map_features,
'user' => Auth::user(),
]); ]);
} }
@@ -274,48 +253,23 @@ class PirepController extends Controller
/** /**
* They have a SimBrief ID, load that up and figure out the flight that it's from * They have a SimBrief ID, load that up and figure out the flight that it's from
*/ */
$fare_values = [];
$simbrief = null;
$simbrief_id = null; $simbrief_id = null;
$aircraft = null;
if ($request->has('sb_id')) { if ($request->has('sb_id')) {
$simbrief_id = $request->input('sb_id'); $simbrief_id = $request->input('sb_id');
$simbrief = SimBrief::find($simbrief_id); $brief = SimBrief::find($simbrief_id);
$pirep = Pirep::fromSimBrief($simbrief); $pirep = Pirep::fromSimBrief($brief);
$aircraft = $simbrief->aircraft;
$aircraft_list[$aircraft->subfleet->name] = [];
$aircraft_list[$aircraft->subfleet->name][$aircraft->id] = $aircraft->name.' - '.$aircraft->registration;
// Convert the fare data into the expected output format
if (!empty($simbrief->fare_data)) {
$fare_values = json_decode($simbrief->fare_data, true);
$fares = [];
$fare_data = json_decode($simbrief->fare_data, true);
foreach ($fare_data as $fare) {
$fares[] = new Fare($fare);
}
$aircraft->subfleet->fares = collect($fares);
}
// TODO: Set more fields from the Simbrief to the PIREP form
} else {
$aircraft_list = $this->aircraftList(true);
} }
return view('pireps.create', [ return view('pireps.create', [
'aircraft' => $aircraft, 'aircraft' => null,
'pirep' => $pirep, 'pirep' => $pirep,
'read_only' => false, 'read_only' => false,
'airline_list' => $this->airlineRepo->selectBoxList(true), 'airline_list' => $this->airlineRepo->selectBoxList(true),
'aircraft_list' => $aircraft_list, 'aircraft_list' => $this->aircraftList(true),
'airport_list' => $this->airportRepo->selectBoxList(true), 'airport_list' => $this->airportRepo->selectBoxList(true),
'pirep_fields' => $this->pirepFieldRepo->all(), 'pirep_fields' => $this->pirepFieldRepo->all(),
'field_values' => [], 'field_values' => [],
'fare_values' => $fare_values,
'simbrief_id' => $simbrief_id, 'simbrief_id' => $simbrief_id,
'simbrief' => $simbrief,
]); ]);
} }
@@ -409,8 +363,8 @@ class PirepController extends Controller
$attrs['submitted_at'] = Carbon::now('UTC'); $attrs['submitted_at'] = Carbon::now('UTC');
$pirep->submitted_at = Carbon::now('UTC'); $pirep->submitted_at = Carbon::now('UTC');
$fields = $this->saveCustomFields($request); $pirep = $this->pirepSvc->create($pirep);
$pirep = $this->pirepSvc->create($pirep, $fields); $this->saveCustomFields($pirep, $request);
$this->saveFares($pirep, $request); $this->saveFares($pirep, $request);
$this->pirepSvc->saveRoute($pirep); $this->pirepSvc->saveRoute($pirep);
@@ -419,13 +373,7 @@ class PirepController extends Controller
if ($brief !== null) { if ($brief !== null) {
/** @var SimBriefService $sbSvc */ /** @var SimBriefService $sbSvc */
$sbSvc = app(SimBriefService::class); $sbSvc = app(SimBriefService::class);
// Keep the flight_id with SimBrief depending on the button selected $sbSvc->attachSimbriefToPirep($pirep, $brief);
// Save = Keep the flight_id , Submit = Remove the flight_id
if ($attrs['submit'] === 'save') {
$sbSvc->attachSimbriefToPirep($pirep, $brief, true);
} elseif ($attrs['submit'] === 'submit') {
$sbSvc->attachSimbriefToPirep($pirep, $brief);
}
} }
} }
@@ -455,18 +403,12 @@ class PirepController extends Controller
*/ */
public function edit($id) public function edit($id)
{ {
/** @var Pirep $pirep */
$pirep = $this->pirepRepo->findWithoutFail($id); $pirep = $this->pirepRepo->findWithoutFail($id);
if (empty($pirep)) { if (empty($pirep)) {
Flash::error('Pirep not found'); Flash::error('Pirep not found');
return redirect(route('frontend.pireps.index')); return redirect(route('frontend.pireps.index'));
} }
if ($pirep->user_id !== Auth::id()) {
Flash::error('Cannot edit someone else\'s PIREP!');
return redirect(route('admin.pireps.index'));
}
// Eager load the subfleet and fares under it // Eager load the subfleet and fares under it
if ($pirep->aircraft) { if ($pirep->aircraft) {
$pirep->aircraft->load('subfleet.fares'); $pirep->aircraft->load('subfleet.fares');
@@ -519,21 +461,12 @@ class PirepController extends Controller
*/ */
public function update($id, UpdatePirepRequest $request) public function update($id, UpdatePirepRequest $request)
{ {
/** @var User $user */
$user = Auth::user();
/** @var Pirep $pirep */
$pirep = $this->pirepRepo->findWithoutFail($id); $pirep = $this->pirepRepo->findWithoutFail($id);
if (empty($pirep)) { if (empty($pirep)) {
Flash::error('Pirep not found'); Flash::error('Pirep not found');
return redirect(route('admin.pireps.index')); return redirect(route('admin.pireps.index'));
} }
if ($user->id !== $pirep->user_id) {
Flash::error('Cannot edit someone else\'s PIREP!');
return redirect(route('admin.pireps.index'));
}
$orig_route = $pirep->route; $orig_route = $pirep->route;
$attrs = $request->all(); $attrs = $request->all();
$attrs['submit'] = strtolower($attrs['submit']); $attrs['submit'] = strtolower($attrs['submit']);
@@ -551,8 +484,7 @@ class PirepController extends Controller
$this->pirepSvc->saveRoute($pirep); $this->pirepSvc->saveRoute($pirep);
} }
$fields = $this->saveCustomFields($request); $this->saveCustomFields($pirep, $request);
$this->pirepSvc->updateCustomFields($pirep->id, $fields);
$this->saveFares($pirep, $request); $this->saveFares($pirep, $request);
if ($attrs['submit'] === 'save') { if ($attrs['submit'] === 'save') {
@@ -561,8 +493,12 @@ class PirepController extends Controller
$this->pirepSvc->submit($pirep); $this->pirepSvc->submit($pirep);
Flash::success('PIREP submitted!'); Flash::success('PIREP submitted!');
} elseif ($attrs['submit'] === 'delete' || $attrs['submit'] === 'cancel') { } elseif ($attrs['submit'] === 'delete' || $attrs['submit'] === 'cancel') {
$this->pirepSvc->delete($pirep); $this->pirepRepo->update([
Flash::success('PIREP deleted!'); 'state' => PirepState::CANCELLED,
'status' => PirepStatus::CANCELLED,
], $pirep->id);
Flash::success('PIREP cancelled!');
return redirect(route('frontend.pireps.index')); return redirect(route('frontend.pireps.index'));
} }
@@ -587,11 +523,6 @@ class PirepController extends Controller
return redirect(route('admin.pireps.index')); return redirect(route('admin.pireps.index'));
} }
if ($pirep->user_id !== Auth::id()) {
Flash::error('Cannot edit someone else\'s PIREP!');
return redirect(route('admin.pireps.index'));
}
$this->pirepSvc->submit($pirep); $this->pirepSvc->submit($pirep);
return redirect(route('frontend.pireps.show', [$pirep->id])); return redirect(route('frontend.pireps.show', [$pirep->id]));
} }

View File

@@ -10,7 +10,6 @@ use App\Repositories\AirlineRepository;
use App\Repositories\AirportRepository; use App\Repositories\AirportRepository;
use App\Repositories\UserRepository; use App\Repositories\UserRepository;
use App\Support\Countries; use App\Support\Countries;
use App\Support\Discord;
use App\Support\Timezonelist; use App\Support\Timezonelist;
use App\Support\Utils; use App\Support\Utils;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -53,7 +52,7 @@ class ProfileController extends Controller
{ {
// Is the ACARS module enabled? // Is the ACARS module enabled?
$acars_enabled = false; $acars_enabled = false;
$acars = Module::find('VMSAcars'); $acars = Module::find('VMSACARS');
if ($acars) { if ($acars) {
$acars_enabled = $acars->isEnabled(); $acars_enabled = $acars->isEnabled();
} }
@@ -80,20 +79,22 @@ class ProfileController extends Controller
public function show($id) public function show($id)
{ {
/** @var \App\Models\User $user */ /** @var \App\Models\User $user */
$with = ['airline', 'awards', 'current_airport', 'fields.field', 'home_airport', 'last_pirep', 'rank', 'typeratings']; $user = User::with(['awards', 'fields', 'fields.field'])
$user = User::with($with)->where('id', $id)->first(); ->where('id', $id)
->first();
if (empty($user)) { if (empty($user)) {
Flash::error('User not found!'); Flash::error('User not found!');
return redirect(route('frontend.dashboard.index')); return redirect(route('frontend.dashboard.index'));
} }
$airports = $this->airportRepo->all();
$userFields = $this->userRepo->getUserFields($user, true); $userFields = $this->userRepo->getUserFields($user, true);
return view('profile.index', [ return view('profile.index', [
'user' => $user, 'user' => $user,
'userFields' => $userFields, 'userFields' => $userFields,
'acars' => $this->acarsEnabled(), 'airports' => $airports,
]); ]);
} }
@@ -109,7 +110,9 @@ class ProfileController extends Controller
public function edit(Request $request) public function edit(Request $request)
{ {
/** @var \App\Models\User $user */ /** @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)) { if (empty($user)) {
Flash::error('User not found!'); Flash::error('User not found!');
@@ -118,7 +121,7 @@ class ProfileController extends Controller
$airlines = $this->airlineRepo->selectBoxList(); $airlines = $this->airlineRepo->selectBoxList();
$airports = $this->airportRepo->selectBoxList(false, setting('pilots.home_hubs_only')); $airports = $this->airportRepo->selectBoxList(false, setting('pilots.home_hubs_only'));
$userFields = $this->userRepo->getUserFields($user); $userFields = $this->userRepo->getUserFields($user, false);
return view('profile.edit', [ return view('profile.edit', [
'user' => $user, 'user' => $user,
@@ -177,16 +180,6 @@ class ProfileController extends Controller
Storage::delete($user->avatar); Storage::delete($user->avatar);
} }
// Find out the user's private channel id
/*
// TODO: Uncomment when Discord API functionality is enabled
if ($request->filled('discord_id')) {
$discord_id = $request->post('discord_id');
if ($discord_id !== $user->discord_id) {
$req_data['discord_private_channel_id'] = Discord::getPrivateChannelId($discord_id);
}
}*/
if ($request->hasFile('avatar')) { if ($request->hasFile('avatar')) {
$avatar = $request->file('avatar'); $avatar = $request->file('avatar');
$file_name = $user->ident.'.'.$avatar->getClientOriginalExtension(); $file_name = $user->ident.'.'.$avatar->getClientOriginalExtension();

View File

@@ -4,18 +4,10 @@ namespace App\Http\Controllers\Frontend;
use App\Exceptions\AssetNotFound; use App\Exceptions\AssetNotFound;
use App\Models\Aircraft; use App\Models\Aircraft;
use App\Models\Bid;
use App\Models\Enums\AircraftState;
use App\Models\Enums\AircraftStatus;
use App\Models\Enums\FareType;
use App\Models\Enums\FlightType; use App\Models\Enums\FlightType;
use App\Models\Fare;
use App\Models\Flight;
use App\Models\SimBrief; use App\Models\SimBrief;
use App\Models\User;
use App\Repositories\FlightRepository; use App\Repositories\FlightRepository;
use App\Services\FareService; use App\Services\FareService;
use App\Services\ModuleService;
use App\Services\SimBriefService; use App\Services\SimBriefService;
use App\Services\UserService; use App\Services\UserService;
use Exception; use Exception;
@@ -26,20 +18,17 @@ class SimBriefController
{ {
private $fareSvc; private $fareSvc;
private $flightRepo; private $flightRepo;
private $moduleSvc;
private $simBriefSvc; private $simBriefSvc;
private $userSvc; private $userSvc;
public function __construct( public function __construct(
FareService $fareSvc, FareService $fareSvc,
FlightRepository $flightRepo, FlightRepository $flightRepo,
ModuleService $moduleSvc,
SimBriefService $simBriefSvc, SimBriefService $simBriefSvc,
UserService $userSvc UserService $userSvc
) { ) {
$this->fareSvc = $fareSvc; $this->fareSvc = $fareSvc;
$this->flightRepo = $flightRepo; $this->flightRepo = $flightRepo;
$this->moduleSvc = $moduleSvc;
$this->simBriefSvc = $simBriefSvc; $this->simBriefSvc = $simBriefSvc;
$this->userSvc = $userSvc; $this->userSvc = $userSvc;
} }
@@ -60,9 +49,8 @@ class SimBriefController
$flight_id = $request->input('flight_id'); $flight_id = $request->input('flight_id');
$aircraft_id = $request->input('aircraft_id'); $aircraft_id = $request->input('aircraft_id');
$flight = $this->flightRepo->with(['subfleets'])->find($flight_id);
/** @var Flight $flight */ $flight = $this->fareSvc->getReconciledFaresForFlight($flight);
$flight = $this->flightRepo->with(['airline', 'arr_airport', 'dpt_airport', 'fares', 'subfleets'])->find($flight_id);
if (!$flight) { if (!$flight) {
flash()->error('Unknown flight'); flash()->error('Unknown flight');
@@ -75,47 +63,6 @@ class SimBriefController
return redirect(route('frontend.flights.index')); return redirect(route('frontend.flights.index'));
} }
// Generate SimBrief Static ID
$static_id = $user->ident.'_'.$flight->id;
// 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;
}
$withCount = ['simbriefs' => function ($query) {
$query->whereNull('pirep_id');
}];
// 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();
return view('flights.simbrief_aircraft', [
'flight' => $flight,
'aircrafts' => $aircraft,
]);
}
// Check if a Simbrief profile already exists // Check if a Simbrief profile already exists
$simbrief = SimBrief::select('id')->where([ $simbrief = SimBrief::select('id')->where([
'flight_id' => $flight_id, 'flight_id' => $flight_id,
@@ -126,26 +73,34 @@ class SimBriefController
return redirect(route('frontend.simbrief.briefing', [$simbrief->id])); return redirect(route('frontend.simbrief.briefing', [$simbrief->id]));
} }
// SimBrief profile does not exists and everything else is ok // Simbrief Profile doesn't exist; prompt the user to create a new one
// Select aircraft which will be used for calculations and details $aircraft = Aircraft::select('registration', 'name', 'icao', 'iata', 'subfleet_id')
/** @var Aircraft $aircraft */ ->where('id', $aircraft_id)
$aircraft = Aircraft::with(['airline'])->where('id', $aircraft_id)->first(); ->get();
// Figure out the proper fares to use for this flight/aircraft if ($flight->subfleets->count() > 0) {
$all_fares = $this->fareSvc->getFareWithOverrides($aircraft->subfleet->fares, $flight->fares); $subfleets = $flight->subfleets;
// TODO: Reconcile the fares for this aircraft w/ proper for the flight/subfleet
// Get passenger and baggage weights with failsafe defaults
if ($flight->flight_type === FlightType::CHARTER_PAX_ONLY) {
$pax_weight = setting('simbrief.charter_pax_weight', 168);
$bag_weight = setting('simbrief.charter_baggage_weight', 28);
} else { } else {
$pax_weight = setting('simbrief.noncharter_pax_weight', 185); $subfleets = $this->userSvc->getAllowableSubfleets($user);
$bag_weight = setting('simbrief.noncharter_baggage_weight', 35);
} }
// Get the load factors with failsafe for loadmax if nothing is defined if ($flight->flight_type === FlightType::CHARTER_PAX_ONLY) {
$pax_weight = 197;
} else {
$pax_weight = 208;
}
// No aircraft selected, show that form
if (!$aircraft_id) {
return view('flights.simbrief_aircraft', [
'flight' => $flight,
'aircraft' => $aircraft,
'subfleets' => $subfleets,
'pax_weight' => $pax_weight,
]);
}
// Get the correct load factors
$lfactor = $flight->load_factor ?? setting('flights.default_load_factor'); $lfactor = $flight->load_factor ?? setting('flights.default_load_factor');
$lfactorv = $flight->load_factor_variance ?? setting('flights.load_factor_variance'); $lfactorv = $flight->load_factor_variance ?? setting('flights.load_factor_variance');
@@ -155,91 +110,14 @@ class SimBriefController
$loadmax = $lfactor + $lfactorv; $loadmax = $lfactor + $lfactorv;
$loadmax = $loadmax > 100 ? 100 : $loadmax; $loadmax = $loadmax > 100 ? 100 : $loadmax;
if ($loadmax === 0) {
$loadmax = 100;
}
// Load fares for passengers
$loaddist = []; // The load distribution string
$pax_load_sheet = [];
$tpaxfig = 0;
/** @var Fare $fare */
foreach ($all_fares as $fare) {
if ($fare->type !== FareType::PASSENGER || empty($fare->capacity)) {
continue;
}
$count = floor(($fare->capacity * rand($loadmin, $loadmax)) / 100);
$tpaxfig += $count;
$pax_load_sheet[] = [
'id' => $fare->id,
'code' => $fare->code,
'name' => $fare->name,
'type' => $fare->type,
'capacity' => (int) $fare->capacity,
'count' => $count,
];
$loaddist[] = $fare->code.' '.$count;
}
// Calculate total weights
if (setting('units.weight') === 'kg') {
$tpaxload = round(($pax_weight * $tpaxfig) / 2.205);
$tbagload = round(($bag_weight * $tpaxfig) / 2.205);
} else {
$tpaxload = round($pax_weight * $tpaxfig);
$tbagload = round($bag_weight * $tpaxfig);
}
// Load up fares for cargo
$tcargoload = 0;
$cargo_load_sheet = [];
foreach ($all_fares as $fare) {
if ($fare->type !== FareType::CARGO || empty($fare->capacity)) {
continue;
}
$count = ceil((($fare->capacity - $tbagload) * rand($loadmin, $loadmax)) / 100);
$tcargoload += $count;
$cargo_load_sheet[] = [
'id' => $fare->id,
'code' => $fare->code,
'name' => $fare->name,
'type' => $fare->type,
'capacity' => $fare->capacity,
'count' => $count,
];
$loaddist[] = $fare->code.' '.$count;
}
$tpayload = $tpaxload + $tbagload + $tcargoload;
$request->session()->put('simbrief_fares', array_merge($pax_load_sheet, $cargo_load_sheet));
// Show the main simbrief form // Show the main simbrief form
return view('flights.simbrief_form', [ return view('flights.simbrief_form', [
'user' => $user, 'flight' => $flight,
'flight' => $flight, 'aircraft' => $aircraft,
'aircraft' => $aircraft, 'subfleets' => $subfleets,
'pax_weight' => $pax_weight, 'pax_weight' => $pax_weight,
'bag_weight' => $bag_weight, 'loadmin' => $loadmin,
'loadmin' => $loadmin, 'loadmax' => $loadmax,
'loadmax' => $loadmax,
'pax_load_sheet' => $pax_load_sheet,
'cargo_load_sheet' => $cargo_load_sheet,
'tpaxfig' => $tpaxfig,
'tpaxload' => $tpaxload,
'tbagload' => $tbagload,
'tpayload' => $tpayload,
'tcargoload' => $tcargoload,
'loaddist' => implode(' ', $loaddist),
'static_id' => $static_id,
]); ]);
} }
@@ -252,11 +130,7 @@ class SimBriefController
*/ */
public function briefing($id) public function briefing($id)
{ {
/** @var User $user */ $simbrief = SimBrief::find($id);
$user = Auth::user();
/** @var SimBrief $simbrief */
$simbrief = SimBrief::with(['flight.airline', 'pirep.airline'])->find($id);
if (!$simbrief) { if (!$simbrief) {
flash()->error('SimBrief briefing not found'); flash()->error('SimBrief briefing not found');
return redirect(route('frontend.flights.index')); return redirect(route('frontend.flights.index'));
@@ -269,18 +143,11 @@ class SimBriefController
$equipment = substr($str, $wc + 1, $tr - 2); $equipment = substr($str, $wc + 1, $tr - 2);
$transponder = substr($str, $tr + 1); $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', [ return view('flights.simbrief_briefing', [
'user' => $user, 'simbrief' => $simbrief,
'simbrief' => $simbrief, 'wakecat' => $wakecat,
'wakecat' => $wakecat, 'equipment' => $equipment,
'equipment' => $equipment, 'transponder' => $transponder,
'transponder' => $transponder,
'bid' => $bid,
'flight' => $simbrief->flight,
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]); ]);
} }
@@ -355,7 +222,6 @@ class SimBriefController
/** /**
* Check whether the OFP was generated. Pass in two items, the flight_id and ofp_id * Check whether the OFP was generated. Pass in two items, the flight_id and ofp_id
* This does the actual "attachment" of the Simbrief to the flight
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* *
@@ -363,14 +229,10 @@ class SimBriefController
*/ */
public function check_ofp(Request $request) public function check_ofp(Request $request)
{ {
/** @var User $user */
$user = Auth::user();
$ofp_id = $request->input('ofp_id'); $ofp_id = $request->input('ofp_id');
$flight_id = $request->input('flight_id'); $flight_id = $request->input('flight_id');
$aircraft_id = $request->input('aircraft_id');
$fares = $request->session()->get('simbrief_fares', []);
$simbrief = $this->simBriefSvc->downloadOfp($user->id, $ofp_id, $flight_id, $aircraft_id, $fares); $simbrief = $this->simBriefSvc->downloadOfp(Auth::user()->id, $ofp_id, $flight_id);
if ($simbrief === null) { if ($simbrief === null) {
$error = new AssetNotFound(new Exception('Simbrief OFP not found')); $error = new AssetNotFound(new Exception('Simbrief OFP not found'));
return $error->getResponse(); return $error->getResponse();
@@ -381,31 +243,6 @@ class SimBriefController
]); ]);
} }
/**
* Get the latest generated OFP. Pass in two additional items, the Simbrief userid and static_id
* This will get the latest edited/regenerated of from Simbrief and update our records
* We do not need to send the fares again, so used an empty array
*/
public function update_ofp(Request $request)
{
/** @var User $user */
$user = Auth::user();
$ofp_id = $request->input('ofp_id');
$flight_id = $request->input('flight_id');
$aircraft_id = $request->input('aircraft_id');
$sb_userid = $request->input('sb_userid');
$sb_static_id = $request->input('sb_static_id');
$fares = [];
$simbrief = $this->simBriefSvc->downloadOfp($user->id, $ofp_id, $flight_id, $aircraft_id, $fares, $sb_userid, $sb_static_id);
if ($simbrief === null) {
$error = new AssetNotFound(new Exception('Simbrief OFP not found'));
return $error->getResponse();
}
return redirect(route('frontend.simbrief.briefing', [$ofp_id]));
}
/** /**
* Generate the API code * Generate the API code
* *

View File

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

View File

@@ -25,6 +25,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\View\View; use Illuminate\View\View;
use function in_array; use function in_array;
use Laracasts\Flash\Flash;
use RuntimeException; use RuntimeException;
class InstallerController extends Controller class InstallerController extends Controller
@@ -202,21 +203,21 @@ class InstallerController extends Controller
Log::error('Testing db before writing configs failed'); Log::error('Testing db before writing configs failed');
Log::error($e->getMessage()); Log::error($e->getMessage());
flash()->error($e->getMessage()); Flash::error($e->getMessage());
return redirect(route('installer.step2'))->withInput(); return redirect(route('installer.step2'))->withInput();
} }
// Now write out the env file // Now write out the env file
$attrs = [ $attrs = [
'SITE_NAME' => $request->post('site_name'), 'SITE_NAME' => $request->post('site_name'),
'APP_URL' => $request->post('app_url'), 'SITE_URL' => $request->post('site_url'),
'DB_CONNECTION' => $request->post('db_conn'), 'DB_CONN' => $request->post('db_conn'),
'DB_HOST' => $request->post('db_host'), 'DB_HOST' => $request->post('db_host'),
'DB_PORT' => $request->post('db_port'), 'DB_PORT' => $request->post('db_port'),
'DB_DATABASE' => $request->post('db_name'), 'DB_NAME' => $request->post('db_name'),
'DB_USERNAME' => $request->post('db_user'), 'DB_USER' => $request->post('db_user'),
'DB_PASSWORD' => $request->post('db_pass'), 'DB_PASS' => $request->post('db_pass'),
'DB_PREFIX' => $request->post('db_prefix'), 'DB_PREFIX' => $request->post('db_prefix'),
]; ];
/* /*
@@ -230,7 +231,7 @@ class InstallerController extends Controller
Log::error('Config files failed to write'); Log::error('Config files failed to write');
Log::error($e->getMessage()); Log::error($e->getMessage());
flash()->error($e->getMessage()); Flash::error($e->getMessage());
return redirect(route('installer.step2'))->withInput(); return redirect(route('installer.step2'))->withInput();
} }
@@ -256,7 +257,7 @@ class InstallerController extends Controller
Log::error('Error on db setup: '.$e->getMessage()); Log::error('Error on db setup: '.$e->getMessage());
//dd($e); //dd($e);
$this->envSvc->removeConfigFiles(); $this->envSvc->removeConfigFiles();
flash()->error($e->getMessage()); Flash::error($e->getMessage());
return redirect(route('installer.step2'))->withInput(); return redirect(route('installer.step2'))->withInput();
} }

View File

@@ -3,32 +3,49 @@
namespace App\Http\Controllers\System; namespace App\Http\Controllers\System;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Repositories\KvpRepository;
use App\Services\AnalyticsService;
use App\Services\Installer\InstallerService; use App\Services\Installer\InstallerService;
use App\Services\Installer\MigrationService; use App\Services\Installer\MigrationService;
use App\Services\Installer\SeederService; use App\Services\Installer\SeederService;
use Codedge\Updater\UpdaterManager;
use function count; use function count;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
class UpdateController extends Controller class UpdateController extends Controller
{ {
private $analyticsSvc;
private $installerSvc; private $installerSvc;
private $kvpRepo;
private $migrationSvc; private $migrationSvc;
private $seederSvc; private $seederSvc;
private $updateManager;
/** /**
* @param AnalyticsService $analyticsSvc
* @param InstallerService $installerSvc * @param InstallerService $installerSvc
* @param KvpRepository $kvpRepo
* @param MigrationService $migrationSvc * @param MigrationService $migrationSvc
* @param SeederService $seederSvc * @param SeederService $seederSvc
* @param UpdaterManager $updateManager
*/ */
public function __construct( public function __construct(
AnalyticsService $analyticsSvc,
InstallerService $installerSvc, InstallerService $installerSvc,
KvpRepository $kvpRepo,
MigrationService $migrationSvc, MigrationService $migrationSvc,
SeederService $seederSvc SeederService $seederSvc,
UpdaterManager $updateManager
) { ) {
$this->analyticsSvc = $analyticsSvc;
$this->migrationSvc = $migrationSvc; $this->migrationSvc = $migrationSvc;
$this->seederSvc = $seederSvc; $this->seederSvc = $seederSvc;
$this->installerSvc = $installerSvc; $this->installerSvc = $installerSvc;
$this->kvpRepo = $kvpRepo;
$this->updateManager = $updateManager;
} }
/** /**
@@ -90,4 +107,38 @@ class UpdateController extends Controller
{ {
return redirect('/admin'); return redirect('/admin');
} }
/**
* Show the update page with the latest version
*
* @return Factory|View
*/
public function updater()
{
$version = $this->kvpRepo->get('latest_version_tag');
return view('system.updater.downloader/downloader', [
'version' => $version,
]);
}
/**
* Download the actual update and then forward the user to the updater page
*
* @return mixed
*/
public function update_download()
{
$version = $this->kvpRepo->get('latest_version_tag');
if (empty($version)) {
return view('system.updater.steps.step1-no-update');
}
$release = $this->updateManager->source('github')->fetch($version);
$this->updateManager->source('github')->update($release);
$this->analyticsSvc->sendUpdate();
Log::info('Update completed to '.$version.', redirecting');
return redirect('/update');
}
} }

View File

@@ -39,7 +39,7 @@ class ApiAuth implements Middleware
return $this->unauthorized('User not found with key "'.$api_key.'"'); return $this->unauthorized('User not found with key "'.$api_key.'"');
} }
if ($user->state !== UserState::ACTIVE && $user->state !== UserState::ON_LEAVE) { if ($user->state !== UserState::ACTIVE) {
return $this->unauthorized('User is not ACTIVE, please contact an administrator'); return $this->unauthorized('User is not ACTIVE, please contact an administrator');
} }
@@ -50,9 +50,6 @@ class ApiAuth implements Middleware
return $user; return $user;
}); });
// Force english locale for API
app()->setLocale('en');
return $next($request); return $next($request);
} }

View File

@@ -15,7 +15,6 @@ class JsonResponse implements Middleware
{ {
$response = $next($request); $response = $next($request);
$response->headers->set('Content-Type', 'application/json'); $response->headers->set('Content-Type', 'application/json');
$response->headers->set('charset', 'utf-8');
return $response; return $response;
} }

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