Inheritance: extends Pimcore\Model\AbstractModel
Beispiel #1
1
 /**
  * Returns the configuration for the image thumbnail with the given ID.
  */
 public function imageThumbnailAction()
 {
     $this->checkUserPermission("thumbnails");
     try {
         $id = $this->getParam("id");
         if ($id) {
             $config = Asset\Image\Thumbnail\Config::getByName($id);
             if (!$config instanceof Asset\Image\Thumbnail\Config) {
                 throw new \Exception("Thumbnail '" . $id . "' file doesn't exists");
             }
             $this->encoder->encode(["success" => true, "data" => $config->getForWebserviceExport()]);
             return;
         }
     } catch (\Exception $e) {
         \Logger::error($e);
         $this->encoder->encode(["success" => false, "msg" => (string) $e]);
     }
     $this->encoder->encode(["success" => false]);
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // get all thumbnails
     $dir = Asset\Image\Thumbnail\Config::getWorkingDir();
     $thumbnails = array();
     $files = scandir($dir);
     foreach ($files as $file) {
         if (strpos($file, ".xml")) {
             $thumbnails[] = str_replace(".xml", "", $file);
         }
     }
     $allowedThumbs = array();
     if ($input->getOption("thumbnails")) {
         $allowedThumbs = explode(",", $input->getOption("thumbnails"));
     }
     // get only images
     $conditions = array("type = 'image'");
     if ($input->getOption("parent")) {
         $parent = Asset::getById($input->getOption("parent"));
         if ($parent instanceof Asset\Folder) {
             $conditions[] = "path LIKE '" . $parent->getFullPath() . "/%'";
         } else {
             $this->writeError($input->getOption("parent") . " is not a valid asset folder ID!");
             exit;
         }
     }
     $list = new Asset\Listing();
     $list->setCondition(implode(" AND ", $conditions));
     $total = $list->getTotalCount();
     $perLoop = 10;
     for ($i = 0; $i < ceil($total / $perLoop); $i++) {
         $list->setLimit($perLoop);
         $list->setOffset($i * $perLoop);
         $images = $list->load();
         foreach ($images as $image) {
             foreach ($thumbnails as $thumbnail) {
                 if (empty($allowedThumbs) && !$input->getOption("system") || in_array($thumbnail, $allowedThumbs)) {
                     if ($input->getOption("force")) {
                         $image->clearThumbnail($thumbnail);
                     }
                     $this->output->writeln("generating thumbnail for image: " . $image->getFullpath() . " | " . $image->getId() . " | Thumbnail: " . $thumbnail . " : " . formatBytes(memory_get_usage()));
                     $this->output->writeln("generated thumbnail: " . $image->getThumbnail($thumbnail));
                 }
             }
             if ($input->getOption("system")) {
                 $thumbnail = Asset\Image\Thumbnail\Config::getPreviewConfig();
                 if ($input->getOption("force")) {
                     $image->clearThumbnail($thumbnail->getName());
                 }
                 $this->output->writeln("generating thumbnail for image: " . $image->getFullpath() . " | " . $image->getId() . " | Thumbnail: System Preview (tree) : " . formatBytes(memory_get_usage()));
                 $this->output->writeln("generated thumbnail: " . $image->getThumbnail($thumbnail));
             }
         }
         \Pimcore::collectGarbage();
     }
 }
Beispiel #3
0
 /**
  * Loads a list of predefined properties for the specicifies parameters, returns an array of Property\Predefined elements
  *
  * @return array
  */
 public function load()
 {
     $properties = array();
     $propertiesData = $this->db->fetchAll($this->model->getFilter(), $this->model->getOrder());
     foreach ($propertiesData as $propertyData) {
         $properties[] = Config::getByName($propertyData["id"]);
     }
     $this->model->setThumbnails($properties);
     return $properties;
 }
Beispiel #4
0
 /**
  * @param $thumbnailName
  * @param int $page
  * @param bool $deferred $deferred deferred means that the image will be generated on-the-fly (details see below)
  * @return mixed|string
  */
 public function getImageThumbnail($thumbnailName, $page = 1, $deferred = false)
 {
     // just 4 testing
     //$this->clearThumbnails(true);
     if (!\Pimcore\Document::isAvailable()) {
         \Logger::error("Couldn't create image-thumbnail of document " . $this->getFullPath() . " no document adapter is available");
         return "/pimcore/static/img/filetype-not-supported.png";
     }
     $thumbnail = Image\Thumbnail\Config::getByAutoDetect($thumbnailName);
     $thumbnail->setName("document_" . $thumbnail->getName() . "-" . $page);
     try {
         if (!$deferred) {
             $converter = \Pimcore\Document::getInstance();
             $converter->load($this->getFileSystemPath());
             $path = PIMCORE_TEMPORARY_DIRECTORY . "/document-image-cache/document_" . $this->getId() . "__thumbnail_" . $page . ".png";
             if (!is_dir(dirname($path))) {
                 \Pimcore\File::mkdir(dirname($path));
             }
             $lockKey = "document-thumbnail-" . $this->getId() . "-" . $page;
             if (!is_file($path) && !Model\Tool\Lock::isLocked($lockKey)) {
                 Model\Tool\Lock::lock($lockKey);
                 $converter->saveImage($path, $page);
                 Model\Tool\Lock::release($lockKey);
             } else {
                 if (Model\Tool\Lock::isLocked($lockKey)) {
                     return "/pimcore/static/img/please-wait.png";
                 }
             }
         }
         if ($thumbnail) {
             $path = Image\Thumbnail\Processor::process($this, $thumbnail, $path, $deferred);
         }
         return preg_replace("@^" . preg_quote(PIMCORE_DOCUMENT_ROOT) . "@", "", $path);
     } catch (\Exception $e) {
         \Logger::error("Couldn't create image-thumbnail of document " . $this->getFullPath());
         \Logger::error($e);
     }
     return "/pimcore/static/img/filetype-not-supported.png";
 }
