<?php
namespace App\EventSubscriber\Content;
use App\Entity\Connection\ContentImageConnection;
use App\Entity\Content\Text;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use App\Event\Content\ContentDisplayEvent;
use Avt\Graphics\Image\Resizer\ResizerInterface;
use Avt\Graphics\Image\Storage\StorageDriverInterface;
use Avt\Graphics\Image\Model\Path;
use Avt\Graphics\Image\Model\Context;
/**
* @author Przemysław Chrupek <przemyslaw.chrupek@avt.pl>
*/
class ContentInTextImagesSubscriber implements EventSubscriberInterface
{
const IMG_POPUP_SIZE = 1600;
const IMG_MAX_SIZE = 970;
/**
* @var ResizerInterface
*/
private $resizer;
/**
* @var StorageDriverInterface
*/
private $sd;
/**
* @var Content
*/
private $content;
public function __construct(ResizerInterface $resizer, StorageDriverInterface $storageDriver)
{
$this->resizer = $resizer;
$this->sd = $storageDriver;
}
public static function getSubscribedEvents()
{
return [
ContentDisplayEvent::NAME => [
['preContentDisplay', 101],
]
];
}
public function preContentDisplay(ContentDisplayEvent $event)
{
$this->content = $event->getContent();
$text = $this->content->getText();
if (!$text instanceof Text) {
return;
}
$patternImg = '/<img([^\>]*src=\"([\/]{0,1}i\/\d\d\d\d\/\d\d\/\d\d\/(\d+)-[^\"]*)\"[^\>\/]*)\/{0,1}>/msi';
$text->setValue(preg_replace_callback($patternImg, [$this, 'replaceImg'], $text->getValue()));
}
/**
* @param array $matches
*/
private function replaceImg($matches)
{
$img = '';
$html = '';
foreach ($this->content->getImagesByType(ContentImageConnection::TYPE_TEXT) as $im) {
if ($im->getImage()->getId() == $matches[3]) {
$img = $im;
}
}
if (empty($img)) {
return false;
}
$title = (!empty($img->getAlt())) ? sprintf(' title="%s"', strip_tags((str_replace('"', '', $img->getAlt())))) : '';
if ($img->getPopup()) {
$html .= sprintf('<a class="imagesInContent" href="%s"%s>', $this->getImage($img), $title);
}
$html .= $this->getPicture($img);
if ($img->getPopup()) {
$html .= '</a>';
}
return $html;
}
/**
* @param ContentImageConnection $img
*/
private function getPicture($img)
{
$alt = (!empty($img->getAlt())) ? strip_tags((str_replace('"', '', $img->getAlt()))) : '';
$imgOriginalWidth = $img->getImage()->getWidth();
$imgRequestedWidth = $img->getMaxWidth() ?? self::IMG_MAX_SIZE;
$lastImgWidth = (self::IMG_MAX_SIZE > $imgRequestedWidth) ? $imgRequestedWidth : self::IMG_MAX_SIZE;
$path = $this->sd->analyzePath(Context::ORIGIN, $img->getImage()->getPath() . '/' . $img->getImage()->getBasename());
/**
* key - window size
* value - img width
*/
$imgSizes = [
380 => 350,
480 => 460,
576 => 550,
768 => 680,
1024 => 650,
1199 => 750
];
$pictureElement = $this->resizer->setInput($path)
->build()
->defPictureElement();
foreach ($imgSizes as $screen => $imgWidth) {
if ($imgWidth > $imgOriginalWidth) { // if requested img is bigger than original - skip
continue;
}
$pictureElement
->sourceNode()
->mediaMaxWidth($screen)
->resizeNode()
->width($imgWidth)
->endNode()
->endNode();
}
$pictureElement
->imgNode()
->alt($alt)
->resizeNode()
->width($lastImgWidth)
->endNode()
->endNode();
$pictureElement->end()->process();
return $this->resizer->render([]);
}
/**
* @param ContentImageConnection $img
*/
private function getImage($img)
{
$path = $this->sd->analyzePath(Context::ORIGIN, $img->getImage()->getPath() . '/' . $img->getImage()->getBasename());
$width = $img->getImage()->getWidth() < self::IMG_POPUP_SIZE ? $img->getImage()->getWidth() : self::IMG_POPUP_SIZE;
$this->resizer->setInput($path)
->build()
->defResize()
->width($width)
->end()
->process();
return $this->resizer->getResizedImages()->offsetGet(0)->getSrc();
}
}