AzuraCast/src/Entity/ApiGenerator/SongApiGenerator.php

134 lines
4.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Entity\ApiGenerator;
use App\Entity;
use App\Http\Router;
use App\Media\RemoteAlbumArt;
use Doctrine\ORM\EntityManagerInterface;
use GuzzleHttp\Psr7\UriResolver;
use GuzzleHttp\Psr7\Utils;
use Psr\Http\Message\UriInterface;
class SongApiGenerator
{
public function __construct(
protected EntityManagerInterface $em,
protected Router $router,
protected Entity\Repository\StationRepository $stationRepo,
protected Entity\Repository\CustomFieldRepository $customFieldRepo,
protected RemoteAlbumArt $remoteAlbumArt
) {
}
public function __invoke(
Entity\Interfaces\SongInterface $song,
?Entity\Station $station = null,
?UriInterface $baseUri = null,
bool $allowRemoteArt = false,
bool $isNowPlaying = false,
): Entity\Api\Song {
$response = new Entity\Api\Song();
$response->id = $song->getSongId();
$response->text = $song->getText() ?? '';
$response->artist = $song->getArtist() ?? '';
$response->title = $song->getTitle() ?? '';
if ($song instanceof Entity\StationMedia) {
$response->album = $song->getAlbum() ?? '';
$response->genre = $song->getGenre() ?? '';
$response->isrc = $song->getIsrc() ?? '';
$response->lyrics = $song->getLyrics() ?? '';
$response->custom_fields = $this->getCustomFields($song->getId());
} else {
$response->custom_fields = $this->getCustomFields();
}
$response->art = UriResolver::resolve(
$baseUri ?? $this->router->getBaseUrl(),
$this->getAlbumArtUrl($song, $station, $allowRemoteArt, $isNowPlaying)
);
return $response;
}
protected function getAlbumArtUrl(
Entity\Interfaces\SongInterface $song,
?Entity\Station $station = null,
bool $allowRemoteArt = false,
bool $isNowPlaying = false,
): UriInterface {
if (null !== $station && $song instanceof Entity\StationMedia) {
$mediaUpdatedTimestamp = $song->getArtUpdatedAt();
if (0 !== $mediaUpdatedTimestamp) {
return $this->router->named(
route_name: 'api:stations:media:art',
route_params: [
'station_id' => $station->getId(),
'media_id' => $song->getUniqueId() . '-' . $mediaUpdatedTimestamp,
]
);
}
}
if ($allowRemoteArt && $this->remoteAlbumArt->enableForApis()) {
$url = $this->remoteAlbumArt->getUrlForSong($song);
if (null !== $url) {
return Utils::uriFor($url);
}
}
if ($isNowPlaying && null !== $station) {
$currentStreamer = $station->getCurrentStreamer();
if (null !== $currentStreamer && 0 !== $currentStreamer->getArtUpdatedAt()) {
return $this->router->named(
route_name: 'api:stations:streamer:art',
route_params: [
'station_id' => $station->getIdRequired(),
'id' => $currentStreamer->getIdRequired() . '|' . $currentStreamer->getArtUpdatedAt(),
],
);
}
}
return $this->stationRepo->getDefaultAlbumArtUrl($station);
}
/**
* Return all custom fields, either with a null value or with the custom value assigned to the given Media ID.
*
* @param int|null $media_id
*
* @return mixed[]
*/
protected function getCustomFields(?int $media_id = null): array
{
$fields = $this->customFieldRepo->getFieldIds();
$mediaFields = [];
if ($media_id !== null) {
$mediaFieldsRaw = $this->em->createQuery(
<<<'DQL'
SELECT smcf.field_id, smcf.value
FROM App\Entity\StationMediaCustomField smcf
WHERE smcf.media_id = :media_id
DQL
)->setParameter('media_id', $media_id)
->getArrayResult();
foreach ($mediaFieldsRaw as $row) {
$mediaFields[$row['field_id']] = $row['value'];
}
}
$customFields = [];
foreach ($fields as $fieldId => $fieldKey) {
$customFields[$fieldKey] = $mediaFields[$fieldId] ?? null;
}
return $customFields;
}
}