@@ -171,7 +171,6 @@ class CustomerController extends AbstractCrudController
|
|||||||
{
|
{
|
||||||
return $this->render('customers', array_merge(array(
|
return $this->render('customers', array_merge(array(
|
||||||
'customer_order' => $currentOrder,
|
'customer_order' => $currentOrder,
|
||||||
'display_customer' => 20,
|
|
||||||
'page' => $this->getRequest()->get('page', 1)
|
'page' => $this->getRequest()->get('page', 1)
|
||||||
), $customParams)
|
), $customParams)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,10 +14,13 @@ namespace Thelia\Core\Template\Element;
|
|||||||
|
|
||||||
use Propel\Runtime\ActiveQuery\Criteria;
|
use Propel\Runtime\ActiveQuery\Criteria;
|
||||||
use Propel\Runtime\ActiveQuery\ModelCriteria;
|
use Propel\Runtime\ActiveQuery\ModelCriteria;
|
||||||
|
use Propel\Runtime\Collection\ObjectCollection;
|
||||||
|
use Propel\Runtime\Util\PropelModelPager;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Thelia\Core\Security\SecurityContext;
|
use Thelia\Core\Security\SecurityContext;
|
||||||
use Thelia\Core\Template\Element\Exception\LoopException;
|
use Thelia\Core\Template\Element\Exception\LoopException;
|
||||||
use Thelia\Core\Template\Loop\Argument\Argument;
|
use Thelia\Core\Template\Loop\Argument\Argument;
|
||||||
|
use Thelia\Core\Translation\Translator;
|
||||||
use Thelia\Type\EnumListType;
|
use Thelia\Type\EnumListType;
|
||||||
use Thelia\Type\EnumType;
|
use Thelia\Type\EnumType;
|
||||||
use Thelia\Type\TypeCollection;
|
use Thelia\Type\TypeCollection;
|
||||||
@@ -53,8 +56,11 @@ abstract class BaseLoop
|
|||||||
protected $timestampable = false;
|
protected $timestampable = false;
|
||||||
protected $versionable = false;
|
protected $versionable = false;
|
||||||
|
|
||||||
private static $cacheLoopResult = array();
|
/** @var Translator */
|
||||||
private static $cacheCount = array();
|
protected $translator = null;
|
||||||
|
|
||||||
|
private static $cacheLoopResult = [];
|
||||||
|
private static $cacheCount = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Loop
|
* Create a new Loop
|
||||||
@@ -70,6 +76,7 @@ abstract class BaseLoop
|
|||||||
$this->request = $container->get('request');
|
$this->request = $container->get('request');
|
||||||
$this->dispatcher = $container->get('event_dispatcher');
|
$this->dispatcher = $container->get('event_dispatcher');
|
||||||
$this->securityContext = $container->get('thelia.securityContext');
|
$this->securityContext = $container->get('thelia.securityContext');
|
||||||
|
$this->translator = $container->get("thelia.translator");
|
||||||
|
|
||||||
$this->args = $this->getArgDefinitions()->addArguments($this->getDefaultArgs(), false);
|
$this->args = $this->getArgDefinitions()->addArguments($this->getDefaultArgs(), false);
|
||||||
}
|
}
|
||||||
@@ -81,53 +88,54 @@ abstract class BaseLoop
|
|||||||
*/
|
*/
|
||||||
protected function getDefaultArgs()
|
protected function getDefaultArgs()
|
||||||
{
|
{
|
||||||
$defaultArgs = array(
|
$defaultArgs = [
|
||||||
Argument::createBooleanTypeArgument('backend_context', false),
|
Argument::createBooleanTypeArgument('backend_context', false),
|
||||||
Argument::createBooleanTypeArgument('force_return', false),
|
Argument::createBooleanTypeArgument('force_return', false),
|
||||||
Argument::createAnyTypeArgument('type'),
|
Argument::createAnyTypeArgument('type'),
|
||||||
);
|
];
|
||||||
|
|
||||||
if (true === $this->countable) {
|
if (true === $this->countable) {
|
||||||
$defaultArgs = array_merge($defaultArgs, array(
|
$defaultArgs = array_merge($defaultArgs, [
|
||||||
Argument::createIntTypeArgument('offset', 0),
|
Argument::createIntTypeArgument('offset', 0),
|
||||||
Argument::createIntTypeArgument('page'),
|
Argument::createIntTypeArgument('page'),
|
||||||
Argument::createIntTypeArgument('limit', PHP_INT_MAX),
|
Argument::createIntTypeArgument('limit', PHP_INT_MAX),
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this instanceof SearchLoopInterface) {
|
if ($this instanceof SearchLoopInterface) {
|
||||||
$defaultArgs = array_merge($defaultArgs, array(
|
|
||||||
Argument::createAnyTypeArgument('search_term'),
|
$defaultArgs = array_merge($defaultArgs, [
|
||||||
new Argument(
|
Argument::createAnyTypeArgument('search_term'),
|
||||||
'search_in',
|
new Argument(
|
||||||
new TypeCollection(
|
'search_in',
|
||||||
new EnumListType($this->getSearchIn())
|
new TypeCollection(
|
||||||
)
|
new EnumListType($this->getSearchIn())
|
||||||
),
|
)
|
||||||
new Argument(
|
|
||||||
'search_mode',
|
|
||||||
new TypeCollection(
|
|
||||||
new EnumType(array(
|
|
||||||
SearchLoopInterface::MODE_ANY_WORD,
|
|
||||||
SearchLoopInterface::MODE_SENTENCE,
|
|
||||||
SearchLoopInterface::MODE_STRICT_SENTENCE,
|
|
||||||
))
|
|
||||||
),
|
),
|
||||||
SearchLoopInterface::MODE_STRICT_SENTENCE
|
new Argument(
|
||||||
)
|
'search_mode',
|
||||||
));
|
new TypeCollection(
|
||||||
|
new EnumType([
|
||||||
|
SearchLoopInterface::MODE_ANY_WORD,
|
||||||
|
SearchLoopInterface::MODE_SENTENCE,
|
||||||
|
SearchLoopInterface::MODE_STRICT_SENTENCE,
|
||||||
|
])
|
||||||
|
),
|
||||||
|
SearchLoopInterface::MODE_STRICT_SENTENCE
|
||||||
|
)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $defaultArgs;
|
return $defaultArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a getter to loop parameters
|
* Provides a getter to loop parameter values
|
||||||
*
|
*
|
||||||
* @param string $name the methode name (only getArgname is supported)
|
* @param string $name the method name (only getArgname is supported)
|
||||||
* @param $arguments this parameter is ignored
|
* @param mixed $arguments this parameter is ignored
|
||||||
*
|
*
|
||||||
* @return null
|
* @return mixed the argument value
|
||||||
* @throws \InvalidArgumentException if the parameter is unknown or the method name is not supported.
|
* @throws \InvalidArgumentException if the parameter is unknown or the method name is not supported.
|
||||||
*/
|
*/
|
||||||
public function __call($name, $arguments)
|
public function __call($name, $arguments)
|
||||||
@@ -137,10 +145,12 @@ abstract class BaseLoop
|
|||||||
// camelCase to underscore: getNotEmpty -> not_empty
|
// camelCase to underscore: getNotEmpty -> not_empty
|
||||||
$argName = strtolower(preg_replace('/([^A-Z])([A-Z])/', "$1_$2", substr($name, 3)));
|
$argName = strtolower(preg_replace('/([^A-Z])([A-Z])/', "$1_$2", substr($name, 3)));
|
||||||
|
|
||||||
return $this->getArg($argName)->getValue();
|
return $this->getArgValue($argName);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \InvalidArgumentException(sprintf("Unsupported magic method %s. only getArgname() is supported.", $name));
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans("Unsupported magic method %name. only getArgname() is supported.", ['%name' => $name])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,12 +158,12 @@ abstract class BaseLoop
|
|||||||
*
|
*
|
||||||
* @param array $nameValuePairs a array of name => value pairs. The name is the name of the argument.
|
* @param array $nameValuePairs a array of name => value pairs. The name is the name of the argument.
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException if somùe argument values are missing, or invalid
|
* @throws \InvalidArgumentException if some argument values are missing, or invalid
|
||||||
*/
|
*/
|
||||||
public function initializeArgs(array $nameValuePairs)
|
public function initializeArgs(array $nameValuePairs)
|
||||||
{
|
{
|
||||||
$faultActor = array();
|
$faultActor = [];
|
||||||
$faultDetails = array();
|
$faultDetails = [];
|
||||||
|
|
||||||
$loopType = isset($nameValuePairs['type']) ? $nameValuePairs['type'] : "undefined";
|
$loopType = isset($nameValuePairs['type']) ? $nameValuePairs['type'] : "undefined";
|
||||||
$loopName = isset($nameValuePairs['name']) ? $nameValuePairs['name'] : "undefined";
|
$loopName = isset($nameValuePairs['name']) ? $nameValuePairs['name'] : "undefined";
|
||||||
@@ -167,19 +177,38 @@ abstract class BaseLoop
|
|||||||
/* check if mandatory */
|
/* check if mandatory */
|
||||||
if ($value === null && $argument->mandatory) {
|
if ($value === null && $argument->mandatory) {
|
||||||
$faultActor[] = $argument->name;
|
$faultActor[] = $argument->name;
|
||||||
$faultDetails[] = sprintf('"%s" parameter is missing in loop type: %s, name: %s', $argument->name, $loopType, $loopName);
|
$faultDetails[] = $this->translator->trans(
|
||||||
|
'"%param" parameter is missing in loop type: %type, name: %name', [
|
||||||
|
'%param' => $argument->name,
|
||||||
|
'%type' => $loopType,
|
||||||
|
'%name' => $loopName
|
||||||
|
]
|
||||||
|
);
|
||||||
} else if ($value === '') {
|
} else if ($value === '') {
|
||||||
if (!$argument->empty) {
|
if (!$argument->empty) {
|
||||||
/* check if empty */
|
/* check if empty */
|
||||||
$faultActor[] = $argument->name;
|
$faultActor[] = $argument->name;
|
||||||
$faultDetails[] = sprintf('"%s" parameter cannot be empty in loop type: %s, name: %s', $argument->name, $loopType, $loopName);
|
$faultDetails[] = $this->translator->trans(
|
||||||
|
'"%param" parameter cannot be empty in loop type: %type, name: %name', [
|
||||||
|
'%param' => $argument->name,
|
||||||
|
'%type' => $loopType,
|
||||||
|
'%name' => $loopName
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} elseif ($value !== null && !$argument->type->isValid($value)) {
|
} elseif ($value !== null && !$argument->type->isValid($value)) {
|
||||||
/* check type */
|
/* check type */
|
||||||
$faultActor[] = $argument->name;
|
$faultActor[] = $argument->name;
|
||||||
$faultDetails[] = sprintf('Invalid value "%s" for "%s" argument in loop type: %s, name: %s', $value, $argument->name, $loopType, $loopName);
|
$faultDetails[] = $this->translator->trans(
|
||||||
|
'Invalid value "%value" for "%param" parameter in loop type: %type, name: %name', [
|
||||||
|
'%value' => $value,
|
||||||
|
'%param' => $argument->name,
|
||||||
|
'%type' => $loopType,
|
||||||
|
'%name' => $loopName
|
||||||
|
]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
/* set default */
|
/* set default value */
|
||||||
/* did it as last checking for we consider default value is acceptable no matter type or empty restriction */
|
/* did it as last checking for we consider default value is acceptable no matter type or empty restriction */
|
||||||
if ($value === null) {
|
if ($value === null) {
|
||||||
$value = $argument->default;
|
$value = $argument->default;
|
||||||
@@ -189,9 +218,9 @@ abstract class BaseLoop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($faultActor)) {
|
if (! empty($faultActor)) {
|
||||||
|
|
||||||
$complement = sprintf('[%s]', implode(', ', $faultDetails));
|
$complement = sprintf('[%s]', implode(', ', $faultDetails));
|
||||||
|
|
||||||
throw new \InvalidArgumentException($complement);
|
throw new \InvalidArgumentException($complement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,15 +230,17 @@ abstract class BaseLoop
|
|||||||
*
|
*
|
||||||
* @param string $argumentName the argument name
|
* @param string $argumentName the argument name
|
||||||
*
|
*
|
||||||
|
* @return Argument the loop argument.
|
||||||
* @throws \InvalidArgumentException if argument is not found in loop argument list
|
* @throws \InvalidArgumentException if argument is not found in loop argument list
|
||||||
* @return Argument the loop argument.
|
|
||||||
*/
|
*/
|
||||||
protected function getArg($argumentName)
|
protected function getArg($argumentName)
|
||||||
{
|
{
|
||||||
$arg = $this->args->get($argumentName);
|
$arg = $this->args->get($argumentName);
|
||||||
|
|
||||||
if ($arg === null)
|
if ($arg === null)
|
||||||
throw new \InvalidArgumentException("Undefined loop argument '$argumentName'");
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans('Undefined loop argument "%name"', ['%name' => $argumentName])
|
||||||
|
);
|
||||||
|
|
||||||
return $arg;
|
return $arg;
|
||||||
}
|
}
|
||||||
@@ -220,7 +251,7 @@ abstract class BaseLoop
|
|||||||
* @param string $argumentName the argument name
|
* @param string $argumentName the argument name
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException if argument is not found in loop argument list
|
* @throws \InvalidArgumentException if argument is not found in loop argument list
|
||||||
* @return Argument the loop argument.
|
* @return mixed the loop argument value
|
||||||
*/
|
*/
|
||||||
protected function getArgValue($argumentName)
|
protected function getArgValue($argumentName)
|
||||||
{
|
{
|
||||||
@@ -228,20 +259,24 @@ abstract class BaseLoop
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ModelCriteria $search
|
* @param ModelCriteria $search the search request
|
||||||
* @param null $pagination
|
* @param PropelModelPager $pagination the pagination part
|
||||||
*
|
*
|
||||||
* @return array|mixed|\PropelModelPager|\PropelObjectCollection
|
* @return array|PropelModelPager|ObjectCollection
|
||||||
|
* @throws \InvalidArgumentException if the search mode is undefined.
|
||||||
*/
|
*/
|
||||||
protected function search(ModelCriteria $search, &$pagination = null)
|
protected function search(ModelCriteria $search, &$pagination = null)
|
||||||
{
|
{
|
||||||
if (false === $this->countable) {
|
if (false === $this->countable) {
|
||||||
return $search->find();
|
return $search->find();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this instanceof SearchLoopInterface) {
|
if ($this instanceof SearchLoopInterface) {
|
||||||
$searchTerm = $this->getSearch_term();
|
|
||||||
$searchIn = $this->getSearch_in();
|
$searchTerm = $this->getArgValue('search_term');
|
||||||
$searchMode = $this->getSearch_mode();
|
$searchIn = $this->getArgValue('search_in');
|
||||||
|
$searchMode = $this->getArgValue('search_mode');
|
||||||
|
|
||||||
if (null !== $searchTerm && null !== $searchIn) {
|
if (null !== $searchTerm && null !== $searchIn) {
|
||||||
|
|
||||||
switch ($searchMode) {
|
switch ($searchMode) {
|
||||||
@@ -256,6 +291,10 @@ abstract class BaseLoop
|
|||||||
case SearchLoopInterface::MODE_STRICT_SENTENCE:
|
case SearchLoopInterface::MODE_STRICT_SENTENCE:
|
||||||
$searchCriteria = Criteria::EQUAL;
|
$searchCriteria = Criteria::EQUAL;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans("Undefined search mode '%mode'", ['%mode' => $searchMode])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->doSearch($search, $searchTerm, $searchIn, $searchCriteria);
|
$this->doSearch($search, $searchTerm, $searchIn, $searchCriteria);
|
||||||
@@ -269,24 +308,31 @@ abstract class BaseLoop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function searchArray(array $search, &$pagination = null)
|
protected function searchArray(array $search)
|
||||||
{
|
{
|
||||||
if (false === $this->countable) {
|
if (false === $this->countable) {
|
||||||
return $search;
|
return $search;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$limit = intval($this->getArgValue('limit'));
|
||||||
|
$offset = intval($this->getArgValue('offset'));
|
||||||
|
|
||||||
if ($this->getArgValue('page') !== null) {
|
if ($this->getArgValue('page') !== null) {
|
||||||
|
|
||||||
$nbPage = ceil(count($search)/$this->getArgValue('limit'));
|
$pageNum = intval($this->getArgValue('page'));
|
||||||
if ($this->getArgValue('page') > $nbPage || $this->getArgValue('page') <= 0) {
|
|
||||||
return array();
|
$totalPageCount = ceil(count($search) / $limit);
|
||||||
|
|
||||||
|
if ($pageNum > $totalPageCount || $pageNum <= 0) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$firstItem = ($this->getArgValue('page')-1) * $this->getArgValue('limit') + 1;
|
$firstItem = ($pageNum - 1) * $limit + 1;
|
||||||
|
|
||||||
return array_slice($search, $firstItem, $firstItem + $this->getArgValue('limit'), false);
|
return array_slice($search, $firstItem, $firstItem + $limit, false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return array_slice($search, $this->getArgValue('offset'), $this->getArgValue('limit'), false);
|
return array_slice($search, $offset, $limit, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,30 +340,36 @@ abstract class BaseLoop
|
|||||||
/**
|
/**
|
||||||
* @param ModelCriteria $search
|
* @param ModelCriteria $search
|
||||||
*
|
*
|
||||||
* @return array|mixed|\PropelObjectCollection
|
* @return ObjectCollection
|
||||||
*/
|
*/
|
||||||
protected function searchWithOffset(ModelCriteria $search)
|
protected function searchWithOffset(ModelCriteria $search)
|
||||||
{
|
{
|
||||||
if ($this->getArgValue('limit') >= 0) {
|
$limit = intval($this->getArgValue('limit'));
|
||||||
$search->limit($this->getArgValue('limit'));
|
|
||||||
|
if ($limit >= 0) {
|
||||||
|
$search->limit($limit);
|
||||||
}
|
}
|
||||||
$search->offset($this->getArgValue('offset'));
|
|
||||||
|
$search->offset(intval($this->getArgValue('offset')));
|
||||||
|
|
||||||
return $search->find();
|
return $search->find();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ModelCriteria $search
|
* @param ModelCriteria $search
|
||||||
* @param $pagination
|
* @param PropelModelPager $pagination
|
||||||
*
|
*
|
||||||
* @return array|\Propel\Runtime\Util\PropelModelPager
|
* @return array|PropelModelPager
|
||||||
*/
|
*/
|
||||||
protected function searchWithPagination(ModelCriteria $search, &$pagination)
|
protected function searchWithPagination(ModelCriteria $search, &$pagination)
|
||||||
{
|
{
|
||||||
$pagination = $search->paginate($this->getArgValue('page'), $this->getArgValue('limit'));
|
$page = intval($this->getArgValue('page'));
|
||||||
|
$limit = intval($this->getArgValue('limit'));
|
||||||
|
|
||||||
if ($this->getArgValue('page') > $pagination->getLastPage()) {
|
$pagination = $search->paginate($page, $limit);
|
||||||
return array();
|
|
||||||
|
if ($page > $pagination->getLastPage()) {
|
||||||
|
return [];
|
||||||
} else {
|
} else {
|
||||||
return $pagination;
|
return $pagination;
|
||||||
}
|
}
|
||||||
@@ -350,18 +402,21 @@ abstract class BaseLoop
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $pagination
|
* @param PropelModelPager $pagination
|
||||||
|
*
|
||||||
* @return LoopResult
|
* @return LoopResult
|
||||||
*/
|
*/
|
||||||
public function exec(&$pagination)
|
public function exec(&$pagination)
|
||||||
{
|
{
|
||||||
$hash = $this->args->getHash();
|
$hash = $this->args->getHash();
|
||||||
if (false === isset(self::$cacheLoopResult[$hash])) {
|
if (false === isset(self::$cacheLoopResult[$hash])) {
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
|
||||||
if ($this instanceof PropelSearchLoopInterface) {
|
if ($this instanceof PropelSearchLoopInterface) {
|
||||||
$searchModelCriteria = $this->buildModelCriteria();
|
$searchModelCriteria = $this->buildModelCriteria();
|
||||||
if (null === $searchModelCriteria) {
|
|
||||||
$results = array();
|
if (null !== $searchModelCriteria) {
|
||||||
} else {
|
|
||||||
$results = $this->search(
|
$results = $this->search(
|
||||||
$searchModelCriteria,
|
$searchModelCriteria,
|
||||||
$pagination
|
$pagination
|
||||||
@@ -369,13 +424,9 @@ abstract class BaseLoop
|
|||||||
}
|
}
|
||||||
} elseif ($this instanceof ArraySearchLoopInterface) {
|
} elseif ($this instanceof ArraySearchLoopInterface) {
|
||||||
$searchArray = $this->buildArray();
|
$searchArray = $this->buildArray();
|
||||||
if (null === $searchArray) {
|
|
||||||
$results = array();
|
if (null !== $searchArray) {
|
||||||
} else {
|
$results = $this->searchArray($searchArray);
|
||||||
$results = $this->searchArray(
|
|
||||||
$searchArray,
|
|
||||||
$pagination
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,30 +456,49 @@ abstract class BaseLoop
|
|||||||
* - ArraySearchLoopInterface
|
* - ArraySearchLoopInterface
|
||||||
*/
|
*/
|
||||||
$searchInterface = false;
|
$searchInterface = false;
|
||||||
|
|
||||||
if ($this instanceof PropelSearchLoopInterface) {
|
if ($this instanceof PropelSearchLoopInterface) {
|
||||||
if (true === $searchInterface) {
|
if (true === $searchInterface) {
|
||||||
throw new LoopException('Loop cannot implements multiple Search Interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`', LoopException::MULTIPLE_SEARCH_INTERFACE);
|
throw new LoopException(
|
||||||
|
$this->translator->trans(
|
||||||
|
'Loop cannot implements multiple Search Interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`'
|
||||||
|
),
|
||||||
|
LoopException::MULTIPLE_SEARCH_INTERFACE);
|
||||||
}
|
}
|
||||||
$searchInterface = true;
|
$searchInterface = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this instanceof ArraySearchLoopInterface) {
|
if ($this instanceof ArraySearchLoopInterface) {
|
||||||
if (true === $searchInterface) {
|
if (true === $searchInterface) {
|
||||||
throw new LoopException('Loop cannot implements multiple Search Interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`', LoopException::MULTIPLE_SEARCH_INTERFACE);
|
throw new LoopException(
|
||||||
|
$this->translator->trans(
|
||||||
|
'Loop cannot implements multiple Search Interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`'
|
||||||
|
),
|
||||||
|
LoopException::MULTIPLE_SEARCH_INTERFACE);
|
||||||
}
|
}
|
||||||
$searchInterface = true;
|
$searchInterface = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false === $searchInterface) {
|
if (false === $searchInterface) {
|
||||||
throw new LoopException('Loop must implements one of the following interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`', LoopException::SEARCH_INTERFACE_NOT_FOUND);
|
throw new LoopException(
|
||||||
|
$this->translator->trans(
|
||||||
|
'Loop must implements one of the following interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`'
|
||||||
|
),
|
||||||
|
LoopException::SEARCH_INTERFACE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only PropelSearch allows timestamp and version */
|
/* Only PropelSearch allows timestamp and version */
|
||||||
if (!$this instanceof PropelSearchLoopInterface) {
|
if (!$this instanceof PropelSearchLoopInterface) {
|
||||||
if (true === $this->timestampable) {
|
if (true === $this->timestampable) {
|
||||||
throw new LoopException("Loop must implements 'PropelSearchLoopInterface' to be timestampable", LoopException::NOT_TIMESTAMPED);
|
throw new LoopException(
|
||||||
|
$this->translator->trans("Loop must implements 'PropelSearchLoopInterface' to be timestampable"),
|
||||||
|
LoopException::NOT_TIMESTAMPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true === $this->versionable) {
|
if (true === $this->versionable) {
|
||||||
throw new LoopException("Loop must implements 'PropelSearchLoopInterface' to be versionable", LoopException::NOT_VERSIONED);
|
throw new LoopException(
|
||||||
|
$this->translator->trans("Loop must implements 'PropelSearchLoopInterface' to be versionable"),
|
||||||
|
LoopException::NOT_VERSIONED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -441,15 +511,14 @@ abstract class BaseLoop
|
|||||||
abstract public function parseResults(LoopResult $loopResult);
|
abstract public function parseResults(LoopResult $loopResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Definition of loop arguments
|
||||||
* define all args used in your loop
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* example :
|
* example :
|
||||||
*
|
*
|
||||||
* public function getArgDefinitions()
|
* public function getArgDefinitions()
|
||||||
* {
|
* {
|
||||||
* return new ArgumentCollection(
|
* return new ArgumentCollection(
|
||||||
|
*
|
||||||
* Argument::createIntListTypeArgument('id'),
|
* Argument::createIntListTypeArgument('id'),
|
||||||
* new Argument(
|
* new Argument(
|
||||||
* 'ref',
|
* 'ref',
|
||||||
@@ -459,14 +528,7 @@ abstract class BaseLoop
|
|||||||
* ),
|
* ),
|
||||||
* Argument::createIntListTypeArgument('category'),
|
* Argument::createIntListTypeArgument('category'),
|
||||||
* Argument::createBooleanTypeArgument('new'),
|
* 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'),
|
|
||||||
*
|
|
||||||
* );
|
* );
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
@@ -474,4 +536,4 @@ abstract class BaseLoop
|
|||||||
*/
|
*/
|
||||||
abstract protected function getArgDefinitions();
|
abstract protected function getArgDefinitions();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -12,16 +12,20 @@
|
|||||||
|
|
||||||
namespace Thelia\Core\Template\Smarty\Plugins;
|
namespace Thelia\Core\Template\Smarty\Plugins;
|
||||||
|
|
||||||
|
use Propel\Runtime\Util\PropelModelPager;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Thelia\Core\Template\Element\BaseLoop;
|
use Thelia\Core\Template\Element\BaseLoop;
|
||||||
|
use Thelia\Core\Template\Element\LoopResult;
|
||||||
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
|
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
|
||||||
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
|
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
|
||||||
|
|
||||||
use Thelia\Core\Template\Element\Exception\ElementNotFoundException;
|
use Thelia\Core\Template\Element\Exception\ElementNotFoundException;
|
||||||
use Thelia\Core\Template\Element\Exception\InvalidElementException;
|
use Thelia\Core\Template\Element\Exception\InvalidElementException;
|
||||||
|
use Thelia\Core\Translation\Translator;
|
||||||
|
|
||||||
class TheliaLoop extends AbstractSmartyPlugin
|
class TheliaLoop extends AbstractSmartyPlugin
|
||||||
{
|
{
|
||||||
|
/** @var PropelModelPager[] */
|
||||||
protected static $pagination = null;
|
protected static $pagination = null;
|
||||||
|
|
||||||
protected $loopDefinition = array();
|
protected $loopDefinition = array();
|
||||||
@@ -30,10 +34,15 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
protected $dispatcher;
|
protected $dispatcher;
|
||||||
protected $securityContext;
|
protected $securityContext;
|
||||||
|
|
||||||
|
/** @var Translator */
|
||||||
|
protected $translator;
|
||||||
|
|
||||||
/** @var ContainerInterface Service Container */
|
/** @var ContainerInterface Service Container */
|
||||||
protected $container = null;
|
protected $container = null;
|
||||||
|
|
||||||
|
/** @var LoopResult[] */
|
||||||
protected $loopstack = array();
|
protected $loopstack = array();
|
||||||
|
|
||||||
protected $varstack = array();
|
protected $varstack = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,31 +55,43 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
$this->request = $container->get('request');
|
$this->request = $container->get('request');
|
||||||
$this->dispatcher = $container->get('event_dispatcher');
|
$this->dispatcher = $container->get('event_dispatcher');
|
||||||
$this->securityContext = $container->get('thelia.securityContext');
|
$this->securityContext = $container->get('thelia.securityContext');
|
||||||
|
$this->translator = $container->get("thelia.translator");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $loopId
|
* @param string $loopName
|
||||||
*
|
* @return PropelModelPager
|
||||||
* @return \PropelModelPager
|
* @throws \InvalidArgumentException if no pagination was found for loop
|
||||||
*/
|
*/
|
||||||
public static function getPagination($loopName)
|
public static function getPagination($loopName)
|
||||||
{
|
{
|
||||||
if (array_key_exists($loopName, self::$pagination)) {
|
if (array_key_exists($loopName, self::$pagination)) {
|
||||||
return self::$pagination[$loopName];
|
return self::$pagination[$loopName];
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException("Loop $loopName is not defined");
|
throw new \InvalidArgumentException(
|
||||||
|
Translator::getInstance()->trans("No pagination currently defined for loop name '%name'", ['%name' => $loopName ])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the count function: executes a loop and return the number of items found
|
* Process the count function: executes a loop and return the number of items found
|
||||||
|
*
|
||||||
|
* @param array $params parameters array
|
||||||
|
* @param \Smarty_Internal_Template $template
|
||||||
|
*
|
||||||
|
* @return int the item count
|
||||||
|
* @throws \InvalidArgumentException if a parameter is missing
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public function theliaCount($params, $template)
|
public function theliaCount($params, /** @noinspection PhpUnusedParameterInspection */ $template)
|
||||||
{
|
{
|
||||||
$type = $this->getParam($params, 'type');
|
$type = $this->getParam($params, 'type');
|
||||||
|
|
||||||
if (null == $type) {
|
if (null == $type) {
|
||||||
throw new \InvalidArgumentException("Missing 'type' parameter in count arguments");
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans("Missing 'type' parameter in {count} loop arguments")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$loop = $this->createLoopInstance($params);
|
$loop = $this->createLoopInstance($params);
|
||||||
@@ -83,31 +104,39 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
/**
|
/**
|
||||||
* Process {loop name="loop name" type="loop type" ... } ... {/loop} block
|
* Process {loop name="loop name" type="loop type" ... } ... {/loop} block
|
||||||
*
|
*
|
||||||
* @param unknown $params
|
* @param array $params
|
||||||
* @param unknown $content
|
* @param string $content
|
||||||
* @param unknown $template
|
* @param \Smarty_Internal_Template $template
|
||||||
* @param unknown $repeat
|
* @param boolean $repeat
|
||||||
|
*
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
* @return string
|
*
|
||||||
|
* @return void|string
|
||||||
*/
|
*/
|
||||||
public function theliaLoop($params, $content, $template, &$repeat)
|
public function theliaLoop($params, $content, $template, &$repeat)
|
||||||
{
|
{
|
||||||
$name = $this->getParam($params, 'name');
|
$name = $this->getParam($params, 'name');
|
||||||
|
|
||||||
if (null == $name) {
|
if (null == $name) {
|
||||||
throw new \InvalidArgumentException("Missing 'name' parameter in loop arguments");
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans("Missing 'name' parameter in loop arguments")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$type = $this->getParam($params, 'type');
|
$type = $this->getParam($params, 'type');
|
||||||
|
|
||||||
if (null == $type) {
|
if (null == $type) {
|
||||||
throw new \InvalidArgumentException("Missing 'type' parameter in loop arguments");
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans("Missing 'type' parameter in loop arguments")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($content === null) {
|
if ($content === null) {
|
||||||
// Check if a loop with the same name exists in the current scope, and abort if it's the case.
|
// Check if a loop with the same name exists in the current scope, and abort if it's the case.
|
||||||
if (array_key_exists($name, $this->varstack)) {
|
if (array_key_exists($name, $this->varstack)) {
|
||||||
throw new \InvalidArgumentException("A loop named '$name' already exists in the current scope.");
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans("A loop named '%name' already exists in the current scope.", ['%name' => $name])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$loop = $this->createLoopInstance($params);
|
$loop = $this->createLoopInstance($params);
|
||||||
@@ -120,7 +149,7 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
|
|
||||||
$this->loopstack[$name] = $loopResults;
|
$this->loopstack[$name] = $loopResults;
|
||||||
|
|
||||||
// Pas de résultat ? la boucle est terminée, ne pas évaluer le contenu.
|
// No results ? The loop is terminated, do not evaluate loop text.
|
||||||
if ($loopResults->isEmpty()) $repeat = false;
|
if ($loopResults->isEmpty()) $repeat = false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -173,52 +202,56 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process {elseloop rel="loopname"} ... {/elseloop} block
|
* Process {elseloop rel="loopname"} ... {/elseloop} block
|
||||||
*
|
*
|
||||||
* @param unknown $params
|
* @param array $params loop parameters
|
||||||
* @param unknown $content
|
* @param string $content loop text content
|
||||||
* @param unknown $template
|
* @param \Smarty_Internal_Template $template the Smarty object
|
||||||
* @param unknown $repeat
|
* @param boolean $repeat repeat indicator (see Smarty doc.)
|
||||||
* @return Ambigous <string, unknown>
|
* @return string the loop output
|
||||||
*/
|
*/
|
||||||
public function theliaElseloop($params, $content, $template, &$repeat)
|
public function theliaElseloop($params, $content, /** @noinspection PhpUnusedParameterInspection */ $template, &$repeat)
|
||||||
{
|
{
|
||||||
|
// When encountering close tag, check if loop has results.
|
||||||
// When encoutering close tag, check if loop has results.
|
|
||||||
if ($repeat === false) {
|
if ($repeat === false) {
|
||||||
return $this->checkEmptyLoop($params, $template) ? $content : '';
|
return $this->checkEmptyLoop($params) ? $content : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process {ifloop rel="loopname"} ... {/ifloop} block
|
* Process {ifloop rel="loopname"} ... {/ifloop} block
|
||||||
*
|
*
|
||||||
* @param unknown $params
|
* @param array $params loop parameters
|
||||||
* @param unknown $content
|
* @param string $content loop text content
|
||||||
* @param unknown $template
|
* @param \Smarty_Internal_Template $template the Smarty object
|
||||||
* @param unknown $repeat
|
* @param boolean $repeat repeat indicator (see Smarty doc.)
|
||||||
* @return Ambigous <string, unknown>
|
* @return string the loop output
|
||||||
*/
|
*/
|
||||||
public function theliaIfLoop($params, $content, $template, &$repeat)
|
public function theliaIfLoop($params, $content, /** @noinspection PhpUnusedParameterInspection */ $template, &$repeat)
|
||||||
{
|
{
|
||||||
// When encountering close tag, check if loop has results.
|
// When encountering close tag, check if loop has results.
|
||||||
if ($repeat === false) {
|
if ($repeat === false) {
|
||||||
return $this->checkEmptyLoop($params, $template) ? '' : $content;
|
return $this->checkEmptyLoop($params) ? '' : $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process {pageloop rel="loopname"} ... {/pageloop} block
|
* Process {pageloop rel="loopname"} ... {/pageloop} block
|
||||||
*
|
*
|
||||||
* @param $params
|
* @param array $params loop parameters
|
||||||
* @param $content
|
* @param string $content loop text content
|
||||||
* @param $template
|
* @param \Smarty_Internal_Template $template the Smarty object
|
||||||
* @param $repeat
|
* @param boolean $repeat repeat indicator (see Smarty doc.)
|
||||||
*
|
* @return string the loop output
|
||||||
* @return string
|
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function theliaPageLoop($params, $content, $template, &$repeat)
|
public function theliaPageLoop($params, $content, $template, &$repeat)
|
||||||
@@ -226,73 +259,102 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
$loopName = $this->getParam($params, 'rel');
|
$loopName = $this->getParam($params, 'rel');
|
||||||
|
|
||||||
if (null == $loopName)
|
if (null == $loopName)
|
||||||
throw new \InvalidArgumentException("Missing 'rel' parameter in page loop");
|
throw new \InvalidArgumentException($this->translator->trans("Missing 'rel' parameter in page loop"));
|
||||||
|
|
||||||
// Find pagination
|
// Find pagination
|
||||||
$pagination = self::getPagination($loopName);
|
$pagination = self::getPagination($loopName);
|
||||||
if ($pagination === null) { // loop has no result
|
|
||||||
|
|
||||||
|
if ($pagination === null || $pagination->getNbResults() == 0) {
|
||||||
|
// No need to paginate
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($pagination->getNbResults() == 0) {
|
$startPage = intval($this->getParam($params, 'start-page', 1));
|
||||||
return '';
|
$displayedPageCount = intval($this->getParam($params, 'limit', 10));
|
||||||
}
|
|
||||||
|
|
||||||
$nbPage = $this->getParam($params, 'numPage', 10);
|
if (intval($displayedPageCount) == 0) $displayedPageCount = PHP_INT_MAX;
|
||||||
$maxPage = $pagination->getLastPage();
|
|
||||||
|
|
||||||
|
$totalPageCount = $pagination->getLastPage();
|
||||||
|
|
||||||
if ($content === null) {
|
if ($content === null) {
|
||||||
$page = $pagination->getPage();
|
|
||||||
if ($maxPage > ($page + $nbPage)) {
|
// The current page
|
||||||
$end = $page + $nbPage;
|
$currentPage = $pagination->getPage();
|
||||||
} else {
|
|
||||||
$end = $maxPage;
|
// Get the start page.
|
||||||
|
if ($totalPageCount > $displayedPageCount) {
|
||||||
|
$startPage = $currentPage - round($displayedPageCount / 2);
|
||||||
|
|
||||||
|
if ($startPage < 0) $startPage = 1;
|
||||||
}
|
}
|
||||||
$template->assign('PREV', $page > 1 ? $page-1: $page);
|
|
||||||
$template->assign('NEXT', $page < $maxPage ? $page+1 : $maxPage);
|
// This is the iterative page number, the one we're going to increment in this loop
|
||||||
$template->assign('END', $end);
|
$iterationPage = $startPage;
|
||||||
$template->assign('LAST', $pagination->getLastPage());
|
|
||||||
|
// The last displayed page number
|
||||||
|
$endPage = $startPage + $displayedPageCount - 1;
|
||||||
|
|
||||||
|
if ($endPage > $totalPageCount) {
|
||||||
|
$endPage = $totalPageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first displayed page number
|
||||||
|
$template->assign('START' , $startPage);
|
||||||
|
// The previous page number
|
||||||
|
$template->assign('PREV' , $currentPage > 1 ? $currentPage-1 : $currentPage);
|
||||||
|
// The next page number
|
||||||
|
$template->assign('NEXT' , $currentPage < $totalPageCount ? $currentPage+1 : $totalPageCount);
|
||||||
|
// The last displayed page number
|
||||||
|
$template->assign('END' , $endPage);
|
||||||
|
// The overall last page
|
||||||
|
$template->assign('LAST' , $totalPageCount);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$page = $template->getTemplateVars('PAGE');
|
$iterationPage = $template->getTemplateVars('PAGE');
|
||||||
$page++;
|
|
||||||
|
$iterationPage++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($iterationPage <= $template->getTemplateVars('END')) {
|
||||||
|
|
||||||
|
// The iterative page number
|
||||||
|
$template->assign('PAGE', $iterationPage);
|
||||||
|
|
||||||
if ($page <= $template->getTemplateVars('END')) {
|
// The overall current page number
|
||||||
$template->assign('PAGE', $page);
|
|
||||||
$template->assign('CURRENT', $pagination->getPage());
|
$template->assign('CURRENT', $pagination->getPage());
|
||||||
|
|
||||||
|
|
||||||
$repeat = true;
|
$repeat = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($content !== null) {
|
if ($content !== null) {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a loop has returned results. The loop shoud have been executed before, or an
|
* Check if a loop has returned results. The loop shoud have been executed before, or an
|
||||||
* InvalidArgumentException is thrown
|
* InvalidArgumentException is thrown
|
||||||
*
|
*
|
||||||
* @param unknown $params
|
* @param array $params
|
||||||
* @param unknown $template
|
*
|
||||||
|
* @return boolean true if the loop is empty
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
protected function checkEmptyLoop($params, $template)
|
protected function checkEmptyLoop($params)
|
||||||
{
|
{
|
||||||
$loopName = $this->getParam($params, 'rel');
|
$loopName = $this->getParam($params, 'rel');
|
||||||
|
|
||||||
if (null == $loopName)
|
if (null == $loopName)
|
||||||
throw new \InvalidArgumentException("Missing 'rel' parameter in ifloop/elseloop arguments");
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans("Missing 'rel' parameter in ifloop/elseloop arguments")
|
||||||
|
);
|
||||||
|
|
||||||
if (! isset($this->loopstack[$loopName])) {
|
if (! isset($this->loopstack[$loopName]))
|
||||||
throw new \InvalidArgumentException("Loop $loopName is not defined.");
|
throw new \InvalidArgumentException(
|
||||||
}
|
$this->translator->trans("Related loop name '%name'' is not defined.", ['%name' => $loopName])
|
||||||
|
);
|
||||||
|
|
||||||
return $this->loopstack[$loopName]->isEmpty();
|
return $this->loopstack[$loopName]->isEmpty();
|
||||||
}
|
}
|
||||||
@@ -309,14 +371,16 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
$type = strtolower($smartyParams['type']);
|
$type = strtolower($smartyParams['type']);
|
||||||
|
|
||||||
if (! isset($this->loopDefinition[$type])) {
|
if (! isset($this->loopDefinition[$type])) {
|
||||||
throw new ElementNotFoundException(sprintf("'%s' loop type does not exists", $type));
|
throw new ElementNotFoundException(
|
||||||
|
$this->translator->trans("Loop type '%type' is not defined.", ['%type' => $type]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$class = new \ReflectionClass($this->loopDefinition[$type]);
|
$class = new \ReflectionClass($this->loopDefinition[$type]);
|
||||||
|
|
||||||
if ($class->isSubclassOf("Thelia\Core\Template\Element\BaseLoop") === false) {
|
if ($class->isSubclassOf("Thelia\Core\Template\Element\BaseLoop") === false) {
|
||||||
throw new InvalidElementException(sprintf("'%s' Loop class should extends Thelia\Core\Template\Element\BaseLoop",
|
throw new InvalidElementException(
|
||||||
$type));
|
$this->translator->trans("'%type' loop class should extends Thelia\Core\Template\Element\BaseLoop", ['%type' => $type])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$loop = $class->newInstance(
|
$loop = $class->newInstance(
|
||||||
@@ -350,7 +414,12 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
{
|
{
|
||||||
foreach ($loopDefinition as $name => $className) {
|
foreach ($loopDefinition as $name => $className) {
|
||||||
if (array_key_exists($name, $this->loopDefinition)) {
|
if (array_key_exists($name, $this->loopDefinition)) {
|
||||||
throw new \InvalidArgumentException(sprintf("%s loop name already exists for %s class name", $name, $className));
|
throw new \InvalidArgumentException(
|
||||||
|
$this->translator->trans("The loop name '%name' is already defined in %className class", [
|
||||||
|
'%name' => $name,
|
||||||
|
'%className' => $className
|
||||||
|
])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->loopDefinition[$name] = $className;
|
$this->loopDefinition[$name] = $className;
|
||||||
@@ -360,7 +429,7 @@ class TheliaLoop extends AbstractSmartyPlugin
|
|||||||
/**
|
/**
|
||||||
* Defines the various smarty plugins hendled by this class
|
* Defines the various smarty plugins hendled by this class
|
||||||
*
|
*
|
||||||
* @return an array of smarty plugin descriptors
|
* @return SmartyPluginDescriptor[] smarty plugin descriptors
|
||||||
*/
|
*/
|
||||||
public function getPluginDescriptors()
|
public function getPluginDescriptors()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,10 +12,8 @@
|
|||||||
|
|
||||||
namespace Thelia\Module;
|
namespace Thelia\Module;
|
||||||
|
|
||||||
use Thelia\Model\Country;
|
|
||||||
use Thelia\Module\Exception\DeliveryException;
|
|
||||||
|
|
||||||
abstract class AbstractDeliveryModule extends BaseModule implements DeliveryModuleInterface
|
abstract class AbstractDeliveryModule extends BaseModule implements DeliveryModuleInterface
|
||||||
{
|
{
|
||||||
|
// This class is the base class for delivery modules
|
||||||
|
// It may contains common methods in the future.
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,7 @@ use Thelia\Core\HttpFoundation\Request;
|
|||||||
use Thelia\Core\Security\SecurityContext;
|
use Thelia\Core\Security\SecurityContext;
|
||||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||||
use Thelia\Core\HttpFoundation\Session\Session;
|
use Thelia\Core\HttpFoundation\Session\Session;
|
||||||
|
use Thelia\Core\Translation\Translator;
|
||||||
use Thelia\Tools\URL;
|
use Thelia\Tools\URL;
|
||||||
use Thelia\TaxEngine\TaxEngine;
|
use Thelia\TaxEngine\TaxEngine;
|
||||||
|
|
||||||
@@ -95,6 +96,7 @@ abstract class BaseLoopTestor extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->container->set('request', $request);
|
$this->container->set('request', $request);
|
||||||
$this->container->set('event_dispatcher', new EventDispatcher());
|
$this->container->set('event_dispatcher', new EventDispatcher());
|
||||||
|
$this->container->set('thelia.translator',new Translator($this->container));
|
||||||
$this->container->set('thelia.securityContext', new SecurityContext($request));
|
$this->container->set('thelia.securityContext', new SecurityContext($request));
|
||||||
$this->container->set('router.admin', $stubRouterAdmin);
|
$this->container->set('router.admin', $stubRouterAdmin);
|
||||||
$this->container->set('thelia.url.manager', new URL($this->container));
|
$this->container->set('thelia.url.manager', new URL($this->container));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#order
|
#order
|
||||||
max_displayed_orders = 20
|
max_displayed_orders = 20
|
||||||
|
max_displayed_customers = 20
|
||||||
|
|
||||||
#order status
|
#order status
|
||||||
order_not_paid = 'warning'
|
order_not_paid = 'warning'
|
||||||
|
|||||||
@@ -120,7 +120,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{loop name="customer_list" type="customer" current="false" visible="*" order=$customer_order backend_context="1" page=$page limit=$display_customer}
|
{loop name="customer_list" type="customer" current="false" visible="*" order=$customer_order backend_context="1" page=$page limit=#max_displayed_customers#}
|
||||||
{assign "lastOrderDate" ''}
|
{assign "lastOrderDate" ''}
|
||||||
{assign "lastOrderAmount" ''}
|
{assign "lastOrderAmount" ''}
|
||||||
{assign "lastOrderCurrency" ''}
|
{assign "lastOrderCurrency" ''}
|
||||||
@@ -179,34 +179,13 @@
|
|||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6">
|
<td colspan="6">
|
||||||
|
{include
|
||||||
|
file = "includes/pagination.html"
|
||||||
|
|
||||||
<div class="text-center">
|
loop_ref = "customer_list"
|
||||||
<ul class="pagination pagination-centered">
|
max_page_count = 10
|
||||||
|
page_url = "{url path="/admin/customers" customer_order=$customer_order}"
|
||||||
{if $page != 1}
|
}
|
||||||
<li><a href="{url path="/admin/customers" page="1"}">«</a></li>
|
|
||||||
{/if}
|
|
||||||
{pageloop rel="customer_list" numPage="20"}
|
|
||||||
{if $PAGE == $CURRENT && $PAGE > 2}
|
|
||||||
<li><a href="{url path="/admin/customers" page=$PREV}">‹</a></li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{if $PAGE != $CURRENT}
|
|
||||||
<li><a href="{url path="/admin/customers" page="{$PAGE}"}">{$PAGE}</a></li>
|
|
||||||
|
|
||||||
{else}
|
|
||||||
<li class="active"><a href="#">{$PAGE}</a></li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{if $PAGE == $END && $PAGE < $LAST}
|
|
||||||
<li><a href="{url path="/admin/customers" page=$NEXT}">›</a></li>
|
|
||||||
{/if}
|
|
||||||
{/pageloop}
|
|
||||||
{if $LAST > $CURRENT}
|
|
||||||
<li><a href="{url path="/admin/customers" page="$LAST"}">»</a></li>
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
69
templates/backOffice/default/includes/pagination.html
Normal file
69
templates/backOffice/default/includes/pagination.html
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{*
|
||||||
|
A generic pager for thelia back-office
|
||||||
|
|
||||||
|
Parameters :
|
||||||
|
|
||||||
|
$loop_ref: the name of the related loop
|
||||||
|
$max_page_count : maximum number of pages to display
|
||||||
|
$page_url : the URL of the page. The parameter page=x is appended to this URL.
|
||||||
|
|
||||||
|
*}
|
||||||
|
|
||||||
|
{* Prepare the URL so that the page=x parameter coumd be safely appended *}
|
||||||
|
|
||||||
|
{if strpos($page_url, '?')}
|
||||||
|
{$page_url="$page_url&"}
|
||||||
|
{else}
|
||||||
|
{$page_url="$page_url?"}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<ul class="pagination pagination-centered">
|
||||||
|
{pageloop rel=$loop_ref limit=$max_page_count}
|
||||||
|
{$prev_page = $PREV}
|
||||||
|
{$next_page = $NEXT}
|
||||||
|
{$last_page = $LAST}
|
||||||
|
{$has_prev = $CURRENT > 1}
|
||||||
|
{$has_next = $CURRENT < $LAST}
|
||||||
|
|
||||||
|
{$has_pages_after = $END < $LAST && $LAST > $max_page_count}
|
||||||
|
{$has_pages_before = $START > 1}
|
||||||
|
|
||||||
|
{if $PAGE == $START}
|
||||||
|
{if $has_prev}
|
||||||
|
<li><a title="{intl l="Go to first page"}" href="{$page_url}page=1">«</a></li>
|
||||||
|
<li><a title="{intl l="Go to previous page"}" href="{$page_url}page=$prev_page">‹</a></li>
|
||||||
|
|
||||||
|
{if $has_pages_before}
|
||||||
|
<li title="{intl l="More pages before"}" class="disabled"><a href="#">…</a></li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{else}
|
||||||
|
<li class="disabled"><a href="#">«</a></li>
|
||||||
|
<li class="disabled"><a href="#">‹</a></li>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if $PAGE != $CURRENT}
|
||||||
|
<li><a href="{$page_url}page={$PAGE}">{$PAGE}</a></li>
|
||||||
|
{else}
|
||||||
|
<li class="active"><a href="#">{$PAGE}</a></li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if $PAGE == $END}
|
||||||
|
{if $has_next}
|
||||||
|
{if $has_pages_after}
|
||||||
|
<li title="{intl l="More pages after"}" class="disabled"><a href="#">…</a></li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<li><a title="{intl l="Go to next page"}" href="{$page_url}page={$next_page}">›</a></li>
|
||||||
|
<li><a title="{intl l="Go to last page"}" href="{$page_url}page={$last_page}">»</a></li>
|
||||||
|
|
||||||
|
{else}
|
||||||
|
<li class="disabled"><a href="#">›</a></li>
|
||||||
|
<li class="disabled"><a href="#">»</a></li>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
{/pageloop}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
@@ -150,32 +150,13 @@
|
|||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7">
|
<td colspan="7">
|
||||||
|
{include
|
||||||
|
file = "includes/pagination.html"
|
||||||
|
|
||||||
<div class="text-center">
|
loop_ref = "order-list"
|
||||||
<ul class="pagination pagination-centered">
|
max_page_count = 10
|
||||||
{if $order_page != 1}
|
page_url = "{url path="/admin/orders" orders_order=$orders_order}"
|
||||||
<li><a href="{url path="/admin/orders" page=1 orders_order=$orders_order}">«</a></li>
|
}
|
||||||
{else}
|
|
||||||
<li class="disabled"><a href="#">«</a></li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{pageloop rel="order-list"}
|
|
||||||
{if $PAGE != $CURRENT}
|
|
||||||
<li><a href="{url path="/admin/orders" page=$PAGE orders_order=$orders_order}">{$PAGE}</a></li>
|
|
||||||
|
|
||||||
{else}
|
|
||||||
<li class="active"><a href="#">{$PAGE}</a></li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
|
|
||||||
{/pageloop}
|
|
||||||
{if $PAGE == $LAST && $LAST != $CURRENT}
|
|
||||||
<li><a href="{url path="/admin/orders" page=$PAGE orders_order=$orders_order}">»</a></li>
|
|
||||||
{else}
|
|
||||||
<li class="disabled"><a href="#">»</a></li>
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user