Skip to content
Snippets Groups Projects
Commit d5b0279c authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3345039 by phenaproxima, Wim Leers, effulgentsia: Remove dependency on symfony/config

parent 0d9baf31
No related branches found
No related tags found
No related merge requests found
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
"drupal/core": "^9.7 || ^10", "drupal/core": "^9.7 || ^10",
"php-tuf/composer-stager": "^1.2", "php-tuf/composer-stager": "^1.2",
"composer/composer": "^2.2.12 || ^2.3.5", "composer/composer": "^2.2.12 || ^2.3.5",
"composer-runtime-api": "^2.1", "composer-runtime-api": "^2.1"
"symfony/config": "^4.4 || ^6.1"
}, },
"scripts": { "scripts": {
"phpcbf": "scripts/phpcbf.sh", "phpcbf": "scripts/phpcbf.sh",
......
...@@ -7,13 +7,15 @@ namespace Drupal\package_manager; ...@@ -7,13 +7,15 @@ namespace Drupal\package_manager;
use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase; use Drupal\Core\DependencyInjection\ServiceProviderBase;
use PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface; use PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
/** /**
* Defines dynamic container services for Package Manager. * Defines dynamic container services for Package Manager.
* *
* Scans the Composer Stager library and registers its classes in the Drupal
* service container.
*
* @todo Refactor this if/when symfony/config becomes a dependency: revert https://www.drupal.org/i/3345039.
*
* @internal * @internal
* This is an internal part of Package Manager and may be changed or removed * This is an internal part of Package Manager and may be changed or removed
* at any time without warning. External code should not interact with this * at any time without warning. External code should not interact with this
...@@ -32,18 +34,56 @@ final class PackageManagerServiceProvider extends ServiceProviderBase { ...@@ -32,18 +34,56 @@ final class PackageManagerServiceProvider extends ServiceProviderBase {
$mirror = new \ReflectionClass(BeginnerInterface::class); $mirror = new \ReflectionClass(BeginnerInterface::class);
$path = dirname($mirror->getFileName(), 4); $path = dirname($mirror->getFileName(), 4);
// Recursively register all classes and interfaces under that directory, // Certain subdirectories of Composer Stager shouldn't be scanned for
// relative to the \PhpTuf\ComposerStager namespace. // services.
$loader = new DirectoryLoader($container, new FileLocator()); $ignore_directories = [
// All the registered services should be auto-wired and private by default.
$default_definition = new Definition();
$default_definition->setAutowired(TRUE);
$default_definition->setPublic(FALSE);
$loader->registerClasses($default_definition, 'PhpTuf\ComposerStager\\', $path, [
// Ignore classes which we don't want to register as services.
$path . '/Domain/Exception', $path . '/Domain/Exception',
$path . '/Infrastructure/Value', $path . '/Infrastructure/Value',
]); ];
// As we scan for services, compile a list of which classes implement which
// interfaces so that we can set up aliases for interfaces that are only
// implemented by one class (to facilitate autowiring).
$interfaces = [];
// Find all `.php` files in Composer Stager which aren't in the ignored
// directories.
$iterator = new \RecursiveDirectoryIterator($path, \FilesystemIterator::CURRENT_AS_SELF | \FilesystemIterator::SKIP_DOTS);
$iterator = new \RecursiveCallbackFilterIterator($iterator, static function (\SplFileInfo $current) use ($ignore_directories): bool {
if ($current->isDir()) {
return !in_array($current->getPathname(), $ignore_directories, TRUE);
}
return $current->getExtension() === 'php';
});
$iterator = new \RecursiveIteratorIterator($iterator);
/** @var \SplFileInfo $file */
foreach ($iterator as $file) {
// Convert the file name to a class name.
$class_name = substr($file->getPathname(), strlen($path) + 1, -4);
$class_name = 'PhpTuf\\ComposerStager\\' . str_replace(DIRECTORY_SEPARATOR, '\\', $class_name);
// Don't register interfaces and abstract classes as services.
$reflector = new \ReflectionClass($class_name);
if ($reflector->isInterface() || $reflector->isAbstract()) {
continue;
}
foreach ($reflector->getInterfaceNames() as $interface) {
$interfaces[$interface][] = $class_name;
}
// Register the class as an autowired, private service.
$container->register($class_name)
->setClass($class_name)
->setAutowired(TRUE)
->setPublic(FALSE);
}
// Create aliases for interfaces that are only implemented by one class.
// Ignore interfaces that already have a service alias.
foreach ($interfaces as $interface_name => $implementations) {
if (count($implementations) === 1 && !$container->hasAlias($interface_name)) {
$container->setAlias($interface_name, $implementations[0]);
}
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment