Example #1
0
 public function redimlive($type, $id, $offset, $width, $height, $resizeMode = 'none')
 {
     $object = ucfirst($type);
     $queryClass = sprintf("Thelia\\Model\\%sImageQuery", $object);
     $filterMethod = sprintf("filterBy%sId", $object);
     // xxxImageQuery::create()
     $method = new \ReflectionMethod($queryClass, 'create');
     /** @var ModelCriteria $search */
     $search = $method->invoke(null);
     // Static !
     // $query->filterByXXX(id)
     $method = new \ReflectionMethod($queryClass, $filterMethod);
     $method->invoke($search, $id);
     $search->orderByPosition(Criteria::ASC)->offset(max(0, $offset - 1))->limit(1);
     if (null !== ($image = $search->findOne())) {
         switch ($resizeMode) {
             case 'crop':
                 $resizeMode = \Thelia\Action\Image::EXACT_RATIO_WITH_CROP;
                 break;
             case 'borders':
                 $resizeMode = \Thelia\Action\Image::EXACT_RATIO_WITH_BORDERS;
                 break;
             case 'none':
             default:
                 $resizeMode = \Thelia\Action\Image::KEEP_IMAGE_RATIO;
         }
         $baseSourceFilePath = ConfigQuery::read('images_library_path');
         if ($baseSourceFilePath === null) {
             $baseSourceFilePath = THELIA_LOCAL_DIR . 'media' . DS . 'images';
         } else {
             $baseSourceFilePath = THELIA_ROOT . $baseSourceFilePath;
         }
         // Put source image file path
         $sourceFilePath = sprintf('%s/%s/%s', $baseSourceFilePath, $object, $image->getFile());
         // Create image processing event
         $event = new ImageEvent($this->getRequest());
         $event->setSourceFilepath($sourceFilePath)->setCacheSubdirectory($object)->setWidth($width)->setHeight($height)->setResizeMode($resizeMode);
         try {
             // Dispatch image processing event
             $this->getDispatcher()->dispatch(TheliaEvents::IMAGE_PROCESS, $event);
             return Response::create(file_get_contents($event->getCacheFilepath()), 200, array('Content-type' => image_type_to_mime_type(exif_imagetype($event->getCacheFilepath()))));
         } catch (\Exception $ex) {
             Tlog::getInstance()->addError(sprintf("Failed to process image: %s", $ex->getMessage()));
             return new Response("", 500);
         }
     } else {
         $this->pageNotFound();
     }
 }
Example #2
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $request = new Request();
     try {
         $event = new ImageEvent($request);
         $subdir = $input->getArgument('subdir');
         if (!is_null($subdir)) {
             $event->setCacheSubdirectory($subdir);
         }
         $this->getDispatcher()->dispatch(TheliaEvents::IMAGE_CLEAR_CACHE, $event);
         $output->writeln(sprintf('%s image cache successfully cleared.', is_null($subdir) ? 'Entire' : ucfirst($subdir)));
     } catch (\Exception $ex) {
         $output->writeln(sprintf("Failed to clear image cache: %s", $ex->getMessage()));
     }
 }
 public function addWatermark(ImageEvent $event)
 {
     $image = $event->getImageObject();
     $size = $image->getSize();
     Tlog::getInstance()->debug("Category: " . $event->getCacheSubdirectory());
     if ($event->getCacheSubdirectory() == 'product' && $size->getHeight() > 200) {
         $imagine = $this->createImagineInstance();
         $watermark = $imagine->open(__DIR__ . DS . '..' . DS . '/Config/watermark.png');
         $watermark->resize($watermark->getSize()->heighten(round(0.1 * $size->getHeight())));
         $wSize = $watermark->getSize();
         $delta = round(0.02 * $size->getHeight());
         $bottomRight = new Point($size->getWidth() - $wSize->getWidth() - $delta, $size->getHeight() - $wSize->getHeight() - $delta);
         $image->paste($watermark, $bottomRight);
     }
 }
