diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 98017f979..07d12d9f0 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -7,19 +7,22 @@ + + - + + diff --git a/core/lib/Thelia/Core/Template/Loop/Attribute.php b/core/lib/Thelia/Core/Template/Loop/Attribute.php new file mode 100755 index 000000000..1c7b23acf --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Attribute.php @@ -0,0 +1,169 @@ +. */ +/* */ +/*************************************************************************************/ + +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\CategoryQuery; +use Thelia\Model\Base\ProductCategoryQuery; +use Thelia\Model\Base\AttributeQuery; +use Thelia\Model\ConfigQuery; +use Thelia\Model\Map\ProductCategoryTableMap; +use Thelia\Type\TypeCollection; +use Thelia\Type; +use Thelia\Type\BooleanOrBothType; + +/** + * + * Attribute loop + * + * + * Class Attribute + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class Attribute extends BaseLoop +{ + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + Argument::createIntListTypeArgument('product'), + Argument::createIntListTypeArgument('category'), + Argument::createBooleanOrBothTypeArgument('visible', 1), + Argument::createIntListTypeArgument('exclude'), + new Argument( + 'order', + new TypeCollection( + new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse')) + ), + 'manual' + ) + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = AttributeQuery::create(); + + $id = $this->getId(); + + if (null !== $id) { + $search->filterById($id, Criteria::IN); + } + + $exclude = $this->getExclude(); + + if (null !== $exclude) { + $search->filterById($exclude, Criteria::NOT_IN); + } + + $visible = $this->getVisible(); + + if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible); + + $product = $this->getProduct(); + $category = $this->getCategory(); + + if(null !== $product) { + $productCategories = ProductCategoryQuery::create()->select(array(ProductCategoryTableMap::CATEGORY_ID))->filterByProductId($product, Criteria::IN)->find()->getData(); + + if(null === $category) { + $category = $productCategories; + } else { + $category = array_merge($category, $productCategories); + } + } + + if(null !== $category) { + $search->filterByCategory( + CategoryQuery::create()->filterById($category)->find(), + Criteria::IN + ); + } + + $orders = $this->getOrder(); + + foreach($orders as $order) { + switch ($order) { + case "alpha": + $search->addAscendingOrderByColumn(\Thelia\Model\Map\AttributeI18nTableMap::TITLE); + break; + case "alpha_reverse": + $search->addDescendingOrderByColumn(\Thelia\Model\Map\AttributeI18nTableMap::TITLE); + break; + case "manual": + $search->orderByPosition(Criteria::ASC); + break; + case "manual_reverse": + $search->orderByPosition(Criteria::DESC); + 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 + ); + + $attributes = $this->search($search, $pagination); + + $loopResult = new LoopResult(); + + foreach ($attributes as $attribute) { + $loopResultRow = new LoopResultRow(); + $loopResultRow->set("ID", $attribute->getId()); + $loopResultRow->set("TITLE",$attribute->getTitle()); + $loopResultRow->set("CHAPO", $attribute->getChapo()); + $loopResultRow->set("DESCRIPTION", $attribute->getDescription()); + $loopResultRow->set("POSTSCRIPTUM", $attribute->getPostscriptum()); + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php new file mode 100755 index 000000000..1033bf450 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php @@ -0,0 +1,144 @@ +. */ +/* */ +/*************************************************************************************/ + +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\AttributeAvQuery; +use Thelia\Model\ConfigQuery; +use Thelia\Type\TypeCollection; +use Thelia\Type; + +/** + * AttributeAvailability loop + * + * + * Class AttributeAvailability + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class AttributeAvailability extends BaseLoop +{ + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + Argument::createIntListTypeArgument('attribute'), + Argument::createIntListTypeArgument('exclude'), + new Argument( + 'order', + new TypeCollection( + new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse')) + ), + 'manual' + ) + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = AttributeAvQuery::create(); + + $id = $this->getId(); + + if (null !== $id) { + $search->filterById($id, Criteria::IN); + } + + $exclude = $this->getExclude(); + + if (null !== $exclude) { + $search->filterById($exclude, Criteria::NOT_IN); + } + + $attribute = $this->getAttribute(); + + if(null !== $attribute) { + $search->filterByAttributeId($attribute, Criteria::IN); + } + + $orders = $this->getOrder(); + + foreach($orders as $order) { + switch ($order) { + case "alpha": + $search->addAscendingOrderByColumn(\Thelia\Model\Map\AttributeAvI18nTableMap::TITLE); + break; + case "alpha_reverse": + $search->addDescendingOrderByColumn(\Thelia\Model\Map\AttributeAvI18nTableMap::TITLE); + break; + case "manual": + $search->orderByPosition(Criteria::ASC); + break; + case "manual_reverse": + $search->orderByPosition(Criteria::DESC); + 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 + ); + + $attributesAv = $this->search($search, $pagination); + + $loopResult = new LoopResult(); + + foreach ($attributesAv as $attributeAv) { + $loopResultRow = new LoopResultRow(); + $loopResultRow->set("ID", $attributeAv->getId()); + $loopResultRow->set("TITLE",$attributeAv->getTitle()); + $loopResultRow->set("CHAPO", $attributeAv->getChapo()); + $loopResultRow->set("DESCRIPTION", $attributeAv->getDescription()); + $loopResultRow->set("POSTSCRIPTUM", $attributeAv->getPostscriptum()); + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index a3769150d..d856b6d73 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -47,7 +47,7 @@ use Thelia\Type\BooleanOrBothType; * - current : current id is used if you are on a category page * - not_empty : if value is 1, category and subcategories must have at least 1 product * - visible : default 1, if you want category not visible put 0 - * - order : all value available : 'alpha', 'alpha_reverse', 'manual' (default), 'manual-reverse', 'random' + * - order : all value available : 'alpha', 'alpha_reverse', 'manual' (default), 'manual_reverse', 'random' * - exclude : all category id you want to exclude (as for id, an integer or a "string list" can be used) * * example : @@ -78,7 +78,7 @@ class Category extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual-reverse', 'random')) + new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'random')) ), 'manual' ), @@ -136,7 +136,7 @@ class Category extends BaseLoop case "alpha_reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\CategoryI18nTableMap::TITLE); break; - case "manual-reverse": + case "manual_reverse": $search->orderByPosition(Criteria::DESC); break; case "manual": diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureAvailable.php b/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php similarity index 97% rename from core/lib/Thelia/Core/Template/Loop/FeatureAvailable.php rename to core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php index 595794bf4..888d30a92 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureAvailable.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php @@ -39,15 +39,14 @@ use Thelia\Type\TypeCollection; use Thelia\Type; /** - *todo : to be finished - * FeatureAvailable loop + * FeatureAvailability loop * * - * Class FeatureAvailable + * Class FeatureAvailability * @package Thelia\Core\Template\Loop * @author Etienne Roudeix */ -class FeatureAvailable extends BaseLoop +class FeatureAvailability extends BaseLoop { /** * @return ArgumentCollection diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index 13d0409a6..e41361d0a 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -60,7 +60,7 @@ class Folder extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual-reverse', 'random')) + new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'random')) ), 'manual' ), @@ -119,7 +119,7 @@ class Folder extends BaseLoop case "alpha_reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\FolderI18nTableMap::TITLE); break; - case "manual-reverse": + case "manual_reverse": $search->orderByPosition(Criteria::DESC); break; case "manual": diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 8d892a446..2efddad94 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -33,10 +33,7 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; -use Thelia\Model\Base\FeatureProductQuery; use Thelia\Model\CategoryQuery; -use Thelia\Model\FeatureAvQuery; -use Thelia\Model\FeatureQuery; use Thelia\Model\Map\FeatureProductTableMap; use Thelia\Model\Map\ProductTableMap; use Thelia\Model\ProductCategoryQuery; @@ -71,13 +68,13 @@ class Product extends BaseLoop ) ), Argument::createIntListTypeArgument('category'), - //Argument::createBooleanTypeArgument('new'), - //Argument::createBooleanTypeArgument('promo'), - //Argument::createFloatTypeArgument('min_price'), - //Argument::createFloatTypeArgument('max_price'), - //Argument::createIntTypeArgument('min_stock'), - //Argument::createFloatTypeArgument('min_weight'), - //Argument::createFloatTypeArgument('max_weight'), + Argument::createBooleanTypeArgument('new'), + Argument::createBooleanTypeArgument('promo'), + Argument::createFloatTypeArgument('min_price'), + Argument::createFloatTypeArgument('max_price'), + Argument::createIntTypeArgument('min_stock'), + Argument::createFloatTypeArgument('min_weight'), + Argument::createFloatTypeArgument('max_weight'), Argument::createBooleanTypeArgument('current'), Argument::createBooleanTypeArgument('current_category'), Argument::createIntTypeArgument('depth', 1), @@ -85,7 +82,7 @@ class Product extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', /*'min_price', 'max_price',*/ 'manual', 'manual_reverse', 'ref', /*'promo', 'new',*/ 'random', 'given_id')) + new Type\EnumListType(array('alpha', 'alpha_reverse', 'min_price', 'max_price', 'manual', 'manual_reverse', 'ref', 'promo', 'new', 'random', 'given_id')) ), 'alpha' ), @@ -149,20 +146,24 @@ class Product extends BaseLoop ); } - /*$new = $this->getNew(); + $new = $this->getNew(); if ($new === true) { - $search->filterByNewness(1, Criteria::EQUAL); + $search->joinProductSaleElements('is_new', Criteria::INNER_JOIN) + ->addJoinCondition('is_new', "`is_new`.NEWNESS = 1"); } else if($new === false) { - $search->filterByNewness(0, Criteria::EQUAL); + $search->joinProductSaleElements('is_new', Criteria::INNER_JOIN) + ->addJoinCondition('is_new', "`is_new`.NEWNESS = 0"); } $promo = $this->getPromo(); if ($promo === true) { - $search->filterByPromo(1, Criteria::EQUAL); + $search->joinProductSaleElements('is_promo', Criteria::INNER_JOIN) + ->addJoinCondition('is_promo', "`is_promo`.PROMO = 1"); } else if($promo === false) { - $search->filterByNewness(0, Criteria::EQUAL); + $search->joinProductSaleElements('is_promo', Criteria::INNER_JOIN) + ->addJoinCondition('is_promo', "`is_promo`.PROMO = 0"); } $min_stock = $this->getMin_stock(); @@ -171,7 +172,7 @@ class Product extends BaseLoop $search->filterByQuantity($min_stock, Criteria::GREATER_EQUAL); } - $min_price = $this->getMin_price();*/ + //$min_price = $this->getMin_price(); //if(null !== $min_price) { /** diff --git a/core/lib/Thelia/Core/Template/Loop/ProductSaleElement.php b/core/lib/Thelia/Core/Template/Loop/ProductSaleElement.php new file mode 100755 index 000000000..8d892a446 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/ProductSaleElement.php @@ -0,0 +1,420 @@ +. */ +/* */ +/*************************************************************************************/ + +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\FeatureProductQuery; +use Thelia\Model\CategoryQuery; +use Thelia\Model\FeatureAvQuery; +use Thelia\Model\FeatureQuery; +use Thelia\Model\Map\FeatureProductTableMap; +use Thelia\Model\Map\ProductTableMap; +use Thelia\Model\ProductCategoryQuery; +use Thelia\Model\ProductQuery; +use Thelia\Model\ConfigQuery; +use Thelia\Type\TypeCollection; +use Thelia\Type; +use Thelia\Type\BooleanOrBothType; + +/** + * + * Product loop + * + * + * Class Product + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class Product extends BaseLoop +{ + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + new Argument( + 'ref', + new TypeCollection( + new Type\AlphaNumStringListType() + ) + ), + Argument::createIntListTypeArgument('category'), + //Argument::createBooleanTypeArgument('new'), + //Argument::createBooleanTypeArgument('promo'), + //Argument::createFloatTypeArgument('min_price'), + //Argument::createFloatTypeArgument('max_price'), + //Argument::createIntTypeArgument('min_stock'), + //Argument::createFloatTypeArgument('min_weight'), + //Argument::createFloatTypeArgument('max_weight'), + Argument::createBooleanTypeArgument('current'), + Argument::createBooleanTypeArgument('current_category'), + Argument::createIntTypeArgument('depth', 1), + Argument::createBooleanOrBothTypeArgument('visible', 1), + new Argument( + 'order', + new TypeCollection( + new Type\EnumListType(array('alpha', 'alpha_reverse', /*'min_price', 'max_price',*/ 'manual', 'manual_reverse', 'ref', /*'promo', 'new',*/ 'random', 'given_id')) + ), + 'alpha' + ), + Argument::createIntListTypeArgument('exclude'), + Argument::createIntListTypeArgument('exclude_category'), + new Argument( + 'feature_available', + new TypeCollection( + new Type\IntToCombinedIntsListType() + ) + ), + new Argument( + 'feature_values', + new TypeCollection( + new Type\IntToCombinedStringsListType() + ) + ) + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + * @throws \InvalidArgumentException + */ + public function exec(&$pagination) + { + $search = ProductQuery::create(); + + //$search->withColumn('CASE WHEN ' . ProductTableMap::PROMO . '=1 THEN ' . ProductTableMap::PRICE2 . ' ELSE ' . ProductTableMap::PRICE . ' END', 'real_price'); + + $id = $this->getId(); + + if (!is_null($id)) { + $search->filterById($id, Criteria::IN); + } + + $ref = $this->getRef(); + + if (!is_null($ref)) { + $search->filterByRef($ref, Criteria::IN); + } + + $category = $this->getCategory(); + + if (!is_null($category)) { + $categories = CategoryQuery::create()->filterById($category, Criteria::IN)->find(); + + $depth = $this->getDepth(); + + if(null !== $depth) { + foreach(CategoryQuery::findAllChild($category, $depth) as $subCategory) { + $categories->prepend($subCategory); + } + } + + $search->filterByCategory( + $categories, + Criteria::IN + ); + } + + /*$new = $this->getNew(); + + if ($new === true) { + $search->filterByNewness(1, Criteria::EQUAL); + } else if($new === false) { + $search->filterByNewness(0, Criteria::EQUAL); + } + + $promo = $this->getPromo(); + + if ($promo === true) { + $search->filterByPromo(1, Criteria::EQUAL); + } else if($promo === false) { + $search->filterByNewness(0, Criteria::EQUAL); + } + + $min_stock = $this->getMin_stock(); + + if (null != $min_stock) { + $search->filterByQuantity($min_stock, Criteria::GREATER_EQUAL); + } + + $min_price = $this->getMin_price();*/ + + //if(null !== $min_price) { + /** + * Following should work but does not : + * + * $search->filterBy('real_price', $max_price, Criteria::GREATER_EQUAL); + */ + /*$search->condition('in_promo', ProductTableMap::PROMO . Criteria::EQUAL . '1') + ->condition('not_in_promo', ProductTableMap::PROMO . Criteria::NOT_EQUAL . '1') + ->condition('min_price2', ProductTableMap::PRICE2 . Criteria::GREATER_EQUAL . '?', $min_price) + ->condition('min_price', ProductTableMap::PRICE . Criteria::GREATER_EQUAL . '?', $min_price) + ->combine(array('in_promo', 'min_price2'), Criteria::LOGICAL_AND, 'in_promo_min_price') + ->combine(array('not_in_promo', 'min_price'), Criteria::LOGICAL_AND, 'not_in_promo_min_price') + ->where(array('not_in_promo_min_price', 'in_promo_min_price'), Criteria::LOGICAL_OR); + } + + $max_price = $this->getMax_price();*/ + + //if(null !== $max_price) { + /** + * Following should work but does not : + * + * $search->filterBy('real_price', $max_price, Criteria::LESS_EQUAL); + */ + /*$search->condition('in_promo', ProductTableMap::PROMO . Criteria::EQUAL . '1') + ->condition('not_in_promo', ProductTableMap::PROMO . Criteria::NOT_EQUAL . '1') + ->condition('max_price2', ProductTableMap::PRICE2 . Criteria::LESS_EQUAL . '?', $max_price) + ->condition('max_price', ProductTableMap::PRICE . Criteria::LESS_EQUAL . '?', $max_price) + ->combine(array('in_promo', 'max_price2'), Criteria::LOGICAL_AND, 'in_promo_max_price') + ->combine(array('not_in_promo', 'max_price'), Criteria::LOGICAL_AND, 'not_in_promo_max_price') + ->where(array('not_in_promo_max_price', 'in_promo_max_price'), Criteria::LOGICAL_OR); + }*/ + + /*$min_weight = $this->getMin_weight(); + + if(null !== $min_weight) { + $search->filterByWeight($min_weight, Criteria::GREATER_EQUAL); + } + + $max_weight = $this->getMax_weight(); + + if(null !== $max_weight) { + $search->filterByWeight($max_weight, Criteria::LESS_EQUAL); + }*/ + + $current = $this->getCurrent(); + + if ($current === true) { + $search->filterById($this->request->get("product_id")); + } elseif($current === false) { + $search->filterById($this->request->get("product_id"), Criteria::NOT_IN); + } + + $current_category = $this->getCurrent_category(); + + if ($current_category === true) { + $search->filterByCategory( + CategoryQuery::create()->filterByProduct( + ProductCategoryQuery::create()->filterByProductId( + $this->request->get("product_id"), + Criteria::EQUAL + )->find(), + Criteria::IN + )->find(), + Criteria::IN + ); + } elseif($current_category === false) { + $search->filterByCategory( + CategoryQuery::create()->filterByProduct( + ProductCategoryQuery::create()->filterByProductId( + $this->request->get("product_id"), + Criteria::EQUAL + )->find(), + Criteria::IN + )->find(), + Criteria::NOT_IN + ); + } + + $visible = $this->getVisible(); + + if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0); + + $orders = $this->getOrder(); + + 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 "min_price": + $search->orderBy('real_price', Criteria::ASC); + break; + case "max_price": + $search->orderBy('real_price', Criteria::DESC); + break;*/ + case "manual": + if(null === $category || count($category) != 1) + throw new \InvalidArgumentException('Manual order cannot be set without single category argument'); + $search->orderByPosition(Criteria::ASC); + break; + case "manual_reverse": + if(null === $category || count($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(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(ProductTableMap::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_category = $this->getExclude_category(); + + if (!is_null($exclude_category)) { + $search->filterByCategory( + CategoryQuery::create()->filterById($exclude_category, Criteria::IN)->find(), + Criteria::NOT_IN + ); + } + + $feature_available = $this->getFeature_available(); + + if(null !== $feature_available) { + foreach($feature_available as $feature => $feature_choice) { + foreach($feature_choice['values'] as $feature_av) { + $featureAlias = 'fa_' . $feature; + if($feature_av != '*') + $featureAlias .= '_' . $feature_av; + $search->joinFeatureProduct($featureAlias, Criteria::LEFT_JOIN) + ->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_ID = ?", $feature, null, \PDO::PARAM_INT); + if($feature_av != '*') + $search->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_AV_ID = ?", $feature_av, null, \PDO::PARAM_INT); + } + + /* format for mysql */ + $sqlWhereString = $feature_choice['expression']; + if($sqlWhereString == '*') { + $sqlWhereString = 'NOT ISNULL(`fa_' . $feature . '`.ID)'; + } else { + $sqlWhereString = preg_replace('#([0-9]+)#', 'NOT ISNULL(`fa_' . $feature . '_' . '\1`.ID)', $sqlWhereString); + $sqlWhereString = str_replace('&', ' AND ', $sqlWhereString); + $sqlWhereString = str_replace('|', ' OR ', $sqlWhereString); + } + + $search->where("(" . $sqlWhereString . ")"); + } + } + + $feature_values = $this->getFeature_values(); + + if(null !== $feature_values) { + foreach($feature_values as $feature => $feature_choice) { + foreach($feature_choice['values'] as $feature_value) { + $featureAlias = 'fv_' . $feature; + if($feature_value != '*') + $featureAlias .= '_' . $feature_value; + $search->joinFeatureProduct($featureAlias, Criteria::LEFT_JOIN) + ->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_ID = ?", $feature, null, \PDO::PARAM_INT); + if($feature_value != '*') + $search->addJoinCondition($featureAlias, "`$featureAlias`.BY_DEFAULT = ?", $feature_value, null, \PDO::PARAM_STR); + } + + /* format for mysql */ + $sqlWhereString = $feature_choice['expression']; + if($sqlWhereString == '*') { + $sqlWhereString = 'NOT ISNULL(`fv_' . $feature . '`.ID)'; + } else { + $sqlWhereString = preg_replace('#([a-zA-Z0-9_\-]+)#', 'NOT ISNULL(`fv_' . $feature . '_' . '\1`.ID)', $sqlWhereString); + $sqlWhereString = str_replace('&', ' AND ', $sqlWhereString); + $sqlWhereString = str_replace('|', ' OR ', $sqlWhereString); + } + + $search->where("(" . $sqlWhereString . ")"); + } + } + + /** + * 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(ProductTableMap::ID); + + $products = $this->search($search, $pagination); + + $loopResult = new LoopResult(); + + foreach ($products as $product) { + $loopResultRow = new LoopResultRow(); + + $loopResultRow->set("ID", $product->getId()) + ->set("REF",$product->getRef()) + ->set("TITLE",$product->getTitle()) + ->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("POSITION", $product->getPosition()) + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } + +} diff --git a/install/faker.php b/install/faker.php index 39c3270e8..d3d073994 100755 --- a/install/faker.php +++ b/install/faker.php @@ -12,6 +12,22 @@ $currency = \Thelia\Model\CurrencyQuery::create()->filterByCode('EUR')->findOne( try { + $feature = Thelia\Model\FeatureQuery::create() + ->find(); + $feature->delete(); + + $featureAv = Thelia\Model\FeatureAvQuery::create() + ->find(); + $featureAv->delete(); + + $attribute = Thelia\Model\AttributeQuery::create() + ->find(); + $attribute->delete(); + + $attributeAv = Thelia\Model\AttributeAvQuery::create() + ->find(); + $attributeAv->delete(); + $category = Thelia\Model\CategoryQuery::create() ->find(); $category->delete(); @@ -54,6 +70,14 @@ try { ->find(); $accessory->delete(); + $stock = \Thelia\Model\ProductSaleElementsQuery::create() + ->find(); + $stock->delete(); + + $productPrice = \Thelia\Model\ProductPriceQuery::create() + ->find(); + $productPrice->delete(); + //features and features_av $featureList = array(); for($i=0; $i<4; $i++) { @@ -79,78 +103,46 @@ try { } } + //attributes and attributes_av + $attributeList = array(); + for($i=0; $i<4; $i++) { + $attribute = new Thelia\Model\Attribute(); + $attribute->setPosition($i); + $attribute->setTitle($faker->text(20)); + $attribute->setDescription($faker->text(50)); + + $attribute->save(); + $attributeId = $attribute->getId(); + $attributeList[$attributeId] = array(); + + for($j=0; $jsetAttribute($attribute); + $attributeAv->setPosition($j); + $attributeAv->setTitle($faker->text(20)); + $attributeAv->setDescription($faker->text(255)); + + $attributeAv->save(); + $attributeList[$attributeId][] = $attributeAv->getId(); + } + } + //categories and products $productIdList = array(); $categoryIdList = array(); for($i=0; $i<4; $i++) { - $category = new Thelia\Model\Category(); - $category->setParent(0); - $category->setVisible(rand(1, 10)>7 ? 0 : 1); - $category->setPosition($i); - $category->setTitle($faker->text(20)); - $category->setDescription($faker->text(255)); + $category = createCategory($faker, 0, $i, $categoryIdList); - $category->save(); - $categoryIdList[] = $category->getId(); + for($j=1; $jgetId(), $j, $categoryIdList); - for($j=0; $jsetParent($category->getId()); - $subcategory->setVisible(rand(1, 10)>7 ? 0 : 1); - $subcategory->setPosition($j); - $subcategory->setTitle($faker->text(20)); - $subcategory->setDescription($faker->text(255)); - - $subcategory->save(); - $categoryIdList[] = $subcategory->getId(); - - for($k=0; $ksetRef($subcategory->getId() . '_' . $k . '_' . $faker->randomNumber(8)); - $product->addCategory($subcategory); - $product->setVisible(rand(1, 10)>7 ? 0 : 1); - $product->setPosition($k); - $product->setTitle($faker->text(20)); - $product->setDescription($faker->text(255)); - - $product->save(); - $productId = $product->getId(); - $productIdList[] = $productId; - - //add random accessories - or not - for($l=0; $lsetAccessory($productIdList[array_rand($productIdList, 1)]); - $accessory->setProductId($productId); - $accessory->setPosition($l); - - $accessory->save(); - } + for($k=0; $ksetRef($category->getId() . '_' . $k . '_' . $faker->randomNumber(8)); - $product->addCategory($category); - $product->setVisible(rand(1, 10)>7 ? 0 : 1); - $product->setPosition($k); - $product->setTitle($faker->text(20)); - $product->setDescription($faker->text(255)); - - $product->save(); - $productId = $product->getId(); - $productIdList[] = $productId; - - //add random accessories - for($l=0; $lsetAccessory($productIdList[array_rand($productIdList, 1)]); - $accessory->setProductId($productId); - $accessory->setPosition($l); - - $accessory->save(); - } + createProduct($faker, $category, $k, $currency, $productIdList); } } @@ -165,7 +157,7 @@ try { $folder->save(); - for($j=0; $jsetParent($folder->getId()); $subfolder->setVisible(rand(1, 10)>7 ? 0 : 1); @@ -175,7 +167,7 @@ try { $subfolder->save(); - for($k=0; $kaddFolder($subfolder); $content->setVisible(rand(1, 10)>7 ? 0 : 1); @@ -194,5 +186,60 @@ try { $con->rollBack(); } +function createProduct($faker, $category, $position, $currency, &$productIdList) +{ + $product = new Thelia\Model\Product(); + $product->setRef($category->getId() . '_' . $position . '_' . $faker->randomNumber(8)); + $product->addCategory($category); + $product->setVisible(rand(1, 10)>7 ? 0 : 1); + $product->setPosition($position); + $product->setTitle($faker->text(20)); + $product->setDescription($faker->text(255)); + $product->save(); + $productId = $product->getId(); + $productIdList[] = $productId; + + $stock = new \Thelia\Model\ProductSaleElements(); + $stock->setProduct($product); + $stock->setQuantity($faker->randomNumber(1,50)); + $stock->setPromo($faker->randomNumber(0,1)); + $stock->setNewness($faker->randomNumber(0,1)); + $stock->setWeight($faker->randomFloat(2, 100,10000)); + $stock->save(); + + $productPrice = new \Thelia\Model\ProductPrice(); + $productPrice->setProductSaleElements($stock); + $productPrice->setCurrency($currency); + $productPrice->setPrice($faker->randomFloat(2, 20, 250)); + $productPrice->setPromoPrice($faker->randomFloat(2, 20, 250)); + $productPrice->save(); + + //add random accessories - or not + for($i=1; $isetAccessory($productIdList[array_rand($productIdList, 1)]); + $accessory->setProductId($productId); + $accessory->setPosition($i); + + $accessory->save(); + } + + return $product; +} + +function createCategory($faker, $parent, $position, &$categoryIdList) +{ + $category = new Thelia\Model\Category(); + $category->setParent($parent); + $category->setVisible(rand(1, 10)>7 ? 0 : 1); + $category->setPosition($position); + $category->setTitle($faker->text(20)); + $category->setDescription($faker->text(255)); + + $category->save(); + $categoryIdList[] = $category->getId(); + + return $category; +} diff --git a/templates/default/category.html b/templates/default/category.html index 6aabd6edf..9a79f24c2 100755 --- a/templates/default/category.html +++ b/templates/default/category.html @@ -1,3 +1,5 @@ +

Category page

+

CATALOG

@@ -90,17 +92,30 @@ {/loop} +
+ +

ALL ATTRIBUTES AND THEIR AVAILABILITY

+ +
    + {loop name="attr" type="attribute" order="manual"} +
  • + #TITLE +
      + {loop name="attrav" type="attribute_available" order="manual" attribute="#ID"} +
    • #TITLE
    • + {/loop} +
    +
  • + {/loop} +
+
- {*loop name="product" type="product" order="promo,min_price" exclude_category="3"} + + {loop name="product" type="product" order="promo,min_price" exclude_category="3" new="on" promo="off"}

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" feature_available="1: (1 | 2) , 2: 4, 3: 433"}

PRODUCT : #REF / #TITLE