diff --git a/README.md b/README.md
index 07535c9..1f3b66e 100644
--- a/README.md
+++ b/README.md
@@ -94,6 +94,12 @@ Rule is based on [regular expression](https://en.wikipedia.org/wiki/Regular_expr
#### Negated RegEx
Based on the RegEx strategy, but negates the result. Helpful if only a few pages should be restricted.
+### Add custom strategy
+
+The strategy configuration is meant to be extensible. You can create an own strategy by creating a new class that
+implements the `\BitExpert\SyliusForceCustomerLoginPlugin\Model\StrategyInterface` interface and is tagged with
+`force_customer_login.url_strategy` in your service configuration.
+
## Tests
You can run the unit tests with the following command (requires dependency installation):
diff --git a/src/BitExpertSyliusForceCustomerLoginPlugin.php b/src/BitExpertSyliusForceCustomerLoginPlugin.php
index a9f5026..06a8b85 100644
--- a/src/BitExpertSyliusForceCustomerLoginPlugin.php
+++ b/src/BitExpertSyliusForceCustomerLoginPlugin.php
@@ -12,9 +12,12 @@
namespace BitExpert\SyliusForceCustomerLoginPlugin;
+use BitExpert\SyliusForceCustomerLoginPlugin\DependencyInjection\Compiler\RegisterDoctrineMiddlewareCompilerPass;
+use BitExpert\SyliusForceCustomerLoginPlugin\DependencyInjection\Compiler\RegisterDoctrineTypeCompilerPass;
use Sylius\Bundle\CoreBundle\Application\SyliusPluginTrait;
use Sylius\Bundle\ResourceBundle\AbstractResourceBundle;
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
final class BitExpertSyliusForceCustomerLoginPlugin extends AbstractResourceBundle
{
@@ -26,4 +29,12 @@ public function getSupportedDrivers(): array
SyliusResourceBundle::DRIVER_DOCTRINE_ORM,
];
}
+
+ public function build(ContainerBuilder $container): void
+ {
+ parent::build($container);
+
+ $container->addCompilerPass(new RegisterDoctrineTypeCompilerPass());
+ $container->addCompilerPass(new RegisterDoctrineMiddlewareCompilerPass());
+ }
}
diff --git a/src/DependencyInjection/Compiler/RegisterDoctrineMiddlewareCompilerPass.php b/src/DependencyInjection/Compiler/RegisterDoctrineMiddlewareCompilerPass.php
new file mode 100644
index 0000000..aee4556
--- /dev/null
+++ b/src/DependencyInjection/Compiler/RegisterDoctrineMiddlewareCompilerPass.php
@@ -0,0 +1,51 @@
+getDefinition('doctrine.dbal.default_connection.configuration');
+
+ $middlewareMethodCallArgs = $this->extractMethodCallArgs($configDefinition);
+ $middlewareMethodCallArgs[0] = array_merge(
+ $middlewareMethodCallArgs[0] ?? [],
+ [new Reference('bitexpert.sylius_force_customer_login_plugin.doctrine.middleware')],
+ );
+
+ $configDefinition
+ ->removeMethodCall('setMiddlewares')
+ ->addMethodCall('setMiddlewares', $middlewareMethodCallArgs);
+ }
+
+ /** @return Reference[] */
+ private function extractMethodCallArgs(Definition $definition): array
+ {
+ foreach ($definition->getMethodCalls() as $methodCall) {
+ if ('setMiddlewares' === $methodCall[0]) {
+ return $methodCall[1];
+ }
+ }
+
+ return [];
+ }
+}
diff --git a/src/DependencyInjection/Compiler/RegisterDoctrineTypeCompilerPass.php b/src/DependencyInjection/Compiler/RegisterDoctrineTypeCompilerPass.php
new file mode 100644
index 0000000..1355586
--- /dev/null
+++ b/src/DependencyInjection/Compiler/RegisterDoctrineTypeCompilerPass.php
@@ -0,0 +1,39 @@
+hasParameter(self::CONTAINER_TYPES_PARAMETER)) {
+ return;
+ }
+
+ $typeDefinition = $container->getParameter(self::CONTAINER_TYPES_PARAMETER);
+ if (!isset($typeDefinition[Strategy::NAME])) {
+ $typeDefinition[Strategy::NAME] = ['class' => Strategy::class];
+ }
+
+ $container->setParameter(self::CONTAINER_TYPES_PARAMETER, $typeDefinition);
+ }
+}
diff --git a/src/Doctrine/DBAL/Types/Strategy.php b/src/Doctrine/DBAL/Types/Strategy.php
new file mode 100644
index 0000000..56db439
--- /dev/null
+++ b/src/Doctrine/DBAL/Types/Strategy.php
@@ -0,0 +1,65 @@
+strategies = $strategies;
+ }
+
+ public function getSQLDeclaration(array $column, AbstractPlatform $platform)
+ {
+ return $platform->getStringTypeDeclarationSQL($column);
+ }
+
+ public function convertToPHPValue($value, AbstractPlatform $platform)
+ {
+ if (!is_string($value)) {
+ return parent::convertToPHPValue($value, $platform);
+ }
+
+ if (isset($this->strategies[$value])) {
+ return $this->strategies[$value];
+ }
+
+ throw new \RuntimeException(sprintf('Unsupported strategy "%s"!', $value));
+ }
+
+ public function convertToDatabaseValue($value, AbstractPlatform $platform)
+ {
+ if (!($value instanceof StrategyInterface)) {
+ return parent::convertToDatabaseValue($value, $platform);
+ }
+
+ return $value->getType();
+ }
+}
diff --git a/src/Doctrine/StrategyTypeConfigurationMiddleware.php b/src/Doctrine/StrategyTypeConfigurationMiddleware.php
new file mode 100644
index 0000000..59e1595
--- /dev/null
+++ b/src/Doctrine/StrategyTypeConfigurationMiddleware.php
@@ -0,0 +1,48 @@
+strategies as $strategy) {
+ /** @var StrategyInterface $strategy */
+ $strategies[$strategy->getType()] = $strategy;
+ }
+
+ try {
+ /** @var Strategy $type */
+ $type = Type::getType(Strategy::NAME);
+ $type->setStrategies($strategies);
+ } catch (\Exception $e) {
+ }
+
+ return $driver;
+ }
+}
diff --git a/src/Form/Type/WhitelistEntryType.php b/src/Form/Type/WhitelistEntryType.php
index aea4e6a..90258bf 100644
--- a/src/Form/Type/WhitelistEntryType.php
+++ b/src/Form/Type/WhitelistEntryType.php
@@ -12,20 +12,35 @@
namespace BitExpert\SyliusForceCustomerLoginPlugin\Form\Type;
-use BitExpert\SyliusForceCustomerLoginPlugin\Model\NegatedRegexMatcher;
-use BitExpert\SyliusForceCustomerLoginPlugin\Model\RegexMatcher;
-use BitExpert\SyliusForceCustomerLoginPlugin\Model\StaticMatcher;
use BitExpert\SyliusForceCustomerLoginPlugin\Model\StrategyInterface;
use Sylius\Bundle\ChannelBundle\Form\Type\ChannelChoiceType;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
+use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class WhitelistEntryType extends AbstractResourceType
{
+ /**
+ * @param RewindableGenerator $strategies
+ */
+ public function __construct(
+ private readonly iterable $strategies,
+ string $dataClass,
+ array $validationGroups = [],
+ ) {
+ parent::__construct($dataClass, $validationGroups);
+ }
+
public function buildForm(FormBuilderInterface $builder, array $options): void
{
+ $strategies = [];
+ foreach ($this->strategies as $strategy) {
+ /** @var StrategyInterface $strategy */
+ $strategies[] = $strategy;
+ }
+
$builder
->add('channels', ChannelChoiceType::class, [
'multiple' => true,
@@ -41,11 +56,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'empty_data' => '',
])
->add('strategy', ChoiceType::class, [
- 'choices' => [
- new StaticMatcher(),
- new RegexMatcher(),
- new NegatedRegexMatcher(),
- ],
+ 'choices' => $strategies,
'choice_value' => 'name',
'choice_label' => function (?StrategyInterface $strategy): string {
return is_object($strategy) ? $strategy->getName() : '';
diff --git a/src/Model/WhitelistEntry.php b/src/Model/WhitelistEntry.php
index 86c5a31..84084b4 100644
--- a/src/Model/WhitelistEntry.php
+++ b/src/Model/WhitelistEntry.php
@@ -27,7 +27,7 @@ class WhitelistEntry implements WhitelistEntryInterface
private string $urlRule;
- private string $strategy;
+ private StrategyInterface $strategy;
public function __construct()
{
@@ -85,27 +85,11 @@ public function setUrlRule(string $urlRule): void
public function getStrategy(): StrategyInterface
{
- $staticMatcher = new StaticMatcher();
- $regexMatcher = new RegexMatcher();
- $negatedRegexMatcher = new NegatedRegexMatcher();
-
- if ($this->strategy === $staticMatcher->getType()) {
- return $staticMatcher;
- }
-
- if ($this->strategy === $regexMatcher->getType()) {
- return $regexMatcher;
- }
-
- if ($this->strategy === $negatedRegexMatcher->getType()) {
- return $negatedRegexMatcher;
- }
-
- throw new \RuntimeException('Unsupported strategy!');
+ return $this->strategy;
}
public function setStrategy(StrategyInterface $strategy): void
{
- $this->strategy = $strategy->getType();
+ $this->strategy = $strategy;
}
}
diff --git a/src/Resources/config/doctrine/model/WhitelistEntry.orm.xml b/src/Resources/config/doctrine/model/WhitelistEntry.orm.xml
index ff1263b..bffbf3c 100644
--- a/src/Resources/config/doctrine/model/WhitelistEntry.orm.xml
+++ b/src/Resources/config/doctrine/model/WhitelistEntry.orm.xml
@@ -24,6 +24,6 @@
-
+
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index a3a2347..0732ce7 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -1,10 +1,11 @@
-
+
+
diff --git a/src/Resources/config/services/doctrine.xml b/src/Resources/config/services/doctrine.xml
new file mode 100644
index 0000000..a79d3a6
--- /dev/null
+++ b/src/Resources/config/services/doctrine.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Resources/config/services/form.xml b/src/Resources/config/services/form.xml
index 59aaa8e..0c30b48 100644
--- a/src/Resources/config/services/form.xml
+++ b/src/Resources/config/services/form.xml
@@ -5,6 +5,7 @@
+
BitExpert\SyliusForceCustomerLoginPlugin\Model\WhitelistEntry
diff --git a/src/Resources/config/services/strategies.xml b/src/Resources/config/services/strategies.xml
new file mode 100644
index 0000000..7d25eb5
--- /dev/null
+++ b/src/Resources/config/services/strategies.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+