Example #4
0
 /**
  * @param LoopResult $loopResult
  *
  * @return LoopResult
  */
 public function parseResults(LoopResult $loopResult)
 {
     /** @var \Carousel\Model\Carousel $carousel */
     foreach ($loopResult->getResultDataCollection() as $carousel) {
         $loopResultRow = new LoopResultRow($carousel);
         $event = new ImageEvent();
         $event->setSourceFilepath($carousel->getUploadDir() . DS . $carousel->getFile())->setCacheSubdirectory('carousel');
         switch ($this->getResizeMode()) {
             case 'crop':
                 $resize_mode = \Thelia\Action\Image::EXACT_RATIO_WITH_CROP;
                 break;
             case 'borders':
                 $resize_mode = \Thelia\Action\Image::EXACT_RATIO_WITH_BORDERS;
                 break;
             case 'none':
             default:
                 $resize_mode = \Thelia\Action\Image::KEEP_IMAGE_RATIO;
         }
         // Prepare tranformations
         $width = $this->getWidth();
         $height = $this->getHeight();
         $rotation = $this->getRotation();
         $background_color = $this->getBackgroundColor();
         $quality = $this->getQuality();
         $effects = $this->getEffects();
         if (!is_null($width)) {
             $event->setWidth($width);
         }
         if (!is_null($height)) {
             $event->setHeight($height);
         }
         $event->setResizeMode($resize_mode);
         if (!is_null($rotation)) {
             $event->setRotation($rotation);
         }
         if (!is_null($background_color)) {
             $event->setBackgroundColor($background_color);
         }
         if (!is_null($quality)) {
             $event->setQuality($quality);
         }
         if (!is_null($effects)) {
             $event->setEffects($effects);
         }
         $event->setAllowZoom($this->getAllowZoom());
         // Dispatch image processing event
         $this->dispatcher->dispatch(TheliaEvents::IMAGE_PROCESS, $event);
         $loopResultRow->set('ID', $carousel->getId())->set("LOCALE", $this->locale)->set("IMAGE_URL", $event->getFileUrl())->set("ORIGINAL_IMAGE_URL", $event->getOriginalFileUrl())->set("IMAGE_PATH", $event->getCacheFilepath())->set("ORIGINAL_IMAGE_PATH", $event->getSourceFilepath())->set("TITLE", $carousel->getVirtualColumn('i18n_TITLE'))->set("CHAPO", $carousel->getVirtualColumn('i18n_CHAPO'))->set("DESCRIPTION", $carousel->getVirtualColumn('i18n_DESCRIPTION'))->set("POSTSCRIPTUM", $carousel->getVirtualColumn('i18n_POSTSCRIPTUM'))->set("ALT", $carousel->getVirtualColumn('i18n_ALT'))->set("URL", $carousel->getUrl())->set('POSITION', $carousel->getPosition());
         $loopResult->addRow($loopResultRow);
     }
     return $loopResult;
 }
