141 lines
3.3 KiB
PHP
141 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Entity;
|
|
|
|
use App\Repository\AlbumTrackRepository;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
|
|
/**
|
|
* AlbumTrack persists individual tracks fetched from External.
|
|
*/
|
|
#[ORM\Entity(repositoryClass: AlbumTrackRepository::class)]
|
|
#[ORM\Table(name: 'album_tracks')]
|
|
#[ORM\UniqueConstraint(name: 'uniq_album_disc_track', columns: ['album_id', 'disc_number', 'track_number'])]
|
|
class AlbumTrack
|
|
{
|
|
#[ORM\Id]
|
|
#[ORM\GeneratedValue]
|
|
#[ORM\Column(type: 'integer')]
|
|
private ?int $id = null;
|
|
|
|
#[ORM\ManyToOne(targetEntity: Album::class, inversedBy: 'tracks')]
|
|
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
|
private ?Album $album = null;
|
|
|
|
#[ORM\Column(type: 'string', length: 64, nullable: true)]
|
|
private ?string $externalTrackId = null;
|
|
|
|
#[ORM\Column(type: 'integer')]
|
|
private int $discNumber = 1;
|
|
|
|
#[ORM\Column(type: 'integer')]
|
|
private int $trackNumber = 1;
|
|
|
|
#[ORM\Column(type: 'string', length: 512)]
|
|
private string $name = '';
|
|
|
|
#[ORM\Column(type: 'integer')]
|
|
private int $durationMs = 0;
|
|
|
|
#[ORM\Column(type: 'string', length: 1024, nullable: true)]
|
|
private ?string $previewUrl = null;
|
|
|
|
public function getId(): ?int
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function getAlbum(): ?Album
|
|
{
|
|
return $this->album;
|
|
}
|
|
|
|
public function setAlbum(?Album $album): void
|
|
{
|
|
$this->album = $album;
|
|
}
|
|
|
|
public function getExternalTrackId(): ?string
|
|
{
|
|
return $this->externalTrackId;
|
|
}
|
|
|
|
public function setExternalTrackId(?string $externalTrackId): void
|
|
{
|
|
$this->externalTrackId = $externalTrackId;
|
|
}
|
|
|
|
public function getDiscNumber(): int
|
|
{
|
|
return $this->discNumber;
|
|
}
|
|
|
|
public function setDiscNumber(int $discNumber): void
|
|
{
|
|
$this->discNumber = max(1, $discNumber);
|
|
}
|
|
|
|
public function getTrackNumber(): int
|
|
{
|
|
return $this->trackNumber;
|
|
}
|
|
|
|
public function setTrackNumber(int $trackNumber): void
|
|
{
|
|
$this->trackNumber = max(1, $trackNumber);
|
|
}
|
|
|
|
public function getName(): string
|
|
{
|
|
return $this->name;
|
|
}
|
|
|
|
public function setName(string $name): void
|
|
{
|
|
$this->name = $name;
|
|
}
|
|
|
|
public function getDurationMs(): int
|
|
{
|
|
return $this->durationMs;
|
|
}
|
|
|
|
public function setDurationMs(int $durationMs): void
|
|
{
|
|
$this->durationMs = max(0, $durationMs);
|
|
}
|
|
|
|
public function getPreviewUrl(): ?string
|
|
{
|
|
return $this->previewUrl;
|
|
}
|
|
|
|
public function setPreviewUrl(?string $previewUrl): void
|
|
{
|
|
$this->previewUrl = $previewUrl;
|
|
}
|
|
|
|
/**
|
|
* Normalizes the track for template rendering.
|
|
*
|
|
* @return array{disc:int,track:int,name:string,duration_label:string,duration_seconds:int,preview_url:?string}
|
|
*/
|
|
public function toTemplateArray(): array
|
|
{
|
|
$seconds = (int) floor($this->durationMs / 1000);
|
|
$minutes = intdiv($seconds, 60);
|
|
$remainingSeconds = $seconds % 60;
|
|
|
|
return [
|
|
'disc' => $this->discNumber,
|
|
'track' => $this->trackNumber,
|
|
'name' => $this->name,
|
|
'duration_label' => sprintf('%d:%02d', $minutes, $remainingSeconds),
|
|
'duration_seconds' => $seconds,
|
|
'preview_url' => $this->previewUrl,
|
|
];
|
|
}
|
|
}
|
|
|
|
|