vendor/pimcore/pimcore/models/Document/Tag/Image.php line 28

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Enterprise License (PEL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  * @category   Pimcore
  12.  * @package    Document
  13.  *
  14.  * @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  15.  * @license    http://www.pimcore.org/license     GPLv3 and PEL
  16.  */
  17. namespace Pimcore\Model\Document\Tag;
  18. use Pimcore\Model;
  19. use Pimcore\Model\Asset;
  20. use Pimcore\Model\Element;
  21. use Pimcore\Tool\Serialize;
  22. /**
  23.  * @method \Pimcore\Model\Document\Tag\Dao getDao()
  24.  */
  25. class Image extends Model\Document\Tag
  26. {
  27.     /**
  28.      * ID of the referenced image
  29.      *
  30.      * @var int
  31.      */
  32.     public $id;
  33.     /**
  34.      * The ALT text of the image
  35.      *
  36.      * @var string
  37.      */
  38.     public $alt;
  39.     /**
  40.      * Contains the imageobject itself
  41.      *
  42.      * @var Asset\Image
  43.      */
  44.     public $image;
  45.     /**
  46.      * @var bool
  47.      */
  48.     public $cropPercent false;
  49.     /**
  50.      * @var float
  51.      */
  52.     public $cropWidth;
  53.     /**
  54.      * @var float
  55.      */
  56.     public $cropHeight;
  57.     /**
  58.      * @var float
  59.      */
  60.     public $cropTop;
  61.     /**
  62.      * @var float
  63.      */
  64.     public $cropLeft;
  65.     /**
  66.      * @var array
  67.      */
  68.     public $hotspots = [];
  69.     /**
  70.      * @var array
  71.      */
  72.     public $marker = [];
  73.     /**
  74.      * @see TagInterface::getType
  75.      *
  76.      * @return string
  77.      */
  78.     public function getType()
  79.     {
  80.         return 'image';
  81.     }
  82.     /**
  83.      * @see TagInterface::getData
  84.      *
  85.      * @return array
  86.      */
  87.     public function getData()
  88.     {
  89.         return [
  90.             'id' => $this->id,
  91.             'alt' => $this->alt,
  92.             'cropPercent' => $this->cropPercent,
  93.             'cropWidth' => $this->cropWidth,
  94.             'cropHeight' => $this->cropHeight,
  95.             'cropTop' => $this->cropTop,
  96.             'cropLeft' => $this->cropLeft,
  97.             'hotspots' => $this->hotspots,
  98.             'marker' => $this->marker
  99.         ];
  100.     }
  101.     /**
  102.      * @return array
  103.      */
  104.     public function getDataForResource()
  105.     {
  106.         return [
  107.             'id' => $this->id,
  108.             'alt' => $this->alt,
  109.             'cropPercent' => $this->cropPercent,
  110.             'cropWidth' => $this->cropWidth,
  111.             'cropHeight' => $this->cropHeight,
  112.             'cropTop' => $this->cropTop,
  113.             'cropLeft' => $this->cropLeft,
  114.             'hotspots' => $this->hotspots,
  115.             'marker' => $this->marker
  116.         ];
  117.     }
  118.     /**
  119.      * Converts the data so it's suitable for the editmode
  120.      *
  121.      * @return array
  122.      */
  123.     public function getDataEditmode()
  124.     {
  125.         $image $this->getImage();
  126.         if ($image instanceof Asset\Image) {
  127.             $rewritePath = function ($data) {
  128.                 if (!is_array($data)) {
  129.                     return [];
  130.                 }
  131.                 foreach ($data as &$element) {
  132.                     if (array_key_exists('data'$element) && is_array($element['data']) && count($element['data']) > 0) {
  133.                         foreach ($element['data'] as &$metaData) {
  134.                             if ($metaData['value'] instanceof Element\ElementInterface) {
  135.                                 $metaData['value'] = $metaData['value']->getRealFullPath();
  136.                             }
  137.                         }
  138.                     }
  139.                 }
  140.                 return $data;
  141.             };
  142.             $marker $rewritePath($this->marker);
  143.             $hotspots $rewritePath($this->hotspots);
  144.             $marker object2array($marker);
  145.             $hotspots object2array($hotspots);
  146.             return [
  147.                 'id' => $this->id,
  148.                 'path' => $image->getFullPath(),
  149.                 'alt' => $this->alt,
  150.                 'cropPercent' => $this->cropPercent,
  151.                 'cropWidth' => $this->cropWidth,
  152.                 'cropHeight' => $this->cropHeight,
  153.                 'cropTop' => $this->cropTop,
  154.                 'cropLeft' => $this->cropLeft,
  155.                 'hotspots' => $hotspots,
  156.                 'marker' => $marker,
  157.                 'predefinedDataTemplates' => $this->getOptions()['predefinedDataTemplates'] ?? null,
  158.             ];
  159.         }
  160.         return null;
  161.     }
  162.     /**
  163.      * @return array
  164.      */
  165.     public function getOptions()
  166.     {
  167.         $options parent::getOptions();
  168.         if (isset($options['thumbnail']) && !isset($options['focal_point_context_menu_item'])) {
  169.             $thumbConfig Asset\Image\Thumbnail\Config::getByAutoDetect($options['thumbnail']);
  170.             if ($thumbConfig) {
  171.                 foreach ($thumbConfig->getItems() as $item) {
  172.                     if ($item['method'] == 'cover') {
  173.                         $options['focal_point_context_menu_item'] = true;
  174.                         $this->options['focal_point_context_menu_item'] = true;
  175.                         break;
  176.                     }
  177.                 }
  178.             }
  179.         }
  180.         return $options;
  181.     }
  182.     /**
  183.      * @see TagInterface::frontend
  184.      *
  185.      * @return string
  186.      */
  187.     public function frontend()
  188.     {
  189.         if (!is_array($this->options)) {
  190.             $this->options = [];
  191.         }
  192.         $image $this->getImage();
  193.         if ($image instanceof Asset) {
  194.             $thumbnailName $this->options['thumbnail'] ?? null;
  195.             if ($thumbnailName || $this->cropPercent) {
  196.                 // create a thumbnail first
  197.                 $autoName false;
  198.                 $thumbConfig $image->getThumbnailConfig($thumbnailName);
  199.                 if (!$thumbConfig && $this->cropPercent) {
  200.                     $thumbConfig = new Asset\Image\Thumbnail\Config();
  201.                 }
  202.                 if ($this->cropPercent) {
  203.                     $this->applyCustomCropping($thumbConfig);
  204.                     $autoName true;
  205.                 }
  206.                 if (isset($this->options['highResolution']) && $this->options['highResolution'] > 1) {
  207.                     $thumbConfig->setHighResolution($this->options['highResolution']);
  208.                 }
  209.                 // autogenerate a name for the thumbnail because it's different from the original
  210.                 if ($autoName) {
  211.                     $hash md5(Serialize::serialize($thumbConfig->getItems()));
  212.                     $thumbConfig->setName($thumbConfig->getName() . '_auto_' $hash);
  213.                 }
  214.                 $deferred true;
  215.                 if (isset($this->options['deferred'])) {
  216.                     $deferred $this->options['deferred'];
  217.                 }
  218.                 $thumbnail $image->getThumbnail($thumbConfig$deferred);
  219.             } else {
  220.                 // we're using the thumbnail class only to generate the HTML
  221.                 $thumbnail $image->getThumbnail();
  222.             }
  223.             $attributes array_merge($this->options, [
  224.                 'alt' => $this->alt,
  225.                 'title' => $this->alt
  226.             ]);
  227.             $removeAttributes = [];
  228.             if (isset($this->options['removeAttributes']) && is_array($this->options['removeAttributes'])) {
  229.                 $removeAttributes $this->options['removeAttributes'];
  230.             }
  231.             // thumbnail's HTML is always generated by the thumbnail itself
  232.             return $thumbnail->getHtml($attributes$removeAttributes);
  233.         }
  234.     }
  235.     /**
  236.      * @param mixed $data
  237.      *
  238.      * @return $this
  239.      */
  240.     public function setDataFromResource($data)
  241.     {
  242.         if (strlen($data) > 2) {
  243.             $data Serialize::unserialize($data);
  244.         }
  245.         $rewritePath = function ($data) {
  246.             if (!is_array($data)) {
  247.                 return [];
  248.             }
  249.             foreach ($data as &$element) {
  250.                 if (array_key_exists('data'$element) && is_array($element['data']) && count($element['data']) > 0) {
  251.                     foreach ($element['data'] as &$metaData) {
  252.                         // this is for backward compatibility (Array vs. MarkerHotspotItem)
  253.                         if (is_array($metaData)) {
  254.                             $metaData = new Element\Data\MarkerHotspotItem($metaData);
  255.                         }
  256.                     }
  257.                 }
  258.             }
  259.             return $data;
  260.         };
  261.         if (array_key_exists('marker'$data) && is_array($data['marker']) && count($data['marker']) > 0) {
  262.             $data['marker'] = $rewritePath($data['marker']);
  263.         }
  264.         if (array_key_exists('hotspots'$data) && is_array($data['hotspots']) && count($data['hotspots']) > 0) {
  265.             $data['hotspots'] = $rewritePath($data['hotspots']);
  266.         }
  267.         $this->id $data['id'] ?? null;
  268.         $this->alt $data['alt'] ?? null;
  269.         $this->cropPercent $data['cropPercent'] ?? null;
  270.         $this->cropWidth $data['cropWidth'] ?? null;
  271.         $this->cropHeight $data['cropHeight'] ?? null;
  272.         $this->cropTop $data['cropTop'] ?? null;
  273.         $this->cropLeft $data['cropLeft'] ?? null;
  274.         $this->marker $data['marker'] ?? null;
  275.         $this->hotspots $data['hotspots'] ?? null;
  276.         return $this;
  277.     }
  278.     /**
  279.      * @param mixed $data
  280.      *
  281.      * @return $this
  282.      */
  283.     public function setDataFromEditmode($data)
  284.     {
  285.         $rewritePath = function ($data) {
  286.             if (!is_array($data)) {
  287.                 return [];
  288.             }
  289.             foreach ($data as &$element) {
  290.                 if (array_key_exists('data'$element) && is_array($element['data']) && count($element['data']) > 0) {
  291.                     foreach ($element['data'] as &$metaData) {
  292.                         $metaData = new Element\Data\MarkerHotspotItem($metaData);
  293.                         if (in_array($metaData['type'], ['object''asset''document'])) {
  294.                             $el Element\Service::getElementByPath($metaData['type'], $metaData->getValue());
  295.                             $metaData['value'] = $el;
  296.                         }
  297.                     }
  298.                 }
  299.             }
  300.             return $data;
  301.         };
  302.         if (is_array($data)) {
  303.             if (array_key_exists('marker'$data) && is_array($data['marker']) && count($data['marker']) > 0) {
  304.                 $data['marker'] = $rewritePath($data['marker']);
  305.             }
  306.             if (array_key_exists('hotspots'$data) && is_array($data['hotspots']) && count($data['hotspots']) > 0) {
  307.                 $data['hotspots'] = $rewritePath($data['hotspots']);
  308.             }
  309.             $this->id $data['id'] ?? null;
  310.             $this->alt $data['alt'] ?? null;
  311.             $this->cropPercent $data['cropPercent'] ?? null;
  312.             $this->cropWidth $data['cropWidth'] ?? null;
  313.             $this->cropHeight $data['cropHeight'] ?? null;
  314.             $this->cropTop $data['cropTop'] ?? null;
  315.             $this->cropLeft $data['cropLeft'] ?? null;
  316.             $this->marker $data['marker'] ?? null;
  317.             $this->hotspots $data['hotspots'] ?? null;
  318.         }
  319.         return $this;
  320.     }
  321.     /**
  322.      * @return string
  323.      */
  324.     public function getText()
  325.     {
  326.         return $this->alt;
  327.     }
  328.     /**
  329.      * @param string $text
  330.      */
  331.     public function setText($text)
  332.     {
  333.         $this->alt $text;
  334.     }
  335.     /**
  336.      * @return string
  337.      */
  338.     public function getAlt()
  339.     {
  340.         return $this->getText();
  341.     }
  342.     /**
  343.      * @return string
  344.      */
  345.     public function getSrc()
  346.     {
  347.         $image $this->getImage();
  348.         if ($image instanceof Asset) {
  349.             return $image->getFullPath();
  350.         }
  351.         return '';
  352.     }
  353.     /**
  354.      * @return Asset\Image
  355.      */
  356.     public function getImage()
  357.     {
  358.         if (!$this->image) {
  359.             $this->image Asset\Image::getById($this->getId());
  360.         }
  361.         return $this->image;
  362.     }
  363.     /**
  364.      * @param Asset\Image $image
  365.      *
  366.      * @return Model\Document\Tag\Image
  367.      */
  368.     public function setImage($image)
  369.     {
  370.         $this->image $image;
  371.         if ($image instanceof Asset) {
  372.             $this->setId($image->getId());
  373.         }
  374.         return $this;
  375.     }
  376.     /**
  377.      * @param int $id
  378.      *
  379.      * @return Model\Document\Tag\Image
  380.      */
  381.     public function setId($id)
  382.     {
  383.         $this->id $id;
  384.         return $this;
  385.     }
  386.     /**
  387.      * @return int
  388.      */
  389.     public function getId()
  390.     {
  391.         return (int) $this->id;
  392.     }
  393.     /**
  394.      * @param string|array|Asset\Image\Thumbnail\Config $conf
  395.      * @param bool $deferred
  396.      *
  397.      * @return Asset\Image\Thumbnail|string
  398.      */
  399.     public function getThumbnail($conf$deferred true)
  400.     {
  401.         $image $this->getImage();
  402.         if ($image instanceof Asset) {
  403.             $thumbConfig $image->getThumbnailConfig($conf);
  404.             if ($thumbConfig && $this->cropPercent) {
  405.                 $this->applyCustomCropping($thumbConfig);
  406.                 $hash md5(Serialize::serialize($thumbConfig->getItems()));
  407.                 $thumbConfig->setName($thumbConfig->getName() . '_auto_' $hash);
  408.             }
  409.             return $image->getThumbnail($thumbConfig$deferred);
  410.         }
  411.         return '';
  412.     }
  413.     /**
  414.      * @param Asset\Image\Thumbnail\Config $thumbConfig
  415.      */
  416.     protected function applyCustomCropping($thumbConfig)
  417.     {
  418.         $cropConfig = [
  419.             'width' => $this->cropWidth,
  420.             'height' => $this->cropHeight,
  421.             'y' => $this->cropTop,
  422.             'x' => $this->cropLeft
  423.         ];
  424.         $thumbConfig->addItemAt(0'cropPercent'$cropConfig);
  425.         // also crop media query specific configs
  426.         if ($thumbConfig->hasMedias()) {
  427.             foreach ($thumbConfig->getMedias() as $mediaName => $mediaItems) {
  428.                 $thumbConfig->addItemAt(0'cropPercent'$cropConfig$mediaName);
  429.             }
  430.         }
  431.     }
  432.     /**
  433.      * @return bool
  434.      */
  435.     public function isEmpty()
  436.     {
  437.         $image $this->getImage();
  438.         if ($image instanceof Asset\Image) {
  439.             return false;
  440.         }
  441.         return true;
  442.     }
  443.     /**
  444.      * @param Model\Document\PageSnippet $ownerDocument
  445.      * @param array $tags
  446.      *
  447.      * @return array|mixed
  448.      *
  449.      * @internal param array $blockedTags
  450.      */
  451.     public function getCacheTags($ownerDocument$tags = [])
  452.     {
  453.         $tags is_array($tags) ? $tags : [];
  454.         $image $this->getImage();
  455.         if ($image instanceof Asset) {
  456.             if (!array_key_exists($image->getCacheTag(), $tags)) {
  457.                 $tags $image->getCacheTags($tags);
  458.             }
  459.         }
  460.         $getMetaDataCacheTags = function ($data$tags) {
  461.             if (!is_array($data)) {
  462.                 return $tags;
  463.             }
  464.             foreach ($data as $element) {
  465.                 if (array_key_exists('data'$element) && is_array($element['data']) && count($element['data']) > 0) {
  466.                     foreach ($element['data'] as $metaData) {
  467.                         if ($metaData['value'] instanceof Element\ElementInterface) {
  468.                             if (!array_key_exists($metaData['value']->getCacheTag(), $tags)) {
  469.                                 $tags $metaData['value']->getCacheTags($tags);
  470.                             }
  471.                         }
  472.                     }
  473.                 }
  474.             }
  475.             return $tags;
  476.         };
  477.         $tags $getMetaDataCacheTags($this->marker$tags);
  478.         $tags $getMetaDataCacheTags($this->hotspots$tags);
  479.         return $tags;
  480.     }
  481.     /**
  482.      * @return array
  483.      */
  484.     public function resolveDependencies()
  485.     {
  486.         $dependencies = [];
  487.         $image $this->getImage();
  488.         if ($image instanceof Asset\Image) {
  489.             $key 'asset_' $image->getId();
  490.             $dependencies[$key] = [
  491.                 'id' => $image->getId(),
  492.                 'type' => 'asset'
  493.             ];
  494.         }
  495.         $getMetaDataDependencies = function ($data$dependencies) {
  496.             if (!is_array($data)) {
  497.                 return $dependencies;
  498.             }
  499.             foreach ($data as $element) {
  500.                 if (array_key_exists('data'$element) && is_array($element['data']) && count($element['data']) > 0) {
  501.                     foreach ($element['data'] as $metaData) {
  502.                         if ($metaData['value'] instanceof Element\ElementInterface) {
  503.                             $dependencies[$metaData['type'] . '_' $metaData['value']->getId()] = [
  504.                                 'id' => $metaData['value']->getId(),
  505.                                 'type' => $metaData['type']
  506.                             ];
  507.                         }
  508.                     }
  509.                 }
  510.             }
  511.             return $dependencies;
  512.         };
  513.         $dependencies $getMetaDataDependencies($this->marker$dependencies);
  514.         $dependencies $getMetaDataDependencies($this->hotspots$dependencies);
  515.         return $dependencies;
  516.     }
  517.     /**
  518.      * @deprecated
  519.      *
  520.      * @param Model\Webservice\Data\Document\Element $wsElement
  521.      * @param Model\Document\PageSnippet $document
  522.      * @param array $params
  523.      * @param Model\Webservice\IdMapperInterface|null $idMapper
  524.      *
  525.      * @throws \Exception
  526.      */
  527.     public function getFromWebserviceImport($wsElement$document null$params = [], $idMapper null)
  528.     {
  529.         $data $this->sanitizeWebserviceData($wsElement->value);
  530.         if ($data->id !== null) {
  531.             $this->alt $data->alt;
  532.             $this->id $data->id;
  533.             if ($idMapper) {
  534.                 $this->id $idMapper->getMappedId('asset'$data->id);
  535.             }
  536.             if (is_numeric($this->id)) {
  537.                 $image $this->getImage();
  538.                 if (!$image instanceof Asset\Image) {
  539.                     if ($idMapper && $idMapper->ignoreMappingFailures()) {
  540.                         $idMapper->recordMappingFailure('document'$this->getDocumentId(), 'asset'$data->id);
  541.                     } else {
  542.                         throw new \Exception('cannot get values from web service import - referenced image with id [ ' $this->id ' ] is unknown');
  543.                     }
  544.                 }
  545.             } else {
  546.                 if ($idMapper && $idMapper->ignoreMappingFailures()) {
  547.                     $idMapper->recordMappingFailure('document'$this->getDocumentId(), 'asset'$data->id);
  548.                 } else {
  549.                     throw new \Exception('cannot get values from web service import - id is not valid');
  550.                 }
  551.             }
  552.         }
  553.     }
  554.     /**
  555.      * @param float $cropHeight
  556.      *
  557.      * @return $this
  558.      */
  559.     public function setCropHeight($cropHeight)
  560.     {
  561.         $this->cropHeight $cropHeight;
  562.         return $this;
  563.     }
  564.     /**
  565.      * @return float
  566.      */
  567.     public function getCropHeight()
  568.     {
  569.         return $this->cropHeight;
  570.     }
  571.     /**
  572.      * @param float $cropLeft
  573.      *
  574.      * @return $this
  575.      */
  576.     public function setCropLeft($cropLeft)
  577.     {
  578.         $this->cropLeft $cropLeft;
  579.         return $this;
  580.     }
  581.     /**
  582.      * @return float
  583.      */
  584.     public function getCropLeft()
  585.     {
  586.         return $this->cropLeft;
  587.     }
  588.     /**
  589.      * @param bool $cropPercent
  590.      *
  591.      * @return $this
  592.      */
  593.     public function setCropPercent($cropPercent)
  594.     {
  595.         $this->cropPercent $cropPercent;
  596.         return $this;
  597.     }
  598.     /**
  599.      * @return bool
  600.      */
  601.     public function getCropPercent()
  602.     {
  603.         return $this->cropPercent;
  604.     }
  605.     /**
  606.      * @param float $cropTop
  607.      *
  608.      * @return $this
  609.      */
  610.     public function setCropTop($cropTop)
  611.     {
  612.         $this->cropTop $cropTop;
  613.         return $this;
  614.     }
  615.     /**
  616.      * @return float
  617.      */
  618.     public function getCropTop()
  619.     {
  620.         return $this->cropTop;
  621.     }
  622.     /**
  623.      * @param float $cropWidth
  624.      *
  625.      * @return $this
  626.      */
  627.     public function setCropWidth($cropWidth)
  628.     {
  629.         $this->cropWidth $cropWidth;
  630.         return $this;
  631.     }
  632.     /**
  633.      * @return float
  634.      */
  635.     public function getCropWidth()
  636.     {
  637.         return $this->cropWidth;
  638.     }
  639.     /**
  640.      * @param array $hotspots
  641.      */
  642.     public function setHotspots($hotspots)
  643.     {
  644.         $this->hotspots $hotspots;
  645.     }
  646.     /**
  647.      * @return array
  648.      */
  649.     public function getHotspots()
  650.     {
  651.         return $this->hotspots;
  652.     }
  653.     /**
  654.      * @param array $marker
  655.      */
  656.     public function setMarker($marker)
  657.     {
  658.         $this->marker $marker;
  659.     }
  660.     /**
  661.      * @return array
  662.      */
  663.     public function getMarker()
  664.     {
  665.         return $this->marker;
  666.     }
  667.     /**
  668.      * Rewrites id from source to target, $idMapping contains
  669.      * array(
  670.      *  "document" => array(
  671.      *      SOURCE_ID => TARGET_ID,
  672.      *      SOURCE_ID => TARGET_ID
  673.      *  ),
  674.      *  "object" => array(...),
  675.      *  "asset" => array(...)
  676.      * )
  677.      *
  678.      * @param array $idMapping
  679.      */
  680.     public function rewriteIds($idMapping)
  681.     {
  682.         if (array_key_exists('asset'$idMapping) and array_key_exists($this->getId(), $idMapping['asset'])) {
  683.             $this->setId($idMapping['asset'][$this->getId()]);
  684.             // reset marker & hotspot information
  685.             $this->setHotspots([]);
  686.             $this->setMarker([]);
  687.             $this->setCropPercent(false);
  688.             $this->setImage(null);
  689.         }
  690.     }
  691.     public function __sleep()
  692.     {
  693.         $finalVars = [];
  694.         $parentVars parent::__sleep();
  695.         $blockedVars = ['image'];
  696.         foreach ($parentVars as $key) {
  697.             if (!in_array($key$blockedVars)) {
  698.                 $finalVars[] = $key;
  699.             }
  700.         }
  701.         return $finalVars;
  702.     }
  703. }