Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/Definition/ObjectDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use DI\Definition\Dumper\ObjectDefinitionDumper;
use DI\Definition\ObjectDefinition\MethodInjection;
use DI\Definition\ObjectDefinition\PropertyInjection;
use DI\Definition\Source\DefinitionArray;
use ReflectionClass;

/**
Expand Down Expand Up @@ -223,6 +224,25 @@ public function replaceNestedDefinitions(callable $replacer)
});
}

/**
* Replaces all the wildcards in the string with the given replacements.
*
* @param string[] $replacements
*/
public function replaceWildcards(array $replacements)
{
$className = $this->getClassName();

foreach ($replacements as $replacement) {
$pos = strpos($className, DefinitionArray::WILDCARD);
if ($pos !== false) {
$className = substr_replace($className, $replacement, $pos, 1);
}
}

$this->setClassName($className);
}

public function __toString()
{
return (new ObjectDefinitionDumper)->dump($this);
Expand Down
29 changes: 2 additions & 27 deletions src/Definition/Source/DefinitionArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace DI\Definition\Source;

use DI\Definition\Definition;
use DI\Definition\ObjectDefinition;

/**
* Reads DI definitions from a PHP array.
Expand Down Expand Up @@ -106,16 +105,8 @@ public function getDefinition(string $name)
$key = preg_quote($key);
$key = '#' . str_replace('\\' . self::WILDCARD, self::WILDCARD_PATTERN, $key) . '#';
if (preg_match($key, $name, $matches) === 1) {
$definition = $this->normalizer->normalizeRootDefinition($definition, $name);

// For a class definition, we replace * in the class name with the matches
// *Interface -> *Impl => FooInterface -> FooImpl
if ($definition instanceof ObjectDefinition) {
array_shift($matches);
$definition->setClassName(
$this->replaceWildcards($definition->getClassName(), $matches)
);
}
array_shift($matches);
$definition = $this->normalizer->normalizeRootDefinition($definition, $name, $matches);

return $definition;
}
Expand All @@ -136,20 +127,4 @@ public function getDefinitions() : array

return $definitions;
}

/**
* Replaces all the wildcards in the string with the given replacements.
* @param string[] $replacements
*/
private function replaceWildcards(string $string, array $replacements) : string
{
foreach ($replacements as $replacement) {
$pos = strpos($string, self::WILDCARD);
if ($pos !== false) {
$string = substr_replace($string, $replacement, $pos, 1);
}
}

return $string;
}
}
10 changes: 9 additions & 1 deletion src/Definition/Source/DefinitionNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use DI\Definition\Exception\InvalidDefinition;
use DI\Definition\FactoryDefinition;
use DI\Definition\Helper\DefinitionHelper;
use DI\Definition\ObjectDefinition;
use DI\Definition\ValueDefinition;