Example #5
0
 /**
  * Process image and write the result in the image cache.
  *
  * If the image already exists in cache, the cache file is immediately returned, without any processing
  * If the original (full resolution) image is required, create either a symbolic link with the
  * original image in the cache dir, or copy it in the cache dir.
  *
  * This method updates the cache_file_path and file_url attributes of the event
  *
  * @param ImageEvent $event
  * @param string $eventName
  * @param EventDispatcherInterface $dispatcher
  *
  * @throws \Thelia\Exception\ImageException
  * @throws \InvalidArgumentException
  */
 public function processImage(ImageEvent $event, $eventName, EventDispatcherInterface $dispatcher)
 {
     $subdir = $event->getCacheSubdirectory();
     $source_file = $event->getSourceFilepath();
     if (null == $subdir || null == $source_file) {
         throw new \InvalidArgumentException("Cache sub-directory and source file path cannot be null");
     }
     // Find cached file path
     $cacheFilePath = $this->getCacheFilePath($subdir, $source_file, $event->isOriginalImage(), $event->getOptionsHash());
     $originalImagePathInCache = $this->getCacheFilePath($subdir, $source_file, true);
     if (!file_exists($cacheFilePath)) {
         if (!file_exists($source_file)) {
             throw new ImageException(sprintf("Source image file %s does not exists.", $source_file));
         }
         // Create a cached version of the original image in the web space, if not exists
         if (!file_exists($originalImagePathInCache)) {
             $mode = ConfigQuery::read('original_image_delivery_mode', 'symlink');
             if ($mode == 'symlink') {
                 if (false === symlink($source_file, $originalImagePathInCache)) {
                     throw new ImageException(sprintf("Failed to create symbolic link for %s in %s image cache directory", basename($source_file), $subdir));
                 }
             } else {
                 // mode = 'copy'
                 if (false === @copy($source_file, $originalImagePathInCache)) {
                     throw new ImageException(sprintf("Failed to copy %s in %s image cache directory", basename($source_file), $subdir));
                 }
             }
         }
         // Process image only if we have some transformations to do.
         if (!$event->isOriginalImage()) {
             // We have to process the image.
             $imagine = $this->createImagineInstance();
             $image = $imagine->open($source_file);
             if ($image) {
                 // Allow image pre-processing (watermarging, or other stuff...)
                 $event->setImageObject($image);
                 $dispatcher->dispatch(TheliaEvents::IMAGE_PREPROCESSING, $event);
                 $image = $event->getImageObject();
                 $background_color = $event->getBackgroundColor();
                 $palette = new RGB();
                 if ($background_color != null) {
                     $bg_color = $palette->color($background_color);
                 } else {
                     // Define a fully transparent white background color
                     $bg_color = $palette->color('fff', 0);
                 }
                 // Apply resize
                 $image = $this->applyResize($imagine, $image, $event->getWidth(), $event->getHeight(), $event->getResizeMode(), $bg_color, $event->getAllowZoom());
                 // Rotate if required
                 $rotation = intval($event->getRotation());
                 if ($rotation != 0) {
                     $image->rotate($rotation, $bg_color);
                 }
                 // Flip
                 // Process each effects
                 foreach ($event->getEffects() as $effect) {
                     $effect = trim(strtolower($effect));
                     $params = explode(':', $effect);
                     switch ($params[0]) {
                         case 'greyscale':
                         case 'grayscale':
                             $image->effects()->grayscale();
                             break;
                         case 'negative':
                             $image->effects()->negative();
                             break;
                         case 'horizontal_flip':
                         case 'hflip':
                             $image->flipHorizontally();
                             break;
                         case 'vertical_flip':
                         case 'vflip':
                             $image->flipVertically();
                             break;
                         case 'gamma':
                             // Syntax: gamma:value. Exemple: gamma:0.7
                             if (isset($params[1])) {
                                 $gamma = floatval($params[1]);
                                 $image->effects()->gamma($gamma);
                             }
                             break;
                         case 'colorize':
                             // Syntax: colorize:couleur. Exemple: colorize:#ff00cc
                             if (isset($params[1])) {
                                 $the_color = $palette->color($params[1]);
                                 $image->effects()->colorize($the_color);
                             }
                             break;
                     }
                 }
                 $quality = $event->getQuality();
                 if (is_null($quality)) {
                     $quality = ConfigQuery::read('default_images_quality_percent', 75);
                 }
                 // Allow image post-processing (watermarging, or other stuff...)
                 $event->setImageObject($image);
                 $dispatcher->dispatch(TheliaEvents::IMAGE_POSTPROCESSING, $event);
                 $image = $event->getImageObject();
                 $image->save($cacheFilePath, array('quality' => $quality));
             } else {
                 throw new ImageException(sprintf("Source file %s cannot be opened.", basename($source_file)));
             }
         }
     }
     // Compute the image URL
     $processed_image_url = $this->getCacheFileURL($subdir, basename($cacheFilePath));
     // compute the full resolution image path in cache
     $original_image_url = $this->getCacheFileURL($subdir, basename($originalImagePathInCache));
     // Update the event with file path and file URL
     $event->setCacheFilepath($cacheFilePath);
     $event->setCacheOriginalFilepath($originalImagePathInCache);
     $event->setFileUrl(URL::getInstance()->absoluteUrl($processed_image_url, null, URL::PATH_TO_FILE));
     $event->setOriginalFileUrl(URL::getInstance()->absoluteUrl($original_image_url, null, URL::PATH_TO_FILE));
 }
 /**
  * @param ProductImage $image
  * @return ImageEvent
  */
 public function createProductImageEvent(ProductImage $image)
 {
     $imageEvent = new ImageEvent($this->request);
     $baseSourceFilePath = ConfigQuery::read('images_library_path');
     if ($baseSourceFilePath === null) {
         $baseSourceFilePath = THELIA_LOCAL_DIR . 'media' . DS . 'images';
     } else {
         $baseSourceFilePath = THELIA_ROOT . $baseSourceFilePath;
     }
     // Put source image file path
     $sourceFilePath = sprintf('%s/%s/%s', $baseSourceFilePath, 'product', $image->getFile());
     $imageEvent->setSourceFilepath($sourceFilePath);
     $imageEvent->setCacheSubdirectory('product');
     return $imageEvent;
 }
Example #7
0
 /**
  * Try to clear directory ouside of the cache
  *
  * @expectedException \InvalidArgumentException
  */
 public function testClearUnallowedPathCache()
 {
     $event = new ImageEvent($this->request);
     $event->setDispatcher($this->getDispatcher());
     $event->setCacheSubdirectory('../../../..');
     $image = new Image($this->getFileManager());
     $image->clearCache($event);
 }
