Revert "[TASK] Avoid slow array functions in loops"
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Functional / SiteHandling / AbstractTestCase.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
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
18 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
19 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Fixtures\LinkHandlingController;
20 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Internal\ArrayValueInstruction;
21 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
22
23 /**
24 * Abstract test case for frontend requests
25 */
26 abstract class AbstractTestCase extends FunctionalTestCase
27 {
28 use SiteBasedTestTrait;
29
30 protected const ENCRYPTION_KEY = '4408d27a916d51e624b69af3554f516dbab61037a9f7b9fd6f81b4d3bedeccb6';
31
32 protected const TYPO3_CONF_VARS = [
33 'SYS' => [
34 'encryptionKey' => self::ENCRYPTION_KEY,
35 ],
36 'FE' => [
37 'cacheHash' => [
38 'requireCacheHashPresenceParameters' => ['testing[value]']
39 ],
40 ]
41 ];
42
43 protected const LANGUAGE_PRESETS = [
44 'EN' => ['id' => 0, 'title' => 'English', 'locale' => 'en_US.UTF8', 'iso' => 'en', 'hrefLang' => 'en-US', 'direction' => ''],
45 'FR' => ['id' => 1, 'title' => 'French', 'locale' => 'fr_FR.UTF8', 'iso' => 'fr', 'hrefLang' => 'fr-FR', 'direction' => ''],
46 'FR-CA' => ['id' => 2, 'title' => 'Franco-Canadian', 'locale' => 'fr_CA.UTF8', 'iso' => 'fr', 'hrefLang' => 'fr-CA', 'direction' => ''],
47 ];
48
49 /**
50 * @var string[]
51 */
52 protected $coreExtensionsToLoad = ['frontend', 'workspaces'];
53
54 /**
55 * @var string[]
56 */
57 protected $pathsToLinkInTestInstance = [
58 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/AdditionalConfiguration.php' => 'typo3conf/AdditionalConfiguration.php',
59 ];
60
61 /**
62 * Combines string values of multiple array as cross-product into flat items.
63 *
64 * Example:
65 * + meltStrings(['a','b'], ['c','e'], ['f','g'])
66 * + results into ['acf', 'acg', 'aef', 'aeg', 'bcf', 'bcg', 'bef', 'beg']
67 *
68 * @param array $arrays Distinct array that should be melted
69 * @param callable $finalCallback Callback being executed on last multiplier
70 * @param string $prefix Prefix containing concatenated previous values
71 * @return array
72 */
73 protected function meltStrings(array $arrays, callable $finalCallback = null, string $prefix = ''): array
74 {
75 $results = [];
76 $array = array_shift($arrays);
77 foreach ($array as $item) {
78 $resultItem = $prefix . $item;
79 if (count($arrays) > 0) {
80 $results = array_merge(
81 $results,
82 $this->meltStrings($arrays, $finalCallback, $resultItem)
83 );
84 continue;
85 }
86 if ($finalCallback !== null) {
87 $resultItem = call_user_func($finalCallback, $resultItem);
88 }
89 $results[] = $resultItem;
90 }
91 return $results;
92 }
93
94 /**
95 * @param array $array
96 * @return array
97 */
98 protected function wrapInArray(array $array): array
99 {
100 return array_map(
101 function ($item) {
102 return [$item];
103 },
104 $array
105 );
106 }
107
108 /**
109 * @param string[] $array
110 * @return array
111 */
112 protected function keysFromValues(array $array): array
113 {
114 return array_combine($array, $array);
115 }
116
117 /**
118 * Generates key names based on a template and array items as arguments.
119 *
120 * + keysFromTemplate([[1, 2, 3], [11, 22, 33]], '%1$d->%2$d (user:%3$d)')
121 * + returns the following array with generated keys
122 * [
123 * '1->2 (user:3)' => [1, 2, 3],
124 * '11->22 (user:33)' => [11, 22, 33],
125 * ]
126 *
127 * @param array $array
128 * @param string $template
129 * @param callable|null $callback
130 * @return array
131 */
132 protected function keysFromTemplate(array $array, string $template, callable $callback = null): array
133 {
134 $keys = array_unique(
135 array_map(
136 function (array $values) use ($template, $callback) {
137 if ($callback !== null) {
138 $values = call_user_func($callback, $values);
139 }
140 return vsprintf($template, $values);
141 },
142 $array
143 )
144 );
145
146 if (count($keys) !== count($array)) {
147 throw new \LogicException(
148 'Amount of generated keys does not match to item count.',
149 1534682840
150 );
151 }
152
153 return array_combine($keys, $array);
154 }
155
156 /**
157 * @param array $typoScript
158 * @return ArrayValueInstruction
159 */
160 protected function createTypoLinkUrlInstruction(array $typoScript): ArrayValueInstruction
161 {
162 return (new ArrayValueInstruction(LinkHandlingController::class))
163 ->withArray([
164 '10' => 'TEXT',
165 '10.' => [
166 'typolink.' => array_merge(
167 $typoScript,
168 ['returnLast' => 'url']
169 )
170 ]
171 ]);
172 }
173
174 /**
175 * @param array $typoScript
176 * @return ArrayValueInstruction
177 */
178 protected function createHierarchicalMenuProcessorInstruction(array $typoScript): ArrayValueInstruction
179 {
180 return (new ArrayValueInstruction(LinkHandlingController::class))
181 ->withArray([
182 '10' => 'FLUIDTEMPLATE',
183 '10.' => [
184 'file' => 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/FluidJson.html',
185 'dataProcessing.' => [
186 '1' => 'TYPO3\\CMS\\Frontend\\DataProcessing\\MenuProcessor',
187 '1.' => array_merge(
188 $typoScript,
189 ['as' => 'results']
190 )
191 ],
192 ],
193 ]);
194 }
195
196 /**
197 * @param array $typoScript
198 * @return ArrayValueInstruction
199 */
200 protected function createLanguageMenuProcessorInstruction(array $typoScript): ArrayValueInstruction
201 {
202 return (new ArrayValueInstruction(LinkHandlingController::class))
203 ->withArray([
204 '10' => 'FLUIDTEMPLATE',
205 '10.' => [
206 'file' => 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/FluidJson.html',
207 'dataProcessing.' => [
208 '1' => 'TYPO3\\CMS\\Frontend\\DataProcessing\\LanguageMenuProcessor',
209 '1.' => array_merge(
210 $typoScript,
211 ['as' => 'results']
212 )
213 ],
214 ],
215 ]);
216 }
217
218 /**
219 * Filters and keeps only desired names.
220 *
221 * @param array $menu
222 * @param array $keepNames
223 * @return array
224 */
225 protected function filterMenu(
226 array $menu,
227 array $keepNames = ['title', 'link']
228 ): array {
229 if (!in_array('children', $keepNames)) {
230 $keepNames[] = 'children';
231 }
232 return array_map(
233 function (array $menuItem) use ($keepNames) {
234 $menuItem = array_filter(
235 $menuItem,
236 function (string $name) use ($keepNames) {
237 return in_array($name, $keepNames);
238 },
239 ARRAY_FILTER_USE_KEY
240 );
241 if (is_array($menuItem['children'] ?? null)) {
242 $menuItem['children'] = $this->filterMenu(
243 $menuItem['children'],
244 $keepNames
245 );
246 }
247 return $menuItem;
248 },
249 $menu
250 );
251 }
252
253 /**
254 * @param array $keys
255 * @param mixed $payload
256 * @return array
257 */
258 protected function populateToKeys(array $keys, $payload): array
259 {
260 $result = [];
261 foreach ($keys as $key) {
262 $result[$key] = $payload;
263 }
264 return $result;
265 }
266 }