mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
115 lines
3.2 KiB
PHP
115 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
|
|
class Playlist extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
protected $guarded = ['id'];
|
|
|
|
protected $casts = [
|
|
'is_active' => 'boolean',
|
|
'weekdays' => 'array',
|
|
'active_from' => 'datetime:H:i',
|
|
'active_until' => 'datetime:H:i',
|
|
'refresh_time' => 'integer',
|
|
];
|
|
|
|
public function device(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Device::class);
|
|
}
|
|
|
|
public function items(): HasMany
|
|
{
|
|
return $this->hasMany(PlaylistItem::class);
|
|
}
|
|
|
|
public function isActiveNow(): bool
|
|
{
|
|
if (! $this->is_active) {
|
|
return false;
|
|
}
|
|
|
|
// Get user's timezone or fall back to app timezone
|
|
$timezone = $this->device->user->timezone ?? config('app.timezone');
|
|
$now = now($timezone);
|
|
|
|
// Check weekday (using timezone-aware time)
|
|
if ($this->weekdays !== null && ! in_array($now->dayOfWeek, $this->weekdays)) {
|
|
return false;
|
|
}
|
|
|
|
if ($this->active_from !== null && $this->active_until !== null) {
|
|
// Create timezone-aware datetime objects for active_from and active_until
|
|
$activeFrom = $now->copy()
|
|
->setTimeFrom($this->active_from)
|
|
->timezone($timezone);
|
|
|
|
$activeUntil = $now->copy()
|
|
->setTimeFrom($this->active_until)
|
|
->timezone($timezone);
|
|
|
|
// Handle time ranges that span across midnight
|
|
if ($activeFrom > $activeUntil) {
|
|
// Time range spans midnight (e.g., 09:01 to 03:58)
|
|
if ($now >= $activeFrom || $now <= $activeUntil) {
|
|
return true;
|
|
}
|
|
} elseif ($now >= $activeFrom && $now <= $activeUntil) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getNextPlaylistItem(): ?PlaylistItem
|
|
{
|
|
if (! $this->isActiveNow()) {
|
|
return null;
|
|
}
|
|
|
|
// Get active playlist items ordered by display order
|
|
/** @var \Illuminate\Support\Collection|PlaylistItem[] $playlistItems */
|
|
$playlistItems = $this->items()
|
|
->where('is_active', true)
|
|
->orderBy('order')
|
|
->get();
|
|
|
|
if ($playlistItems->isEmpty()) {
|
|
return null;
|
|
}
|
|
|
|
// Get the last displayed item
|
|
$lastDisplayed = $playlistItems
|
|
->sortByDesc('last_displayed_at')
|
|
->first();
|
|
|
|
if (! $lastDisplayed || ! $lastDisplayed->last_displayed_at) {
|
|
// If no item has been displayed yet, return the first one
|
|
return $playlistItems->first();
|
|
}
|
|
|
|
// Find the next item in sequence
|
|
$currentOrder = $lastDisplayed->order;
|
|
$nextItem = $playlistItems
|
|
->where('order', '>', $currentOrder)
|
|
->first();
|
|
|
|
// If there's no next item, loop back to the first one
|
|
if (! $nextItem) {
|
|
return $playlistItems->first();
|
|
}
|
|
|
|
return $nextItem;
|
|
}
|
|
}
|