diff --git a/frontend/src/components/Stations/PodcastEpisodes.vue b/frontend/src/components/Stations/PodcastEpisodes.vue index 0ecbda270..6eb3a23f7 100644 --- a/frontend/src/components/Stations/PodcastEpisodes.vue +++ b/frontend/src/components/Stations/PodcastEpisodes.vue @@ -189,7 +189,7 @@ const fields: DataTableField[] = [ key: 'is_published', label: $gettext('Is Published'), visible: false, - sortable: true, + sortable: false, selectable: true }, { diff --git a/src/Controller/Api/Stations/PodcastEpisodesController.php b/src/Controller/Api/Stations/PodcastEpisodesController.php index c9ca3740f..351f41599 100644 --- a/src/Controller/Api/Stations/PodcastEpisodesController.php +++ b/src/Controller/Api/Stations/PodcastEpisodesController.php @@ -14,7 +14,6 @@ use App\Entity\Repository\PodcastEpisodeRepository; use App\Http\Response; use App\Http\ServerRequest; use App\OpenApi; -use App\Paginator; use App\Service\Flow\UploadedFile; use Doctrine\Common\Collections\Order; use InvalidArgumentException; @@ -213,7 +212,6 @@ final class PodcastEpisodesController extends AbstractApiCrudController ->join('e.podcast', 'p') ->leftJoin('e.media', 'pm') ->where('e.podcast = :podcast') - ->orderBy('e.created_at', 'DESC') ->setParameter('podcast', $podcast); $queryBuilder = $this->searchQueryBuilder( @@ -224,25 +222,18 @@ final class PodcastEpisodesController extends AbstractApiCrudController ] ); - $episodes = array_map( - fn($row) => $this->viewRecord($row, $request), - $queryBuilder->getQuery()->getResult() - ); - - $episodes = $this->sortArray( + $queryBuilder = $this->sortQueryBuilder( $request, - $episodes, + $queryBuilder, [ - 'is_published' => 'is_published', - 'publish_at' => 'publish_at', - 'is_explicit' => 'is_explicit', + 'publish_at' => 'e.publish_at', + 'is_explicit' => 'e.is_explicit', ], - 'id', + 'e.publish_at', Order::Descending ); - $paginator = Paginator::fromArray($episodes, $request); - return $paginator->write($response); + return $this->listPaginatedFromQuery($request, $response, $queryBuilder->getQuery()); } /** diff --git a/src/Controller/Api/Stations/Podcasts/Episodes/ListEpisodesAction.php b/src/Controller/Api/Stations/Podcasts/Episodes/ListEpisodesAction.php index f9c8cb0ed..401791efa 100644 --- a/src/Controller/Api/Stations/Podcasts/Episodes/ListEpisodesAction.php +++ b/src/Controller/Api/Stations/Podcasts/Episodes/ListEpisodesAction.php @@ -37,7 +37,7 @@ final class ListEpisodesAction implements SingleActionInterface ->leftJoin('e.playlist_media', 'sm') ->where('e.podcast = :podcast') ->setParameter('podcast', $podcast) - ->andWhere('e.publish_at IS NULL OR e.publish_at <= :publishTime') + ->andWhere('e.publish_at <= :publishTime') ->setParameter('publishTime', time()) ->andWhere( '(p.source = :sourceManual AND pm.id IS NOT NULL) OR (p.source = :sourcePlaylist AND sm.id IS NOT NULL)' diff --git a/src/Controller/Api/Traits/CanSortResults.php b/src/Controller/Api/Traits/CanSortResults.php index b244d97ce..80364ef6e 100644 --- a/src/Controller/Api/Traits/CanSortResults.php +++ b/src/Controller/Api/Traits/CanSortResults.php @@ -68,15 +68,14 @@ trait CanSortResults ServerRequest $request, Order $defaultSortOrder = Order::Ascending ): array { + $sortValue = Types::stringOrNull($request->getParam('sort'), true); $sortOrder = Types::stringOrNull($request->getParam('sortOrder'), true); - $orderEnum = (null !== $sortOrder) - ? Order::tryFrom(strtoupper($sortOrder)) ?? $defaultSortOrder - : $defaultSortOrder; - return [ - Types::stringOrNull($request->getParam('sort'), true), - $orderEnum, + $sortValue, + (null !== $sortValue && null !== $sortOrder) + ? Order::tryFrom(strtoupper($sortOrder)) ?? $defaultSortOrder + : $defaultSortOrder, ]; } diff --git a/src/Entity/Api/PodcastEpisode.php b/src/Entity/Api/PodcastEpisode.php index 109335b45..7d6d62198 100644 --- a/src/Entity/Api/PodcastEpisode.php +++ b/src/Entity/Api/PodcastEpisode.php @@ -34,10 +34,10 @@ final class PodcastEpisode public int $created_at; #[OA\Property] - public bool $is_published = true; + public int $publish_at; #[OA\Property] - public ?int $publish_at = null; + public bool $is_published = true; #[OA\Property] public bool $has_media = false; diff --git a/src/Entity/Migration/Version20240319115513.php b/src/Entity/Migration/Version20240319115513.php new file mode 100644 index 000000000..74903c8ce --- /dev/null +++ b/src/Entity/Migration/Version20240319115513.php @@ -0,0 +1,34 @@ +addSql( + <<<'SQL' + UPDATE podcast_episode + SET publish_at = created_at + WHERE publish_at IS NULL + SQL + ); + + $this->addSql('ALTER TABLE podcast_episode CHANGE publish_at publish_at INT NOT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE podcast_episode CHANGE publish_at publish_at INT DEFAULT NULL'); + } +} diff --git a/src/Entity/PodcastEpisode.php b/src/Entity/PodcastEpisode.php index 69a5afe3a..608e0ed3c 100644 --- a/src/Entity/PodcastEpisode.php +++ b/src/Entity/PodcastEpisode.php @@ -46,8 +46,8 @@ class PodcastEpisode implements IdentifiableEntityInterface #[Assert\NotBlank] protected string $description; - #[ORM\Column(nullable: true)] - protected ?int $publish_at = null; + #[ORM\Column] + protected int $publish_at; #[ORM\Column] protected bool $explicit; @@ -63,6 +63,7 @@ class PodcastEpisode implements IdentifiableEntityInterface { $this->podcast = $podcast; $this->created_at = time(); + $this->publish_at = time(); } public function getPodcast(): Podcast @@ -126,14 +127,14 @@ class PodcastEpisode implements IdentifiableEntityInterface return $this; } - public function getPublishAt(): ?int + public function getPublishAt(): int { return $this->publish_at; } public function setPublishAt(?int $publishAt): self { - $this->publish_at = $publishAt; + $this->publish_at = $publishAt ?? $this->created_at; return $this; } @@ -181,7 +182,7 @@ class PodcastEpisode implements IdentifiableEntityInterface public function isPublished(): bool { - if ($this->getPublishAt() !== null && $this->getPublishAt() > time()) { + if ($this->getPublishAt() > time()) { return false; } diff --git a/src/Entity/Repository/PodcastRepository.php b/src/Entity/Repository/PodcastRepository.php index ecc60bb35..12f19e7ff 100644 --- a/src/Entity/Repository/PodcastRepository.php +++ b/src/Entity/Repository/PodcastRepository.php @@ -52,7 +52,7 @@ final class PodcastRepository extends Repository LEFT JOIN pe.playlist_media sm WHERE ((p.source = :sourceManual AND pm.id IS NOT NULL) OR (p.source = :sourcePlaylist AND sm.id IS NOT NULL)) - AND (pe.publish_at IS NULL OR pe.publish_at <= :time) + AND (pe.publish_at <= :time) DQL )->setParameter('time', time()) ->setParameter('sourceManual', PodcastSources::Manual->value)