Beispiel #5
0
 /**
  * @return void
  */
 protected function update()
 {
     // only do this if the file exists and contains data
     if ($this->getDataChanged() || !$this->getCustomSetting("imageDimensionsCalculated")) {
         try {
             // save the current data into a tmp file to calculate the dimensions, otherwise updates wouldn't be updated
             // because the file is written in parent::update();
             $tmpFile = $this->getTemporaryFile();
             $dimensions = $this->getDimensions($tmpFile, true);
             unlink($tmpFile);
             if ($dimensions && $dimensions["width"]) {
                 $this->setCustomSetting("imageWidth", $dimensions["width"]);
                 $this->setCustomSetting("imageHeight", $dimensions["height"]);
             }
         } catch (\Exception $e) {
             Logger::error("Problem getting the dimensions of the image with ID " . $this->getId());
         }
         // this is to be downward compatible so that the controller can check if the dimensions are already calculated
         // and also to just do the calculation once, because the calculation can fail, an then the controller tries to
         // calculate the dimensions on every request an also will create a version, ...
         $this->setCustomSetting("imageDimensionsCalculated", true);
     }
     parent::update();
     $this->clearThumbnails();
     // now directly create "system" thumbnails (eg. for the tree, ...)
     if ($this->getDataChanged()) {
         try {
             $path = $this->getThumbnail(Image\Thumbnail\Config::getPreviewConfig())->getFileSystemPath();
             // set the modification time of the thumbnail to the same time from the asset
             // so that the thumbnail check doesn't fail in Asset\Image\Thumbnail\Processor::process();
             // we need the @ in front of touch because of some stream wrapper (eg. s3) which don't support touch()
             @touch($path, $this->getModificationDate());
         } catch (\Exception $e) {
             Logger::error("Problem while creating system-thumbnails for image " . $this->getRealFullPath());
             Logger::error($e);
         }
     }
 }
Beispiel #6
0
    }
}
$list = new Asset\Listing();
$list->setCondition(implode(" AND ", $conditions));
$total = $list->getTotalCount();
$perLoop = 10;
for ($i = 0; $i < ceil($total / $perLoop); $i++) {
    $list->setLimit($perLoop);
    $list->setOffset($i * $perLoop);
    $images = $list->load();
    foreach ($images as $image) {
        foreach ($thumbnails as $thumbnail) {
            if (empty($allowedThumbs) && !$opts->getOption("system") || in_array($thumbnail, $allowedThumbs)) {
                if ($opts->getOption("force")) {
                    $image->clearThumbnail($thumbnail);
                }
                echo "generating thumbnail for image: " . $image->getFullpath() . " | " . $image->getId() . " | Thumbnail: " . $thumbnail . " : " . formatBytes(memory_get_usage()) . " \n";
                echo "generated thumbnail: " . $image->getThumbnail($thumbnail) . "\n";
            }
        }
        if ($opts->getOption("system")) {
            $thumbnail = Asset\Image\Thumbnail\Config::getPreviewConfig();
            if ($opts->getOption("force")) {
                $image->clearThumbnail($thumbnail->getName());
            }
            echo "generating thumbnail for image: " . $image->getFullpath() . " | " . $image->getId() . " | Thumbnail: System Preview (tree) : " . formatBytes(memory_get_usage()) . " \n";
            echo "generated thumbnail: " . $image->getThumbnail($thumbnail) . "\n";
        }
    }
    \Pimcore::collectGarbage();
}
Beispiel #7
0
 /**
  * @param $selector
  * @return bool|static
  */
 protected function createConfig($selector)
 {
     $config = Image\Thumbnail\Config::getByAutoDetect($selector);
     if ($config) {
         $format = strtolower($config->getFormat());
         if ($format == "source") {
             $config->setFormat("PNG");
         }
     }
     return $config;
 }
 /**
  * Returns a list of all image thumbnails.
  */
 public function imageThumbnailsAction()
 {
     $this->checkUserPermission("thumbnails");
     $dir = Asset\Image\Thumbnail\Config::getWorkingDir();
     $pipelines = array();
     $files = scandir($dir);
     foreach ($files as $file) {
         if (strpos($file, ".xml")) {
             $name = str_replace(".xml", "", $file);
             $pipelines[] = array("id" => $name, "text" => $name);
         }
     }
     $this->encoder->encode(array("success" => true, "data" => $pipelines));
 }
 public function thumbnailUpdateAction()
 {
     $this->checkPermission("thumbnails");
     $pipe = Asset\Image\Thumbnail\Config::getByName($this->getParam("name"));
     $settingsData = \Zend_Json::decode($this->getParam("settings"));
     $mediaData = \Zend_Json::decode($this->getParam("medias"));
     foreach ($settingsData as $key => $value) {
         $setter = "set" . ucfirst($key);
         if (method_exists($pipe, $setter)) {
             $pipe->{$setter}($value);
         }
     }
     $pipe->resetItems();
     foreach ($mediaData as $mediaName => $items) {
         foreach ($items as $item) {
             $type = $item["type"];
             unset($item["type"]);
             $pipe->addItem($type, $item, $mediaName);
         }
     }
     $pipe->save();
     $this->deleteThumbnailTmpFiles($pipe);
     $this->_helper->json(array("success" => true));
 }
