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 = array(
19: 'setup' => array(),
20: 'tags' => array(),
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: $this->addSetups($class, (array) $info['setup']);
33: $this->addTags($class, (array) $info['tags']);
34: }
35: }
36:
37:
38: public function addSetups($type, array $setups)
39: {
40: foreach ($this->findByType($type) as $def) {
41: foreach ($setups as $setup) {
42: $def->addSetup($setup);
43: }
44: }
45: }
46:
47:
48: public function addTags($type, array $tags)
49: {
50: $tags = Nette\Utils\Arrays::normalize($tags, TRUE);
51: foreach ($this->findByType($type) as $def) {
52: $def->setTags($def->getTags() + $tags);
53: }
54: }
55:
56:
57: private function findByType($type)
58: {
59: $type = ltrim($type, '\\');
60: return array_filter($this->getContainerBuilder()->getDefinitions(), function ($def) use ($type) {
61: return $def->getClass() === $type || is_subclass_of($def->getClass(), $type)
62: || (PHP_VERSION_ID < 50307 && array_key_exists($type, class_implements($def->getClass())))
63: || $def->getImplement() === $type || is_subclass_of($def->getImplement(), $type)
64: || (PHP_VERSION_ID < 50307 && $def->getImplement() && array_key_exists($type, class_implements($def->getImplement())));
65: });
66: }
67:
68: }
69: