boot(), when Drupal's dependency injection container is being * compiled. Since we cannot use the container at this point (since its * initialization is not yet complete), we instead alter the definition of * a storage class in the container to add more setter injection method * calls to 'addCommandReference'. * * Later, after the container has been completely initialized, we can * fetch the storage class from the DI container (perhaps also via * injection from a reference in the container). At that point, we can * request the list of Console commands that were added via the * (delayed) call(s) to addCommandReference. * * Documentation: * * http://symfony.com/doc/2.7/components/dependency_injection/tags.html#create-a-compilerpass */ class FindCommandsCompilerPass implements CompilerPassInterface { protected $storageClassId; protected $tagId; public function __construct($storageClassId, $tagId) { $this->storageClassId = $storageClassId; $this->tagId = $tagId; } public function process(ContainerBuilder $container) { drush_log(dt("process !storage !tag", ['!storage' => $this->storageClassId, '!tag' => $this->tagId]), LogLevel::DEBUG); // We expect that our called registered the storage // class under the storage class id before adding this // compiler pass, but we will test this presumption to be sure. if (!$container->has($this->storageClassId)) { drush_log(dt("storage class not registered"), LogLevel::DEBUG); return; } $definition = $container->findDefinition( $this->storageClassId ); $taggedServices = $container->findTaggedServiceIds( $this->tagId ); foreach ($taggedServices as $id => $tags) { drush_log(dt("found tagged service !id", ['!id' => $id]), LogLevel::DEBUG); $definition->addMethodCall( 'addCommandReference', array(new Reference($id)) ); } } }