From 7c6d57cd3fc55ca5af832671f8020b9541f0ff4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Wr=C3=B3blewski?= Date: Fri, 9 Feb 2024 22:27:33 +0100 Subject: [PATCH] feat: simplify data tables - removed data table extensions, registry directly working with container --- src/DataTableFactory.php | 33 ++-- src/DataTableFactoryBuilder.php | 97 ----------- src/DataTableFactoryBuilderInterface.php | 41 ----- src/DataTableFactoryInterface.php | 8 +- src/DataTableRegistry.php | 128 +++++++++++++-- src/DataTableRegistryInterface.php | 11 +- src/DataTables.php | 10 -- src/Extension/AbstractDataTableExtension.php | 34 ---- ...ultConfigurationDataTableTypeExtension.php | 57 ------- src/Extension/DataTableExtensionInterface.php | 18 --- .../DependencyInjectionDataTableExtension.php | 27 ---- .../HttpFoundationDataTableExtension.php | 17 -- .../HttpFoundationDataTableTypeExtension.php | 29 ---- src/Extension/PreloadedDataTableExtension.php | 30 ---- src/Query/ChainProxyQueryFactory.php | 31 ---- src/Resources/config/core.php | 15 +- src/Resources/config/extensions.php | 15 -- .../Extension/DataTableTypeFooExtension.php | 16 ++ .../FooDataTableTypeBarExtension.php | 16 ++ .../FooDataTableTypeBazExtension.php | 16 ++ .../DataTable/Query/BarProxyQueryFactory.php | 22 +++ .../DataTable/Query/FooProxyQueryFactory.php | 22 +++ .../DataTable/Type/BarDataTableType.php | 15 ++ .../Type/DataTableTypeWithSameParentType.php | 15 ++ .../DataTable/Type/FooDataTableType.php | 11 ++ .../Type/RecursiveDataTableTypeBar.php | 15 ++ .../Type/RecursiveDataTableTypeBaz.php | 15 ++ .../Type/RecursiveDataTableTypeFoo.php | 15 ++ tests/Unit/DataTableRegistryTest.php | 150 ++++++++++++++++++ 29 files changed, 476 insertions(+), 453 deletions(-) delete mode 100644 src/DataTableFactoryBuilder.php delete mode 100644 src/DataTableFactoryBuilderInterface.php delete mode 100644 src/Extension/AbstractDataTableExtension.php delete mode 100755 src/Extension/Core/DefaultConfigurationDataTableTypeExtension.php delete mode 100644 src/Extension/DataTableExtensionInterface.php delete mode 100644 src/Extension/DependencyInjection/DependencyInjectionDataTableExtension.php delete mode 100644 src/Extension/HttpFoundation/HttpFoundationDataTableExtension.php delete mode 100644 src/Extension/HttpFoundation/HttpFoundationDataTableTypeExtension.php delete mode 100644 src/Extension/PreloadedDataTableExtension.php delete mode 100755 src/Query/ChainProxyQueryFactory.php create mode 100644 tests/Fixtures/DataTable/Extension/DataTableTypeFooExtension.php create mode 100644 tests/Fixtures/DataTable/Extension/FooDataTableTypeBarExtension.php create mode 100644 tests/Fixtures/DataTable/Extension/FooDataTableTypeBazExtension.php create mode 100644 tests/Fixtures/DataTable/Query/BarProxyQueryFactory.php create mode 100644 tests/Fixtures/DataTable/Query/FooProxyQueryFactory.php create mode 100644 tests/Fixtures/DataTable/Type/BarDataTableType.php create mode 100644 tests/Fixtures/DataTable/Type/DataTableTypeWithSameParentType.php create mode 100644 tests/Fixtures/DataTable/Type/FooDataTableType.php create mode 100644 tests/Fixtures/DataTable/Type/RecursiveDataTableTypeBar.php create mode 100644 tests/Fixtures/DataTable/Type/RecursiveDataTableTypeBaz.php create mode 100644 tests/Fixtures/DataTable/Type/RecursiveDataTableTypeFoo.php create mode 100644 tests/Unit/DataTableRegistryTest.php diff --git a/src/DataTableFactory.php b/src/DataTableFactory.php index 3cebbf1f..ad9ac17c 100755 --- a/src/DataTableFactory.php +++ b/src/DataTableFactory.php @@ -4,42 +4,43 @@ namespace Kreyu\Bundle\DataTableBundle; -use Kreyu\Bundle\DataTableBundle\Exception\InvalidArgumentException; -use Kreyu\Bundle\DataTableBundle\Query\ProxyQueryFactoryInterface; use Kreyu\Bundle\DataTableBundle\Query\ProxyQueryInterface; use Kreyu\Bundle\DataTableBundle\Type\DataTableType; class DataTableFactory implements DataTableFactoryInterface { public function __construct( - private DataTableRegistryInterface $registry, - private ?ProxyQueryFactoryInterface $proxyQueryFactory = null, + private readonly DataTableRegistryInterface $registry, ) { } - public function create(string $type = DataTableType::class, mixed $query = null, array $options = []): DataTableInterface + public function create(string $type = DataTableType::class, mixed $data = null, array $options = []): DataTableInterface { - return $this->createBuilder($type, $query, $options)->getDataTable(); + return $this->createBuilder($type, $data, $options)->getDataTable(); } - public function createNamed(string $name, string $type = DataTableType::class, mixed $query = null, array $options = []): DataTableInterface + public function createNamed(string $name, string $type = DataTableType::class, mixed $data = null, array $options = []): DataTableInterface { - return $this->createNamedBuilder($name, $type, $query, $options)->getDataTable(); + return $this->createNamedBuilder($name, $type, $data, $options)->getDataTable(); } - public function createBuilder(string $type = DataTableType::class, mixed $query = null, array $options = []): DataTableBuilderInterface + public function createBuilder(string $type = DataTableType::class, mixed $data = null, array $options = []): DataTableBuilderInterface { - return $this->createNamedBuilder($this->registry->getType($type)->getName(), $type, $query, $options); + return $this->createNamedBuilder($this->registry->getType($type)->getName(), $type, $data, $options); } - public function createNamedBuilder(string $name, string $type = DataTableType::class, mixed $query = null, array $options = []): DataTableBuilderInterface + public function createNamedBuilder(string $name, string $type = DataTableType::class, mixed $data = null, array $options = []): DataTableBuilderInterface { - if (null !== $query && !$query instanceof ProxyQueryInterface) { - if (null === $this->proxyQueryFactory) { - throw new InvalidArgumentException(sprintf('Expected query of type %s, %s given', ProxyQueryInterface::class, get_debug_type($query))); - } + $query = $data; + + if (null !== $data && !$data instanceof ProxyQueryInterface) { + foreach ($this->registry->getProxyQueryFactories() as $proxyQueryFactory) { + if ($proxyQueryFactory->supports($data)) { + $query = $proxyQueryFactory->create($data); + } - $query = $this->proxyQueryFactory->create($query); + break; + } } $type = $this->registry->getType($type); diff --git a/src/DataTableFactoryBuilder.php b/src/DataTableFactoryBuilder.php deleted file mode 100644 index 37a7d998..00000000 --- a/src/DataTableFactoryBuilder.php +++ /dev/null @@ -1,97 +0,0 @@ -resolvedTypeFactory = $resolvedTypeFactory; - - return $this; - } - - public function addExtension(DataTableExtensionInterface $extension): static - { - $this->extensions[] = $extension; - - return $this; - } - - public function addExtensions(array $extensions): static - { - $this->extensions = array_merge($this->extensions, $extensions); - - return $this; - } - - public function addType(DataTableTypeInterface $type): static - { - $this->types[] = $type; - - return $this; - } - - public function addTypes(array $types): static - { - foreach ($types as $type) { - $this->types[] = $type; - } - - return $this; - } - - public function addTypeExtension(DataTableTypeExtensionInterface $typeExtension): static - { - foreach ($typeExtension::getExtendedTypes() as $extendedType) { - $this->typeExtensions[$extendedType][] = $typeExtension; - } - - return $this; - } - - public function addTypeExtensions(array $typeExtensions): static - { - foreach ($typeExtensions as $typeExtension) { - $this->addTypeExtension($typeExtension); - } - - return $this; - } - - public function setProxyQueryFactory(?ProxyQueryFactoryInterface $proxyQueryFactory): static - { - $this->proxyQueryFactory = $proxyQueryFactory; - - return $this; - } - - public function getDataTableFactory(): DataTableFactoryInterface - { - $extensions = $this->extensions; - - if (\count($this->types) > 0 || \count($this->typeExtensions) > 0) { - $extensions[] = new PreloadedDataTableExtension($this->types, $this->typeExtensions); - } - - $registry = new DataTableRegistry($extensions, $this->resolvedTypeFactory ?? new ResolvedDataTableTypeFactory()); - - return new DataTableFactory($registry, $this->proxyQueryFactory); - } -} diff --git a/src/DataTableFactoryBuilderInterface.php b/src/DataTableFactoryBuilderInterface.php deleted file mode 100644 index da6a5485..00000000 --- a/src/DataTableFactoryBuilderInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - $extensions - */ - public function addExtensions(array $extensions): static; - - public function addType(DataTableTypeInterface $type): static; - - /** - * @param array $types - */ - public function addTypes(array $types): static; - - public function addTypeExtension(DataTableTypeExtensionInterface $typeExtension): static; - - /** - * @param array $typeExtensions - */ - public function addTypeExtensions(array $typeExtensions): static; - - public function getDataTableFactory(): DataTableFactoryInterface; -} diff --git a/src/DataTableFactoryInterface.php b/src/DataTableFactoryInterface.php index b64ba9ca..c8cd671a 100755 --- a/src/DataTableFactoryInterface.php +++ b/src/DataTableFactoryInterface.php @@ -6,11 +6,11 @@ interface DataTableFactoryInterface { - public function create(string $type, mixed $query = null, array $options = []): DataTableInterface; + public function create(string $type, mixed $data = null, array $options = []): DataTableInterface; - public function createNamed(string $name, string $type, mixed $query = null, array $options = []): DataTableInterface; + public function createNamed(string $name, string $type, mixed $data = null, array $options = []): DataTableInterface; - public function createBuilder(string $type, mixed $query = null, array $options = []): DataTableBuilderInterface; + public function createBuilder(string $type, mixed $data = null, array $options = []): DataTableBuilderInterface; - public function createNamedBuilder(string $name, string $type, mixed $query = null, array $options = []): DataTableBuilderInterface; + public function createNamedBuilder(string $name, string $type, mixed $data = null, array $options = []): DataTableBuilderInterface; } diff --git a/src/DataTableRegistry.php b/src/DataTableRegistry.php index f0a51eff..49110dee 100755 --- a/src/DataTableRegistry.php +++ b/src/DataTableRegistry.php @@ -4,32 +4,136 @@ namespace Kreyu\Bundle\DataTableBundle; -use Kreyu\Bundle\DataTableBundle\Extension\DataTableExtensionInterface; +use Kreyu\Bundle\DataTableBundle\Exception\InvalidArgumentException; +use Kreyu\Bundle\DataTableBundle\Exception\LogicException; +use Kreyu\Bundle\DataTableBundle\Exception\UnexpectedTypeException; +use Kreyu\Bundle\DataTableBundle\Extension\DataTableTypeExtensionInterface; +use Kreyu\Bundle\DataTableBundle\Query\ProxyQueryFactoryInterface; +use Kreyu\Bundle\DataTableBundle\Query\ProxyQueryInterface; use Kreyu\Bundle\DataTableBundle\Type\DataTableTypeInterface; +use Kreyu\Bundle\DataTableBundle\Type\ResolvedDataTableTypeFactoryInterface; use Kreyu\Bundle\DataTableBundle\Type\ResolvedDataTableTypeInterface; -/** - * @extends AbstractRegistry - */ -class DataTableRegistry extends AbstractRegistry implements DataTableRegistryInterface +class DataTableRegistry implements DataTableRegistryInterface { + /** + * @var array + */ + private array $types; + + /** + * @var array + */ + private array $typeExtensions; + + /** + * @var array + */ + private array $proxyQueryFactories; + + /** + * @var array + */ + private array $resolvedTypes; + + /** + * @var array, bool> + */ + private array $checkedTypes; + + /** + * @param iterable $types + * @param iterable $typeExtensions + * @param iterable $proxyQueryFactories + */ + public function __construct( + iterable $types, + iterable $typeExtensions, + iterable $proxyQueryFactories, + private readonly ResolvedDataTableTypeFactoryInterface $resolvedTypeFactory, + ) { + $this->setTypes($types); + $this->setTypeExtensions($typeExtensions); + $this->setProxyQueryFactories($proxyQueryFactories); + } + public function getType(string $name): ResolvedDataTableTypeInterface { - return $this->doGetType($name); + return $this->resolvedTypes[$name] ??= $this->resolveType($name); + } + + public function hasType(string $name): bool + { + return isset($this->types[$name]); + } + + public function getProxyQueryFactories(): array + { + return $this->proxyQueryFactories; } - final protected function getErrorContextName(): string + private function resolveType(string $name): ResolvedDataTableTypeInterface { - return 'data table'; + $type = $this->types[$name] ?? throw new InvalidArgumentException(sprintf('The data table type %s does not exist', $name)); + + if (isset($this->checkedTypes[$fqcn = $type::class])) { + $types = implode(' > ', array_merge(array_keys($this->checkedTypes), [$fqcn])); + throw new LogicException(sprintf('Circular reference detected for data table type "%s" (%s).', $fqcn, $types)); + } + + $this->checkedTypes[$fqcn] = true; + + $parentType = $type->getParent(); + + try { + return $this->resolvedTypeFactory->createResolvedType( + type: $type, + typeExtensions: $this->typeExtensions[$type::class] ?? [], + parent: $parentType ? $this->getType($parentType) : null, + ); + } finally { + unset($this->checkedTypes[$fqcn]); + } } - final protected function getTypeClass(): string + private function setTypes(iterable $types): void { - return DataTableTypeInterface::class; + $this->types = []; + + foreach ($types as $type) { + if (!$type instanceof DataTableTypeInterface) { + throw new UnexpectedTypeException($type, DataTableTypeInterface::class); + } + + $this->types[$type::class] = $type; + } } - final protected function getExtensionClass(): string + private function setTypeExtensions(iterable $typeExtensions): void { - return DataTableExtensionInterface::class; + $this->typeExtensions = []; + + foreach ($typeExtensions as $typeExtension) { + if (!$typeExtension instanceof DataTableTypeExtensionInterface) { + throw new UnexpectedTypeException($typeExtension, DataTableTypeExtensionInterface::class); + } + + foreach ($typeExtension::getExtendedTypes() as $extendedType) { + $this->typeExtensions[$extendedType][] = $typeExtension; + } + } + } + + private function setProxyQueryFactories(iterable $proxyQueryFactories): void + { + $this->proxyQueryFactories = []; + + foreach ($proxyQueryFactories as $proxyQueryFactory) { + if (!$proxyQueryFactory instanceof ProxyQueryFactoryInterface) { + throw new UnexpectedTypeException($proxyQueryFactory, ProxyQueryFactoryInterface::class); + } + + $this->proxyQueryFactories[] = $proxyQueryFactory; + } } } diff --git a/src/DataTableRegistryInterface.php b/src/DataTableRegistryInterface.php index 473fb515..9bea07b4 100755 --- a/src/DataTableRegistryInterface.php +++ b/src/DataTableRegistryInterface.php @@ -4,7 +4,7 @@ namespace Kreyu\Bundle\DataTableBundle; -use Kreyu\Bundle\DataTableBundle\Extension\DataTableExtensionInterface; +use Kreyu\Bundle\DataTableBundle\Query\ProxyQueryFactoryInterface; use Kreyu\Bundle\DataTableBundle\Type\DataTableTypeInterface; use Kreyu\Bundle\DataTableBundle\Type\ResolvedDataTableTypeInterface; @@ -16,7 +16,12 @@ interface DataTableRegistryInterface public function getType(string $name): ResolvedDataTableTypeInterface; /** - * @return iterable + * @param class-string $name + */ + public function hasType(string $name): bool; + + /** + * @return array */ - public function getExtensions(): iterable; + public function getProxyQueryFactories(): array; } diff --git a/src/DataTables.php b/src/DataTables.php index 57b0db1a..a3d5c331 100644 --- a/src/DataTables.php +++ b/src/DataTables.php @@ -19,11 +19,6 @@ final class DataTables { - public static function createDataTableFactory(): DataTableFactoryInterface - { - return self::createDataTableFactoryBuilder()->getDataTableFactory(); - } - public static function createColumnFactory(): ColumnFactoryInterface { return self::createColumnFactoryBuilder()->getColumnFactory(); @@ -44,11 +39,6 @@ public static function createExporterFactory(): ExporterFactoryInterface return self::createExporterFactoryBuilder()->getExporterFactory(); } - public static function createDataTableFactoryBuilder(): DataTableFactoryBuilderInterface - { - return new DataTableFactoryBuilder(); - } - public static function createColumnFactoryBuilder(): ColumnFactoryBuilderInterface { return new ColumnFactoryBuilder(); diff --git a/src/Extension/AbstractDataTableExtension.php b/src/Extension/AbstractDataTableExtension.php deleted file mode 100644 index 94b577f2..00000000 --- a/src/Extension/AbstractDataTableExtension.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ -abstract class AbstractDataTableExtension extends AbstractExtension implements DataTableExtensionInterface -{ - public function getType(string $name): DataTableTypeInterface - { - return $this->doGetType($name); - } - - final protected function getErrorContextName(): string - { - return 'data table'; - } - - final protected function getTypeClass(): string - { - return DataTableTypeInterface::class; - } - - final protected function getTypeExtensionClass(): string - { - return DataTableTypeExtensionInterface::class; - } -} diff --git a/src/Extension/Core/DefaultConfigurationDataTableTypeExtension.php b/src/Extension/Core/DefaultConfigurationDataTableTypeExtension.php deleted file mode 100755 index f4ea58ec..00000000 --- a/src/Extension/Core/DefaultConfigurationDataTableTypeExtension.php +++ /dev/null @@ -1,57 +0,0 @@ -setDefaults([ - 'themes' => $this->defaults['themes'], - 'column_factory' => $this->defaults['column_factory'], - 'action_factory' => $this->defaults['action_factory'], - 'request_handler' => $this->defaults['request_handler'], - 'sorting_enabled' => $this->defaults['sorting']['enabled'], - 'sorting_persistence_enabled' => $this->defaults['sorting']['persistence_enabled'], - 'sorting_persistence_adapter' => $this->defaults['sorting']['persistence_adapter'], - 'sorting_persistence_subject_provider' => $this->defaults['sorting']['persistence_subject_provider'], - 'pagination_enabled' => $this->defaults['pagination']['enabled'], - 'pagination_persistence_enabled' => $this->defaults['pagination']['persistence_enabled'], - 'pagination_persistence_adapter' => $this->defaults['pagination']['persistence_adapter'], - 'pagination_persistence_subject_provider' => $this->defaults['pagination']['persistence_subject_provider'], - 'filtration_enabled' => $this->defaults['filtration']['enabled'], - 'filtration_persistence_enabled' => $this->defaults['filtration']['persistence_enabled'], - 'filtration_persistence_adapter' => $this->defaults['filtration']['persistence_adapter'], - 'filtration_persistence_subject_provider' => $this->defaults['filtration']['persistence_subject_provider'], - 'filtration_form_factory' => $this->defaults['filtration']['form_factory'], - 'filter_factory' => $this->defaults['filtration']['filter_factory'], - 'personalization_enabled' => $this->defaults['personalization']['enabled'], - 'personalization_persistence_enabled' => $this->defaults['personalization']['persistence_enabled'], - 'personalization_persistence_adapter' => $this->defaults['personalization']['persistence_adapter'], - 'personalization_persistence_subject_provider' => $this->defaults['personalization']['persistence_subject_provider'], - 'personalization_form_factory' => $this->defaults['personalization']['form_factory'], - 'exporting_enabled' => $this->defaults['exporting']['enabled'], - 'exporting_form_factory' => $this->defaults['exporting']['form_factory'], - 'exporter_factory' => $this->defaults['exporting']['exporter_factory'], - ]); - } - - public static function getExtendedTypes(): iterable - { - return [DataTableType::class]; - } -} diff --git a/src/Extension/DataTableExtensionInterface.php b/src/Extension/DataTableExtensionInterface.php deleted file mode 100644 index e6b6a385..00000000 --- a/src/Extension/DataTableExtensionInterface.php +++ /dev/null @@ -1,18 +0,0 @@ -doGetType($name); - } - - protected function getTypeClass(): string - { - return DataTableTypeInterface::class; - } - - protected function getErrorContextName(): string - { - return 'data table'; - } -} diff --git a/src/Extension/HttpFoundation/HttpFoundationDataTableExtension.php b/src/Extension/HttpFoundation/HttpFoundationDataTableExtension.php deleted file mode 100644 index 4b47f21a..00000000 --- a/src/Extension/HttpFoundation/HttpFoundationDataTableExtension.php +++ /dev/null @@ -1,17 +0,0 @@ -setRequestHandler($this->requestHandler); - } - - public static function getExtendedTypes(): iterable - { - return [DataTableType::class]; - } -} diff --git a/src/Extension/PreloadedDataTableExtension.php b/src/Extension/PreloadedDataTableExtension.php deleted file mode 100644 index 11df279e..00000000 --- a/src/Extension/PreloadedDataTableExtension.php +++ /dev/null @@ -1,30 +0,0 @@ - $types - * @param array|array> $typeExtensions - */ - public function __construct( - private readonly array $types = [], - private readonly array $typeExtensions = [], - ) { - } - - protected function loadTypes(): array - { - return $this->types; - } - - protected function loadTypeExtensions(): array - { - return $this->typeExtensions; - } -} diff --git a/src/Query/ChainProxyQueryFactory.php b/src/Query/ChainProxyQueryFactory.php deleted file mode 100755 index 4905587e..00000000 --- a/src/Query/ChainProxyQueryFactory.php +++ /dev/null @@ -1,31 +0,0 @@ - $factories - */ - public function __construct( - private readonly iterable $factories, - ) { - } - - public function create(mixed $data): ProxyQueryInterface - { - foreach ($this->factories as $factory) { - try { - return $factory->create($data); - } catch (UnexpectedTypeException) { - } - } - - throw new InvalidArgumentException(sprintf('Unable to create proxy query for data of type "%s"', get_debug_type($data))); - } -} diff --git a/src/Resources/config/core.php b/src/Resources/config/core.php index 32d6668e..67dea3b3 100755 --- a/src/Resources/config/core.php +++ b/src/Resources/config/core.php @@ -12,8 +12,6 @@ use Kreyu\Bundle\DataTableBundle\Persistence\PersistenceClearerInterface; use Kreyu\Bundle\DataTableBundle\Persistence\StaticPersistenceSubjectProvider; use Kreyu\Bundle\DataTableBundle\Persistence\TokenStoragePersistenceSubjectProvider; -use Kreyu\Bundle\DataTableBundle\Query\ChainProxyQueryFactory; -use Kreyu\Bundle\DataTableBundle\Query\ProxyQueryFactoryInterface; use Kreyu\Bundle\DataTableBundle\Request\HttpFoundationRequestHandler; use Kreyu\Bundle\DataTableBundle\Type\DataTableType; use Kreyu\Bundle\DataTableBundle\Type\ResolvedDataTableTypeFactory; @@ -41,7 +39,9 @@ $services ->set('kreyu_data_table.registry', DataTableRegistry::class) ->args([ - tagged_iterator('kreyu_data_table.extension'), + tagged_iterator('kreyu_data_table.type'), + tagged_iterator('kreyu_data_table.type_extension'), + tagged_iterator('kreyu_data_table.proxy_query.factory'), service('kreyu_data_table.resolved_type_factory'), ]) ->alias(DataTableRegistryInterface::class, 'kreyu_data_table.registry') @@ -51,7 +51,6 @@ ->set('kreyu_data_table.factory', DataTableFactory::class) ->args([ service('kreyu_data_table.registry'), - service('kreyu_data_table.proxy_query.factory.chain'), ]) ->alias(DataTableFactoryInterface::class, 'kreyu_data_table.factory') ; @@ -69,14 +68,6 @@ ->set('kreyu_data_table.request_handler.http_foundation', HttpFoundationRequestHandler::class) ; - $services - ->set('kreyu_data_table.proxy_query.factory.chain', ChainProxyQueryFactory::class) - ->args([ - tagged_iterator('kreyu_data_table.proxy_query.factory'), - ]) - ->alias(ProxyQueryFactoryInterface::class, 'kreyu_data_table.query.proxy_query_factory.chain') - ; - $services ->set('kreyu_data_table.proxy_query.factory.doctrine_orm', DoctrineOrmProxyQueryFactory::class) ->tag('kreyu_data_table.proxy_query.factory') diff --git a/src/Resources/config/extensions.php b/src/Resources/config/extensions.php index 35d9cd93..2e67b3a7 100755 --- a/src/Resources/config/extensions.php +++ b/src/Resources/config/extensions.php @@ -5,8 +5,6 @@ use Kreyu\Bundle\DataTableBundle\Action\Extension\DependencyInjection\DependencyInjectionActionExtension; use Kreyu\Bundle\DataTableBundle\Column\Extension\DependencyInjection\DependencyInjectionColumnExtension; use Kreyu\Bundle\DataTableBundle\Exporter\Extension\DependencyInjection\DependencyInjectionExporterExtension; -use Kreyu\Bundle\DataTableBundle\Extension\DependencyInjection\DependencyInjectionDataTableExtension; -use Kreyu\Bundle\DataTableBundle\Extension\HttpFoundation\HttpFoundationDataTableTypeExtension; use Kreyu\Bundle\DataTableBundle\Filter\Extension\DependencyInjection\DependencyInjectionFilterExtension; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; @@ -15,15 +13,6 @@ return static function (ContainerConfigurator $configurator) { $configurator->services() - ->set('kreyu_data_table.extension', DependencyInjectionDataTableExtension::class) - ->args([ - abstract_arg('All services with tag "kreyu_data_table.type" are stored in a service locator by DataTablePass'), - abstract_arg('All services with tag "kreyu_data_table.type_extension" are stored here by DataTablePass'), - ]) - ->tag('kreyu_data_table.extension', [ - 'type' => 'kreyu_data_table.type', - 'type_extension' => 'kreyu_data_table.type_extension', - ]) ->set('kreyu_data_table.column.extension', DependencyInjectionColumnExtension::class) ->args([ @@ -64,9 +53,5 @@ 'type' => 'kreyu_data_table.action.type', 'type_extension' => 'kreyu_data_table.action.type_extension', ]) - - ->set('kreyu_data_table.type_extension.http_foundation', HttpFoundationDataTableTypeExtension::class) - ->args([service('kreyu_data_table.request_handler.http_foundation')]) - ->tag('kreyu_data_table.type_extension') ; }; diff --git a/tests/Fixtures/DataTable/Extension/DataTableTypeFooExtension.php b/tests/Fixtures/DataTable/Extension/DataTableTypeFooExtension.php new file mode 100644 index 00000000..4c8b2961 --- /dev/null +++ b/tests/Fixtures/DataTable/Extension/DataTableTypeFooExtension.php @@ -0,0 +1,16 @@ +createRegistry()->getType(FooDataTableType::class); + + $this->assertInstanceOf(FooDataTableType::class, $resolvedType->getInnerType()); + } + + public function testGetTypeWithNonExistentType() + { + $this->expectException(InvalidArgumentException::class); + + $this->createRegistry()->getType('stdClass'); + } + + public function testGetTypeWithTypeExtensions() + { + $typeExtensions = [ + new FooDataTableTypeBarExtension(), + new FooDataTableTypeBazExtension(), + ]; + + $resolvedType = $this->createRegistry(typeExtensions: $typeExtensions)->getType(FooDataTableType::class); + + $this->assertSame($typeExtensions, $resolvedType->getTypeExtensions()); + } + + public function testGetTypeWithParent() + { + $resolvedType = $this->createRegistry()->getType(BarDataTableType::class); + + $this->assertInstanceOf(BarDataTableType::class, $resolvedType->getInnerType()); + $this->assertInstanceOf(FooDataTableType::class, $resolvedType->getParent()->getInnerType()); + } + + public function testGetTypeWithParentTypeExtensions() + { + $typeExtensions = [ + new FooDataTableTypeBarExtension(), + new FooDataTableTypeBazExtension(), + ]; + + $resolvedType = $this->createRegistry(typeExtensions: $typeExtensions)->getType(BarDataTableType::class); + + $this->assertEmpty($resolvedType->getTypeExtensions()); + $this->assertSame($typeExtensions, $resolvedType->getParent()->getTypeExtensions()); + } + + public function testTypeCannotHaveItselfAsParent() + { + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Circular reference detected for data table type "Kreyu\Bundle\DataTableBundle\Tests\Fixtures\DataTable\Type\DataTableTypeWithSameParentType" (Kreyu\Bundle\DataTableBundle\Tests\Fixtures\DataTable\Type\DataTableTypeWithSameParentType > Kreyu\Bundle\DataTableBundle\Tests\Fixtures\DataTable\Type\DataTableTypeWithSameParentType).'); + + $registry = $this->createRegistry(types: [new DataTableTypeWithSameParentType()]); + $registry->getType(DataTableTypeWithSameParentType::class); + } + + public function testRecursiveTypeReferences() + { + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Circular reference detected for data table type "Kreyu\Bundle\DataTableBundle\Tests\Fixtures\DataTable\Type\RecursiveDataTableTypeFoo" (Kreyu\Bundle\DataTableBundle\Tests\Fixtures\DataTable\Type\RecursiveDataTableTypeFoo > Kreyu\Bundle\DataTableBundle\Tests\Fixtures\DataTable\Type\RecursiveDataTableTypeBar > Kreyu\Bundle\DataTableBundle\Tests\Fixtures\DataTable\Type\RecursiveDataTableTypeBaz > Kreyu\Bundle\DataTableBundle\Tests\Fixtures\DataTable\Type\RecursiveDataTableTypeFoo).'); + + $registry = $this->createRegistry(types: [ + new RecursiveDataTableTypeFoo(), + new RecursiveDataTableTypeBar(), + new RecursiveDataTableTypeBaz(), + ]); + + $registry->getType(RecursiveDataTableTypeFoo::class); + } + + public function testHasType() + { + $this->assertTrue($this->createRegistry()->hasType(FooDataTableType::class)); + } + + public function testHasTypeWithNonExistentType() + { + $this->assertFalse($this->createRegistry()->hasType('stdClass')); + } + + public function testGetProxyQueryFactories() + { + $proxyQueryFactories = [ + new FooProxyQueryFactory(), + new BarProxyQueryFactory(), + ]; + + $registry = $this->createRegistry(proxyQueryFactories: $proxyQueryFactories); + + $this->assertSame($proxyQueryFactories, $registry->getProxyQueryFactories()); + } + + public function testCreatingRegistryWithInvalidType() + { + $this->expectException(UnexpectedTypeException::class); + $this->createRegistry(types: [new \stdClass()]); + } + + public function testCreatingRegistryWithInvalidTypeExtension() + { + $this->expectException(UnexpectedTypeException::class); + $this->createRegistry(typeExtensions: [new \stdClass()]); + } + + public function testCreatingRegistryWithInvalidProxyQueryFactory() + { + $this->expectException(UnexpectedTypeException::class); + $this->createRegistry(proxyQueryFactories: [new \stdClass()]); + } + + private function createRegistry(array $types = [], array $typeExtensions = [], array $proxyQueryFactories = []): DataTableRegistry + { + return new DataTableRegistry( + types: $types ?: [ + new DataTableType(), + new FooDataTableType(), + new BarDataTableType(), + ], + typeExtensions: $typeExtensions, + proxyQueryFactories: $proxyQueryFactories, + resolvedTypeFactory: new ResolvedDataTableTypeFactory(), + ); + } +}