Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' of git://github.com/zendframework/zf2
Browse files Browse the repository at this point in the history
  • Loading branch information
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 32 deletions.
66 changes: 37 additions & 29 deletions src/Di.php
Expand Up @@ -169,11 +169,11 @@ public function newInstance($name, array $params = array(), $isShared = true)
}

$instantiator = $definitions->getInstantiator($class);
$injectionMethods = $definitions->getMethods($class);
$injectionMethods = array();
$injectionMethods[$class] = $definitions->getMethods($class);

$supertypeInjectionMethods = array();
foreach ($definitions->getClassSupertypes($class) as $supertype) {
$supertypeInjectionMethods[$supertype] = $definitions->getMethods($supertype);
$injectionMethods[$supertype] = $definitions->getMethods($supertype);
}

if ($instantiator === '__construct') {
Expand Down Expand Up @@ -208,7 +208,7 @@ public function newInstance($name, array $params = array(), $isShared = true)
}
}

$this->handleInjectDependencies($instance, $injectionMethods, $supertypeInjectionMethods, $params, $class, $alias, $name);
$this->handleInjectDependencies($instance, $injectionMethods, $params, $class, $alias, $name);

array_pop($this->instanceContext);
return $instance;
Expand All @@ -223,40 +223,39 @@ public function injectDependencies($instance, array $params = array())
{
$definitions = $this->definitions();
$class = get_class($instance);
$injectionMethods = ($definitions->hasClass($class)) ? $definitions->getMethods($class) : array();
$superTypeInjectionMethods = array();
$injectionMethods = array(
$class => ($definitions->hasClass($class)) ? $definitions->getMethods($class) : array()
);
$parent = $class;
while ($parent = get_parent_class($parent)) {
if ($definitions->hasClass($parent)) {
$superTypeInjectionMethods[$parent] = $definitions->getMethods($parent);
$injectionMethods[$parent] = $definitions->getMethods($parent);
}
}
foreach (class_implements($class) as $interface) {
if ($definitions->hasClass($interface)) {
$superTypeInjectionMethods[$interface] = $definitions->getMethods($interface);
$injectionMethods[$interface] = $definitions->getMethods($interface);
}
}
$this->handleInjectDependencies($instance, $injectionMethods, $superTypeInjectionMethods, $params, $class, null, null);
$this->handleInjectDependencies($instance, $injectionMethods, $params, $class, null, null);
}


