Repository: pheature-flags/pheature-flags (php)

Issue:
[Symfony-toggle] Create FeatureRepository Compiler pass
**Epic:** https://github.com/pheature-flags/pheature-flags/issues/97 Symfony Toggle
**Package:** https://github.com/pheature-flags/symfony-toggle 

**Description:**

Create FeatureRepository Compiler pass from existing PheatureFlagsExtension. And include the compiler pass in the extension class.

```php
<?php


        $repository = $container->register(FeatureRepository::class, FeatureRepository::class)
            ->setAutowired(false)
            ->setLazy(true)
            ->setFactory([FeatureRepositoryFactory::class, 'create']);
 
```

Pull request:
[#174] create feature repository compiler pass
Closed #174 

Patch:
diff --git a/packages/symfony-toggle/composer.json b/packages/symfony-toggle/composer.json
index e0885dd..83987f0 100644
--- a/packages/symfony-toggle/composer.json
+++ b/packages/symfony-toggle/composer.json
@@ -21,8 +21,9 @@
         "symfony/framework-bundle": "~5.0"
     },
     "require-dev": {
-        "doctrine/dbal": ">=2.5 || ^3.0.0",
+        "doctrine/dbal": "^3.1",
         "infection/infection": "^0.21.0",
+        "pheature/dbal-toggle": "@dev",
         "pheature/inmemory-toggle": "@dev",
         "pheature/toggle-crud": "@dev",
         "pheature/toggle-crud-psr7-api": "@dev",
diff --git a/packages/symfony-toggle/config/dbal_config.yaml b/packages/symfony-toggle/config/dbal_config.yaml
new file mode 100644
index 0000000..444f452
--- /dev/null
+++ b/packages/symfony-toggle/config/dbal_config.yaml
@@ -0,0 +1,8 @@
+pheature_flags:
+  driver: dbal
+  segment_types:
+    - { type: 'identity_segment', factory_id: 'Pheature\Model\Toggle\SegmentFactory' }
+    - { type: 'strict_matching_segment', factory_id: 'Pheature\Model\Toggle\SegmentFactory' }
+  strategy_types:
+    - { type: 'enable_by_matching_segment', factory_id: 'Pheature\Model\Toggle\StrategyFactory' }
+    - { type: 'enable_by_matching_identity_id', factory_id: 'Pheature\Model\Toggle\StrategyFactory' }
diff --git a/packages/symfony-toggle/src/DependencyInjection/FeatureRepositoryFactoryPass.php b/packages/symfony-toggle/src/DependencyInjection/FeatureRepositoryFactoryPass.php
new file mode 100644
index 0000000..d525e23
--- /dev/null
+++ b/packages/symfony-toggle/src/DependencyInjection/FeatureRepositoryFactoryPass.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Pheature\Community\Symfony\DependencyInjection;
+
+use Doctrine\DBAL\Connection;
+use Pheature\Core\Toggle\Write\FeatureRepository;
+use Pheature\Crud\Psr11\Toggle\FeatureRepositoryFactory;
+use Pheature\Crud\Psr11\Toggle\ToggleConfig;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+final class FeatureRepositoryFactoryPass implements CompilerPassInterface
+{
+    public function process(ContainerBuilder $container): void
+    {
+        /** @var array<array<mixed>> $pheatureFlagsConfig */
+        $pheatureFlagsConfig = $container->getExtensionConfig('pheature_flags');
+        $mergedConfig = array_merge(...$pheatureFlagsConfig);
+
+        $repository = $container->register(FeatureRepository::class, FeatureRepository::class)
+            ->setAutowired(false)
+            ->setLazy(true)
+            ->setFactory([FeatureRepositoryFactory::class, 'create'])
+            ->addArgument(new Reference(ToggleConfig::class));
+
+        if ('dbal' === $mergedConfig['driver']) {
+            $repository->addArgument(new Reference(Connection::class));
+        } else {
+            $repository->addArgument(null);
+        }
+    }
+}
diff --git a/packages/symfony-toggle/src/DependencyInjection/PheatureFlagsExtension.php b/packages/symfony-toggle/src/DependencyInjection/PheatureFlagsExtension.php
index a296ad7..e7c9eb7 100644
--- a/packages/symfony-toggle/src/DependencyInjection/PheatureFlagsExtension.php
+++ b/packages/symfony-toggle/src/DependencyInjection/PheatureFlagsExtension.php
@@ -39,25 +39,22 @@ final class PheatureFlagsExtension extends ConfigurableExtension
             ->addArgument(new Reference(ToggleConfig::class))
             ->addArgument(new Reference(ChainToggleStrategyFactory::class));
 
-        $repository = $container->register(FeatureRepository::class, FeatureRepository::class)
-            ->setAutowired(false)
-            ->setLazy(true)
-            ->setFactory([FeatureRepositoryFactory::class, 'create']);
-
         if ('dbal' === $driver) {
             $finder->addArgument(new Reference(Connection::class));
-            $repository->addArgument(new Reference(Connection::class));
         }
 
         if ('inmemory' === $driver) {
             $finder->addArgument(null);
-            $repository->addArgument(null);
             $container->register(InMemoryFeatureFactory::class, InMemoryFeatureFactory::class)
                 ->setAutowired(false)
                 ->setLazy(true)
                 ->addArgument(new Reference(ChainToggleStrategyFactory::class));
         }
 
+        $container->addCompilerPass(new SegmentFactoryPass());
+        $container->addCompilerPass(new ToggleStrategyFactoryPass());
+        $container->addCompilerPass(new FeatureRepositoryFactoryPass());
+
         $container->register(Toggle::class, Toggle::class)
             ->setAutowired(false)
             ->setLazy(true)
diff --git a/packages/symfony-toggle/src/PheatureFlagsBundle.php b/packages/symfony-toggle/src/PheatureFlagsBundle.php
index 6b710a1..f181ab1 100644
--- a/packages/symfony-toggle/src/PheatureFlagsBundle.php
+++ b/packages/symfony-toggle/src/PheatureFlagsBundle.php
@@ -4,8 +4,6 @@ declare(strict_types=1);
 
 namespace Pheature\Community\Symfony;
 
-use Pheature\Community\Symfony\DependencyInjection\SegmentFactoryPass;
-use Pheature\Community\Symfony\DependencyInjection\ToggleStrategyFactoryPass;
 use Pheature\Model\Toggle\EnableByMatchingIdentityId;
 use Pheature\Model\Toggle\EnableByMatchingSegment;
 use Pheature\Model\Toggle\IdentitySegment;
@@ -46,8 +44,5 @@ final class PheatureFlagsBundle extends Bundle
     public function build(ContainerBuilder $container): void
     {
         $container->loadFromExtension('pheature_flags', self::DEFAULT_CONFIG);
-
-        $container->addCompilerPass(new SegmentFactoryPass());
-        $container->addCompilerPass(new ToggleStrategyFactoryPass());
     }
 }


