Skip to content

Commit

Permalink
Refactor DoctrineDiscriminatorType
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Dec 6, 2021
1 parent c9aaf62 commit 9129c08
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 64 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"php": "^8.0",
"ext-json": "*",
"ext-pcre": "*",
"sonata-project/doctrine-extensions": "^1.1",
"symfony/form": "^5.4 || ^6.0",
"symfony/http-foundation": "^5.4 || ^6.0",
"symfony/options-resolver": "^5.4 || ^6.0",
Expand All @@ -49,6 +48,7 @@
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.3",
"doctrine/doctrine-bundle": "^2.5",
"doctrine/orm": "^2.5",
"doctrine/persistence": "^1.3 || ^2.0",
"ergebnis/composer-normalize": "^2.0.1",
Expand All @@ -62,6 +62,7 @@
"twig/intl-extra": "^2.4 || ^3.0"
},
"conflict": {
"doctrine/doctrine-bundle": "<2.5",
"doctrine/orm": "<2.5",
"symfony/framework-bundle": "<5.4"
},
Expand Down
15 changes: 0 additions & 15 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ parameters:
count: 1
path: src/Type/BatchTimeType.php

-
message: "#^Method Nucleos\\\\Form\\\\Type\\\\DoctrineDiscriminatorType\\:\\:__construct\\(\\) has parameter \\$manager with generic class Sonata\\\\Doctrine\\\\Entity\\\\BaseEntityManager but does not specify its types\\: T$#"
count: 1
path: src/Type/DoctrineDiscriminatorType.php

-
message: "#^Property Nucleos\\\\Form\\\\Type\\\\DoctrineDiscriminatorType\\:\\:\\$entityManager with generic class Sonata\\\\Doctrine\\\\Entity\\\\BaseEntityManager does not specify its types\\: T$#"
count: 1
path: src/Type/DoctrineDiscriminatorType.php

-
message: "#^Method Nucleos\\\\Form\\\\Tests\\\\Bridge\\\\Symfony\\\\App\\\\AppKernel\\:\\:configureContainer\\(\\) has parameter \\$container with no type specified\\.$#"
count: 1
Expand Down Expand Up @@ -50,11 +40,6 @@ parameters:
count: 1
path: tests/Bridge/Symfony/Bundle/BundleIntegrationTest.php

-
message: "#^Property Nucleos\\\\Form\\\\Tests\\\\Type\\\\DoctrineDiscriminatorTypeTest\\:\\:\\$baseEntityManager with generic class Sonata\\\\Doctrine\\\\Entity\\\\BaseEntityManager does not specify its types\\: T$#"
count: 1
path: tests/Type/DoctrineDiscriminatorTypeTest.php

-
message: "#^Property Nucleos\\\\Form\\\\Tests\\\\Type\\\\DoctrineDiscriminatorTypeTest\\:\\:\\$classMetadata with generic class Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata does not specify its types\\: T$#"
count: 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ public function load(array $configs, ContainerBuilder $container): void
$loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('form.php');
$loader->load('validator.php');

/** @var array<string, mixed> $bundles */
$bundles = $container->getParameter('kernel.bundles');

if (isset($bundles['DoctrineBundle'])) {
$loader->load('form_doctrine.php');
}
}

public function prepend(ContainerBuilder $container): void
Expand Down
24 changes: 24 additions & 0 deletions src/Bridge/Symfony/Resources/config/form_doctrine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

/*
* (c) Christian Gripp <mail@core23.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Nucleos\Form\Type\DoctrineDiscriminatorType;

return static function (ContainerConfigurator $container): void {
$container->services()

->set(DoctrineDiscriminatorType::class)
->tag('form.type', [])
->args([
service('doctrine'),
])

;
};
48 changes: 38 additions & 10 deletions src/Type/DoctrineDiscriminatorType.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@

namespace Nucleos\Form\Type;

use Sonata\Doctrine\Entity\BaseEntityManager;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;

abstract class DoctrineDiscriminatorType extends AbstractType
final class DoctrineDiscriminatorType extends AbstractType
{
private BaseEntityManager $entityManager;
private ManagerRegistry $manager;

public function __construct(BaseEntityManager $manager)
public function __construct(ManagerRegistry $manager)
{
$this->entityManager = $manager;
$this->manager = $manager;
}

public function getParent(): ?string
Expand All @@ -31,19 +35,43 @@ public function getParent(): ?string
}

public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'choice_loader' => function (Options $options): ChoiceLoaderInterface {
$class = $options['class'];

return new CallbackChoiceLoader(fn (): array => $this->getChoices($class));
},
]);

$resolver->setRequired(['class']);
}

/**
* @param class-string $class
*
* @return array<string, string>
*/
private function getChoices(string $class): array
{
$choices = [];

$meta = $this->entityManager->getEntityManager()->getClassMetadata($this->entityManager->getClass());
$manager = $this->manager->getManagerForClass($class);

if (null === $manager) {
return $choices;
}

$meta = $manager->getClassMetadata($class);

\assert($meta instanceof ClassMetadataInfo);

if (\is_array($meta->discriminatorMap)) {
foreach ($meta->discriminatorMap as $key => $class) {
foreach ($meta->discriminatorMap as $key => $value) {
$choices[$key] = $key;
}
}

$resolver->setDefaults([
'choices' => $choices,
]);
return $choices;
}
}
2 changes: 2 additions & 0 deletions tests/Bridge/Symfony/App/AppKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Nucleos\Form\Tests\Bridge\Symfony\App;

use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Nucleos\Form\Bridge\Symfony\Bundle\NucleosFormBundle;
use Nucleos\Form\Tests\Bridge\Symfony\App\Controller\SampleTestController;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
Expand All @@ -31,6 +32,7 @@ public function __construct()
public function registerBundles(): iterable
{
yield new FrameworkBundle();
yield new DoctrineBundle();
yield new NucleosFormBundle();
}

Expand Down
10 changes: 10 additions & 0 deletions tests/Bridge/Symfony/App/config/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
framework:
secret: secret

doctrine:
dbal:
driver: pdo_sqlite
path: "%kernel.cache_dir%/test.db3"
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:

services:
_defaults:
autowire: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Nucleos\Form\Type\BatchTimeType;
use Nucleos\Form\Type\DACHCountryType;
use Nucleos\Form\Type\DateOutputType;
use Nucleos\Form\Type\DoctrineDiscriminatorType;
use Nucleos\Form\Type\GenderType;
use Nucleos\Form\Type\NumberOutputType;
use Nucleos\Form\Type\OutputType;
Expand All @@ -31,6 +32,8 @@ final class NucleosFormExtensionTest extends AbstractExtensionTestCase
{
public function testLoadDefault(): void
{
$this->setParameter('kernel.bundles', []);

$this->load();

$this->assertContainerBuilderHasService(DACHCountryType::class);
Expand All @@ -45,6 +48,19 @@ public function testLoadDefault(): void

$this->assertContainerBuilderHasService(DateAfterValidator::class);
$this->assertContainerBuilderHasService(BatchTimeAfterValidator::class);

$this->assertContainerBuilderNotHasService(DoctrineDiscriminatorType::class);
}

public function testLoadDefaultWithAdmin(): void
{
$this->setParameter('kernel.bundles', [
'DoctrineBundle' => true,
]);

$this->load();

$this->assertContainerBuilderHasService(DoctrineDiscriminatorType::class);
}

public function testLoadWithTwigExtension(): void
Expand Down
18 changes: 0 additions & 18 deletions tests/Fixtures/EntityDoctrineDiscriminatorType.php

This file was deleted.

Loading

0 comments on commit 9129c08

Please sign in to comment.