Added image action and loop

This commit is contained in:
franck
2013-08-15 11:46:46 +02:00
parent 47bc545019
commit a56e05b36b
25 changed files with 7180 additions and 0 deletions

View 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;
}
}

View 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;
}
}