Test patch:
diff --git a/packages/symfony-toggle/test/DependencyInjection/FeatureRepositoryFactoryPassTest.php b/packages/symfony-toggle/test/DependencyInjection/FeatureRepositoryFactoryPassTest.php
new file mode 100644
index 0000000..2185388
--- /dev/null
+++ b/packages/symfony-toggle/test/DependencyInjection/FeatureRepositoryFactoryPassTest.php
@@ -0,0 +1,55 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Pheature\Test\Community\Symfony\DependencyInjection;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\DriverManager;
+use Pheature\Community\Symfony\DependencyInjection\FeatureRepositoryFactoryPass;
+use Pheature\Core\Toggle\Write\FeatureRepository;
+use Pheature\Crud\Psr11\Toggle\ToggleConfig;
+use PHPUnit\Framework\TestCase;
+
+final class FeatureRepositoryFactoryPassTest extends TestCase
+{
+    public function testItShouldRegisterInMemoryFeatureRepositoryInContainer(): void
+    {
+        $compilerPass = new FeatureRepositoryFactoryPass();
+        $container = TestContainerFactory::create($compilerPass);
+        $container->register(ToggleConfig::class, ToggleConfig::class)->addArgument([
+            'driver' => 'inmemory',
+            'prefix' => '',
+        ]);
+
+        $featureRepositoryFactoryDefinition = $container->getDefinition(FeatureRepository::class);
+        self::assertFalse($featureRepositoryFactoryDefinition->isAutowired());
+        self::assertTrue($featureRepositoryFactoryDefinition->isLazy());
+
+        $featureRepositoryFactory = $container->get(FeatureRepository::class);
+        self::assertInstanceOf(FeatureRepository::class, $featureRepositoryFactory);
+    }
+
+    public function testItShouldRegisterDbalFeatureRepositoryInContainer(): void
+    {
+        touch('test.sqlite');
+        $compilerPass = new FeatureRepositoryFactoryPass();
+        $container = TestContainerFactory::create($compilerPass, 'dbal');
+        $container->register(ToggleConfig::class, ToggleConfig::class)->addArgument([
+            'driver' => 'dbal',
+            'prefix' => '',
+        ]);
+        $container->register(Connection::class, Connection::class)
+            ->setFactory([DriverManager::class, 'getConnection'])
+            ->addArgument(['url' => 'sqlite:///test.sqlite']);
+        $container->prependExtensionConfig('pheature_flags', ['driver' => 'dbal']);
+
+        $featureRepositoryFactoryDefinition = $container->getDefinition(FeatureRepository::class);
+        self::assertFalse($featureRepositoryFactoryDefinition->isAutowired());
+        self::assertTrue($featureRepositoryFactoryDefinition->isLazy());
+
+        $featureRepositoryFactory = $container->get(FeatureRepository::class);
+        self::assertInstanceOf(FeatureRepository::class, $featureRepositoryFactory);
+        unlink('test.sqlite');
+    }
+}
diff --git a/packages/symfony-toggle/test/DependencyInjection/TestContainerFactory.php b/packages/symfony-toggle/test/DependencyInjection/TestContainerFactory.php
index 8ff0863..06c96b8 100644
--- a/packages/symfony-toggle/test/DependencyInjection/TestContainerFactory.php
+++ b/packages/symfony-toggle/test/DependencyInjection/TestContainerFactory.php
@@ -12,15 +12,19 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
 
 final class TestContainerFactory
 {
-    public static function create(CompilerPassInterface $compilerPass): ContainerBuilder
+    public static function create(CompilerPassInterface $compilerPass, string $driver = 'inmemory'): ContainerBuilder
     {
         $containerBuilder = new ContainerBuilder();
         $extension = new PheatureFlagsExtension();
         $containerBuilder->registerExtension($extension);
 
         $phpFileLoader = new YamlFileLoader($containerBuilder, new FileLocator());
-        $phpFileLoader->load(realpath(__DIR__ . '/../../config/config.yaml'));
-
+        if ('inmemory' === $driver) {
+            $phpFileLoader->load(realpath(__DIR__ . '/../../config/config.yaml'));
+        }
+        if ('dbal' === $driver) {
+            $phpFileLoader->load(realpath(__DIR__ . '/../../config/dbal_config.yaml'));
+        }
         $compilerPass->process($containerBuilder);
 
         return $containerBuilder;