protected function handleInjectDependencies($instance, $injectionMethods, $supertypeInjectionMethods, $params, $instanceClass, $instanceAlias, $requestedName)
protected function handleInjectDependencies($instance, $injectionMethods, $params, $instanceClass, $instanceAlias, $requestedName)
{

// localize dependencies
$definitions = $this->definitions;
$instanceManager = $this->instanceManager();

if ($injectionMethods || $supertypeInjectionMethods) {
foreach ($injectionMethods as $injectionMethod => $methodIsRequired) {
if ($injectionMethod !== '__construct'){
$this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, $params, $instanceAlias, $methodIsRequired, $instanceClass);
}
}
foreach ($supertypeInjectionMethods as $supertype => $supertypeInjectionMethod) {
foreach ($supertypeInjectionMethod as $injectionMethod => $methodIsRequired) {
if ($injectionMethod !== '__construct') {
$this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, $params, $instanceAlias, $methodIsRequired, $supertype);
$calledMethods = array('__construct' => true);

if ($injectionMethods) {
foreach ($injectionMethods as $type => $typeInjectionMethods) {
foreach ($typeInjectionMethods as $typeInjectionMethod => $methodIsRequired) {
if (!isset($calledMethods[$typeInjectionMethod])) {
if ($this->resolveAndCallInjectionMethodForInstance($instance, $typeInjectionMethod, $params, $instanceAlias, $methodIsRequired, $type)) {
$calledMethods[$typeInjectionMethod] = true;
}
}
}
}
Expand Down Expand Up @@ -288,13 +287,20 @@ protected function handleInjectDependencies($instance, $injectionMethods, $super
}
if ($objectsToInject) {
foreach ($objectsToInject as $objectToInject) {
foreach ($injectionMethods as $injectionMethod => $methodIsRequired) {
$methodParams = $definitions->getMethodParameters($instanceClass, $injectionMethod);
if ($methodParams) {
foreach ($methodParams as $methodParam) {
if (get_class($objectToInject) == $methodParam[1] || $this->isSubclassOf(get_class($objectToInject), $methodParam[1])) {
$this->resolveAndCallInjectionMethodForInstance($instance, $injectionMethod, array($methodParam[0] => $objectToInject), $instanceAlias, true, get_class($instance));
continue 3;
$calledMethods = array('__construct' => true);
foreach ($injectionMethods as $type => $typeInjectionMethods) {
foreach ($typeInjectionMethods as $typeInjectionMethod => $methodIsRequired) {
if (!isset($calledMethods[$typeInjectionMethod])) {
$methodParams = $definitions->getMethodParameters($type, $typeInjectionMethod);
if ($methodParams) {
foreach ($methodParams as $methodParam) {
if (get_class($objectToInject) == $methodParam[1] || $this->isSubclassOf(get_class($objectToInject), $methodParam[1])) {
if ($this->resolveAndCallInjectionMethodForInstance($instance, $typeInjectionMethod, array($methodParam[0] => $objectToInject), $instanceAlias, true, $type)) {
$calledMethods[$typeInjectionMethod] = true;
}
continue 3;
}
}
}
}
}
Expand Down Expand Up @@ -391,11 +397,13 @@ protected function resolveAndCallInjectionMethodForInstance($instance, $method,
$methodClass = ($methodClass) ?: get_class($instance);
$callParameters = $this->resolveMethodParameters($methodClass, $method, $params, $alias, $methodIsRequired);
if ($callParameters == false) {
return;
return false;
}
if ($callParameters !== array_fill(0, count($callParameters), null)) {
call_user_func_array(array($instance, $method), $callParameters);
return true;
}
return false;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions test/Definition/CompilerDefinitionTest.php
Expand Up @@ -49,9 +49,9 @@ public function testCompilerSupertypes()
$definition = new CompilerDefinition;
$definition->addDirectory(__DIR__ . '/../TestAsset/CompilerClasses');
$definition->compile();
$this->assertCount(0, $definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\C'));
$this->assertCount(1, $definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\D'));
$this->assertCount(2, $definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\E'));
$this->assertEquals(0, count($definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\C')));
$this->assertEquals(1, count($definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\D')));
$this->assertEquals(2, count($definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\E')));
$this->assertContains('ZendTest\Di\TestAsset\CompilerClasses\C', $definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\D'));
$this->assertContains('ZendTest\Di\TestAsset\CompilerClasses\C', $definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\E'));
$this->assertContains('ZendTest\Di\TestAsset\CompilerClasses\D', $definition->getClassSupertypes('ZendTest\Di\TestAsset\CompilerClasses\E'));
Expand Down
24 changes: 24 additions & 0 deletions test/DiTest.php
Expand Up @@ -640,4 +640,28 @@ public function testDiWillInjectDependenciesForAlias()
$b = $di->get('b_alias');
$this->assertInstanceOf('ZendTest\Di\TestAsset\SetterInjection\A', $b->a);
}

/*
* @group SetterInjection
* @group SupertypeResolution
*/
public function testInjectionForSetterInjectionWillNotUseSupertypeWhenChildParamIsExplicitlyDefined()
{
$di = new Di();
// for setter injection, the dependency is not required, thus it must be forced
$di->instanceManager()->setParameters(
'ZendTest\Di\TestAsset\InheritanceClasses\B',
array('test' => 'b')
);
$di->instanceManager()->setParameters(
'ZendTest\Di\TestAsset\InheritanceClasses\A',
array('test' => 'a')
);

$b = $di->get('ZendTest\Di\TestAsset\InheritanceClasses\B');
$this->assertEquals('b', $b->test);

$c = $di->get('ZendTest\Di\TestAsset\InheritanceClasses\C');
$this->assertEquals('b', $c->test);
}
}
14 changes: 14 additions & 0 deletions test/TestAsset/InheritanceClasses/A.php
@@ -0,0 +1,14 @@
<?php

namespace ZendTest\Di\TestAsset\InheritanceClasses;

class A
{
public $test;

public function setTest($test)
{
$this->test = $test;
return $this;
}
}
7 changes: 7 additions & 0 deletions test/TestAsset/InheritanceClasses/B.php
@@ -0,0 +1,7 @@
<?php

namespace ZendTest\Di\TestAsset\InheritanceClasses;

class B extends A
{
}
7 changes: 7 additions & 0 deletions test/TestAsset/InheritanceClasses/C.php
@@ -0,0 +1,7 @@
<?php

namespace ZendTest\Di\TestAsset\InheritanceClasses;

class C extends B
{
}

0 comments on commit ae0af2f

Please sign in to comment.