diff --git a/src/Bundle/DependencyInjection/Configuration.php b/src/Bundle/DependencyInjection/Configuration.php index 6de235407..7da7477d5 100644 --- a/src/Bundle/DependencyInjection/Configuration.php +++ b/src/Bundle/DependencyInjection/Configuration.php @@ -39,6 +39,9 @@ public function getConfigTreeBuilder(): TreeBuilder ->arrayNode('mapping') ->addDefaultsIfNotSet() ->children() + ->arrayNode('imports') + ->prototype('scalar')->end() + ->end() ->arrayNode('paths') ->prototype('scalar')->end() ->end() diff --git a/src/Bundle/DependencyInjection/SyliusResourceExtension.php b/src/Bundle/DependencyInjection/SyliusResourceExtension.php index ba3c013c6..4c6604276 100644 --- a/src/Bundle/DependencyInjection/SyliusResourceExtension.php +++ b/src/Bundle/DependencyInjection/SyliusResourceExtension.php @@ -33,11 +33,14 @@ use Sylius\Resource\Twig\Context\Factory\ContextFactoryInterface; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Config\Resource\DirectoryResource; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\Finder\Finder; use function Symfony\Component\String\u; final class SyliusResourceExtension extends Extension implements PrependExtensionInterface @@ -66,6 +69,7 @@ public function load(array $configs, ContainerBuilder $container): void $container->setParameter('sylius.resource.settings', $config['settings']); $container->setAlias('sylius.resource_controller.authorization_checker', $config['authorization_checker']); + $this->registerMetadataConfiguration($container, $config); $this->autoRegisterResources($config, $container); $this->loadPersistence($config['drivers'], $config['resources'], $loader, $container); @@ -320,4 +324,43 @@ private function loadResources(array $loadedResources, ContainerBuilder $contain } } } + + private function registerMetadataConfiguration(ContainerBuilder $container, array $config): void + { + $resources = $this->getResourceFilesToWatch($container, $config); + + $container->getDefinition('sylius.metadata.resource_extractor.php_file')->replaceArgument(0, $resources); + } + + private function getResourceFilesToWatch(ContainerBuilder $container, array $config): array + { + $files = []; + + /** @var string $path */ + foreach ($config['mapping']['imports'] ?? [] as $path) { + if (is_dir($path)) { + foreach (Finder::create()->followLinks()->files()->in($path)->name('/\.php$/')->sortByName() as $file) { + $files[] = $file->getRealPath(); + } + + $container->addResource(new DirectoryResource($path, '/\.php$/')); + + continue; + } + + if ($container->fileExists($path, false)) { + if (!str_ends_with($path, '.php')) { + throw new RuntimeException(\sprintf('Unsupported mapping type in "%s", supported type is PHP.', $path)); + } + + $files[] = $path; + + continue; + } + + throw new RuntimeException(\sprintf('Could not open file or directory "%s".', $path)); + } + + return $files; + } } diff --git a/src/Bundle/Resources/config/services/metadata/extractor.xml b/src/Bundle/Resources/config/services/metadata/extractor.xml new file mode 100644 index 000000000..6b0b6f0a1 --- /dev/null +++ b/src/Bundle/Resources/config/services/metadata/extractor.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/Bundle/Configuration/ConfigurationTest.php b/tests/Bundle/Configuration/ConfigurationTest.php index 54865c590..a6093872a 100644 --- a/tests/Bundle/Configuration/ConfigurationTest.php +++ b/tests/Bundle/Configuration/ConfigurationTest.php @@ -71,6 +71,7 @@ public function it_has_no_default_mapping_paths(): void ], [ 'mapping' => [ + 'imports' => [], 'paths' => [], ], ], @@ -89,6 +90,7 @@ public function its_mapping_paths_can_be_customized(): void ], [ 'mapping' => [ + 'imports' => [], 'paths' => [ 'path/to/resources', ], diff --git a/tests/Bundle/DependencyInjection/SyliusResourceExtensionTest.php b/tests/Bundle/DependencyInjection/SyliusResourceExtensionTest.php index 11a4e2c50..6460013a9 100644 --- a/tests/Bundle/DependencyInjection/SyliusResourceExtensionTest.php +++ b/tests/Bundle/DependencyInjection/SyliusResourceExtensionTest.php @@ -123,6 +123,7 @@ public function it_registers_parameter_for_paths(): void ]); $this->assertContainerBuilderHasParameter('sylius.resource.mapping', [ + 'imports' => [], 'paths' => [ __DIR__ . '/Dummy', ], @@ -181,6 +182,36 @@ public function it_registers_doctrine_related_services_when_doctrine_is_availabl $this->assertContainerBuilderHasService(RemoveProcessor::class); } + public function testItRegistersMetadataConfigurationWithADirectoryAsImportPath(): void + { + $this->load([ + 'mapping' => [ + 'imports' => [ + __DIR__ . '/php', + ], + ], + ]); + + $emptyPhpFile = realpath(__DIR__ . '/php/empty_file.php'); + $this->assertContainerBuilderHasService('sylius.metadata.resource_extractor.php_file'); + $this->assertSame([$emptyPhpFile], $this->container->getDefinition('sylius.metadata.resource_extractor.php_file')->getArgument(0)); + } + + public function testItRegistersMetadataConfigurationWithAFileAsImportPath(): void + { + $this->load([ + 'mapping' => [ + 'imports' => [ + __DIR__ . '/php/empty_file.php', + ], + ], + ]); + + $emptyPhpFile = realpath(__DIR__ . '/php/empty_file.php'); + $this->assertContainerBuilderHasService('sylius.metadata.resource_extractor.php_file'); + $this->assertSame([$emptyPhpFile], $this->container->getDefinition('sylius.metadata.resource_extractor.php_file')->getArgument(0)); + } + protected function getContainerExtensions(): array { $this->setParameter('kernel.bundles', []); diff --git a/tests/Bundle/DependencyInjection/php/empty_file.php b/tests/Bundle/DependencyInjection/php/empty_file.php new file mode 100644 index 000000000..7404988e8 --- /dev/null +++ b/tests/Bundle/DependencyInjection/php/empty_file.php @@ -0,0 +1,12 @@ +