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 $type => $info) {
28: $info = $this->validateConfig($this->defaults, $info, $this->prefix($type));
29: if ($info['inject'] !== null) {
30: $info['tags'][InjectExtension::TAG_INJECT] = $info['inject'];
31: }
32: $info = Nette\DI\Helpers::filterArguments($info);
33: $this->addSetups($type, (array) $info['setup']);
34: $this->addTags($type, (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: if (is_array($setup)) {
44: $setup = new Nette\DI\Statement(key($setup), array_values($setup));
45: }
46: $def->addSetup($setup);
47: }
48: }
49: }
50:
51:
52: public function addTags($type, array $tags)
53: {
54: $tags = Nette\Utils\Arrays::normalize($tags, true);
55: foreach ($this->findByType($type) as $def) {
56: $def->setTags($def->getTags() + $tags);
57: }
58: }
59:
60:
61: private function findByType($type)
62: {
63: return array_filter($this->getContainerBuilder()->getDefinitions(), function ($def) use ($type) {
64: return is_a($def->getImplement(), $type, true)
65: || ($def->getImplementMode() !== $def::IMPLEMENT_MODE_GET && is_a($def->getType(), $type, true));
66: });
67: }
68: }
69: