You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

108 lines
2.9 KiB

<?php
namespace App\Twig\Components\Organisms;
use App\Dto\FeaturedArticleCard;
use App\Repository\ArticleRepository;
use App\Service\MagazineIndexStore;
use Psr\Cache\InvalidArgumentException;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
#[AsTwigComponent]
final class FeaturedList
{
public string $category = '';
public string $title = '';
public array $list = [];
public function __construct(
private readonly MagazineIndexStore $store,
private readonly ArticleRepository $articleRepository,
) {
}
/**
* @throws InvalidArgumentException
*/
public function mount($category): void
{
$this->list = [];
$this->title = '';
$coord = $category[1] ?? '';
$this->category = (string) $coord;
$parts = explode(':', $this->category, 3);
if (\count($parts) < 3) {
return;
}
$slug = $parts[2];
$catIndex = $this->store->getCategory($slug);
if (!\is_object($catIndex) || !\method_exists($catIndex, 'getTags')) {
return;
}
$slugs = [];
foreach ($catIndex->getTags() as $tag) {
if (($tag[0] ?? null) === 'title' && isset($tag[1])) {
$this->title = (string) $tag[1];
}
if (($tag[0] ?? null) === 'a' && isset($tag[1])) {
$segs = explode(':', (string) $tag[1], 3);
$slugs[] = trim((string) end($segs));
if (\count($slugs) >= 5) {
break;
}
}
}
if ($this->title === '') {
$this->title = $slug;
}
if ($slugs === []) {
return;
}
$articles = $this->articleRepository->findFeaturedCardsBySlugs($slugs);
$slugMap = [];
foreach ($articles as $article) {
$articleSlug = trim((string) $article->getSlug());
if ($articleSlug !== '') {
if (!isset($slugMap[$articleSlug])) {
$slugMap[$articleSlug] = $article;
} elseif (self::isNewer($article, $slugMap[$articleSlug])) {
$slugMap[$articleSlug] = $article;
}
}
}
$orderedList = [];
foreach ($slugs as $articleSlug) {
$articleSlug = trim((string) $articleSlug);
if ($articleSlug !== '' && isset($slugMap[$articleSlug])) {
$orderedList[] = $slugMap[$articleSlug];
}
}
$this->list = array_slice($orderedList, 0, 4);
}
private static function isNewer(FeaturedArticleCard $a, FeaturedArticleCard $b): bool
{
$ca = $a->getCreatedAt();
$cb = $b->getCreatedAt();
if ($ca === null) {
return false;
}
if ($cb === null) {
return true;
}
return $ca > $cb;
}
}