Beispiel #10
0
 /**
  * @see Document\Tag\TagInterface::frontend
  * @return string
  */
 public function frontend()
 {
     if (!is_array($this->options)) {
         $this->options = array();
     }
     $image = $this->getImage();
     if ($image instanceof Asset) {
         if (isset($this->options["thumbnail"]) && $this->options["thumbnail"] || $this->cropPercent) {
             // create a thumbnail first
             $autoName = false;
             $thumbConfig = $image->getThumbnailConfig($this->options["thumbnail"]);
             if (!$thumbConfig && $this->cropPercent) {
                 $thumbConfig = new Asset\Image\Thumbnail\Config();
             }
             if ($this->cropPercent) {
                 $cropConfig = array("width" => $this->cropWidth, "height" => $this->cropHeight, "y" => $this->cropTop, "x" => $this->cropLeft);
                 $thumbConfig->addItemAt(0, "cropPercent", $cropConfig);
                 // also crop media query specific configs
                 if ($thumbConfig->hasMedias()) {
                     foreach ($thumbConfig->getMedias() as $mediaName => $mediaItems) {
                         $thumbConfig->addItemAt(0, "cropPercent", $cropConfig, $mediaName);
                     }
                 }
                 $autoName = true;
             }
             if ($this->options["highResolution"] && $this->options["highResolution"] > 1) {
                 $thumbConfig->setHighResolution($this->options["highResolution"]);
             }
             // autogenerate a name for the thumbnail because it's different from the original
             if ($autoName) {
                 $hash = md5(Serialize::serialize($thumbConfig->getItems()));
                 $thumbConfig->setName($thumbConfig->getName() . "_auto_" . $hash);
             }
             $imagePath = $image->getThumbnail($thumbConfig);
         } else {
             $imagePath = $image->getFullPath();
         }
         $altText = $this->alt;
         $titleText = $this->alt;
         if (empty($titleText)) {
             if ($this->getImage()->getMetadata("title")) {
                 $titleText = $this->getImage()->getMetadata("title");
             }
         }
         if (empty($altText)) {
             if ($this->getImage()->getMetadata("alt")) {
                 $altText = $this->getImage()->getMetadata("alt");
             } else {
                 $altText = $titleText;
             }
         }
         // get copyright from asset
         if ($this->getImage()->getMetadata("copyright")) {
             if (!empty($altText)) {
                 $altText .= " | ";
             }
             if (!empty($titleText)) {
                 $titleText .= " | ";
             }
             $altText .= "© " . $this->getImage()->getMetadata("copyright");
             $titleText .= "© " . $this->getImage()->getMetadata("copyright");
         }
         $defaultAttributes = array("alt" => $altText);
         if (!empty($titleText)) {
             $defaultAttributes["title"] = $titleText;
         }
         // add attributes to image
         $allowedAttributes = array("alt", "align", "border", "height", "hspace", "ismap", "longdesc", "usemap", "vspace", "width", "class", "dir", "id", "lang", "style", "title", "xml:lang", "onmouseover", "onabort", "onclick", "ondblclick", "onmousedown", "onmousemove", "onmouseout", "onmouseup", "onkeydown", "onkeypress", "onkeyup", "itemprop", "itemscope", "itemtype", "disableWidthHeightAttributes");
         $htmlEscapeAttributes = array("alt", "align", "border", "height", "hspace", "longdesc", "usemap", "vspace", "width", "class", "dir", "id", "lang", "title");
         $customAttributes = array();
         if (array_key_exists("attributes", $this->options) && is_array($this->options["attributes"])) {
             $customAttributes = $this->options["attributes"];
         }
         $availableAttribs = array_merge($this->options, $defaultAttributes, $customAttributes);
         $attribs = [];
         $attribsRaw = [];
         foreach ($availableAttribs as $key => $value) {
             if ((is_string($value) || is_numeric($value) || is_bool($value)) && (in_array($key, $allowedAttributes) || array_key_exists($key, $customAttributes))) {
                 $attribsRaw[$key] = $value;
                 if (in_array($key, $htmlEscapeAttributes)) {
                     $value = htmlspecialchars($value);
                 }
                 $attribs[] = $key . '="' . $value . '"';
             }
         }
         if ($imagePath instanceof Asset\Image\Thumbnail) {
             // thumbnail's HTML is always generated by the thumbnail itself
             return $imagePath->getHTML($attribsRaw);
         } else {
             return '<img src="' . $imagePath . '" ' . implode(" ", $attribs) . ' />';
         }
     }
 }
