vendor/pimcore/pimcore/models/Asset/Video/ImageThumbnail.php line 102

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 Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Model\Asset\Video;
  15. use Pimcore\Event\AssetEvents;
  16. use Pimcore\Event\FrontendEvents;
  17. use Pimcore\File;
  18. use Pimcore\Logger;
  19. use Pimcore\Model;
  20. use Pimcore\Model\Asset\Image;
  21. use Pimcore\Tool\Storage;
  22. use Symfony\Component\EventDispatcher\GenericEvent;
  23. use Symfony\Component\Lock\LockFactory;
  24. /**
  25.  * @property Model\Asset\Video|null $asset
  26.  */
  27. final class ImageThumbnail
  28. {
  29.     use Model\Asset\Thumbnail\ImageThumbnailTrait;
  30.     /**
  31.      * @internal
  32.      *
  33.      * @var int|null
  34.      */
  35.     protected $timeOffset;
  36.     /**
  37.      * @internal
  38.      *
  39.      * @var Image|null
  40.      */
  41.     protected $imageAsset;
  42.     /**
  43.      * @param Model\Asset\Video|null $asset
  44.      * @param string|array|Image\Thumbnail\Config|null $config
  45.      * @param int|null $timeOffset
  46.      * @param Image|null $imageAsset
  47.      * @param bool $deferred
  48.      */
  49.     public function __construct($asset$config null$timeOffset null$imageAsset null$deferred true)
  50.     {
  51.         $this->asset $asset;
  52.         $this->timeOffset $timeOffset;
  53.         $this->imageAsset $imageAsset;
  54.         $this->config $this->createConfig($config);
  55.         $this->deferred $deferred;
  56.     }
  57.     /**
  58.      * TODO: Pimcore 11: Change method signature to getPath($args = [])
  59.      *
  60.      * @param mixed $args,...
  61.      *
  62.      * @return string
  63.      */
  64.     public function getPath(...$args)
  65.     {
  66.         // TODO: Pimcore 11: remove calling the covertArgsBcLayer() method
  67.         $args $this->convertArgsBcLayer($args);
  68.         // set defaults
  69.         $deferredAllowed $args['deferredAllowed'] ?? true;
  70.         $frontend $args['frontend'] ?? \Pimcore\Tool::isFrontend();
  71.         $pathReference $this->getPathReference($deferredAllowed);
  72.         $path $this->convertToWebPath($pathReference$frontend);
  73.         $event = new GenericEvent($this, [
  74.             'pathReference' => $pathReference,
  75.             'frontendPath' => $path,
  76.         ]);
  77.         \Pimcore::getEventDispatcher()->dispatch($eventFrontendEvents::ASSET_VIDEO_IMAGE_THUMBNAIL);
  78.         $path $event->getArgument('frontendPath');
  79.         return $path;
  80.     }
  81.     /**
  82.      * @internal
  83.      *
  84.      * @param bool $deferredAllowed
  85.      *
  86.      * @throws \Exception
  87.      */
  88.     public function generate($deferredAllowed true)
  89.     {
  90.         $deferred $deferredAllowed && $this->deferred;
  91.         $generated false;
  92.         if ($this->asset && empty($this->pathReference)) {
  93.             $cs $this->asset->getCustomSetting('image_thumbnail_time');
  94.             $im $this->asset->getCustomSetting('image_thumbnail_asset');
  95.             if ($im || $this->imageAsset) {
  96.                 if ($this->imageAsset) {
  97.                     $im $this->imageAsset;
  98.                 } else {
  99.                     $im Model\Asset::getById($im);
  100.                 }
  101.                 if ($im instanceof Image) {
  102.                     $imageThumbnail $im->getThumbnail($this->getConfig());
  103.                     $this->pathReference $imageThumbnail->getPathReference();
  104.                 }
  105.             }
  106.             if (empty($this->pathReference)) {
  107.                 $timeOffset $this->timeOffset;
  108.                 if (!is_numeric($timeOffset) && is_numeric($cs)) {
  109.                     $timeOffset $cs;
  110.                 }
  111.                 // fallback
  112.                 if (!is_numeric($timeOffset) && $this->asset instanceof Model\Asset\Video) {
  113.                     $timeOffset ceil($this->asset->getDuration() / 3);
  114.                 }
  115.                 $storage Storage::get('asset_cache');
  116.                 $cacheFilePath sprintf(
  117.                     '%s/%s/image-thumb__%s__video_original_image/time_%s.png',
  118.                     rtrim($this->asset->getRealPath(), '/'),
  119.                     $this->asset->getId(),
  120.                     $this->asset->getId(),
  121.                     $timeOffset
  122.                 );
  123.                 if (!$storage->fileExists($cacheFilePath)) {
  124.                     $lock \Pimcore::getContainer()->get(LockFactory::class)->createLock($cacheFilePath);
  125.                     $lock->acquire(true);
  126.                     // after we got the lock, check again if the image exists in the meantime - if not - generate it
  127.                     if (!$storage->fileExists($cacheFilePath)) {
  128.                         $tempFile File::getLocalTempFilePath('png');
  129.                         $converter \Pimcore\Video::getInstance();
  130.                         $converter->load($this->asset->getLocalFile());
  131.                         $converter->saveImage($tempFile$timeOffset);
  132.                         $generated true;
  133.                         $storage->write($cacheFilePathfile_get_contents($tempFile));
  134.                     }
  135.                     $lock->release();
  136.                 }
  137.                 $cacheFileStream $storage->readStream($cacheFilePath);
  138.                 if ($this->getConfig()) {
  139.                     $this->getConfig()->setFilenameSuffix('time-' $timeOffset);
  140.                     try {
  141.                         $this->pathReference Image\Thumbnail\Processor::process(
  142.                             $this->asset,
  143.                             $this->getConfig(),
  144.                             $cacheFileStream,
  145.                             $deferred,
  146.                             $generated
  147.                         );
  148.                     } catch (\Exception $e) {
  149.                         Logger::error("Couldn't create image-thumbnail of video " $this->asset->getRealFullPath() . ': ' $e);
  150.                     }
  151.                 }
  152.             }
  153.         }
  154.         if (empty($this->pathReference)) {
  155.             $this->pathReference = [
  156.                 'type' => 'error',
  157.                 'src' => '/bundles/pimcoreadmin/img/filetype-not-supported.svg',
  158.             ];
  159.         }
  160.         $event = new GenericEvent($this, [
  161.             'deferred' => $deferred,
  162.             'generated' => $generated,
  163.         ]);
  164.         \Pimcore::getEventDispatcher()->dispatch($eventAssetEvents::VIDEO_IMAGE_THUMBNAIL);
  165.     }
  166.     /**
  167.      * Get the public path to the thumbnail image.
  168.      * This method is here for backwards compatility.
  169.      * Up to Pimcore 1.4.8 a thumbnail was returned as a path to an image.
  170.      *
  171.      * @return string Public path to thumbnail image.
  172.      */
  173.     public function __toString()
  174.     {
  175.         return $this->getPath();
  176.     }
  177.     /**
  178.      * @param string|array|Image\Thumbnail\Config $selector
  179.      *
  180.      * @return Image\Thumbnail\Config|null
  181.      *
  182.      * @throws Model\Exception\NotFoundException
  183.      */
  184.     private function createConfig($selector)
  185.     {
  186.         $thumbnailConfig Image\Thumbnail\Config::getByAutoDetect($selector);
  187.         if (!empty($selector) && $thumbnailConfig === null) {
  188.             throw new Model\Exception\NotFoundException('Thumbnail definition "' . (is_string($selector) ? $selector '') . '" does not exist');
  189.         }
  190.         return $thumbnailConfig;
  191.     }
  192.     /**
  193.      * @param string $name
  194.      * @param int $highRes
  195.      *
  196.      * @return Image\Thumbnail|null
  197.      *
  198.      * @throws \Exception
  199.      */
  200.     public function getMedia($name$highRes 1)
  201.     {
  202.         $thumbConfig $this->getConfig();
  203.         if ($thumbConfig instanceof Image\Thumbnail\Config) {
  204.             $mediaConfigs $thumbConfig->getMedias();
  205.             if (isset($mediaConfigs[$name])) {
  206.                 $thumbConfigRes = clone $thumbConfig;
  207.                 $thumbConfigRes->selectMedia($name);
  208.                 $thumbConfigRes->setHighResolution($highRes);
  209.                 $thumbConfigRes->setMedias([]);
  210.                 $imgId $this->asset->getCustomSetting('image_thumbnail_asset');
  211.                 $img Model\Asset::getById($imgId);
  212.                 if ($img instanceof Image) {
  213.                     $thumb $img->getThumbnail($thumbConfigRes);
  214.                 }
  215.                 return $thumb ?? null;
  216.             } else {
  217.                 throw new \Exception("Media query '" $name "' doesn't exist in thumbnail configuration: " $thumbConfig->getName());
  218.             }
  219.         }
  220.         return null;
  221.     }
  222. }