From fd8290720943962df6242b05c35ac5e049f0390e Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 2 Aug 2013 16:18:45 +0200 Subject: [PATCH] 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