Rajout du dossier core + MAJ .gitignore

This commit is contained in:
2019-11-21 12:48:42 +01:00
parent f4aabcb9b1
commit 459f8966b0
10448 changed files with 1835600 additions and 1 deletions

View File

@@ -0,0 +1,191 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition;
use ArrayAccess;
use Countable;
use Iterator;
use Thelia\Condition\Implementation\ConditionInterface;
/**
* Manage a set of ConditionInterface
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ConditionCollection implements Iterator, Countable, ArrayAccess
{
/** @var ConditionInterface[] */
protected $conditions = [];
/**
* (PHP 5 &gt;= 5.0.0)
* Return the current element
* @link http://php.net/manual/en/iterator.current.php
*
* @return mixed Can return any type.
*/
public function current()
{
$var = current($this->conditions);
return $var;
}
/**
* (PHP 5 &gt;= 5.0.0)
* Move forward to next element
* @link http://php.net/manual/en/iterator.next.php
*
* @return void Any returned value is ignored.
*/
public function next()
{
next($this->conditions);
}
/**
* (PHP 5 &gt;= 5.0.0)
* Return the key of the current element
* @link http://php.net/manual/en/iterator.key.php
*
* @return mixed scalar on success, or null on failure.
*/
public function key()
{
$var = key($this->conditions);
return $var;
}
/**
* (PHP 5 &gt;= 5.0.0)
* Checks if current position is valid
* @link http://php.net/manual/en/iterator.valid.php
*
* @return boolean The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
*/
public function valid()
{
$key = key($this->conditions);
$var = ($key !== null && $key !== false);
return $var;
}
/**
* (PHP 5 &gt;= 5.0.0)
* Rewind the Iterator to the first element
* @link http://php.net/manual/en/iterator.rewind.php
*
* @return void Any returned value is ignored.
*/
public function rewind()
{
reset($this->conditions);
}
/**
* (PHP 5 &gt;= 5.1.0)
* Count elements of an object
* @link http://php.net/manual/en/countable.count.php
*
* @return int The custom count as an integer.
* The return value is cast to an integer.
*/
public function count()
{
return count($this->conditions);
}
/**
* (PHP 5 >= 5.0.0)
* Whether a offset exists
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
* @param mixed $offset
* An offset to check for.
*
* @return boolean true on success or false on failure.
* The return value will be casted to boolean if non-boolean was returned.
*/
public function offsetExists($offset)
{
return isset($this->conditions[$offset]);
}
/**
* (PHP 5 >= 5.0.0)
* Offset to retrieve
* @link http://php.net/manual/en/arrayaccess.offsetget.php
* @param mixed $offset
* The offset to retrieve.
*
* @return mixed Can return all value types.
*/
public function offsetGet($offset)
{
return isset($this->conditions[$offset]) ? $this->conditions[$offset] : null;
}
/**
* (PHP 5 >= 5.0.0)
* Offset to set
* @link http://php.net/manual/en/arrayaccess.offsetset.php
* @param mixed $offset
* The offset to assign the value to.
* @param mixed $value
* The value to set.
*
* @return void
*/
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->conditions[] = $value;
} else {
$this->conditions[$offset] = $value;
}
}
/**
* (PHP 5 >= 5.0.0)
* Offset to unset
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
* @param mixed $offset
* The offset to unset.
*
* @return void
*/
public function offsetUnset($offset)
{
unset($this->conditions[$offset]);
}
/**
* Allow to compare 2 set of conditions
*
* @return string Jsoned data
*/
public function __toString()
{
$arrayToSerialize = [];
/** @var ConditionInterface $condition */
foreach ($this as $condition) {
$arrayToSerialize[] = $condition->getSerializableCondition();
}
return json_encode($arrayToSerialize);
}
}

View File

@@ -0,0 +1,125 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition;
use Thelia\Condition\Implementation\ConditionInterface;
/**
* Validate Conditions
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ConditionEvaluator
{
/**
* Check if an Event matches SerializableCondition
*
* @param ConditionCollection $conditions Conditions to check against the Event
*
* @return bool
*/
public function isMatching(ConditionCollection $conditions)
{
$isMatching = true;
/** @var ConditionInterface $condition */
foreach ($conditions as $condition) {
if (!$condition->isMatching()) {
return false;
}
}
return $isMatching;
}
/**
* Do variable comparison
*
* @param mixed $v1 Variable 1
* @param string $o Operator ex : Operators::DIFFERENT
* @param mixed $v2 Variable 2
*
* @throws \Exception
* @return bool
*/
public function variableOpComparison($v1, $o, $v2)
{
if ($o == Operators::DIFFERENT) {
return ($v1 != $v2);
}
switch ($o) {
case Operators::SUPERIOR:
// >
if ($v1 > $v2) {
return true;
} else {
continue;
}
break;
case Operators::SUPERIOR_OR_EQUAL:
// >=
if ($v1 >= $v2) {
return true;
} else {
continue;
}
break;
case Operators::INFERIOR:
// <
if ($v1 < $v2) {
return true;
} else {
continue;
}
break;
case Operators::INFERIOR_OR_EQUAL:
// <=
if ($v1 <= $v2) {
return true;
} else {
continue;
}
break;
case Operators::EQUAL:
// ==
if ($v1 == $v2) {
return true;
} else {
continue;
}
break;
case Operators::IN:
// in
if (in_array($v1, $v2)) {
return true;
} else {
continue;
}
break;
case Operators::OUT:
// not in
if (!in_array($v1, $v2)) {
return true;
} else {
continue;
}
break;
default:
throw new \Exception('Unrecognized operator ' . $o);
}
return false;
}
}

View File

