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
44 changed files with 141 additions and 463 deletions

View File

@@ -12,24 +12,13 @@ abstract class Metar
{
/**
* 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,
* return a blank string
* since this shouldn't be directly called. Call `get_metar($icao)` instead
*
* @param $icao
*
* @return mixed
*/
abstract protected function get_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;
abstract protected function metar($icao): string;
/**
* Download the METAR, wrap in caching
@@ -38,9 +27,9 @@ abstract class Metar
*
* @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;
if (Cache::has($key)) {
@@ -51,7 +40,7 @@ abstract class Metar
}
try {
$raw_metar = $this->get_metar($icao);
$raw_metar = $this->metar($icao);
} catch (\Exception $e) {
Log::error('Error getting METAR: '.$e->getMessage(), $e->getTrace());
return '';
@@ -63,37 +52,4 @@ abstract class 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

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

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

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

View File

@@ -147,12 +147,6 @@ class FlightController extends Controller
$flights = collect();
$saved_flights = [];
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);
$saved_flights[] = $bid->flight->id;
}

View File

@@ -52,7 +52,7 @@ class ProfileController extends Controller
{
// Is the ACARS module enabled?
$acars_enabled = false;
$acars = Module::find('VMSAcars');
$acars = Module::find('VMSACARS');
if ($acars) {
$acars_enabled = $acars->isEnabled();
}
@@ -95,7 +95,6 @@ class ProfileController extends Controller
'user' => $user,
'userFields' => $userFields,
'airports' => $airports,
'acars' => $this->acarsEnabled(),
]);
}
@@ -122,7 +121,7 @@ class ProfileController extends Controller
$airlines = $this->airlineRepo->selectBoxList();
$airports = $this->airportRepo->selectBoxList(false, setting('pilots.home_hubs_only'));
$userFields = $this->userRepo->getUserFields($user, true);
$userFields = $this->userRepo->getUserFields($user, false);
return view('profile.edit', [
'user' => $user,

View File

@@ -110,12 +110,6 @@ class SimBriefController
$loadmax = $lfactor + $lfactorv;
$loadmax = $loadmax > 100 ? 100 : $loadmax;
// Failsafe for admins not defining load values for their flights
// and also leave the general settings empty, set loadmax to 100
if ($loadmax === 0) {
$loadmax = 100;
}
// Show the main simbrief form
return view('flights.simbrief_form', [
'flight' => $flight,

View File

@@ -27,7 +27,6 @@ class Pirep extends Resource
{
$res = parent::toArray($request);
$res['ident'] = $this->ident;
$res['phase'] = $this->status;
$res['status_text'] = PirepStatus::label($this->status);
// Set these to the response units

View File

@@ -4,14 +4,6 @@ namespace App\Models;
use App\Contracts\Model;
/**
* @property int id
* @property string pirep_id
* @property int fare_id
* @property int count
* @property Pirep pirep
* @property Fare fare
*/
class PirepFare extends Model
{
public $table = 'pirep_fares';

View File

@@ -46,32 +46,12 @@ class AirportService extends Service
return;
}
$raw_metar = $this->metarProvider->metar($icao);
$raw_metar = $this->metarProvider->get_metar($icao);
if ($raw_metar && $raw_metar !== '') {
return new Metar($raw_metar);
}
}
/**
* Return the METAR for a given airport
*
* @param $icao
*
* @return Metar|null
*/
public function getTaf($icao)
{
$icao = trim($icao);
if ($icao === '') {
return;
}
$raw_taf = $this->metarProvider->taf($icao);
if ($raw_taf && $raw_taf !== '') {
return new Metar($raw_taf, true);
}
}
/**
* Lookup an airport's information from a remote provider. This handles caching
* the data internally
@@ -121,7 +101,7 @@ class AirportService extends Service
}
// Don't lookup the airport, so just add in something generic
if (!setting('general.auto_airport_lookup')) {
if (!setting('general.auto_airport_lookup', false)) {
$airport = new Airport([
'id' => $icao,
'icao' => $icao,

View File

@@ -92,6 +92,6 @@ class CronService extends Service
// More than 5 minutes... there's a problem
$diff = $dt_now->diff($dt);
return $diff->i > 60 * 12; // Hasn't run for 12 hours
return $diff->i > 5;
}
}

View File

@@ -286,7 +286,9 @@ class FareService extends Service
*/
public function getForPirep(Pirep $pirep)
{
return PirepFare::where('pirep_id', $pirep->id)->get();
$found_fares = PirepFare::where('pirep_id', $pirep->id)->get();
return $found_fares;
}
/**
@@ -311,8 +313,6 @@ class FareService extends Service
$fare['pirep_id'] = $pirep->id;
// other fields: ['fare_id', 'count']
Log::info('Saving fare pirep='.$pirep->id.', fare='.$fare['count']);
$field = new PirepFare($fare);
$field->save();
}

View File

@@ -137,13 +137,6 @@ class FlightService extends Service
{
/** @var \Illuminate\Support\Collection $subfleets */
$subfleets = $flight->subfleets;
// If no subfleets assigned to a flight get users allowed subfleets
if ($subfleets === null || $subfleets->count() === 0) {
$subfleets = $this->userSvc->getAllowableSubfleets($user);
}
// If subfleets are still empty return the flight
if ($subfleets === null || $subfleets->count() === 0) {
return $flight;
}