Beispiel #11
0
 /**
  * Get a thumbnail image configuration.
  * @param mixed $selector Name, array or object describing a thumbnail configuration.
  * @return Thumbnail\Config
  */
 protected function createConfig($selector)
 {
     return Thumbnail\Config::getByAutoDetect($selector);
 }
 /**
  * @param \Zend_Controller_Request_Abstract $request
  */
 public function routeStartup(\Zend_Controller_Request_Abstract $request)
 {
     // this is a filter which checks for common used files (by browser, crawlers, ...) and prevent the default
     // error page, because this is more resource-intensive than exiting right here
     if (preg_match("@^/website/var/tmp/image-thumbnails(.*)?/([0-9]+)/thumb__([a-zA-Z0-9_\\-]+)([^\\@]+)(\\@[0-9.]+x)?\\.([a-zA-Z]{2,5})@", $request->getPathInfo(), $matches)) {
         $assetId = $matches[2];
         $thumbnailName = $matches[3];
         $format = $matches[6];
         if ($asset = Asset::getById($assetId)) {
             try {
                 $page = 1;
                 $thumbnailFile = null;
                 $thumbnailConfig = null;
                 $deferredConfigId = "thumb_" . $assetId . "__" . md5($request->getPathInfo());
                 if ($thumbnailConfigItem = TmpStore::get($deferredConfigId)) {
                     $thumbnailConfig = $thumbnailConfigItem->getData();
                     TmpStore::delete($deferredConfigId);
                     if (!$thumbnailConfig instanceof Asset\Image\Thumbnail\Config) {
                         throw new \Exception("Deferred thumbnail config file doesn't contain a valid \\Asset\\Image\\Thumbnail\\Config object");
                     }
                     $tmpPage = array_pop(explode("-", $thumbnailName));
                     if (is_numeric($tmpPage)) {
                         $page = $tmpPage;
                     }
                 } else {
                     //get thumbnail for e.g. pdf page thumb__document_pdfPage-5
                     if (preg_match("|document_(.*)\\-(\\d+)\$|", $thumbnailName, $matchesThumbs)) {
                         $thumbnailName = $matchesThumbs[1];
                         $page = (int) $matchesThumbs[2];
                     }
                     // just check if the thumbnail exists -> throws exception otherwise
                     $thumbnailConfig = Asset\Image\Thumbnail\Config::getByName($thumbnailName);
                 }
                 if ($asset instanceof Asset\Document) {
                     $thumbnailConfig->setName(preg_replace("/\\-[\\d]+/", "", $thumbnailConfig->getName()));
                     $thumbnailConfig->setName(str_replace("document_", "", $thumbnailConfig->getName()));
                     $thumbnailFile = PIMCORE_DOCUMENT_ROOT . $asset->getImageThumbnail($thumbnailConfig, $page);
                 } else {
                     if ($asset instanceof Asset\Image) {
                         //check if high res image is called
                         if (array_key_exists(5, $matches)) {
                             $highResFactor = (double) str_replace(array("@", "x"), "", $matches[5]);
                             $thumbnailConfig->setHighResolution($highResFactor);
                         }
                         $thumbnailFile = PIMCORE_DOCUMENT_ROOT . $asset->getThumbnail($thumbnailConfig);
                     }
                 }
                 if ($thumbnailFile && file_exists($thumbnailFile)) {
                     $fileExtension = \Pimcore\File::getFileExtension($thumbnailFile);
                     if (in_array($fileExtension, array("gif", "jpeg", "jpeg", "png", "pjpeg"))) {
                         header("Content-Type: image/" . $fileExtension, true);
                     } else {
                         header("Content-Type: " . $asset->getMimetype(), true);
                     }
                     header("Content-Length: " . filesize($thumbnailFile), true);
                     while (@ob_end_flush()) {
                     }
                     flush();
                     readfile($thumbnailFile);
                     exit;
                 }
             } catch (\Exception $e) {
                 // nothing to do
                 \Logger::error("Thumbnail with name '" . $thumbnailName . "' doesn't exist");
             }
         }
     }
 }
Beispiel #13
0
 /**
  * @param \Zend_Controller_Request_Abstract $request
  */
 public function routeStartup(\Zend_Controller_Request_Abstract $request)
 {
     // this is a filter which checks for common used files (by browser, crawlers, ...) and prevent the default
     // error page, because this is more resource-intensive than exiting right here
     if (preg_match("@/image-thumbnails(.*)?/([0-9]+)/thumb__([a-zA-Z0-9_\\-]+)([^\\@]+)(\\@[0-9.]+x)?\\.([a-zA-Z]{2,5})@", rawurldecode($request->getPathInfo()), $matches)) {
         $assetId = $matches[2];
         $thumbnailName = $matches[3];
         if ($asset = Asset::getById($assetId)) {
             try {
                 $page = 1;
                 // default
                 $thumbnailFile = null;
                 $thumbnailConfig = null;
                 //get thumbnail for e.g. pdf page thumb__document_pdfPage-5
                 if (preg_match("|document_(.*)\\-(\\d+)\$|", $thumbnailName, $matchesThumbs)) {
                     $thumbnailName = $matchesThumbs[1];
                     $page = (int) $matchesThumbs[2];
                 }
                 // just check if the thumbnail exists -> throws exception otherwise
                 $thumbnailConfig = Asset\Image\Thumbnail\Config::getByName($thumbnailName);
                 if (!$thumbnailConfig) {
                     // check if there's an item in the TmpStore
                     $deferredConfigId = "thumb_" . $assetId . "__" . md5($matches[0]);
                     if ($thumbnailConfigItem = TmpStore::get($deferredConfigId)) {
                         $thumbnailConfig = $thumbnailConfigItem->getData();
                         TmpStore::delete($deferredConfigId);
                         if (!$thumbnailConfig instanceof Asset\Image\Thumbnail\Config) {
                             throw new \Exception("Deferred thumbnail config file doesn't contain a valid \\Asset\\Image\\Thumbnail\\Config object");
                         }
                     }
                 }
                 if (!$thumbnailConfig) {
                     throw new \Exception("Thumbnail '" . $thumbnailName . "' file doesn't exists");
                 }
                 if ($asset instanceof Asset\Document) {
                     $thumbnailConfig->setName(preg_replace("/\\-[\\d]+/", "", $thumbnailConfig->getName()));
                     $thumbnailConfig->setName(str_replace("document_", "", $thumbnailConfig->getName()));
                     $thumbnailFile = $asset->getImageThumbnail($thumbnailConfig, $page)->getFileSystemPath();
                 } elseif ($asset instanceof Asset\Image) {
                     //check if high res image is called
                     if (array_key_exists(5, $matches)) {
                         $highResFactor = (double) str_replace(["@", "x"], "", $matches[5]);
                         $thumbnailConfig->setHighResolution($highResFactor);
                     }
                     // check if a media query thumbnail was requested
                     if (preg_match("#~\\-~([\\d]+w)#", $matches[4], $mediaQueryResult)) {
                         $thumbnailConfig->selectMedia($mediaQueryResult[1]);
                     }
                     $thumbnailFile = $asset->getThumbnail($thumbnailConfig)->getFileSystemPath();
                 }
                 if ($thumbnailFile && file_exists($thumbnailFile)) {
                     // set appropriate caching headers
                     // see also: https://github.com/pimcore/pimcore/blob/1931860f0aea27de57e79313b2eb212dcf69ef13/.htaccess#L86-L86
                     $lifetime = 86400 * 7;
                     // 1 week lifetime, same as direct delivery in .htaccess
                     header("Cache-Control: public, max-age=" . $lifetime);
                     header("Expires: " . date("D, d M Y H:i:s T", time() + $lifetime));
                     $fileExtension = \Pimcore\File::getFileExtension($thumbnailFile);
                     if (in_array($fileExtension, ["gif", "jpeg", "jpeg", "png", "pjpeg"])) {
                         header("Content-Type: image/" . $fileExtension, true);
                     } else {
                         header("Content-Type: " . $asset->getMimetype(), true);
                     }
                     header("Content-Length: " . filesize($thumbnailFile), true);
                     while (@ob_end_flush()) {
                     }
                     flush();
                     readfile($thumbnailFile);
                     exit;
                 }
             } catch (\Exception $e) {
                 // nothing to do
                 Logger::error("Thumbnail with name '" . $thumbnailName . "' doesn't exist");
             }
         }
     }
 }
