From c28ac536aa63f90fd70cc195d0651e018ed6c449 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 19 Jul 2013 13:59:25 +0200 Subject: [PATCH] accessory loop product loop order fix --- core/lib/Thelia/Config/Resources/config.xml | 1 + .../Thelia/Core/Template/Element/BaseLoop.php | 2 +- .../Thelia/Core/Template/Loop/Accessory.php | 119 ++++++++++++++++++ .../Thelia/Core/Template/Loop/Category.php | 49 ++++---- .../lib/Thelia/Core/Template/Loop/Product.php | 103 +++++++-------- core/lib/Thelia/Type/EnumListType.php | 6 + core/lib/Thelia/Type/TypeCollection.php | 5 + templates/smarty-sample/category.html | 12 +- 8 files changed, 217 insertions(+), 80 deletions(-) create mode 100755 core/lib/Thelia/Core/Template/Loop/Accessory.php diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index dee0b57b6..5a3e56c61 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -5,6 +5,7 @@ xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd"> + diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 72c59290d..4051b49a3 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -51,7 +51,7 @@ abstract class BaseLoop protected $securityContext; - private $args; + protected $args; /** * Create a new Loop diff --git a/core/lib/Thelia/Core/Template/Loop/Accessory.php b/core/lib/Thelia/Core/Template/Loop/Accessory.php new file mode 100755 index 000000000..0f2ef7c20 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Accessory.php @@ -0,0 +1,119 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +use Thelia\Core\Template\Loop\Product; + +use Propel\Runtime\ActiveQuery\Criteria; +use Propel\Runtime\ActiveQuery\Join; +use Thelia\Core\Template\Element\BaseLoop; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Core\Template\Element\LoopResultRow; + +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Core\Template\Loop\Argument\Argument; +use Thelia\Log\Tlog; + +use Thelia\Model\AccessoryQuery; +use Thelia\Model\ProductQuery; +use Thelia\Model\ConfigQuery; +use Thelia\Type\TypeCollection; +use Thelia\Type; + +/** + * + * Accessory loop + * + * + * Class Accessory + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class Accessory extends Product +{ + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + $argumentCollection = parent::getArgDefinitions(); + + $argumentCollection->addArgument( + Argument::createIntListTypeArgument('product', null, true) + ); + + $argumentCollection->get('order')->default = "accessory"; + + $argumentCollection->get('order')->type->getKey(0)->addValue('accessory'); + $argumentCollection->get('order')->type->getKey(0)->addValue('accessory_reverse'); + + return $argumentCollection; + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = AccessoryQuery::create(); + + $product = $this->getProduct(); + $search->filterByProductId($product, Criteria::IN); + + $order = $this->getOrder(); + $orderByAccessory = array_search('accessory', $order); + $orderByAccessoryReverse = array_search('accessory_reverse', $order); + if($orderByAccessory !== false) { + $search->orderByPosition(Criteria::ASC); + $order[$orderByAccessory] = 'given_id'; + $this->args->get('order')->setValue( implode(',', $order) ); + } + if($orderByAccessoryReverse !== false) { + $search->orderByPosition(Criteria::DESC); + $order[$orderByAccessoryReverse] = 'given_id'; + $this->args->get('order')->setValue( implode(',', $order) ); + } + + $accessories = $this->search($search); + + $accessoryIdList = array(0); + foreach ($accessories as $accessory) { + array_push($accessoryIdList, $accessory->getAccessory()); + } + + $receivedIdList = $this->getId(); + + /* if an Id list is receive, loop will only match accessories from this list */ + if($receivedIdList === null) { + $this->args->get('id')->setValue( implode(',', $accessoryIdList) ); + } else { + $this->args->get('id')->setValue( implode(',', array_intersect($receivedIdList, $accessoryIdList)) ); + } + + return parent::exec($pagination); + } + +} diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index 96809f5dc..c5c64b894 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -83,8 +83,9 @@ class Category extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType('alpha', 'alpha_reverse', 'reverse') - ) + new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual-reverse', 'random')) + ), + 'manual' ), Argument::createBooleanTypeArgument('random', 0), Argument::createIntListTypeArgument('exclude') @@ -139,34 +140,28 @@ class Category extends BaseLoop $orders = $this->getOrder(); - if(null === $orders) { - $search->orderByPosition(); - } else { - foreach($orders as $order) { - switch ($order) { - case "alpha": - $search->addAscendingOrderByColumn(\Thelia\Model\CategoryI18nPeer::TITLE); - break; - case "alpha_reverse": - $search->addDescendingOrderByColumn(\Thelia\Model\CategoryI18nPeer::TITLE); - break; - case "reverse": - $search->orderByPosition(\Criteria::DESC); - break; - default: - $search->orderByPosition(); - break; - } + foreach($orders as $order) { + switch ($order) { + case "alpha": + $search->addAscendingOrderByColumn(\Thelia\Model\Map\CategoryI18nTableMap::TITLE); + break; + case "alpha_reverse": + $search->addDescendingOrderByColumn(\Thelia\Model\Map\CategoryI18nTableMap::TITLE); + 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; } } - $random = $this->getRandom(); - - if ($random === true) { - $search->clearOrderByColumns(); - $search->addAscendingOrderByColumn('RAND()'); - } - /** * \Criteria::INNER_JOIN in second parameter for joinWithI18n exclude query without translation. * diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 5d07861f0..56fc3cd28 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -84,8 +84,9 @@ class Product extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'reverse', 'min_price', 'max_price', 'manual', 'manual_reverse', 'ref', 'promo', 'new', 'random')) - ) + new Type\EnumListType(array('alpha', 'alpha_reverse', 'reverse', 'min_price', 'max_price', 'manual', 'manual_reverse', 'ref', 'promo', 'new', 'random', 'given_id')) + ), + 'manual' ), Argument::createIntListTypeArgument('exclude'), Argument::createIntListTypeArgument('exclude_category'), @@ -254,54 +255,56 @@ class Product extends BaseLoop $orders = $this->getOrder(); - if(null === $orders) { - $search->orderByPosition(); - } else { - foreach($orders as $order) { - switch ($order) { - case "alpha": - $search->addAscendingOrderByColumn(\Thelia\Model\Map\CategoryI18nTableMap::TITLE); - $search->addAscendingOrderByColumn(\Thelia\Model\Map\CategoryI18nTableMap::TITLE); - break; - case "alpha_reverse": - $search->addDescendingOrderByColumn(\Thelia\Model\Map\CategoryI18nTableMap::TITLE); - break; - case "reverse": - $search->orderByPosition(Criteria::DESC); - break; - case "min_price": - $search->orderBy('real_price', Criteria::ASC); - break; - case "max_price": - $search->orderBy('real_price', Criteria::DESC); - break; - case "manual": - if(null === $this->category || count($this->category) != 1) - throw new \InvalidArgumentException('Manual order cannot be set without single category argument'); - $search->addAscendingOrderByColumn(ProductTableMap::POSITION); - break; - case "manual_reverse": - if(null === $this->category || count($this->category) != 1) - throw new \InvalidArgumentException('Manual order cannot be set without single category argument'); - $search->addDescendingOrderByColumn(ProductTableMap::POSITION); - break; - case "ref": - $search->addAscendingOrderByColumn(ProductTableMap::REF); - break; - case "promo": - $search->addDescendingOrderByColumn(ProductTableMap::PROMO); - break; - case "new": - $search->addDescendingOrderByColumn(ProductTableMap::NEWNESS); - break; - case "random": - $search->clearOrderByColumns(); - $search->addAscendingOrderByColumn('RAND()'); - break(2); - default: - $search->orderByPosition(); - break; - } + + foreach($orders as $order) { + switch ($order) { + case "alpha": + $search->addAscendingOrderByColumn(\Thelia\Model\Map\ProductI18nTableMap::TITLE); + break; + case "alpha_reverse": + $search->addDescendingOrderByColumn(\Thelia\Model\Map\ProductI18nTableMap::TITLE); + break; + case "reverse": + $search->orderByPosition(Criteria::DESC); + break; + case "min_price": + $search->orderBy('real_price', Criteria::ASC); + break; + case "max_price": + $search->orderBy('real_price', Criteria::DESC); + break; + case "manual": + if(null === $this->category || count($this->category) != 1) + throw new \InvalidArgumentException('Manual order cannot be set without single category argument'); + $search->orderByPosition(Criteria::ASC); + break; + case "manual_reverse": + if(null === $this->category || count($this->category) != 1) + throw new \InvalidArgumentException('Manual order cannot be set without single category argument'); + $search->orderByPosition(Criteria::DESC); + break; + case "ref": + $search->orderByRef(Criteria::ASC); + break; + case "promo": + $search->orderByPromo(Criteria::DESC); + break; + case "new": + $search->orderByNewness(Criteria::DESC); + break; + case "given_id": + if (!is_null($id)) { + foreach($id as $singleId) { + $givenIdMatched = 'given_id_matched_' . $singleId; + $search->withColumn(ProductTableMap::ID . "='$singleId'", $givenIdMatched); + $search->orderBy($givenIdMatched, Criteria::DESC); + } + } + break; + case "random": + $search->clearOrderByColumns(); + $search->addAscendingOrderByColumn('RAND()'); + break(2); } } diff --git a/core/lib/Thelia/Type/EnumListType.php b/core/lib/Thelia/Type/EnumListType.php index 1603dc89f..c80501737 100755 --- a/core/lib/Thelia/Type/EnumListType.php +++ b/core/lib/Thelia/Type/EnumListType.php @@ -38,6 +38,12 @@ class EnumListType implements TypeInterface $this->values = $values; } + public function addValue($value) + { + if(!in_array($value, $this->values)) + $this->values[] = $value; + } + public function getType() { return 'Enum list type'; diff --git a/core/lib/Thelia/Type/TypeCollection.php b/core/lib/Thelia/Type/TypeCollection.php index 460d9b96e..c2170bfb6 100755 --- a/core/lib/Thelia/Type/TypeCollection.php +++ b/core/lib/Thelia/Type/TypeCollection.php @@ -142,4 +142,9 @@ class TypeCollection implements \Iterator return null; } + + public function getKey($key) + { + return isset($this->types[$key]) ? $this->types[$key] : null; + } } diff --git a/templates/smarty-sample/category.html b/templates/smarty-sample/category.html index ef97c92e1..f8da127a1 100755 --- a/templates/smarty-sample/category.html +++ b/templates/smarty-sample/category.html @@ -37,11 +37,19 @@ weight : #WEIGHT
{/loop*} -{loop name="product" type="product" order="ref" feature_values="1: foo"} +{*loop name="product" type="product" order="ref" feature_values="1: foo"}

PRODUCT : #REF / #TITLE

price : #PRICE €
promo price : #PROMO_PRICE €
is promo : #PROMO
is new : #NEW
weight : #WEIGHT
-{/loop} +{/loop*} + +{loop name="product" type="product" order="ref"} +

PRODUCT : #REF / #TITLE

+

Accessories

+ {loop name="acc" type="accessory" product="#ID" order="max_price"} + #REF - + {/loop} +{/loop} \ No newline at end of file