View File

@@ -51,8 +51,13 @@ class FlightImporter extends ImportExport
'fields' => 'nullable',
];
/** @var AirportService */
private $airportSvc;
/** @var FareService */
private $fareSvc;
/** @var FlightService */
private $flightSvc;
/**

View File

@@ -118,11 +118,7 @@ class ImportService extends Service
// turn it into a collection and run some filtering
$row = collect($row)->map(function ($val, $index) {
$val = trim($val);
if ($val === '') {
return;
}
return $val;
return empty($val) ? null : $val;
})->toArray();
// Try to validate

View File

@@ -9,16 +9,13 @@ use Exception;
use Illuminate\Support\Facades\Log;
/**
* Return the raw METAR/TAF string from the NOAA Aviation Weather Service
* Return the raw METAR string from the NOAA Aviation Weather Service
*/
class AviationWeather extends Metar
{
private const METAR_URL =
'https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecent=true&stationString=';
private const TAF_URL =
'https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=tafs&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecent=true&stationString=';
private $httpClient;
public function __construct(HttpClient $httpClient)
@@ -36,7 +33,7 @@ class AviationWeather extends Metar
*
* @return string
*/
protected function get_metar($icao): string
protected function metar($icao): string
{
if ($icao === '') {
return '';
@@ -70,53 +67,7 @@ class AviationWeather extends Metar
return $xml->data->METAR->raw_text->__toString();
} catch (Exception $e) {
Log::error('Error reading METAR: '.$e->getMessage());
return '';
}
}
/**
* Do the actual retrieval of the TAF
*
* @param $icao
*
* @throws \GuzzleHttp\Exception\GuzzleException
*
* @return string
*/
protected function get_taf($icao): string
{
if ($icao === '') {
return '';
}
$tafurl = static::TAF_URL.$icao;
try {
$tafres = $this->httpClient->get($tafurl, []);
$tafxml = simplexml_load_string($tafres);
$tafattrs = $tafxml->data->attributes();
if (!isset($tafattrs['num_results'])) {
return '';
}
$tafnum_results = $tafattrs['num_results'];
if (empty($tafnum_results)) {
return '';
}
$tafnum_results = (int) $tafnum_results;
if ($tafnum_results === 0) {
return '';
}
if (count($tafxml->data->TAF->raw_text) === 0) {
return '';
}
return $tafxml->data->TAF->raw_text->__toString();
} catch (Exception $e) {
Log::error('Error reading TAF: '.$e->getMessage());
return '';
}
}

View File

@@ -21,7 +21,6 @@ use App\Repositories\SubfleetRepository;
use App\Repositories\UserRepository;
use App\Support\Units\Time;
use App\Support\Utils;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use function is_array;
@@ -255,41 +254,6 @@ class UserService extends Service
return $user;
}
/**
* Return all of the users that are determined to be on leave. Only goes through the
* currently active users. If the user doesn't have a PIREP, then the creation date
* of the user record is used to determine the difference
*/
public function findUsersOnLeave(): array
{
$leave_days = setting('pilots.auto_leave_days');
if ($leave_days === 0) {
return [];
}
$return_users = [];
$date = Carbon::now('UTC');
$users = User::with(['last_pirep'])->where('state', UserState::ACTIVE)->get();
/** @var User $user */
foreach ($users as $user) {
// If they haven't submitted a PIREP, use the date that the user was created
if (!$user->last_pirep) {
$diff_date = $user->created_at;
} else {
$diff_date = $user->last_pirep->submitted_at;
}
// See if the difference is larger than what the setting calls for
if ($date->diffInDays($diff_date) > $leave_days) {
$return_users[] = $user;
}
}
return $return_users;
}
/**
* Return the subfleets this user is allowed access to,
* based on their current rank
@@ -462,7 +426,7 @@ class UserService extends Service
$user->state = UserState::ON_LEAVE;
$user->save();
event(new UserStateChanged($user, UserState::ON_LEAVE));
event(new UserStateChanged($user, UserState::ACTIVE));
$user->refresh();
return $user;

View File

@@ -123,10 +123,6 @@ class Utils
return $val;
}
if ($result->hostname === 'localhost') {
return 'localhost';
}
// Couldn't validate a domain, see if this is an IP address?
if (filter_var($url, FILTER_VALIDATE_IP)) {
return $url;

View File

@@ -11,8 +11,7 @@ use App\Services\AirportService;
class Weather extends Widget
{
protected $config = [
'icao' => null,
'raw_only' => null,
'icao' => null,
];
/**
@@ -23,12 +22,10 @@ class Weather extends Widget
/** @var \App\Services\AirportService $airportSvc */
$airportSvc = app(AirportService::class);
$metar = $airportSvc->getMetar($this->config['icao']);
$taf = $airportSvc->getTaf($this->config['icao']);
return view('widgets.weather', [
'config' => $this->config,
'metar' => $metar,
'taf' => $taf,
'unit_alt' => setting('units.altitude'),
'unit_dist' => setting('units.distance'),
'unit_temp' => setting('units.temperature'),

View File

@@ -58,8 +58,7 @@
"webpatser/laravel-uuid": "~3.0",
"oomphinc/composer-installers-extender": "^1.1",
"laravel/ui": "^2.0",
"madnest/madzipper": "^1.0",
"elcobvg/laravel-opcache": "^0.4.1"
"madnest/madzipper": "^1.0"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.0",

59
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5bd282b9602f7922883277e45c82603e",
"content-hash": "6f5fb0bd12dc789b1ad1613ddf907a80",
"packages": [
{
"name": "akaunting/money",
@@ -1655,63 +1655,6 @@
],
"time": "2020-08-08T21:28:19+00:00"
},
{
"name": "elcobvg/laravel-opcache",
"version": "0.4.1",
"source": {
"type": "git",
"url": "https://github.com/elcobvg/laravel-opcache.git",
"reference": "a9af6d12f8bda562dd187f6d5368c647c1f02a44"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/elcobvg/laravel-opcache/zipball/a9af6d12f8bda562dd187f6d5368c647c1f02a44",
"reference": "a9af6d12f8bda562dd187f6d5368c647c1f02a44",
"shasum": ""
},
"require": {
"php": ">=7.0.0"
},
"require-dev": {
"mockery/mockery": "1.0",
"orchestra/testbench": "3.5",
"phpunit/phpunit": "6.5",
"squizlabs/php_codesniffer": "3.2"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"ElcoBvg\\Opcache\\ServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"ElcoBvg\\Opcache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Elco Brouwer von Gonzenbach",
"email": "elco.brouwer@gmail.com"
}
],
"description": "Custom OPcache Cache Driver for Laravel. Faster than Redis or memcached.",
"homepage": "https://github.com/elcobvg/laravel-opcache",
"keywords": [
"Opcache",
"cache",
"driver",
"laravel",
"webprofiler"
],
"time": "2020-05-16T00:51:29+00:00"
},
{
"name": "facade/flare-client-php",
"version": "1.3.5",

View File

@@ -131,10 +131,22 @@ return [
'Yaml' => Symfony\Component\Yaml\Yaml::class,
// ENUMS
'ActiveState' => App\Models\Enums\ActiveState::class,
'UserState' => App\Models\Enums\UserState::class,
'PirepSource' => App\Models\Enums\PirepSource::class,
'PirepState' => App\Models\Enums\PirepState::class,
'PirepStatus' => App\Models\Enums\PirepStatus::class,
'AcarsType' => App\Models\Enums\AcarsType::class,
'ActiveState' => App\Models\Enums\ActiveState::class,
'AircraftState' => App\Models\Enums\AircraftState::class,
'AircraftStatus' => App\Models\Enums\AircraftStatus::class,
'Days' => App\Models\Enums\Days::class,
'ExpenseType' => App\Models\Enums\ExpenseType::class,
'FareType' => App\Models\Enums\FareType::class,
'FlightType' => App\Models\Enums\FlightType::class,
'FuelType' => App\Models\Enums\FuelType::class,
'JournalType' => App\Models\Enums\JournalType::class,
'NavaidType' => App\Models\Enums\NavaidType::class,
'PageType' => App\Models\Enums\PageType::class,
'PirepFieldSource' => App\Models\Enums\PirepFieldSource::class,
'PirepSource' => App\Models\Enums\PirepSource::class,
'PirepState' => App\Models\Enums\PirepState::class,
'PirepStatus' => App\Models\Enums\PirepStatus::class,
'UserState' => App\Models\Enums\UserState::class,
],
];

View File

@@ -135,7 +135,7 @@ return [
*/
'monitor_backups' => [
[
'name' => config('app.name'),
'name' => config(config('app.name'), 'phpvms-backup'),
'disks' => ['local'],
'health_checks' => [
MaximumAgeInDays::class => 1,
@@ -172,27 +172,27 @@ return [
/*
* The number of days for which backups must be kept.
*/
'keep_all_backups_for_days' => 3,
'keep_all_backups_for_days' => 7,
/*
* The number of days for which daily backups must be kept.
*/
'keep_daily_backups_for_days' => 2,
'keep_daily_backups_for_days' => 7,
/*
* The number of weeks for which one weekly backup must be kept.
*/
'keep_weekly_backups_for_weeks' => 2,
'keep_weekly_backups_for_weeks' => 4,
/*
* The number of months for which one monthly backup must be kept.
*/
'keep_monthly_backups_for_months' => 1,
'keep_monthly_backups_for_months' => 4,
/*
* The number of years for which one yearly backup must be kept.
*/
'keep_yearly_backups_for_years' => 1,
'keep_yearly_backups_for_years' => 2,
/*
* After cleaning up the backups remove the oldest backup until

View File

@@ -9,18 +9,14 @@ return [
'key' => 'airports.lookup:',
'time' => 60 * 30,
],
'METAR_WEATHER_LOOKUP' => [
'key' => 'airports.weather.metar.', // append icao
'WEATHER_LOOKUP' => [
'key' => 'airports.weather.', // append icao
'time' => 60 * 60, // Cache for 60 minutes
],
'RANKS_PILOT_LIST' => [
'key' => 'ranks.pilot_list',
'time' => 60 * 10,
],
'TAF_WEATHER_LOOKUP' => [
'key' => 'airports.weather.taf.', // append icao
'time' => 60 * 60, // Cache for 60 minutes
],
'USER_API_KEY' => [
'key' => 'user.apikey',
'time' => 60 * 5, // 5 min

View File

@@ -23,7 +23,6 @@ return [
'tokenizer',
'json',
'curl',
'dom',
],
// Make sure these are writable

View File

@@ -15,7 +15,8 @@ return [
|
*/
'default' => env('MAIL_DRIVER', 'smtp'),
'driver' => env('MAIL_DRIVER', 'smtp'),
'mailers' => [
'smtp' => [
'transport' => 'smtp',
@@ -70,21 +71,4 @@ return [
'address' => env('MAIL_FROM_ADDRESS', 'no-reply@phpvms.net'),
],
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
];

View File

@@ -20,7 +20,7 @@ return [
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => 'mysql',
'connection' => null,
'table' => 'sessions',
'store' => null,
'lottery' => [1, 100],

View File

@@ -42,7 +42,7 @@ class PilotHoursAwards extends Award
*/
public function check($flight_minutes = null): bool
{
if (!is_numeric($flight_minutes)) {
if (!is_int($flight_minutes)) {
Log::error('PilotHourAwards: Flight time "'.$flight_minutes.'" is not a valid flight time');
return false;
}

11
package-lock.json generated
View File

@@ -1983,6 +1983,11 @@
"resolved": "https://registry.npmjs.org/bootstrap-sass/-/bootstrap-sass-3.4.1.tgz",
"integrity": "sha512-p5rxsK/IyEDQm2CwiHxxUi0MZZtvVFbhWmyMOt4lLkA4bujDA1TGoKT0i1FKIWiugAdP+kK8T5KMDFIKQCLYIA=="
},
"bootstrap3": {
"version": "npm:bootstrap@3.4.1",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz",
"integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -5812,9 +5817,9 @@
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
"lodash.memoize": {
"version": "4.1.2",

View File

@@ -33,7 +33,7 @@
"leaflet-providers": "1.0.*",
"leaflet-rotatedmarker": "^0.2.0",
"leaflet.geodesic": "^2.5.2",
"lodash": ">=4.17.21",
"lodash": ">=4.17.19",
"marked": "^1.2.2",
"minimist": "^1.2.2",
"moment": "^2.29.1",

View File

@@ -130,11 +130,3 @@
border-radius: 5px;
width: 250px;
}
/*
* fix the dropdown menu on mobile view
*/
.dropdown-menu:not(.show) {
display: none;
}

View File

@@ -80,7 +80,7 @@ return [
// Overrides config/mail.php
'mail' => [
'default' => 'mail', # Default is to use the mail() fn
'driver' => 'mail', # Default is to use the mail() fn
'mailers' => [
'smtp' => [
'transport' => 'smtp',
@@ -107,8 +107,7 @@ return [
// Overrides config/session.php
'session' => [
'driver' => 'database',
'connection' => 'mysql',
'default' => 'file',
'lifetime' => 60 * 24, # 24 hours
],
];

View File

@@ -4,7 +4,7 @@
<div class="content">
@if($cron_problem_exists)
<div class="alert alert-danger" role="alert">
The cron has not run in more than 12 hours; make sure it's setup and check logs at
There was a problem running the cron; make sure it's setup and check logs at
<span class="text-monospace bg-gradient-dark">storage/logs/cron.log</span>.
<a href="{{ docs_link('cron') }}" target="_blank">See the docs</a>
</div>

View File

@@ -223,8 +223,8 @@
<form action="https://my.vatsim.net/pilots/flightplan" method="GET" target="_blank">
<input type="hidden" name="raw" value="{{ $simbrief->xml->atc->flightplan_text }}">
<input type="hidden" name="fuel_time" value="@secstohhmm($simbrief->xml->times->endurance)">
<input type="hidden" name="speed" value="@if(substr($simbrief->xml->atc->initial_spd,0,1) === '0') {{ substr($simbrief->xml->atc->initial_spd,1) }} @else {{ $simbrief->xml->atc->initial_spd }} @endif">
<input type="hidden" name="altitude" value="{{ $simbrief->xml->general->initial_altitude }}">
<input type="hidden" name="speed" value="{{ $simbrief->xml->atc->initial_spd }}">
<input type="hidden" name="altitude" value="{{ $simbrief->xml->atc->initial_alt }}">
<input id="vatsim_prefile" type="submit" class="btn btn-primary" value="File ATC on VATSIM"/>
</form>
</div>

View File

@@ -133,11 +133,11 @@
<div class="text-right">
@if (isset($acars) && $acars === true)
<a href="{{ route('frontend.profile.acars') }}" class="btn btn-primary"
onclick="alert('Copy or Save to \'My Documents/phpVMS\'')">ACARS Config</a>
onclick="alert('Save to \'My Documents/phpVMS\'')">ACARS Config</a>
&nbsp;
@endif
<a href="{{ route('frontend.profile.regen_apikey') }}" class="btn btn-warning"
onclick="return confirm('Are you sure? This will reset your API key!')">@lang('profile.newapikey')</a>
onclick="return confirm({{ __('Are you sure? This will reset your API key.') }})">@lang('profile.newapikey')</a>
&nbsp;
<a href="{{ route('frontend.profile.edit', [$user->id]) }}"
class="btn btn-primary">@lang('common.edit')</a>
@@ -171,7 +171,7 @@
<div class="col-sm-12">
<table class="table table-full-width">
@foreach($userFields as $field)
@if(!$field->private)
@if($field->public === true)
<tr>
<td>{{ $field->name }}</td>
<td>{{ $field->value }}</td>

View File

@@ -4,8 +4,10 @@ If you want to edit this, you can reference the CheckWX API docs:
https://api.checkwx.com/#metar-decoded
--}}
<table class="table table-striped">
@if($config['raw_only'] != true && $metar)
@if(!$metar)
<p>@lang('widgets.weather.nometar')</p>
@else
<table class="table table-striped">
<tr>
<td>@lang('widgets.weather.conditions')</td>
<td>{{ $metar['category'] }}</td>
@@ -18,35 +20,35 @@ https://api.checkwx.com/#metar-decoded
</td>
</tr>
@if($metar['visibility'])
<tr>
<td>Visibility</td>
<td>{{ $metar['visibility'][$unit_dist] }} {{$unit_dist}}</td>
</tr>
<tr>
<td>Visibility</td>
<td>{{ $metar['visibility'][$unit_dist] }} {{$unit_dist}}</td>
</tr>
@endif
@if($metar['runways_visual_range'])
<tr>
<tr>
<td>Runway Visual Range</td>
<td>
@foreach($metar['runways_visual_range'] as $rvr)
<b>RWY{{ $rvr['runway'] }}</b>; {{ $rvr['report'] }}<br>
@endforeach
</td>
</tr>
</tr>
@endif
@if($metar['present_weather_report'] <> 'Dry')
<tr>
<tr>
<td>Phenomena</td>
<td>{{ $metar['present_weather_report'] }}</td>
</tr>
</tr>
@endif
@if($metar['clouds'] || $metar['cavok'])
<tr>
<tr>
<td>@lang('widgets.weather.clouds')</td>
<td>
@if($unit_alt === 'ft') {{ $metar['clouds_report_ft'] }} @else {{ $metar['clouds_report'] }} @endif
@if($metar['cavok'] == 1) Ceiling and Visibility OK @endif
</td>
</tr>
</tr>
@endif
<tr>
<td>Temperature</td>
@@ -61,20 +63,20 @@ https://api.checkwx.com/#metar-decoded
<td>{{ number_format($metar['barometer']['hPa']) }} hPa / {{ number_format($metar['barometer']['inHg'], 2) }} inHg</td>
</tr>
@if($metar['recent_weather_report'])
<tr>
<tr>
<td>Recent Phenomena</td>
<td>{{ $metar['recent_weather_report'] }}</td>
</tr>
</tr>
@endif
@if($metar['runways_report'])
<tr>
<tr>
<td>Runway Condition</td>
<td>
@foreach($metar['runways_report'] as $runway)
<b>RWY{{ $runway['runway'] }}</b>; {{ $runway['report'] }}<br>
@endforeach
</td>
</tr>
</tr>
@endif
@if($metar['remarks'])
<tr>
@@ -86,13 +88,9 @@ https://api.checkwx.com/#metar-decoded
<td>@lang('widgets.weather.updated')</td>
<td>{{$metar['observed_time']}} ({{$metar['observed_age']}})</td>
</tr>
@endif
<tr>
<td>@lang('common.metar')</td>
<td>@if($metar) {{ $metar['raw'] }} @else @lang('widgets.weather.nometar') @endif</td>
<td>{{ $metar['raw'] }}</td>
</tr>
<tr>
<td>TAF</td>
<td>@if($taf) {{ $taf['raw'] }} @else @lang('widgets.weather.nometar') @endif</td>
</tr>
</table>
</table>
@endif

View File

@@ -467,6 +467,11 @@ class ImporterTest extends TestCase
*/
public function testFlightImporter(): void
{
$this->updateSetting('general.auto_airport_lookup', false);
factory(Airport::class)->create(['icao' => 'KAUS']);
factory(Airport::class)->create(['icao' => 'KJFK']);
[$airline, $subfleet] = $this->insertFlightsScaffoldData();
$file_path = base_path('tests/data/flights.csv');
@@ -531,6 +536,19 @@ class ImporterTest extends TestCase
// Check the subfleets
$subfleets = $flight->subfleets;
$this->assertCount(1, $subfleets);
// Reimport, see that data updates
$file_path = base_path('tests/data/flights-update.csv');
$status = $this->importSvc->importFlights($file_path);
$flight = Flight::where([
'airline_id' => $airline->id,
'flight_number' => '1972',
])->first();
$this->assertCount(1, $status['success']);
$this->assertEquals('12:00 CST', $flight->dpt_time);
$this->assertEquals('18:35 EST', $flight->arr_time);
}
/**
@@ -634,8 +652,8 @@ class ImporterTest extends TestCase
$this->assertEquals(true, $airport->hub);
$this->assertEquals('30.1945', $airport->lat);
$this->assertEquals('-97.6699', $airport->lon);
$this->assertEquals(0.0, $airport->ground_handling_cost);
$this->assertEquals(setting('airports.default_jet_a_fuel_cost'), $airport->fuel_jeta_cost);
$this->assertEquals(250, $airport->ground_handling_cost);
$this->assertEquals(0.8, $airport->fuel_jeta_cost); // should be updated
// See if it imported
$airport = Airport::where([

View File

@@ -168,8 +168,6 @@ class MetarTest extends TestCase
public function testHttpCallSuccess()
{
$this->mockXmlResponse('aviationweather/kjfk.xml');
/** @var AirportService $airportSvc */
$airportSvc = app(AirportService::class);
$this->assertInstanceOf(Metar::class, $airportSvc->getMetar('kjfk'));

View File

@@ -3,9 +3,7 @@
namespace Tests;
use App\Models\Aircraft;
use App\Models\Enums\UserState;
use App\Models\Flight;
use App\Models\Pirep;
use App\Models\Subfleet;
use App\Models\User;
use Exception;
@@ -23,37 +21,34 @@ trait TestData
{
$subfleet = $this->createSubfleetWithAircraft(1);
$rank = $this->createRank(2, [$subfleet['subfleet']->id]);
return factory(User::class)->create(array_merge([
$user = factory(User::class)->create(array_merge([
'flight_time' => 1000,
'rank_id' => $rank->id,
'state' => UserState::ACTIVE,
], $attrs));
return $user;
}
/**
* Create a new PIREP with a proper subfleet/rank/user and an
* aircraft that the user is allowed to fly
*
* @param array $user_attrs Additional attributes for the user
* @param array $pirep_attrs Additional attributes for the PIREP
*
* @throws \Exception
*
* @return \App\Models\Pirep
*/
protected function createPirep(array $user_attrs = [], array $pirep_attrs = [])
protected function createPirep()
{
$subfleet = $this->createSubfleetWithAircraft(2);
$rank = $this->createRank(10, [$subfleet['subfleet']->id]);
$this->user = factory(\App\Models\User::class)->create(array_merge([
$this->user = factory(\App\Models\User::class)->create([
'rank_id' => $rank->id,
], $user_attrs));
]);
// Return a Pirep model
return factory(Pirep::class)->make(array_merge([
$pirep = factory(\App\Models\Pirep::class)->make([
'aircraft_id' => $subfleet['aircraft']->random()->id,
], $pirep_attrs));
]);
return $pirep;
}
/**

View File

@@ -5,14 +5,11 @@ namespace Tests;
use App\Exceptions\PilotIdNotFound;
use App\Exceptions\UserPilotIdExists;
use App\Models\Airline;
use App\Models\Enums\UserState;
use App\Models\Fare;
use App\Models\Pirep;
use App\Models\User;
use App\Repositories\SettingRepository;
use App\Services\FareService;
use App\Services\UserService;
use Carbon\Carbon;
use Illuminate\Support\Facades\Hash;
class UserTest extends TestCase
@@ -327,48 +324,4 @@ class UserTest extends TestCase
$this->assertEquals($expected, $user->name_private);
}
}
/**
* @throws \Exception
*/
public function testUserLeave(): void
{
$this->createUser(['status' => UserState::ACTIVE]);
$users_on_leave = $this->userSvc->findUsersOnLeave();
$this->assertEquals(0, count($users_on_leave));
$this->updateSetting('pilots.auto_leave_days', 1);
$user = $this->createUser([
'status' => UserState::ACTIVE,
'created_at' => Carbon::now('UTC')->subDays(5),
]);
$users_on_leave = $this->userSvc->findUsersOnLeave();
$this->assertEquals(1, count($users_on_leave));
$this->assertEquals($user->id, $users_on_leave[0]->id);
// Give that user a new PIREP, still old
/** @var \App\Models\Pirep $pirep */
$pirep = factory(Pirep::class)->create(['submitted_at' => Carbon::now('UTC')->subDays(5)]);
$user->last_pirep_id = $pirep->id;
$user->save();
$user->refresh();
$users_on_leave = $this->userSvc->findUsersOnLeave();
$this->assertEquals(1, count($users_on_leave));
$this->assertEquals($user->id, $users_on_leave[0]->id);
// Create a new PIREP
/** @var \App\Models\Pirep $pirep */
$pirep = factory(Pirep::class)->create(['submitted_at' => Carbon::now('UTC')]);
$user->last_pirep_id = $pirep->id;
$user->save();
$user->refresh();
$users_on_leave = $this->userSvc->findUsersOnLeave();
$this->assertEquals(0, count($users_on_leave));
}
}

View File

@@ -100,6 +100,5 @@ class UtilsTest extends TestCase
$this->assertEquals('phpvms.co.uk', Utils::getRootDomain('http://phpvms.co.uk'));
$this->assertEquals('phpvms.co.uk', Utils::getRootDomain('http://www.phpvms.co.uk'));
$this->assertEquals('127.0.0.1', Utils::getRootDomain('http://127.0.0.1'));
$this->assertEquals('localhost', Utils::getRootDomain('http://localhost'));
}
}

View File

@@ -1,4 +1,4 @@
icao,iata,name,location,country,timezone,hub,lat,lon,ground_handling_cost,fuel_100ll_cost,fuel_jeta_cost,fuel_mogas_cost
KAUS,AUS,Austin-Bergstrom,"Austin, Texas, USA", United States,America/Chicago,1,30.1945,-97.6699,0,,,
KSFO,SFO,San Francisco,"San Francisco, California, USA", United States,America/California,1,30.1945,-97.6699,,,0.9,
KJFK,JFK,Kennedy,"Queens, New York, USA", United States,America/New_York,0,30.1945,abcd,150,,0.8,
icao,iata,name,location,country,timezone,hub,lat,lon,ground_handling_cost,fuel_100ll_cost,fuel_jeta_cost,fuel_mogas_cost
KAUS,AUS,Austin-Bergstrom,"Austin, Texas, USA", United States,America/Chicago,1,30.1945,-97.6699,250,0.8,0.8,0.8
KSFO,SFO,San Francisco,"San Francisco, California, USA", United States,America/California,1,30.1945,-97.6699,,,0.9,
KJFK,JFK,Kennedy,"Queens, New York, USA", United States,America/New_York,0,30.1945,abcd,150,,0.8,
1 icao iata name location country timezone hub lat lon ground_handling_cost fuel_100ll_cost fuel_jeta_cost fuel_mogas_cost
2 KAUS AUS Austin-Bergstrom Austin, Texas, USA United States America/Chicago 1 30.1945 -97.6699 0 250 0.8 0.8 0.8
3 KSFO SFO San Francisco San Francisco, California, USA United States America/California 1 30.1945 -97.6699 0.9
4 KJFK JFK Kennedy Queens, New York, USA United States America/New_York 0 30.1945 abcd 150 0.8

View File

@@ -0,0 +1,2 @@
airline,flight_number,route_code,route_leg,dpt_airport,arr_airport,alt_airport,days,dpt_time,arr_time,level,distance,flight_time,flight_type,load_factor, load_factor_variance,pilot_pay,route,notes,active,subfleets,fares,fields
VMS,1972, ,,KAUS,KJFK,KLGA,15,12:00 CST,18:35 EST,350,1477,207,J,85,0,100, ILEXY2 ZENZI LFK ELD J29 MEM Q29 JHW J70 STENT J70 MAGIO J70 LVZ LENDY6,"Just a flight",1,A32X,Y?price=300&cost=100&capacity=130;F?price=600&cost=400;B?,Departure Gate=4;Arrival Gate=C41
1 airline flight_number route_code route_leg dpt_airport arr_airport alt_airport days dpt_time arr_time level distance flight_time flight_type load_factor load_factor_variance pilot_pay route notes active subfleets fares fields
2 VMS 1972 KAUS KJFK KLGA 15 12:00 CST 18:35 EST 350 1477 207 J 85 0 100 ILEXY2 ZENZI LFK ELD J29 MEM Q29 JHW J70 STENT J70 MAGIO J70 LVZ LENDY6 Just a flight 1 A32X Y?price=300&cost=100&capacity=130;F?price=600&cost=400;B? Departure Gate=4;Arrival Gate=C41