mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
175 lines
4.4 KiB
PHP
175 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\Device;
|
|
use App\Models\Playlist;
|
|
use App\Models\PlaylistItem;
|
|
use App\Models\Plugin;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class MashupCreateCommand extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'mashup:create';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = 'Create a new mashup and add it to a playlist';
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*/
|
|
public function handle(): int
|
|
{
|
|
// Select device
|
|
$device = $this->selectDevice();
|
|
if (! $device instanceof Device) {
|
|
return 1;
|
|
}
|
|
|
|
// Select playlist
|
|
$playlist = $this->selectPlaylist($device);
|
|
if (! $playlist instanceof Playlist) {
|
|
return 1;
|
|
}
|
|
|
|
// Select mashup layout
|
|
$layout = $this->selectLayout();
|
|
if (! $layout) {
|
|
return 1;
|
|
}
|
|
|
|
// Get mashup name
|
|
$name = $this->getMashupName();
|
|
if (! $name) {
|
|
return 1;
|
|
}
|
|
|
|
// Select plugins
|
|
$plugins = $this->selectPlugins($layout);
|
|
if ($plugins->isEmpty()) {
|
|
return 1;
|
|
}
|
|
|
|
$maxOrder = $playlist->items()->max('order') ?? 0;
|
|
|
|
// Create playlist item with mashup
|
|
PlaylistItem::createMashup(
|
|
playlist: $playlist,
|
|
layout: $layout,
|
|
pluginIds: $plugins->pluck('id')->toArray(),
|
|
name: $name,
|
|
order: $maxOrder + 1
|
|
);
|
|
|
|
$this->info('Mashup created successfully!');
|
|
|
|
return 0;
|
|
}
|
|
|
|
protected function selectDevice(): ?Device
|
|
{
|
|
$devices = Device::all();
|
|
if ($devices->isEmpty()) {
|
|
$this->error('No devices found. Please create a device first.');
|
|
|
|
return null;
|
|
}
|
|
|
|
$deviceId = $this->choice(
|
|
'Select a device',
|
|
$devices->mapWithKeys(fn ($device): array => [$device->id => $device->name])->toArray()
|
|
);
|
|
|
|
return $devices->firstWhere('id', $deviceId);
|
|
}
|
|
|
|
protected function selectPlaylist(Device $device): ?Playlist
|
|
{
|
|
/** @var Collection|Playlist[] $playlists */
|
|
$playlists = $device->playlists;
|
|
if ($playlists->isEmpty()) {
|
|
$this->error('No playlists found for this device. Please create a playlist first.');
|
|
|
|
return null;
|
|
}
|
|
|
|
$playlistId = $this->choice(
|
|
'Select a playlist',
|
|
$playlists->mapWithKeys(fn (Playlist $playlist): array => [$playlist->id => $playlist->name])->toArray()
|
|
);
|
|
|
|
return $playlists->firstWhere('id', $playlistId);
|
|
}
|
|
|
|
protected function selectLayout(): ?string
|
|
{
|
|
return $this->choice(
|
|
'Select a layout',
|
|
PlaylistItem::getAvailableLayouts()
|
|
);
|
|
}
|
|
|
|
protected function getMashupName(): ?string
|
|
{
|
|
$name = $this->ask('Enter a name for this mashup', 'Mashup');
|
|
|
|
if (mb_strlen((string) $name) < 2) {
|
|
$this->error('The name must be at least 2 characters.');
|
|
|
|
return null;
|
|
}
|
|
|
|
if (mb_strlen((string) $name) > 50) {
|
|
$this->error('The name must not exceed 50 characters.');
|
|
|
|
return null;
|
|
}
|
|
|
|
return $name;
|
|
}
|
|
|
|
protected function selectPlugins(string $layout): Collection
|
|
{
|
|
$requiredCount = PlaylistItem::getRequiredPluginCountForLayout($layout);
|
|
|
|
$plugins = Plugin::all();
|
|
if ($plugins->isEmpty()) {
|
|
$this->error('No plugins found. Please create some plugins first.');
|
|
|
|
return collect();
|
|
}
|
|
|
|
$selectedPlugins = collect();
|
|
$availablePlugins = $plugins->mapWithKeys(fn ($plugin): array => [$plugin->id => $plugin->name])->toArray();
|
|
|
|
for ($i = 0; $i < $requiredCount; ++$i) {
|
|
$position = match ($i) {
|
|
0 => 'first',
|
|
1 => 'second',
|
|
2 => 'third',
|
|
3 => 'fourth',
|
|
default => ($i + 1).'th'
|
|
};
|
|
|
|
$pluginId = $this->choice(
|
|
"Select the $position plugin",
|
|
$availablePlugins
|
|
);
|
|
|
|
$selectedPlugins->push($plugins->firstWhere('id', $pluginId));
|
|
unset($availablePlugins[$pluginId]);
|
|
}
|
|
|
|
return $selectedPlugins;
|
|
}
|
|
}
|