@@ -0,0 +1,157 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\Condition\Implementation\ConditionInterface;
use Thelia\Coupon\FacadeInterface;
/**
* Manage how Condition could interact with the current application state (Thelia)
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ConditionFactory
{
/** @var ContainerInterface Service Container */
protected $container = null;
/** @var FacadeInterface Provide necessary value from Thelia */
protected $adapter;
/** @var array ConditionCollection to process*/
protected $conditions = null;
/**
* Constructor
*
* @param ContainerInterface $container Service container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->adapter = $container->get('thelia.facade');
}
/**
* Serialize a collection of conditions
*
* @param ConditionCollection $collection A collection of conditions
*
* @return string A ready to be stored Condition collection
*/
public function serializeConditionCollection(ConditionCollection $collection)
{
if ($collection->count() == 0) {
/** @var ConditionInterface $conditionNone */
$conditionNone = $this->container->get(
'thelia.condition.match_for_everyone'
);
$collection[] = $conditionNone;
}
$serializableConditions = [];
/** @var $condition ConditionInterface */
foreach ($collection as $condition) {
$serializableConditions[] = $condition->getSerializableCondition();
}
return base64_encode(json_encode($serializableConditions));
}
/**
* Unserialize a collection of conditions
*
* @param string $serializedConditions Serialized Conditions
*
* @return ConditionCollection Conditions ready to be processed
*/
public function unserializeConditionCollection($serializedConditions)
{
$unserializedConditions = json_decode(base64_decode($serializedConditions));
$collection = new ConditionCollection();
if (!empty($unserializedConditions)) {
/** @var SerializableCondition $condition */
foreach ($unserializedConditions as $condition) {
if ($this->container->has($condition->conditionServiceId)) {
/** @var ConditionInterface $conditionManager */
$conditionManager = $this->build(
$condition->conditionServiceId,
(array) $condition->operators,
(array) $condition->values
);
$collection[] = clone $conditionManager;
}
}
}
return $collection;
}
/**
* Build a Condition from form
*
* @param string $conditionServiceId Condition class name
* @param array $operators Condition Operator (<, >, = )
* @param array $values Values setting this Condition
*
* @throws \InvalidArgumentException
* @return ConditionInterface Ready to use Condition or false
*/
public function build($conditionServiceId, array $operators, array $values)
{
if (!$this->container->has($conditionServiceId)) {
return false;
}
/** @var ConditionInterface $condition */
$condition = $this->container->get($conditionServiceId);
$condition->setValidatorsFromForm($operators, $values);
return clone $condition;
}
/**
* Get Condition inputs from serviceId
*
* @param string $conditionServiceId ConditionManager class name
*
* @return array Ready to be drawn condition inputs
*/
public function getInputsFromServiceId($conditionServiceId)
{
if (!$this->container->has($conditionServiceId)) {
return false;
}
/** @var ConditionInterface $condition */
$condition = $this->container->get($conditionServiceId);
return $this->getInputsFromConditionInterface($condition);
}
/**
* Get Condition inputs from serviceId
*
* @param ConditionInterface $condition ConditionManager
*
* @return array Ready to be drawn condition inputs
*/
public function getInputsFromConditionInterface(ConditionInterface $condition)
{
return $condition->getValidators();
}
}

View File

@@ -0,0 +1,35 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition;
/**
* Manage how Condition could interact with each others
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class ConditionOrganizer implements ConditionOrganizerInterface
{
/**
* Organize ConditionInterface
*
* @param array $conditions Array of ConditionInterface
*
* @return array Array of ConditionInterface sorted
*/
public function organize(array $conditions)
{
// @todo: Implement organize() method.
}
}

View File

@@ -0,0 +1,32 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition;
/**
* Manage how Condition could interact with each other
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
interface ConditionOrganizerInterface
{
/**
* Organize ConditionInterface
*
* @param array $conditions Array of ConditionInterface
*
* @return array Array of ConditionInterface sorted
*/
public function organize(array $conditions);
}

View File

@@ -0,0 +1,155 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Exception\InvalidConditionValueException;
use Thelia\Model\Country;
use Thelia\Model\CountryQuery;
/**
* Check a Checkout against its Product number
*
* @package Condition
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
abstract class AbstractMatchCountries extends ConditionAbstract
{
/** Condition 1st parameter : quantity */
const COUNTRIES_LIST = 'countries';
/**
* @inheritdoc
*/
public function __construct(FacadeInterface $facade)
{
$this->availableOperators = [
self::COUNTRIES_LIST => [
Operators::IN,
Operators::OUT
]
];
parent::__construct($facade);
}
abstract protected function getSummaryLabel($cntryStrList, $i18nOperator);
abstract protected function getFormLabel();
/**
* @inheritdoc
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->checkComparisonOperatorValue($operators, self::COUNTRIES_LIST);
// Use default values if data is not defined.
if (! isset($operators[self::COUNTRIES_LIST]) || ! isset($values[self::COUNTRIES_LIST])) {
$operators[self::COUNTRIES_LIST] = Operators::IN;
$values[self::COUNTRIES_LIST] = [];
}
// Be sure that the value is an array, make one if required
if (! is_array($values[self::COUNTRIES_LIST])) {
$values[self::COUNTRIES_LIST] = array($values[self::COUNTRIES_LIST]);
}
// Check that at least one category is selected
if (empty($values[self::COUNTRIES_LIST])) {
throw new InvalidConditionValueException(
get_class(),
self::COUNTRIES_LIST
);
}
$this->operators = [ self::COUNTRIES_LIST => $operators[self::COUNTRIES_LIST] ];
$this->values = [ self::COUNTRIES_LIST => $values[self::COUNTRIES_LIST] ];
return $this;
}
/**
* @inheritdoc
*/
public function isMatching()
{
// The delivery address should match one of the selected countries.
/* TODO !!!! */
return $this->conditionValidator->variableOpComparison(
$this->facade->getNbArticlesInCart(),
$this->operators[self::COUNTRIES_LIST],
$this->values[self::COUNTRIES_LIST]
);
}
/**
* @inheritdoc
*/
public function getSummary()
{
$i18nOperator = Operators::getI18n(
$this->translator,
$this->operators[self::COUNTRIES_LIST]
);
$cntryStrList = '';
$cntryIds = $this->values[self::COUNTRIES_LIST];
if (null !== $cntryList = CountryQuery::create()->findPks($cntryIds)) {
/** @var Country $cntry */
foreach ($cntryList as $cntry) {
$cntryStrList .= $cntry->setLocale($this->getCurrentLocale())->getTitle() . ', ';
}
$cntryStrList = rtrim($cntryStrList, ', ');
}
return $this->getSummaryLabel($cntryStrList, $i18nOperator);
}
/**
* @inheritdoc
*/
protected function generateInputs()
{
return array(
self::COUNTRIES_LIST => array(
'availableOperators' => $this->availableOperators[self::COUNTRIES_LIST],
'value' => '',
'selectedOperator' => Operators::IN
)
);
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render(
'coupon/condition-fragments/countries-condition.html',
[
'operatorSelectHtml' => $this->drawBackOfficeInputOperators(self::COUNTRIES_LIST),
'countries_field_name' => self::COUNTRIES_LIST,
'values' => isset($this->values[self::COUNTRIES_LIST]) ? $this->values[self::COUNTRIES_LIST] : array(),
'countryLabel' => $this->getFormLabel()
]
);
}
}

