getStation(); // Verify that the station supports requests. if (!$station->getBackendTypeEnum()->isEnabled() || !$station->getEnableRequests()) { return $response->withStatus(403) ->withJson(new Entity\Api\Error(403, __('This station does not accept requests currently.'))); } $playlistIds = $this->getRequestablePlaylists($station); $qb = $this->em->createQueryBuilder(); $qb->select('sm, spm, sp') ->from(Entity\StationMedia::class, 'sm') ->leftJoin('sm.playlists', 'spm') ->leftJoin('spm.playlist', 'sp') ->where('sm.storage_location = :storageLocation') ->andWhere('sp.id IN (:playlistIds)') ->setParameter('storageLocation', $station->getMediaStorageLocation()) ->setParameter('playlistIds', $playlistIds); $queryParams = $request->getQueryParams(); if (!empty($queryParams['sort'])) { $sortDirection = (($queryParams['sortOrder'] ?? 'ASC') === 'ASC') ? 'ASC' : 'DESC'; match ($queryParams['sort']) { 'name', 'song_title' => $qb->addOrderBy('sm.title', $sortDirection), 'song_artist' => $qb->addOrderBy('sm.artist', $sortDirection), 'song_album' => $qb->addOrderBy('sm.album', $sortDirection), 'song_genre' => $qb->addOrderBy('sm.genre', $sortDirection), default => null, }; } else { $qb->orderBy('sm.artist', 'ASC') ->addOrderBy('sm.title', 'ASC'); } $search_phrase = trim($queryParams['searchPhrase'] ?? ''); if (!empty($search_phrase)) { $qb->andWhere('(sm.title LIKE :query OR sm.artist LIKE :query OR sm.album LIKE :query)') ->setParameter('query', '%' . $search_phrase . '%'); } $paginator = Paginator::fromQueryBuilder($qb, $request); $is_bootgrid = $paginator->isFromBootgrid(); $router = $request->getRouter(); $baseUrl = $router->getBaseUrl(); $paginator->setPostprocessor( function (Entity\StationMedia $media_row) use ($station, $is_bootgrid, $baseUrl, $router) { $row = new Entity\Api\StationRequest(); $row->song = ($this->songApiGenerator)($media_row, $station, $baseUrl); $row->request_id = $media_row->getUniqueId(); $row->request_url = (string)$router->named( 'api:requests:submit', [ 'station_id' => $station->getId(), 'media_id' => $media_row->getUniqueId(), ] ); $row->resolveUrls($baseUrl); if ($is_bootgrid) { return Utilities\Arrays::flattenArray($row, '_'); } return $row; } ); return $paginator->write($response); } /** * @param Entity\Station $station */ private function getRequestablePlaylists(Entity\Station $station): array { $playlists = $this->em->createQuery( <<setParameter('station', $station) ->toIterable(); $ids = []; $now = CarbonImmutable::now($station->getTimezoneObject()); /** @var Entity\StationPlaylist $playlist */ foreach ($playlists as $playlist) { if ($this->scheduler->isPlaylistScheduledToPlayNow($playlist, $now)) { $ids[] = $playlist->getIdRequired(); } } return $ids; } public function submitAction( ServerRequest $request, Response $response, string $station_id, string $media_id ): ResponseInterface { $station = $request->getStation(); // Verify that the station supports requests. if (!$station->getBackendTypeEnum()->isEnabled() || !$station->getEnableRequests()) { return $response->withStatus(403) ->withJson(new Entity\Api\Error(403, __('This station does not accept requests currently.'))); } try { $user = $request->getUser(); } catch (Exception\InvalidRequestAttribute) { $user = null; } $isAuthenticated = ($user instanceof Entity\User); try { $this->requestRepo->submit( $station, $media_id, $isAuthenticated, $request->getIp(), $request->getHeaderLine('User-Agent') ); return $response->withJson(Entity\Api\Status::success()); } catch (Exception $e) { return $response->withStatus(400) ->withJson(new Entity\Api\Error(400, $e->getMessage())); } } }