Example #8
0
 public function parseResults(LoopResult $loopResult)
 {
     // Create image processing event
     $event = new ImageEvent($this->request);
     // Prepare tranformations
     $width = $this->getWidth();
     $height = $this->getHeight();
     $rotation = $this->getRotation();
     $background_color = $this->getBackgroundColor();
     $quality = $this->getQuality();
     $effects = $this->getEffects();
     if (!is_null($effects)) {
         $effects = explode(',', $effects);
     }
     switch ($this->getResizeMode()) {
         case 'crop':
             $resize_mode = \Thelia\Action\Image::EXACT_RATIO_WITH_CROP;
             break;
         case 'borders':
             $resize_mode = \Thelia\Action\Image::EXACT_RATIO_WITH_BORDERS;
             break;
         case 'none':
         default:
             $resize_mode = \Thelia\Action\Image::KEEP_IMAGE_RATIO;
     }
     foreach ($loopResult->getResultDataCollection() as $result) {
         // Setup required transformations
         if (!is_null($width)) {
             $event->setWidth($width);
         }
         if (!is_null($height)) {
             $event->setHeight($height);
         }
         $event->setResizeMode($resize_mode);
         if (!is_null($rotation)) {
             $event->setRotation($rotation);
         }
         if (!is_null($background_color)) {
             $event->setBackgroundColor($background_color);
         }
         if (!is_null($quality)) {
             $event->setQuality($quality);
         }
         if (!is_null($effects)) {
             $event->setEffects($effects);
         }
         // Put source image file path
         $source_filepath = sprintf("%s%s/%s/%s", THELIA_ROOT, ConfigQuery::read('images_library_path', 'local' . DS . 'media' . DS . 'images'), $this->objectType, $result->getFile());
         $event->setSourceFilepath($source_filepath);
         $event->setCacheSubdirectory($this->objectType);
         $loopResultRow = new LoopResultRow($result);
         $loopResultRow->set("ID", $result->getId())->set("LOCALE", $this->locale)->set("ORIGINAL_IMAGE_PATH", $source_filepath)->set("TITLE", $result->getVirtualColumn('i18n_TITLE'))->set("CHAPO", $result->getVirtualColumn('i18n_CHAPO'))->set("DESCRIPTION", $result->getVirtualColumn('i18n_DESCRIPTION'))->set("POSTSCRIPTUM", $result->getVirtualColumn('i18n_POSTSCRIPTUM'))->set("VISIBLE", $result->getVisible())->set("POSITION", $result->getPosition())->set("OBJECT_TYPE", $this->objectType)->set("OBJECT_ID", $this->objectId);
         $addRow = true;
         $returnErroredImages = $this->getBackendContext() || !$this->getIgnoreProcessingErrors();
         try {
             // Dispatch image processing event
             $this->dispatcher->dispatch(TheliaEvents::IMAGE_PROCESS, $event);
             $loopResultRow->set("IMAGE_URL", $event->getFileUrl())->set("ORIGINAL_IMAGE_URL", $event->getOriginalFileUrl())->set("IMAGE_PATH", $event->getCacheFilepath())->set("PROCESSING_ERROR", false);
         } catch (\Exception $ex) {
             // Ignore the result and log an error
             Tlog::getInstance()->addError(sprintf("Failed to process image in image loop: %s", $ex->getMessage()));
             if ($returnErroredImages) {
                 $loopResultRow->set("IMAGE_URL", '')->set("ORIGINAL_IMAGE_URL", '')->set("IMAGE_PATH", '')->set("PROCESSING_ERROR", true);
             } else {
                 $addRow = false;
             }
         }
         if ($addRow) {
             $this->addOutputFields($loopResultRow, $result);
             $loopResult->addRow($loopResultRow);
         }
     }
     return $loopResult;
 }
 /**
  * @param $type
  * @param RewritingUrl $result
  * @param $configValues
  * @param $sitemap
  */
 protected function generateSitemapImage($type, $result, $configValues, &$sitemap)
 {
     $event = new ImageEvent();
     $event->setWidth($configValues['width'])->setHeight($configValues['height'])->setQuality($configValues['quality'])->setRotation($configValues['rotation'])->setResizeMode($configValues['resizeMode'])->setBackgroundColor($configValues['bgColor'])->setAllowZoom($configValues['allowZoom']);
     // Put source image file path
     $source_filepath = sprintf("%s%s/%s/%s", THELIA_ROOT, ConfigQuery::read('images_library_path', 'local/media/images'), $type, $result->getVirtualColumn('PRODUCT_FILE'));
     $event->setSourceFilepath($source_filepath);
     $event->setCacheSubdirectory($type);
     try {
         // Dispatch image processing event
         $this->dispatch(TheliaEvents::IMAGE_PROCESS, $event);
         // New sitemap image entry
         $sitemap[] = '
         <url>
             <loc>' . URL::getInstance()->absoluteUrl($result->getUrl()) . '</loc>
             <image:image>
                 <image:loc>' . $event->getFileUrl() . '</image:loc>
                 <image:title>' . htmlspecialchars($result->getVirtualColumn('PRODUCT_TITLE')) . '</image:title>
             </image:image>
         </url>';
     } catch (\Exception $ex) {
     }
 }