View File

@@ -0,0 +1,203 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Exception\InvalidConditionValueException;
use Thelia\Model\CartItem;
use Thelia\Model\Category;
use Thelia\Model\CategoryQuery;
/**
* Check a Checkout against its Product number
*
* @package Condition
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
class CartContainsCategories extends ConditionAbstract
{
/** Condition 1st parameter : quantity */
const CATEGORIES_LIST = 'categories';
/**
* @inheritdoc
*/
public function __construct(FacadeInterface $facade)
{
$this->availableOperators = [
self::CATEGORIES_LIST => [
Operators::IN,
Operators::OUT
]
];
parent::__construct($facade);
}
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.cart_contains_categories';
}
/**
* @inheritdoc
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->checkComparisonOperatorValue($operators, self::CATEGORIES_LIST);
// Use default values if data is not defined.
if (! isset($operators[self::CATEGORIES_LIST]) || ! isset($values[self::CATEGORIES_LIST])) {
$operators[self::CATEGORIES_LIST] = Operators::IN;
$values[self::CATEGORIES_LIST] = [];
}
// Be sure that the value is an array, make one if required
if (! is_array($values[self::CATEGORIES_LIST])) {
$values[self::CATEGORIES_LIST] = array($values[self::CATEGORIES_LIST]);
}
// Check that at least one category is selected
if (empty($values[self::CATEGORIES_LIST])) {
throw new InvalidConditionValueException(
get_class(),
self::CATEGORIES_LIST
);
}
$this->operators = [ self::CATEGORIES_LIST => $operators[self::CATEGORIES_LIST] ];
$this->values = [ self::CATEGORIES_LIST => $values[self::CATEGORIES_LIST] ];
return $this;
}
/**
* @inheritdoc
*/
public function isMatching()
{
$cartItems = $this->facade->getCart()->getCartItems();
/** @var CartItem $cartItem */
foreach ($cartItems as $cartItem) {
$categories = $cartItem->getProduct()->getCategories();
/** @var Category $category */
foreach ($categories as $category) {
$catecoryInCart = $this->conditionValidator->variableOpComparison(
$category->getId(),
$this->operators[self::CATEGORIES_LIST],
$this->values[self::CATEGORIES_LIST]
);
if ($catecoryInCart) {
return true;
}
}
}
return false;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'Cart contains categories condition',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'The coupon applies if the cart contains at least one product of the selected categories',
[]
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function getSummary()
{
$i18nOperator = Operators::getI18n(
$this->translator,
$this->operators[self::CATEGORIES_LIST]
);
$catStrList = '';
$catIds = $this->values[self::CATEGORIES_LIST];
if (null !== $catList = CategoryQuery::create()->findPks($catIds)) {
/** @var Category $cat */
foreach ($catList as $cat) {
$catStrList .= $cat->setLocale($this->getCurrentLocale())->getTitle() . ', ';
}
$catStrList = rtrim($catStrList, ', ');
}
$toolTip = $this->translator->trans(
'At least one of cart products categories is %op% <strong>%categories_list%</strong>',
[
'%categories_list%' => $catStrList,
'%op%' => $i18nOperator
]
);
return $toolTip;
}
/**
* @inheritdoc
*/
protected function generateInputs()
{
return array(
self::CATEGORIES_LIST => array(
'availableOperators' => $this->availableOperators[self::CATEGORIES_LIST],
'value' => '',
'selectedOperator' => Operators::IN
)
);
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render(
'coupon/condition-fragments/cart-contains-categories-condition.html',
[
'operatorSelectHtml' => $this->drawBackOfficeInputOperators(self::CATEGORIES_LIST),
'categories_field_name' => self::CATEGORIES_LIST,
'values' => isset($this->values[self::CATEGORIES_LIST]) ? $this->values[self::CATEGORIES_LIST] : array()
]
);
}
}

View File

@@ -0,0 +1,196 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Exception\InvalidConditionValueException;
use Thelia\Model\ProductQuery;
use Thelia\Model\CartItem;
use Thelia\Model\Product;
/**
* Check a Checkout against its Product number
*
* @package Condition
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
class CartContainsProducts extends ConditionAbstract
{
/** Condition 1st parameter : quantity */
const PRODUCTS_LIST = 'products';
/**
* @inheritdoc
*/
public function __construct(FacadeInterface $facade)
{
$this->availableOperators = [
self::PRODUCTS_LIST => [
Operators::IN,
Operators::OUT
]
];
parent::__construct($facade);
}
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.cart_contains_products';
}
/**
* @inheritdoc
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->checkComparisonOperatorValue($operators, self::PRODUCTS_LIST);
// Use default values if data is not defined.
if (! isset($operators[self::PRODUCTS_LIST]) || ! isset($values[self::PRODUCTS_LIST])) {
$operators[self::PRODUCTS_LIST] = Operators::IN;
$values[self::PRODUCTS_LIST] = [];
}
// Be sure that the value is an array, make one if required
if (! is_array($values[self::PRODUCTS_LIST])) {
$values[self::PRODUCTS_LIST] = array($values[self::PRODUCTS_LIST]);
}
// Check that at least one product is selected
if (empty($values[self::PRODUCTS_LIST])) {
throw new InvalidConditionValueException(
get_class(),
self::PRODUCTS_LIST
);
}
$this->operators = [ self::PRODUCTS_LIST => $operators[self::PRODUCTS_LIST] ];
$this->values = [ self::PRODUCTS_LIST => $values[self::PRODUCTS_LIST] ];
return $this;
}
/**
* @inheritdoc
*/
public function isMatching()
{
$cartItems = $this->facade->getCart()->getCartItems();
/** @var CartItem $cartItem */
foreach ($cartItems as $cartItem) {
if ($this->conditionValidator->variableOpComparison(
$cartItem->getProduct()->getId(),
$this->operators[self::PRODUCTS_LIST],
$this->values[self::PRODUCTS_LIST]
)) {
return true;
}
}
return false;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'Cart contains specific products',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'The coupon applies if the cart contains at least one product of the specified product list',
[]
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function getSummary()
{
$i18nOperator = Operators::getI18n(
$this->translator,
$this->operators[self::PRODUCTS_LIST]
);
$prodStrList = '';
$prodIds = $this->values[self::PRODUCTS_LIST];
if (null !== $prodList = ProductQuery::create()->findPks($prodIds)) {
/** @var Product $prod */
foreach ($prodList as $prod) {
$prodStrList .= $prod->setLocale($this->getCurrentLocale())->getTitle() . ', ';
}
$prodStrList = rtrim($prodStrList, ', ');
}
$toolTip = $this->translator->trans(
'Cart contains at least a product %op% <strong>%products_list%</strong>',
[
'%products_list%' => $prodStrList,
'%op%' => $i18nOperator
]
);
return $toolTip;
}
/**
* @inheritdoc
*/
protected function generateInputs()
{
return array(
self::PRODUCTS_LIST => array(
'availableOperators' => $this->availableOperators[self::PRODUCTS_LIST],
'value' => '',
'selectedOperator' => Operators::IN
)
);
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render(
'coupon/condition-fragments/cart-contains-products-condition.html',
[
'operatorSelectHtml' => $this->drawBackOfficeInputOperators(self::PRODUCTS_LIST),
'products_field_name' => self::PRODUCTS_LIST,
'values' => isset($this->values[self::PRODUCTS_LIST]) ? $this->values[self::PRODUCTS_LIST] : array()
]
);
}
}

