Upgraded drupal core with security updates
[yaffs-website] / web / core / lib / Drupal / Core / ParamConverter / ParamConverterManager.php
1 <?php
2
3 namespace Drupal\Core\ParamConverter;
4
5 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
6 use Symfony\Component\Routing\RouteCollection;
7
8 /**
9  * Manages converter services for converting request parameters to full objects.
10  *
11  * A typical use case for this would be upcasting (converting) a node id to a
12  * node entity.
13  */
14 class ParamConverterManager implements ParamConverterManagerInterface {
15
16   /**
17    * Array of loaded converter services keyed by their ids.
18    *
19    * @var array
20    */
21   protected $converters = [];
22
23   /**
24    * {@inheritdoc}
25    */
26   public function addConverter(ParamConverterInterface $param_converter, $id) {
27     $this->converters[$id] = $param_converter;
28     return $this;
29   }
30
31   /**
32    * {@inheritdoc}
33    */
34   public function getConverter($converter) {
35     if (isset($this->converters[$converter])) {
36       return $this->converters[$converter];
37     }
38     else {
39       throw new \InvalidArgumentException(sprintf('No converter has been registered for %s', $converter));
40     }
41   }
42
43   /**
44    * {@inheritdoc}
45    */
46   public function setRouteParameterConverters(RouteCollection $routes) {
47     foreach ($routes->all() as $route) {
48       if (!$parameters = $route->getOption('parameters')) {
49         // Continue with the next route if no parameters have been defined.
50         continue;
51       }
52
53       // Loop over all defined parameters and look up the right converter.
54       foreach ($parameters as $name => &$definition) {
55         if (isset($definition['converter'])) {
56           // Skip parameters that already have a manually set converter.
57           continue;
58         }
59
60         foreach (array_keys($this->converters) as $converter) {
61           if ($this->getConverter($converter)->applies($definition, $name, $route)) {
62             $definition['converter'] = $converter;
63             break;
64           }
65         }
66       }
67
68       // Override the parameters array.
69       $route->setOption('parameters', $parameters);
70     }
71   }
72
73   /**
74    * {@inheritdoc}
75    */
76   public function convert(array $defaults) {
77     /** @var $route \Symfony\Component\Routing\Route */
78     $route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
79
80     // Skip this enhancer if there are no parameter definitions.
81     if (!$parameters = $route->getOption('parameters')) {
82       return $defaults;
83     }
84
85     // Invoke the registered converter for each parameter.
86     foreach ($parameters as $name => $definition) {
87       if (!isset($defaults[$name])) {
88         // Do not try to convert anything that is already set to NULL.
89         continue;
90       }
91
92       if (!isset($definition['converter'])) {
93         // Continue if no converter has been specified.
94         continue;
95       }
96
97       // If a converter returns NULL it means that the parameter could not be
98       // converted.
99       $defaults[$name] = $this->getConverter($definition['converter'])->convert($defaults[$name], $definition, $name, $defaults);
100       if (!isset($defaults[$name])) {
101         throw new ParamNotConvertedException(sprintf('The "%s" parameter was not converted for the path "%s" (route name: "%s")', $name, $route->getPath(), $defaults[RouteObjectInterface::ROUTE_NAME]));
102       }
103     }
104
105     return $defaults;
106   }
107
108 }