This commit is contained in:
franck
2013-07-24 17:38:54 +02:00
22 changed files with 805 additions and 431 deletions

View File

@@ -51,7 +51,7 @@ abstract class BaseLoop
protected $securityContext;
private $args;
protected $args;
/**
* Create a new Loop
@@ -143,8 +143,6 @@ abstract class BaseLoop
$argument->setValue($value);
}
$this->args->next();
}
if (!empty($faultActor)) {

View File

@@ -0,0 +1,119 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
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 <eroudeix@openstudio.fr>
*/
class Accessory extends Product
{
/**
* @return ArgumentCollection
*/
protected function getArgDefinitions()
{
$argumentCollection = parent::getArgDefinitions();
$argumentCollection->addArgument(
Argument::createIntTypeArgument('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);
}
}

View File

@@ -46,12 +46,7 @@ use Thelia\Type;
* - 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 : sorting by title alphabetical order
* * alpha_reverse : sorting by title alphabetical reverse order
* * reverse : sorting by position descending
* * by default results are sorting by position ascending
* - random : if 1, random results. Default value is 0
* - 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 :
@@ -79,14 +74,13 @@ class Category extends BaseLoop
Argument::createBooleanTypeArgument('current'),
Argument::createBooleanTypeArgument('not_empty', 0),
Argument::createBooleanTypeArgument('visible', 1),
Argument::createAnyTypeArgument('link'),
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')
);
}
@@ -128,45 +122,32 @@ class Category extends BaseLoop
$search->filterById($exclude, Criteria::NOT_IN);
}
$link = $this->getLink();
if (!is_null($link)) {
$search->filterByLink($link);
}
$search->filterByVisible($this->getVisible() ? 1 : 0);
$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.
*
@@ -194,8 +175,7 @@ class Category extends BaseLoop
$loopResultRow->set("PARENT", $category->getParent());
$loopResultRow->set("ID", $category->getId());
$loopResultRow->set("URL", $category->getUrl());
$loopResultRow->set("LINK", $category->getLink());
$loopResultRow->set("NB_CHILD", $category->countChild());
$loopResultRow->set("PRODUCT_COUNT", $category->countChild());
$loopResult->addRow($loopResultRow);
}

View File

@@ -24,6 +24,7 @@
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;
@@ -32,7 +33,11 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Log\Tlog;
use Thelia\Model\Base\FeatureProdQuery;
use Thelia\Model\CategoryQuery;
use Thelia\Model\FeatureAvQuery;
use Thelia\Model\FeatureQuery;
use Thelia\Model\Map\FeatureProdTableMap;
use Thelia\Model\Map\ProductTableMap;
use Thelia\Model\ProductCategoryQuery;
use Thelia\Model\ProductQuery;
@@ -74,16 +79,29 @@ class Product extends BaseLoop
Argument::createFloatTypeArgument('max_weight'),
Argument::createBooleanTypeArgument('current'),
Argument::createBooleanTypeArgument('current_category'),
Argument::createIntTypeArgument('depth'),
Argument::createIntTypeArgument('depth', 1),
Argument::createBooleanTypeArgument('visible', 1),
new Argument(
'order',
new TypeCollection(
new Type\EnumListType(array('alpha', 'alpha_reverse', 'reverse', 'min_price', 'max_price', 'manual', 'manual_reverse', 'ref', 'promo', 'new'))
new Type\EnumListType(array('alpha', 'alpha_reverse', 'min_price', 'max_price', 'manual', 'manual_reverse', 'ref', 'promo', 'new', 'random', 'given_id'))
),
'manual'
),
Argument::createIntListTypeArgument('exclude'),
Argument::createIntListTypeArgument('exclude_category'),
new Argument(
'feature_available',
new TypeCollection(
new Type\IntToCombinedIntsListType()
)
),
Argument::createBooleanTypeArgument('random', 0),
Argument::createIntListTypeArgument('exclude')
new Argument(
'feature_values',
new TypeCollection(
new Type\IntToCombinedStringsListType()
)
)
);
}
@@ -231,70 +249,133 @@ class Product extends BaseLoop
);
}
$search->filterByVisible($this->getVisible());
$visible = $this->getVisible();
$search->filterByVisible($visible);
$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;
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 "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(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);
}
}
$random = $this->getRandom();
if ($random === true) {
$search->clearOrderByColumns();
$search->addAscendingOrderByColumn('RAND()');
}
$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->joinFeatureProd($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->joinFeatureProd($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.
*
@@ -306,6 +387,8 @@ class Product extends BaseLoop
(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();
@@ -324,8 +407,6 @@ class Product extends BaseLoop
$loopResultRow->set("PROMO", $product->getPromo());
$loopResultRow->set("NEW", $product->getNewness());
//$loopResultRow->set("URL", $product->getUrl());
$loopResult->addRow($loopResultRow);
}