View File

@@ -0,0 +1,351 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Operators;
use Thelia\Condition\SerializableCondition;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
use Thelia\Exception\InvalidConditionOperatorException;
use Thelia\Exception\InvalidConditionValueException;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Currency;
use Thelia\Type\FloatType;
/**
* Assist in writing a condition of whether the Condition is applied or not
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
abstract class ConditionAbstract implements ConditionInterface
{
/** @var array Available Operators (Operators::CONST) */
protected $availableOperators = [];
/** @var array Parameters validating parameters against */
protected $validators = [];
/** @var FacadeInterface Provide necessary value from Thelia */
protected $facade = null;
/** @var Translator Service Translator */
protected $translator = null;
/** @var array Operators set by Admin in BackOffice */
protected $operators = [];
/** @var array Values set by Admin in BackOffice */
protected $values = [];
/** @var ConditionEvaluator Conditions validator */
protected $conditionValidator = null;
/**
* Constructor
*
* @param FacadeInterface $facade Service Facade
*/
public function __construct(FacadeInterface $facade)
{
$this->facade = $facade;
$this->translator = $facade->getTranslator();
$this->conditionValidator = $facade->getConditionEvaluator();
}
/**
* @param array $operatorList the list of comparison operator values, as entered in the condition parameter form
* @param string $parameterName the name of the parameter to check
*
* @return $this
*
* @throws \Thelia\Exception\InvalidConditionOperatorException if the operator value is not in the allowed value
*/
protected function checkComparisonOperatorValue($operatorList, $parameterName)
{
$isOperator1Legit = $this->isOperatorLegit(
$operatorList[$parameterName],
$this->availableOperators[$parameterName]
);
if (!$isOperator1Legit) {
throw new InvalidConditionOperatorException(
get_class(),
$parameterName
);
}
return $this;
}
/**
* Return all validators
*
* @return array
*/
public function getValidators()
{
$this->validators = $this->generateInputs();
$translatedInputs = [];
foreach ($this->validators as $key => $validator) {
$translatedOperators = [];
foreach ($validator['availableOperators'] as $availableOperators) {
$translatedOperators[$availableOperators] = Operators::getI18n(
$this->translator,
$availableOperators
);
}
$validator['availableOperators'] = $translatedOperators;
$translatedInputs[$key] = $validator;
}
$validators = [
'inputs' => $translatedInputs,
'setOperators' => $this->operators,
'setValues' => $this->values
];
return $validators;
}
/**
* Generate inputs ready to be drawn.
*
* TODO: what these "inputs ready to be drawn" is not clear.
*
* @throws \Thelia\Exception\NotImplementedException
* @return array
*/
protected function generateInputs()
{
throw new \Thelia\Exception\NotImplementedException(
'The generateInputs method must be implemented in ' . get_class()
);
}
/**
* Get ConditionManager Service id
*
* @return string
*/
public function getServiceId()
{
throw new \Thelia\Exception\NotImplementedException(
'The getServiceId method must be implemented in ' . get_class()
);
}
/**
* Validate if Operator given is available for this Condition
*
* @param string $operator Operator to validate ex <
* @param array $availableOperators Available operators
*
* @return bool
*/
protected function isOperatorLegit($operator, array $availableOperators)
{
return in_array($operator, $availableOperators);
}
/**
* Return a serializable Condition
*
* @return SerializableCondition
*/
public function getSerializableCondition()
{
$serializableCondition = new SerializableCondition();
$serializableCondition->conditionServiceId = $this->getServiceId();
$serializableCondition->operators = $this->operators;
$serializableCondition->values = $this->values;
return $serializableCondition;
}
/**
* Check if currency if valid or not
*
* @param string $currencyValue Currency EUR|USD|..
*
* @return bool
* @throws \Thelia\Exception\InvalidConditionValueException
*/
protected function isCurrencyValid($currencyValue)
{
$availableCurrencies = $this->facade->getAvailableCurrencies();
/** @var Currency $currency */
$currencyFound = false;
foreach ($availableCurrencies as $currency) {
if ($currencyValue == $currency->getCode()) {
$currencyFound = true;
}
}
if (!$currencyFound) {
throw new InvalidConditionValueException(
get_class(),
'currency'
);
}
return true;
}
/**
* Check if price is valid
*
* @param float $priceValue Price value to check
*
* @return bool
* @throws \Thelia\Exception\InvalidConditionValueException
*/
protected function isPriceValid($priceValue)
{
$floatType = new FloatType();
if (!$floatType->isValid($priceValue) || $priceValue <= 0) {
throw new InvalidConditionValueException(
get_class(),
'price'
);
}
return true;
}
/**
* Draw the operator input displayed in the BackOffice
* allowing Admin to set its Coupon Conditions
*
* @param string $inputKey Input key (ex: self::INPUT1)
*
* @return string HTML string
*/
protected function drawBackOfficeInputOperators($inputKey)
{
$html = '';
$inputs = $this->getValidators();
if (isset($inputs['inputs'][$inputKey])) {
$html = $this->facade->getParser()->render(
'coupon/condition-fragments/condition-selector.html',
[
'operators' => $inputs['inputs'][$inputKey]['availableOperators'],
'value' => isset($this->operators[$inputKey]) ? $this->operators[$inputKey] : '',
'inputKey' => $inputKey
]
);
}
return $html;
}
/**
* Draw the base input displayed in the BackOffice
* allowing Admin to set its Coupon Conditions
*
* @param string $label I18n input label
* @param string $inputKey Input key (ex: self::INPUT1)
*
* @return string HTML string
*/
protected function drawBackOfficeBaseInputsText($label, $inputKey)
{
$operatorSelectHtml = $this->drawBackOfficeInputOperators($inputKey);
$currentValue = '';
if (isset($this->values) && isset($this->values[$inputKey])) {
$currentValue = $this->values[$inputKey];
}
return $this->facade->getParser()->render(
'coupon/conditions-fragments/base-input-text.html',
[
'label' => $label,
'inputKey' => $inputKey,
'currentValue' => $currentValue,
'operatorSelectHtml' => $operatorSelectHtml
]
);
}
/**
* Draw the quantity input displayed in the BackOffice
* allowing Admin to set its Coupon Conditions
*
* @param string $inputKey Input key (ex: self::INPUT1)
* @param int $max Maximum selectable
* @param int $min Minimum selectable
*
* @return string HTML string
*/
protected function drawBackOfficeInputQuantityValues($inputKey, $max = 10, $min = 0)
{
return $this->facade->getParser()->render(
'coupon/condition-fragments/quantity-selector.html',
[
'min' => $min,
'max' => $max,
'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '',
'inputKey' => $inputKey
]
);
}
/**
* Draw the currency input displayed in the BackOffice
* allowing Admin to set its Coupon Conditions
*
* @param string $inputKey Input key (ex: self::INPUT1)
*
* @return string HTML string
*/
protected function drawBackOfficeCurrencyInput($inputKey)
{
$currencies = CurrencyQuery::create()->find();
$cleanedCurrencies = [];
/** @var Currency $currency */
foreach ($currencies as $currency) {
$cleanedCurrencies[$currency->getCode()] = $currency->getSymbol();
}
return $this->facade->getParser()->render(
'coupon/condition-fragments/currency-selector.html',
[
'currencies' => $cleanedCurrencies,
'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '',
'inputKey' => $inputKey
]
);
}
/**
* A helper to het the current locale.
*
* @return string the current locale.
*/
protected function getCurrentLocale()
{
return $this->facade->getRequest()->getSession()->getLang()->getLocale();
}
}

