drupalmoduleupgrader-8.x-1.5/src/Routing/ParameterMap.php
src/Routing/ParameterMap.php
<?php
namespace Drupal\drupalmoduleupgrader\Routing;
use Doctrine\Common\Collections\ArrayCollection;
use Drupal\drupalmoduleupgrader\Utility\Path\Drupal7\PathComponent;
use Drupal\drupalmoduleupgrader\Utility\Path\Drupal8\PathComponent as PathComponent8x;
use Drupal\drupalmoduleupgrader\Utility\Path\PathUtilityInterface;
use Symfony\Component\Routing\Route as Drupal8Route;
/**
* Represents a set of parameter bindings for a particular path, callback,
* and set of arguments.
*/
class ParameterMap extends ArrayCollection {
/**
* @var \Drupal\drupalmoduleupgrader\Utility\Path\PathUtilityInterface
*/
protected $path;
/**
* @var int
*/
protected $_length = 0;
protected $bindings = [];
/**
* {@inheritdoc}
*/
public function __construct(PathUtilityInterface $path, array $parameters, array $arguments = []) {
parent::__construct();
$this->path = $path;
$this->_length = sizeof($path);
while ($parameters) {
$argument = $arguments ? array_shift($arguments) : ParameterBinding::NO_ARGUMENT;
$this->addBinding(new ParameterBinding($path, array_shift($parameters), $argument));
}
}
/**
* {@inheritdoc}
*/
public function toArray() {
$output = [];
foreach ($this->bindings as $key => $bindings) {
if (is_integer($key)) {
/** @var ParameterBinding[] $bindings */
foreach ($bindings as $binding) {
$parameter = $binding->getParameter()->getName();
$function = $binding->getParameter()->getFunction()->getName()->getText();
$output[$function][$parameter]['name'] = $bindings[0]->getParameter()->getName();
$value = $bindings[0]->getValue();
if ($value instanceof PathComponent && $value->isWildcard()) {
$output[$function][$parameter]['type'] = ltrim($value, '%');
}
}
}
}
return $output;
}
/**
* Merge another parameter map into this one. Bindings from the incoming map
* should 'win', although the specifics are up to the implementing classes.
*
* @param ParameterMap $map
* The parameter map to merge.
*/
public function merge(ParameterMap $map) {
foreach ($map as $binding) {
$this->addBinding($binding);
}
}
/**
* Adds a binding to this map, overwriting the existing one if there is a
* conflict.
*
* @param ParameterBinding $binding
* The binding to add.
*/
public function addBinding(ParameterBinding $binding) {
$value = $binding->getValue();
// The binding will return a PathComponent if it expects to be physically
// represented in the path, whether or not it already is.
if ($value instanceof PathComponent) {
if ($binding->inPath()) {
$key = $binding->getArgument();
}
else {
$key = $this->path->indexOf($value);
if ($key === FALSE) {
$key = $this->_length++;
}
}
}
else {
$key = $binding->getParameter()->getName();
}
$this->set($key, $binding);
if (!isset($this->bindings[$key])) {
$this->bindings[$key] = [];
}
array_unshift($this->bindings[$key], $binding);
}
/**
* Applies the parameter map to a path, modifying it as needed.
*
* @param \Drupal\drupalmoduleupgrader\Utility\Path\PathUtilityInterface $path
* The path to modify (in-place).
*/
public function applyPath(PathUtilityInterface $path) {
foreach ($this as $key => $binding) {
if (is_integer($key)) {
$path[$key] = new PathComponent8x('{' . $binding->getParameter()->getName() . '}');
}
}
}
/**
* Apply the parameter map to a Drupal 8 route, modifying it as needed.
*
* @param \Symfony\Component\Routing\Route $route
* The route to process.
*/
public function applyRoute(Drupal8Route $route) {
$this->applyPath($this->path);
foreach ($this as $key => $binding) {
$parameter = $binding->getParameter();
/** @var ParameterBinding $binding */
if (is_integer($key)) {
if ($parameter->isOptional()) {
// @todo Don't use eval().
$value = eval('return ' . $parameter->getValue() . ';');
$route->setDefault($parameter->getName(), $value);
}
}
elseif ($binding->hasArgument()) {
$route->setDefault($parameter->getName(), $binding->getValue());
}
}
$route->setPath($this->path->__toString());
}
}