Beispiel #14
0
 /**
  * how many frames, delay in seconds between frames, pimcore thumbnail configuration
  *
  * @param int $frames
  * @param int $delay
  * @param null $thumbnail
  * @return string
  */
 public function getPreviewAnimatedGif($frames = 10, $delay = 200, $thumbnail = null)
 {
     if (!$frames) {
         $frames = 10;
     }
     if (!$delay) {
         $delay = 200;
         // no clue which unit this has ;-)
     }
     $thumbnailUniqueId = md5(serialize([$thumbnail, $frames, $delay]));
     $animGifPath = PIMCORE_TEMPORARY_DIRECTORY . "/video-image-cache/video_" . $this->getId() . "_" . $thumbnailUniqueId . ".gif";
     if (!is_file($animGifPath)) {
         $duration = $this->getDuration();
         $sampleRate = floor($duration / $frames);
         $thumbnails = [];
         $delays = [];
         $thumbnailConfig = $this->getImageThumbnailConfig($thumbnail);
         if (!$thumbnailConfig) {
             $thumbnailConfig = new Image\Thumbnail\Config();
         }
         $thumbnailConfig->setFormat("GIF");
         for ($i = 0; $i <= $frames; $i++) {
             $frameImage = $this->getImageThumbnail($thumbnailConfig, $i * $sampleRate);
             $frameImage = PIMCORE_DOCUMENT_ROOT . $frameImage;
             if (preg_match("/\\.gif\$/", $frameImage) && filesize($frameImage) > 10) {
                 // check if the image is correct and not a "not supported" placeholder
                 $thumbnails[] = $frameImage;
                 $delays[] = $delay;
             }
         }
         try {
             $animator = new \Pimcore\Image\GifAnimator($thumbnails, $delays, 0, 2, 255, 255, 255, "url");
             $animGifContent = $animator->GetAnimation();
         } catch (\Exception $e) {
             \Logger::error($e);
             $animGifContent = file_get_contents($thumbnails[0]);
         }
         File::put($animGifPath, $animGifContent);
     }
     $animGifPath = preg_replace("@^" . preg_quote(PIMCORE_DOCUMENT_ROOT, "@") . "@", "", $animGifPath);
     return $animGifPath;
 }
