/** * @param MethodInjection $definition * @param \ReflectionFunctionAbstract $functionReflection * @param array $parameters * * @throws DefinitionException A parameter has no value defined or guessable. * @return array Parameters to use to call the function. */ public function resolveParameters(MethodInjection $definition = null, \ReflectionFunctionAbstract $functionReflection = null, array $parameters = []) { $args = []; if (!$functionReflection) { return $args; } $definitionParameters = $definition ? $definition->getParameters() : array(); foreach ($functionReflection->getParameters() as $index => $parameter) { if (array_key_exists($parameter->getName(), $parameters)) { // Look in the $parameters array $value =& $parameters[$parameter->getName()]; } elseif (array_key_exists($index, $definitionParameters)) { // Look in the definition $value =& $definitionParameters[$index]; } else { // If the parameter is optional and wasn't specified, we take its default value if ($parameter->isOptional()) { $args[] = $this->getParameterDefaultValue($parameter, $functionReflection); continue; } throw new DefinitionException(sprintf("The parameter '%s' of %s has no value defined or guessable", $parameter->getName(), $this->getFunctionName($functionReflection))); } if ($value instanceof DefinitionHelper) { $nestedDefinition = $value->getDefinition(''); // If the container cannot produce the entry, we can use the default parameter value if ($parameter->isOptional() && !$this->definitionResolver->isResolvable($nestedDefinition)) { $value = $this->getParameterDefaultValue($parameter, $functionReflection); } else { $value = $this->definitionResolver->resolve($nestedDefinition); } } $args[] =& $value; } return $args; }
private function dumpMethodParameters($className, MethodInjection $methodInjection) { $methodReflection = new \ReflectionMethod($className, $methodInjection->getMethodName()); $args = []; $definitionParameters = $methodInjection->getParameters(); foreach ($methodReflection->getParameters() as $index => $parameter) { if (array_key_exists($index, $definitionParameters)) { $value = $definitionParameters[$index]; if ($value instanceof EntryReference) { $args[] = sprintf('$%s = get(%s)', $parameter->getName(), $value->getName()); } else { $args[] = sprintf('$%s = %s', $parameter->getName(), var_export($value, true)); } continue; } // If the parameter is optional and wasn't specified, we take its default value if ($parameter->isOptional()) { try { $value = $parameter->getDefaultValue(); $args[] = sprintf('$%s = (default value) %s', $parameter->getName(), var_export($value, true)); continue; } catch (ReflectionException $e) { // The default value can't be read through Reflection because it is a PHP internal class } } $args[] = sprintf('$%s = #UNDEFINED#', $parameter->getName()); } return implode(PHP_EOL . ' ', $args); }
private function mergeConstructorInjection(ObjectDefinition $definition) { if ($definition->getConstructorInjection() !== null) { if ($this->constructorInjection !== null) { // Merge $this->constructorInjection->merge($definition->getConstructorInjection()); } else { // Set $this->constructorInjection = $definition->getConstructorInjection(); } } }
/** * {@inheritdoc} */ public function getDefinition($name) { if (!class_exists($name) && !interface_exists($name)) { return null; } $definition = new ObjectDefinition($name); // Constructor $class = new \ReflectionClass($name); $constructor = $class->getConstructor(); if ($constructor && $constructor->isPublic()) { $definition->setConstructorInjection(MethodInjection::constructor($this->getParametersDefinition($constructor))); } return $definition; }
/** * {@inheritdoc} */ public function getDefinition($entryName) { $definition = new ObjectDefinition($entryName, $this->className); if ($this->lazy !== null) { $definition->setLazy($this->lazy); } if ($this->scope !== null) { $definition->setScope($this->scope); } if (!empty($this->constructor)) { $parameters = $this->fixParameters($definition, '__construct', $this->constructor); $constructorInjection = MethodInjection::constructor($parameters); $definition->setConstructorInjection($constructorInjection); } if (!empty($this->properties)) { foreach ($this->properties as $property => $value) { $definition->addPropertyInjection(new PropertyInjection($property, $value)); } } if (!empty($this->methods)) { foreach ($this->methods as $method => $calls) { foreach ($calls as $parameters) { $parameters = $this->fixParameters($definition, $method, $parameters); $methodInjection = new MethodInjection($method, $parameters); $definition->addMethodInjection($methodInjection); } } } return $definition; }
private function getMethodInjection(ReflectionMethod $method) { // Look for @Inject annotation /** @var $annotation Inject|null */ try { $annotation = $this->getAnnotationReader()->getMethodAnnotation($method, 'DI\\Annotation\\Inject'); } catch (AnnotationException $e) { throw new AnnotationException(sprintf('@Inject annotation on %s::%s is malformed. %s', $method->getDeclaringClass()->getName(), $method->getName(), $e->getMessage()), 0, $e); } $annotationParameters = $annotation ? $annotation->getParameters() : []; // @Inject on constructor is implicit if (!($annotation || $method->isConstructor())) { return null; } $parameters = []; foreach ($method->getParameters() as $index => $parameter) { $entryName = $this->getMethodParameter($index, $parameter, $annotationParameters); if ($entryName !== null) { $parameters[$index] = new EntryReference($entryName); } } if ($method->isConstructor()) { return MethodInjection::constructor($parameters); } else { return new MethodInjection($method->getName(), $parameters); } }