Version 1
[yaffs-website] / web / core / lib / Drupal / Component / Utility / ArgumentsResolver.php
diff --git a/web/core/lib/Drupal/Component/Utility/ArgumentsResolver.php b/web/core/lib/Drupal/Component/Utility/ArgumentsResolver.php
new file mode 100644 (file)
index 0000000..0bd53b2
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+
+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 = [];
+    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()));
+  }
+
+}