View File

@@ -0,0 +1,107 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\SerializableCondition;
use Thelia\Coupon\FacadeInterface;
use Thelia\Exception\InvalidConditionOperatorException;
use Thelia\Exception\InvalidConditionValueException;
/**
* Manage how the application checks its state in order to check if it matches the implemented condition
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
interface ConditionInterface
{
/**
* Constructor
*
* @param FacadeInterface $adapter Service adapter
*/
public function __construct(FacadeInterface $adapter);
/**
* Get Condition Service id
*
* @return string
*/
public function getServiceId();
/**
* Check validators relevancy and store them
*
* @param array $operators an array of operators (greater than, less than, etc.) entered in the condition parameter input form, one for each condition defined by the Condition
* @param array $values an array of values entered in in the condition parameter input form, one for each condition defined by the Condition
*
* @throws InvalidConditionOperatorException
* @throws InvalidConditionValueException
*
* @return $this
*/
public function setValidatorsFromForm(array $operators, array $values);
/**
* Test if the current application state matches conditions
*
* @return bool
*/
public function isMatching();
/**
* Get I18n name
*
* @return string
*/
public function getName();
/**
* Get I18n tooltip
* Explain in detail what the Condition checks
*
* @return string
*/
public function getToolTip();
/**
* Get I18n summary
* Explain briefly the condition with given values
*
* @return string
*/
public function getSummary();
/**
* Return all validators
*
* @return array
*/
public function getValidators();
/**
* Return a serializable Condition
*
* @return SerializableCondition
*/
public function getSerializableCondition();
/**
* Draw the input displayed in the BackOffice
* allowing Admin to set its Coupon Conditions
*
* @return string HTML string
*/
public function drawBackOfficeInputs();
}

View File

