api fixes/updates
This commit is contained in:
parent
50abda71cb
commit
b96f1cd7c4
@ -29,6 +29,7 @@ class CreateAcarsTables extends Migration
|
||||
$table->unsignedInteger('gs')->nullable();
|
||||
$table->unsignedInteger('transponder')->nullable();
|
||||
$table->string('autopilot')->nullable();
|
||||
$table->decimal('fuel')->nullable();
|
||||
$table->decimal('fuel_flow')->nullable();
|
||||
$table->string('sim_time')->nullable();
|
||||
|
||||
|
1075
app/Database/seeds/in_progress.yml
Normal file
1075
app/Database/seeds/in_progress.yml
Normal file
File diff suppressed because it is too large
Load Diff
@ -240,7 +240,8 @@ class PirepController extends Controller
|
||||
*/
|
||||
public function update($id, UpdateRequest $request)
|
||||
{
|
||||
Log::info('PIREP Update, user '.Auth::id(), $request->post());
|
||||
Log::info('PIREP Update, user '.Auth::id());
|
||||
Log::info($request->getContent());
|
||||
|
||||
$user = Auth::user();
|
||||
$pirep = Pirep::find($id);
|
||||
|
@ -26,12 +26,13 @@ class PositionRequest extends FormRequest
|
||||
'positions.*.lat' => 'required|numeric',
|
||||
'positions.*.lon' => 'required|numeric',
|
||||
'positions.*.altitude' => 'nullable|numeric',
|
||||
'positions.*.heading' => 'nullable|integer|between:0,360',
|
||||
'positions.*.heading' => 'nullable|numeric|between:0,360',
|
||||
'positions.*.vs' => 'nullable',
|
||||
'positions.*.gs' => 'nullable',
|
||||
'positions.*.transponder' => 'nullable',
|
||||
'positions.*.autopilot' => 'nullable',
|
||||
'positions.*.fuel_flow' => 'nullable',
|
||||
'positions.*.fuel' => 'nullable|numeric',
|
||||
'positions.*.fuel_flow' => 'nullable|numeric',
|
||||
'positions.*.log' => 'nullable',
|
||||
'positions.*.created_at' => 'nullable|date',
|
||||
];
|
||||
|
@ -43,9 +43,9 @@ class UpdateRequest extends FormRequest
|
||||
'notes' => 'nullable',
|
||||
'source_name' => 'nullable|max:25',
|
||||
'landing_rate' => 'nullable|numeric',
|
||||
'block_off_time' => 'nullable|date',
|
||||
'block_on_time' => 'nullable|date',
|
||||
'created_at' => 'nullable|date',
|
||||
'block_off_time' => 'nullable',
|
||||
'block_on_time' => 'nullable',
|
||||
'created_at' => 'nullable',
|
||||
'status' => 'nullable',
|
||||
'score' => 'nullable|integer',
|
||||
|
||||
|
@ -33,6 +33,8 @@ use PhpUnitsOfMeasure\Exception\NonStringUnitName;
|
||||
* @property integer block_time
|
||||
* @property integer flight_time In minutes
|
||||
* @property integer planned_flight_time
|
||||
* @property mixed planned_distance
|
||||
* @property mixed distance
|
||||
* @property integer score
|
||||
* @property User user
|
||||
* @property Flight|null flight
|
||||
@ -105,11 +107,20 @@ class Pirep extends Model
|
||||
'score' => 'integer',
|
||||
'source' => 'integer',
|
||||
'state' => 'integer',
|
||||
'block_off_time' => 'datetime',
|
||||
'block_on_time' => 'datetime',
|
||||
'submitted_at' => 'datetime',
|
||||
#'block_off_time' => 'datetime',
|
||||
#'block_on_time' => 'datetime',
|
||||
#'submitted_at' => 'datetime',
|
||||
];
|
||||
|
||||
/*protected $dates = [
|
||||
'block_off_time',
|
||||
'block_on_time',
|
||||
'submitted_at',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at'
|
||||
];*/
|
||||
|
||||
public static $rules = [
|
||||
'airline_id' => 'required|exists:airlines,id',
|
||||
'aircraft_id' => 'required|exists:aircraft,id',
|
||||
@ -140,6 +151,24 @@ class Pirep extends Model
|
||||
return $flight_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block off time in carbon format
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getBlockOffTimeAttribute()
|
||||
{
|
||||
return new Carbon($this->attributes['block_off_time']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block on time
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getBlockOnTimeAttribute()
|
||||
{
|
||||
return new Carbon($this->attributes['block_on_time']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new Length unit so conversions can be made
|
||||
* @return int|Distance
|
||||
@ -236,16 +265,16 @@ class Pirep extends Model
|
||||
*/
|
||||
public function getProgressPercentAttribute()
|
||||
{
|
||||
$upper_bound = $this->flight_time;
|
||||
if($this->planned_flight_time) {
|
||||
$upper_bound = $this->planned_flight_time;
|
||||
$upper_bound = $this->distance['nmi'];
|
||||
if($this->planned_distance) {
|
||||
$upper_bound = $this->planned_distance['nmi'];
|
||||
}
|
||||
|
||||
if(!$upper_bound) {
|
||||
$upper_bound = 1;
|
||||
}
|
||||
|
||||
return round(($this->flight_time / $upper_bound) * 100, 0);
|
||||
return round(($this->distance['nmi'] / $upper_bound) * 100, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@ use App\Models\Setting;
|
||||
use App\Models\Subfleet;
|
||||
use App\Repositories\SettingRepository;
|
||||
use App\Services\ModuleService;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use View;
|
||||
@ -27,6 +28,11 @@ class AppServiceProvider extends ServiceProvider
|
||||
public function boot(): void
|
||||
{
|
||||
Schema::defaultStringLength(191);
|
||||
|
||||
Carbon::serializeUsing(function ($carbon) {
|
||||
return $carbon->format('U');
|
||||
});
|
||||
|
||||
$this->app->bind('setting', SettingRepository::class);
|
||||
|
||||
View::share('moduleSvc', app(ModuleService::class));
|
||||
@ -39,6 +45,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
PirepField::observe(PirepFieldObserver::class);
|
||||
Setting::observe(SettingObserver::class);
|
||||
Subfleet::observe(SubfleetObserver::class);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10838,246 +10838,6 @@ button.close {
|
||||
.select2-container--classic.select2-container--open .select2-dropdown {
|
||||
border-color: #5897fb; }
|
||||
|
||||
@charset "UTF-8";
|
||||
|
||||
/*!
|
||||
* Pikaday
|
||||
* Copyright © 2014 David Bushell | BSD & MIT license | http://dbushell.com/
|
||||
*/
|
||||
|
||||
.pika-single {
|
||||
z-index: 9999;
|
||||
display: block;
|
||||
position: relative;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-bottom-color: #bbb;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
/*
|
||||
clear child float (pika-lendar), using the famous micro clearfix hack
|
||||
http://nicolasgallagher.com/micro-clearfix-hack/
|
||||
*/
|
||||
.pika-single:before,
|
||||
.pika-single:after {
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
.pika-single:after { clear: both }
|
||||
.pika-single { *zoom: 1 }
|
||||
|
||||
.pika-single.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pika-single.is-bound {
|
||||
position: absolute;
|
||||
box-shadow: 0 5px 15px -5px rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
.pika-lendar {
|
||||
float: left;
|
||||
width: 240px;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.pika-title {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pika-label {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
position: relative;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 5px 3px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-weight: bold;
|
||||
background-color: #fff;
|
||||
}
|
||||
.pika-title select {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
z-index: 9998;
|
||||
margin: 0;
|
||||
left: 0;
|
||||
top: 5px;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.pika-prev,
|
||||
.pika-next {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
outline: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 30px;
|
||||
/* hide text using text-indent trick, using width value (it's enough) */
|
||||
text-indent: 20px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 75% 75%;
|
||||
opacity: .5;
|
||||
*position: absolute;
|
||||
*top: 0;
|
||||
}
|
||||
|
||||
.pika-prev:hover,
|
||||
.pika-next:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.pika-prev,
|
||||
.is-rtl .pika-next {
|
||||
float: left;
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==');
|
||||
*left: 0;
|
||||
}
|
||||
|
||||
.pika-next,
|
||||
.is-rtl .pika-prev {
|
||||
float: right;
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=');
|
||||
*right: 0;
|
||||
}
|
||||
|
||||
.pika-prev.is-disabled,
|
||||
.pika-next.is-disabled {
|
||||
cursor: default;
|
||||
opacity: .2;
|
||||
}
|
||||
|
||||
.pika-select {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
}
|
||||
|
||||
.pika-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.pika-table th,
|
||||
.pika-table td {
|
||||
width: 14.285714285714286%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.pika-table th {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
line-height: 25px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pika-button {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
outline: none;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
line-height: 15px;
|
||||
text-align: right;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.pika-week {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.is-today .pika-button {
|
||||
color: #33aaff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.is-selected .pika-button,
|
||||
.has-event .pika-button {
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
background: #33aaff;
|
||||
box-shadow: inset 0 1px 3px #178fe5;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.has-event .pika-button {
|
||||
background: #005da9;
|
||||
box-shadow: inset 0 1px 3px #0076c9;
|
||||
}
|
||||
|
||||
.is-disabled .pika-button,
|
||||
.is-inrange .pika-button {
|
||||
background: #D5E9F7;
|
||||
}
|
||||
|
||||
.is-startrange .pika-button {
|
||||
color: #fff;
|
||||
background: #6CB31D;
|
||||
box-shadow: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.is-endrange .pika-button {
|
||||
color: #fff;
|
||||
background: #33aaff;
|
||||
box-shadow: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.is-disabled .pika-button {
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
color: #999;
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
.is-outside-current-month .pika-button {
|
||||
color: #999;
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
.is-selection-disabled {
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.pika-button:hover,
|
||||
.pika-row.pick-whole-week:hover .pika-button {
|
||||
color: #fff;
|
||||
background: #ff8000;
|
||||
box-shadow: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* styling for abbr */
|
||||
.pika-table abbr {
|
||||
border-bottom: none;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
|
||||
/*! X-editable - v1.5.1
|
||||
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
|
||||
* http://github.com/vitalets/x-editable
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,16 +1,16 @@
|
||||
{
|
||||
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=3d5b0dff38050f6b5e0b",
|
||||
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=cd886ba18357a1c96ec0",
|
||||
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=b0a0f05b94a4486db4f2",
|
||||
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=cc80aec3cf1646f83d8d",
|
||||
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=926a7c24ec36533523e3",
|
||||
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=559d5e8e5d6ecc64a3af",
|
||||
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=c65781eda730445d666e",
|
||||
"/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d",
|
||||
"/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d",
|
||||
"/assets/admin/img/clear.png": "/assets/admin/img/clear.png?id=0e92f4c3efc6988a3c96",
|
||||
"/assets/admin/img/loading.gif": "/assets/admin/img/loading.gif?id=90a4b76b4f11558691f6",
|
||||
"/assets/global/js/jquery.js": "/assets/global/js/jquery.js?id=6a07da9fae934baf3f74",
|
||||
"/assets/admin/css/vendor.css": "/assets/admin/css/vendor.css?id=99aedbd62dfa118e7b73",
|
||||
"/assets/admin/js/vendor.js": "/assets/admin/js/vendor.js?id=5130233c88c71fc60135",
|
||||
"/assets/admin/css/vendor.css": "/assets/admin/css/vendor.css?id=d4c03403265f42272050",
|
||||
"/assets/admin/js/vendor.js": "/assets/admin/js/vendor.js?id=aa7db4bedfe23409f625",
|
||||
"/assets/admin/css/blue.png": "/assets/admin/css/blue.png?id=753a3c0dec86d3a38d9c",
|
||||
"/assets/admin/css/blue@2x.png": "/assets/admin/css/blue@2x.png?id=97da23d47b838cbd4bef",
|
||||
"/assets/global/js/vendor.js": "/assets/global/js/vendor.js?id=6436d215691e8f38eb12",
|
||||
|
@ -1,14 +1,9 @@
|
||||
|
||||
const leaflet = require('leaflet');
|
||||
|
||||
import draw_base_map from './base_map'
|
||||
import {addWMSLayer} from './helpers';
|
||||
|
||||
import {
|
||||
ACTUAL_ROUTE_COLOR,
|
||||
PLAN_ROUTE_COLOR,
|
||||
CIRCLE_COLOR
|
||||
} from './config'
|
||||
import {ACTUAL_ROUTE_COLOR, CIRCLE_COLOR, PLAN_ROUTE_COLOR} from './config'
|
||||
|
||||
/**
|
||||
* Show some popup text when a feature is clicked on
|
||||
@ -49,20 +44,28 @@ export const pointToLayer = (feature, latlng) => {
|
||||
export default (opts) => {
|
||||
|
||||
opts = Object.assign({
|
||||
|
||||
route_points: null,
|
||||
planned_route_line: null,
|
||||
actual_route_points: null,
|
||||
actual_route_line: null,
|
||||
render_elem: 'map',
|
||||
live_map: false,
|
||||
aircraft_icon: '/assets/img/acars/aircraft.png',
|
||||
metar_wms: {
|
||||
url: '',
|
||||
params: {}
|
||||
},
|
||||
}, opts);
|
||||
|
||||
console.log(opts);
|
||||
const aircraftIcon = leaflet.icon({
|
||||
iconUrl: opts.aircraft_icon,
|
||||
iconSize: [42, 42],
|
||||
iconAnchor: [21, 21],
|
||||
});
|
||||
|
||||
let map = draw_base_map(opts);
|
||||
let layerLiveFlight;
|
||||
|
||||
if (opts.metar_wms.url !== '') {
|
||||
addWMSLayer(map, opts.metar_wms);
|
||||
@ -134,4 +137,31 @@ export default (opts) => {
|
||||
|
||||
route_points.addTo(map)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const liveFlight = () => {
|
||||
const uri = opts.pirep_uri;
|
||||
const live_route = $.ajax({
|
||||
url: uri,
|
||||
dataType: 'json',
|
||||
error: console.log
|
||||
});
|
||||
|
||||
$.when(live_route).done((routeJson) => {
|
||||
layerLiveFlight = leaflet.geoJSON(routeJson, {
|
||||
pointToLayer: function (feature, latlon) {
|
||||
return leaflet.marker(latlon, {
|
||||
icon: aircraftIcon,
|
||||
rotationAngle: feature.properties.heading
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
layerLiveFlight.addTo(map)
|
||||
});
|
||||
};
|
||||
|
||||
setInterval(liveFlight, 10000);
|
||||
};
|
||||
|
@ -9,10 +9,12 @@
|
||||
@section('scripts')
|
||||
<script type="text/javascript">
|
||||
phpvms.map.render_route_map({
|
||||
pirep_uri: '{!! url('/api/pireps/'.$pirep->id.'/acars/geojson') !!}',
|
||||
route_points: {!! json_encode($map_features['planned_rte_points']) !!},
|
||||
planned_route_line: {!! json_encode($map_features['planned_rte_line']) !!},
|
||||
actual_route_line: {!! json_encode($map_features['actual_route_line']) !!},
|
||||
actual_route_points: {!! json_encode($map_features['actual_route_points']) !!},
|
||||
aircraft_icon: '{!! public_asset('/assets/img/acars/aircraft.png') !!}',
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
@ -9,7 +9,13 @@
|
||||
<div class="col-12">
|
||||
<p>
|
||||
<h2 style="margin-bottom: 5px;">{{$pirep->airline->code}}{{ $pirep->ident }}</h2>
|
||||
<p>Arrived {{$pirep->created_at->diffForHumans()}}</p>
|
||||
<p>
|
||||
@if($pirep->state === PirepState::IN_PROGRESS)
|
||||
|
||||
@else
|
||||
Arrived {{$pirep->created_at->diffForHumans()}}
|
||||
@endif
|
||||
</p>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@ -55,8 +61,10 @@
|
||||
<div class="progress" style="margin: 20px 0;">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar"
|
||||
aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"
|
||||
style="width: {{$pirep->progress_percent}}%">
|
||||
style="width: {{$pirep->progress_percent}}%;">
|
||||
{{--<p style="padding: 10px">
|
||||
{{ Utils::minutesToTimeString($pirep->flight_time) }}
|
||||
</p>--}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -78,8 +86,8 @@
|
||||
<div class="col-4">
|
||||
|
||||
<h2> </h2>
|
||||
<table class="table table-hover table-condensed">
|
||||
<tr>
|
||||
<table class="table table-striped">
|
||||
{{--<tr>
|
||||
<td width="30%">Status</td>
|
||||
<td>
|
||||
@php
|
||||
@ -96,6 +104,15 @@
|
||||
{{ PirepState::label($pirep->state) }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>--}}
|
||||
|
||||
<tr>
|
||||
<td width="30%">State</td>
|
||||
<td>
|
||||
<div class="badge badge-info">
|
||||
{{ PirepStatus::label($pirep->status) }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -16,9 +16,10 @@
|
||||
<table class="table">
|
||||
@foreach($pireps as $pirep)
|
||||
<tr>
|
||||
<td>{{ $pirep->ident }}</td>
|
||||
<td>{{ $pirep->airline->code }}{{ $pirep->ident }}</td>
|
||||
<td>{{ $pirep->dpt_airport_id }}</td>
|
||||
<td>{{ $pirep->arr_airport_id }}</td>
|
||||
<td>{{ $pirep->aircraft->name }}</td>
|
||||
<td>
|
||||
{{ PirepStatus::label($pirep->status) }}
|
||||
</td>
|
||||
|
@ -9,8 +9,8 @@ class UtilsTest extends TestCase
|
||||
|
||||
public function testDates()
|
||||
{
|
||||
$carbon = new \Carbon\Carbon('2018-03-18 00:20:43');
|
||||
//echo $carbon;
|
||||
$carbon = new \Carbon\Carbon('2018-04-28T12:55:40Z');
|
||||
$this->assertNotNull($carbon);
|
||||
}
|
||||
|
||||
public function testSecondsToTimeParts()
|
||||
|
Loading…
Reference in New Issue
Block a user