Skip to content

Commit beb77bd

Browse files
committed
Migrating rules to new 'architecture'
1 parent 69b13f1 commit beb77bd

22 files changed

+163
-379
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule;
6+
7+
use Sylius\Component\Core\Model\ProductInterface;
8+
use Webmozart\Assert\Assert;
9+
10+
final class ContainsProductRuleChecker implements RuleCheckerInterface
11+
{
12+
public const TYPE = 'contains_product';
13+
14+
public function isEligible(ProductInterface $product, array $configuration): bool
15+
{
16+
Assert::keyExists($configuration, 'product');
17+
Assert::stringNotEmpty($configuration['product']);
18+
19+
return $configuration['product'] === $product->getCode();
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule;
6+
7+
use Sylius\Component\Core\Model\ProductInterface;
8+
use Webmozart\Assert\Assert;
9+
10+
final class ContainsProductsRuleChecker implements RuleCheckerInterface
11+
{
12+
public const TYPE = 'contains_products';
13+
14+
public function isEligible(ProductInterface $product, array $configuration): bool
15+
{
16+
Assert::keyExists($configuration, 'products');
17+
Assert::isArray($configuration['products']);
18+
Assert::allStringNotEmpty($configuration['products']);
19+
20+
return in_array($product->getCode(), $configuration['products'], true);
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule;
6+
7+
use Sylius\Component\Core\Model\ProductInterface;
8+
use Webmozart\Assert\Assert;
9+
10+
final class HasNotTaxonRuleChecker implements RuleCheckerInterface
11+
{
12+
public const TYPE = 'has_not_taxon';
13+
14+
public function isEligible(ProductInterface $product, array $configuration): bool
15+
{
16+
Assert::keyExists($configuration, 'taxons');
17+
Assert::isArray($configuration['taxons']);
18+
Assert::allStringNotEmpty($configuration['taxons']);
19+
20+
foreach ($product->getTaxons() as $taxon) {
21+
if (in_array($taxon->getCode(), $configuration['taxons'], true)) {
22+
return false;
23+
}
24+
}
25+
26+
return !in_array($product->getMainTaxon()?->getCode(), $configuration['taxons'], true);
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule;
6+
7+
use Sylius\Component\Core\Model\ProductInterface;
8+
use Webmozart\Assert\Assert;
9+
10+
final class HasTaxonRuleChecker implements RuleCheckerInterface
11+
{
12+
public const TYPE = 'has_taxon';
13+
14+
public function isEligible(ProductInterface $product, array $configuration): bool
15+
{
16+
Assert::keyExists($configuration, 'taxons');
17+
Assert::isArray($configuration['taxons']);
18+
Assert::allStringNotEmpty($configuration['taxons']);
19+
20+
foreach ($product->getTaxons() as $taxon) {
21+
if (in_array($taxon->getCode(), $configuration['taxons'], true)) {
22+
return true;
23+
}
24+
}
25+
26+
return in_array($product->getMainTaxon()?->getCode(), $configuration['taxons'], true);
27+
}
28+
}

src/Checker/PreQualification/Rule/RuleCheckerInterface.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?php
2+
23
declare(strict_types=1);
34

45
namespace Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule;
56

6-
77
use Sylius\Component\Core\Model\ProductInterface;
88

99
interface RuleCheckerInterface

src/DependencyInjection/Compiler/RegisterRulesPass.php src/DependencyInjection/Compiler/RegisterRulesAndRuleCheckersPass.php

+11-9
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,30 @@
1010
use Symfony\Component\DependencyInjection\Reference;
1111
use Webmozart\Assert\Assert;
1212

13-
final class RegisterRulesPass implements CompilerPassInterface
13+
final class RegisterRulesAndRuleCheckersPass implements CompilerPassInterface
1414
{
1515
public function process(ContainerBuilder $container): void
1616
{
17-
$registry = $container->getDefinition('setono_sylius_catalog_promotion.registry.rule');
17+
$registry = $container->getDefinition('setono_sylius_catalog_promotion.registry.rule_checker');
1818
$formRegistry = $container->getDefinition('setono_sylius_catalog_promotion.form_registry.rule');
19+
20+
/** @var array<string, string> $formToLabelMap */
1921
$formToLabelMap = [];
2022

2123
/**
2224
* @var string $id
23-
* @var array $tagged
25+
* @var array $tags
2426
*/
25-
foreach ($container->findTaggedServiceIds('setono_sylius_catalog_promotion.rule') as $id => $tagged) {
27+
foreach ($container->findTaggedServiceIds('setono_sylius_catalog_promotion.rule_checker') as $id => $tags) {
2628
/** @var array $attributes */
27-
foreach ($tagged as $attributes) {
29+
foreach ($tags as $attributes) {
2830
if (!isset($attributes['type'], $attributes['label'], $attributes['form_type'])) {
29-
throw new InvalidArgumentException('Tagged rule `' . $id . '` needs to have `type`, `form_type` and `label` attributes.');
31+
throw new InvalidArgumentException('Tagged rule checker `' . $id . '` needs to have `type`, `form_type` and `label` attributes.');
3032
}
3133

32-
Assert::string($attributes['type']);
33-
Assert::string($attributes['label']);
34-
Assert::string($attributes['form_type']);
34+
Assert::stringNotEmpty($attributes['type']);
35+
Assert::stringNotEmpty($attributes['label']);
36+
Assert::stringNotEmpty($attributes['form_type']);
3537

3638
$formToLabelMap[$attributes['type']] = $attributes['label'];
3739
$registry->addMethodCall('register', [$attributes['type'], new Reference($id)]);

src/DependencyInjection/SetonoSyliusCatalogPromotionExtension.php

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Setono\SyliusCatalogPromotionPlugin\DependencyInjection;
66

7+
use Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule\RuleCheckerInterface;
78
use Setono\SyliusCatalogPromotionPlugin\Checker\Runtime\RuntimeCheckerInterface;
89
use Sylius\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractResourceExtension;
910
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
@@ -26,6 +27,7 @@ public function load(array $configs, ContainerBuilder $container): void
2627
$loader->load('services.xml');
2728

2829
$container->registerForAutoconfiguration(RuntimeCheckerInterface::class)->addTag('setono_sylius_catalog_promotion.runtime_checker');
30+
$container->registerForAutoconfiguration(RuleCheckerInterface::class)->addTag('setono_sylius_catalog_promotion.rule_checker');
2931

3032
$this->registerResources('setono_sylius_catalog_promotion', SyliusResourceBundle::DRIVER_DOCTRINE_ORM, $config['resources'], $container);
3133
}

src/Factory/PromotionRuleFactory.php

+15-24
Original file line numberDiff line numberDiff line change
@@ -5,56 +5,47 @@
55
namespace Setono\SyliusCatalogPromotionPlugin\Factory;
66

77
use InvalidArgumentException;
8+
use Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule\ContainsProductRuleChecker;
9+
use Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule\ContainsProductsRuleChecker;
10+
use Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule\HasNotTaxonRuleChecker;
11+
use Setono\SyliusCatalogPromotionPlugin\Checker\PreQualification\Rule\HasTaxonRuleChecker;
812
use Setono\SyliusCatalogPromotionPlugin\Model\PromotionRuleInterface;
9-
use Setono\SyliusCatalogPromotionPlugin\Rule\ContainsProductRule;
10-
use Setono\SyliusCatalogPromotionPlugin\Rule\ContainsProductsRule;
11-
use Setono\SyliusCatalogPromotionPlugin\Rule\HasNotTaxonRule;
12-
use Setono\SyliusCatalogPromotionPlugin\Rule\HasTaxonRule;
13-
use function sprintf;
1413
use Sylius\Component\Resource\Factory\FactoryInterface;
1514
use Webmozart\Assert\Assert;
1615

1716
final class PromotionRuleFactory implements PromotionRuleFactoryInterface
1817
{
19-
private FactoryInterface $decoratedFactory;
20-
21-
private array $rules;
22-
23-
public function __construct(
24-
FactoryInterface $decoratedFactory,
25-
array $rules,
26-
) {
27-
$this->decoratedFactory = $decoratedFactory;
28-
$this->rules = $rules;
18+
public function __construct(private readonly FactoryInterface $decoratedFactory, private readonly array $rules)
19+
{
2920
}
3021

3122
public function createNew(): PromotionRuleInterface
3223
{
33-
/** @var PromotionRuleInterface $obj */
3424
$obj = $this->decoratedFactory->createNew();
25+
Assert::isInstanceOf($obj, PromotionRuleInterface::class);
3526

3627
return $obj;
3728
}
3829

3930
public function createByType(string $type, array $configuration, bool $strict = false): PromotionRuleInterface
4031
{
4132
switch ($type) {
42-
case HasTaxonRule::TYPE:
33+
case HasTaxonRuleChecker::TYPE:
4334
Assert::keyExists($configuration, 'taxons');
4435
Assert::isArray($configuration['taxons']);
4536

4637
return $this->createHasTaxon($configuration['taxons']);
47-
case HasNotTaxonRule::TYPE:
38+
case HasNotTaxonRuleChecker::TYPE:
4839
Assert::keyExists($configuration, 'taxons');
4940
Assert::isArray($configuration['taxons']);
5041

5142
return $this->createHasNotTaxon($configuration['taxons']);
52-
case ContainsProductRule::TYPE:
43+
case ContainsProductRuleChecker::TYPE:
5344
Assert::keyExists($configuration, 'product');
5445
Assert::string($configuration['product']);
5546

5647
return $this->createContainsProduct($configuration['product']);
57-
case ContainsProductsRule::TYPE:
48+
case ContainsProductsRuleChecker::TYPE:
5849
Assert::keyExists($configuration, 'products');
5950
Assert::isArray($configuration['products']);
6051

@@ -76,7 +67,7 @@ public function createHasTaxon(array $taxonCodes): PromotionRuleInterface
7667
Assert::allString($taxonCodes);
7768

7869
return $this->createPromotionRule(
79-
HasTaxonRule::TYPE,
70+
HasTaxonRuleChecker::TYPE,
8071
['taxons' => $taxonCodes],
8172
);
8273
}
@@ -86,15 +77,15 @@ public function createHasNotTaxon(array $taxonCodes): PromotionRuleInterface
8677
Assert::allString($taxonCodes);
8778

8879
return $this->createPromotionRule(
89-
HasNotTaxonRule::TYPE,
80+
HasNotTaxonRuleChecker::TYPE,
9081
['taxons' => $taxonCodes],
9182
);
9283
}
9384

9485
public function createContainsProduct(string $productCode): PromotionRuleInterface
9586
{
9687
return $this->createPromotionRule(
97-
ContainsProductRule::TYPE,
88+
ContainsProductRuleChecker::TYPE,
9889
['product' => $productCode],
9990
);
10091
}
@@ -104,7 +95,7 @@ public function createContainsProducts(array $productCodes): PromotionRuleInterf
10495
Assert::allString($productCodes);
10596

10697
return $this->createPromotionRule(
107-
ContainsProductsRule::TYPE,
98+
ContainsProductsRuleChecker::TYPE,
10899
['products' => $productCodes],
109100
);
110101
}

src/Registry/RuleServiceRegistry.php

-19
This file was deleted.

src/Resources/config/services/applicator.xml

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
xmlns="http://symfony.com/schema/dic/services"
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66
<services>
7+
<service id="Setono\SyliusCatalogPromotionPlugin\Applicator\RuntimePromotionsApplicatorInterface"
8+
alias="Setono\SyliusCatalogPromotionPlugin\Applicator\RuntimePromotionsApplicator"/>
9+
710
<service id="Setono\SyliusCatalogPromotionPlugin\Applicator\RuntimePromotionsApplicator">
811
<argument type="service" id="setono_sylius_catalog_promotion.repository.promotion"/>
912
<argument type="service" id="Setono\SyliusCatalogPromotionPlugin\Checker\Runtime\RuntimeCheckerInterface"/>

src/Resources/config/services/calculator.xml

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@
44
xmlns="http://symfony.com/schema/dic/services"
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66
<services>
7-
<service id="Setono\SyliusCatalogPromotionPlugin\Calculator\ProductVariantPricesCalculator"
8-
decorates="sylius.calculator.product_variant_price"
9-
decoration-priority="64">
10-
<argument type="service" id="Setono\SyliusCatalogPromotionPlugin\Calculator\ProductVariantPricesCalculator.inner"/>
11-
<argument type="service" id="setono_sylius_catalog_promotion.repository.promotion"/>
7+
<service id="Setono\SyliusCatalogPromotionPlugin\Calculator\ProductVariantPricesCalculator">
8+
<argument type="service" id="Setono\SyliusCatalogPromotionPlugin\Applicator\RuntimePromotionsApplicatorInterface"/>
129
</service>
1310
</services>
1411
</container>

src/Resources/config/services/form.xml

+16-15
Original file line numberDiff line numberDiff line change
@@ -17,56 +17,57 @@
1717
<service id="setono_sylius_catalog_promotion.form_registry.rule"
1818
class="Sylius\Bundle\ResourceBundle\Form\Registry\FormTypeRegistry"/>
1919

20-
<service id="setono_sylius_catalog_promotion.form.type.promotion"
21-
class="Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionType">
20+
<service id="Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionType">
2221
<argument>%setono_sylius_catalog_promotion.model.promotion.class%</argument>
2322
<argument>%setono_sylius_catalog_promotion.form.type.promotion.validation_groups%</argument>
23+
2424
<tag name="form.type"/>
2525
</service>
2626

27-
<service id="setono_sylius_catalog_promotion.form.type.promotion_rule"
28-
class="Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionRuleType">
27+
<service id="Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionRuleType">
2928
<argument type="service" id="setono_sylius_catalog_promotion.form_registry.rule"/>
3029
<argument>%setono_sylius_catalog_promotion.model.promotion_rule.class%</argument>
3130
<argument>%setono_sylius_catalog_promotion.form.type.promotion_rule.validation_groups%</argument>
3231

3332
<tag name="form.type"/>
3433
</service>
3534

36-
<service id="setono_sylius_catalog_promotion.form.type.promotion_rule.collection"
37-
class="Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionRuleCollectionType">
38-
<argument type="service" id="setono_sylius_catalog_promotion.registry.rule"/>
35+
<service id="Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionRuleCollectionType">
36+
<argument type="service" id="setono_sylius_catalog_promotion.registry.rule_checker"/>
37+
3938
<tag name="form.type"/>
4039
</service>
4140

42-
<service id="setono_sylius_catalog_promotion.form.type.promotion_rule_choice"
43-
class="Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionRuleChoiceType">
41+
<service id="Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionRuleChoiceType">
4442
<argument>%setono_sylius_catalog_promotion.promotion_rules%</argument>
43+
4544
<tag name="form.type"/>
4645
</service>
4746

4847
<!-- Rules -->
48+
<!-- TODO: Delete this and use Sylius' instead. Do the same for other configuration types that are the same -->
4949
<service id="setono_sylius_catalog_promotion.form.type.promotion_rule.has_taxon_configuration"
5050
class="Setono\SyliusCatalogPromotionPlugin\Form\Type\Rule\HasTaxonConfigurationType">
5151
<argument type="service" id="sylius.form.type.data_transformer.taxons_to_codes"/>
52+
5253
<tag name="form.type"/>
5354
</service>
5455

55-
<service id="setono_sylius_catalog_promotion.form.type.promotion_rule.has_not_taxon_configuration"
56-
class="Setono\SyliusCatalogPromotionPlugin\Form\Type\Rule\HasNotTaxonConfigurationType">
56+
<service id="Setono\SyliusCatalogPromotionPlugin\Form\Type\Rule\HasNotTaxonConfigurationType">
5757
<argument type="service" id="sylius.form.type.data_transformer.taxons_to_codes"/>
58+
5859
<tag name="form.type"/>
5960
</service>
6061

61-
<service id="setono_sylius_catalog_promotion.form.type.promotion_rule.contains_products_configuration"
62-
class="Setono\SyliusCatalogPromotionPlugin\Form\Type\Rule\ContainsProductsConfigurationType">
62+
<service id="Setono\SyliusCatalogPromotionPlugin\Form\Type\Rule\ContainsProductsConfigurationType">
6363
<argument type="service" id="sylius.form.type.data_transformer.products_to_codes"/>
64+
6465
<tag name="form.type"/>
6566
</service>
6667

67-
<service id="setono_sylius_catalog_promotion.form.type.promotion_rule.contains_product_configuration"
68-
class="Setono\SyliusCatalogPromotionPlugin\Form\Type\Rule\ContainsProductConfigurationType">
68+
<service id="Setono\SyliusCatalogPromotionPlugin\Form\Type\Rule\ContainsProductConfigurationType">
6969
<argument type="service" id="sylius.repository.product"/>
70+
7071
<tag name="form.type"/>
7172
</service>
7273
</services>

0 commit comments

Comments
 (0)