/**
Expand Down Expand Up @@ -38,10 +39,11 @@ public function __construct(Autowiring $autowiring)
*
* @param mixed $definition
* @param string $name The definition name.
* @param string[] $wildcardsReplacements Replacements for wildcard definitions.
*
* @throws InvalidDefinition
*/
public function normalizeRootDefinition($definition, string $name) : Definition
public function normalizeRootDefinition($definition, string $name, array $wildcardsReplacements = null) : Definition
{
if ($definition instanceof DefinitionHelper) {
$definition = $definition->getDefinition($name);
Expand All @@ -53,6 +55,12 @@ public function normalizeRootDefinition($definition, string $name) : Definition
$definition = new ValueDefinition($definition);
}

// For a class definition, we replace * in the class name with the matches
// *Interface -> *Impl => FooInterface -> FooImpl
if ($wildcardsReplacements && $definition instanceof ObjectDefinition) {
$definition->replaceWildcards($wildcardsReplacements);
}

if ($definition instanceof AutowireDefinition) {
$definition = $this->autowiring->autowire($name, $definition);
}
Expand Down
57 changes: 57 additions & 0 deletions tests/IntegrationTest/Definitions/WildcardDefinitionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
use DI\ContainerBuilder;
use DI\Test\IntegrationTest\BaseContainerTest;
use DI\Test\IntegrationTest\Fixtures\Implementation1;
use DI\Test\IntegrationTest\Fixtures\Implementation2;
use DI\Test\IntegrationTest\Fixtures\Interface1;
use DI\Test\IntegrationTest\Fixtures\Interface2;

/**
* Test definitions using wildcards.
Expand Down Expand Up @@ -36,6 +38,61 @@ public function test_wildcards(ContainerBuilder $builder)
self::assertEntryIsNotCompiled($container, 'DI\Test\IntegrationTest\*\Interface*');
self::assertEntryIsNotCompiled($container, Interface1::class);
}
/**
* @dataProvider provideContainer
*/
public function test_wildcard_with_static_name(ContainerBuilder $builder)
{
$builder->addDefinitions([
'DI\Test\IntegrationTest\*\Interface*' => \DI\create(Implementation1::class),
]);
$container = $builder->build();

$object = $container->get(Interface1::class);
$this->assertInstanceOf(Implementation1::class, $object);

self::assertEntryIsNotCompiled($container, Interface1::class);
}

/**
* @dataProvider provideContainer
*/
public function test_wildcards_autowire(ContainerBuilder $builder)
{
$builder->addDefinitions([
'DI\Test\IntegrationTest\*\Interface*' => \DI\autowire('DI\Test\IntegrationTest\*\Implementation*'),
]);
$container = $builder->build();

$object = $container->get(Interface1::class);
$this->assertInstanceOf(Implementation1::class, $object);

self::assertEntryIsNotCompiled($container, 'DI\Test\IntegrationTest\*\Interface*');
self::assertEntryIsNotCompiled($container, Interface1::class);
self::assertEntryIsNotCompiled($container, Interface2::class);
}

/**
* @dataProvider provideContainer
*/
public function test_wildcards_autowire_with_dependency(ContainerBuilder $builder)
{
$builder->addDefinitions([
'DI\Test\IntegrationTest\*\Interface*' => \DI\autowire('DI\Test\IntegrationTest\*\Implementation*'),
]);
$container = $builder->build();

$object = $container->get(Interface1::class);
$this->assertInstanceOf(Implementation1::class, $object);

$object2 = $container->get(Interface2::class);
$this->assertInstanceOf(Implementation2::class, $object2);
$this->assertInstanceOf(Implementation1::class, $object2->dependency);

self::assertEntryIsNotCompiled($container, 'DI\Test\IntegrationTest\*\Interface*');
self::assertEntryIsNotCompiled($container, Interface1::class);
self::assertEntryIsNotCompiled($container, Interface2::class);
}

/**
* @dataProvider provideContainer
Expand Down
20 changes: 20 additions & 0 deletions tests/IntegrationTest/Fixtures/Implementation2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace DI\Test\IntegrationTest\Fixtures;

/**
* Fixture class.
*/
class Implementation2 implements Interface2
{
/**
* @var Interface1
*/
public $dependency;

public function __construct(Interface1 $dependency) {
$this->dependency = $dependency;
}
}
9 changes: 9 additions & 0 deletions tests/IntegrationTest/Fixtures/Interface2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace DI\Test\IntegrationTest\Fixtures;

interface Interface2
{
}
35 changes: 35 additions & 0 deletions tests/UnitTest/Definition/ObjectDefinitionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,39 @@ public function test_method_injections()
new MethodInjection('method2'),
], $definition->getMethodInjections());
}

public function test_replace_wildcards()
{
$definition = new ObjectDefinition('class', 'Foo*\Bar*\Baz*');
$definition->replaceWildcards(['1', '2', '3']);
$this->assertEquals('Foo1\Bar2\Baz3', $definition->getClassName());
}

public function test_replace_wildcards_with_no_classname_defined()
{
$definition = new ObjectDefinition('Foo*\Bar*\Baz*');
$definition->replaceWildcards(['1', '2', '3']);
$this->assertEquals('Foo1\Bar2\Baz3', $definition->getClassName());
}

public function test_replace_wildcards_with_extra_replacements()
{
$definition = new ObjectDefinition('Foo*\Bar\Baz');
$definition->replaceWildcards(['1', '2', '3']);
$this->assertEquals('Foo1\Bar\Baz', $definition->getClassName());
}

public function test_replace_wildcards_with_missing_replacements()
{
$definition = new ObjectDefinition('Foo*\Bar*\Baz*');
$definition->replaceWildcards(['1']);
$this->assertEquals('Foo1\Bar*\Baz*', $definition->getClassName());
}

public function test_replace_wildcards_with_no_wildcards()
{
$definition = new ObjectDefinition('Foo\Bar\Baz');
$definition->replaceWildcards(['1', '2', '3']);
$this->assertEquals('Foo\Bar\Baz', $definition->getClassName());
}
}