<?php
namespace Crehler\ImageBooster\Decorator;
use Crehler\ImageBooster\Struct\MediaBoostersStruct;
use Shopware\Core\Content\Media\Aggregate\MediaThumbnail\MediaThumbnailCollection;
use Shopware\Core\Content\Media\Aggregate\MediaThumbnail\MediaThumbnailEntity;
use Shopware\Core\Content\Media\MediaEntity;
use Shopware\Core\Content\Media\MediaEvents;
use Shopware\Core\Content\Media\Pathname\UrlGeneratorInterface;
use Shopware\Core\Framework\Api\Context\AdminApiSource;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\Struct\Struct;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MediaLoadedSubscriberDecorator implements EventSubscriberInterface
{
private EventSubscriberInterface $originalService;
private UrlGeneratorInterface $urlGenerator;
public function __construct(EventSubscriberInterface $originalService, UrlGeneratorInterface $urlGenerator)
{
$this->originalService = $originalService;
$this->urlGenerator = $urlGenerator;
}
public static function getSubscribedEvents(): array
{
return [
MediaEvents::MEDIA_LOADED_EVENT => [
['unserialize', 10],
['addUrls'],
],
'crehler.custom_media.attach_urls' => [
['addUrls'],
]
];
}
public function addUrls(EntityLoadedEvent $event): void
{
if ($event->getContext()->getSource() instanceof AdminApiSource) {
if ($event->getName() === MediaEvents::MEDIA_LOADED_EVENT) {
$this->originalService->addUrls($event);
}
return;
}
/** @var MediaEntity $media */
foreach ($event->getEntities() as $element) {
$media = $element;
if (!$media instanceof MediaEntity) {
$media = $element->getMedia();
}
if (!$media->hasFile() || $media->isPrivate()) {
continue;
}
$media->setUrl($this->urlGenerator->getAbsoluteMediaUrl($media));
/** @var MediaBoostersStruct $boosters */
$boosters = $media->getExtension('mediaBoosters');
if ($boosters) {
if (!$boosters->isUrlGenerated()) {
$this->addBoostersUrls($media, $boosters);
}
// $this->setWatermarkUrls($media);
}
if ($media->getThumbnails() === null || $media->getThumbnails()->count() === 0) {
if ($media->getThumbnailsRo()) {
$media->setThumbnails(unserialize($media->getThumbnailsRo()));
} else {
$media->setThumbnails(new MediaThumbnailCollection());
}
}
// foreach ($media->getThumbnails() as $thumbnail) {
// $this->addThumbnailUrl($thumbnail, $media);
// }
if (!$element instanceof MediaEntity) {
$element->setMedia($media);
}
}
}
public function unserialize(EntityLoadedEvent $event): void
{
$this->originalService->unserialize($event);
}
// private function addThumbnailUrl(MediaThumbnailEntity $thumbnail, MediaEntity $media): void
// {
// $thumbnail->setUrl(
// $this->urlGenerator->getAbsoluteThumbnailUrl(
// $media,
// $thumbnail
// )
// );
// }
/** @param MediaBoostersStruct $struct */
private function addBoostersUrls(MediaEntity $mediaEntity, Struct $struct)
{
$absPath = $this->urlGenerator->getAbsoluteMediaUrl($mediaEntity);
$relPath = $this->urlGenerator->getRelativeMediaUrl($mediaEntity);
$basePath = str_replace($relPath, '', $absPath);
if ($struct->getAvifMedia() && !str_contains($struct->getAvifMedia()->getPath(), $basePath)) {
$struct->getAvifMedia()->setGeneratedPath(sprintf("%s%s", $basePath, $struct->getAvifMedia()->getPath()));
}
if ($struct->getWebpMedia() && !str_contains($struct->getWebpMedia()->getPath(), $basePath)) {
$struct->getWebpMedia()->setGeneratedPath(sprintf("%s%s", $basePath, $struct->getWebpMedia()->getPath()));
}
if ($struct->getWatermark() && !str_contains($struct->getWatermark()->getPath(), $basePath)) {
$struct->getWatermark()->setGeneratedPath(sprintf("%s%s", $basePath, $struct->getWatermark()->getPath()));
}
foreach ($struct->getAvifThumbnails() as $thumb) {
if (!str_contains($thumb->getPath(), $basePath)) {
$thumb->setGeneratedPath(sprintf("%s%s", $basePath, $thumb->getPath()));
}
}
foreach ($struct->getWebpThumbnails() as $thumb) {
if (!str_contains($thumb->getPath(), $basePath)) {
$thumb->setGeneratedPath(sprintf("%s%s", $basePath, $thumb->getPath()));
}
}
foreach ($struct->getWatermarkThumbnails() as $thumb) {
if (!str_contains($thumb->getPath(), $basePath)) {
$thumb->setGeneratedPath(sprintf("%s%s", $basePath, $thumb->getPath()));
}
}
}
// private function setWatermarkUrls(MediaEntity $mediaEntity)
// {
// $absPath = $this->urlGenerator->getAbsoluteMediaUrl($mediaEntity);
// $relPath = $this->urlGenerator->getRelativeMediaUrl($mediaEntity);
// /** @var MediaBoostersStruct $mediaBoosters */
// $mediaBoosters = $mediaEntity->getExtension('mediaBoosters');
// $boosterPath = null;
// if ($mediaBoosters->getWatermark()) {
// $boosterPath = $mediaBoosters->getWatermark()->getPath();
// $mediaBoosters->getWatermark()->setGeneratedPath(str_replace($relPath, $boosterPath, $absPath));
// }
// if (!$boosterPath) {
// return false;
// }
// if ($mediaEntity->getThumbnails()) {
// foreach ($mediaEntity->getThumbnails() as $thumbnail) {
// $this->replaceThumbnailUrl($mediaEntity, $thumbnail, $mediaBoosters);
// }
// }
// $mediaEntity->setUrl(str_replace($relPath, $boosterPath, $absPath));
// return true;
// }
// private function replaceThumbnailUrl(MediaEntity $mediaEntity, MediaThumbnailEntity $mediaThumbnailEntity, MediaBoostersStruct $boosters)
// {
// $absPath = $this->urlGenerator->getAbsoluteThumbnailUrl($mediaEntity, $mediaThumbnailEntity);
// $relPath = $this->urlGenerator->getRelativeThumbnailUrl($mediaEntity, $mediaThumbnailEntity);
// if (empty($boosters->getWatermarkThumbnails())) {
// return false;
// }
// $boosterPath = null;
// /** @var MediaBoosterEntity $booster */
// foreach ($boosters->getWatermarkThumbnails() as $booster) {
// if (
// $booster->getHeight() === $mediaThumbnailEntity->getHeight()
// && $booster->getWidth() === $mediaThumbnailEntity->getWidth()
// ) {
// $boosterPath = $booster->getPath();
// break;
// }
// }
// if (!$boosterPath) {
// return false;
// }
// $mediaThumbnailEntity->setUrl(str_replace($relPath, $boosterPath, $absPath));
// return true;
// }
}