Beispiel #15
0
 /**
  * @param $asset
  * @param Config $config
  * @param null $fileSystemPath
  * @param bool $deferred deferred means that the image will be generated on-the-fly (details see below)
  * @param bool $returnAbsolutePath
  * @param bool $generated
  * @return mixed|string
  */
 public static function process($asset, Config $config, $fileSystemPath = null, $deferred = false, $returnAbsolutePath = false, &$generated = false)
 {
     $generated = false;
     $errorImage = PIMCORE_PATH . "/static6/img/filetype-not-supported.png";
     $format = strtolower($config->getFormat());
     $contentOptimizedFormat = false;
     if (!$fileSystemPath && $asset instanceof Asset) {
         $fileSystemPath = $asset->getFileSystemPath();
     }
     if ($asset instanceof Asset) {
         $id = $asset->getId();
     } else {
         $id = "dyn~" . crc32($fileSystemPath);
     }
     $fileExt = File::getFileExtension(basename($fileSystemPath));
     // simple detection for source type if SOURCE is selected
     if ($format == "source" || empty($format)) {
         $format = self::getAllowedFormat($fileExt, ["jpeg", "gif", "png"], "png");
         $contentOptimizedFormat = true;
         // format can change depending of the content (alpha-channel, ...)
     }
     if ($format == "print") {
         $format = self::getAllowedFormat($fileExt, ["svg", "jpeg", "png", "tiff"], "png");
         if (($format == "tiff" || $format == "svg") && \Pimcore\Tool::isFrontentRequestByAdmin()) {
             // return a webformat in admin -> tiff cannot be displayed in browser
             $format = "png";
             $deferred = false;
             // deferred is default, but it's not possible when using isFrontentRequestByAdmin()
         } elseif ($format == "tiff") {
             $transformations = $config->getItems();
             if (is_array($transformations) && count($transformations) > 0) {
                 foreach ($transformations as $transformation) {
                     if (!empty($transformation)) {
                         if ($transformation["method"] == "tifforiginal") {
                             return self::returnPath($fileSystemPath, $returnAbsolutePath);
                         }
                     }
                 }
             }
         } elseif ($format == "svg") {
             return self::returnPath($fileSystemPath, $returnAbsolutePath);
         }
     } elseif ($format == "tiff") {
         if (\Pimcore\Tool::isFrontentRequestByAdmin()) {
             // return a webformat in admin -> tiff cannot be displayed in browser
             $format = "png";
             $deferred = false;
             // deferred is default, but it's not possible when using isFrontentRequestByAdmin()
         }
     }
     $thumbDir = $asset->getImageThumbnailSavePath() . "/thumb__" . $config->getName();
     $filename = preg_replace("/\\." . preg_quote(File::getFileExtension($asset->getFilename())) . "/", "", $asset->getFilename());
     // add custom suffix if available
     if ($config->getFilenameSuffix()) {
         $filename .= "~-~" . $config->getFilenameSuffix();
     }
     // add high-resolution modifier suffix to the filename
     if ($config->getHighResolution() > 1) {
         $filename .= "@" . $config->getHighResolution() . "x";
     }
     $fileExtension = $format;
     if ($format == "original") {
         $fileExtension = \Pimcore\File::getFileExtension($fileSystemPath);
     }
     $filename .= "." . $fileExtension;
     $fsPath = $thumbDir . "/" . $filename;
     // deferred means that the image will be generated on-the-fly (when requested by the browser)
     // the configuration is saved for later use in Pimcore\Controller\Plugin\Thumbnail::routeStartup()
     // so that it can be used also with dynamic configurations
     if ($deferred) {
         // only add the config to the TmpStore if necessary (the config is auto-generated)
         if (!Config::getByName($config->getName())) {
             $configId = "thumb_" . $id . "__" . md5(str_replace(PIMCORE_TEMPORARY_DIRECTORY, "", $fsPath));
             TmpStore::add($configId, $config, "thumbnail_deferred");
         }
         return self::returnPath($fsPath, $returnAbsolutePath);
     }
     // all checks on the file system should be below the deferred part for performance reasons (remote file systems)
     if (!file_exists($fileSystemPath)) {
         return self::returnPath($errorImage, $returnAbsolutePath);
     }
     if (!is_dir(dirname($fsPath))) {
         File::mkdir(dirname($fsPath));
     }
     $path = self::returnPath($fsPath, false);
     // check for existing and still valid thumbnail
     if (is_file($fsPath) and filemtime($fsPath) >= filemtime($fileSystemPath)) {
         return self::returnPath($fsPath, $returnAbsolutePath);
     }
     // transform image
     $image = Asset\Image::getImageTransformInstance();
     $image->setPreserveColor($config->isPreserveColor());
     $image->setPreserveMetaData($config->isPreserveMetaData());
     if (!$image->load($fileSystemPath)) {
         return self::returnPath($errorImage, $returnAbsolutePath);
     }
     $image->setUseContentOptimizedFormat($contentOptimizedFormat);
     $startTime = StopWatch::microtime_float();
     $transformations = $config->getItems();
     // check if the original image has an orientation exif flag
     // if so add a transformation at the beginning that rotates and/or mirrors the image
     if (function_exists("exif_read_data")) {
         $exif = @exif_read_data($fileSystemPath);
         if (is_array($exif)) {
             if (array_key_exists("Orientation", $exif)) {
                 $orientation = intval($exif["Orientation"]);
                 if ($orientation > 1) {
                     $angleMappings = [2 => 180, 3 => 180, 4 => 180, 5 => 90, 6 => 90, 7 => 90, 8 => 270];
                     if (array_key_exists($orientation, $angleMappings)) {
                         array_unshift($transformations, ["method" => "rotate", "arguments" => ["angle" => $angleMappings[$orientation]]]);
                     }
                     // values that have to be mirrored, this is not very common, but should be covered anyway
                     $mirrorMappings = [2 => "vertical", 4 => "horizontal", 5 => "vertical", 7 => "horizontal"];
                     if (array_key_exists($orientation, $mirrorMappings)) {
                         array_unshift($transformations, ["method" => "mirror", "arguments" => ["mode" => $mirrorMappings[$orientation]]]);
                     }
                 }
             }
         }
     }
     if (is_array($transformations) && count($transformations) > 0) {
         $sourceImageWidth = PHP_INT_MAX;
         $sourceImageHeight = PHP_INT_MAX;
         if ($asset instanceof Asset\Image) {
             $sourceImageWidth = $asset->getWidth();
             $sourceImageHeight = $asset->getHeight();
         }
         $highResFactor = $config->getHighResolution();
         $calculateMaxFactor = function ($factor, $original, $new) {
             $newFactor = $factor * $original / $new;
             if ($newFactor < 1) {
                 // don't go below factor 1
                 $newFactor = 1;
             }
             return $newFactor;
         };
         // sorry for the goto/label - but in this case it makes life really easier and the code more readable
         prepareTransformations:
         foreach ($transformations as $transformation) {
             if (!empty($transformation)) {
                 $arguments = [];
                 $mapping = self::$argumentMapping[$transformation["method"]];
                 if (is_array($transformation["arguments"])) {
                     foreach ($transformation["arguments"] as $key => $value) {
                         $position = array_search($key, $mapping);
                         if ($position !== false) {
                             // high res calculations if enabled
                             if (!in_array($transformation["method"], ["cropPercent"]) && in_array($key, ["width", "height", "x", "y"])) {
                                 if ($highResFactor && $highResFactor > 1) {
                                     $value *= $highResFactor;
                                     $value = (int) ceil($value);
                                     // check if source image is big enough otherwise adjust the high-res factor
                                     if (in_array($key, ["width", "x"])) {
                                         if ($sourceImageWidth < $value) {
                                             $highResFactor = $calculateMaxFactor($highResFactor, $sourceImageWidth, $value);
                                             goto prepareTransformations;
                                         }
                                     } elseif (in_array($key, ["height", "y"])) {
                                         if ($sourceImageHeight < $value) {
                                             $highResFactor = $calculateMaxFactor($highResFactor, $sourceImageHeight, $value);
                                             goto prepareTransformations;
                                         }
                                     }
                                 }
                             }
                             $arguments[$position] = $value;
                         }
                     }
                 }
                 ksort($arguments);
                 if (method_exists($image, $transformation["method"])) {
                     call_user_func_array([$image, $transformation["method"]], $arguments);
                 }
             }
         }
     }
     $image->save($fsPath, $format, $config->getQuality());
     $generated = true;
     if ($contentOptimizedFormat) {
         $tmpStoreKey = str_replace(PIMCORE_TEMPORARY_DIRECTORY . "/", "", $fsPath);
         TmpStore::add($tmpStoreKey, "-", "image-optimize-queue");
     }
     clearstatcache();
     Logger::debug("Thumbnail " . $path . " generated in " . (StopWatch::microtime_float() - $startTime) . " seconds");
     // set proper permissions
     @chmod($fsPath, File::getDefaultMode());
     // quick bugfix / workaround, it seems that imagemagick / image optimizers creates sometimes empty PNG chunks (total size 33 bytes)
     // no clue why it does so as this is not continuous reproducible, and this is the only fix we can do for now
     // if the file is corrupted the file will be created on the fly when requested by the browser (because it's deleted here)
     if (is_file($fsPath) && filesize($fsPath) < 50) {
         unlink($fsPath);
     }
     return self::returnPath($fsPath, $returnAbsolutePath);
 }
