1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\DI\Extensions;
9:
10: use Nette;
11:
12:
13: 14: 15:
16: class DecoratorExtension extends Nette\DI\CompilerExtension
17: {
18: public $defaults = [
19: 'setup' => [],
20: 'tags' => [],
21: 'inject' => NULL,
22: ];
23:
24:
25: public function beforeCompile()
26: {
27: foreach ($this->getConfig() as $class => $info) {
28: $info = $this->validateConfig($this->defaults, $info, $this->prefix($class));
29: if ($info['inject'] !== NULL) {
30: $info['tags'][InjectExtension::TAG_INJECT] = $info['inject'];
31: }
32: $info = Nette\DI\Helpers::filterArguments($info);
33: $this->addSetups($class, (array) $info['setup']);
34: $this->addTags($class, (array) $info['tags']);
35: }
36: }
37:
38:
39: public function addSetups($type, array $setups)
40: {
41: foreach ($this->findByType($type) as $def) {
42: foreach ($setups as $setup) {
43: $def->addSetup($setup);
44: }
45: }
46: }
47:
48:
49: public function addTags($type, array $tags)
50: {
51: $tags = Nette\Utils\Arrays::normalize($tags, TRUE);
52: foreach ($this->findByType($type) as $def) {
53: $def->setTags($def->getTags() + $tags);
54: }
55: }
56:
57:
58: private function findByType($type)
59: {
60: $type = ltrim($type, '\\');
61: return array_filter($this->getContainerBuilder()->getDefinitions(), function ($def) use ($type) {
62: return is_a($def->getClass(), $type, TRUE) || is_a($def->getImplement(), $type, TRUE);
63: });
64: }
65:
66: }
67: