class ArgumentsResolver

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Component/Utility/ArgumentsResolver.php \Drupal\Component\Utility\ArgumentsResolver
  2. 8.9.x core/lib/Drupal/Component/Utility/ArgumentsResolver.php \Drupal\Component\Utility\ArgumentsResolver
  3. 11.x core/lib/Drupal/Component/Utility/ArgumentsResolver.php \Drupal\Component\Utility\ArgumentsResolver

Resolves the arguments to pass to a callable.

Hierarchy

Expanded class hierarchy of ArgumentsResolver

3 files declare their use of ArgumentsResolver
AccessArgumentsResolverFactory.php in core/lib/Drupal/Core/Access/AccessArgumentsResolverFactory.php
ArgumentsResolverTest.php in core/tests/Drupal/Tests/Component/Utility/ArgumentsResolverTest.php
RequestHandler.php in core/modules/rest/src/RequestHandler.php

File

core/lib/Drupal/Component/Utility/ArgumentsResolver.php, line 8

Namespace

Drupal\Component\Utility
View source
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 = [];
    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 = Reflection::getParameterClassName($parameter);
    $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) {
      $parameter_type_hint = new \ReflectionClass($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) {
    if (is_array($callable)) {
      return new \ReflectionMethod($callable[0], $callable[1]);
    }
    if (is_string($callable) && str_contains($callable, "::")) {
      return PHP_VERSION_ID < 80300 ? new \ReflectionMethod($callable) : \ReflectionMethod::createFromMethodName($callable);
    }
    return 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()));
  }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
ArgumentsResolver::$objects protected property An associative array of parameter names to object candidate values.
ArgumentsResolver::$scalars protected property An associative array of parameter names to scalar candidate values.
ArgumentsResolver::$wildcards protected property An array object candidates tried on every parameter regardless of name.
ArgumentsResolver::getArgument protected function Gets the argument value for a parameter.
ArgumentsResolver::getArguments public function Gets arguments suitable for passing to the given callable. Overrides ArgumentsResolverInterface::getArguments
ArgumentsResolver::getReflector protected function Gets a reflector for the access check callable.
ArgumentsResolver::handleUnresolvedArgument protected function Handles unresolved arguments for getArgument().
ArgumentsResolver::__construct public function Constructs a new ArgumentsResolver.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.