Beispiel #16
0
 /**
  * @param null $thumbnailName
  * @return mixed
  */
 public function getThumbnail($thumbnailName = null)
 {
     if (!$this->getImage()) {
         return "";
     }
     $crop = null;
     if (is_array($this->getCrop())) {
         $crop = $this->getCrop();
     }
     $thumbConfig = $this->getImage()->getThumbnailConfig($thumbnailName);
     if (!$thumbConfig && $crop) {
         $thumbConfig = new Asset\Image\Thumbnail\Config();
     }
     if ($crop) {
         $thumbConfig->addItemAt(0, "cropPercent", array("width" => $crop["cropWidth"], "height" => $crop["cropHeight"], "y" => $crop["cropTop"], "x" => $crop["cropLeft"]));
         $hash = md5(\Pimcore\Tool\Serialize::serialize($thumbConfig->getItems()));
         $thumbConfig->setName($thumbConfig->getName() . "_auto_" . $hash);
     }
     return $this->getImage()->getThumbnail($thumbConfig);
 }
 public function getDocumentThumbnailAction()
 {
     $document = Asset::getById(intval($this->getParam("id")));
     $thumbnail = Asset\Image\Thumbnail\Config::getByAutoDetect($this->getAllParams());
     $format = strtolower($thumbnail->getFormat());
     if ($format == "source") {
         $thumbnail->setFormat("jpeg");
         // default format for documents is JPEG not PNG (=too big)
     }
     if ($this->getParam("treepreview")) {
         $thumbnail = Asset\Image\Thumbnail\Config::getPreviewConfig();
     }
     $page = 1;
     if (is_numeric($this->getParam("page"))) {
         $page = (int) $this->getParam("page");
     }
     $thumbnailFile = PIMCORE_DOCUMENT_ROOT . $document->getImageThumbnail($thumbnail, $page);
     $format = "png";
     header("Content-type: image/" . $format, true);
     header("Content-Length: " . filesize($thumbnailFile), true);
     $this->sendThumbnailCacheHeaders();
     while (@ob_end_flush()) {
     }
     flush();
     readfile($thumbnailFile);
     exit;
 }
