Files

109 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Modules\RestaurantDelivery\DTOs;
use Illuminate\Http\Request;
readonly class RiderLocationDTO
{
public function __construct(
public float $latitude,
public float $longitude,
public ?float $speed = null,
public ?float $bearing = null,
public ?float $accuracy = null,
public ?float $altitude = null,
public ?\DateTimeInterface $timestamp = null,
) {}
/**
* Create DTO from request.
*/
public static function fromRequest(Request $request): self
{
return new self(
latitude: (float) $request->input('latitude'),
longitude: (float) $request->input('longitude'),
speed: $request->filled('speed') ? (float) $request->input('speed') : null,
bearing: $request->filled('bearing') ? (float) $request->input('bearing') : null,
accuracy: $request->filled('accuracy') ? (float) $request->input('accuracy') : null,
altitude: $request->filled('altitude') ? (float) $request->input('altitude') : null,
timestamp: $request->filled('timestamp') ? new \DateTime($request->input('timestamp')) : null,
);
}
/**
* Create DTO from array.
*/
public static function fromArray(array $data): self
{
return new self(
latitude: (float) ($data['latitude'] ?? $data['lat'] ?? 0),
longitude: (float) ($data['longitude'] ?? $data['lng'] ?? 0),
speed: isset($data['speed']) ? (float) $data['speed'] : null,
bearing: isset($data['bearing']) ? (float) $data['bearing'] : null,
accuracy: isset($data['accuracy']) ? (float) $data['accuracy'] : null,
altitude: isset($data['altitude']) ? (float) $data['altitude'] : null,
timestamp: isset($data['timestamp']) ? new \DateTime($data['timestamp']) : null,
);
}
/**
* Convert to array.
*/
public function toArray(): array
{
return array_filter([
'latitude' => $this->latitude,
'longitude' => $this->longitude,
'speed' => $this->speed,
'bearing' => $this->bearing,
'accuracy' => $this->accuracy,
'altitude' => $this->altitude,
'timestamp' => $this->timestamp?->format('Y-m-d H:i:s'),
], fn ($value) => $value !== null);
}
/**
* Convert to Firebase format.
*/
public function toFirebaseFormat(): array
{
return [
'lat' => $this->latitude,
'lng' => $this->longitude,
'speed' => $this->speed,
'bearing' => $this->bearing,
'accuracy' => $this->accuracy,
'timestamp' => ($this->timestamp ?? now())->getTimestamp() * 1000, // JavaScript timestamp
];
}
/**
* Check if location is valid.
*/
public function isValid(): bool
{
return $this->latitude >= -90
&& $this->latitude <= 90
&& $this->longitude >= -180
&& $this->longitude <= 180;
}
/**
* Check if accuracy is acceptable.
*/
public function hasAcceptableAccuracy(?float $threshold = null): bool
{
if ($this->accuracy === null) {
return true;
}
$threshold = $threshold ?? config('restaurant-delivery.firebase.location.accuracy_threshold', 50);
return $this->accuracy <= $threshold;
}
}