<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use App\Entity\Details\Operation\DetailsStep;
use App\Entity\MediaObject\MediaCoupon;
use App\Entity\MediaObject\MediaMultiOffer;
use App\Entity\MediaObject\MediaObject;
use App\Entity\MediaObject\MediaParticipation;
use App\Entity\Operation\Coupon;
use App\Entity\Participation\Participation;
use App\Entity\Participation\Step;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Vich\UploaderBundle\Storage\StorageInterface;
final class ResolveMediaObjectContentUrlSubscriber implements EventSubscriberInterface
{
private const RESOURCE_CLASS_CHECK = [
MediaObject::class,
MediaCoupon::class,
MediaMultiOffer::class,
MediaParticipation::class,
Participation::class,
Step::class,
DetailsStep::class,
];
private $storage;
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $em;
/**
* @var RequestStack
*/
private RequestStack $requestStack;
/**
* ResolveMediaObjectContentUrlSubscriber constructor.
* @param StorageInterface $storage
* @param EntityManagerInterface $em
* @param RequestStack $requestStack
*/
public function __construct(
StorageInterface $storage,
EntityManagerInterface $em,
RequestStack $requestStack
)
{
$this->storage = $storage;
$this->em = $em;
$this->requestStack = $requestStack;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['onPreSerialize', EventPriorities::PRE_SERIALIZE],
];
}
public function onPreSerialize(ViewEvent $event): void
{
$controllerResult = $event->getControllerResult();
$request = $event->getRequest();
if ($controllerResult instanceof Response || !$request->attributes->getBoolean('_api_respond', true)) {
return;
}
if (!$attributes = RequestAttributesExtractor::extractAttributes($request)) {
return;
}
$valid = false;
foreach (self::RESOURCE_CLASS_CHECK as $resourceClass) {
if (!\is_a($attributes['resource_class'], $resourceClass, true)) {
$valid = true;
}
}
if (!$valid) {
return;
}
$objects = $controllerResult;
if (!is_iterable($objects)) {
$objects = [$objects];
}
foreach ($objects as $object) {
if ($object instanceof Step) {
$this->resolveContentUrl($object->getInvoices()->toArray());
continue;
}
if ($object instanceof Coupon) {
$this->resolveContentUrl($object->getDetails()->getImages());
continue;
}
if (!$object instanceof MediaObject) {
continue;
}
$this->resolveContentUrl([$object]);
}
}
private function resolveContentUrl(iterable $mediaObjects)
{
foreach ($mediaObjects as $mediaObject) {
if (!$mediaObject instanceof MediaObject) {
continue;
}
$contentUrl = $this->storage->resolveUri($mediaObject, 'file');
$contentUrl = $this->requestStack->getCurrentRequest()->getUriForPath($contentUrl);
$mediaObject->setContentUrl($contentUrl);
}
}
}