Beispiel #18
0
 /**
  * @param $asset
  * @param Config $config
  * @param null $fileSystemPath
  * @param bool $deferred deferred means that the image will be generated on-the-fly (details see below)
  * @return mixed|string
  */
 public static function process($asset, Config $config, $fileSystemPath = null, $deferred = false)
 {
     $format = strtolower($config->getFormat());
     $contentOptimizedFormat = false;
     if (!$fileSystemPath && $asset instanceof Asset) {
         $fileSystemPath = $asset->getFileSystemPath();
     }
     if ($asset instanceof Asset) {
         $id = $asset->getId();
     } else {
         $id = "dyn~" . crc32($fileSystemPath);
     }
     if (!file_exists($fileSystemPath)) {
         return "/pimcore/static/img/filetype-not-supported.png";
     }
     $modificationDate = filemtime($fileSystemPath);
     $fileExt = File::getFileExtension(basename($fileSystemPath));
     // simple detection for source type if SOURCE is selected
     if ($format == "source" || empty($format)) {
         $format = self::getAllowedFormat($fileExt, array("jpeg", "gif", "png"), "png");
         $contentOptimizedFormat = true;
         // format can change depending of the content (alpha-channel, ...)
     }
     if ($format == "print") {
         $format = self::getAllowedFormat($fileExt, array("svg", "jpeg", "png", "tiff"), "png");
         if (($format == "tiff" || $format == "svg") && \Pimcore\Tool::isFrontentRequestByAdmin()) {
             // return a webformat in admin -> tiff cannot be displayed in browser
             $format = "png";
         } else {
             if ($format == "tiff") {
                 $transformations = $config->getItems();
                 if (is_array($transformations) && count($transformations) > 0) {
                     foreach ($transformations as $transformation) {
                         if (!empty($transformation)) {
                             if ($transformation["method"] == "tifforiginal") {
                                 return str_replace(PIMCORE_DOCUMENT_ROOT, "", $fileSystemPath);
                             }
                         }
                     }
                 }
             } else {
                 if ($format == "svg") {
                     return str_replace(PIMCORE_DOCUMENT_ROOT, "", $fileSystemPath);
                 }
             }
         }
     }
     $thumbDir = $asset->getImageThumbnailSavePath() . "/thumb__" . $config->getName();
     $filename = preg_replace("/\\." . preg_quote(File::getFileExtension($asset->getFilename())) . "/", "", $asset->getFilename());
     // add custom suffix if available
     if ($config->getFilenameSuffix()) {
         $filename .= "~-~" . $config->getFilenameSuffix();
     }
     // add high-resolution modifier suffix to the filename
     if ($config->getHighResolution() > 1) {
         $filename .= "@" . $config->getHighResolution() . "x";
     }
     $filename .= "." . $format;
     $fsPath = $thumbDir . "/" . $filename;
     if (!is_dir(dirname($fsPath))) {
         File::mkdir(dirname($fsPath));
     }
     $path = str_replace(PIMCORE_DOCUMENT_ROOT, "", $fsPath);
     // check for existing and still valid thumbnail
     if (is_file($fsPath) and filemtime($fsPath) >= $modificationDate) {
         return $path;
     }
     // deferred means that the image will be generated on-the-fly (when requested by the browser)
     // the configuration is saved for later use in Pimcore\Controller\Plugin\Thumbnail::routeStartup()
     // so that it can be used also with dynamic configurations
     if ($deferred) {
         $configId = "thumb_" . $id . "__" . md5($path);
         TmpStore::add($configId, $config, "thumbnail_deferred");
         return $path;
     }
     // transform image
     $image = Asset\Image::getImageTransformInstance();
     if (!$image->load($fileSystemPath)) {
         return "/pimcore/static/img/filetype-not-supported.png";
     }
     $image->setUseContentOptimizedFormat($contentOptimizedFormat);
     $startTime = StopWatch::microtime_float();
     $transformations = $config->getItems();
     // check if the original image has an orientation exif flag
     // if so add a transformation at the beginning that rotates and/or mirrors the image
     if (function_exists("exif_read_data")) {
         $exif = @exif_read_data($fileSystemPath);
         if (is_array($exif)) {
             if (array_key_exists("Orientation", $exif)) {
                 $orientation = intval($exif["Orientation"]);
                 if ($orientation > 1) {
                     $angleMappings = [2 => 180, 3 => 180, 4 => 180, 5 => 90, 6 => 90, 7 => 90, 8 => 270];
                     if (array_key_exists($orientation, $angleMappings)) {
                         array_unshift($transformations, ["method" => "rotate", "arguments" => ["angle" => $angleMappings[$orientation]]]);
                     }
                     // values that have to be mirrored, this is not very common, but should be covered anyway
                     $mirrorMappings = [2 => "vertical", 4 => "horizontal", 5 => "vertical", 7 => "horizontal"];
                     if (array_key_exists($orientation, $mirrorMappings)) {
                         array_unshift($transformations, ["method" => "mirror", "arguments" => ["mode" => $mirrorMappings[$orientation]]]);
                     }
                 }
             }
         }
     }
     if (is_array($transformations) && count($transformations) > 0) {
         foreach ($transformations as $transformation) {
             if (!empty($transformation)) {
                 $arguments = array();
                 $mapping = self::$argumentMapping[$transformation["method"]];
                 if (is_array($transformation["arguments"])) {
                     foreach ($transformation["arguments"] as $key => $value) {
                         $position = array_search($key, $mapping);
                         if ($position !== false) {
                             // high res calculations if enabled
                             if (!in_array($transformation["method"], ["cropPercent"]) && in_array($key, array("width", "height", "x", "y"))) {
                                 if ($config->getHighResolution() && $config->getHighResolution() > 1) {
                                     $value *= $config->getHighResolution();
                                 }
                             }
                             $arguments[$position] = $value;
                         }
                     }
                 }
                 ksort($arguments);
                 call_user_func_array(array($image, $transformation["method"]), $arguments);
             }
         }
     }
     $image->save($fsPath, $format, $config->getQuality());
     if ($contentOptimizedFormat) {
         $tmpStoreKey = str_replace(PIMCORE_TEMPORARY_DIRECTORY . "/", "", $fsPath);
         TmpStore::add($tmpStoreKey, "-", "image-optimize-queue");
     }
     clearstatcache();
     \Logger::debug("Thumbnail " . $path . " generated in " . (StopWatch::microtime_float() - $startTime) . " seconds");
     // set proper permissions
     @chmod($fsPath, File::getDefaultMode());
     // quick bugfix / workaround, it seems that imagemagick / image optimizers creates sometimes empty PNG chunks (total size 33 bytes)
     // no clue why it does so as this is not continuous reproducible, and this is the only fix we can do for now
     // if the file is corrupted the file will be created on the fly when requested by the browser (because it's deleted here)
     if (is_file($fsPath) && filesize($fsPath) < 50) {
         unlink($fsPath);
     }
     return $path;
 }
// create legacy config folder
$legacyFolder = PIMCORE_CONFIGURATION_DIRECTORY . "/LEGACY";
if (!is_dir($legacyFolder)) {
    mkdir($legacyFolder, 0777, true);
}
// IMAGE THUMBNAILS
$dir = PIMCORE_CONFIGURATION_DIRECTORY . "/imagepipelines";
if (is_dir($dir)) {
    $file = Pimcore\Config::locateConfigFile("image-thumbnails");
    $json = \Pimcore\Db\JsonFileTable::get($file);
    $json->truncate();
    $files = scandir($dir);
    foreach ($files as $file) {
        if (strpos($file, ".xml")) {
            $name = str_replace(".xml", "", $file);
            $thumbnail = Asset\Image\Thumbnail\Config::getByName($name);
            $thumbnail = object2array($thumbnail);
            $thumbnail["id"] = $thumbnail["name"];
            unset($thumbnail["name"]);
            $json->insertOrUpdate($thumbnail, $thumbnail["id"]);
        }
    }
    // move data
    rename($dir, $legacyFolder . "/imagepipelines");
}
// VIDEO THUMBNAILS
$dir = PIMCORE_CONFIGURATION_DIRECTORY . "/videopipelines";
if (is_dir($dir)) {
    $file = Pimcore\Config::locateConfigFile("video-thumbnails");
    $json = \Pimcore\Db\JsonFileTable::get($file);
    $json->truncate();