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