Added image action and loop
This commit is contained in:
237
core/lib/Thelia/Core/Event/ImageEvent.php
Normal file
237
core/lib/Thelia/Core/Event/ImageEvent.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Core\Event;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Model\Cart;
|
||||
|
||||
class ImageEvent extends ActionEvent
|
||||
{
|
||||
/**
|
||||
* @var string The complete file name (with path) of the source image
|
||||
*/
|
||||
protected $source_filepath = null;
|
||||
/**
|
||||
* @var string The target subdirectory in the image cache
|
||||
*/
|
||||
protected $cache_subdirectory = null;
|
||||
|
||||
/**
|
||||
* @var string The absolute URL of the cached image (in the web space)
|
||||
*/
|
||||
protected $file_url = null;
|
||||
|
||||
/**
|
||||
* @var string The absolute path of the cached image file
|
||||
*/
|
||||
protected $cache_filepath = null;
|
||||
|
||||
/**
|
||||
* @var string The image category (i.e. the subdirectory in image cache)
|
||||
*/
|
||||
protected $category = null;
|
||||
|
||||
/**
|
||||
* @var integer the required image width
|
||||
*/
|
||||
protected $width = null;
|
||||
|
||||
/**
|
||||
* @var int the required image height
|
||||
*/
|
||||
protected $height = null;
|
||||
|
||||
/**
|
||||
* @var string the resize mode, either crop, bands, none
|
||||
*/
|
||||
protected $resize_mode = null;
|
||||
|
||||
/**
|
||||
* @var string the background color in RGB format (eg. #ff8000)
|
||||
*/
|
||||
protected $background_color = null;
|
||||
|
||||
/**
|
||||
* @var array a list of effects (grayscale, negative, mirror...), applied in the specified order.
|
||||
*/
|
||||
protected $effects = array();
|
||||
|
||||
/**
|
||||
* @var int the rotation angle in degrees, none if zero or null
|
||||
*/
|
||||
protected $rotation = null;
|
||||
|
||||
/**
|
||||
* @var int the quality of the result image, from 0 (!) to 100
|
||||
*/
|
||||
protected $quality = null;
|
||||
|
||||
/**
|
||||
* @return boolean true if the required image is the original image
|
||||
*/
|
||||
public function isOriginalImage() {
|
||||
return
|
||||
empty($this->width)
|
||||
&& empty($this->height)
|
||||
&& empty($this->resize_mode)
|
||||
&& empty($this->background_color)
|
||||
&& empty($this->effects)
|
||||
&& empty($this->rotation)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string a hash identifiying the processing options
|
||||
*/
|
||||
public function getSignature() {
|
||||
return md5(
|
||||
$this->width
|
||||
. $this->height
|
||||
. $this->resize_mode
|
||||
. $this->background_color
|
||||
. implode(',', $this->effects)
|
||||
. $this->rotation
|
||||
);
|
||||
}
|
||||
|
||||
public function getCategory()
|
||||
{
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function setCategory($category)
|
||||
{
|
||||
$this->category = $category;
|
||||
}
|
||||
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
public function setWidth($width)
|
||||
{
|
||||
$this->width = $width;
|
||||
}
|
||||
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
public function setHeight($height)
|
||||
{
|
||||
$this->height = $height;
|
||||
}
|
||||
|
||||
public function getResizeMode()
|
||||
{
|
||||
return $this->resize_mode;
|
||||
}
|
||||
|
||||
public function setResizeMode($resize_mode)
|
||||
{
|
||||
$this->resize_mode = $resize_mode;
|
||||
}
|
||||
|
||||
public function getBackgroundColor()
|
||||
{
|
||||
return $this->background_color;
|
||||
}
|
||||
|
||||
public function setBackgroundColor($background_color)
|
||||
{
|
||||
$this->background_color = $background_color;
|
||||
}
|
||||
|
||||
public function getEffects()
|
||||
{
|
||||
return $this->effects;
|
||||
}
|
||||
|
||||
public function setEffects(array $effects)
|
||||
{
|
||||
$this->effects = $effects;
|
||||
}
|
||||
|
||||
public function getRotation()
|
||||
{
|
||||
return $this->rotation;
|
||||
}
|
||||
|
||||
public function setRotation($rotation)
|
||||
{
|
||||
$this->rotation = $rotation;
|
||||
}
|
||||
|
||||
public function getFileUrl()
|
||||
{
|
||||
return $this->file_url;
|
||||
}
|
||||
|
||||
public function setFileUrl($file_url)
|
||||
{
|
||||
$this->file_url = $file_url;
|
||||
}
|
||||
|
||||
public function getCacheFilepath()
|
||||
{
|
||||
return $this->cache_filepath;
|
||||
}
|
||||
|
||||
public function setCacheFilepath($cache_filepath)
|
||||
{
|
||||
$this->cache_filepath = $cache_filepath;
|
||||
}
|
||||
|
||||
public function getSourceFilepath()
|
||||
{
|
||||
return $this->source_filepath;
|
||||
}
|
||||
|
||||
public function setSourceFilepath($source_filepath)
|
||||
{
|
||||
$this->source_filepath = $source_filepath;
|
||||
}
|
||||
|
||||
public function getCacheSubdirectory()
|
||||
{
|
||||
return $this->cache_subdirectory;
|
||||
}
|
||||
|
||||
public function setCacheSubdirectory($cache_subdirectory)
|
||||
{
|
||||
$this->cache_subdirectory = $cache_subdirectory;
|
||||
}
|
||||
|
||||
public function getQuality()
|
||||
{
|
||||
return $this->quality;
|
||||
}
|
||||
|
||||
public function setQuality($quality)
|
||||
{
|
||||
$this->quality = $quality;
|
||||
}
|
||||
|
||||
}
|
||||
263
core/lib/Thelia/Core/Template/Loop/Image.php
Normal file
263
core/lib/Thelia/Core/Template/Loop/Image.php
Normal file
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Core\Template\Loop;
|
||||
use Thelia\Core\Template\Element\BaseLoop;
|
||||
use Thelia\Core\Template\Loop\Argument\Argument;
|
||||
use Thelia\Core\Event\ImageEvent;
|
||||
use Thelia\Model\CategoryImageQuery;
|
||||
use Thelia\Model\ProductImageQuery;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
|
||||
/**
|
||||
* The image loop
|
||||
*
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
*/
|
||||
class Image extends BaseLoop
|
||||
{
|
||||
/**
|
||||
* @var array Possible image sources
|
||||
*/
|
||||
protected $possible_sources = array('category', 'product', 'folder', 'content');
|
||||
|
||||
/**
|
||||
* Dynamically create the search query, and set the proper filter and order
|
||||
*
|
||||
* @return ModelCriteria the propel Query object
|
||||
*/
|
||||
protected function getSearchQuery() {
|
||||
|
||||
$search = null;
|
||||
|
||||
foreach($this->possible_sources as $source) {
|
||||
|
||||
$argValue = intval($this->getArgValue($source));
|
||||
|
||||
if ($argValue > 0) {
|
||||
|
||||
$object = ucfirst($source);
|
||||
|
||||
$queryClass = sprintf("%sImageQuery", $object);
|
||||
$filterMethod = sprintf("filterBy%s", $object);
|
||||
$mapClass = sprintf("\Thelia\Model\Map\%sI18nTableMap", $object);
|
||||
|
||||
// xxxImageQuery::create()
|
||||
$method = new \ReflectionMethod($queryClass, 'create');
|
||||
$search = $reflectionMethod->invoke(null); // Static !
|
||||
|
||||
// $query->filterByXXX($id)
|
||||
$method = new \ReflectionMethod($queryClass, $filterMethod);
|
||||
$method->invoke($search, $argValue);
|
||||
|
||||
$map = new \ReflectionClass($mapClass);
|
||||
$title_map = $map->getConstant('TITLE');
|
||||
|
||||
$orders = $this->getOrder();
|
||||
|
||||
// Results ordering
|
||||
foreach ($orders as $order) {
|
||||
switch ($order) {
|
||||
case "alpha":
|
||||
$search->addAscendingOrderByColumn($title_map);
|
||||
break;
|
||||
case "alpha-reverse":
|
||||
$search->addDescendingOrderByColumn($title_map);
|
||||
break;
|
||||
case "manual-reverse":
|
||||
$search->orderByPosition(Criteria::DESC);
|
||||
break;
|
||||
case "manual":
|
||||
$search->orderByPosition(Criteria::ASC);
|
||||
break;
|
||||
case "random":
|
||||
$search->clearOrderByColumns();
|
||||
$search->addAscendingOrderByColumn('RAND()');
|
||||
break(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($search == null)
|
||||
throw new \InvalidArgumentException(sprintf("Unable to find image source. Valid sources are %s", implode(',', $this->possible_sources)));
|
||||
|
||||
return $search;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param unknown $pagination
|
||||
*/
|
||||
public function exec($pagination)
|
||||
{
|
||||
// Select the proper query to use
|
||||
$search = $this->getSearchQuery();
|
||||
|
||||
$id = $this->getId();
|
||||
|
||||
if (! is_null($id)) {
|
||||
$search->filterById($id, Criteria::IN);
|
||||
}
|
||||
|
||||
$exclude = $this->getExclude();
|
||||
if (!is_null($exclude))
|
||||
$search->filterById($exclude, Criteria::NOT_IN);
|
||||
|
||||
// Create image processing event
|
||||
$event = new ImageEvent($this->request);
|
||||
|
||||
// Prepare tranformations
|
||||
// Setup required transformations
|
||||
$width = $this->getWidth();
|
||||
$height = $this->getHeight();
|
||||
$resize_mode = $this->getResizeMode();
|
||||
$rotation = $this->getRotation();
|
||||
$background_color = $this->getBackgroundColor();
|
||||
$quality = $this->getQuality();
|
||||
$effects = $this->getEffects();
|
||||
$effects = $this->getEffects();
|
||||
if (! is_null($effects)) {
|
||||
$effects = explode(',', $effects);
|
||||
}
|
||||
|
||||
/**
|
||||
* \Criteria::INNER_JOIN in second parameter for joinWithI18n exclude query without translation.
|
||||
*
|
||||
* @todo : verify here if we want results for row without translations.
|
||||
*/
|
||||
|
||||
$search->joinWithI18n(
|
||||
$this->request->getSession()->getLocale(),
|
||||
(ConfigQuery::read("default_lang_without_translation", 1)) ? Criteria::LEFT_JOIN : Criteria::INNER_JOIN
|
||||
);
|
||||
|
||||
$results = $this->search($search, $pagination);
|
||||
|
||||
$loopResult = new LoopResult();
|
||||
|
||||
foreach ($results as $result) {
|
||||
|
||||
// Create image processing event
|
||||
$event = new ImageEvent($this->request);
|
||||
|
||||
// Setup required transformations
|
||||
if (! is_null($width)) $event->setWidth($width);
|
||||
if (! is_null($height)) $event->setHeigth($height);
|
||||
if (! is_null($resize_mode)) $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);
|
||||
|
||||
// Dispatch image processing event
|
||||
$this->dispatcher->dispatch(TheliaEvents::IMAGE_PROCESS, $event);
|
||||
|
||||
$loopResultRow = new LoopResultRow();
|
||||
|
||||
$loopResultRow
|
||||
->set("ID", $result->getId())
|
||||
->set("IMAGE_URL", $event->getFileUrl())
|
||||
->set("FILE_URL", $event->
|
||||
;
|
||||
|
||||
$loopResult->addRow($loopResultRow);
|
||||
}
|
||||
|
||||
return $loopResult;
|
||||
/*
|
||||
#PRODUIT : identifiant du produit associé (valué si le paramètre "produit" a été indiqué)
|
||||
#PRODTITRE : titre du produit associé (valué si le paramètre "produit" a été indiqué)
|
||||
#PRODREF : référence du produit associé (valué si le paramètre "produit" a été indiqué)
|
||||
#RUBRIQUE : identifiant de la rubrique associée (valué si le paramètre "rubrique" a été indiqué)
|
||||
#RUBTITRE : titre de la rubrique associée (valué si le paramètre "rubrique" a été indiqué)
|
||||
#DOSSIER : identifiant du dossier associée (valué si le paramètre "dossier" a été indiqué)
|
||||
#DOSTITRE : titre du dossier associée (valué si le paramètre "dossier" a été indiqué)
|
||||
#CONTENU : identifiant du contenu associée (valué si le paramètre "contenu" a été indiqué)
|
||||
#CONTTITRE : titre du contenu associée (valué si le paramètre "contenu" a été indiqué)
|
||||
#IMAGE : URL de l'image transformée (redimensionnée, inversée, etc. suivant les paramètres d'entrée de la boucle).
|
||||
#FICHIER : URL de l'image originale
|
||||
#ID : identifiant de l'image
|
||||
#TITRE : titre de l'image
|
||||
#CHAPO : description courte de l'image
|
||||
#DESCRIPTION : description longue de l'image
|
||||
#COMPT : compteur débutant à 1. Utile pour l'utilisation de Javascript.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection
|
||||
*/
|
||||
protected function getArgDefinitions()
|
||||
{
|
||||
$collection = new ArgumentCollection(
|
||||
|
||||
Argument::createIntListTypeArgument('id'),
|
||||
Argument::createIntListTypeArgument('exclude'),
|
||||
new Argument(
|
||||
'order',
|
||||
new TypeCollection(
|
||||
new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual-reverse', 'random'))
|
||||
),
|
||||
'manual'
|
||||
),
|
||||
|
||||
Argument::createIntTypeArgument('width'),
|
||||
Argument::createIntTypeArgument('height'),
|
||||
Argument::createIntTypeArgument('rotation', 0),
|
||||
Argument::createAnyTypeArgument('background_color'),
|
||||
Argument::createIntTypeArgument('quality'),
|
||||
new Argument(
|
||||
'resize_mode',
|
||||
new TypeCollection(
|
||||
new Type\EnumListType(array('crop', 'borders', 'none'))
|
||||
),
|
||||
'none'
|
||||
),
|
||||
Argument::createAnyTypeArgument('effects'),
|
||||
|
||||
Argument::createIntTypeArgument('category'),
|
||||
Argument::createIntTypeArgument('product'),
|
||||
Argument::createIntTypeArgument('folder'),
|
||||
Argument::createIntTypeArgument('content'),
|
||||
|
||||
new Argument(
|
||||
'source',
|
||||
new TypeCollection(
|
||||
new Type\EnumListType($this->possible_sources)
|
||||
)
|
||||
),
|
||||
|
||||
Argument::createIntListTypeArgument('lang')
|
||||
);
|
||||
|
||||
// Add possible image sources
|
||||
foreach($possible_sources as $source) {
|
||||
$collection->addArgument(Argument::createIntTypeArgument($source))
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user