Ensure podcast publish_at field is always set and sortable and fix sorting issues with the Podcast Episodes admin UI.

This commit is contained in:
Buster Neece 2024-03-19 07:27:48 -05:00
parent eed6811b38
commit 838095eee6
No known key found for this signature in database
8 changed files with 56 additions and 31 deletions

View File

@ -189,7 +189,7 @@ const fields: DataTableField[] = [
key: 'is_published',
label: $gettext('Is Published'),
visible: false,
sortable: true,
sortable: false,
selectable: true
},
{

View File

@ -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());
}
/**

View File

@ -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)'

View File

@ -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,
];
}

View File

@ -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;

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace App\Entity\Migration;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20240319115513 extends AbstractMigration
{
public function getDescription(): string
{
return 'Make Podcast Episode publish date always have a value.';
}
public function up(Schema $schema): void
{
$this->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');
}
}

View File

@ -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;
}

View File

@ -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)