From d61eeef0d6279cac3c3a1d58b35e7a8450276607 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 20:47:05 +0200 Subject: [PATCH] Finalized images action and loop --- .gitignore | 2 + core/lib/Thelia/Action/Image.php | 130 ++++++++--- core/lib/Thelia/Command/Install.php | 3 +- core/lib/Thelia/Config/Resources/action.xml | 5 + core/lib/Thelia/Config/Resources/config.xml | 1 + core/lib/Thelia/Core/Event/ImageEvent.php | 8 +- core/lib/Thelia/Core/Template/Loop/Image.php | 214 +++++++++++++----- .../Smarty/Assets/SmartyAssetsManager.php | 2 +- core/lib/Thelia/Exception/ImageException.php | 8 + core/lib/Thelia/Model/Base/Currency.php | 86 +++++-- core/lib/Thelia/Model/Base/CurrencyQuery.php | 47 +++- core/lib/Thelia/Model/Base/Lang.php | 86 +++++-- core/lib/Thelia/Model/Base/LangQuery.php | 47 +++- .../lib/Thelia/Model/Map/CurrencyTableMap.php | 36 +-- core/lib/Thelia/Model/Map/LangTableMap.php | 36 +-- core/lib/Thelia/Tests/Action/ImageTest.php | 53 ++++- core/lib/Thelia/Tools/URL.php | 18 +- install/INSTALL-TODO.txt | 5 +- install/faker.php | 79 ++++++- install/insert.sql | 2 +- install/thelia.sql | 2 + local/config/schema.xml | 4 +- local/media/.gitkeep | 0 templates/default/images.html | 104 +++++++++ 24 files changed, 812 insertions(+), 166 deletions(-) create mode 100644 local/media/.gitkeep create mode 100644 templates/default/images.html diff --git a/.gitignore b/.gitignore index 16709f59f..cad92f7a8 100755 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ coverage .project .settings/ local/cache/* +local/media/documents/* +local/media/images/* web/assets/* web/cache/* web/.htaccess diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index 353f9d9c3..dcf4390c5 100644 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -36,12 +36,37 @@ use Imagine\Image\Box; use Imagine\Image\Color; use Imagine\Image\Point; use Thelia\Exception\ImageException; -use Thelia\Log\Tlog; use Thelia\Core\Event\TheliaEvents; /** * - * Image management actions + * Image management actions. This class handles image processing an caching. + * + * Basically, images are stored outside the web space (by default in local/media/images), + * and cached in the web space (by default in web/local/images). + * + * In the images caches directory, a subdirectory for images categories (eg. product, category, folder, etc.) is + * automatically created, and the cached image is created here. Plugin may use their own subdirectory as required. + * + * The cached image name contains a hash of the processing options, and the original (normalized) name of the image. + * + * A copy (or symbolic link, by default) of the original image is always created in the cache, so that the full + * resolution image is always available. + * + * Various image processing options are available : + * + * - resizing, with border, crop, or by keeping image aspect ratio + * - rotation, in degrees, positive or negative + * - background color, applyed to empty background when creating borders or rotating + * - effects. The effects are applied in the specified order. The following effects are available: + * - gamma:value : change the image Gamma to the specified value. Example: gamma:0.7 + * - grayscale or greyscale: switch image to grayscale + * - colorize:color : apply a color mask to the image. Exemple: colorize:#ff2244 + * - negative : transform the image in its negative equivalent + * - vflip or vertical_flip : vertical flip + * - hflip or horizontal_flip : horizontal flip + * + * If a problem occurs, an ImageException may be thrown. * * @package Thelia\Action * @author Franck Allimant @@ -54,6 +79,42 @@ class Image extends BaseAction implements EventSubscriberInterface const EXACT_RATIO_WITH_CROP = 2; const KEEP_IMAGE_RATIO = 3; + /** + * Clear the image cache. Is a subdirectory is specified, only this directory is cleared. + * If no directory is specified, the whole cache is cleared. + * Only files are deleted, directories will remain. + * + * @param ImageEvent $event + */ + public function clearCache(ImageEvent $event) { + + $path = $this->getCachePath($event->getCacheSubdirectory(), false); + + $this->clearDirectory($path); + } + + /** + * Recursively clears the specified directory. + * + * @param string $path the directory path + */ + protected function clearDirectory($path) { + + $iterator = new \DirectoryIterator($path); + + foreach ($iterator as $fileinfo) { + + if ($fileinfo->isDot()) continue; + + if ($fileinfo->isFile() || $fileinfo->isLink()) { + @unlink($fileinfo->getPathname()); + } + else if ($fileinfo->isDir()) { + $this->clearDirectory($fileinfo->getPathname()); + } + } + } + /** * Process image and write the result in the image cache. * @@ -85,23 +146,24 @@ class Image extends BaseAction implements EventSubscriberInterface if (! file_exists($cacheFilePath)) { + if (! file_exists($source_file)) { + throw new ImageException(sprintf("Source image file %s does not exists.", $source_file)); + } + // Create a chached 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)) { - $error_message = sprintf("Failed to create symbolic link for %s in %s image cache directory", basename($source_file), $subdir); - Tlog::getInstance()->addError($error_message); - throw new ImageException($error_message); + 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)) { - $error_message = sprintf("Failed to copy %s in %s image cache directory", basename($source_file), $subdir); - Tlog::getInstance()->addError($error_message); - throw new ImageException($error_message); + throw new ImageException(sprintf("Failed to copy %s in %s image cache directory", basename($source_file), $subdir)); } } } @@ -191,11 +253,11 @@ class Image extends BaseAction implements EventSubscriberInterface array('quality' => $quality) ); } + else { + throw new ImageException(sprintf("Source file %s cannot be opened.", basename($source_file))); + } } } - 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)); @@ -207,8 +269,8 @@ class Image extends BaseAction implements EventSubscriberInterface $event->setCacheFilepath($cacheFilePath); $event->setCacheOriginalFilepath($originalImagePathInCache); - $event->setFileUrl(URL::absoluteUrl($processed_image_url)); - $event->setOriginalFileUrl(URL::absoluteUrl($original_image_url)); + $event->setFileUrl(URL::absoluteUrl($processed_image_url, null, URL::PATH_TO_FILE)); + $event->setOriginalFileUrl(URL::absoluteUrl($original_image_url, null, URL::PATH_TO_FILE)); } /** @@ -320,7 +382,7 @@ class Image extends BaseAction implements EventSubscriberInterface { $path = $this->getCachePathFromWebRoot($subdir); - return URL::absoluteUrl(sprintf("%s/%s", $path, $safe_filename)); + return URL::absoluteUrl(sprintf("%s/%s", $path, $safe_filename), null, URL::PATH_TO_FILE); } /** @@ -341,22 +403,28 @@ class Image extends BaseAction implements EventSubscriberInterface if ($forceOriginalImage || $event->isOriginalImage()) return sprintf("%s/%s", $path, $safe_filename); else - return sprintf("%s/%s-%s", $path, $event->getSignature(), $safe_filename); + return sprintf("%s/%s-%s", $path, $event->getOptionsHash(), $safe_filename); } /** * Return the cache directory path relative to Web Root * - * @param string $subdir the subdirectory related to cache base + * @param string $subdir the subdirectory related to cache base, or null to get the cache directory only. * @return string the cache directory path relative to Web Root */ - protected function getCachePathFromWebRoot($subdir) + protected function getCachePathFromWebRoot($subdir = null) { - $safe_subdir = basename($subdir); - $cache_dir_from_web_root = ConfigQuery::read('image_cache_dir_from_web_root', 'cache'); - $path = sprintf("%s/%s", $cache_dir_from_web_root, $safe_subdir); + if ($subdir != null) { + $safe_subdir = basename($subdir); + + $path = sprintf("%s/%s", $cache_dir_from_web_root, $safe_subdir); + } + else + $path = $cache_dir_from_web_root; + + // Check if path is valid, e.g. in the cache dir return $path; } @@ -364,11 +432,11 @@ class Image extends BaseAction implements EventSubscriberInterface /** * Return the absolute cache directory path * - * @param string $subdir the subdirectory related to cache base + * @param string $subdir the subdirectory related to cache base, or null to get the cache base directory. * @throws \RuntimeException if cache directory cannot be created * @return string the absolute cache directory path */ - protected function getCachePath($subdir) + protected function getCachePath($subdir = null, $create_if_not_exists = true) { $cache_base = $this->getCachePathFromWebRoot($subdir); @@ -377,15 +445,19 @@ class Image extends BaseAction implements EventSubscriberInterface $path = sprintf("%s/%s", $web_root, $cache_base); // Create directory (recursively) if it does not exists. - if (!is_dir($path)) { + if ($create_if_not_exists && !is_dir($path)) { if (!@mkdir($path, 0777, true)) { - $error_message = sprintf("Failed to create %s/%s image cache directory", $cache_base); - Tlog::getInstance()->addError($error_message); - - throw new ImageException($error_message); + throw new ImageException(sprintf("Failed to create %s/%s image cache directory", $cache_base)); } } + // Check if path is valid, e.g. in the cache dir + $cache_base = realpath(sprintf("%s/%s", $web_root, $this->getCachePathFromWebRoot())); + + if (strpos(realpath($path), $cache_base) !== 0) { + throw new \InvalidArgumentException(sprintf("Invalid cache path %s, with subdirectory %s", $path, $subdir)); + } + return $path; } @@ -396,7 +468,7 @@ class Image extends BaseAction implements EventSubscriberInterface */ protected function createImagineInstance() { - $driver = ConfigQuery::read("imagine_driver", "gd"); + $driver = ConfigQuery::read("imagine_graphic_driver", "gd"); switch ($driver) { case 'imagik': diff --git a/core/lib/Thelia/Command/Install.php b/core/lib/Thelia/Command/Install.php index c151c44b7..edf459086 100755 --- a/core/lib/Thelia/Command/Install.php +++ b/core/lib/Thelia/Command/Install.php @@ -189,7 +189,8 @@ class Install extends ContainerAwareCommand file_put_contents($configFile, $configContent); - $fs->remove($sampleConfigFile); + // FA - no, as no further install will be possible + // $fs->remove($sampleConfigFile); $fs->remove($this->getContainer()->getParameter("kernel.cache_dir")); diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 988c86ce9..f773b4cd7 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -27,6 +27,11 @@ + + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 98017f979..8181c60fc 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -25,6 +25,7 @@ + diff --git a/core/lib/Thelia/Core/Event/ImageEvent.php b/core/lib/Thelia/Core/Event/ImageEvent.php index f6421eb9f..a105d9f6f 100644 --- a/core/lib/Thelia/Core/Event/ImageEvent.php +++ b/core/lib/Thelia/Core/Event/ImageEvent.php @@ -97,18 +97,18 @@ class ImageEvent extends ActionEvent protected $quality = null; /** - * @return boolean true if the required image is the original image + * @return boolean true if the required image is the original image (resize_mode and background_color are not significant) */ 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 empty($this->width) && empty($this->height) /* && empty($this->resize_mode) && empty($this->background_color) not significant */ + && empty($this->effects) && empty($this->rotation) && empty($this->quality); } /** * @return string a hash identifiying the processing options */ - public function getSignature() + public function getOptionsHash() { return md5( $this->width . $this->height . $this->resize_mode . $this->background_color . implode(',', $this->effects) diff --git a/core/lib/Thelia/Core/Template/Loop/Image.php b/core/lib/Thelia/Core/Template/Loop/Image.php index 4414e0e4e..e7a7ddca4 100644 --- a/core/lib/Thelia/Core/Template/Loop/Image.php +++ b/core/lib/Thelia/Core/Template/Loop/Image.php @@ -28,6 +28,15 @@ use Thelia\Core\Event\ImageEvent; use Thelia\Model\CategoryImageQuery; use Thelia\Model\ProductImageQuery; use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Type\TypeCollection; +use Thelia\Type\EnumListType; +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Model\ConfigQuery; +use Thelia\Core\Template\Element\LoopResultRow; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Type\EnumType; +use Thelia\Log\Tlog; /** * The image loop @@ -44,61 +53,101 @@ class Image extends BaseLoop /** * Dynamically create the search query, and set the proper filter and order * + * @param string $source a valid source identifier (@see $possible_sources) + * @param int $object_id the source object ID * @return ModelCriteria the propel Query object */ - protected function getSearchQuery() { + protected function createSearchQuery($source, $object_id) { + + $object = ucfirst($source); + + $queryClass = sprintf("\Thelia\Model\%sImageQuery", $object); + $filterMethod = sprintf("filterBy%sId", $object); + $mapClass = sprintf("\Thelia\Model\Map\%sI18nTableMap", $object); + + // xxxImageQuery::create() + $method = new \ReflectionMethod($queryClass, 'create'); + $search = $method->invoke(null); // Static ! + + // $query->filterByXXX(id) + $method = new \ReflectionMethod($queryClass, $filterMethod); + $method->invoke($search, $object_id); + + $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; + } + } + + return $search; + } + + /** + * Dynamically create the search query, and set the proper filter and order + * + * @param string $object_type (returned) the a valid source identifier (@see $possible_sources) + * @param string $object_id (returned) the ID of the source object + * @return ModelCriteria the propel Query object + */ + protected function getSearchQuery(&$object_type, &$object_id) { $search = null; - foreach($this->possible_sources as $source) { + // Check form source="product" source_id="123" style arguments + $source = $this->getSource(); - $argValue = intval($this->getArgValue($source)); + if (! is_null($source)) { - if ($argValue > 0) { + $source_id = $this->getSourceId(); - $object = ucfirst($source); + // echo "source = ".$this->getSource().", id=".$id."
"; - $queryClass = sprintf("%sImageQuery", $object); - $filterMethod = sprintf("filterBy%s", $object); - $mapClass = sprintf("\Thelia\Model\Map\%sI18nTableMap", $object); + if (is_null($source_id)) { + throw new \InvalidArgumentException("'source_id' argument cannot be null if 'source' argument is specified."); + } - // xxxImageQuery::create() - $method = new \ReflectionMethod($queryClass, 'create'); - $search = $reflectionMethod->invoke(null); // Static ! + $search = $this->createSearchQuery($source, $source_id); - // $query->filterByXXX($id) - $method = new \ReflectionMethod($queryClass, $filterMethod); - $method->invoke($search, $argValue); + $object_type = $source; + $object_id = $source_id; + } + else { + // Check for product="id" folder="id", etc. style arguments + foreach($this->possible_sources as $source) { - $map = new \ReflectionClass($mapClass); - $title_map = $map->getConstant('TITLE'); + $argValue = intval($this->getArgValue($source)); - $orders = $this->getOrder(); + if ($argValue > 0) { - // 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; - } + $search = $this->createSearchQuery($source, $argValue); + + $object_type = $source; + $object_id = $argValue; + + break; } - - break; } } @@ -111,10 +160,12 @@ class Image extends BaseLoop /** * @param unknown $pagination */ - public function exec($pagination) + public function exec(&$pagination) { - // Select the proper query to use - $search = $this->getSearchQuery(); + // Select the proper query to use, and get the object type + $object_type = $object_id = null; + + $search = $this->getSearchQuery($object_type, $object_id); $id = $this->getId(); @@ -130,10 +181,8 @@ class Image extends BaseLoop $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(); @@ -143,6 +192,21 @@ class Image extends BaseLoop $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; + + } + /** * \Criteria::INNER_JOIN in second parameter for joinWithI18n exclude query without translation. * @@ -165,25 +229,51 @@ class Image extends BaseLoop // 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($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); - // Dispatch image processing event - $this->dispatcher->dispatch(TheliaEvents::IMAGE_PROCESS, $event); + // Put source image file path + $source_filepath = sprintf("%s%s/%s/%s", + THELIA_ROOT, + ConfigQuery::read('documents_library_path', 'local/media/images'), + $object_type, + $result->getFile() + ); - $loopResultRow = new LoopResultRow(); + $event->setSourceFilepath($source_filepath); + $event->setCacheSubdirectory($object_type); - $loopResultRow - ->set("ID", $result->getId()) - ->set("IMAGE_URL", $event->getFileUrl()) - ->set("FILE_URL", $event-> - ; + try { + // Dispatch image processing event + $this->dispatcher->dispatch(TheliaEvents::IMAGE_PROCESS, $event); - $loopResult->addRow($loopResultRow); + $loopResultRow = new LoopResultRow(); + + $loopResultRow + ->set("ID", $result->getId()) + ->set("IMAGE_URL", $event->getFileUrl()) + ->set("ORIGINAL_IMAGE_URL", $event->getOriginalFileUrl()) + ->set("IMAGE_PATH", $event->getCacheFilepath()) + ->set("ORIGINAL_IMAGE_PATH", $source_filepath) + ->set("TITLE", $result->getTitle()) + ->set("CHAPO", $result->getChapo()) + ->set("DESCRIPTION", $result->getDescription()) + ->set("POSTSCRIPTUM", $result->getPostscriptum()) + ->set("POSITION", $result->getPosition()) + ->set("OBJECT_TYPE", $object_type) + ->set("OBJECT_ID", $object_id) + ; + + $loopResult->addRow($loopResultRow); + } + catch (\Exception $ex) { + // Ignore the result and log an error + Tlog::getInstance()->addError("Failed to process image in image loop: ", $this->args); + } } return $loopResult; @@ -200,6 +290,7 @@ class Image extends BaseLoop #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 @@ -219,7 +310,7 @@ class Image extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual-reverse', 'random')) + new EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual-reverse', 'random')) ), 'manual' ), @@ -232,7 +323,7 @@ class Image extends BaseLoop new Argument( 'resize_mode', new TypeCollection( - new Type\EnumListType(array('crop', 'borders', 'none')) + new EnumType(array('crop', 'borders', 'none')) ), 'none' ), @@ -246,16 +337,17 @@ class Image extends BaseLoop new Argument( 'source', new TypeCollection( - new Type\EnumListType($this->possible_sources) + new EnumType($this->possible_sources) ) ), + Argument::createIntTypeArgument('source_id'), Argument::createIntListTypeArgument('lang') ); // Add possible image sources - foreach($possible_sources as $source) { - $collection->addArgument(Argument::createIntTypeArgument($source)) + foreach($this->possible_sources as $source) { + $collection->addArgument(Argument::createIntTypeArgument($source)); } return $collection; diff --git a/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php b/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php index e3365be85..a07eba565 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php +++ b/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php @@ -70,7 +70,7 @@ class SmartyAssetsManager $url = $this->assetic_manager->asseticize( $asset_dir.'/'.$asset_file, $this->web_root."/".$this->path_relative_to_web_root, - URL::absoluteUrl($this->path_relative_to_web_root, array(), true /* path only */), + URL::absoluteUrl($this->path_relative_to_web_root, null, URL::PATH_TO_FILE /* path only */), $assetType, $filters, $debug diff --git a/core/lib/Thelia/Exception/ImageException.php b/core/lib/Thelia/Exception/ImageException.php index 77d2a8ba5..60774dabf 100644 --- a/core/lib/Thelia/Exception/ImageException.php +++ b/core/lib/Thelia/Exception/ImageException.php @@ -23,6 +23,14 @@ namespace Thelia\Exception; +use Thelia\Log\Tlog; + class ImageException extends \RuntimeException { + public function __construct($message, $code = null, $previous = null) { + + Tlog::getInstance()->addError($message); + + parent::__construct($message, $code, $previous); + } } diff --git a/core/lib/Thelia/Model/Base/Currency.php b/core/lib/Thelia/Model/Base/Currency.php index 5ab40a742..77718992f 100644 --- a/core/lib/Thelia/Model/Base/Currency.php +++ b/core/lib/Thelia/Model/Base/Currency.php @@ -87,6 +87,12 @@ abstract class Currency implements ActiveRecordInterface */ protected $rate; + /** + * The value for the position field. + * @var int + */ + protected $position; + /** * The value for the by_default field. * @var int @@ -473,6 +479,17 @@ abstract class Currency implements ActiveRecordInterface return $this->rate; } + /** + * Get the [position] column value. + * + * @return int + */ + public function getPosition() + { + + return $this->position; + } + /** * Get the [by_default] column value. * @@ -608,6 +625,27 @@ abstract class Currency implements ActiveRecordInterface return $this; } // setRate() + /** + * Set the value of [position] column. + * + * @param int $v new value + * @return \Thelia\Model\Currency The current object (for fluent API support) + */ + public function setPosition($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->position !== $v) { + $this->position = $v; + $this->modifiedColumns[] = CurrencyTableMap::POSITION; + } + + + return $this; + } // setPosition() + /** * Set the value of [by_default] column. * @@ -720,16 +758,19 @@ abstract class Currency implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : CurrencyTableMap::translateFieldName('Rate', TableMap::TYPE_PHPNAME, $indexType)]; $this->rate = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : CurrencyTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : CurrencyTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; + $this->position = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : CurrencyTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; $this->by_default = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : CurrencyTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : CurrencyTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : CurrencyTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : CurrencyTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -742,7 +783,7 @@ abstract class Currency implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 7; // 7 = CurrencyTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 8; // 8 = CurrencyTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Currency object", 0, $e); @@ -1052,6 +1093,9 @@ abstract class Currency implements ActiveRecordInterface if ($this->isColumnModified(CurrencyTableMap::RATE)) { $modifiedColumns[':p' . $index++] = 'RATE'; } + if ($this->isColumnModified(CurrencyTableMap::POSITION)) { + $modifiedColumns[':p' . $index++] = 'POSITION'; + } if ($this->isColumnModified(CurrencyTableMap::BY_DEFAULT)) { $modifiedColumns[':p' . $index++] = 'BY_DEFAULT'; } @@ -1084,6 +1128,9 @@ abstract class Currency implements ActiveRecordInterface case 'RATE': $stmt->bindValue($identifier, $this->rate, PDO::PARAM_STR); break; + case 'POSITION': + $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); + break; case 'BY_DEFAULT': $stmt->bindValue($identifier, $this->by_default, PDO::PARAM_INT); break; @@ -1168,12 +1215,15 @@ abstract class Currency implements ActiveRecordInterface return $this->getRate(); break; case 4: - return $this->getByDefault(); + return $this->getPosition(); break; case 5: - return $this->getCreatedAt(); + return $this->getByDefault(); break; case 6: + return $this->getCreatedAt(); + break; + case 7: return $this->getUpdatedAt(); break; default: @@ -1209,9 +1259,10 @@ abstract class Currency implements ActiveRecordInterface $keys[1] => $this->getCode(), $keys[2] => $this->getSymbol(), $keys[3] => $this->getRate(), - $keys[4] => $this->getByDefault(), - $keys[5] => $this->getCreatedAt(), - $keys[6] => $this->getUpdatedAt(), + $keys[4] => $this->getPosition(), + $keys[5] => $this->getByDefault(), + $keys[6] => $this->getCreatedAt(), + $keys[7] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1279,12 +1330,15 @@ abstract class Currency implements ActiveRecordInterface $this->setRate($value); break; case 4: - $this->setByDefault($value); + $this->setPosition($value); break; case 5: - $this->setCreatedAt($value); + $this->setByDefault($value); break; case 6: + $this->setCreatedAt($value); + break; + case 7: $this->setUpdatedAt($value); break; } // switch() @@ -1315,9 +1369,10 @@ abstract class Currency implements ActiveRecordInterface if (array_key_exists($keys[1], $arr)) $this->setCode($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setSymbol($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setRate($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setByDefault($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setCreatedAt($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setUpdatedAt($arr[$keys[6]]); + if (array_key_exists($keys[4], $arr)) $this->setPosition($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setByDefault($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); } /** @@ -1333,6 +1388,7 @@ abstract class Currency implements ActiveRecordInterface if ($this->isColumnModified(CurrencyTableMap::CODE)) $criteria->add(CurrencyTableMap::CODE, $this->code); if ($this->isColumnModified(CurrencyTableMap::SYMBOL)) $criteria->add(CurrencyTableMap::SYMBOL, $this->symbol); if ($this->isColumnModified(CurrencyTableMap::RATE)) $criteria->add(CurrencyTableMap::RATE, $this->rate); + if ($this->isColumnModified(CurrencyTableMap::POSITION)) $criteria->add(CurrencyTableMap::POSITION, $this->position); if ($this->isColumnModified(CurrencyTableMap::BY_DEFAULT)) $criteria->add(CurrencyTableMap::BY_DEFAULT, $this->by_default); if ($this->isColumnModified(CurrencyTableMap::CREATED_AT)) $criteria->add(CurrencyTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(CurrencyTableMap::UPDATED_AT)) $criteria->add(CurrencyTableMap::UPDATED_AT, $this->updated_at); @@ -1402,6 +1458,7 @@ abstract class Currency implements ActiveRecordInterface $copyObj->setCode($this->getCode()); $copyObj->setSymbol($this->getSymbol()); $copyObj->setRate($this->getRate()); + $copyObj->setPosition($this->getPosition()); $copyObj->setByDefault($this->getByDefault()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -2578,6 +2635,7 @@ abstract class Currency implements ActiveRecordInterface $this->code = null; $this->symbol = null; $this->rate = null; + $this->position = null; $this->by_default = null; $this->created_at = null; $this->updated_at = null; diff --git a/core/lib/Thelia/Model/Base/CurrencyQuery.php b/core/lib/Thelia/Model/Base/CurrencyQuery.php index 140b70463..eb4b1b2f7 100644 --- a/core/lib/Thelia/Model/Base/CurrencyQuery.php +++ b/core/lib/Thelia/Model/Base/CurrencyQuery.php @@ -26,6 +26,7 @@ use Thelia\Model\Map\CurrencyTableMap; * @method ChildCurrencyQuery orderByCode($order = Criteria::ASC) Order by the code column * @method ChildCurrencyQuery orderBySymbol($order = Criteria::ASC) Order by the symbol column * @method ChildCurrencyQuery orderByRate($order = Criteria::ASC) Order by the rate column + * @method ChildCurrencyQuery orderByPosition($order = Criteria::ASC) Order by the position column * @method ChildCurrencyQuery orderByByDefault($order = Criteria::ASC) Order by the by_default column * @method ChildCurrencyQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildCurrencyQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -34,6 +35,7 @@ use Thelia\Model\Map\CurrencyTableMap; * @method ChildCurrencyQuery groupByCode() Group by the code column * @method ChildCurrencyQuery groupBySymbol() Group by the symbol column * @method ChildCurrencyQuery groupByRate() Group by the rate column + * @method ChildCurrencyQuery groupByPosition() Group by the position column * @method ChildCurrencyQuery groupByByDefault() Group by the by_default column * @method ChildCurrencyQuery groupByCreatedAt() Group by the created_at column * @method ChildCurrencyQuery groupByUpdatedAt() Group by the updated_at column @@ -65,6 +67,7 @@ use Thelia\Model\Map\CurrencyTableMap; * @method ChildCurrency findOneByCode(string $code) Return the first ChildCurrency filtered by the code column * @method ChildCurrency findOneBySymbol(string $symbol) Return the first ChildCurrency filtered by the symbol column * @method ChildCurrency findOneByRate(double $rate) Return the first ChildCurrency filtered by the rate column + * @method ChildCurrency findOneByPosition(int $position) Return the first ChildCurrency filtered by the position column * @method ChildCurrency findOneByByDefault(int $by_default) Return the first ChildCurrency filtered by the by_default column * @method ChildCurrency findOneByCreatedAt(string $created_at) Return the first ChildCurrency filtered by the created_at column * @method ChildCurrency findOneByUpdatedAt(string $updated_at) Return the first ChildCurrency filtered by the updated_at column @@ -73,6 +76,7 @@ use Thelia\Model\Map\CurrencyTableMap; * @method array findByCode(string $code) Return ChildCurrency objects filtered by the code column * @method array findBySymbol(string $symbol) Return ChildCurrency objects filtered by the symbol column * @method array findByRate(double $rate) Return ChildCurrency objects filtered by the rate column + * @method array findByPosition(int $position) Return ChildCurrency objects filtered by the position column * @method array findByByDefault(int $by_default) Return ChildCurrency objects filtered by the by_default column * @method array findByCreatedAt(string $created_at) Return ChildCurrency objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildCurrency objects filtered by the updated_at column @@ -164,7 +168,7 @@ abstract class CurrencyQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, CODE, SYMBOL, RATE, BY_DEFAULT, CREATED_AT, UPDATED_AT FROM currency WHERE ID = :p0'; + $sql = 'SELECT ID, CODE, SYMBOL, RATE, POSITION, BY_DEFAULT, CREATED_AT, UPDATED_AT FROM currency WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -393,6 +397,47 @@ abstract class CurrencyQuery extends ModelCriteria return $this->addUsingAlias(CurrencyTableMap::RATE, $rate, $comparison); } + /** + * Filter the query on the position column + * + * Example usage: + * + * $query->filterByPosition(1234); // WHERE position = 1234 + * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) + * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 + * + * + * @param mixed $position The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildCurrencyQuery The current query, for fluid interface + */ + public function filterByPosition($position = null, $comparison = null) + { + if (is_array($position)) { + $useMinMax = false; + if (isset($position['min'])) { + $this->addUsingAlias(CurrencyTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($position['max'])) { + $this->addUsingAlias(CurrencyTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(CurrencyTableMap::POSITION, $position, $comparison); + } + /** * Filter the query on the by_default column * diff --git a/core/lib/Thelia/Model/Base/Lang.php b/core/lib/Thelia/Model/Base/Lang.php index 694f86bc5..3379594ef 100644 --- a/core/lib/Thelia/Model/Base/Lang.php +++ b/core/lib/Thelia/Model/Base/Lang.php @@ -84,6 +84,12 @@ abstract class Lang implements ActiveRecordInterface */ protected $url; + /** + * The value for the position field. + * @var int + */ + protected $position; + /** * The value for the by_default field. * @var int @@ -419,6 +425,17 @@ abstract class Lang implements ActiveRecordInterface return $this->url; } + /** + * Get the [position] column value. + * + * @return int + */ + public function getPosition() + { + + return $this->position; + } + /** * Get the [by_default] column value. * @@ -575,6 +592,27 @@ abstract class Lang implements ActiveRecordInterface return $this; } // setUrl() + /** + * Set the value of [position] column. + * + * @param int $v new value + * @return \Thelia\Model\Lang The current object (for fluent API support) + */ + public function setPosition($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->position !== $v) { + $this->position = $v; + $this->modifiedColumns[] = LangTableMap::POSITION; + } + + + return $this; + } // setPosition() + /** * Set the value of [by_default] column. * @@ -690,16 +728,19 @@ abstract class Lang implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : LangTableMap::translateFieldName('Url', TableMap::TYPE_PHPNAME, $indexType)]; $this->url = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : LangTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : LangTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; + $this->position = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : LangTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; $this->by_default = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : LangTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : LangTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : LangTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : LangTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -712,7 +753,7 @@ abstract class Lang implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 8; // 8 = LangTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 9; // 9 = LangTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Lang object", 0, $e); @@ -947,6 +988,9 @@ abstract class Lang implements ActiveRecordInterface if ($this->isColumnModified(LangTableMap::URL)) { $modifiedColumns[':p' . $index++] = 'URL'; } + if ($this->isColumnModified(LangTableMap::POSITION)) { + $modifiedColumns[':p' . $index++] = 'POSITION'; + } if ($this->isColumnModified(LangTableMap::BY_DEFAULT)) { $modifiedColumns[':p' . $index++] = 'BY_DEFAULT'; } @@ -982,6 +1026,9 @@ abstract class Lang implements ActiveRecordInterface case 'URL': $stmt->bindValue($identifier, $this->url, PDO::PARAM_STR); break; + case 'POSITION': + $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); + break; case 'BY_DEFAULT': $stmt->bindValue($identifier, $this->by_default, PDO::PARAM_INT); break; @@ -1069,12 +1116,15 @@ abstract class Lang implements ActiveRecordInterface return $this->getUrl(); break; case 5: - return $this->getByDefault(); + return $this->getPosition(); break; case 6: - return $this->getCreatedAt(); + return $this->getByDefault(); break; case 7: + return $this->getCreatedAt(); + break; + case 8: return $this->getUpdatedAt(); break; default: @@ -1110,9 +1160,10 @@ abstract class Lang implements ActiveRecordInterface $keys[2] => $this->getCode(), $keys[3] => $this->getLocale(), $keys[4] => $this->getUrl(), - $keys[5] => $this->getByDefault(), - $keys[6] => $this->getCreatedAt(), - $keys[7] => $this->getUpdatedAt(), + $keys[5] => $this->getPosition(), + $keys[6] => $this->getByDefault(), + $keys[7] => $this->getCreatedAt(), + $keys[8] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1169,12 +1220,15 @@ abstract class Lang implements ActiveRecordInterface $this->setUrl($value); break; case 5: - $this->setByDefault($value); + $this->setPosition($value); break; case 6: - $this->setCreatedAt($value); + $this->setByDefault($value); break; case 7: + $this->setCreatedAt($value); + break; + case 8: $this->setUpdatedAt($value); break; } // switch() @@ -1206,9 +1260,10 @@ abstract class Lang implements ActiveRecordInterface if (array_key_exists($keys[2], $arr)) $this->setCode($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setLocale($arr[$keys[3]]); if (array_key_exists($keys[4], $arr)) $this->setUrl($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setByDefault($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); + if (array_key_exists($keys[5], $arr)) $this->setPosition($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setByDefault($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]); } /** @@ -1225,6 +1280,7 @@ abstract class Lang implements ActiveRecordInterface if ($this->isColumnModified(LangTableMap::CODE)) $criteria->add(LangTableMap::CODE, $this->code); if ($this->isColumnModified(LangTableMap::LOCALE)) $criteria->add(LangTableMap::LOCALE, $this->locale); if ($this->isColumnModified(LangTableMap::URL)) $criteria->add(LangTableMap::URL, $this->url); + if ($this->isColumnModified(LangTableMap::POSITION)) $criteria->add(LangTableMap::POSITION, $this->position); if ($this->isColumnModified(LangTableMap::BY_DEFAULT)) $criteria->add(LangTableMap::BY_DEFAULT, $this->by_default); if ($this->isColumnModified(LangTableMap::CREATED_AT)) $criteria->add(LangTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(LangTableMap::UPDATED_AT)) $criteria->add(LangTableMap::UPDATED_AT, $this->updated_at); @@ -1295,6 +1351,7 @@ abstract class Lang implements ActiveRecordInterface $copyObj->setCode($this->getCode()); $copyObj->setLocale($this->getLocale()); $copyObj->setUrl($this->getUrl()); + $copyObj->setPosition($this->getPosition()); $copyObj->setByDefault($this->getByDefault()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1336,6 +1393,7 @@ abstract class Lang implements ActiveRecordInterface $this->code = null; $this->locale = null; $this->url = null; + $this->position = null; $this->by_default = null; $this->created_at = null; $this->updated_at = null; diff --git a/core/lib/Thelia/Model/Base/LangQuery.php b/core/lib/Thelia/Model/Base/LangQuery.php index 1a99ff28a..a5100c5f8 100644 --- a/core/lib/Thelia/Model/Base/LangQuery.php +++ b/core/lib/Thelia/Model/Base/LangQuery.php @@ -23,6 +23,7 @@ use Thelia\Model\Map\LangTableMap; * @method ChildLangQuery orderByCode($order = Criteria::ASC) Order by the code column * @method ChildLangQuery orderByLocale($order = Criteria::ASC) Order by the locale column * @method ChildLangQuery orderByUrl($order = Criteria::ASC) Order by the url column + * @method ChildLangQuery orderByPosition($order = Criteria::ASC) Order by the position column * @method ChildLangQuery orderByByDefault($order = Criteria::ASC) Order by the by_default column * @method ChildLangQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildLangQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -32,6 +33,7 @@ use Thelia\Model\Map\LangTableMap; * @method ChildLangQuery groupByCode() Group by the code column * @method ChildLangQuery groupByLocale() Group by the locale column * @method ChildLangQuery groupByUrl() Group by the url column + * @method ChildLangQuery groupByPosition() Group by the position column * @method ChildLangQuery groupByByDefault() Group by the by_default column * @method ChildLangQuery groupByCreatedAt() Group by the created_at column * @method ChildLangQuery groupByUpdatedAt() Group by the updated_at column @@ -48,6 +50,7 @@ use Thelia\Model\Map\LangTableMap; * @method ChildLang findOneByCode(string $code) Return the first ChildLang filtered by the code column * @method ChildLang findOneByLocale(string $locale) Return the first ChildLang filtered by the locale column * @method ChildLang findOneByUrl(string $url) Return the first ChildLang filtered by the url column + * @method ChildLang findOneByPosition(int $position) Return the first ChildLang filtered by the position column * @method ChildLang findOneByByDefault(int $by_default) Return the first ChildLang filtered by the by_default column * @method ChildLang findOneByCreatedAt(string $created_at) Return the first ChildLang filtered by the created_at column * @method ChildLang findOneByUpdatedAt(string $updated_at) Return the first ChildLang filtered by the updated_at column @@ -57,6 +60,7 @@ use Thelia\Model\Map\LangTableMap; * @method array findByCode(string $code) Return ChildLang objects filtered by the code column * @method array findByLocale(string $locale) Return ChildLang objects filtered by the locale column * @method array findByUrl(string $url) Return ChildLang objects filtered by the url column + * @method array findByPosition(int $position) Return ChildLang objects filtered by the position column * @method array findByByDefault(int $by_default) Return ChildLang objects filtered by the by_default column * @method array findByCreatedAt(string $created_at) Return ChildLang objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildLang objects filtered by the updated_at column @@ -148,7 +152,7 @@ abstract class LangQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, TITLE, CODE, LOCALE, URL, BY_DEFAULT, CREATED_AT, UPDATED_AT FROM lang WHERE ID = :p0'; + $sql = 'SELECT ID, TITLE, CODE, LOCALE, URL, POSITION, BY_DEFAULT, CREATED_AT, UPDATED_AT FROM lang WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -394,6 +398,47 @@ abstract class LangQuery extends ModelCriteria return $this->addUsingAlias(LangTableMap::URL, $url, $comparison); } + /** + * Filter the query on the position column + * + * Example usage: + * + * $query->filterByPosition(1234); // WHERE position = 1234 + * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) + * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 + * + * + * @param mixed $position The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildLangQuery The current query, for fluid interface + */ + public function filterByPosition($position = null, $comparison = null) + { + if (is_array($position)) { + $useMinMax = false; + if (isset($position['min'])) { + $this->addUsingAlias(LangTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($position['max'])) { + $this->addUsingAlias(LangTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(LangTableMap::POSITION, $position, $comparison); + } + /** * Filter the query on the by_default column * diff --git a/core/lib/Thelia/Model/Map/CurrencyTableMap.php b/core/lib/Thelia/Model/Map/CurrencyTableMap.php index b1251801a..b37a6b30a 100644 --- a/core/lib/Thelia/Model/Map/CurrencyTableMap.php +++ b/core/lib/Thelia/Model/Map/CurrencyTableMap.php @@ -57,7 +57,7 @@ class CurrencyTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 7; + const NUM_COLUMNS = 8; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class CurrencyTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 7; + const NUM_HYDRATE_COLUMNS = 8; /** * the column name for the ID field @@ -89,6 +89,11 @@ class CurrencyTableMap extends TableMap */ const RATE = 'currency.RATE'; + /** + * the column name for the POSITION field + */ + const POSITION = 'currency.POSITION'; + /** * the column name for the BY_DEFAULT field */ @@ -125,12 +130,12 @@ class CurrencyTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Code', 'Symbol', 'Rate', 'ByDefault', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'code', 'symbol', 'rate', 'byDefault', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(CurrencyTableMap::ID, CurrencyTableMap::CODE, CurrencyTableMap::SYMBOL, CurrencyTableMap::RATE, CurrencyTableMap::BY_DEFAULT, CurrencyTableMap::CREATED_AT, CurrencyTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'CODE', 'SYMBOL', 'RATE', 'BY_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'code', 'symbol', 'rate', 'by_default', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) + self::TYPE_PHPNAME => array('Id', 'Code', 'Symbol', 'Rate', 'Position', 'ByDefault', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'code', 'symbol', 'rate', 'position', 'byDefault', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(CurrencyTableMap::ID, CurrencyTableMap::CODE, CurrencyTableMap::SYMBOL, CurrencyTableMap::RATE, CurrencyTableMap::POSITION, CurrencyTableMap::BY_DEFAULT, CurrencyTableMap::CREATED_AT, CurrencyTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'CODE', 'SYMBOL', 'RATE', 'POSITION', 'BY_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'code', 'symbol', 'rate', 'position', 'by_default', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); /** @@ -140,12 +145,12 @@ class CurrencyTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Code' => 1, 'Symbol' => 2, 'Rate' => 3, 'ByDefault' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'code' => 1, 'symbol' => 2, 'rate' => 3, 'byDefault' => 4, 'createdAt' => 5, 'updatedAt' => 6, ), - self::TYPE_COLNAME => array(CurrencyTableMap::ID => 0, CurrencyTableMap::CODE => 1, CurrencyTableMap::SYMBOL => 2, CurrencyTableMap::RATE => 3, CurrencyTableMap::BY_DEFAULT => 4, CurrencyTableMap::CREATED_AT => 5, CurrencyTableMap::UPDATED_AT => 6, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'CODE' => 1, 'SYMBOL' => 2, 'RATE' => 3, 'BY_DEFAULT' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, ), - self::TYPE_FIELDNAME => array('id' => 0, 'code' => 1, 'symbol' => 2, 'rate' => 3, 'by_default' => 4, 'created_at' => 5, 'updated_at' => 6, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Code' => 1, 'Symbol' => 2, 'Rate' => 3, 'Position' => 4, 'ByDefault' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'code' => 1, 'symbol' => 2, 'rate' => 3, 'position' => 4, 'byDefault' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), + self::TYPE_COLNAME => array(CurrencyTableMap::ID => 0, CurrencyTableMap::CODE => 1, CurrencyTableMap::SYMBOL => 2, CurrencyTableMap::RATE => 3, CurrencyTableMap::POSITION => 4, CurrencyTableMap::BY_DEFAULT => 5, CurrencyTableMap::CREATED_AT => 6, CurrencyTableMap::UPDATED_AT => 7, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'CODE' => 1, 'SYMBOL' => 2, 'RATE' => 3, 'POSITION' => 4, 'BY_DEFAULT' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), + self::TYPE_FIELDNAME => array('id' => 0, 'code' => 1, 'symbol' => 2, 'rate' => 3, 'position' => 4, 'by_default' => 5, 'created_at' => 6, 'updated_at' => 7, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); /** @@ -168,6 +173,7 @@ class CurrencyTableMap extends TableMap $this->addColumn('CODE', 'Code', 'VARCHAR', false, 45, null); $this->addColumn('SYMBOL', 'Symbol', 'VARCHAR', false, 45, null); $this->addColumn('RATE', 'Rate', 'FLOAT', false, null, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('BY_DEFAULT', 'ByDefault', 'TINYINT', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); @@ -351,6 +357,7 @@ class CurrencyTableMap extends TableMap $criteria->addSelectColumn(CurrencyTableMap::CODE); $criteria->addSelectColumn(CurrencyTableMap::SYMBOL); $criteria->addSelectColumn(CurrencyTableMap::RATE); + $criteria->addSelectColumn(CurrencyTableMap::POSITION); $criteria->addSelectColumn(CurrencyTableMap::BY_DEFAULT); $criteria->addSelectColumn(CurrencyTableMap::CREATED_AT); $criteria->addSelectColumn(CurrencyTableMap::UPDATED_AT); @@ -359,6 +366,7 @@ class CurrencyTableMap extends TableMap $criteria->addSelectColumn($alias . '.CODE'); $criteria->addSelectColumn($alias . '.SYMBOL'); $criteria->addSelectColumn($alias . '.RATE'); + $criteria->addSelectColumn($alias . '.POSITION'); $criteria->addSelectColumn($alias . '.BY_DEFAULT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Model/Map/LangTableMap.php b/core/lib/Thelia/Model/Map/LangTableMap.php index 86e3ebe16..9eb864388 100644 --- a/core/lib/Thelia/Model/Map/LangTableMap.php +++ b/core/lib/Thelia/Model/Map/LangTableMap.php @@ -57,7 +57,7 @@ class LangTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 8; + const NUM_COLUMNS = 9; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class LangTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 8; + const NUM_HYDRATE_COLUMNS = 9; /** * the column name for the ID field @@ -94,6 +94,11 @@ class LangTableMap extends TableMap */ const URL = 'lang.URL'; + /** + * the column name for the POSITION field + */ + const POSITION = 'lang.POSITION'; + /** * the column name for the BY_DEFAULT field */ @@ -121,12 +126,12 @@ class LangTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Title', 'Code', 'Locale', 'Url', 'ByDefault', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'title', 'code', 'locale', 'url', 'byDefault', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(LangTableMap::ID, LangTableMap::TITLE, LangTableMap::CODE, LangTableMap::LOCALE, LangTableMap::URL, LangTableMap::BY_DEFAULT, LangTableMap::CREATED_AT, LangTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'TITLE', 'CODE', 'LOCALE', 'URL', 'BY_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'title', 'code', 'locale', 'url', 'by_default', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id', 'Title', 'Code', 'Locale', 'Url', 'Position', 'ByDefault', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'title', 'code', 'locale', 'url', 'position', 'byDefault', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(LangTableMap::ID, LangTableMap::TITLE, LangTableMap::CODE, LangTableMap::LOCALE, LangTableMap::URL, LangTableMap::POSITION, LangTableMap::BY_DEFAULT, LangTableMap::CREATED_AT, LangTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'TITLE', 'CODE', 'LOCALE', 'URL', 'POSITION', 'BY_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'title', 'code', 'locale', 'url', 'position', 'by_default', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -136,12 +141,12 @@ class LangTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Title' => 1, 'Code' => 2, 'Locale' => 3, 'Url' => 4, 'ByDefault' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'title' => 1, 'code' => 2, 'locale' => 3, 'url' => 4, 'byDefault' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), - self::TYPE_COLNAME => array(LangTableMap::ID => 0, LangTableMap::TITLE => 1, LangTableMap::CODE => 2, LangTableMap::LOCALE => 3, LangTableMap::URL => 4, LangTableMap::BY_DEFAULT => 5, LangTableMap::CREATED_AT => 6, LangTableMap::UPDATED_AT => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'TITLE' => 1, 'CODE' => 2, 'LOCALE' => 3, 'URL' => 4, 'BY_DEFAULT' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'title' => 1, 'code' => 2, 'locale' => 3, 'url' => 4, 'by_default' => 5, 'created_at' => 6, 'updated_at' => 7, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Title' => 1, 'Code' => 2, 'Locale' => 3, 'Url' => 4, 'Position' => 5, 'ByDefault' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'title' => 1, 'code' => 2, 'locale' => 3, 'url' => 4, 'position' => 5, 'byDefault' => 6, 'createdAt' => 7, 'updatedAt' => 8, ), + self::TYPE_COLNAME => array(LangTableMap::ID => 0, LangTableMap::TITLE => 1, LangTableMap::CODE => 2, LangTableMap::LOCALE => 3, LangTableMap::URL => 4, LangTableMap::POSITION => 5, LangTableMap::BY_DEFAULT => 6, LangTableMap::CREATED_AT => 7, LangTableMap::UPDATED_AT => 8, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'TITLE' => 1, 'CODE' => 2, 'LOCALE' => 3, 'URL' => 4, 'POSITION' => 5, 'BY_DEFAULT' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, ), + self::TYPE_FIELDNAME => array('id' => 0, 'title' => 1, 'code' => 2, 'locale' => 3, 'url' => 4, 'position' => 5, 'by_default' => 6, 'created_at' => 7, 'updated_at' => 8, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -165,6 +170,7 @@ class LangTableMap extends TableMap $this->addColumn('CODE', 'Code', 'VARCHAR', false, 10, null); $this->addColumn('LOCALE', 'Locale', 'VARCHAR', false, 45, null); $this->addColumn('URL', 'Url', 'VARCHAR', false, 255, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('BY_DEFAULT', 'ByDefault', 'TINYINT', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); @@ -333,6 +339,7 @@ class LangTableMap extends TableMap $criteria->addSelectColumn(LangTableMap::CODE); $criteria->addSelectColumn(LangTableMap::LOCALE); $criteria->addSelectColumn(LangTableMap::URL); + $criteria->addSelectColumn(LangTableMap::POSITION); $criteria->addSelectColumn(LangTableMap::BY_DEFAULT); $criteria->addSelectColumn(LangTableMap::CREATED_AT); $criteria->addSelectColumn(LangTableMap::UPDATED_AT); @@ -342,6 +349,7 @@ class LangTableMap extends TableMap $criteria->addSelectColumn($alias . '.CODE'); $criteria->addSelectColumn($alias . '.LOCALE'); $criteria->addSelectColumn($alias . '.URL'); + $criteria->addSelectColumn($alias . '.POSITION'); $criteria->addSelectColumn($alias . '.BY_DEFAULT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Tests/Action/ImageTest.php b/core/lib/Thelia/Tests/Action/ImageTest.php index fa25672d7..195613c0b 100644 --- a/core/lib/Thelia/Tests/Action/ImageTest.php +++ b/core/lib/Thelia/Tests/Action/ImageTest.php @@ -113,7 +113,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase /** * - * Tru to process a non-existent file + * Try to process a non-existent file * * @expectedException \InvalidArgumentException */ @@ -129,6 +129,24 @@ class ImageTest extends \PHPUnit_Framework_TestCase $image->processImage($event); } + /** + * + * Try to process a file outside of the cache + * + * @expectedException \InvalidArgumentException + */ + public function testProcessImageOutsideValidPath() + { + $event = new ImageEvent($this->request); + + $image = new Image($this->getContainer()); + + $event->setCacheFilepath("blablabla.png"); + $event->setCacheSubdirectory("../../../"); + + $image->processImage($event); + } + /** * No operation done on source file -> copie ! */ @@ -317,4 +335,37 @@ class ImageTest extends \PHPUnit_Framework_TestCase $image->processImage($event); } + public function testClearTestsCache() { + $event = new ImageEvent($this->request); + + $event->setCacheSubdirectory('tests'); + + $image = new Image($this->getContainer()); + + $image->clearCache($event); + } + + public function testClearWholeCache() { + $event = new ImageEvent($this->request); + + $image = new Image($this->getContainer()); + + $image->clearCache($event); + } + + /** + * Try to clear directory ouside of the cache + * + * @expectedException \InvalidArgumentException + */ + public function testClearUnallowedPathCache() { + $event = new ImageEvent($this->request); + + $event->setCacheSubdirectory('../../../..'); + + $image = new Image($this->getContainer()); + + $image->clearCache($event); + } + } \ No newline at end of file diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index accd4fd8b..5a88fa922 100644 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -27,6 +27,9 @@ use Thelia\Model\ConfigQuery; class URL { + const PATH_TO_FILE = true; + const WITH_INDEX_PAGE = false; + public static function getIndexPage() { return ConfigQuery::read('base_url', '/') . "index_dev.php"; // FIXME ! @@ -39,25 +42,28 @@ class URL * * @param string $path the relative path * @param array $parameters An array of parameters - * @param boolean $path_only if true, getIndexPage() will not be added + * @param boolean $path_only if true (PATH_TO_FILE), getIndexPage() will not be added * * @return string The generated URL */ - public static function absoluteUrl($path, array $parameters = array(), $path_only = false) + public static function absoluteUrl($path, array $parameters = null, $path_only = self::WITH_INDEX_PAGE) { // Already absolute ? if (substr($path, 0, 4) != 'http') { - $root = $path_only ? ConfigQuery::read('base_url', '/') : self::getIndexPage(); + $root = $path_only == self::PATH_TO_FILE ? ConfigQuery::read('base_url', '/') : self::getIndexPage(); - $base = $root . '/' . ltrim($path, '/'); + $base = rtrim($root, '/') . '/' . ltrim($path, '/'); } else $base = $path; + $queryString = ''; - foreach ($parameters as $name => $value) { - $queryString .= sprintf("%s=%s&", urlencode($name), urlencode($value)); + if (! is_null($parameters)) { + foreach ($parameters as $name => $value) { + $queryString .= sprintf("%s=%s&", urlencode($name), urlencode($value)); + } } $sepChar = strstr($base, '?') === false ? '?' : '&'; diff --git a/install/INSTALL-TODO.txt b/install/INSTALL-TODO.txt index ba319c228..8ea68554e 100644 --- a/install/INSTALL-TODO.txt +++ b/install/INSTALL-TODO.txt @@ -20,4 +20,7 @@ Variables Config à initialiser: - form.secret : token csrf - verifyStock : vérification du stock lors du paiement/ajout au panier. Defaut 1 - default_images_quality_percent : qualité par défaut des images générées (0 à 100, défaut: 75). -- original_image_delivery_mode : mode de mise à disposition des images originales (full resolution) dans le cache. 'symlink' pour un lien symbolique, 'copy' pour une copie \ No newline at end of file +- original_image_delivery_mode : mode de mise à disposition des images originales (full resolution) dans le cache. 'symlink' pour un lien symbolique, 'copy' pour une copie +- images_library_path : chemin vers le répertoire où sont stockés les images source (defaut: local/media/images) +- image_cache_dir_from_web_root : le repértoire de base où sont cachées les images, relatif à /web (cache/images) +- imagine_graphic_driver : le drivers utilisé par Imagine (gd, imagik, gmagick), defaut: 'gd' diff --git a/install/faker.php b/install/faker.php index 23bbed2bb..54d5c80fc 100755 --- a/install/faker.php +++ b/install/faker.php @@ -1,4 +1,9 @@ beginTransaction(); $currency = \Thelia\Model\CurrencyQuery::create()->filterByCode('EUR')->findOne(); +function generate_image($image, $position, $typeobj, $id) { + + global $faker; + + $image + ->setTitle($faker->text(20)) + ->setDescription($faker->text(250)) + ->setChapo($faker->text(40)) + ->setPostscriptum($faker->text(40)) + ->setPosition($position) + ->setFile(sprintf("sample-image-%s.png", $id)) + ->save() + ; + + // Generate images + $image_data = file_get_contents("http://placehold.it/320x200&text=Image+for+$typeobj+ID+".$id); + $image_file = sprintf("%s/../local/media/images/%s/sample-image-%s.png", __DIR__, $typeobj, $id); + + if (! is_dir(dirname($image_file))) mkdir(dirname($image_file), 0777, true); + + if ($fh = fopen($image_file, "w")) { + fwrite($fh, $image_data); + fclose($fh); + } +} + try { + $stmt = $con->prepare("SET foreign_key_checks = 0"); + $stmt->execute(); + $category = Thelia\Model\CategoryQuery::create() ->find(); $category->delete(); @@ -50,6 +84,9 @@ try { ->find(); $content->delete(); + $stmt = $con->prepare("SET foreign_key_checks = 1"); + $stmt->execute(); + //first category $sweet = new Thelia\Model\Category(); $sweet->setParent(0); @@ -60,6 +97,10 @@ try { $sweet->save(); + $image = new CategoryImage(); + $image->setCategoryId($sweet->getId()); + generate_image($image, 1, 'category', $sweet->getId()); + //second category $jeans = new Thelia\Model\Category(); $jeans->setParent(0); @@ -70,6 +111,10 @@ try { $jeans->save(); + $image = new CategoryImage(); + $image->setCategoryId($jeans->getId()); + generate_image($image, 2, 'category', $jeans->getId()); + //third category $other = new Thelia\Model\Category(); $other->setParent($jeans->getId()); @@ -80,6 +125,10 @@ try { $other->save(); + $image = new CategoryImage(); + $image->setCategoryId($other->getId()); + generate_image($image, 3, 'category', $other->getId()); + for ($i=1; $i <= 5; $i++) { $product = new \Thelia\Model\Product(); $product->addCategory($sweet); @@ -102,8 +151,12 @@ try { $productPrice->setProductSaleElements($stock); $productPrice->setCurrency($currency); $productPrice->setPrice($faker->randomFloat(2, 20, 2500)); + $productPrice->save(); + $image = new ProductImage(); + $image->setProductId($product->getId()); + generate_image($image, $i, 'product', $product->getId()); } for ($i=1; $i <= 5; $i++) { @@ -130,6 +183,10 @@ try { $productPrice->setPrice($faker->randomFloat(2, 20, 2500)); $productPrice->save(); + $image = new ProductImage(); + $image->setProductId($product->getId()); + generate_image($image, $i, 'product', $product->getId()); + } //folders and contents @@ -143,6 +200,10 @@ try { $folder->save(); + $image = new FolderImage(); + $image->setFolderId($folder->getId()); + generate_image($image, $i, 'folder', $folder->getId()); + for($j=0; $jsetParent($folder->getId()); @@ -153,6 +214,10 @@ try { $subfolder->save(); + $image = new FolderImage(); + $image->setFolderId($subfolder->getId()); + generate_image($image, $j, 'folder', $subfolder->getId()); + for($k=0; $kaddFolder($subfolder); @@ -162,6 +227,11 @@ try { $content->setDescription($faker->text(255)); $content->save(); + + $image = new ContentImage(); + $image->setContentId($content->getId()); + generate_image($image, $k, 'content', $content->getId()); + } } } @@ -188,8 +258,13 @@ try { } $con->commit(); -} catch (Exception $e) { - echo "error : ".$e->getMessage()."\n"; +} +catch (PropelException $pe) { + echo "Propel error: ".$pe->getMessage()."\n".$pe->getTraceAsString(); + $con->rollBack(); +} +catch (Exception $e) { + echo "error occured : ".$e->getMessage()."\n".$e->getTraceAsString(); $con->rollBack(); } diff --git a/install/insert.sql b/install/insert.sql index 1263f47df..a7255eba2 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -7,7 +7,7 @@ INSERT INTO `lang`(`id`,`title`,`code`,`locale`,`url`,`by_default`,`position`,`c INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES ('session_config.default', '1', 1, 1, NOW(), NOW()), ('verifyStock', '1', 1, 0, NOW(), NOW()); -('imagine_driver', 'gd', 1, 0, NOW(), NOW()); +('imagine_graphic_driver', 'gd', 1, 0, NOW(), NOW()); ('default_images_quality_percent', '75', 1, 0, NOW(), NOW()); ('original_image_delivery_mode', 'symlink', 1, 0, NOW(), NOW()); diff --git a/install/thelia.sql b/install/thelia.sql index 1e80ab01d..6d16cfdc1 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -521,6 +521,7 @@ CREATE TABLE `lang` `code` VARCHAR(10), `locale` VARCHAR(45), `url` VARCHAR(255), + `position` INTEGER NOT NULL, `by_default` TINYINT, `created_at` DATETIME, `updated_at` DATETIME, @@ -719,6 +720,7 @@ CREATE TABLE `currency` `code` VARCHAR(45), `symbol` VARCHAR(45), `rate` FLOAT, + `position` INTEGER NOT NULL, `by_default` TINYINT, `created_at` DATETIME, `updated_at` DATETIME, diff --git a/local/config/schema.xml b/local/config/schema.xml index 1bed327b1..460d1814b 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -385,7 +385,8 @@ - + + @@ -545,6 +546,7 @@ + diff --git a/local/media/.gitkeep b/local/media/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/templates/default/images.html b/templates/default/images.html new file mode 100644 index 000000000..c72beaecd --- /dev/null +++ b/templates/default/images.html @@ -0,0 +1,104 @@ +{include file="includes/header.html"} + + +
+

