[BUGFIX] Streamline PageTypeDecorator handling
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Routing / Enhancer / AbstractEnhancer.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Core\Routing\Enhancer;
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
19 use TYPO3\CMS\Core\Routing\Aspect\AspectInterface;
20 use TYPO3\CMS\Core\Routing\Aspect\ModifiableAspectInterface;
21 use TYPO3\CMS\Core\Routing\Route;
22
23 /**
24 * Abstract Enhancer, useful for custom enhancers
25 */
26 abstract class AbstractEnhancer implements EnhancerInterface
27 {
28 /**
29 * @var AspectInterface[]
30 */
31 protected $aspects = [];
32
33 /**
34 * @var VariableProcessor
35 */
36 protected $variableProcessor;
37
38 /**
39 * @param Route $route
40 * @param AspectInterface[] $aspects
41 * @param string|null $namespace
42 */
43 protected function applyRouteAspects(Route $route, array $aspects, string $namespace = null)
44 {
45 if (empty($aspects)) {
46 return;
47 }
48 $aspects = $this->getVariableProcessor()
49 ->deflateKeys($aspects, $namespace, $route->getArguments());
50 $route->setAspects($aspects);
51 }
52
53 /**
54 * Modify the route path to add the variable names with the aspects.
55 *
56 * @param string $routePath
57 * @return string
58 */
59 protected function modifyRoutePath(string $routePath): string
60 {
61 $substitutes = [];
62 foreach ($this->aspects as $variableName => $aspect) {
63 if (!$aspect instanceof ModifiableAspectInterface) {
64 continue;
65 }
66 $value = $aspect->modify();
67 if ($value !== null) {
68 $substitutes['{' . $variableName . '}'] = $value;
69 }
70 }
71 return str_replace(
72 array_keys($substitutes),
73 array_values($substitutes),
74 $routePath
75 );
76 }
77
78 /**
79 * Retrieves type from processed route and modifies remaining query parameters.
80 *
81 * @param Route $route
82 * @param array $remainingQueryParameters reference to remaining query parameters
83 * @return string
84 */
85 protected function resolveType(Route $route, array &$remainingQueryParameters): string
86 {
87 $type = $remainingQueryParameters['type'] ?? 0;
88 $decoratedParameters = $route->getOption('_decoratedParameters');
89 if (isset($decoratedParameters['type'])) {
90 $type = $decoratedParameters['type'];
91 unset($decoratedParameters['type']);
92 $remainingQueryParameters = array_replace_recursive(
93 $remainingQueryParameters,
94 $decoratedParameters
95 );
96 }
97 return (string)$type;
98 }
99
100 /**
101 * @return VariableProcessor
102 */
103 protected function getVariableProcessor(): VariableProcessor
104 {
105 if (isset($this->variableProcessor)) {
106 return $this->variableProcessor;
107 }
108 return $this->variableProcessor = new VariableProcessor();
109 }
110
111 /**
112 * {@inheritdoc}
113 */
114 public function setAspects(array $aspects): void
115 {
116 $this->aspects = $aspects;
117 }
118
119 /**
120 * {@inheritdoc}
121 */
122 public function getAspects(): array
123 {
124 return $this->aspects;
125 }
126 }