@@ -0,0 +1,190 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Exception\InvalidConditionValueException;
use Thelia\Exception\UnmatchableConditionException;
use Thelia\Model\Customer;
use Thelia\Model\CustomerQuery;
/**
* Check a Checkout against its Product number
*
* @package Condition
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
class ForSomeCustomers extends ConditionAbstract
{
const CUSTOMERS_LIST = 'customers';
/**
* @inheritdoc
*/
public function __construct(FacadeInterface $facade)
{
$this->availableOperators = [
self::CUSTOMERS_LIST => [
Operators::IN,
Operators::OUT
]
];
parent::__construct($facade);
}
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.for_some_customers';
}
/**
* @inheritdoc
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->checkComparisonOperatorValue($operators, self::CUSTOMERS_LIST);
// Use default values if data is not defined.
if (! isset($operators[self::CUSTOMERS_LIST]) || ! isset($values[self::CUSTOMERS_LIST])) {
$operators[self::CUSTOMERS_LIST] = Operators::IN;
$values[self::CUSTOMERS_LIST] = [];
}
// Be sure that the value is an array, make one if required
if (! is_array($values[self::CUSTOMERS_LIST])) {
$values[self::CUSTOMERS_LIST] = array($values[self::CUSTOMERS_LIST]);
}
// Check that at least one product is selected
if (empty($values[self::CUSTOMERS_LIST])) {
throw new InvalidConditionValueException(
get_class(),
self::CUSTOMERS_LIST
);
}
$this->operators = [ self::CUSTOMERS_LIST => $operators[self::CUSTOMERS_LIST] ];
$this->values = [ self::CUSTOMERS_LIST => $values[self::CUSTOMERS_LIST] ];
return $this;
}
/**
* @inheritdoc
*/
public function isMatching()
{
if (null === $customer = $this->facade->getCustomer()) {
throw new UnmatchableConditionException();
}
return $this->conditionValidator->variableOpComparison(
$customer->getId(),
$this->operators[self::CUSTOMERS_LIST],
$this->values[self::CUSTOMERS_LIST]
);
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'For one ore more customers',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'The coupon applies to some customers only',
[]
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function getSummary()
{
$i18nOperator = Operators::getI18n(
$this->translator,
$this->operators[self::CUSTOMERS_LIST]
);
$custStrList = '';
$custIds = $this->values[self::CUSTOMERS_LIST];
if (null !== $custList = CustomerQuery::create()->findPks($custIds)) {
/** @var Customer $cust */
foreach ($custList as $cust) {
$custStrList .= $cust->getLastname() . ' ' . $cust->getFirstname() . ' ('.$cust->getRef().'), ';
}
$custStrList = rtrim($custStrList, ', ');
}
$toolTip = $this->translator->trans(
'Customer is %op% <strong>%customer_list%</strong>',
[
'%customer_list%' => $custStrList,
'%op%' => $i18nOperator
]
);
return $toolTip;
}
/**
* @inheritdoc
*/
protected function generateInputs()
{
return array(
self::CUSTOMERS_LIST => array(
'availableOperators' => $this->availableOperators[self::CUSTOMERS_LIST],
'value' => '',
'selectedOperator' => Operators::IN
)
);
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render(
'coupon/condition-fragments/customers-condition.html',
[
'operatorSelectHtml' => $this->drawBackOfficeInputOperators(self::CUSTOMERS_LIST),
'customers_field_name' => self::CUSTOMERS_LIST,
'values' => isset($this->values[self::CUSTOMERS_LIST]) ? $this->values[self::CUSTOMERS_LIST] : array()
]
);
}
}

View File

@@ -0,0 +1,94 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Exception\UnmatchableConditionException;
/**
* Check a Checkout against its Product number
*
* @package Condition
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
class MatchBillingCountries extends AbstractMatchCountries
{
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.match_billing_countries';
}
/**
* @inheritdoc
*/
public function isMatching()
{
if (null === $customer = $this->facade->getCustomer()) {
throw new UnmatchableConditionException();
}
$billingAddress = $customer->getDefaultAddress();
return $this->conditionValidator->variableOpComparison(
$billingAddress->getCountryId(),
$this->operators[self::COUNTRIES_LIST],
$this->values[self::COUNTRIES_LIST]
);
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'Billing country',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'The coupon applies to the selected billing countries',
[]
);
return $toolTip;
}
protected function getSummaryLabel($cntryStrList, $i18nOperator)
{
return $this->translator->trans(
'Only if order billing country is %op% <strong>%countries_list%</strong>',
[
'%countries_list%' => $cntryStrList,
'%op%' => $i18nOperator
]
);
}
protected function getFormLabel()
{
return $this->translator->trans(
'Billing country is',
[]
);
}
}

View File

@@ -0,0 +1,96 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Exception\UnmatchableConditionException;
/**
* Check a Checkout against its Product number
*
* @package Condition
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
class MatchDeliveryCountries extends AbstractMatchCountries
{
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.match_delivery_countries';
}
/**
* @inheritdoc
*/
public function isMatching()
{
if (null === $customer = $this->facade->getCustomer()) {
throw new UnmatchableConditionException();
}
if (null === $deliveryAddress = $this->facade->getDeliveryAddress()) {
throw new UnmatchableConditionException();
}
return $this->conditionValidator->variableOpComparison(
$deliveryAddress->getCountryId(),
$this->operators[self::COUNTRIES_LIST],
$this->values[self::COUNTRIES_LIST]
);
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'Delivery country',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'The coupon applies to the selected delivery countries',
[]
);
return $toolTip;
}
protected function getSummaryLabel($cntryStrList, $i18nOperator)
{
return $this->translator->trans(
'Only if order shipping country is %op% <strong>%countries_list%</strong>',
[
'%countries_list%' => $cntryStrList,
'%op%' => $i18nOperator
]
);
}
protected function getFormLabel()
{
return $this->translator->trans(
'Delivery country is',
[]
);
}
}

View File

@@ -0,0 +1,117 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Coupon\FacadeInterface;
/**
* Allow every one, perform no check
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class MatchForEveryone extends ConditionAbstract
{
/**
* @inheritdoc
*/
public function __construct(FacadeInterface $facade)
{
// Define the allowed comparison operators
$this->availableOperators = [];
parent::__construct($facade);
}
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.match_for_everyone';
}
/**
* @inheritdoc
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->operators = [];
$this->values = [];
return $this;
}
/**
* @inheritdoc
*/
public function isMatching()
{
return true;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'Unconditional usage',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'This condition is always true',
[]
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function getSummary()
{
$toolTip = $this->translator->trans(
'Unconditionnal usage',
[]
);
return $toolTip;
}
/**
* @inheritdoc
*/
protected function generateInputs()
{
return [];
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
// No input
return '';
}
}

View File