Category Images

+
    + {loop type="category" name="jsvdfk"} +
  • Category id #ID: #TITLE

    +
      +
    • + {loop type="image" name="image_test" category="#ID" width="200" height="100" resize_mode="borders"} +

      Processed file URL: #IMAGE_URL

      +

      Original file URL: #ORIGINAL_IMAGE_URL

      + + {/loop} + + {loop type="image" name="image_test" category="#ID"} +

      Full size file URL: #IMAGE_URL

      + + {/loop} + + {loop type="image" name="image_test" source="category" source_id="#ID"} +

      source="category" source_id="x" argument style: Processed file URL: #IMAGE_URL

      + {/loop} +
    • +
    +
  • + {/loop} +
+
+ + +
+

Product Images

+
    + {loop type="product" name="jsvdfk"} +
  • Product id #ID: #TITLE

    +
      +
    • + {loop type="image" name="image_test" product="#ID" width="200" height="100" resize_mode="borders" effects="gamma:0.7" background_color="#cc8000"} +

      Processed file URL: #IMAGE_URL

      +

      Original file URL: #ORIGINAL_IMAGE_URL

      +

      Images:

      + + + {/loop} + {loop type="image" name="image_test" product="#ID" width="200" height="100" resize_mode="crop"} + + {/loop} + {loop type="image" name="image_test" product="#ID" width="100" height="200" resize_mode="borders" background_color="#cc8000"} + + {/loop} + {loop type="image" name="image_test" product="#ID" width="100" rotation="-20" background_color="#facabe"} + + {/loop} + {loop type="image" name="image_test" product="#ID" width="200" height="100" resize_mode="borders" background_color="#facabe" effects="negative"} + + {/loop} +

      +
    • +
  • + {/loop} +
+
+ +
+

Folder Images

+
    + {loop type="folder" name="jsvdfk"} +
  • Folder id #ID: #TITLE

    +
      +
    • + {loop type="image" name="image_test" folder="#ID" width="200" height="100" resize_mode="borders"} +

      Processed file URL: #IMAGE_URL

      +

      Original file URL: #ORIGINAL_IMAGE_URL

      + + {/loop} +
    • +
    +
  • + {/loop} +
+
+ +
+

Content Images

+
    + {loop type="content" name="jsvdfk"} +
  • Content id #ID: #TITLE

    +
      +
    • + {loop type="image" name="image_test" content="#ID" width="200" height="100" resize_mode="borders"} +

      Processed file URL: #IMAGE_URL

      +

      Original file URL: #ORIGINAL_IMAGE_URL

      + + {/loop} +
    • +
    +
  • + {/loop} +
+
+ +{include file="includes/footer.html"} \ No newline at end of file