vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php line 53

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Console\DependencyInjection;
  11. use Symfony\Component\Console\Command\Command;
  12. use Symfony\Component\Console\Command\LazyCommand;
  13. use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
  14. use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
  15. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  16. use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
  17. use Symfony\Component\DependencyInjection\ContainerBuilder;
  18. use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
  19. use Symfony\Component\DependencyInjection\Reference;
  20. use Symfony\Component\DependencyInjection\TypedReference;
  21. /**
  22.  * Registers console commands.
  23.  *
  24.  * @author GrĂ©goire Pineau <lyrixx@lyrixx.info>
  25.  */
  26. class AddConsoleCommandPass implements CompilerPassInterface
  27. {
  28.     public function process(ContainerBuilder $container)
  29.     {
  30.         $commandServices $container->findTaggedServiceIds('console.command'true);
  31.         $lazyCommandMap = [];
  32.         $lazyCommandRefs = [];
  33.         $serviceIds = [];
  34.         foreach ($commandServices as $id => $tags) {
  35.             $definition $container->getDefinition($id);
  36.             $definition->addTag('container.no_preload');
  37.             $class $container->getParameterBag()->resolveValue($definition->getClass());
  38.             if (isset($tags[0]['command'])) {
  39.                 $aliases $tags[0]['command'];
  40.             } else {
  41.                 if (!$r $container->getReflectionClass($class)) {
  42.                     throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.'$class$id));
  43.                 }
  44.                 if (!$r->isSubclassOf(Command::class)) {
  45.                     throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".'$id'console.command'Command::class));
  46.                 }
  47.                 $aliases str_replace('%''%%'$class::getDefaultName() ?? '');
  48.             }
  49.             $aliases explode('|'$aliases ?? '');
  50.             $commandName array_shift($aliases);
  51.             if ($isHidden '' === $commandName) {
  52.                 $commandName array_shift($aliases);
  53.             }
  54.             if (null === $commandName) {
  55.                 if (!$definition->isPublic() || $definition->isPrivate() || $definition->hasTag('container.private')) {
  56.                     $commandId 'console.command.public_alias.'.$id;
  57.                     $container->setAlias($commandId$id)->setPublic(true);
  58.                     $id $commandId;
  59.                 }
  60.                 $serviceIds[] = $id;
  61.                 continue;
  62.             }
  63.             $description $tags[0]['description'] ?? null;
  64.             unset($tags[0]);
  65.             $lazyCommandMap[$commandName] = $id;
  66.             $lazyCommandRefs[$id] = new TypedReference($id$class);
  67.             foreach ($aliases as $alias) {
  68.                 $lazyCommandMap[$alias] = $id;
  69.             }
  70.             foreach ($tags as $tag) {
  71.                 if (isset($tag['command'])) {
  72.                     $aliases[] = $tag['command'];
  73.                     $lazyCommandMap[$tag['command']] = $id;
  74.                 }
  75.                 $description ??= $tag['description'] ?? null;
  76.             }
  77.             $definition->addMethodCall('setName', [$commandName]);
  78.             if ($aliases) {
  79.                 $definition->addMethodCall('setAliases', [$aliases]);
  80.             }
  81.             if ($isHidden) {
  82.                 $definition->addMethodCall('setHidden', [true]);
  83.             }
  84.             if (!$description) {
  85.                 if (!$r $container->getReflectionClass($class)) {
  86.                     throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.'$class$id));
  87.                 }
  88.                 if (!$r->isSubclassOf(Command::class)) {
  89.                     throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".'$id'console.command'Command::class));
  90.                 }
  91.                 $description str_replace('%''%%'$class::getDefaultDescription() ?? '');
  92.             }
  93.             if ($description) {
  94.                 $definition->addMethodCall('setDescription', [$description]);
  95.                 $container->register('.'.$id.'.lazy'LazyCommand::class)
  96.                     ->setArguments([$commandName$aliases$description$isHidden, new ServiceClosureArgument($lazyCommandRefs[$id])]);
  97.                 $lazyCommandRefs[$id] = new Reference('.'.$id.'.lazy');
  98.             }
  99.         }
  100.         $container
  101.             ->register('console.command_loader'ContainerCommandLoader::class)
  102.             ->setPublic(true)
  103.             ->addTag('container.no_preload')
  104.             ->setArguments([ServiceLocatorTagPass::register($container$lazyCommandRefs), $lazyCommandMap]);
  105.         $container->setParameter('console.command.ids'$serviceIds);
  106.     }
  107. }