Compare commits

..

14 Commits

Author SHA1 Message Date
Shift
1f78434b71 Add .shift to open Pull Request 2022-01-28 00:53:11 +00:00
Nabeel Shahzad
723f66a382 More data updates 2022-01-27 13:30:49 -05:00
Nabeel Shahzad
27be992395 Update seeds for a shorter test flight 2022-01-27 12:14:28 -05:00
Sam
6160d57790 Fix docker image name (#1382)
closes #1381
2022-01-11 09:46:53 -05:00
B.Fatih KOZ
7fabd57e13 Fix flight and subfleet import with edited fares (#1379)
* Fix fare import

* StyleFix
2022-01-11 08:17:32 -05:00
B.Fatih KOZ
09453becf8 Award Checks Update (#1376)
Add active/passive check for awards and update the handler to pass only active ones to the process when needed.
2022-01-10 15:49:50 -05:00
B.Fatih KOZ
023313c681 Check settings and filter aircraft list if needed (#1377)
Check settings and filter aircraft list if needed.
2022-01-10 13:29:30 -05:00
B.Fatih KOZ
d3b7d25abd Add ability to export flights of an airline only(#1375)
* Airline Flight Export

Add ability to export flights of an airline only

* StyleFix
2022-01-10 09:27:40 -05:00
B.Fatih KOZ
7799867302 Fix Weather Widget blade (#1372)
Old blade was failing due to missing items in a metar like below

`SVMC 031703Z AUTO NIL`
2022-01-04 14:51:39 -05:00
B.Fatih KOZ
fd7c1b8314 Update RegisterController.php (#1373)
Get only active and displayed UserFields.
2022-01-04 14:29:41 -05:00
B.Fatih KOZ
c12cf0964a Fix setting name (#1371) 2021-12-14 18:10:39 -05:00
Nabeel S
2202d5bf99 Setting for how often the live map updates #1369 (#1370) 2021-12-14 12:48:21 -05:00
B.Fatih KOZ
064682b71f Type Rating update (#1366)
* Update Typerating.php

Add `'active'` to fillable

* Update fields.blade.php

Fixed grid, positioning of checkbox label and removed extra row
2021-12-08 12:40:10 -05:00
Nabeel Shahzad
3c9d419ebb Clarify logs for pirep cancel/updates 2021-12-07 13:24:18 -05:00
29 changed files with 289 additions and 168 deletions

1
.gitignore vendored
View File

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

4
.shift Normal file
View File

@@ -0,0 +1,4 @@
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

@@ -166,6 +166,27 @@ class ImportExport
return [];
}
if (strpos($split_values[0], '?') !== false) {
// This contains the query string, which turns it into a multi-level array
$query_str = explode('?', $split_values[0]);
$parent = trim($query_str[0]);
$children = [];
$kvp = explode('&', trim($query_str[1]));
foreach ($kvp as $items) {
if (!$items) {
continue;
}
$this->kvpToArray($items, $children);
}
$ret[$parent] = $children;
return $ret;
}
// This is not a query string, return it back untouched
return [$split_values[0]];
}

View File

@@ -0,0 +1,15 @@
<?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

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

View File

@@ -34,6 +34,17 @@ airports:
lon: -97.6698889
hub: 1
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
iata: JFK
icao: KJFK
@@ -448,6 +459,21 @@ flights:
- id: flightid_1
airline_id: 1
flight_number: 100
dpt_airport_id: KHPN
arr_airport_id: KJFK
route: DCT CMK V374 DENNA V44 BELTT/N0346F140 V44 DPK DCT
distance: 113
level: 110
dpt_time: 6PM CST
arr_time: 11PM EST
flight_time: 240
flight_type: J
load_factor: 100
created_at: NOW
updated_at: NOW
- id: flightid_2
airline_id: 1
flight_number: 101
dpt_airport_id: KAUS
arr_airport_id: KJFK
route: KAUS SID TNV J87 IAH J2 LCH J22 MEI J239 ATL J52 AJFEB J14 BYJAC Q60 JAXSN J14 COLIN J61 HUBBS J55 SIE STAR KJFK

File diff suppressed because one or more lines are too long

View File

@@ -137,6 +137,13 @@
options: ''
type: int
description: 'Initial zoom level on the map'
- key: acars.update_interval
name: 'Refresh Interval'
group: acars
value: 60
options: ''
type: int
description: 'How often the live map updates its data'
- key: airports.default_ground_handling_cost
name: 'Default Ground Handling Cost'
group: airports

View File

@@ -300,14 +300,18 @@ class FlightController extends Controller
public function export(Request $request)
{
$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);
return response()
->download($path, 'flights.csv', [
'content-type' => 'text/csv',
])
->deleteFileAfterSend(true);
return response()->download($path, $file_name, ['content-type' => 'text/csv'])->deleteFileAfterSend(true);
}
/**

View File

@@ -148,10 +148,10 @@ class AcarsController extends Controller
$pirep = Pirep::find($id);
$this->checkCancelled($pirep);
Log::debug(
/*Log::debug(
'Posting ACARS update (user: '.Auth::user()->ident.', pirep id :'.$id.'): ',
$request->post()
);
);*/
$count = 0;
$positions = $request->post('positions');
@@ -223,7 +223,7 @@ class AcarsController extends Controller
$pirep = Pirep::find($id);
$this->checkCancelled($pirep);
Log::debug('Posting ACARS log, PIREP: '.$id, $request->post());
// Log::debug('Posting ACARS log, PIREP: '.$id, $request->post());
$count = 0;
$logs = $request->post('logs');

View File

@@ -25,6 +25,7 @@ use App\Models\Pirep;
use App\Models\PirepComment;
use App\Models\PirepFare;
use App\Models\PirepFieldValue;
use App\Models\User;
use App\Repositories\JournalRepository;
use App\Repositories\PirepRepository;
use App\Services\Finance\PirepFinanceService;
@@ -235,8 +236,12 @@ class PirepController extends Controller
Log::info('PIREP Update, user '.Auth::id());
Log::info($request->getContent());
/** @var User $user */
$user = Auth::user();
/** @var Pirep $pirep */
$pirep = Pirep::find($pirep_id);
$this->checkCancelled($pirep);
$attrs = $this->parsePirep($request);
@@ -278,6 +283,7 @@ class PirepController extends Controller
{
Log::info('PIREP file, user '.Auth::id(), $request->post());
/** @var User $user */
$user = Auth::user();
// Check if the status is cancelled...
@@ -332,7 +338,7 @@ class PirepController extends Controller
*/
public function cancel($pirep_id, Request $request)
{
Log::info('PIREP Cancel, user '.Auth::id(), $request->post());
Log::info('PIREP '.$pirep_id.' Cancel, user '.Auth::id(), $request->post());
$pirep = Pirep::find($pirep_id);
$this->pirepSvc->cancel($pirep);

View File

@@ -138,7 +138,7 @@ class RegisterController extends Controller
Log::info('User registered: ', $user->toArray());
$userFields = UserField::all();
$userFields = UserField::where(['show_on_registration' => true, 'active' => true])->get();
foreach ($userFields as $field) {
$field_name = 'field_'.$field->slug;
UserFieldValue::updateOrCreate([

View File

@@ -91,8 +91,12 @@ class PirepController extends Controller
*/
public function aircraftList($add_blank = false)
{
$user = Auth::user();
$user_loc = filled($user->curr_airport_id) ? $user->curr_airport_id : $user->home_airport_id;
$location_check = setting('pireps.only_aircraft_at_dpt_airport', false);
$aircraft = [];
$subfleets = $this->userSvc->getAllowableSubfleets(Auth::user());
$subfleets = $this->userSvc->getAllowableSubfleets($user);
if ($add_blank) {
$aircraft[''] = '';
@@ -100,7 +104,9 @@ class PirepController extends Controller
foreach ($subfleets as $subfleet) {
$tmp = [];
foreach ($subfleet->aircraft as $ac) {
foreach ($subfleet->aircraft->when($location_check, function ($query) use ($user_loc) {
return $query->where('airport_id', $user_loc);
}) as $ac) {
$tmp[$ac->id] = $ac['name'].' - '.$ac['registration'];
}

View File

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

View File

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

View File

@@ -13,6 +13,7 @@ class Typerating extends Model
'type',
'description',
'image_url',
'active',
];
// Validation

View File

@@ -253,8 +253,9 @@ class FlightImporter extends ImportExport
$fare_attributes = [];
}
$fare = Fare::updateOrCreate(['code' => $fare_code], ['name' => $fare_code]);
$fare = Fare::firstOrCreate(['code' => $fare_code], ['name' => $fare_code]);
$this->fareSvc->setForFlight($flight, $fare, $fare_attributes);
$fare->save();
}
}

View File

@@ -84,8 +84,9 @@ class SubfleetImporter extends ImportExport
$fare_attributes = [];
}
$fare = Fare::updateOrCreate(['code' => $fare_code], ['name' => $fare_code]);
$fare = Fare::firstOrCreate(['code' => $fare_code], ['name' => $fare_code]);
$this->fareSvc->setForSubfleet($subfleet, $fare, $fare_attributes);
$fare->save();
}
}
}

View File

@@ -134,6 +134,11 @@ class Database
->where($id_col, $row[$id_col])
->update($row);
} else {
// Remove ID column if it exists and its empty, let the DB set it
/*if (array_key_exists($id_col, $row) && empty($row[$id_col])) {
unset($row[$id_col]);
}*/
DB::table($table)->insert($row);
}
} catch (QueryException $e) {

View File

@@ -2,7 +2,7 @@
version: '3'
services:
app:
image: phpvms:latest
image: nabeelio/phpvms
environment:
DB_HOST: mysql
REDIS_HOST: redis

16
package-lock.json generated
View File

@@ -1,5 +1,5 @@
{
"name": "npm-proj-1638580747126-0.26275087051876245RtoWoC",
"name": "phpvms",
"lockfileVersion": 2,
"requires": true,
"packages": {
@@ -12,7 +12,7 @@
"bootstrap": "~4.3",
"bootstrap-sass": "^3.4.1",
"bootstrap3": "npm:bootstrap@~3.4",
"ckeditor4": "^4.15.1",
"ckeditor4": "4.14.0",
"cookieconsent": "^3.1.0",
"cross-env": "^5.1.6",
"eonasdan-bootstrap-datetimepicker": "^4.17.47",
@@ -3030,9 +3030,9 @@
}
},
"node_modules/ckeditor4": {
"version": "4.15.1",
"resolved": "https://registry.npmjs.org/ckeditor4/-/ckeditor4-4.15.1.tgz",
"integrity": "sha512-t2q61VG2h0i5DwZ+G3jTesrBSGnhNK0iKVdSzLBKx40PQzcDUDZOWJbMlpbAOuMzAAS096x5J2H4u/IyQRl1vQ=="
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/ckeditor4/-/ckeditor4-4.14.0.tgz",
"integrity": "sha512-g5p3bhbxbwB094bE7ss0rOyvG/azYdRjLTyngnPM2+fKZhnPrMVaFDx3SiiWKB+zyvndT3Deu54VTv/z2MQJCA=="
},
"node_modules/class-utils": {
"version": "0.3.6",
@@ -16466,9 +16466,9 @@
}
},
"ckeditor4": {
"version": "4.15.1",
"resolved": "https://registry.npmjs.org/ckeditor4/-/ckeditor4-4.15.1.tgz",
"integrity": "sha512-t2q61VG2h0i5DwZ+G3jTesrBSGnhNK0iKVdSzLBKx40PQzcDUDZOWJbMlpbAOuMzAAS096x5J2H4u/IyQRl1vQ=="
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/ckeditor4/-/ckeditor4-4.14.0.tgz",
"integrity": "sha512-g5p3bhbxbwB094bE7ss0rOyvG/azYdRjLTyngnPM2+fKZhnPrMVaFDx3SiiWKB+zyvndT3Deu54VTv/z2MQJCA=="
},
"class-utils": {
"version": "0.3.6",

View File

@@ -17,7 +17,7 @@
"bootstrap": "~4.3",
"bootstrap-sass": "^3.4.1",
"bootstrap3": "npm:bootstrap@~3.4",
"ckeditor4": "4.15.1",
"ckeditor4": "4.14.0",
"cookieconsent": "^3.1.0",
"cross-env": "^5.1.6",
"eonasdan-bootstrap-datetimepicker": "^4.17.47",

View File

@@ -1,5 +1,5 @@
@extends('admin.app')
@section('title', "Edit \"$award->title\" Award")
@section('title', "Edit \"$award->name\" Award")
@section('content')
<div class="card border-blue-bottom">
<div class="content">

View File

@@ -18,17 +18,13 @@
<p class="text-danger">{{ $errors->first('name') }}</p>
</div>
<div class="form-group col-sm-6">
{!! Form::label('image', 'Image:') !!}
<div class="callout callout-info">
<i class="icon fa fa-info">&nbsp;&nbsp;</i>
This is the image of the award. Be creative!
</div>
{!! Form::text('image_url', null, [
'class' => 'form-control',
'placeholder' => 'Enter the url of the image location'
]) !!}
{!! Form::text('image_url', null, ['class' => 'form-control', 'placeholder' => 'Enter the url of the image location']) !!}
<p class="text-danger">{{ $errors->first('image_url') }}</p>
</div>
</div>
@@ -47,29 +43,31 @@
<div class="form-group col-sm-6">
<div>
{{ Form::label('ref_model', 'Award Class:') }}
{{ Form::select('ref_model', $award_classes, null , [
'class' => 'form-control select2',
'id' => 'award_class_select',
]) }}
{{ Form::select('ref_model', $award_classes, null, ['class' => 'form-control select2', 'id' => 'award_class_select']) }}
<p class="text-danger">{{ $errors->first('ref_model') }}</p>
</div>
<div>
{{ Form::label('ref_model_params', 'Award Class parameters') }}
{{ Form::text('ref_model_params', null, ['class' => 'form-control']) }}
<p class="text-danger">{{ $errors->first('ref_model_params') }}</p>
<p id="ref_model_param_description">
</p>
<p id="ref_model_param_description"></p>
</div>
</div>
</div>
<div class="row">
<!-- Submit Field -->
<div class="form-group col-sm-12">
{{-- Active/Deactive Checkbox --}}
<div class="form-group col-sm-6 text-left">
<div class="checkbox">
<label class="checkbox-inline">
{{ Form::label('active', 'Active: ') }}
{{ Form::hidden('active', false) }}
{{ Form::checkbox('active') }}
</label>
</div>
</div>
{{-- Form Actions --}}
<div class="form-group col-sm-6">
<div class="pull-right">
{!! Form::button('Save', ['type' => 'submit', 'class' => 'btn btn-success']) !!}
<a href="{!! route('admin.awards.index') !!}" class="btn btn-warn">Cancel</a>

View File

@@ -1,40 +1,47 @@
<table class="table table-hover table-responsive" id="awards-table">
<thead>
<th>Name</th>
<th>Description</th>
<th>Image</th>
<th class="text-right">Action</th>
<th>Name</th>
<th>Description</th>
<th>Image</th>
<th class="text-center">Active</th>
<th class="text-right">Action</th>
</thead>
<tbody>
@foreach($awards as $award)
<tr>
<td>
<a href="{{ route('admin.awards.edit', [$award->id]) }}">
{{ $award->name }}</a>
</td>
<td>{{ $award->description }}</td>
<td>
@if($award->image_url)
<img src="{{ $award->image_url }}" name="{{ $award->name }}" alt="No Image Available" style="height: 100px"/>
@else
-
@endif
</td>
<td class="text-right">
{{ Form::open(['route' => ['admin.awards.destroy', $award->id], 'method' => 'delete']) }}
<a href="{{ route('admin.awards.edit', [$award->id]) }}" class='btn btn-sm btn-success btn-icon'>
<i class="fas fa-pencil-alt"></i></a>
{{ Form::button('<i class="fa fa-times"></i>', [
'type' => 'submit',
'class' => 'btn btn-sm btn-danger btn-icon',
'onclick' => "return confirm('Are you sure you want to delete this award?')"
]) }}
{{ Form::close() }}
</td>
</tr>
@endforeach
@foreach($awards->sortby('name', SORT_NATURAL) as $award)
<tr>
<td>
<a href="{{ route('admin.awards.edit', [$award->id]) }}">{{ $award->name }}</a>
</td>
<td>
{{ $award->description }}
</td>
<td>
@if($award->image_url)
<img src="{{ $award->image_url }}" name="{{ $award->name }}" alt="No Image Available" style="height: 100px"/>
@else
-
@endif
</td>
<td class="text-center">
@if($award->active)
<i class="fas fa-check-circle fa-2x text-success"></i>
@else
<i class="fas fa-times-circle fa-2x text-danger"></i>
@endif
</td>
<td class="text-right">
{{ Form::open(['route' => ['admin.awards.destroy', $award->id], 'method' => 'delete']) }}
<a href="{{ route('admin.awards.edit', [$award->id]) }}" class='btn btn-sm btn-success btn-icon'>
<i class="fas fa-pencil-alt"></i>
</a>
{{ Form::button('<i class="fa fa-times"></i>', [
'type' => 'submit',
'class' => 'btn btn-sm btn-danger btn-icon',
'onclick' => "return confirm('Are you sure you want to delete this award?')"
]) }}
{{ Form::close() }}
</td>
</tr>
@endforeach
</tbody>
</table>
</table>

View File

@@ -2,8 +2,15 @@
@section('title', 'Flights')
@section('actions')
<li><a href="{{ route('admin.flights.export') }}"><i class="ti-plus"></i>Export to CSV</a></li>
<li><a href="{{ route('admin.flights.import') }}"><i class="ti-plus"></i>Import from CSV</a></li>
<li>
<a href="{{ route('admin.flights.export') }}@if(request()->get('airline_id')){{ '?airline_id='.request()->get('airline_id') }}@endif">
<i class="ti-plus"></i>
Export to CSV @if(request()->get('airline_id')) (Selected Airline) @endif
</a>
</li>
<li>
<a href="{{ route('admin.flights.import') }}"><i class="ti-plus"></i>Import from CSV</a>
</li>
<li>
<a href="{{ route('admin.flights.create') }}">
<i class="ti-plus"></i>

View File

@@ -1,10 +1,10 @@
<div class="row">
<div class="form-group col-sm-6">
<div class="form-group col-sm-7">
{{ Form::label('name', 'Name:') }}
{{ Form::text('name', null, ['class' => 'form-control']) }}
<p class="text-danger">{{ $errors->first('name') }}</p>
</div>
<div class="form-group col-sm-6">
<div class="form-group col-sm-5">
{{ Form::label('type', 'Type Code:') }}
{{ Form::text('type', null, ['class' => 'form-control']) }}
<p class="text-danger">{{ $errors->first('type') }}</p>
@@ -12,12 +12,12 @@
</div>
<div class="row">
<div class="form-group col-md-7">
<div class="form-group col-sm-7">
{{ Form::label('description', 'Description:') }}
{{ Form::text('description', null, ['class' => 'form-control']) }}
<p class="text-danger">{{ $errors->first('description') }}</p>
</div>
<div class="form-group col-md-5">
<div class="form-group col-sm-5">
{{ Form::label('image_url', 'Image Link:') }}
{{ Form::text('image_url', null, ['class' => 'form-control']) }}
<p class="text-danger">{{ $errors->first('image_url') }}</p>
@@ -25,19 +25,16 @@
</div>
<div class="row">
<div class="form-group col-md-3">
<div class="form-group col-sm-3">
<div class="checkbox">
<label class="checkbox-inline">
{{ Form::label('active', 'Active:') }}
{{ Form::hidden('active', false) }}
{{ Form::checkbox('active') }}
{{ Form::label('active', 'Active:') }}
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="col-sm-9">
<div class="text-right">
{{ Form::button('Save', ['type' => 'submit', 'class' => 'btn btn-success']) }}
</div>

View File

@@ -114,6 +114,7 @@ and being mindful of the rivets bindings
center: ['{{ $center[0] }}', '{{ $center[1] }}'],
zoom: '{{ $zoom }}',
aircraft_icon: '{!! public_asset('/assets/img/acars/aircraft.png') !!}',
refresh_interval: {{ setting('acars.update_interval', 60) }},
units: '{{ setting('units.distance') }}',
leafletOptions: {
scrollWheelZoom: false,

View File

@@ -14,7 +14,7 @@ https://api.checkwx.com/#metar-decoded
<td>@lang('widgets.weather.wind')</td>
<td>
@if($metar['wind_speed'] < '1') Calm @else {{ $metar['wind_speed'] }} kts @lang('common.from') {{ $metar['wind_direction_label'] }} ({{ $metar['wind_direction']}}&deg;) @endif
@if($metar['wind_gust_speed']) @lang('widgets.weather.guststo') {{ $metar['wind_gust_speed'] }} @endif
@if($metar['wind_gust_speed']) @lang('widgets.weather.guststo') {{ $metar['wind_gust_speed'] }} @endif
</td>
</tr>
@if($metar['visibility'])
@@ -24,58 +24,62 @@ https://api.checkwx.com/#metar-decoded
</tr>
@endif
@if($metar['runways_visual_range'])
<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>
@endif
@if($metar['present_weather_report'] <> 'Dry')
<tr>
<td>Phenomena</td>
<td>{{ $metar['present_weather_report'] }}</td>
</tr>
@endif
<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>
@endif
@if($metar['present_weather_report'] && $metar['present_weather_report'] <> 'Dry')
<tr>
<td>Phenomena</td>
<td>{{ $metar['present_weather_report'] }}</td>
</tr>
@endif
@if($metar['clouds'] || $metar['cavok'])
<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>
@endif
<tr>
<td>@lang('widgets.weather.temp')</td>
<td>
@if($metar['temperature'][$unit_temp]) {{ $metar['temperature'][$unit_temp] }} @else 0 @endif &deg;{{strtoupper($unit_temp)}}
@if($metar['dew_point']), @lang('widgets.weather.dewpoint') @if($metar['dew_point'][$unit_temp]) {{ $metar['dew_point'][$unit_temp] }} @else 0 @endif &deg;{{strtoupper($unit_temp)}} @endif
@if($metar['humidity']), @lang('widgets.weather.humidity') {{ $metar['humidity'] }}% @endif
</td>
</tr>
<tr>
<td>@lang('widgets.weather.barometer')</td>
<td>{{ number_format($metar['barometer']['hPa']) }} hPa / {{ number_format($metar['barometer']['inHg'], 2) }} inHg</td>
</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>
@endif
@if($metar['temperature'])
<tr>
<td>@lang('widgets.weather.temp')</td>
<td>
@if($metar['temperature'][$unit_temp]) {{ $metar['temperature'][$unit_temp] }} @else 0 @endif &deg;{{strtoupper($unit_temp)}}
@if($metar['dew_point']), @lang('widgets.weather.dewpoint') @if($metar['dew_point'][$unit_temp]) {{ $metar['dew_point'][$unit_temp] }} @else 0 @endif &deg;{{strtoupper($unit_temp)}} @endif
@if($metar['humidity']), @lang('widgets.weather.humidity') {{ $metar['humidity'] }}% @endif
</td>
</tr>
@endif
@if($metar['barometer'])
<tr>
<td>@lang('widgets.weather.barometer')</td>
<td>{{ number_format($metar['barometer']['hPa']) }} hPa / {{ number_format($metar['barometer']['inHg'], 2) }} inHg</td>
</tr>
@endif
@if($metar['recent_weather_report'])
<tr>
<td>Recent Phenomena</td>
<td>{{ $metar['recent_weather_report'] }}</td>
</tr>
@endif
@if($metar['runways_report'])
<tr>
<td>Runway Condition</td>
<td>
@foreach($metar['runways_report'] as $runway)
<b>RWY{{ $runway['runway'] }}</b>; {{ $runway['report'] }}<br>
@endforeach
</td>
</tr>
@endif
<tr>
<td>Recent Phenomena</td>
<td>{{ $metar['recent_weather_report'] }}</td>
</tr>
@endif
@if($metar['runways_report'])
<tr>
<td>Runway Condition</td>
<td>
@foreach($metar['runways_report'] as $runway)
<b>RWY{{ $runway['runway'] }}</b>; {{ $runway['report'] }}<br>
@endforeach
</td>
</tr>
@endif
@if($metar['remarks'])
<tr>
<td>@lang('widgets.weather.remarks')</td>