‪TYPO3CMS  9.5
ExtbasePluginEnhancer.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
3 
5 
6 /*
7  * This file is part of the TYPO3 CMS project.
8  *
9  * It is free software; you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License, either version 2
11  * of the License, or any later version.
12  *
13  * For the full copyright and license information, please read the
14  * LICENSE.txt file that was distributed with this source code.
15  *
16  * The TYPO3 project - inspiring people to share!
17  */
18 
22 
41 {
45  protected ‪$routesOfPlugin;
46 
47  public function ‪__construct(array ‪$configuration)
48  {
49  parent::__construct(‪$configuration);
50  $this->routesOfPlugin = $this->configuration['routes'] ?? [];
51  // Only set the namespace if the plugin+extension keys are given. This allows to also use "namespace" property
52  // instead from the parent constructor.
53  if (isset($this->configuration['extension']) && isset($this->configuration['plugin'])) {
54  $extensionName = $this->configuration['extension'];
55  $pluginName = $this->configuration['plugin'];
56  $extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', $extensionName)));
57  $pluginSignature = strtolower($extensionName . '_' . $pluginName);
58  $this->namespace = 'tx_' . $pluginSignature;
59  }
60  return;
61  }
62 
66  public function ‪enhanceForMatching(‪RouteCollection $collection): void
67  {
68  $i = 0;
70  $defaultPageRoute = $collection->get('default');
71  foreach ($this->routesOfPlugin as ‪$configuration) {
72  $route = $this->‪getVariant($defaultPageRoute, ‪$configuration);
73  $collection->add($this->namespace . '_' . $i++, $route);
74  }
75  }
76 
80  protected function ‪getVariant(Route $defaultPageRoute, array ‪$configuration): Route
81  {
82  $arguments = ‪$configuration['_arguments'] ?? [];
83  unset(‪$configuration['_arguments']);
84 
86  $routePath = $this->‪modifyRoutePath($configuration['routePath']);
87  $routePath = ‪$variableProcessor->‪deflateRoutePath($routePath, $this->namespace, $arguments);
88  unset(‪$configuration['routePath']);
89  $options = array_merge($defaultPageRoute->getOptions(), ['_enhancer' => $this, 'utf8' => true, '_arguments' => $arguments]);
90  $route = new Route(rtrim($defaultPageRoute->getPath(), '/') . '/' . ltrim($routePath, '/'), [], [], $options);
91 
92  $defaults = array_merge_recursive(
93  $defaultPageRoute->getDefaults(),
94  ‪$variableProcessor->‪deflateKeys($this->configuration['defaults'] ?? [], $this->namespace, $arguments)
95  );
96  // only keep `defaults` that are actually used in `routePath`
97  $defaults = $this->‪filterValuesByPathVariables(
98  $route,
99  $defaults
100  );
101  // apply '_controller' to route defaults
102  $defaults = array_merge_recursive(
103  $defaults,
104  array_intersect_key(‪$configuration, ['_controller' => true])
105  );
106  $route->setDefaults($defaults);
107  $this->‪applyRouteAspects($route, $this->aspects ?? [], $this->namespace);
108  $this->‪applyRequirements($route, $this->configuration['requirements'] ?? [], $this->namespace);
109  return $route;
110  }
111 
115  public function ‪enhanceForGeneration(RouteCollection $collection, array $originalParameters): void
116  {
117  if (!is_array($originalParameters[$this->namespace] ?? null)) {
118  return;
119  }
120  // apply default controller and action names if not set in parameters
121  if (!$this->‪hasControllerActionValues($originalParameters[$this->namespace])
122  && !empty($this->configuration['defaultController'])
123  ) {
125  $this->configuration['defaultController'],
126  $originalParameters[$this->namespace],
127  true
128  );
129  }
130 
131  $i = 0;
133  $defaultPageRoute = $collection->get('default');
134  foreach ($this->routesOfPlugin as ‪$configuration) {
135  $variant = $this->‪getVariant($defaultPageRoute, ‪$configuration);
136  // The enhancer tells us: This given route does not match the parameters
137  if (!$this->‪verifyRequiredParameters($variant, $originalParameters)) {
138  continue;
139  }
140  $parameters = $originalParameters;
141  unset($parameters[$this->namespace]['action']);
142  unset($parameters[$this->namespace]['controller']);
143  $compiledRoute = $variant->compile();
144  // contains all given parameters, even if not used as variables in route
145  $deflatedParameters = $this->‪deflateParameters($variant, $parameters);
146  $variables = array_flip($compiledRoute->getPathVariables());
147  $mergedParams = array_replace($variant->getDefaults(), $deflatedParameters);
148  // all params must be given, otherwise we exclude this variant
149  // (it is allowed that $variables is empty - in this case variables are
150  // "given" implicitly through controller-action pair in `_controller`)
151  if (array_diff_key($variables, $mergedParams)) {
152  continue;
153  }
154  $variant->addOptions(['deflatedParameters' => $deflatedParameters]);
155  $collection->add($this->namespace . '_' . $i++, $variant);
156  }
157  }
158 
167  public function ‪inflateParameters(array $parameters, array $internals = []): array
168  {
169  $parameters = $this->‪getVariableProcessor()
170  ->‪inflateNamespaceParameters($parameters, $this->namespace);
171  $parameters[‪$this->namespace] = $parameters[‪$this->namespace] ?? [];
172 
173  // Invalid if there is no controller given, so this enhancers does not do anything
174  if (empty($internals['_controller'] ?? null)) {
175  return $parameters;
176  }
178  $internals['_controller'],
179  $parameters[$this->namespace],
180  false
181  );
182  return $parameters;
183  }
184 
192  protected function ‪verifyRequiredParameters(Route $route, array $parameters): bool
193  {
194  if (!is_array($parameters[$this->namespace])) {
195  return false;
196  }
197  if (!$route->hasDefault('_controller')) {
198  return false;
199  }
200  $controller = $route->getDefault('_controller');
201  list($controllerName, $actionName) = explode('::', $controller);
202  if ($controllerName !== $parameters[$this->namespace]['controller']) {
203  return false;
204  }
205  if ($actionName !== $parameters[$this->namespace]['action']) {
206  return false;
207  }
208  return true;
209  }
216  protected function ‪hasControllerActionValues(array $target): bool
217  {
218  return !empty($target['controller']) && !empty($target['action']);
219  }
220 
228  protected function ‪applyControllerActionValues(string $controllerActionValue, array &$target, bool $tryUpdate = false)
229  {
230  if (strpos($controllerActionValue, '::') === false) {
231  return;
232  }
233  list($controllerName, $actionName) = explode('::', $controllerActionValue, 2);
234  // use default action name if controller matches
235  if ($tryUpdate && empty($target['action']) && $controllerName === ($target['controller'] ?? null)) {
236  $target['action'] = $actionName;
237  // use default controller name if action is defined (implies: non-default-controllers must be given)
238  } elseif ($tryUpdate && empty($target['controller']) && !empty($target['action'])) {
239  $target['controller'] = $controllerName;
240  // fallback and override
241  } else {
242  $target['controller'] = $controllerName;
243  $target['action'] = $actionName;
244  }
245  }
246 }
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\modifyRoutePath
‪string modifyRoutePath(string $routePath)
Definition: AbstractEnhancer.php:151
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\applyControllerActionValues
‪applyControllerActionValues(string $controllerActionValue, array &$target, bool $tryUpdate=false)
Definition: ExtbasePluginEnhancer.php:227
‪TYPO3\CMS\Core\Routing\Enhancer\VariableProcessor\deflateRoutePath
‪string deflateRoutePath(string $routePath, string $namespace=null, array $arguments=[])
Definition: VariableProcessor.php:114
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\filterValuesByPathVariables
‪array filterValuesByPathVariables(Route $route, array $values)
Definition: AbstractEnhancer.php:97
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\applyRequirements
‪applyRequirements(Route $route, array $requirements, string $namespace=null)
Definition: AbstractEnhancer.php:56
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\getVariant
‪getVariant(Route $defaultPageRoute, array $configuration)
Definition: ExtbasePluginEnhancer.php:79
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\$variableProcessor
‪VariableProcessor $variableProcessor
Definition: AbstractEnhancer.php:34
‪TYPO3\CMS\Core\Routing\RouteCollection
Definition: RouteCollection.php:27
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\$routesOfPlugin
‪array $routesOfPlugin
Definition: ExtbasePluginEnhancer.php:44
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\enhanceForGeneration
‪enhanceForGeneration(RouteCollection $collection, array $originalParameters)
Definition: ExtbasePluginEnhancer.php:114
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\getVariableProcessor
‪VariableProcessor getVariableProcessor()
Definition: AbstractEnhancer.php:196
‪TYPO3\CMS\Core\Routing\Enhancer\VariableProcessor\deflateKeys
‪array deflateKeys(array $items, string $namespace=null, array $arguments=[], bool $hash=true)
Definition: VariableProcessor.php:232
‪TYPO3\CMS\Core\Routing\Enhancer\PluginEnhancer
Definition: PluginEnhancer.php:42
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\hasControllerActionValues
‪bool hasControllerActionValues(array $target)
Definition: ExtbasePluginEnhancer.php:215
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\verifyRequiredParameters
‪bool verifyRequiredParameters(Route $route, array $parameters)
Definition: ExtbasePluginEnhancer.php:191
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer
Definition: ExtbasePluginEnhancer.php:41
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\applyRouteAspects
‪applyRouteAspects(Route $route, array $aspects, string $namespace=null)
Definition: AbstractEnhancer.php:41
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\__construct
‪__construct(array $configuration)
Definition: ExtbasePluginEnhancer.php:46
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\enhanceForMatching
‪enhanceForMatching(RouteCollection $collection)
Definition: ExtbasePluginEnhancer.php:65
‪TYPO3\CMS\Extbase\Routing
Definition: ExtbasePluginEnhancer.php:4
‪TYPO3\CMS\Core\Routing\Route
Definition: Route.php:31
‪TYPO3\CMS\Core\Routing\Enhancer\PluginEnhancer\$namespace
‪string $namespace
Definition: PluginEnhancer.php:49
‪TYPO3\CMS\Core\Routing\Enhancer\PluginEnhancer\deflateParameters
‪array deflateParameters(Route $route, array $parameters)
Definition: PluginEnhancer.php:175
‪TYPO3\CMS\Core\Routing\Enhancer\VariableProcessor\inflateNamespaceParameters
‪array inflateNamespaceParameters(array $parameters, string $namespace, array $arguments=[])
Definition: VariableProcessor.php:182
‪TYPO3\CMS\Core\Routing\Enhancer\PluginEnhancer\$configuration
‪array $configuration
Definition: PluginEnhancer.php:45
‪TYPO3\CMS\Extbase\Routing\ExtbasePluginEnhancer\inflateParameters
‪array inflateParameters(array $parameters, array $internals=[])
Definition: ExtbasePluginEnhancer.php:166