Skip to content

Commit 242a0b3

Browse files
committed
ContainerBuilder: added support for array append '$prop[]' = value
1 parent 34105e6 commit 242a0b3

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

src/DI/ContainerBuilder.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ public function formatStatement(Statement $statement)
744744
} elseif (!Nette\Utils\Arrays::isList($entity) || count($entity) !== 2) {
745745
throw new ServiceCreationException(sprintf('Expected class, method or property, %s given.', PhpHelpers::dump($entity)));
746746

747-
} elseif (!preg_match('#^\$?' . PhpHelpers::PHP_IDENT . '\z#', $entity[1])) {
747+
} elseif (!preg_match('#^\$?' . PhpHelpers::PHP_IDENT . '(\[\])?\z#', $entity[1])) {
748748
throw new ServiceCreationException("Expected function, method or property name, '$entity[1]' given.");
749749

750750
} elseif ($entity[0] === '') { // globalFunc
@@ -757,15 +757,22 @@ public function formatStatement(Statement $statement)
757757
}
758758
return $this->formatPhp("$inner->?(?*)", [$entity[1], $arguments]);
759759

760-
} elseif ($entity[1][0] === '$') { // property getter or setter
760+
} elseif ($entity[1][0] === '$') { // property getter, setter or appender
761761
Validators::assert($arguments, 'list:0..1', "setup arguments for '" . Nette\Utils\Callback::toString($entity) . "'");
762+
$name = substr($entity[1], 1);
763+
if ($append = (substr($name, -2) === '[]')) {
764+
if (!$arguments) {
765+
throw new ServiceCreationException("Missing argument for $entity[1].");
766+
}
767+
$name = substr($name, 0, -2);
768+
}
762769
if ($this->getServiceName($entity[0])) {
763-
$prop = $this->formatPhp('?->?', [$entity[0], substr($entity[1], 1)]);
770+
$prop = $this->formatPhp('?->?', [$entity[0], $name]);
764771
} else {
765-
$prop = $this->formatPhp($entity[0] . '::$?', [substr($entity[1], 1)]);
772+
$prop = $this->formatPhp($entity[0] . '::$?', [$name]);
766773
}
767774
return $arguments
768-
? $this->formatPhp("$prop = ?", [$arguments[0]])
775+
? $this->formatPhp($prop . ($append ? '[]' : '') . ' = ?', [$arguments[0]])
769776
: $prop;
770777

771778
} elseif ($service = $this->getServiceName($entity[0])) { // service method

tests/DI/Compiler.services.setup.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Assert::same([
7474
Assert::same(8, $container->getService('lorem')->test);
7575
Assert::same(9, Ipsum::$staticTest);
7676
Assert::equal(new Lorem, $container->getService('ipsum')->test);
77+
Assert::same([1, 2], $container->getService('lorem')->arr);
7778

7879
Assert::count(4, Ipsum::$instances);
7980
Assert::same($container->getService('lorem'), Ipsum::$instances[3]->arg);

tests/DI/ContainerBuilder.error.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,14 @@ $builder->addDefinition('25_service')
4141
Assert::exception(function () use ($builder) {
4242
$builder->getByType(stdClass::class);
4343
}, Nette\DI\ServiceCreationException::class, 'Multiple services of type stdClass found: extension.one, 25_service. If you want to overwrite service extension.one, give it proper name.');
44+
45+
46+
47+
$builder = new DI\ContainerBuilder;
48+
$builder->addDefinition('one')
49+
->setClass('stdClass')
50+
->addSetup('$prop[]');
51+
52+
Assert::exception(function () use ($builder) {
53+
$builder->generateClasses();
54+
}, Nette\InvalidStateException::class, "Service 'one': Missing argument for \$prop[].");

tests/DI/files/compiler.services.setup.neon

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ services:
2424
- [@self, $test](true)
2525
- $test = false
2626
- $%property%(8)
27+
- '$arr[]' = 1
28+
- '$arr[]'=2
2729

2830
# static class property
2931
- Ipsum::$staticTest(9)

0 commit comments

Comments
 (0)