@@ -0,0 +1,224 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Currency;
use Thelia\Model\CurrencyQuery;
/**
* Condition AvailableForTotalAmount
* Check if a Checkout total amount match criteria
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>, Franck Allimant <franck@cqfdev.fr>
*
*/
class MatchForTotalAmount extends ConditionAbstract
{
/** Condition 1st parameter : price */
const CART_TOTAL = 'price';
/** Condition 1st parameter : currency */
const CART_CURRENCY = 'currency';
public function __construct(FacadeInterface $facade)
{
// Define the allowed comparison operators
$this->availableOperators = [
self::CART_TOTAL => [
Operators::INFERIOR,
Operators::INFERIOR_OR_EQUAL,
Operators::EQUAL,
Operators::SUPERIOR_OR_EQUAL,
Operators::SUPERIOR
],
self::CART_CURRENCY => [
Operators::EQUAL,
]
];
parent::__construct($facade);
}
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.match_for_total_amount';
}
/**
* @inheritdoc
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this
->checkComparisonOperatorValue($operators, self::CART_TOTAL)
->checkComparisonOperatorValue($operators, self::CART_CURRENCY);
$this->isPriceValid($values[self::CART_TOTAL]);
$this->isCurrencyValid($values[self::CART_CURRENCY]);
$this->operators = array(
self::CART_TOTAL => $operators[self::CART_TOTAL],
self::CART_CURRENCY => $operators[self::CART_CURRENCY],
);
$this->values = array(
self::CART_TOTAL => $values[self::CART_TOTAL],
self::CART_CURRENCY => $values[self::CART_CURRENCY],
);
return $this;
}
/**
* Test if Customer meets conditions
*
* @return bool
*/
public function isMatching()
{
$condition1 = $this->conditionValidator->variableOpComparison(
$this->facade->getCartTotalTaxPrice(),
$this->operators[self::CART_TOTAL],
$this->values[self::CART_TOTAL]
);
if ($condition1) {
$condition2 = $this->conditionValidator->variableOpComparison(
$this->facade->getCheckoutCurrency(),
$this->operators[self::CART_CURRENCY],
$this->values[self::CART_CURRENCY]
);
if ($condition2) {
return true;
}
}
return false;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'Cart total amount',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'Check the total Cart amount in the given currency',
[]
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function getSummary()
{
$i18nOperator = Operators::getI18n(
$this->translator,
$this->operators[self::CART_TOTAL]
);
$toolTip = $this->translator->trans(
'If cart total amount is <strong>%operator%</strong> %amount% %currency%',
array(
'%operator%' => $i18nOperator,
'%amount%' => $this->values[self::CART_TOTAL],
'%currency%' => $this->values[self::CART_CURRENCY]
)
);
return $toolTip;
}
/**
* @inheritdoc
*/
protected function generateInputs()
{
$currencies = CurrencyQuery::create()->filterByVisible(true)->find();
$cleanedCurrencies = [];
/** @var Currency $currency */
foreach ($currencies as $currency) {
$cleanedCurrencies[$currency->getCode()] = $currency->getSymbol();
}
return array(
self::CART_TOTAL => array(
'availableOperators' => $this->availableOperators[self::CART_TOTAL],
'availableValues' => '',
'value' => '',
'selectedOperator' => ''
),
self::CART_CURRENCY => array(
'availableOperators' => $this->availableOperators[self::CART_CURRENCY],
'availableValues' => $cleanedCurrencies,
'value' => '',
'selectedOperator' => Operators::EQUAL
)
);
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
$labelPrice = $this->facade
->getTranslator()
->trans('Cart total amount is', []);
$html = $this->drawBackOfficeBaseInputsText($labelPrice, self::CART_TOTAL);
return $html;
}
/**
* @inheritdoc
*/
protected function drawBackOfficeBaseInputsText($label, $inputKey)
{
return $this->facade->getParser()->render(
'coupon/condition-fragments/cart-total-amount-condition.html',
[
'label' => $label,
'inputKey' => $inputKey,
'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '',
'field_1_name' => self::CART_TOTAL,
'field_2_name' => self::CART_CURRENCY,
'operatorSelectHtml' => $this->drawBackOfficeInputOperators(self::CART_TOTAL),
'currencySelectHtml' => $this->drawBackOfficeCurrencyInput(self::CART_CURRENCY),
]
);
}
}

View File

@@ -0,0 +1,187 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Exception\InvalidConditionValueException;
/**
* Check a Checkout against its Product number
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>, Franck Allimant <franck@cqfdev.fr>
*
*/
class MatchForXArticles extends ConditionAbstract
{
/** Condition 1st parameter : quantity */
const CART_QUANTITY = 'quantity';
/**
* @inheritdoc
*/
public function __construct(FacadeInterface $facade)
{
$this->availableOperators = array(
self::CART_QUANTITY => array(
Operators::INFERIOR,
Operators::INFERIOR_OR_EQUAL,
Operators::EQUAL,
Operators::SUPERIOR_OR_EQUAL,
Operators::SUPERIOR
)
);
parent::__construct($facade);
}
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.match_for_x_articles';
}
/**
* @inheritdoc
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->checkComparisonOperatorValue($operators, self::CART_QUANTITY);
if (intval($values[self::CART_QUANTITY]) <= 0) {
throw new InvalidConditionValueException(
get_class(),
'quantity'
);
}
$this->operators = [
self::CART_QUANTITY => $operators[self::CART_QUANTITY]
];
$this->values = [
self::CART_QUANTITY => $values[self::CART_QUANTITY]
];
return $this;
}
/**
* @inheritdoc
*/
public function isMatching()
{
$condition1 = $this->conditionValidator->variableOpComparison(
$this->facade->getNbArticlesInCart(),
$this->operators[self::CART_QUANTITY],
$this->values[self::CART_QUANTITY]
);
if ($condition1) {
return true;
}
return false;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'Cart item count',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'The cart item count should match the condition',
[]
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function getSummary()
{
$i18nOperator = Operators::getI18n(
$this->translator,
$this->operators[self::CART_QUANTITY]
);
$toolTip = $this->translator->trans(
'If cart item count is <strong>%operator%</strong> %quantity%',
array(
'%operator%' => $i18nOperator,
'%quantity%' => $this->values[self::CART_QUANTITY]
)
);
return $toolTip;
}
/**
* @inheritdoc
*/
protected function generateInputs()
{
return array(
self::CART_QUANTITY => array(
'availableOperators' => $this->availableOperators[self::CART_QUANTITY],
'value' => '',
'selectedOperator' => ''
)
);
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
$labelQuantity = $this->facade
->getTranslator()
->trans('Cart item count is');
$html = $this->drawBackOfficeBaseInputsText($labelQuantity, self::CART_QUANTITY);
return $html;
}
/**
* @inheritdoc
*/
protected function drawBackOfficeBaseInputsText($label, $inputKey)
{
return $this->facade->getParser()->render(
'coupon/condition-fragments/cart-item-count-condition.html',
[
'label' => $label,
'operatorSelectHtml' => $this->drawBackOfficeInputOperators($inputKey),
'quantitySelectHtml' => $this->drawBackOfficeInputQuantityValues($inputKey, 20, 1)
]
);
}
}

View File

