4
0
mirror of https://github.com/AzuraCast/AzuraCast.git synced 2024-06-26 10:57:06 +00:00
AzuraCast/src/Controller/Api/Stations/OnDemand/ListAction.php
Buster "Silver Eagle" Neece a42fd321a5
Code quality improvements.
2020-10-05 01:27:12 -05:00

141 lines
4.6 KiB
PHP

<?php
namespace App\Controller\Api\Stations\OnDemand;
use App\ApiUtilities;
use App\Entity;
use App\Http\Response;
use App\Http\RouterInterface;
use App\Http\ServerRequest;
use App\Paginator\ArrayPaginator;
use App\Utilities;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\EntityManagerInterface;
use DoctrineBatchUtils\BatchProcessing\SimpleBatchIteratorAggregate;
use Psr\Http\Message\ResponseInterface;
use Psr\SimpleCache\CacheInterface;
class ListAction
{
protected EntityManagerInterface $em;
protected ApiUtilities $apiUtils;
public function __construct(EntityManagerInterface $em, ApiUtilities $apiUtils)
{
$this->em = $em;
$this->apiUtils = $apiUtils;
}
public function __invoke(
ServerRequest $request,
Response $response,
CacheInterface $cache
): ResponseInterface {
$station = $request->getStation();
// Verify that the station supports on-demand streaming.
if (!$station->getEnableOnDemand()) {
return $response->withStatus(403)
->withJson(new Entity\Api\Error(403, __('This station does not support on-demand streaming.')));
}
$cacheKey = 'ondemand_' . $station->getId();
if ($cache->has($cacheKey)) {
$trackList = $cache->get($cacheKey, []);
} else {
$trackList = $this->buildTrackList($station, $request->getRouter());
$cache->set($cacheKey, $trackList, 300);
}
$trackList = new ArrayCollection($trackList);
$params = $request->getQueryParams();
$searchPhrase = trim($params['searchPhrase']);
if (!empty($searchPhrase)) {
$searchFields = [
'media_title',
'media_artist',
'media_album',
'playlist',
];
$customFields = array_keys($this->apiUtils->getCustomFields());
foreach ($customFields as $customField) {
$searchFields[] = 'media_custom_fields_' . $customField;
}
$trackList = $trackList->filter(function ($row) use ($searchFields, $searchPhrase) {
foreach ($searchFields as $searchField) {
if (false !== stripos($row[$searchField], $searchPhrase)) {
return true;
}
}
return false;
});
}
if (!empty($params['sort'])) {
$sortField = $params['sort'];
$sortDirection = $params['sortOrder'] ?? Criteria::ASC;
$criteria = new Criteria;
$criteria->orderBy([$sortField => $sortDirection]);
$trackList = $trackList->matching($criteria);
}
$paginator = new ArrayPaginator($trackList, $request);
return $paginator->write($response);
}
protected function buildTrackList(Entity\Station $station, RouterInterface $router): array
{
$list = [];
$playlists = $this->em->createQuery(/** @lang DQL */ '
SELECT sp FROM App\Entity\StationPlaylist sp
WHERE sp.station = :station
AND sp.id IS NOT NULL
AND sp.is_enabled = 1
AND sp.include_in_on_demand = 1')
->setParameter('station', $station)
->getArrayResult();
foreach ($playlists as $playlist) {
$query = $this->em->createQuery(/** @lang DQL */ '
SELECT sm FROM App\Entity\StationMedia sm
WHERE sm.id IN (
SELECT spm.media_id
FROM App\Entity\StationPlaylistMedia spm
WHERE spm.playlist_id = :playlist_id
)
ORDER BY sm.artist ASC, sm.title ASC')
->setParameter('playlist_id', $playlist['id']);
$iterator = SimpleBatchIteratorAggregate::fromQuery($query, 50);
foreach ($iterator as $media) {
/** @var Entity\StationMedia $media */
$row = new Entity\Api\StationOnDemand();
$row->track_id = $media->getUniqueId();
$row->media = $media->api($this->apiUtils);
$row->playlist = $playlist['name'];
$row->download_url = (string)$router->named('api:stations:ondemand:download', [
'station_id' => $station->getId(),
'media_id' => $media->getUniqueId(),
]);
$row->resolveUrls($router->getBaseUrl());
$list[] = Utilities::flattenArray($row, '_');
}
}
return $list;
}
}