public static create ( DI\Definition\Definition $definition, $message ) | ||
$definition | DI\Definition\Definition |
/** * Resolve a function call definition to a value. * * This will call the function and return its result. * * @param FunctionCallDefinition $definition * * {@inheritdoc} */ public function resolve(Definition $definition, array $parameters = array()) { $this->assertIsFunctionCallDefinition($definition); $callable = $definition->getCallable(); $functionReflection = CallableReflectionFactory::fromCallable($callable); try { $args = $this->parameterResolver->resolveParameters($definition, $functionReflection, $parameters); } catch (DefinitionException $e) { throw DefinitionException::create($definition, $e->getMessage()); } if ($functionReflection instanceof \ReflectionFunction) { return $functionReflection->invokeArgs($args); } /** @var \ReflectionMethod $functionReflection */ if ($functionReflection->isStatic()) { // Static method $object = null; } elseif (is_object($callable)) { // Callable object $object = $callable; } elseif (is_string($callable)) { // Callable class (need to be instantiated) $object = $this->container->get($callable); } elseif (is_string($callable[0])) { // Class method $object = $this->container->get($callable[0]); } else { // Object method $object = $callable[0]; } return $functionReflection->invokeArgs($object, $args); }
private function assertClassIsInstantiable(ObjectDefinition $definition, ReflectionClass $classReflection) { if (!$classReflection->isInstantiable()) { throw DefinitionException::create($definition, sprintf("Entry %s cannot be resolved: class %s is not instantiable", $definition->getName(), $definition->getClassName())); } }
/** * Fixes parameters indexed by the parameter name -> reindex by position. * * This is necessary so that merging definitions between sources is possible. * * @param ObjectDefinition $definition * @param string $method * @param array $parameters * @throws DefinitionException * @return array */ private function fixParameters(ObjectDefinition $definition, $method, $parameters) { $fixedParameters = []; foreach ($parameters as $index => $parameter) { // Parameter indexed by the parameter name, we reindex it with its position if (is_string($index)) { $callable = [$definition->getClassName(), $method]; try { $reflectionParameter = new \ReflectionParameter($callable, $index); } catch (\ReflectionException $e) { throw DefinitionException::create($definition, sprintf("Parameter with name '%s' could not be found. %s.", $index, $e->getMessage())); } $index = $reflectionParameter->getPosition(); } $fixedParameters[$index] = $parameter; } return $fixedParameters; }
/** * Create the parameter array to call a method. * * @param ClassDefinition $definition * @param MethodInjection $methodInjection * @param ReflectionMethod $methodReflection * @param array $parameters Force some parameters to specific values. * * @throws DefinitionException A parameter has no defined or guessable value. * @return array Array of parameters to use to call the method. */ private function prepareMethodParameters(ClassDefinition $definition, MethodInjection $methodInjection = null, ReflectionMethod $methodReflection = null, array $parameters = array()) { if (!$methodReflection) { return array(); } $args = array(); foreach ($methodReflection->getParameters() as $index => $parameter) { if (array_key_exists($parameter->getName(), $parameters)) { // Look in the $parameters array $value = $parameters[$parameter->getName()]; } elseif ($methodInjection && $methodInjection->hasParameter($index)) { // Look in the definition $value = $methodInjection->getParameter($index); } else { // If the parameter is optional and wasn't specified, we take its default value if ($parameter->isOptional()) { $args[] = $this->getParameterDefaultValue($parameter, $methodReflection); continue; } throw DefinitionException::create($definition, sprintf("The parameter '%s' of %s::%s has no value defined or guessable", $parameter->getName(), $methodReflection->getDeclaringClass()->getName(), $methodReflection->getName())); } if ($value instanceof EntryReference) { $args[] = $this->container->get($value->getName()); } else { $args[] = $value; } } return $args; }
private function assertClassIsInstantiable(ObjectDefinition $definition) { if (!$definition->isInstantiable()) { throw DefinitionException::create($definition, sprintf('Entry "%s" cannot be resolved: the class is not instantiable', $definition->getName())); } }