diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml
index 08575590f..e94fbf1fe 100755
--- a/core/lib/Thelia/Config/Resources/config.xml
+++ b/core/lib/Thelia/Config/Resources/config.xml
@@ -206,6 +206,9 @@
+
+
+
diff --git a/core/lib/Thelia/Constraint/ConstraintManager.php b/core/lib/Thelia/Constraint/ConstraintManager.php
index 6cbcbb1be..28073abaa 100644
--- a/core/lib/Thelia/Constraint/ConstraintManager.php
+++ b/core/lib/Thelia/Constraint/ConstraintManager.php
@@ -23,6 +23,9 @@
namespace Thelia\Constraint;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Thelia\Constraint\Rule\CouponRuleInterface;
+use Thelia\Constraint\Rule\SerializableRule;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Coupon\CouponRuleCollection;
@@ -40,6 +43,9 @@ use Thelia\Coupon\CouponRuleCollection;
*/
class ConstraintManager
{
+ /** @var ContainerInterface Service Container */
+ protected $container = null;
+
/** @var CouponAdapterInterface Provide necessary value from Thelia*/
protected $adapter;
@@ -49,27 +55,28 @@ class ConstraintManager
/**
* Constructor
*
- * @param CouponAdapterInterface $adapter Provide necessary value from Thelia
- * @param CouponRuleCollection $rules Rules associated with the Constraint
+ * @param ContainerInterface $container Service container
*/
- function __construct(CouponAdapterInterface $adapter, CouponRuleCollection $rules)
+ function __construct(ContainerInterface $container)
{
- $this->adapter = $adapter;
- $this->rule = $rules;
+ $this->container = $container;
+ $this->adapter = $container->get('thelia.adapter');
}
/**
* Check if the current Coupon is matching its conditions (Rules)
* Thelia variables are given by the CouponAdapterInterface
*
+ * @param CouponRuleCollection $collection A collection of rules
+ *
* @return bool
*/
- public function isMatching()
+ public function isMatching(CouponRuleCollection $collection)
{
$isMatching = true;
/** @var CouponRuleInterface $rule */
- foreach ($this->rules->getRules() as $rule) {
+ foreach ($collection->getRules() as $rule) {
if (!$rule->isMatching($this->adapter)) {
$isMatching = false;
}
@@ -78,5 +85,53 @@ class ConstraintManager
return $isMatching;
}
+ /**
+ * Serialize a collection of rules
+ *
+ * @param CouponRuleCollection $collection A collection of rules
+ *
+ * @return string A ready to be stored Rule collection
+ */
+ public function serializeCouponRuleCollection(CouponRuleCollection $collection)
+ {
+ $serializableRules = array();
+ $rules = $collection->getRules();
+ if ($rules !== null) {
+ /** @var $rule CouponRuleInterface */
+ foreach ($rules as $rule) {
+ $serializableRules[] = $rule->getSerializableRule();
+ }
+ }
+ return (string) base64_encode(serialize($serializableRules));
+ }
+ /**
+ * Unserialize a collection of rules
+ *
+ * @param string $serializedRules Serialized Rules
+ *
+ * @return CouponRuleCollection Rules ready to be processed
+ */
+ public function unserializeCouponRuleCollection($serializedRules)
+ {
+ $unserializedRules = unserialize(base64_decode($serializedRules));
+ $collection = new CouponRuleCollection();
+
+ if (!empty($serializedRules) && !empty($unserializedRules)) {
+ /** @var SerializableRule $rule */
+ foreach ($unserializedRules as $rule) {
+ if ($this->container->has($rule->ruleServiceId)) {
+ /** @var CouponRuleInterface $couponRule */
+ $couponRule = $this->container->get($rule->ruleServiceId);
+ $couponRule->populateFromForm(
+ $rule->operators,
+ $rule->values
+ );
+ $collection->add($couponRule);
+ }
+ }
+ }
+
+ return $collection;
+ }
}
\ No newline at end of file
diff --git a/core/lib/Thelia/Constraint/Rule/AvailableForTotalAmount.php b/core/lib/Thelia/Constraint/Rule/AvailableForTotalAmount.php
index 7b4629b0f..58c19d8fd 100644
--- a/core/lib/Thelia/Constraint/Rule/AvailableForTotalAmount.php
+++ b/core/lib/Thelia/Constraint/Rule/AvailableForTotalAmount.php
@@ -62,30 +62,6 @@ class AvailableForTotalAmount extends CouponRuleAbstract
/** @var PriceParam Price Validator */
protected $priceValidator = null;
- /**
- * Constructor
- *
- * @param CouponAdapterInterface $adapter allowing to gather
- * all necessary Thelia variables
- * @param array $validators Array of RuleValidator
- * validating $paramsToValidate against
- *
- * @throws \Thelia\Exception\InvalidRuleException
- */
- public function __construct(CouponAdapterInterface $adapter, array $validators)
- {
- parent::__construct($adapter, $validators);
-
- if (isset($validators[self::PARAM1_PRICE])
- && $validators[self::PARAM1_PRICE] instanceof RuleValidator
- ) {
- $this->priceValidator = $validators[self::PARAM1_PRICE];
- } else {
- throw new InvalidRuleException(get_class());
- }
- }
-
-
/**
* Check if backoffice inputs are relevant or not
*
@@ -171,17 +147,6 @@ class AvailableForTotalAmount extends CouponRuleAbstract
return $this;
}
- /**
- * Return all validators
- * Serialization purpose
- *
- * @return array
- */
- public function getValidators()
- {
- return $this->validators;
- }
-
/**
* Get I18n name
*
@@ -203,13 +168,11 @@ class AvailableForTotalAmount extends CouponRuleAbstract
*/
public function getToolTip()
{
- /** @var Translator $translator */
- $translator = $this->get('thelia.translator');
$i18nOperator = Operators::getI18n(
- $translator, $this->priceValidator->getOperator()
+ $this->translator, $this->priceValidator->getOperator()
);
- $toolTip = $translator->trans(
+ $toolTip = $this->translator->trans(
'If cart total amount is %operator% %amount% %currency%',
array(
'%operator%' => $i18nOperator,
diff --git a/core/lib/Thelia/Constraint/Rule/AvailableForXArticles.php b/core/lib/Thelia/Constraint/Rule/AvailableForXArticles.php
index c60404218..95ea8e5b1 100644
--- a/core/lib/Thelia/Constraint/Rule/AvailableForXArticles.php
+++ b/core/lib/Thelia/Constraint/Rule/AvailableForXArticles.php
@@ -56,31 +56,6 @@ class AvailableForXArticles extends CouponRuleAbstract
/** @var QuantityParam Quantity Validator */
protected $quantityValidator = null;
- /**
- * Constructor
- *
- * @param CouponAdapterInterface $adapter allowing to gather
- * all necessary Thelia variables
- * @param array $validators Array of RuleValidator
- * validating $paramsToValidate against
- *
- * @throws InvalidRuleException
- */
- public function __construct(CouponAdapterInterface $adapter, array $validators = null)
- {
- parent::__construct($adapter, $validators);
-
- if (isset($validators[self::PARAM1_QUANTITY])
- && $validators[self::PARAM1_QUANTITY] instanceof RuleValidator
- ) {
- $this->quantityValidator = $validators[self::PARAM1_QUANTITY];
- } else {
- throw new InvalidRuleException(get_class());
- }
-
- $this->adapter = $adapter;
- }
-
/**
* Check if backoffice inputs are relevant or not
*
@@ -176,10 +151,7 @@ class AvailableForXArticles extends CouponRuleAbstract
*/
public function getName()
{
- /** @var Translator $translator */
- $translator = $this->adapter->get('thelia.translator');
-
- return $translator->trans(
+ return $this->translator->trans(
'Number of articles in cart',
array(),
'constraint'
@@ -193,14 +165,11 @@ class AvailableForXArticles extends CouponRuleAbstract
*/
public function getToolTip()
{
- /** @var Translator $translator */
- $translator = $this->adapter->get('thelia.translator');
-
$i18nOperator = Operators::getI18n(
- $translator, $this->priceValidator->getOperator()
+ $this->translator, $this->priceValidator->getOperator()
);
- $toolTip = $translator->trans(
+ $toolTip = $this->translator->trans(
'If cart products quantity is %operator% %quantity%',
array(
'%operator%' => $i18nOperator,
@@ -256,5 +225,4 @@ class AvailableForXArticles extends CouponRuleAbstract
return $serializableRule;
}
-
}
\ No newline at end of file
diff --git a/core/lib/Thelia/Constraint/Rule/CouponRuleAbstract.php b/core/lib/Thelia/Constraint/Rule/CouponRuleAbstract.php
index ff97ee3a0..ff8a26a8a 100644
--- a/core/lib/Thelia/Constraint/Rule/CouponRuleAbstract.php
+++ b/core/lib/Thelia/Constraint/Rule/CouponRuleAbstract.php
@@ -24,6 +24,7 @@
namespace Thelia\Constraint\Rule;
use Symfony\Component\Intl\Exception\NotImplementedException;
+use Symfony\Component\Translation\Translator;
use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Constraint\Validator\ComparableInterface;
use Thelia\Constraint\Validator\RuleValidator;
@@ -60,29 +61,17 @@ abstract class CouponRuleAbstract implements CouponRuleInterface
/** @var CouponAdapterInterface Provide necessary value from Thelia */
protected $adapter = null;
+ /** @var Translator Service Translator */
+ protected $translator = null;
+
/**
* Constructor
- * Ex:
- * Param 1 :
- * $priceValidator = new RuleValidator(
- * Operators::INFERIOR,
- * new IntegerParam(10)
- * )
- * $validators[AvailableForTotalAmount::PARAM1_PRICE] = $priceValidator
*
- * Param 2 :
- * $paramsToValidate[AvailableForTotalAmount::PARAM1_PRICE] = 9
- *
- * @param CouponAdapterInterface $adapter allowing to gather
- * all necessary Thelia variables
- * @param array $validators Array of RuleValidator
- * validating $paramsToValidate against
+ * @param Translator $translator Service translator
*/
- public function __construct(CouponAdapterInterface $adapter, array $validators)
+ function __construct(Translator $translator)
{
- $this->setValidators($validators);
- $this->adapter = $adapter;
- $this->setParametersToValidate($this->adapter);
+ $this->translator($translator);
}
/**
@@ -180,4 +169,15 @@ abstract class CouponRuleAbstract implements CouponRuleInterface
throw new \Thelia\Exception\NotImplementedException();
}
+ /**
+ * Return all validators
+ * Serialization purpose
+ *
+ * @return array
+ */
+ public function getValidators()
+ {
+ return $this->validators;
+ }
+
}
\ No newline at end of file
diff --git a/core/lib/Thelia/Constraint/Rule/CouponRuleInterface.php b/core/lib/Thelia/Constraint/Rule/CouponRuleInterface.php
index ce8e6c469..f2b9447e3 100644
--- a/core/lib/Thelia/Constraint/Rule/CouponRuleInterface.php
+++ b/core/lib/Thelia/Constraint/Rule/CouponRuleInterface.php
@@ -39,6 +39,13 @@ use Thelia\Coupon\CouponAdapterInterface;
*/
interface CouponRuleInterface
{
+ /**
+ * Constructor
+ *
+ * @param Translator $translator Service translator
+ */
+ function __construct(Translator $translator);
+
/**
* Check if backoffice inputs are relevant or not
*
diff --git a/core/lib/Thelia/Constraint/Rule/SerializableRule.php b/core/lib/Thelia/Constraint/Rule/SerializableRule.php
index 66caa793d..3cab5e70c 100644
--- a/core/lib/Thelia/Constraint/Rule/SerializableRule.php
+++ b/core/lib/Thelia/Constraint/Rule/SerializableRule.php
@@ -37,7 +37,7 @@ namespace Thelia\Constraint\Rule;
class SerializableRule
{
/** @var string Rule Service id */
- public $ruleClassName = null;
+ public $ruleServiceId = null;
/** @var array Operators set by Admin for this Rule */
public $operators = array();
diff --git a/core/lib/Thelia/Coupon/CouponFactory.php b/core/lib/Thelia/Coupon/CouponFactory.php
index 23f082974..3ff064601 100644
--- a/core/lib/Thelia/Coupon/CouponFactory.php
+++ b/core/lib/Thelia/Coupon/CouponFactory.php
@@ -137,7 +137,7 @@ class CouponFactory
// *
// * @return CouponRuleInterface Ready to use Rule or false
// */
-// public function buildCouponRuleFromForm($ruleClassName, $operator, array $values)
+// public function buildCouponRuleFromForm($ruleServiceId, $operator, array $values)
// {
// /** @var CouponAdapterInterface $adapter */
// $adapter = $this->container->get('thelia.adapter');
diff --git a/core/lib/Thelia/Coupon/CouponManager.php b/core/lib/Thelia/Coupon/CouponManager.php
index ad351081c..ee20b4fd0 100644
--- a/core/lib/Thelia/Coupon/CouponManager.php
+++ b/core/lib/Thelia/Coupon/CouponManager.php
@@ -52,7 +52,7 @@ class CouponManager
/**
* Constructor
*
- * @param ContainerInterface $container Service container
+ * @param ContainerInterface $container Service container
*/
function __construct(ContainerInterface $container)
{
diff --git a/core/lib/Thelia/Coupon/CouponRuleCollection.php b/core/lib/Thelia/Coupon/CouponRuleCollection.php
index 2f1a51dc0..93db32beb 100644
--- a/core/lib/Thelia/Coupon/CouponRuleCollection.php
+++ b/core/lib/Thelia/Coupon/CouponRuleCollection.php
@@ -23,9 +23,9 @@
namespace Thelia\Coupon;
-use Symfony\Component\Serializer\Encoder\JsonEncoder;
+use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\Constraint\Rule\CouponRuleInterface;
-use Thelia\Exception\InvalidRuleException;
+use Thelia\Constraint\Rule\SerializableRule;
/**
* Created by JetBrains PhpStorm.
@@ -45,19 +45,10 @@ class CouponRuleCollection
/**
* Constructor
- *
- * @param array $rules Array of CouponRuleInterface
- *
- * @throws \Thelia\Exception\InvalidRuleException
*/
- function __construct(array $rules)
+ function __construct()
{
- foreach ($rules as $rule) {
- if (!$rule instanceof CouponRuleInterface) {
- throw new InvalidRuleException(get_class());
- }
- }
- $this->rules = $rules;
+
}
/**
diff --git a/core/lib/Thelia/Model/Coupon.php b/core/lib/Thelia/Model/Coupon.php
index 03a59b8e9..f5788ff4f 100755
--- a/core/lib/Thelia/Model/Coupon.php
+++ b/core/lib/Thelia/Model/Coupon.php
@@ -24,6 +24,7 @@
namespace Thelia\Model;
use Propel\Runtime\Propel;
+use Thelia\Constraint\Rule\CouponRuleInterface;
use Thelia\Coupon\CouponRuleCollection;
use Thelia\Model\Base\Coupon as BaseCoupon;
use Thelia\Model\Map\CouponTableMap;
@@ -98,37 +99,34 @@ class Coupon extends BaseCoupon
}
}
- /**
- * Set the value of [serialized_rules] column.
- *
- * @param CouponRuleCollection $rules A set of Rules
- *
- * @return \Thelia\Model\Coupon The current object (for fluent API support)
- */
- public function setRules(CouponRuleCollection $rules)
- {
- $serializedRules = null;
- if ($rules !== null) {
-
- $serializedRules = (string) base64_encode(serialize($rules));
- }
-
- if ($this->serialized_rules !== $serializedRules) {
- $this->serialized_rules = $serializedRules;
- $this->modifiedColumns[] = CouponTableMap::SERIALIZED_RULES;
- }
-
- return $this;
- }
+// /**
+// * Set the value of [serialized_rules] column.
+// * Convert a CouponRuleCollection into a serialized array of SerializableRule
+// *
+// * @param CouponRuleCollection $rules A set of Rules
+// *
+// * @return \Thelia\Model\Coupon The current object (for fluent API support)
+// */
+// public function setRules(CouponRuleCollection $rules)
+// {
+// $serializedRules = null;
+// if ($rules !== null) {
+// /** @var $rule CouponRuleInterface */
+// foreach ($rules->getRules() as $rule) {
+// $serializedRules[] = $rule->getSerializableRule();
+// }
+//
+// $serializedRules = (string) base64_encode(serialize($serializedRules));
+// }
+//
+// if ($this->serialized_rules !== $serializedRules) {
+// $this->serialized_rules = $serializedRules;
+// $this->modifiedColumns[] = CouponTableMap::SERIALIZED_RULES;
+// }
+//
+// return $this;
+// }
+
- /**
- * Get the [serialized_rules] column value.
- *
- * @return CouponRuleCollection Rules ready to be processed
- */
- public function getRules()
- {
- return unserialize(base64_decode($this->serialized_rules));
- }
}
diff --git a/core/lib/Thelia/Tests/Constraint/ConstraintManagerTest.php b/core/lib/Thelia/Tests/Constraint/ConstraintManagerTest.php
index 08389ef9e..5d0be5711 100644
--- a/core/lib/Thelia/Tests/Constraint/ConstraintManagerTest.php
+++ b/core/lib/Thelia/Tests/Constraint/ConstraintManagerTest.php
@@ -23,6 +23,8 @@
namespace Thelia\Constraint;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Thelia\Constraint\Rule\AvailableForXArticles;
use Thelia\Constraint\Validator\PriceParam;
use Thelia\Constraint\Validator\RuleValidator;
use Thelia\Constraint\Rule\AvailableForTotalAmount;
@@ -50,12 +52,10 @@ class ConstraintManagerTest extends \PHPUnit_Framework_TestCase
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
- protected function setUp()
+ public function setUp()
{
}
-
-
public function incompleteTest()
{
$this->markTestIncomplete(
@@ -63,6 +63,62 @@ class ConstraintManagerTest extends \PHPUnit_Framework_TestCase
);
}
+ /**
+ * Check the Rules serialization module
+ */
+ public function testRuleSerialisation()
+ {
+ $translator = $this->getMock('\Thelia\Core\Translation\Translator');
+
+ $rule1 = new AvailableForTotalAmount($translator);
+ $operators = array(AvailableForTotalAmount::PARAM1_PRICE => Operators::SUPERIOR);
+ $values = array(
+ AvailableForTotalAmount::PARAM1_PRICE => 40.00,
+ AvailableForTotalAmount::PARAM1_CURRENCY => 'EUR'
+ );
+ $rule1->populateFromForm($operators, $values);
+
+ $rule2 = new AvailableForTotalAmount($translator);
+ $operators = array(AvailableForTotalAmount::PARAM1_PRICE => Operators::INFERIOR);
+ $values = array(
+ AvailableForTotalAmount::PARAM1_PRICE => 400.00,
+ AvailableForTotalAmount::PARAM1_CURRENCY => 'EUR'
+ );
+ $rule2->populateFromForm($operators, $values);
+
+ $rules = new CouponRuleCollection(array($rule1, $rule2));
+
+ /** @var ConstraintManager $constraintManager */
+ $constraintManager = new ConstraintManager($this->getContainer());
+
+ $serializedRules = $constraintManager->serializeCouponRuleCollection($rules);
+ $unserializedRules = $constraintManager->unserializeCouponRuleCollection($serializedRules);
+
+ $expected = $rules;
+ $actual = $unserializedRules;
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Get Mocked Container with 2 Rules
+ *
+ * @return ContainerBuilder
+ */
+ public function getContainer()
+ {
+ $container = new ContainerBuilder();
+
+ $translator = $this->getMock('\Thelia\Core\Translation\Translator');
+ $rule1 = new AvailableForTotalAmount($translator);
+ $rule2 = new AvailableForXArticles($translator);
+
+ $container->set('thelia.constraint.rule.available_for_total_amount', $rule1);
+ $container->set('thelia.constraint.rule.available_for_x_articles', $rule2);
+
+ return $container;
+ }
+
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.