From fe850718cc1a1f70a1466f2780e8729c889f5175 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Fri, 2 Aug 2013 12:40:51 +0200 Subject: [PATCH 1/8] update schema, changin some relations between tables --- core/lib/Thelia/Model/Map/CurrencyTableMap.php | 3 ++- core/lib/Thelia/Model/Map/ProductPriceTableMap.php | 4 ++-- .../Thelia/Model/Map/ProductSaleElementsTableMap.php | 11 ++++++++++- install/thelia.sql | 4 +++- local/config/schema.xml | 6 +++--- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/core/lib/Thelia/Model/Map/CurrencyTableMap.php b/core/lib/Thelia/Model/Map/CurrencyTableMap.php index c9a707d9a..b1251801a 100644 --- a/core/lib/Thelia/Model/Map/CurrencyTableMap.php +++ b/core/lib/Thelia/Model/Map/CurrencyTableMap.php @@ -180,7 +180,7 @@ class CurrencyTableMap extends TableMap { $this->addRelation('Order', '\\Thelia\\Model\\Order', RelationMap::ONE_TO_MANY, array('id' => 'currency_id', ), 'SET NULL', 'RESTRICT', 'Orders'); $this->addRelation('Cart', '\\Thelia\\Model\\Cart', RelationMap::ONE_TO_MANY, array('id' => 'currency_id', ), null, null, 'Carts'); - $this->addRelation('ProductPrice', '\\Thelia\\Model\\ProductPrice', RelationMap::ONE_TO_MANY, array('id' => 'currency_id', ), null, null, 'ProductPrices'); + $this->addRelation('ProductPrice', '\\Thelia\\Model\\ProductPrice', RelationMap::ONE_TO_MANY, array('id' => 'currency_id', ), 'CASCADE', null, 'ProductPrices'); $this->addRelation('CurrencyI18n', '\\Thelia\\Model\\CurrencyI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'CurrencyI18ns'); } // buildRelations() @@ -205,6 +205,7 @@ class CurrencyTableMap extends TableMap // Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool, // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. OrderTableMap::clearInstancePool(); + ProductPriceTableMap::clearInstancePool(); CurrencyI18nTableMap::clearInstancePool(); } diff --git a/core/lib/Thelia/Model/Map/ProductPriceTableMap.php b/core/lib/Thelia/Model/Map/ProductPriceTableMap.php index 2b231321b..1a6274e2d 100644 --- a/core/lib/Thelia/Model/Map/ProductPriceTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductPriceTableMap.php @@ -169,8 +169,8 @@ class ProductPriceTableMap extends TableMap */ public function buildRelations() { - $this->addRelation('ProductSaleElements', '\\Thelia\\Model\\ProductSaleElements', RelationMap::MANY_TO_ONE, array('product_sale_elements_id' => 'id', ), null, null); - $this->addRelation('Currency', '\\Thelia\\Model\\Currency', RelationMap::MANY_TO_ONE, array('currency_id' => 'id', ), null, null); + $this->addRelation('ProductSaleElements', '\\Thelia\\Model\\ProductSaleElements', RelationMap::MANY_TO_ONE, array('product_sale_elements_id' => 'id', ), 'CASCADE', null); + $this->addRelation('Currency', '\\Thelia\\Model\\Currency', RelationMap::MANY_TO_ONE, array('currency_id' => 'id', ), 'CASCADE', null); } // buildRelations() /** diff --git a/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php b/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php index 2eb9a0b83..21c005f5c 100644 --- a/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php @@ -178,7 +178,7 @@ class ProductSaleElementsTableMap extends TableMap $this->addRelation('Product', '\\Thelia\\Model\\Product', RelationMap::MANY_TO_ONE, array('product_id' => 'id', ), 'CASCADE', 'RESTRICT'); $this->addRelation('AttributeCombination', '\\Thelia\\Model\\AttributeCombination', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), null, null, 'AttributeCombinations'); $this->addRelation('CartItem', '\\Thelia\\Model\\CartItem', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), null, null, 'CartItems'); - $this->addRelation('ProductPrice', '\\Thelia\\Model\\ProductPrice', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), null, null, 'ProductPrices'); + $this->addRelation('ProductPrice', '\\Thelia\\Model\\ProductPrice', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), 'CASCADE', null, 'ProductPrices'); } // buildRelations() /** @@ -193,6 +193,15 @@ class ProductSaleElementsTableMap extends TableMap 'timestampable' => array('create_column' => 'created_at', 'update_column' => 'updated_at', ), ); } // getBehaviors() + /** + * Method to invalidate the instance pool of all tables related to product_sale_elements * by a foreign key with ON DELETE CASCADE + */ + public static function clearRelatedInstancePool() + { + // Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool, + // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. + ProductPriceTableMap::clearInstancePool(); + } /** * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. diff --git a/install/thelia.sql b/install/thelia.sql index 3f587f40f..0cf0efe7f 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -1349,10 +1349,12 @@ CREATE TABLE `product_price` INDEX `idx_product_price_currency_id` (`currency_id`), CONSTRAINT `fk_product_price_product_sale_elements_id` FOREIGN KEY (`product_sale_elements_id`) - REFERENCES `product_sale_elements` (`id`), + REFERENCES `product_sale_elements` (`id`) + ON DELETE CASCADE, CONSTRAINT `fk_product_price_currency_id` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`) + ON DELETE CASCADE ) ENGINE=InnoDB; -- --------------------------------------------------------------------- diff --git a/local/config/schema.xml b/local/config/schema.xml index cea0b7763..46850f8b2 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1,4 +1,4 @@ - + @@ -990,10 +990,10 @@ - + - + From ab1598e50c1441c71c991f586a713faef1621d03 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 2 Aug 2013 14:59:52 +0200 Subject: [PATCH 2/8] bug fix in loops --- core/lib/Thelia/Core/Template/Loop/Category.php | 4 +++- core/lib/Thelia/Core/Template/Loop/Product.php | 10 +++++----- templates/default/bug.html | 4 ---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index 87ea0ec08..009ed1ed1 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -161,11 +161,13 @@ class Category extends BaseLoop $categories = $this->search($search, $pagination); + $notEmpty = $this->getNot_empty(); + $loopResult = new LoopResult(); foreach ($categories as $category) { - if ($this->not_empty && $category->countAllProducts() == 0) continue; + if ($notEmpty && $category->countAllProducts() == 0) continue; $loopResultRow = new LoopResultRow(); diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 817419ff4..96033e56c 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -402,11 +402,11 @@ class Product extends BaseLoop ->set("CHAPO", $product->getChapo()) ->set("DESCRIPTION", $product->getDescription()) ->set("POSTSCRIPTUM", $product->getPostscriptum()) - ->set("PRICE", $product->getPrice()) - ->set("PROMO_PRICE", $product->getPrice2()) - ->set("WEIGHT", $product->getWeight()) - ->set("PROMO", $product->getPromo()) - ->set("NEW", $product->getNewness()) + //->set("PRICE", $product->getPrice()) + //->set("PROMO_PRICE", $product->getPrice2()) + //->set("WEIGHT", $product->getWeight()) + //->set("PROMO", $product->getPromo()) + //->set("NEW", $product->getNewness()) ->set("POSITION", $product->getPosition()) ; diff --git a/templates/default/bug.html b/templates/default/bug.html index a1bc296ac..e69de29bb 100644 --- a/templates/default/bug.html +++ b/templates/default/bug.html @@ -1,4 +0,0 @@ -{loop name="cat" type="category" id="99999"} - {loop name="prod" type="product" category="#ID"} - {/loop} -{/loop} \ No newline at end of file From 8874404e4d33367ec1014a233e765fe4c6d5bece Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 2 Aug 2013 15:25:29 +0200 Subject: [PATCH 3/8] remove link from folder --- core/lib/Thelia/Config/Resources/config.xml | 1 + core/lib/Thelia/Core/Template/Loop/Folder.php | 198 ++++++++++++++++++ templates/default/folder.html | 20 ++ 3 files changed, 219 insertions(+) create mode 100755 core/lib/Thelia/Core/Template/Loop/Folder.php create mode 100755 templates/default/folder.html diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 58c0c8579..17ed3b332 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -14,6 +14,7 @@ + diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php new file mode 100755 index 000000000..d6de1f7a7 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -0,0 +1,198 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +use Propel\Runtime\ActiveQuery\Criteria; +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\FolderQuery; +use Thelia\Model\ConfigQuery; +use Thelia\Type\TypeCollection; +use Thelia\Type; + +/** + * + * Folder loop, all params available : + * + * - id : can be an id (eq : 3) or a "string list" (eg: 3, 4, 5) + * - parent : categories having this parent id + * - current : current id is used if you are on a folder page + * - not_empty : if value is 1, folder and subcategories must have at least 1 product + * - visible : default 1, if you want folder not visible put 0 + * - order : all value available : 'alpha', 'alpha_reverse', 'manual' (default), 'manual-reverse', 'random' + * - exclude : all folder id you want to exclude (as for id, an integer or a "string list" can be used) + * + * example : + * + * + * #TITLE : #ID + * + * + * + * Class Folder + * @package Thelia\Core\Template\Loop + * @author Manuel Raynaud + * @author Etienne Roudeix + */ +class Folder extends BaseLoop +{ + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + Argument::createIntTypeArgument('parent'), + Argument::createBooleanTypeArgument('current'), + Argument::createBooleanTypeArgument('not_empty', 0), + Argument::createBooleanTypeArgument('visible', 1), + new Argument( + 'order', + new TypeCollection( + new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual-reverse', 'random')) + ), + 'manual' + ), + Argument::createIntListTypeArgument('exclude') + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = FolderQuery::create(); + + $id = $this->getId(); + + if (!is_null($id)) { + $search->filterById($id, Criteria::IN); + } + + $parent = $this->getParent(); + + if (!is_null($parent)) { + $search->filterByParent($parent); + } + + + $current = $this->getCurrent(); + + if ($current === true) { + $search->filterById($this->request->get("folder_id")); + } elseif ($current === false) { + $search->filterById($this->request->get("folder_id"), Criteria::NOT_IN); + } + + + $exclude = $this->getExclude(); + + if (!is_null($exclude)) { + $search->filterById($exclude, Criteria::NOT_IN); + } + + $search->filterByVisible($this->getVisible() ? 1 : 0); + + $orders = $this->getOrder(); + + foreach($orders as $order) { + switch ($order) { + case "alpha": + $search->addAscendingOrderByColumn(\Thelia\Model\Map\FolderI18nTableMap::TITLE); + break; + case "alpha_reverse": + $search->addDescendingOrderByColumn(\Thelia\Model\Map\FolderI18nTableMap::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; + } + } + + /** + * \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 + ); + + $categories = $this->search($search, $pagination); + + $notEmpty = $this->getNot_empty(); + + $loopResult = new LoopResult(); + + foreach ($categories as $folder) { + + if ($notEmpty && $folder->countAllProducts() == 0) continue; + + $loopResultRow = new LoopResultRow(); + + $loopResultRow + ->set("ID", $folder->getId()) + ->set("TITLE",$folder->getTitle()) + ->set("CHAPO", $folder->getChapo()) + ->set("DESCRIPTION", $folder->getDescription()) + ->set("POSTSCRIPTUM", $folder->getPostscriptum()) + ->set("PARENT", $folder->getParent()) + ->set("URL", $folder->getUrl()) + ->set("PRODUCT_COUNT", $folder->countChild()) + ->set("VISIBLE", $folder->getVisible() ? "1" : "0") + ->set("POSITION", $folder->getPosition()) + + ->set("CREATE_DATE", $folder->getCreatedAt()) + ->set("UPDATE_DATE", $folder->getUpdatedAt()) + ->set("VERSION", $folder->getVersion()) + ->set("VERSION_DATE", $folder->getVersionCreatedAt()) + ->set("VERSION_AUTHOR", $folder->getVersionCreatedBy()) + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} \ No newline at end of file diff --git a/templates/default/folder.html b/templates/default/folder.html new file mode 100755 index 000000000..ea50c314b --- /dev/null +++ b/templates/default/folder.html @@ -0,0 +1,20 @@ +{loop name="folder0" type="folder" parent="0"} +

FOLDER : #TITLE

+ {loop name="folder1" type="folder" parent="#ID"} +
+

SUBFOLDER : #TITLE (#LOOP_COUNT / #LOOP_TOTAL)

+ {*loop name="content" type="content" folder="#ID"} +

CONTENT : #REF / #TITLE

+ #PRICE € + {/loop*} +
+
+ {/loop} + + {*loop name="content" type="content" folder="#ID"} +

CONTENT : #REF / #TITLE

+ #PRICE € + {/loop*} +
+
+{/loop} \ No newline at end of file From aac1533e657a5fc565a9e36c478f1c8667b0a958 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 2 Aug 2013 15:35:06 +0200 Subject: [PATCH 4/8] change faker --- core/lib/Thelia/Core/Template/Loop/Folder.php | 20 +--------- install/faker.php | 40 ++++++++++++++++--- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index d6de1f7a7..93ae038b6 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -38,27 +38,9 @@ use Thelia\Type\TypeCollection; use Thelia\Type; /** - * - * Folder loop, all params available : - * - * - id : can be an id (eq : 3) or a "string list" (eg: 3, 4, 5) - * - parent : categories having this parent id - * - current : current id is used if you are on a folder page - * - not_empty : if value is 1, folder and subcategories must have at least 1 product - * - visible : default 1, if you want folder not visible put 0 - * - order : all value available : 'alpha', 'alpha_reverse', 'manual' (default), 'manual-reverse', 'random' - * - exclude : all folder id you want to exclude (as for id, an integer or a "string list" can be used) - * - * example : - * - * - * #TITLE : #ID - * - * - * * Class Folder + * * @package Thelia\Core\Template\Loop - * @author Manuel Raynaud * @author Etienne Roudeix */ class Folder extends BaseLoop diff --git a/install/faker.php b/install/faker.php index 85a338ebe..2ade870e2 100755 --- a/install/faker.php +++ b/install/faker.php @@ -20,13 +20,21 @@ try { ->find(); $product->delete(); + $folder = Thelia\Model\FolderQuery::create() + ->find(); + $folder->delete(); + + $content = Thelia\Model\ContentQuery::create() + ->find(); + $content->delete(); + //first category $sweet = new Thelia\Model\Category(); $sweet->setParent(0); $sweet->setVisible(1); $sweet->setPosition(1); $sweet->setDescription($faker->text(255)); - $sweet->setTitle($faker->bs); + $sweet->setTitle($faker->text(20)); $sweet->save(); @@ -36,7 +44,7 @@ try { $jeans->setVisible(1); $jeans->setPosition(2); $jeans->setDescription($faker->text(255)); - $jeans->setTitle($faker->bs); + $jeans->setTitle($faker->text(20)); $jeans->save(); @@ -46,14 +54,14 @@ try { $other->setVisible(1); $other->setPosition(3); $other->setDescription($faker->text(255)); - $other->setTitle($faker->bs); + $other->setTitle($faker->text(20)); $other->save(); for ($i=1; $i <= 5; $i++) { $product = new \Thelia\Model\Product(); $product->addCategory($sweet); - $product->setTitle($faker->bs); + $product->setTitle($faker->text(20)); $product->setDescription($faker->text(250)); /* $product->setQuantity($faker->randomNumber(1,50)); $product->setPrice($faker->randomFloat(2, 20, 2500));*/ @@ -79,7 +87,7 @@ try { for ($i=1; $i <= 5; $i++) { $product = new \Thelia\Model\Product(); $product->addCategory($jeans); - $product->setTitle($faker->bs); + $product->setTitle($faker->text(20)); $product->setDescription($faker->text(250)); /* $product->setQuantity($faker->randomNumber(1,50)); $product->setPrice($faker->randomFloat(2, 20, 2500));*/ @@ -102,6 +110,28 @@ try { } + //folders + for($i=0; $i<4; $i++) { + $folder = new Thelia\Model\Folder(); + $folder->setParent(0); + $folder->setVisible(rand(1, 10)>7 ? 0 : 1); + $folder->setPosition($i); + $folder->setTitle($faker->text(20)); + $folder->setDescription($faker->text(255)); + + $folder->save(); + + for($i=0; $isetParent($folder->getId()); + $subfolder->setVisible(rand(1, 10)>7 ? 0 : 1); + $subfolder->setPosition($i); + $subfolder->setTitle($faker->text(20)); + $subfolder->setDescription($faker->text(255)); + + $subfolder->save(); + } + } $con->commit(); } catch (Exception $e) { From 265a6bb2a8066c85a4fb53f1b6eba3857d5cf33c Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Fri, 2 Aug 2013 16:10:26 +0200 Subject: [PATCH 5/8] change event class for customer actions --- core/lib/Thelia/Action/Customer.php | 11 +++--- core/lib/Thelia/Core/Event/CustomerEvent.php | 38 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 core/lib/Thelia/Core/Event/CustomerEvent.php diff --git a/core/lib/Thelia/Action/Customer.php b/core/lib/Thelia/Action/Customer.php index 3a39a4bf2..6ed4b480d 100755 --- a/core/lib/Thelia/Action/Customer.php +++ b/core/lib/Thelia/Action/Customer.php @@ -25,6 +25,7 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\ActionEvent; +use Thelia\Core\Event\CustomerEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Form\BaseForm; use Thelia\Form\CustomerCreation; @@ -88,8 +89,8 @@ class Customer implements EventSubscriberInterface $data["password"], $request->getSession()->getLang() ); - - $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CREATECUSTOMER, $event); + $customerEvent = new CustomerEvent($customer); + $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CREATECUSTOMER, $customerEvent); // Connect the newly created user,and redirect to the success URL $this->processSuccessfulLogin($event, $customer, $customerCreationForm, true); @@ -136,7 +137,8 @@ class Customer implements EventSubscriberInterface $customer = CustomerQuery::create()->findPk(1); try { - $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECUSTOMER, $event); + $customerEvent = new CustomerEvent($customer); + $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECUSTOMER, $customerEvent); $data = $form->getData(); @@ -153,7 +155,8 @@ class Customer implements EventSubscriberInterface $data["country"] ); - $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECUSTOMER, $event); + $customerEvent->customer = $customer; + $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECUSTOMER, $customerEvent); // Update the logged-in user, and redirect to the success URL (exits) // We don-t send the login event, as the customer si already logged. diff --git a/core/lib/Thelia/Core/Event/CustomerEvent.php b/core/lib/Thelia/Core/Event/CustomerEvent.php new file mode 100644 index 000000000..f9f00278d --- /dev/null +++ b/core/lib/Thelia/Core/Event/CustomerEvent.php @@ -0,0 +1,38 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + + +use Thelia\Model\Customer; + +class CustomerEvent extends InternalEvent { + + public $customer; + + public function __construct(Customer $customer) + { + $this->customer = $customer; + } + +} \ No newline at end of file From fd8290720943962df6242b05c35ac5e049f0390e Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 2 Aug 2013 16:18:45 +0200 Subject: [PATCH 6/8] folder and content fake folder and content loops --- core/lib/Thelia/Config/Resources/config.xml | 1 + .../lib/Thelia/Core/Template/Loop/Content.php | 238 ++++++++++++++++++ core/lib/Thelia/Core/Template/Loop/Folder.php | 7 +- .../lib/Thelia/Core/Template/Loop/Product.php | 1 + core/lib/Thelia/Model/Folder.php | 33 ++- core/lib/Thelia/Model/FolderQuery.php | 48 +++- install/faker.php | 15 +- templates/default/folder.html | 26 +- 8 files changed, 346 insertions(+), 23 deletions(-) create mode 100755 core/lib/Thelia/Core/Template/Loop/Content.php diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 17ed3b332..b5ccb598c 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -9,6 +9,7 @@ + diff --git a/core/lib/Thelia/Core/Template/Loop/Content.php b/core/lib/Thelia/Core/Template/Loop/Content.php new file mode 100755 index 000000000..f0606755d --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Content.php @@ -0,0 +1,238 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +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\Base\FeatureContentQuery; +use Thelia\Model\FolderQuery; +use Thelia\Model\Map\ContentTableMap; +use Thelia\Model\ContentFolderQuery; +use Thelia\Model\ContentQuery; +use Thelia\Model\ConfigQuery; +use Thelia\Type\TypeCollection; +use Thelia\Type; + +/** + * + * Content loop + * + * + * Class Content + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class Content extends BaseLoop +{ + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + Argument::createIntListTypeArgument('folder'), + Argument::createBooleanTypeArgument('current'), + Argument::createBooleanTypeArgument('current_folder'), + Argument::createIntTypeArgument('depth', 1), + Argument::createBooleanTypeArgument('visible', 1), + new Argument( + 'order', + new TypeCollection( + new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'random', 'given_id')) + ), + 'alpha' + ), + Argument::createIntListTypeArgument('exclude'), + Argument::createIntListTypeArgument('exclude_folder') + ); + } + + /** + * @param $pagination + * + * @return LoopResult + * @throws \InvalidArgumentException + */ + public function exec(&$pagination) + { + $search = ContentQuery::create(); + + $id = $this->getId(); + + if (!is_null($id)) { + $search->filterById($id, Criteria::IN); + } + + $folder = $this->getFolder(); + + if (!is_null($folder)) { + $folders = FolderQuery::create()->filterById($folder, Criteria::IN)->find(); + + $depth = $this->getDepth(); + + if(null !== $depth) { + foreach(FolderQuery::findAllChild($folder, $depth) as $subFolder) { + $folders->prepend($subFolder); + } + } + + $search->filterByFolder( + $folders, + Criteria::IN + ); + } + + $current = $this->getCurrent(); + + if ($current === true) { + $search->filterById($this->request->get("content_id")); + } elseif($current === false) { + $search->filterById($this->request->get("content_id"), Criteria::NOT_IN); + } + + $current_folder = $this->getCurrent_folder(); + + if ($current_folder === true) { + $search->filterByFolder( + FolderQuery::create()->filterByContent( + ContentFolderQuery::create()->filterByContentId( + $this->request->get("content_id"), + Criteria::EQUAL + )->find(), + Criteria::IN + )->find(), + Criteria::IN + ); + } elseif($current_folder === false) { + $search->filterByFolder( + FolderQuery::create()->filterByContent( + ContentFolderQuery::create()->filterByContentId( + $this->request->get("content_id"), + Criteria::EQUAL + )->find(), + Criteria::IN + )->find(), + Criteria::NOT_IN + ); + } + + $visible = $this->getVisible(); + + $search->filterByVisible($visible); + + $orders = $this->getOrder(); + + foreach($orders as $order) { + switch ($order) { + case "alpha": + $search->addAscendingOrderByColumn(\Thelia\Model\Map\ContentI18nTableMap::TITLE); + break; + case "alpha_reverse": + $search->addDescendingOrderByColumn(\Thelia\Model\Map\ContentI18nTableMap::TITLE); + break; + case "manual": + if(null === $folder || count($folder) != 1) + throw new \InvalidArgumentException('Manual order cannot be set without single folder argument'); + $search->orderByPosition(Criteria::ASC); + break; + case "manual_reverse": + if(null === $folder || count($folder) != 1) + throw new \InvalidArgumentException('Manual order cannot be set without single folder argument'); + $search->orderByPosition(Criteria::DESC); + break; + case "given_id": + if(null === $id) + throw new \InvalidArgumentException('Given_id order cannot be set without `id` argument'); + foreach($id as $singleId) { + $givenIdMatched = 'given_id_matched_' . $singleId; + $search->withColumn(ContentTableMap::ID . "='$singleId'", $givenIdMatched); + $search->orderBy($givenIdMatched, Criteria::DESC); + } + break; + case "random": + $search->clearOrderByColumns(); + $search->addAscendingOrderByColumn('RAND()'); + break(2); + } + } + + $exclude = $this->getExclude(); + + if (!is_null($exclude)) { + $search->filterById($exclude, Criteria::NOT_IN); + } + + $exclude_folder = $this->getExclude_folder(); + + if (!is_null($exclude_folder)) { + $search->filterByFolder( + FolderQuery::create()->filterById($exclude_folder, Criteria::IN)->find(), + Criteria::NOT_IN + ); + } + + /** + * 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 + ); + + $search->groupBy(ContentTableMap::ID); + + $contents = $this->search($search, $pagination); + + $loopResult = new LoopResult(); + + foreach ($contents as $content) { + $loopResultRow = new LoopResultRow(); + + $loopResultRow->set("ID", $content->getId()) + ->set("TITLE",$content->getTitle()) + ->set("CHAPO", $content->getChapo()) + ->set("DESCRIPTION", $content->getDescription()) + ->set("POSTSCRIPTUM", $content->getPostscriptum()) + ->set("POSITION", $content->getPosition()) + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } + +} diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index 93ae038b6..b6b5768fd 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -141,13 +141,13 @@ class Folder extends BaseLoop (ConfigQuery::read("default_lang_without_translation", 1)) ? Criteria::LEFT_JOIN : Criteria::INNER_JOIN ); - $categories = $this->search($search, $pagination); + $folders = $this->search($search, $pagination); $notEmpty = $this->getNot_empty(); $loopResult = new LoopResult(); - foreach ($categories as $folder) { + foreach ($folders as $folder) { if ($notEmpty && $folder->countAllProducts() == 0) continue; @@ -160,8 +160,7 @@ class Folder extends BaseLoop ->set("DESCRIPTION", $folder->getDescription()) ->set("POSTSCRIPTUM", $folder->getPostscriptum()) ->set("PARENT", $folder->getParent()) - ->set("URL", $folder->getUrl()) - ->set("PRODUCT_COUNT", $folder->countChild()) + ->set("CONTENT_COUNT", $folder->countChild()) ->set("VISIBLE", $folder->getVisible() ? "1" : "0") ->set("POSITION", $folder->getPosition()) diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 96033e56c..d50bfc495 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -109,6 +109,7 @@ class Product extends BaseLoop * @param $pagination * * @return \Thelia\Core\Template\Element\LoopResult + * @throws \InvalidArgumentException */ public function exec(&$pagination) { diff --git a/core/lib/Thelia/Model/Folder.php b/core/lib/Thelia/Model/Folder.php index b23f5998d..a19ab6796 100755 --- a/core/lib/Thelia/Model/Folder.php +++ b/core/lib/Thelia/Model/Folder.php @@ -4,6 +4,37 @@ namespace Thelia\Model; use Thelia\Model\Base\Folder as BaseFolder; -class Folder extends BaseFolder { +class Folder extends BaseFolder +{ + /** + * @return int number of contents for the folder + */ + public function countChild() + { + return FolderQuery::countChild($this->getId()); + } + /** + * + * count all products for current category and sub categories + * + * @return int + */ + public function countAllContents() + { + $children = FolderQuery::findAllChild($this->getId()); + array_push($children, $this); + + $contentsCount = 0; + + foreach($children as $child) + { + $contentsCount += ProductQuery::create() + ->filterByCategory($child) + ->count(); + } + + return $contentsCount; + + } } diff --git a/core/lib/Thelia/Model/FolderQuery.php b/core/lib/Thelia/Model/FolderQuery.php index 388dff085..949cbbc43 100755 --- a/core/lib/Thelia/Model/FolderQuery.php +++ b/core/lib/Thelia/Model/FolderQuery.php @@ -15,6 +15,52 @@ use Thelia\Model\Base\FolderQuery as BaseFolderQuery; * long as it does not already exist in the output directory. * */ -class FolderQuery extends BaseFolderQuery { +class FolderQuery extends BaseFolderQuery +{ + /** + * + * count how many direct contents a folder has + * + * @param int $parent folder id + * @return int + */ + public static function countChild($parent) + { + return self::create()->filterByParent($parent)->count(); + } + /** + * find all contents for a given folder. + * + * @param $folderId the folder id or an array of id + * @param int $depth max depth you want to search + * @param int $currentPosition don't change this param, it is used for recursion + * @return \Thelia\Model\Folder[] + */ + public static function findAllChild($folderId, $depth = 0, $currentPosition = 0) + { + $result = array(); + + if(is_array($folderId)) { + foreach($folderId as $folderSingleId) { + $result = array_merge($result, (array) self::findAllChild($folderSingleId, $depth, $currentPosition)); + } + } else { + $currentPosition++; + + if($depth == $currentPosition && $depth != 0) return; + + $categories = self::create() + ->filterByParent($folderId) + ->find(); + + + foreach ($categories as $folder) { + array_push($result, $folder); + $result = array_merge($result, (array) self::findAllChild($folder->getId(), $depth, $currentPosition)); + } + } + + return $result; + } } // FolderQuery diff --git a/install/faker.php b/install/faker.php index 2ade870e2..e528e9bc7 100755 --- a/install/faker.php +++ b/install/faker.php @@ -121,15 +121,26 @@ try { $folder->save(); - for($i=0; $isetParent($folder->getId()); $subfolder->setVisible(rand(1, 10)>7 ? 0 : 1); - $subfolder->setPosition($i); + $subfolder->setPosition($j); $subfolder->setTitle($faker->text(20)); $subfolder->setDescription($faker->text(255)); $subfolder->save(); + + for($k=0; $kaddFolder($subfolder); + $content->setVisible(rand(1, 10)>7 ? 0 : 1); + $content->setPosition($k); + $content->setTitle($faker->text(20)); + $content->setDescription($faker->text(255)); + + $content->save(); + } } } diff --git a/templates/default/folder.html b/templates/default/folder.html index ea50c314b..7d12036f9 100755 --- a/templates/default/folder.html +++ b/templates/default/folder.html @@ -1,20 +1,16 @@ -{loop name="folder0" type="folder" parent="0"} +{loop name="folder0" type="folder" parent="0" order="alpha_reverse"} +

FOLDER : #TITLE

{loop name="folder1" type="folder" parent="#ID"} -
+

SUBFOLDER : #TITLE (#LOOP_COUNT / #LOOP_TOTAL)

- {*loop name="content" type="content" folder="#ID"} -

CONTENT : #REF / #TITLE

- #PRICE € - {/loop*} -
-
+ {loop name="content" type="content" folder="#ID"} +
+

CONTENT : #TITLE

+

#DESCRIPTION

+
+ {/loop} +
{/loop} - - {*loop name="content" type="content" folder="#ID"} -

CONTENT : #REF / #TITLE

- #PRICE € - {/loop*} -
-
+
{/loop} \ No newline at end of file From 3507cde1f8e9ac03953866930c5a6345d20ffafd Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 2 Aug 2013 16:20:52 +0200 Subject: [PATCH 7/8] content and folder loops tests --- .../Tests/Core/Template/Loop/ContentTest.php | 51 +++++++++++++++++++ .../Tests/Core/Template/Loop/FolderTest.php | 51 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100755 core/lib/Thelia/Tests/Core/Template/Loop/ContentTest.php create mode 100755 core/lib/Thelia/Tests/Core/Template/Loop/FolderTest.php diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/ContentTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/ContentTest.php new file mode 100755 index 000000000..71922dbab --- /dev/null +++ b/core/lib/Thelia/Tests/Core/Template/Loop/ContentTest.php @@ -0,0 +1,51 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Core\Template\Loop; + +use Thelia\Tests\Core\Template\Element\BaseLoopTestor; + +use Thelia\Core\Template\Loop\Content; + +/** + * + * @author Etienne Roudeix + * + */ +class ContentTest extends BaseLoopTestor +{ + public function getTestedClassName() + { + return 'Thelia\Core\Template\Loop\Content'; + } + + public function getTestedInstance() + { + return new Content($this->request, $this->dispatcher, $this->securityContext); + } + + public function getMandatoryArguments() + { + return array(); + } +} diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/FolderTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/FolderTest.php new file mode 100755 index 000000000..2505c2fc2 --- /dev/null +++ b/core/lib/Thelia/Tests/Core/Template/Loop/FolderTest.php @@ -0,0 +1,51 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Core\Template\Loop; + +use Thelia\Tests\Core\Template\Element\BaseLoopTestor; + +use Thelia\Core\Template\Loop\Folder; + +/** + * + * @author Etienne Roudeix + * + */ +class FolderTest extends BaseLoopTestor +{ + public function getTestedClassName() + { + return 'Thelia\Core\Template\Loop\Folder'; + } + + public function getTestedInstance() + { + return new Folder($this->request, $this->dispatcher, $this->securityContext); + } + + public function getMandatoryArguments() + { + return array(); + } +} From 5c4bba4ce93788063832bbd68b1af2a894570424 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 2 Aug 2013 16:26:30 +0200 Subject: [PATCH 8/8] feature and feature_av in faker --- install/faker.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/install/faker.php b/install/faker.php index e528e9bc7..725bb26da 100755 --- a/install/faker.php +++ b/install/faker.php @@ -110,7 +110,7 @@ try { } - //folders + //folders and contents for($i=0; $i<4; $i++) { $folder = new Thelia\Model\Folder(); $folder->setParent(0); @@ -144,6 +144,27 @@ try { } } + //features and features_av + for($i=0; $i<4; $i++) { + $feature = new Thelia\Model\Feature(); + $feature->setVisible(rand(1, 10)>7 ? 0 : 1); + $feature->setPosition($i); + $feature->setTitle($faker->text(20)); + $feature->setDescription($faker->text(50)); + + $feature->save(); + + for($j=0; $jsetFeature($feature); + $featureAv->setPosition($j); + $featureAv->setTitle($faker->text(20)); + $featureAv->setDescription($faker->text(255)); + + $featureAv->save(); + } + } + $con->commit(); } catch (Exception $e) { echo "error : ".$e->getMessage()."\n";