‪TYPO3CMS  11.5
AbstractEnhancer.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
23 
27 abstract class ‪AbstractEnhancer implements ‪EnhancerInterface
28 {
32  protected ‪$aspects = [];
33 
37  protected ‪$variableProcessor;
38 
44  protected function ‪applyRouteAspects(‪Route $route, array ‪$aspects, string $namespace = null)
45  {
46  if (empty(‪$aspects)) {
47  return;
48  }
50  ->‪deflateKeys($aspects, $namespace, $route->‪getArguments());
51  $route->‪setAspects(‪$aspects);
52  }
53 
59  protected function ‪applyRequirements(‪Route $route, array $requirements, string $namespace = null)
60  {
61  $requirements = $this->‪getVariableProcessor()
62  ->‪deflateKeys($requirements, $namespace, $route->‪getArguments());
63  // only keep requirements that are actually part of the current route path
64  $requirements = $this->‪filterValuesByPathVariables($route, $requirements);
65  // Symfony's behavior on applying pattern for parameters just concerns values
66  // to be passed either to URL or to internal parameters - they are always the
67  // same, without any transformation.
68  //
69  // TYPO3 extends ("enhances") this behavior by making a difference between values
70  // for generation (resulting in a URL) and matching (resulting in query parameters)
71  // having the following implications and meaning:
72  //
73  // + since requirements in classic Symfony focus on parameters in URLs
74  // and aspects define a mapping between URL part (e.g. 'some-example-news')
75  // and the corresponding internal argument (e.g. 'tx_news_pi1[news]=123')
76  // + thus, the requirement definition cannot be used for resolving and generating
77  // a route at the same time (it would have to be e.g. `[\w_._]+` AND `\d+`)
78  //
79  // Symfony's default regular expression pattern `[^/]+` (see
80  // `RouteCompiler::compilePattern()`) has to be overridden with `.+` to
81  // allow URI parameters like `some-example-news/january` as well.
82  //
83  // Existing `requirements` for TYPO3 route enhancers are not modified, only those
84  // that are not defined and would use Symfony's default pattern.
85  $requirements = $this->‪defineValuesByAspect($route, $requirements, '.+');
86  $route->setRequirements($requirements);
87  }
88 
100  protected function ‪filterValuesByPathVariables(‪Route $route, array $values): array
101  {
102  return array_intersect_key(
103  $values,
104  array_flip($route->compile()->getPathVariables())
105  );
106  }
107 
117  protected function ‪overrideValuesByAspect(‪Route $route, array $values, string $targetValue): array
118  {
119  foreach (array_keys($route->‪getAspects()) as $variableName) {
120  $values[$variableName] = $targetValue;
121  }
122  return $values;
123  }
124 
134  protected function ‪defineValuesByAspect(‪Route $route, array $values, string $targetValue): array
135  {
136  foreach (array_keys($route->‪getAspects()) as $variableName) {
137  if (isset($values[$variableName])) {
138  continue;
139  }
140  $values[$variableName] = $targetValue;
141  }
142  return $values;
143  }
144 
154  protected function ‪modifyRoutePath(string $routePath): string
155  {
156  $substitutes = [];
157  foreach ($this->aspects as $variableName => $aspect) {
158  if (!$aspect instanceof ‪ModifiableAspectInterface) {
159  continue;
160  }
161  $value = $aspect->modify();
162  if ($value !== null) {
163  $substitutes['{' . $variableName . '}'] = $value;
164  $substitutes['{!' . $variableName . '}'] = $value;
165  }
166  }
167  return str_replace(
168  array_keys($substitutes),
169  array_values($substitutes),
170  $routePath
171  );
172  }
173 
181  protected function ‪resolveType(‪Route $route, array &$remainingQueryParameters): string
182  {
183  $type = $remainingQueryParameters['type'] ?? 0;
184  $decoratedParameters = $route->getOption('_decoratedParameters');
185  if (isset($decoratedParameters['type'])) {
186  $type = $decoratedParameters['type'];
187  unset($decoratedParameters['type']);
188  $remainingQueryParameters = array_replace_recursive(
189  $remainingQueryParameters,
190  $decoratedParameters
191  );
192  }
193  return (string)$type;
194  }
195 
199  protected function ‪getVariableProcessor(): ‪VariableProcessor
200  {
201  if (isset($this->variableProcessor)) {
203  }
204  return $this->variableProcessor = new ‪VariableProcessor();
205  }
206 
210  public function ‪setAspects(array ‪$aspects): void
211  {
212  $this->aspects = ‪$aspects;
213  }
214 
218  public function ‪getAspects(): array
219  {
220  return ‪$this->aspects;
221  }
222 }
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\modifyRoutePath
‪string modifyRoutePath(string $routePath)
Definition: AbstractEnhancer.php:152
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\getAspects
‪getAspects()
Definition: AbstractEnhancer.php:216
‪TYPO3\CMS\Core\Routing\Aspect\AspectInterface
Definition: AspectInterface.php:23
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\filterValuesByPathVariables
‪array filterValuesByPathVariables(Route $route, array $values)
Definition: AbstractEnhancer.php:98
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\applyRequirements
‪applyRequirements(Route $route, array $requirements, string $namespace=null)
Definition: AbstractEnhancer.php:57
‪TYPO3\CMS\Core\Routing\Enhancer\VariableProcessor
Definition: VariableProcessor.php:24
‪TYPO3\CMS\Core\Routing\Route\getArguments
‪array getArguments()
Definition: Route.php:61
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\defineValuesByAspect
‪array defineValuesByAspect(Route $route, array $values, string $targetValue)
Definition: AbstractEnhancer.php:132
‪TYPO3\CMS\Core\Routing\Route\setAspects
‪$this setAspects(array $aspects)
Definition: Route.php:92
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\getVariableProcessor
‪VariableProcessor getVariableProcessor()
Definition: AbstractEnhancer.php:197
‪TYPO3\CMS\Core\Routing\Enhancer
Definition: AbstractEnhancer.php:18
‪TYPO3\CMS\Core\Routing\Enhancer\VariableProcessor\deflateKeys
‪array deflateKeys(array $items, string $namespace=null, array $arguments=[], bool $hash=true)
Definition: VariableProcessor.php:233
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\$variableProcessor
‪VariableProcessor null $variableProcessor
Definition: AbstractEnhancer.php:35
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer
Definition: AbstractEnhancer.php:28
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\applyRouteAspects
‪applyRouteAspects(Route $route, array $aspects, string $namespace=null)
Definition: AbstractEnhancer.php:42
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\resolveType
‪string resolveType(Route $route, array &$remainingQueryParameters)
Definition: AbstractEnhancer.php:179
‪TYPO3\CMS\Core\Routing\Route
Definition: Route.php:32
‪TYPO3\CMS\Core\Routing\Route\getAspects
‪array getAspects()
Definition: Route.php:79
‪TYPO3\CMS\Core\Routing\Aspect\ModifiableAspectInterface
Definition: ModifiableAspectInterface.php:25
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\setAspects
‪setAspects(array $aspects)
Definition: AbstractEnhancer.php:208
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\$aspects
‪AspectInterface[] $aspects
Definition: AbstractEnhancer.php:31
‪TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer\overrideValuesByAspect
‪array overrideValuesByAspect(Route $route, array $values, string $targetValue)
Definition: AbstractEnhancer.php:115
‪TYPO3\CMS\Core\Routing\Enhancer\EnhancerInterface
Definition: EnhancerInterface.php:27