Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
30 / 30
ArgumentsResolver
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
5 / 5
19
100.00% covered (success)
100.00%
30 / 30
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
4 / 4
 getArguments
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 getArgument
100.00% covered (success)
100.00%
1 / 1
11
100.00% covered (success)
100.00%
15 / 15
 getReflector
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 handleUnresolvedArgument
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
6 / 6
<?php
/**
 * @file
 * Contains \Drupal\Component\Utility\ArgumentsResolver.
 */
namespace Drupal\Component\Utility;
/**
 * Resolves the arguments to pass to a callable.
 */
class ArgumentsResolver implements ArgumentsResolverInterface {
  /**
   * An associative array of parameter names to scalar candidate values.
   *
   * @var array
   */
  protected $scalars;
  /**
   * An associative array of parameter names to object candidate values.
   *
   * @var array
   */
  protected $objects;
  /**
   * An array object candidates tried on every parameter regardless of name.
   *
   * @var array
   */
  protected $wildcards;
  /**
   * Constructs a new ArgumentsResolver.
   *
   * @param array $scalars
   *   An associative array of parameter names to scalar candidate values.
   * @param object[] $objects
   *   An associative array of parameter names to object candidate values.
   * @param object[] $wildcards
   *   An array object candidates tried on every parameter regardless of its
   *   name.
   */
  public function __construct(array $scalars, array $objects, array $wildcards) {
    $this->scalars = $scalars;
    $this->objects = $objects;
    $this->wildcards = $wildcards;
  }
  /**
   * {@inheritdoc}
   */
  public function getArguments(callable $callable) {
    $arguments = array();
    foreach ($this->getReflector($callable)->getParameters() as $parameter) {
      $arguments[] = $this->getArgument($parameter);
    }
    return $arguments;
  }
  /**
   * Gets the argument value for a parameter.
   *
   * @param \ReflectionParameter $parameter
   *   The parameter of a callable to get the value for.
   *
   * @return mixed
   *   The value of the requested parameter value.
   *
   * @throws \RuntimeException
   *   Thrown when there is a missing parameter.
   */
  protected function getArgument(\ReflectionParameter $parameter) {
    $parameter_type_hint = $parameter->getClass();
    $parameter_name = $parameter->getName();
    // If the argument exists and is NULL, return it, regardless of
    // parameter type hint.
    if (!isset($this->objects[$parameter_name]) && array_key_exists($parameter_name, $this->objects)) {
      return NULL;
    }
    if ($parameter_type_hint) {
      // If the argument exists and complies with the type hint, return it.
      if (isset($this->objects[$parameter_name]) && is_object($this->objects[$parameter_name]) && $parameter_type_hint->isInstance($this->objects[$parameter_name])) {
        return $this->objects[$parameter_name];
      }
      // Otherwise, resolve wildcard arguments by type matching.
      foreach ($this->wildcards as $wildcard) {
        if ($parameter_type_hint->isInstance($wildcard)) {
          return $wildcard;
        }
      }
    }
    elseif (isset($this->scalars[$parameter_name])) {
      return $this->scalars[$parameter_name];
    }
    // If the callable provides a default value, use it.
    if ($parameter->isDefaultValueAvailable()) {
      return $parameter->getDefaultValue();
    }
    // Can't resolve it: call a method that throws an exception or can be
    // overridden to do something else.
    return $this->handleUnresolvedArgument($parameter);
  }
  /**
   * Gets a reflector for the access check callable.
   *
   * The access checker may be either a procedural function (in which case the
   * callable is the function name) or a method (in which case the callable is
   * an array of the object and method name).
   *
   * @param callable $callable
   *   The callable (either a function or a method).
   *
   * @return \ReflectionFunctionAbstract
   *   The ReflectionMethod or ReflectionFunction to introspect the callable.
   */
  protected function getReflector(callable $callable) {
    return is_array($callable) ? new \ReflectionMethod($callable[0], $callable[1]) : new \ReflectionFunction($callable);
  }
  /**
   * Handles unresolved arguments for getArgument().
   *
   * Subclasses that override this method may return a default value
   * instead of throwing an exception.
   *
   * @throws \RuntimeException
   *   Thrown when there is a missing parameter.
   */
  protected function handleUnresolvedArgument(\ReflectionParameter $parameter) {
    $class = $parameter->getDeclaringClass();
    $function = $parameter->getDeclaringFunction();
    if ($class && !$function->isClosure()) {
      $function_name = $class->getName() . '::' . $function->getName();
    }
    else {
      $function_name = $function->getName();
    }
    throw new \RuntimeException(sprintf('Callable "%s" requires a value for the "$%s" argument.', $function_name, $parameter->getName()));
  }
}