Chris@14: Chris@14: * Chris@14: * For the full copyright and license information, please view the LICENSE Chris@14: * file that was distributed with this source code. Chris@14: */ Chris@14: Chris@14: namespace Symfony\Component\Console\DependencyInjection; Chris@14: Chris@14: use Symfony\Component\Console\Command\Command; Chris@14: use Symfony\Component\Console\CommandLoader\ContainerCommandLoader; Chris@14: use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; Chris@14: use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; Chris@14: use Symfony\Component\DependencyInjection\ContainerBuilder; Chris@14: use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; Chris@14: use Symfony\Component\DependencyInjection\TypedReference; Chris@14: Chris@14: /** Chris@14: * Registers console commands. Chris@14: * Chris@14: * @author Grégoire Pineau Chris@14: */ Chris@14: class AddConsoleCommandPass implements CompilerPassInterface Chris@14: { Chris@14: private $commandLoaderServiceId; Chris@14: private $commandTag; Chris@14: Chris@14: public function __construct($commandLoaderServiceId = 'console.command_loader', $commandTag = 'console.command') Chris@14: { Chris@14: $this->commandLoaderServiceId = $commandLoaderServiceId; Chris@14: $this->commandTag = $commandTag; Chris@14: } Chris@14: Chris@14: public function process(ContainerBuilder $container) Chris@14: { Chris@14: $commandServices = $container->findTaggedServiceIds($this->commandTag, true); Chris@17: $lazyCommandMap = []; Chris@17: $lazyCommandRefs = []; Chris@17: $serviceIds = []; Chris@17: $lazyServiceIds = []; Chris@14: Chris@14: foreach ($commandServices as $id => $tags) { Chris@14: $definition = $container->getDefinition($id); Chris@14: $class = $container->getParameterBag()->resolveValue($definition->getClass()); Chris@14: Chris@14: $commandId = 'console.command.'.strtolower(str_replace('\\', '_', $class)); Chris@14: Chris@14: if (isset($tags[0]['command'])) { Chris@14: $commandName = $tags[0]['command']; Chris@14: } else { Chris@14: if (!$r = $container->getReflectionClass($class)) { Chris@14: throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); Chris@14: } Chris@14: if (!$r->isSubclassOf(Command::class)) { Chris@14: throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); Chris@14: } Chris@14: $commandName = $class::getDefaultName(); Chris@14: } Chris@14: Chris@14: if (null === $commandName) { Chris@14: if (isset($serviceIds[$commandId]) || $container->hasAlias($commandId)) { Chris@14: $commandId = $commandId.'_'.$id; Chris@14: } Chris@14: if (!$definition->isPublic() || $definition->isPrivate()) { Chris@14: $container->setAlias($commandId, $id)->setPublic(true); Chris@14: $id = $commandId; Chris@14: } Chris@14: $serviceIds[$commandId] = $id; Chris@14: Chris@14: continue; Chris@14: } Chris@14: Chris@14: $serviceIds[$commandId] = $id; Chris@14: $lazyServiceIds[$id] = true; Chris@14: unset($tags[0]); Chris@14: $lazyCommandMap[$commandName] = $id; Chris@14: $lazyCommandRefs[$id] = new TypedReference($id, $class); Chris@17: $aliases = []; Chris@14: Chris@14: foreach ($tags as $tag) { Chris@14: if (isset($tag['command'])) { Chris@14: $aliases[] = $tag['command']; Chris@14: $lazyCommandMap[$tag['command']] = $id; Chris@14: } Chris@14: } Chris@14: Chris@17: $definition->addMethodCall('setName', [$commandName]); Chris@14: Chris@14: if ($aliases) { Chris@17: $definition->addMethodCall('setAliases', [$aliases]); Chris@14: } Chris@14: } Chris@14: Chris@14: $container Chris@14: ->register($this->commandLoaderServiceId, ContainerCommandLoader::class) Chris@14: ->setPublic(true) Chris@17: ->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]); Chris@14: Chris@14: $container->setParameter('console.command.ids', $serviceIds); Chris@14: $container->setParameter('console.lazy_command.ids', $lazyServiceIds); Chris@14: } Chris@14: }