<?php
/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Sulu\Bundle\MediaBundle\Search\Subscriber;
use Massive\Bundle\SearchBundle\Search\Event\PreIndexEvent;
use Massive\Bundle\SearchBundle\Search\Factory;
use Massive\Bundle\SearchBundle\Search\SearchEvents;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Sulu\Bundle\MediaBundle\Api\Media;
use Sulu\Bundle\MediaBundle\Entity\FileVersionMeta;
use Sulu\Bundle\MediaBundle\Media\Manager\MediaManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* This subscriber populates the image URL field
* when a Structure containing an image field is indexed.
*/
class MediaSearchSubscriber implements EventSubscriberInterface
{
/**
* @var MediaManagerInterface
*/
protected $mediaManager;
/**
* The format of the image, which will be returned in the search.
*
* @var string
*/
protected $searchImageFormat;
/**
* @var Factory
*/
protected $factory;
/**
* @var array
*/
protected $thumbnailMimeTypes;
/**
* @var LoggerInterface
*/
protected $logger;
/**
* @param Factory $factory Massive search factory
* @param LoggerInterface $logger
* @param array $thumbnailMimeTypes
* @param string $searchImageFormat
*/
public function __construct(
MediaManagerInterface $mediaManager,
Factory $factory,
$thumbnailMimeTypes,
$searchImageFormat,
LoggerInterface $logger = null
) {
$this->mediaManager = $mediaManager;
$this->factory = $factory;
$this->searchImageFormat = $searchImageFormat;
$this->thumbnailMimeTypes = $thumbnailMimeTypes;
$this->logger = $logger ?: new NullLogger();
}
public static function getSubscribedEvents()
{
return [
SearchEvents::PRE_INDEX => 'handlePreIndex',
];
}
/**
* Adds the image to the search document.
*/
public function handlePreIndex(PreIndexEvent $event)
{
$metadata = $event->getMetadata();
if (
!$event->getSubject() instanceof FileVersionMeta
&& FileVersionMeta::class !== $metadata->getName()
) {
return;
}
$document = $event->getDocument();
$subject = $event->getSubject();
$locale = $subject->getLocale();
$fileVersion = $subject->getFileVersion();
$file = $fileVersion->getFile();
$media = $file->getMedia();
// Do not try and get the image URL if the mime type is not in the
// list of mime types for which thumbnails are generated.
foreach ($this->thumbnailMimeTypes as $type) {
if (\fnmatch($type, $fileVersion->getMimeType())) {
$document->setImageUrl($this->getImageUrl($media, $locale));
break;
}
}
$document->addField($this->factory->createField(
'media_id',
$media->getId()
));
$document->addField($this->factory->createField(
'media_mime',
$fileVersion->getMimeType()
));
if ($collection = $media->getCollection()) {
$document->addField($this->factory->createField(
'collection_id',
$collection->getId()
));
}
}
/**
* Return the image URL for the given media.
*
* TODO: The media API needs to be improved here.
*/
private function getImageUrl($media, $locale)
{
$mediaApi = new Media($media, $locale);
$this->mediaManager->addFormatsAndUrl($mediaApi);
$formats = $mediaApi->getThumbnails();
if (!isset($formats[$this->searchImageFormat])) {
$this->logger->warning(\sprintf(
'Media with ID "%s" does not have thumbnail format "%s". This thumbnail would be used by the search results.',
$media->getId(),
$this->searchImageFormat
));
return;
}
return $formats[$this->searchImageFormat];
}
}