<?php
namespace App\Subscriber\Content;
use App\Dictionary\ContentStatus;
use App\Entity\Content;
use App\Entity\ContentImageset;
use App\Entity\ContentVideo;
use App\Event\Content\ContentCheckedEvent;
use App\Event\Content\ContentPublishedEvent;
use App\Event\Content\ContentRenamedEvent;
use App\Event\Content\ContentStatusChangedEvent;
use App\Lib\Content\ContentServiceAwareInterface;
use App\Service\Content\ContentService;
use App\Service\Content\SeoService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ContentCheckSeoSubscriber implements EventSubscriberInterface, ContentServiceAwareInterface
{
protected ContentService $service;
protected SeoService $seoService;
public function __construct(ContentService $service, SeoService $seoService)
{
$this->setContentService($service);
$this->setSeoService($seoService);
}
public function setSeoService(SeoService $seoService): self
{
$this->seoService = $seoService;
return $this;
}
public function getSeoService(): SeoService
{
return $this->seoService;
}
public function setContentService(ContentService $service): ContentServiceAwareInterface
{
$this->service = $service;
return $this;
}
public function getContentService(): ContentService
{
return $this->service;
}
public static function getSubscribedEvents(): array
{
return [
ContentCheckedEvent::class => [
['onCheckedAndAcceptedGenerateSeo', 0],
],
ContentRenamedEvent::class => [
['onRenameRegenerateSlug', 0],
],
ContentStatusChangedEvent::class => [
['onNewWaitraitingImagesetGenerateSlug', 0],
],
ContentPublishedEvent::class => [
['fixMissingSlugOnPublish', 1024],
],
];
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onCheckedAndAcceptedGenerateSeo(ContentCheckedEvent $event)
{
if (!$event->isAccepted()) {
return;
}
$content = $event->getContent();
// seo stuff
$seoService = $this->getSeoService();
$updated = false;
if (empty($content->getMetaDescription())) {
$content->setMetaDescription($seoService->generateMetaDescription($content));
$updated = true;
}
if (empty($content->getMetaKeywords())) {
$content->setMetaKeywords(implode(', ', $seoService->generateMetaKeywords($content)));
$updated = true;
}
if (null !== $content->getContent() && empty($content->getContent()->getSlug())) {
$content->getContent()->setSlug($seoService->generateSlug($content));
$updated = true;
}
if ($updated) {
$content->setUpdatedAt(new \DateTime());
}
$this->service->storeEntity($content);
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onRenameRegenerateSlug(ContentRenamedEvent $event)
{
$entity = $event->getEntity();
if ($entity instanceof ContentVideo || $entity instanceof ContentImageset) {
$content = $entity->getContent();
$entity->setSlug($this->getSeoService()->generateSlug($content));
$content->setUpdatedAt(new \DateTime());
$this->service->storeEntity($content);
}
}
public function onNewWaitraitingImagesetGenerateSlug(ContentStatusChangedEvent $event): void
{
if ($event->isVideo() || ContentStatus::WAITRATING !== $event->getNewStatus() || !empty($event->getContent()->getSlug())) {
return;
}
/** @var ContentImageset $contentAbstract */
$contentAbstract = $event->getContent();
$slug = $this->getSeoService()->generateSlug($contentAbstract->getContent());
$contentAbstract->setSlug($slug);
$this->service->storeEntity($contentAbstract);
}
public function fixMissingSlugOnPublish(ContentPublishedEvent $event)
{
if (!$event->getContent()->isImageset() || !$event->getContent()->isSlugEmpty()) {
return;
}
/** @var Content $content */
$content = $event->getContent();
$slug = $this->getSeoService()->generateSlug($content);
$content->getContent()->setSlug($slug);
$this->service->storeEntity($content);
}
}