@@ -0,0 +1,83 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\Operators;
/**
* Class MatchForXArticlesIncludeQuantity
* @package Thelia\Condition\Implementation
* @author Baixas Alban <abaixas@openstudio.fr>
*/
class MatchForXArticlesIncludeQuantity extends MatchForXArticles
{
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.match_for_x_articles_include_quantity';
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans('Cart item include quantity count');
}
/**
* @inheritdoc
*/
public function isMatching()
{
return $this->conditionValidator->variableOpComparison(
$this->facade->getNbArticlesInCartIncludeQuantity(),
$this->operators[self::CART_QUANTITY],
$this->values[self::CART_QUANTITY]
);
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
$labelQuantity = $this->facade->getTranslator()->trans('Cart item include quantity count is');
return $this->drawBackOfficeBaseInputsText($labelQuantity, self::CART_QUANTITY);
}
/**
* @inheritdoc
*/
public function getSummary()
{
$i18nOperator = Operators::getI18n(
$this->translator,
$this->operators[self::CART_QUANTITY]
);
$toolTip = $this->translator->trans(
'If cart item (include quantity) count is <strong>%operator%</strong> %quantity%',
array(
'%operator%' => $i18nOperator,
'%quantity%' => $this->values[self::CART_QUANTITY]
)
);
return $toolTip;
}
}

View File

@@ -0,0 +1,184 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Exception\InvalidConditionValueException;
use Thelia\Tools\DateTimeFormat;
/**
* Check a Checkout against its Product number
*
* @package Condition
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
class StartDate extends ConditionAbstract
{
const START_DATE = 'start_date';
/**
* @inheritdoc
*/
public function __construct(FacadeInterface $facade)
{
$this->availableOperators = [
self::START_DATE => [
Operators::SUPERIOR_OR_EQUAL
]
];
parent::__construct($facade);
}
/**
* @inheritdoc
*/
public function getServiceId()
{
return 'thelia.condition.start_date';
}
/**
* @inheritdoc
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->checkComparisonOperatorValue($operators, self::START_DATE);
if (! isset($values[self::START_DATE])) {
$values[self::START_DATE] = time();
}
// Parse the entered date to get a timestamp, if we don't already have one
if (! is_int($values[self::START_DATE])) {
$date = \DateTime::createFromFormat($this->getDateFormat(), $values[self::START_DATE]);
// Check that the date is valid
if (false === $date) {
throw new InvalidConditionValueException(
get_class(),
self::START_DATE
);
}
$timestamp = $date->getTimestamp();
} else {
$timestamp = $values[self::START_DATE];
}
$this->operators = [ self::START_DATE => $operators[self::START_DATE] ];
$this->values = [ self::START_DATE => $timestamp ];
return $this;
}
/**
* @inheritdoc
*/
public function isMatching()
{
return $this->conditionValidator->variableOpComparison(
time(),
$this->operators[self::START_DATE],
$this->values[self::START_DATE]
);
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->translator->trans(
'Start date',
[]
);
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->translator->trans(
'The coupon is valid after a given date',
[]
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function getSummary()
{
$date = new \DateTime();
$date->setTimestamp($this->values[self::START_DATE]);
$strDate = $date->format($this->getDateFormat());
$toolTip = $this->translator->trans(
'Valid only from %date% to the coupon expiration date',
[
'%date%' => $strDate,
],
'condition'
);
return $toolTip;
}
private function getDateFormat()
{
return DateTimeFormat::getInstance($this->facade->getRequest())->getFormat("date");
}
/**
* @inheritdoc
*/
protected function generateInputs()
{
return array(
self::START_DATE => array(
'availableOperators' => $this->availableOperators[self::START_DATE],
'value' => '',
'selectedOperator' => Operators::SUPERIOR_OR_EQUAL
)
);
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
if (isset($this->values[self::START_DATE])) {
$date = new \DateTime();
$date->setTimestamp($this->values[self::START_DATE]);
$strDate = $date->format($this->getDateFormat());
} else {
$strDate = '';
}
return $this->facade->getParser()->render('coupon/condition-fragments/start-date-condition.html', [
'fieldName' => self::START_DATE,
'criteria' => Operators::SUPERIOR_OR_EQUAL,
'dateFormat' => $this->getDateFormat(),
'currentValue' => $strDate
]);
}
}

View File

@@ -0,0 +1,108 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition;
use Thelia\Core\Translation\Translator;
/**
* Represent available Operations in condition checking
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
abstract class Operators
{
/** Param1 is inferior to Param2 */
const INFERIOR = '<';
/** Param1 is inferior to Param2 */
const INFERIOR_OR_EQUAL = '<=';
/** Param1 is equal to Param2 */
const EQUAL = '==';
/** Param1 is superior to Param2 */
const SUPERIOR_OR_EQUAL = '>=';
/** Param1 is superior to Param2 */
const SUPERIOR = '>';
/** Param1 is different to Param2 */
const DIFFERENT = '!=';
/** Param1 is in Param2 */
const IN = 'in';
/** Param1 is not in Param2 */
const OUT = 'out';
/**
* Get operator translation
*
* @param Translator $translator Provide necessary value from Thelia
* @param string $operator Operator const
*
* @return string
*/
public static function getI18n(Translator $translator, $operator)
{
$ret = $operator;
switch ($operator) {
case self::INFERIOR:
$ret = $translator->trans(
'Less than',
[]
);
break;
case self::INFERIOR_OR_EQUAL:
$ret = $translator->trans(
'Less than or equals',
[]
);
break;
case self::EQUAL:
$ret = $translator->trans(
'Equal to',
[]
);
break;
case self::SUPERIOR_OR_EQUAL:
$ret = $translator->trans(
'Greater than or equals',
[]
);
break;
case self::SUPERIOR:
$ret = $translator->trans(
'Greater than',
[]
);
break;
case self::DIFFERENT:
$ret = $translator->trans(
'Not equal to',
[]
);
break;
case self::IN:
$ret = $translator->trans(
'In',
[]
);
break;
case self::OUT:
$ret = $translator->trans(
'Not in',
[]
);
break;
default:
}
return $ret;
}
}

View File

@@ -0,0 +1,32 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition;
/**
* A condition ready to be serialized and stored in DataBase
*
* @package Condition
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class SerializableCondition
{
/** @var string Condition Service id */
public $conditionServiceId = null;
/** @var array Operators set by Admin for this Condition */
public $operators = [];
/** @var array Values set by Admin for this Condition */
public $values = [];
}