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

Commit

Permalink
Merge branch 'hotfix/di'
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralph Schindler committed Nov 4, 2011
Show file tree
Hide file tree
Showing 12 changed files with 403 additions and 136 deletions.
5 changes: 5 additions & 0 deletions src/Definition/ClassDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public function addMethod($method, $isRequired = null)
$this->methods[$method] = (bool) $isRequired;
}

/**
* @param $method
* @param $parameterName
* @param array $parameterInfo (keys: required, type)
*/
public function addMethodParameter($method, $parameterName, array $parameterInfo)
{
if (!array_key_exists($method, $this->methods)) {
Expand Down
129 changes: 91 additions & 38 deletions src/Di.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,19 @@ public function newInstance($name, array $params = array(), $isShared = true)
if (array_key_exists('__construct', $injectionMethods)) {
unset($injectionMethods['__construct']);
}
} elseif (is_callable($instantiator)) {
} elseif (is_callable($instantiator, false)) {
$object = $this->createInstanceViaCallback($instantiator, $params, $alias);
} else {
throw new Exception\RuntimeException('Invalid instantiator');
if (is_array($instantiator)) {
$msg = sprintf(
'Invalid instantiator: %s::%s() is not callable.',
isset($instantiator[0]) ? $instantiator[0] : 'NoClassGiven',
isset($instantiator[1]) ? $instantiator[1] : 'NoMethodGiven'
);
} else {
$msg = 'Invalid instantiator: ' . $instantiator;
}
throw new \RuntimeException($msg);
}

if ($isShared) {
Expand All @@ -197,17 +206,35 @@ public function newInstance($name, array $params = array(), $isShared = true)
$instanceConfiguration = $instanceManager->getConfiguration($name);

if ($instanceConfiguration['injections']) {
$objectsToInject = array();
foreach ($instanceConfiguration['injections'] as $classAliasToInject) {
$objectsToInject[] = $this->get($classAliasToInject, $params);
$objectsToInject = $methodsToCall = array();
foreach ($instanceConfiguration['injections'] as $injectName => $injectValue) {
if (is_int($injectName) && is_string($injectValue)) {
$objectsToInject[] = $this->get($injectValue, $params);
} elseif (is_string($injectName) && is_array($injectValue)) {
if (is_string(key($injectValue))) {
$methodsToCall[] = array('method' => $injectName, 'args' => $injectValue);
} else {
foreach ($injectValue as $methodCallArgs) {
$methodsToCall[] = array('method' => $injectName, 'args' => $methodCallArgs);
}
}
} elseif (is_object($injectValue)) {
$objectsToInject[] = $injectValue;
} elseif (is_int($injectName) && is_array($injectValue)) {
// @todo must find method name somehow
throw new Exception\RuntimeException(
'An injection was provided with a keyed index and an array of data, try using'
. ' the name of a particular method as a key for your injection data.'
);
}
}
if ($objectsToInject) {
// @todo this needs to be optimized
foreach ($objectsToInject as $objectToInject) {
foreach ($injectionMethods as $injectionMethod => $methodIsRequired) {
if ($methodParams = $definitions->getMethodParameters($class, $injectionMethod)) {
foreach ($methodParams as $methodParam) {
if ($this->isSubclassOf(get_class($objectToInject), $methodParam[1])) {
if (get_class($objectToInject) == $methodParam[1] ||
$this->isSubclassOf(get_class($objectToInject), $methodParam[1])) {
$callParams = $this->resolveMethodParameters(get_class($object), $injectionMethod,
array($methodParam[0] => $objectToInject), false, $alias, true
);
Expand All @@ -221,6 +248,14 @@ public function newInstance($name, array $params = array(), $isShared = true)
}
}
}
if ($methodsToCall) {
foreach ($methodsToCall as $methodInfo) {
$callParams = $this->resolveMethodParameters(get_class($object), $methodInfo['method'],
$methodInfo['args'], false, $alias, true
);
call_user_func_array(array($object, $methodInfo['method']), $callParams);
}
}
}
}

Expand All @@ -234,21 +269,23 @@ public function newInstance($name, array $params = array(), $isShared = true)
* @todo
* @param unknown_type $object
*/
public function injectObjects($targetObject, array $objects = array())
{
if ($objects === array()) {
throw new \Exception('Not yet implmeneted');
}
/*
public function injectObjects($targetObject, array $objects = array())
{
if ($objects === array()) {
throw new \Exception('Not yet implmeneted');
}
$targetClass = get_class($targetObject);
if (!$this->definitions()->hasClass($targetClass)) {
throw new Exception\RuntimeException('A definition for this object type cannot be found');
}
$targetClass = get_class($targetObject);
if (!$this->definitions()->hasClass($targetClass)) {
throw new Exception\RuntimeException('A definition for this object type cannot be found');
}
foreach ($objects as $objectToInject) {
foreach ($objects as $objectToInject) {
}
}
}
}
*/

/**
* Retrieve a class instance based on class name
Expand Down Expand Up @@ -303,6 +340,8 @@ protected function createInstanceViaCallback($callback, $params, $alias)
if (is_array($callback)) {
$class = (is_object($callback[0])) ? get_class($callback[0]) : $callback[0];
$method = $callback[1];
} elseif (is_string($callback) && strpos($callback, '::') !== false) {
list($class, $method) = explode('::', $callback, 2);
} else {
throw new Exception\RuntimeException('Invalid callback type provided to ' . __METHOD__);
}
Expand Down Expand Up @@ -397,29 +436,34 @@ protected function resolveMethodParameters($class, $method, array $callTimeUserP
if (isset($callTimeUserParams[$fqName]) || isset($callTimeUserParams[$name])) {

// @todo FQ Name in call time params
if (isset($callTimeUserParams[$fqName])) throw \Exception('Implementation incomplete for fq names');
if (isset($callTimeUserParams[$fqName])) {
$callTimeCurValue =& $callTimeUserParams[$fqName];
} else {
$callTimeCurValue =& $callTimeUserParams[$name];
}

if (is_string($callTimeUserParams[$name])) {
if ($this->instanceManager->hasAlias($callTimeUserParams[$name])) {
if (is_string($callTimeCurValue)) {
if ($this->instanceManager->hasAlias($callTimeCurValue)) {
// was an alias provided?
$computedParams['required'][$fqName] = array(
$callTimeUserParams[$name],
$this->instanceManager->getClassFromAlias($callTimeUserParams[$name])
$this->instanceManager->getClassFromAlias($callTimeCurValue)
);
} elseif ($this->definitions->hasClass($callTimeUserParams[$name])) {
// was a known class provided?
$computedParams['required'][$fqName] = array(
$callTimeUserParams[$name],
$callTimeUserParams[$name]
$callTimeCurValue,
$callTimeCurValue
);
} else {
// must be a value
$computedParams['value'][$fqName] = $callTimeUserParams[$name];
$computedParams['value'][$fqName] = $callTimeCurValue;
}
} else {
// int, float, null, object, etc
$computedParams['value'][$fqName] = $callTimeUserParams[$name];
$computedParams['value'][$fqName] = $callTimeCurValue;
}
unset($callTimeCurValue);
continue;
}

Expand All @@ -433,26 +477,35 @@ protected function resolveMethodParameters($class, $method, array $callTimeUserP
if (isset($iConfig[$thisIndex]['parameters'][$fqName]) || isset($iConfig[$thisIndex]['parameters'][$name])) {

// @todo FQ Name in config parameters
if (isset($iConfig[$thisIndex]['parameters'][$fqName])) throw \Exception('Implementation incomplete for fq names');
if (isset($iConfig[$thisIndex]['parameters'][$fqName])) {
$iConfigCurValue =& $iConfig[$thisIndex]['parameters'][$fqName];
} else {
$iConfigCurValue =& $iConfig[$thisIndex]['parameters'][$name];
}

if (is_string($iConfig[$thisIndex]['parameters'][$name])
if (is_string($iConfigCurValue)
&& $type === false) {
$computedParams['value'][$fqName] = $iConfig[$thisIndex]['parameters'][$name];
} elseif (is_string($iConfig[$thisIndex]['parameters'][$name])
&& isset($aliases[$iConfig[$thisIndex]['parameters'][$name]])) {
$computedParams['value'][$fqName] = $iConfigCurValue;
} elseif (is_string($iConfigCurValue)
&& isset($aliases[$iConfigCurValue])) {
$computedParams['required'][$fqName] = array(
$iConfig[$thisIndex]['parameters'][$name],
$this->instanceManager->getClassFromAlias($iConfig[$thisIndex]['parameters'][$name])
$this->instanceManager->getClassFromAlias($iConfigCurValue)
);
} elseif (is_string($iConfig[$thisIndex]['parameters'][$name])
&& $this->definitions->hasClass($iConfig[$thisIndex]['parameters'][$name])) {
} elseif (is_string($iConfigCurValue)
&& $this->definitions->hasClass($iConfigCurValue)) {
$computedParams['required'][$fqName] = array(
$iConfig[$thisIndex]['parameters'][$name],
$iConfig[$thisIndex]['parameters'][$name]
$iConfigCurValue,
$iConfigCurValue
);
} elseif (is_object($iConfigCurValue)
&& $iConfigCurValue instanceof \Closure
&& $type !== 'Closure') {
$computedParams['value'][$fqName] = $iConfigCurValue();
} else {
$computedParams['value'][$fqName] = $iConfig[$thisIndex]['parameters'][$name];
$computedParams['value'][$fqName] = $iConfigCurValue;
}
unset($iConfigCurValue);
continue 2;
}

Expand Down
49 changes: 1 addition & 48 deletions test/ConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,53 +72,6 @@ public function testConfigurationCanConfigureBuilderDefinitionFromIni()

}

public function testCanSetInstantiatorToStaticFactory()
{
$config = new Configuration(array(
'definition' => array(
'class' => array(
'ZendTest\Di\TestAsset\DummyParams' => array(
'instantiator' => array('ZendTest\Di\TestAsset\StaticFactory', 'factory'),
),
'ZendTest\Di\TestAsset\StaticFactory' => array(
'methods' => array(
'factory' => array(
'struct' => array(
'type' => 'ZendTest\Di\TestAsset\Struct',
'required' => true,
),
'params' => array(
'required' => true,
),
),
),
),
),
),
'instance' => array(
'ZendTest\Di\TestAsset\DummyParams' => array(
'parameters' => array(
'struct' => 'ZendTest\Di\TestAsset\Struct',
'params' => array(
'foo' => 'bar',
),
),
),
'ZendTest\Di\TestAsset\Struct' => array(
'parameters' => array(
'param1' => 'hello',
'param2' => 'world',
),
),
),
));
$di = new Di();
$di->configure($config);
$dummyParams = $di->get('ZendTest\Di\TestAsset\DummyParams');
$this->assertEquals($dummyParams->params['param1'], 'hello');
$this->assertEquals($dummyParams->params['param2'], 'world');
$this->assertEquals($dummyParams->params['foo'], 'bar');
$this->assertArrayNotHasKey('methods', $di->definitions()->hasMethods('ZendTest\Di\TestAsset\StaticFactory'));
}


}

0 comments on commit 730ce14

Please sign in to comment.