Mercurial > hg > isophonics-drupal-site
diff core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,111 @@ +<?php + +namespace Drupal\Core\ParamConverter; + +use Symfony\Cmf\Component\Routing\RouteObjectInterface; +use Symfony\Component\Routing\RouteCollection; + +/** + * Manages converter services for converting request parameters to full objects. + * + * A typical use case for this would be upcasting (converting) a node id to a + * node entity. + */ +class ParamConverterManager implements ParamConverterManagerInterface { + + /** + * Array of loaded converter services keyed by their ids. + * + * @var array + */ + protected $converters = []; + + /** + * {@inheritdoc} + */ + public function addConverter(ParamConverterInterface $param_converter, $id) { + $this->converters[$id] = $param_converter; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getConverter($converter) { + if (isset($this->converters[$converter])) { + return $this->converters[$converter]; + } + else { + throw new \InvalidArgumentException(sprintf('No converter has been registered for %s', $converter)); + } + } + + /** + * {@inheritdoc} + */ + public function setRouteParameterConverters(RouteCollection $routes) { + foreach ($routes->all() as $route) { + if (!$parameters = $route->getOption('parameters')) { + // Continue with the next route if no parameters have been defined. + continue; + } + + // Loop over all defined parameters and look up the right converter. + foreach ($parameters as $name => &$definition) { + if (isset($definition['converter'])) { + // Skip parameters that already have a manually set converter. + continue; + } + + foreach (array_keys($this->converters) as $converter) { + if ($this->getConverter($converter)->applies($definition, $name, $route)) { + $definition['converter'] = $converter; + break; + } + } + } + + // Override the parameters array. + $route->setOption('parameters', $parameters); + } + } + + /** + * {@inheritdoc} + */ + public function convert(array $defaults) { + /** @var $route \Symfony\Component\Routing\Route */ + $route = $defaults[RouteObjectInterface::ROUTE_OBJECT]; + + // Skip this enhancer if there are no parameter definitions. + if (!$parameters = $route->getOption('parameters')) { + return $defaults; + } + + // Invoke the registered converter for each parameter. + foreach ($parameters as $name => $definition) { + if (!isset($defaults[$name])) { + // Do not try to convert anything that is already set to NULL. + continue; + } + + if (!isset($definition['converter'])) { + // Continue if no converter has been specified. + continue; + } + + // If a converter returns NULL it means that the parameter could not be + // converted. + $value = $defaults[$name]; + $defaults[$name] = $this->getConverter($definition['converter'])->convert($value, $definition, $name, $defaults); + if (!isset($defaults[$name])) { + $message = 'The "%s" parameter was not converted for the path "%s" (route name: "%s")'; + $route_name = $defaults[RouteObjectInterface::ROUTE_NAME]; + throw new ParamNotConvertedException(sprintf($message, $name, $route->getPath(), $route_name), 0, NULL, $route_name, [$name => $value]); + } + } + + return $defaults; + } + +}