Skip to content

Commit 28fdac3

Browse files
committed
added DecoratorExtension
1 parent c7d046e commit 28fdac3

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Nette Framework (http://nette.org)
5+
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
6+
*/
7+
8+
namespace Nette\DI\Extensions;
9+
10+
use Nette,
11+
Nette\DI\Statement;
12+
13+
14+
/**
15+
* Decorators for services.
16+
*
17+
* @author David Grudl
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+
$this->validate($info, $this->defaults, $this->prefix($class));
32+
$info += $this->defaults;
33+
if ($info['inject'] !== NULL) {
34+
$info['tags'][InjectExtension::TAG_INJECT] = $info['inject'];
35+
}
36+
$this->addSetups($class, $info['setup']);
37+
$this->addTags($class, $info['tags']);
38+
}
39+
}
40+
41+
42+
public function addSetups($type, array $setups)
43+
{
44+
$builder = $this->getContainerBuilder();
45+
foreach ($builder->findByType($type, FALSE) as $name) {
46+
foreach ($setups as $setup) {
47+
$builder->getDefinition($name)->addSetup($setup);
48+
}
49+
}
50+
}
51+
52+
53+
public function addTags($type, array $tags)
54+
{
55+
$tags = Nette\Utils\Arrays::normalize($tags, TRUE);
56+
$builder = $this->getContainerBuilder();
57+
foreach ($builder->findByType($type, FALSE) as $name) {
58+
$def = $builder->getDefinition($name);
59+
$def->setTags($def->getTags() + $tags);
60+
}
61+
}
62+
63+
64+
private function validate(array $config, array $expected, $name)
65+
{
66+
if ($extra = array_diff_key($config, $expected)) {
67+
$extra = implode(", $name.", array_keys($extra));
68+
throw new Nette\InvalidStateException("Unknown option $name.$extra.");
69+
}
70+
}
71+
72+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\DI\Compiler: service decorators.
5+
*/
6+
7+
use Nette\DI,
8+
Nette\DI\Statement,
9+
Tester\Assert;
10+
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
15+
interface Iface
16+
{}
17+
18+
19+
class Service extends Nette\Object implements Iface
20+
{
21+
public $setup;
22+
23+
function setup($a = NULL)
24+
{
25+
$this->setup[] = $a;
26+
}
27+
}
28+
29+
30+
$compiler = new DI\Compiler;
31+
$compiler->addExtension('decorator', new Nette\DI\Extensions\DecoratorExtension);
32+
$container = createContainer($compiler, '
33+
decorator:
34+
Nette\Object:
35+
setup:
36+
- setup(Object)
37+
inject: yes
38+
39+
Iface:
40+
setup:
41+
- setup(Iface)
42+
- setup
43+
tags: [b, tag: 1]
44+
45+
services:
46+
one:
47+
class: Service
48+
tags: [a, tag: 2]
49+
setup:
50+
- setup(Service)
51+
');
52+
53+
54+
$builder = $compiler->getContainerBuilder();
55+
56+
Assert::same(
57+
array('a' => TRUE, 'tag' => 2, 'inject' => TRUE, 'b' => TRUE),
58+
$builder->getDefinition('one')->tags
59+
);
60+
61+
Assert::true( $builder->getDefinition('one')->getTag('inject') );
62+
63+
Assert::equal( array(
64+
new Statement(array('@self', 'setup'), array('Service')),
65+
new Statement(array('@self', 'setup'), array('Object')),
66+
new Statement(array('@self', 'setup'), array('Iface')),
67+
new Statement(array('@self', 'setup')),
68+
), $builder->getDefinition('one')->getSetup() );

0 commit comments

Comments
 (0)