From 3d384a4b37e483b29b956c4396ceed95a3e40e85 Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Wed, 27 Mar 2024 18:19:16 -0400 Subject: [PATCH] feat: allow `ForObject` attribute to configure `EntityRepository` services --- .../Symfony/ZenstruckCollectionBundle.php | 21 ++++++++++++++-- .../Fixture/Repository/CategoryRepository.php | 24 +++++++++++++++++++ tests/Symfony/Fixture/Service1.php | 8 +++++-- tests/Symfony/Fixture/TestKernel.php | 5 ++++ 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 tests/Symfony/Fixture/Repository/CategoryRepository.php diff --git a/src/Collection/Symfony/ZenstruckCollectionBundle.php b/src/Collection/Symfony/ZenstruckCollectionBundle.php index ac14b08..359c3dd 100644 --- a/src/Collection/Symfony/ZenstruckCollectionBundle.php +++ b/src/Collection/Symfony/ZenstruckCollectionBundle.php @@ -15,11 +15,14 @@ use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\LogicException; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\Bundle\AbstractBundle; use Zenstruck\Collection\Doctrine\Grid\ObjectGridDefinition; +use Zenstruck\Collection\Doctrine\ORM\EntityRepository; +use Zenstruck\Collection\Grid\GridDefinition; use Zenstruck\Collection\Symfony\Attributes\AsGrid; use Zenstruck\Collection\Symfony\Attributes\ForObject; @@ -58,8 +61,22 @@ public function loadExtension(array $config, ContainerConfigurator $container, C if (isset($builder->getParameter('kernel.bundles')['DoctrineBundle'])) { $loader->load('doctrine.php'); - $builder->registerAttributeForAutoconfiguration(ForObject::class, function(ChildDefinition $definition, ForObject $attribute) { - $definition->addTag('zenstruck_collection.grid_definition', ['key' => $attribute->class, 'as_object' => true]); + $builder->registerAttributeForAutoconfiguration(ForObject::class, function(ChildDefinition $definition, ForObject $attribute, \ReflectionClass $class) { // @phpstan-ignore-line + if ($class->implementsInterface(GridDefinition::class)) { + $definition->addTag('zenstruck_collection.grid_definition', ['key' => $attribute->class, 'as_object' => true]); + + return; + } + + if (!$class->isSubclassOf(EntityRepository::class)) { + throw new LogicException(\sprintf('Can only use "%s" on classes that implement "%s" or extend "%s".', ForObject::class, GridDefinition::class, EntityRepository::class)); + } + + if (EntityRepository::class !== $class->getConstructor()?->getDeclaringClass()->name) { + throw new LogicException(\sprintf('Cannot use "%s" on "%s" as it overrides the constructor.', ForObject::class, $class->name)); + } + + $definition->setArgument('$class', $attribute->class); }); } } diff --git a/tests/Symfony/Fixture/Repository/CategoryRepository.php b/tests/Symfony/Fixture/Repository/CategoryRepository.php new file mode 100644 index 0000000..449ae33 --- /dev/null +++ b/tests/Symfony/Fixture/Repository/CategoryRepository.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Zenstruck\Collection\Tests\Symfony\Fixture\Repository; + +use Zenstruck\Collection\Doctrine\ORM\EntityRepository; +use Zenstruck\Collection\Symfony\Attributes\ForObject; +use Zenstruck\Collection\Tests\Symfony\Fixture\Entity\Category; + +/** + * @author Kevin Bond + */ +#[ForObject(Category::class)] +final class CategoryRepository extends EntityRepository +{ +} diff --git a/tests/Symfony/Fixture/Service1.php b/tests/Symfony/Fixture/Service1.php index 928fc15..9b3ec27 100644 --- a/tests/Symfony/Fixture/Service1.php +++ b/tests/Symfony/Fixture/Service1.php @@ -12,6 +12,7 @@ namespace Zenstruck\Collection\Tests\Symfony\Fixture; use Zenstruck\Collection\Doctrine\ObjectRepositoryFactory; +use Zenstruck\Collection\Tests\Symfony\Fixture\Repository\CategoryRepository; use Zenstruck\Collection\Tests\Symfony\Fixture\Repository\PostRepository; /** @@ -19,7 +20,10 @@ */ final class Service1 { - public function __construct(public ObjectRepositoryFactory $factory, public PostRepository $postRepo) - { + public function __construct( + public ObjectRepositoryFactory $factory, + public PostRepository $postRepo, + public CategoryRepository $categoryRepo, + ) { } } diff --git a/tests/Symfony/Fixture/TestKernel.php b/tests/Symfony/Fixture/TestKernel.php index 6c8421c..c45971d 100644 --- a/tests/Symfony/Fixture/TestKernel.php +++ b/tests/Symfony/Fixture/TestKernel.php @@ -23,6 +23,7 @@ use Zenstruck\Collection\Tests\Symfony\Fixture\Grid\Grid1Definition; use Zenstruck\Collection\Tests\Symfony\Fixture\Grid\Grid2Definition; use Zenstruck\Collection\Tests\Symfony\Fixture\Grid\Grid3Definition; +use Zenstruck\Collection\Tests\Symfony\Fixture\Repository\CategoryRepository; use Zenstruck\Collection\Tests\Symfony\Fixture\Repository\PostRepository; use Zenstruck\Foundry\ZenstruckFoundryBundle; @@ -81,6 +82,10 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load ->setAutowired(true) ->setAutoconfigured(true) ; + $c->register(CategoryRepository::class) + ->setAutowired(true) + ->setAutoconfigured(true) + ; $c->register(Service2::class) ->setPublic(true) ->setAutowired(true)