-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
FindCommandsCompilerPass.php
72 lines (65 loc) · 2.74 KB
/
FindCommandsCompilerPass.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
namespace Drush\Drupal;
use Drush\Drush;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
/**
* This compiler pass is added to Drupal's ContainerBuilder by our own
* subclass of DrupalKernel. Our DrupalKernel subclass knows which
* compiler passes to add because they are registered to it via its
* 'alter()' method. This happens in DrupalBoot8 immediately after the
* DrupalKernel object is created.
*
* Having been thus added, this compiler pass will then be called during
* $kernel->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): void
{
Drush::logger()->debug(dt("process !storage !tag", ['!storage' => $this->storageClassId, '!tag' => $this->tagId]));
// 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::logger()->debug(dt("storage class not registered"));
return;
}
$definition = $container->findDefinition(
$this->storageClassId
);
$taggedServices = $container->findTaggedServiceIds(
$this->tagId
);
foreach ($taggedServices as $id => $tags) {
Drush::logger()->debug(dt("Found tagged service !id", ['!id' => $id]));
$definition->addMethodCall(
'addCommandReference',
[new Reference($id, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]
);
}
}
}