[SECURITY] Disallow pht as file extension
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Functional / Rendering / LocalizedContentRenderingTest.php
1 <?php
2 declare(strict_types=1);
3
4 namespace TYPO3\CMS\Frontend\Tests\Functional\Rendering;
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\Database\ConnectionPool;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Response;
22
23 /**
24 * Test case checking if localized tt_content is rendered correctly with different language settings
25 *
26 * The following values are relevant:
27 *
28 * -- TypoScript --
29 * config.sys_language_uid = [0,1,2,3,4...] (set via the language parameter &L=1 from the FrontendRequest in the tests)
30 * Fetch the page overlay of the current page if the value is > 0 and if not available, then
31 * "config.sys_language_mode" is evaluated.
32 * If this setting is set to "0" or empty, then no page overlay is evaluated, and no further parameters are
33 * relevant or evaluated.
34 *
35 * config.sys_language_mode = [strict, content_fallback;2,3, ignore]
36 * Only evaluated when sys_language_uid > 0, and the requested page translation is NOT available.
37 * Decides if "pageNotFound" (strict), "content_fallback" with a fallback chain ($TSFE->sys_language_content is set
38 * to that value) or "ignore" (just render the page and the content as this translation would exist).
39 * When set to "0" or not set "", this means that the page request is using the default language for content
40 * and page properties.
41 * Content fallback is evaluated on page level, not on the CE level. So it only makes a difference when the pages_language_overlay
42 * for the requested language does not exist.
43 *
44 * config.sys_language_overlay = [0, 1, hideNonTranslated]
45 * Only relevant if $TSFE->sys_language_content is > 0.
46 * Sets the property $TSFE->sys_language_contentOL at a request. Further calls via $TSFE->sys_page->getRecordOverlay
47 * receive this value to see if an overlay should happen.
48 * 0:
49 * Just fetch records from selected ($TSFE->sys_language_content) language, no overlay will happen,
50 * no fetching of the records from the default language. This boils down to "free mode" language handling.
51 *
52 * 1:
53 * Fetch records from the default language and overlay them with translations. If some record is not translated
54 * default language version will be shown.
55 *
56 * hideNotTranslated:
57 * Fetch records from the default language and overlay them with translations. If some record is not translated
58 * it will not be shown.
59 *
60 * -- Frontend / TypoScriptFrontendController --
61 *
62 * $TSFE->sys_language_uid
63 * Defines in which language the current page was requested, this is relevant when building menus or links to other
64 * pages.
65 * $TSFE->sys_language_content
66 * Contains the language UID of the content records that should be overlaid to would be fetched.
67 * This is especially useful when a page requested with language=4 should fall back to showing content of language=2 (see config.sys_language_mode=content_fallback)
68 * $TSFE->sys_language_contentOL
69 * Contains the info if and how record overlays (when fetching content) should be handled, either "0" (no overlays done)
70 * or "1" (do overlays with possible mixed content, or "hideNonTranslated". see "config.sys_language_overlay"
71 * This is used in conjunction with $TSFE->sys_language_content.
72 * $TSFE->sys_language_mode
73 * Contains the config.sys_language_mode parameter, which is either "", "strict", "content_fallback" or "ignore"
74 * Only used within $TSFE->settingLanguage() and in Extbase.
75 */
76 class LocalizedContentRenderingTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase
77 {
78 const VALUE_PageId = 89;
79 const TABLE_Content = 'tt_content';
80 const TABLE_Pages = 'pages';
81
82 /**
83 * @var string
84 */
85 protected $scenarioDataSetDirectory = 'typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/';
86
87 /**
88 * Custom 404 handler returning valid json is registered so the $this->getFrontendResponse()
89 * does not fail on 404 pages
90 *
91 * @var array
92 */
93 protected $configurationToUseInTestInstance = [
94 'FE' => [
95 'pageNotFound_handling' => 'READFILE:typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/404Template.html'
96 ]
97 ];
98
99 protected function setUp()
100 {
101 parent::setUp();
102 $this->importScenarioDataSet('LiveDefaultPages');
103 $this->importScenarioDataSet('LiveDefaultElements');
104
105 $this->backendUser->workspace = 0;
106 }
107
108 public function defaultLanguageConfigurationDataProvider(): array
109 {
110 return [
111 [
112 'typoScript' => 'config.sys_language_overlay = 0
113 config.sys_language_mode =',
114 'sys_language_mode' => '',
115 'sys_language_contentOL' => 0
116 ],
117 [
118 'typoScript' => 'config.sys_language_overlay = 0
119 config.sys_language_mode = content_fallback',
120 'sys_language_mode' => 'content_fallback',
121 'sys_language_contentOL' => 0
122 ],
123 [
124 'typoScript' => 'config.sys_language_overlay = 0
125 config.sys_language_mode = content_fallback;1,0',
126 'sys_language_mode' => 'content_fallback',
127 'sys_language_contentOL' => 0
128 ],
129 [
130 'typoScript' => 'config.sys_language_overlay = 0
131 config.sys_language_mode = strict',
132 'sys_language_mode' => 'strict',
133 'sys_language_contentOL' => 0
134 ],
135 [
136 'typoScript' => 'config.sys_language_overlay = 0
137 config.sys_language_mode = ignore',
138 'sys_language_mode' => 'ignore',
139 'sys_language_contentOL' => 0
140 ],
141 [
142 'typoScript' => 'config.sys_language_overlay = 1
143 config.sys_language_mode =',
144 'sys_language_mode' => '',
145 'sys_language_contentOL' => 1
146 ],
147 [
148 'typoScript' => 'config.sys_language_overlay = 1
149 config.sys_language_mode = content_fallback',
150 'sys_language_mode' => 'content_fallback',
151 'sys_language_contentOL' => 1
152 ],
153 [
154 'typoScript' => 'config.sys_language_overlay = 1
155 config.sys_language_mode = content_fallback;1,0',
156 'sys_language_mode' => 'content_fallback',
157 'sys_language_contentOL' => 1
158 ],
159 [
160 'typoScript' => 'config.sys_language_overlay = 1
161 config.sys_language_mode = strict',
162 'sys_language_mode' => 'strict',
163 'sys_language_contentOL' => 1
164 ],
165 [
166 'typoScript' => 'config.sys_language_overlay = 1
167 config.sys_language_mode = ignore',
168 'sys_language_mode' => 'ignore',
169 'sys_language_contentOL' => 1
170 ],
171 [
172 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
173 config.sys_language_mode =',
174 'sys_language_mode' => '',
175 'sys_language_contentOL' => 'hideNonTranslated'
176 ],
177 [
178 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
179 config.sys_language_mode = content_fallback',
180 'sys_language_mode' => 'content_fallback',
181 'sys_language_contentOL' => 'hideNonTranslated'
182 ],
183 [
184 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
185 config.sys_language_mode = content_fallback;1,0',
186 'sys_language_mode' => 'content_fallback',
187 'sys_language_contentOL' => 'hideNonTranslated'
188 ],
189 [
190 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
191 config.sys_language_mode = strict',
192 'sys_language_mode' => 'strict',
193 'sys_language_contentOL' => 'hideNonTranslated'
194 ],
195 [
196 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
197 config.sys_language_mode = ignore',
198 'sys_language_mode' => 'ignore',
199 'sys_language_contentOL' => 'hideNonTranslated'
200 ],
201 ];
202 }
203
204 /**
205 * For the default language all combination of language settings should give the same result,
206 * regardless of TypoScript settings, if the requested language is "0" then no TypoScript settings apply.
207 *
208 * @test
209 * @dataProvider defaultLanguageConfigurationDataProvider
210 *
211 * @param string $typoScript
212 * @param string $sysLanguageMode
213 * @param string $sysLanguageContentOL
214 */
215 public function onlyEnglishContentIsRenderedForDefaultLanguage(string $typoScript, string $sysLanguageMode, string $sysLanguageContentOL)
216 {
217 $this->setUpFrontendRootPage(1, [
218 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts',
219 ]);
220 $this->addTypoScriptToTemplateRecord(1, $typoScript);
221
222 $frontendResponse = $this->getFrontendResponse(self::VALUE_PageId, 0);
223 $responseSections = $frontendResponse->getResponseSections();
224 $visibleHeaders = ['Regular Element #1', 'Regular Element #2', 'Regular Element #3'];
225 $this->assertThat(
226 $responseSections,
227 $this->getRequestSectionHasRecordConstraint()
228 ->setTable(self::TABLE_Content)
229 ->setField('header')
230 ->setValues(...$visibleHeaders)
231 );
232 $this->assertThat(
233 $responseSections,
234 $this->getRequestSectionDoesNotHaveRecordConstraint()
235 ->setTable(self::TABLE_Content)
236 ->setField('header')
237 ->setValues(...$this->getNonVisibleHeaders($visibleHeaders))
238 );
239
240 $content = json_decode($frontendResponse->getContent());
241 $this->assertEquals('Default language Page', $content->Scope->page->title);
242 $this->assertEquals(0, $content->Scope->tsfe->sys_language_uid, 'sys_language_uid doesn\'t match');
243 $this->assertEquals(0, $content->Scope->tsfe->sys_language_content, 'sys_language_content doesn\'t match');
244 $this->assertEquals($sysLanguageMode, $content->Scope->tsfe->sys_language_mode, 'sys_language_mode doesn\t match');
245 $this->assertEquals($sysLanguageContentOL, $content->Scope->tsfe->sys_language_contentOL, 'sys_language_contentOL doesn\t match');
246 }
247
248 /**
249 * Dutch language has pages_language_overlay record and some content elements are translated
250 *
251 * @return array
252 */
253 public function dutchDataProvider(): array
254 {
255 //Expected behaviour:
256 //Page is translated to Dutch, so changing sys_language_mode does NOT change the results
257 //Page title is always [DK]Page, and both sys_language_content and sys_language_uid are always 1
258 return [
259 [
260 'typoScript' => 'config.sys_language_overlay = 0
261 config.sys_language_mode =',
262 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3', '[DK] Without default language', '[DK] UnHidden Element #4'],
263 'sys_language_mode' => '',
264 'sys_language_contentOL' => 0
265 ],
266 [
267 'typoScript' => 'config.sys_language_overlay = 0
268 config.sys_language_mode = content_fallback',
269 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3', '[DK] Without default language', '[DK] UnHidden Element #4'],
270 'sys_language_mode' => 'content_fallback',
271 'sys_language_contentOL' => 0
272 ],
273 [
274 'typoScript' => 'config.sys_language_overlay = 0
275 config.sys_language_mode = content_fallback;1,0',
276 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3', '[DK] Without default language', '[DK] UnHidden Element #4'],
277 'sys_language_mode' => 'content_fallback',
278 'sys_language_contentOL' => 0
279 ],
280 [
281 'typoScript' => 'config.sys_language_overlay = 0
282 config.sys_language_mode = strict',
283 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3', '[DK] Without default language', '[DK] UnHidden Element #4'],
284 'sys_language_mode' => 'strict',
285 'sys_language_contentOL' => 0
286 ],
287 [
288 'typoScript' => 'config.sys_language_overlay = 0
289 config.sys_language_mode = ignore',
290 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3', '[DK] Without default language', '[DK] UnHidden Element #4'],
291 'sys_language_mode' => 'ignore',
292 'sys_language_contentOL' => 0
293 ],
294 [
295 'typoScript' => 'config.sys_language_overlay = 1
296 config.sys_language_mode =',
297 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', 'Regular Element #2', '[Translate to Dansk:] Regular Element #3'],
298 'sys_language_mode' => '',
299 'sys_language_contentOL' => 1
300 ],
301 // Expected behaviour:
302 // Not translated element #2 is shown because sys_language_overlay = 1 (with sys_language_overlay = hideNonTranslated, it would be hidden)
303 [
304 'typoScript' => 'config.sys_language_overlay = 1
305 config.sys_language_mode = content_fallback',
306 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', 'Regular Element #2', '[Translate to Dansk:] Regular Element #3'],
307 'sys_language_mode' => 'content_fallback',
308 'sys_language_contentOL' => 1
309 ],
310 // Expected behaviour:
311 // Same as config.sys_language_mode = content_fallback because we're requesting language 1, so no additional fallback possible
312 //
313 [
314 'typoScript' => 'config.sys_language_overlay = 1
315 config.sys_language_mode = content_fallback;1,0',
316 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', 'Regular Element #2', '[Translate to Dansk:] Regular Element #3'],
317 'sys_language_mode' => 'content_fallback',
318 'sys_language_contentOL' => 1
319 ],
320 [
321 'typoScript' => 'config.sys_language_overlay = 1
322 config.sys_language_mode = strict',
323 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', 'Regular Element #2', '[Translate to Dansk:] Regular Element #3'],
324 'sys_language_mode' => 'strict',
325 'sys_language_contentOL' => 1
326 ],
327 [
328 'typoScript' => 'config.sys_language_overlay = 1
329 config.sys_language_mode = ignore',
330 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', 'Regular Element #2', '[Translate to Dansk:] Regular Element #3'],
331 'sys_language_mode' => 'ignore',
332 'sys_language_contentOL' => 1
333 ],
334 // Expected behaviour:
335 // Non translated default language elements are not shown, because of hideNonTranslated
336 [
337 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
338 config.sys_language_mode =',
339 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3'],
340 'sys_language_mode' => '',
341 'sys_language_contentOL' => 'hideNonTranslated'
342 ],
343 [
344 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
345 config.sys_language_mode = content_fallback',
346 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3'],
347 'sys_language_mode' => 'content_fallback',
348 'sys_language_contentOL' => 'hideNonTranslated'
349 ],
350 [
351 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
352 config.sys_language_mode = content_fallback;1,0',
353 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3'],
354 'sys_language_mode' => 'content_fallback',
355 'sys_language_contentOL' => 'hideNonTranslated'
356 ],
357 //Setting sys_language_mode = strict has the same effect as previous data sets, because the translation of the page exists
358 [
359 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
360 config.sys_language_mode = strict',
361 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3'],
362 'sys_language_mode' => 'strict',
363 'sys_language_contentOL' => 'hideNonTranslated'
364 ],
365 [
366 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
367 config.sys_language_mode = ignore',
368 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3'],
369 'sys_language_mode' => 'ignore',
370 'sys_language_contentOL' => 'hideNonTranslated'
371 ],
372 ];
373 }
374
375 /**
376 * @test
377 * @dataProvider dutchDataProvider
378 *
379 * @param string $typoScript
380 * @param array $visibleHeaders
381 * @param string $sysLanguageMode
382 * @param string $sysLanguageContentOL
383 */
384 public function renderingOfDutchLanguage(string $typoScript, array $visibleHeaders, string $sysLanguageMode, string $sysLanguageContentOL)
385 {
386 $this->setUpFrontendRootPage(1, [
387 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts',
388 ]);
389 $this->addTypoScriptToTemplateRecord(1, $typoScript);
390 $frontendResponse = $this->getFrontendResponse(self::VALUE_PageId, 1);
391 $responseSections = $frontendResponse->getResponseSections();
392 $this->assertThat(
393 $responseSections,
394 $this->getRequestSectionHasRecordConstraint()
395 ->setTable(self::TABLE_Content)
396 ->setField('header')
397 ->setValues(...$visibleHeaders)
398 );
399 $this->assertThat(
400 $responseSections,
401 $this->getRequestSectionDoesNotHaveRecordConstraint()
402 ->setTable(self::TABLE_Content)
403 ->setField('header')
404 ->setValues(...$this->getNonVisibleHeaders($visibleHeaders))
405 );
406 $content = json_decode($frontendResponse->getContent());
407 $this->assertEquals('[DK]Page', $content->Scope->page->title);
408 $this->assertEquals(1, $content->Scope->tsfe->sys_language_uid, 'sys_language_uid doesn\'t match');
409 $this->assertEquals(1, $content->Scope->tsfe->sys_language_content, 'sys_language_content doesn\'t match');
410 $this->assertEquals($sysLanguageMode, $content->Scope->tsfe->sys_language_mode, 'sys_language_mode doesn\t match');
411 $this->assertEquals($sysLanguageContentOL, $content->Scope->tsfe->sys_language_contentOL, 'sys_language_contentOL doesn\t match');
412 }
413
414 public function contentOnNonTranslatedPageDataProvider(): array
415 {
416 //Expected behaviour:
417 //the page is NOT translated so setting sys_language_mode to different values changes the results
418 //- setting sys_language_mode to empty value makes TYPO3 return default language records
419 //- setting it to strict throws 404, independently from other settings
420 //Setting config.sys_language_overlay = 0
421 return [
422 [
423 'typoScript' => 'config.sys_language_overlay = 0
424 config.sys_language_mode =',
425 'visibleRecordHeaders' => ['Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
426 'pageTitle' => 'Default language Page',
427 'sys_language_uid' => 0,
428 'sys_language_content' => 0,
429 'sys_language_mode' => '',
430 'sys_language_contentOL' => 0,
431 ],
432 [
433 'typoScript' => 'config.sys_language_overlay = 0
434 config.sys_language_mode = content_fallback',
435 'visibleRecordHeaders' => ['Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
436 'pageTitle' => 'Default language Page',
437 'sys_language_uid' => 2,
438 'sys_language_content' => 0,
439 'sys_language_mode' => 'content_fallback',
440 'sys_language_contentOL' => 0,
441 ],
442 [
443 'typoScript' => 'config.sys_language_overlay = 0
444 config.sys_language_mode = content_fallback;1,0',
445 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3', '[DK] Without default language', '[DK] UnHidden Element #4'],
446 'pageTitle' => 'Default language Page', //TODO: change it to "[DK]Page" once #81657 is fixed
447 'sys_language_uid' => 2,
448 'sys_language_content' => 1,
449 'sys_language_mode' => 'content_fallback',
450 'sys_language_contentOL' => 0,
451 ],
452 [
453 'typoScript' => 'config.sys_language_overlay = 0
454 config.sys_language_mode = strict',
455 'visibleRecordHeaders' => [],
456 'pageTitle' => '',
457 'sys_language_uid' => 2,
458 'sys_language_content' => 2,
459 'sys_language_mode' => 'strict',
460 'sys_language_contentOL' => 0,
461 'status' => 404,
462 ],
463 [
464 'typoScript' => 'config.sys_language_overlay = 0
465 config.sys_language_mode = ignore',
466 'visibleRecordHeaders' => ['[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', '[DE] Without default language'],
467 'pageTitle' => 'Default language Page',
468 'sys_language_uid' => 2,
469 'sys_language_content' => 2,
470 'sys_language_mode' => 'ignore',
471 'sys_language_contentOL' => 0,
472 ],
473 5 => [
474 'typoScript' => 'config.sys_language_overlay = 1
475 config.sys_language_mode =',
476 'visibleRecordHeaders' => ['Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
477 'pageTitle' => 'Default language Page',
478 'sys_language_uid' => 0,
479 'sys_language_content' => 0,
480 'sys_language_mode' => '',
481 'sys_language_contentOL' => 1,
482 ],
483 //falling back to default language
484 [
485 'typoScript' => 'config.sys_language_overlay = 1
486 config.sys_language_mode = content_fallback',
487 'visibleRecordHeaders' => ['Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
488 'pageTitle' => 'Default language Page',
489 'sys_language_uid' => 2,
490 'sys_language_content' => 0,
491 'sys_language_mode' => 'content_fallback',
492 'sys_language_contentOL' => 1,
493 ],
494 //Dutch elements are shown because of the content fallback 1,0 - first Dutch, then default language
495 //note that '[DK] Without default language' is NOT shown - due to overlays (fetch default language and overlay it with translations)
496 [
497 'typoScript' => 'config.sys_language_overlay = 1
498 config.sys_language_mode = content_fallback;1,0',
499 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', 'Regular Element #2', '[Translate to Dansk:] Regular Element #3'],
500 'pageTitle' => 'Default language Page', //TODO: change it to "[DK]Page" once #81657 is fixed
501 'sys_language_uid' => 2,
502 'sys_language_content' => 1,
503 'sys_language_mode' => 'content_fallback',
504 'sys_language_contentOL' => 1,
505 ],
506 [
507 'typoScript' => 'config.sys_language_overlay = 1
508 config.sys_language_mode = strict',
509 'visibleRecordHeaders' => [],
510 'pageTitle' => '',
511 'sys_language_uid' => 2,
512 'sys_language_content' => 2,
513 'sys_language_mode' => 'strict',
514 'sys_language_contentOL' => 1,
515 'status' => 404
516 ],
517 [
518 'typoScript' => 'config.sys_language_overlay = 1
519 config.sys_language_mode = ignore',
520 'visibleRecordHeaders' => ['[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
521 'pageTitle' => 'Default language Page',
522 'sys_language_uid' => 2,
523 'sys_language_content' => 2,
524 'sys_language_mode' => 'ignore',
525 'sys_language_contentOL' => 1,
526 ],
527 10 => [
528 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
529 config.sys_language_mode =',
530 'visibleRecordHeaders' => ['Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
531 'pageTitle' => 'Default language Page',
532 'sys_language_uid' => 0,
533 'sys_language_content' => 0,
534 'sys_language_mode' => '',
535 'sys_language_contentOL' => 'hideNonTranslated',
536 ],
537 [
538 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
539 config.sys_language_mode = content_fallback',
540 'visibleRecordHeaders' => ['Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
541 'pageTitle' => 'Default language Page',
542 'sys_language_uid' => 2,
543 'sys_language_content' => 0,
544 'sys_language_mode' => 'content_fallback',
545 'sys_language_contentOL' => 'hideNonTranslated',
546 ],
547 [
548 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
549 config.sys_language_mode = content_fallback;1,0',
550 'visibleRecordHeaders' => ['[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3'],
551 'pageTitle' => 'Default language Page', //TODO: change it to "[DK]Page" once #81657 is fixed
552 'sys_language_uid' => 2,
553 'sys_language_content' => 1,
554 'sys_language_mode' => 'content_fallback',
555 'sys_language_contentOL' => 'hideNonTranslated',
556 ],
557 [
558 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
559 config.sys_language_mode = strict',
560 'visibleRecordHeaders' => [],
561 'pageTitle' => '',
562 'sys_language_uid' => 2,
563 'sys_language_content' => 2,
564 'sys_language_mode' => 'strict',
565 'sys_language_contentOL' => 'hideNonTranslated',
566 'status' => 404,
567 ],
568 [
569 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
570 config.sys_language_mode = ignore',
571 'visibleRecordHeaders' => ['[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1'],
572 'pageTitle' => 'Default language Page',
573 'sys_language_uid' => 2,
574 'sys_language_content' => 2,
575 'sys_language_mode' => 'ignore',
576 'sys_language_contentOL' => 'hideNonTranslated',
577 ],
578 ];
579 }
580
581 /**
582 * Page uid 89 is NOT translated to german
583 *
584 * @test
585 * @dataProvider contentOnNonTranslatedPageDataProvider
586 *
587 * @param string $typoScript
588 * @param array $visibleHeaders
589 * @param string $pageTitle
590 * @param int $sysLanguageUid
591 * @param int $sysLanguageContent
592 * @param string $sysLanguageMode
593 * @param string $sysLanguageContentOL
594 * @param string $status 'success' or 404
595 */
596 public function contentOnNonTranslatedPageGerman(string $typoScript, array $visibleHeaders, string $pageTitle, int $sysLanguageUid, int $sysLanguageContent, string $sysLanguageMode, string $sysLanguageContentOL, string $status='success')
597 {
598 $this->setUpFrontendRootPage(1, [
599 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts',
600 ]);
601 $this->addTypoScriptToTemplateRecord(1, $typoScript);
602
603 $frontendResponse = $this->getFrontendResponse(self::VALUE_PageId, 2);
604 if ($status === Response::STATUS_Success) {
605 $responseSections = $frontendResponse->getResponseSections();
606 $this->assertThat(
607 $responseSections,
608 $this->getRequestSectionHasRecordConstraint()
609 ->setTable(self::TABLE_Content)
610 ->setField('header')
611 ->setValues(...$visibleHeaders)
612 );
613 $this->assertThat(
614 $responseSections,
615 $this->getRequestSectionDoesNotHaveRecordConstraint()
616 ->setTable(self::TABLE_Content)
617 ->setField('header')
618 ->setValues(...$this->getNonVisibleHeaders($visibleHeaders))
619 );
620
621 $content = json_decode($frontendResponse->getContent());
622 $this->assertEquals($pageTitle, $content->Scope->page->title);
623 $this->assertEquals($sysLanguageUid, $content->Scope->tsfe->sys_language_uid, 'sys_language_uid doesn\'t match');
624 $this->assertEquals($sysLanguageContent, $content->Scope->tsfe->sys_language_content, 'sys_language_content doesn\'t match');
625 $this->assertEquals($sysLanguageMode, $content->Scope->tsfe->sys_language_mode, 'sys_language_mode doesn\t match');
626 $this->assertEquals($sysLanguageContentOL, $content->Scope->tsfe->sys_language_contentOL, 'sys_language_contentOL doesn\t match');
627 }
628 //some configuration combinations results in 404, in that case status will be set to 404
629 $this->assertEquals($status, $frontendResponse->getStatus());
630 }
631
632 public function contentOnPartiallyTranslatedPageDataProvider(): array
633 {
634
635 //Expected behaviour:
636 //Setting sys_language_mode to different values doesn't influence the result as the requested page is translated to Polish,
637 //Page title is always [PL]Page, and both sys_language_content and sys_language_uid are always 3
638 return [
639 [
640 'typoScript' => 'config.sys_language_overlay = 0
641 config.sys_language_mode =',
642 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', '[PL] Without default language'],
643 'sys_language_mode' => '',
644 'sys_language_contentOL' => 0
645 ],
646 [
647 'typoScript' => 'config.sys_language_overlay = 0
648 config.sys_language_mode = content_fallback',
649 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', '[PL] Without default language'],
650 'sys_language_mode' => 'content_fallback',
651 'sys_language_contentOL' => 0
652 ],
653 [
654 'typoScript' => 'config.sys_language_overlay = 0
655 config.sys_language_mode = content_fallback;1,0',
656 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', '[PL] Without default language'],
657 'sys_language_mode' => 'content_fallback',
658 'sys_language_contentOL' => 0
659 ],
660 [
661 'typoScript' => 'config.sys_language_overlay = 0
662 config.sys_language_mode = strict',
663 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', '[PL] Without default language'],
664 'sys_language_mode' => 'strict',
665 'sys_language_contentOL' => 0
666 ],
667 [
668 'typoScript' => 'config.sys_language_overlay = 0
669 config.sys_language_mode = ignore',
670 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', '[PL] Without default language'],
671 'sys_language_mode' => 'ignore',
672 'sys_language_contentOL' => 0
673 ],
674 5 => [
675 'typoScript' => 'config.sys_language_overlay = 1
676 config.sys_language_mode =',
677 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
678 'sys_language_mode' => '',
679 'sys_language_contentOL' => 1
680 ],
681 // Expected behaviour:
682 // Not translated element #2 is shown because sys_language_overlay = 1 (with sys_language_overlay = hideNonTranslated, it would be hidden)
683 [
684 'typoScript' => 'config.sys_language_overlay = 1
685 config.sys_language_mode = content_fallback',
686 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
687 'sys_language_mode' => 'content_fallback',
688 'sys_language_contentOL' => 1
689 ],
690 // Expected behaviour:
691 // Element #3 is not translated in PL and it is translated in DK. It's not shown as content_fallback is not related to single CE level
692 // but on page level - and this page is translated to Polish, so no fallback is happening
693 [
694 'typoScript' => 'config.sys_language_overlay = 1
695 config.sys_language_mode = content_fallback;1,0',
696 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
697 'sys_language_mode' => 'content_fallback',
698 'sys_language_contentOL' => 1
699 ],
700 [
701 'typoScript' => 'config.sys_language_overlay = 1
702 config.sys_language_mode = strict',
703 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
704 'sys_language_mode' => 'strict',
705 'sys_language_contentOL' => 1
706 ],
707 [
708 'typoScript' => 'config.sys_language_overlay = 1
709 config.sys_language_mode = ignore',
710 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1', 'Regular Element #2', 'Regular Element #3'],
711 'sys_language_mode' => 'ignore',
712 'sys_language_contentOL' => 1
713 ],
714 // Expected behaviour:
715 // Non translated default language elements are not shown, because of hideNonTranslated
716 10 => [
717 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
718 config.sys_language_mode =',
719 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1'],
720 'sys_language_mode' => '',
721 'sys_language_contentOL' => 'hideNonTranslated'
722 ],
723 [
724 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
725 config.sys_language_mode = content_fallback',
726 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1'],
727 'sys_language_mode' => 'content_fallback',
728 'sys_language_contentOL' => 'hideNonTranslated'
729 ],
730 [
731 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
732 config.sys_language_mode = content_fallback;1,0',
733 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1'],
734 'sys_language_mode' => 'content_fallback',
735 'sys_language_contentOL' => 'hideNonTranslated'
736 ],
737 [
738 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
739 config.sys_language_mode = strict',
740 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1'],
741 'sys_language_mode' => 'strict',
742 'sys_language_contentOL' => 'hideNonTranslated'
743 ],
744 [
745 'typoScript' => 'config.sys_language_overlay = hideNonTranslated
746 config.sys_language_mode = ignore',
747 'visibleRecordHeaders' => ['[Translate to Polski:] Regular Element #1'],
748 'sys_language_mode' => 'ignore',
749 'sys_language_contentOL' => 'hideNonTranslated'
750 ]
751 ];
752 }
753
754 /**
755 * Page uid 89 is translated to to Polish, but not all CE are translated
756 *
757 * @test
758 * @dataProvider contentOnPartiallyTranslatedPageDataProvider
759 *
760 * @param string $typoScript
761 * @param array $visibleHeaders
762 * @param string $sysLanguageMode
763 * @param string $sysLanguageContentOL
764 */
765 public function contentOnPartiallyTranslatedPage(string $typoScript, array $visibleHeaders, string $sysLanguageMode, string $sysLanguageContentOL)
766 {
767 $this->setUpFrontendRootPage(1, [
768 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts',
769 ]);
770 $this->addTypoScriptToTemplateRecord(1, $typoScript);
771
772 $frontendResponse = $this->getFrontendResponse(self::VALUE_PageId, 3);
773 $this->assertEquals('success', $frontendResponse->getStatus());
774 $responseSections = $frontendResponse->getResponseSections();
775
776 $this->assertThat(
777 $responseSections,
778 $this->getRequestSectionHasRecordConstraint()
779 ->setTable(self::TABLE_Content)
780 ->setField('header')
781 ->setValues(...$visibleHeaders)
782 );
783 $this->assertThat(
784 $responseSections,
785 $this->getRequestSectionDoesNotHaveRecordConstraint()
786 ->setTable(self::TABLE_Content)
787 ->setField('header')
788 ->setValues(...$this->getNonVisibleHeaders($visibleHeaders))
789 );
790
791 $content = json_decode($frontendResponse->getContent());
792 $this->assertEquals('[PL]Page', $content->Scope->page->title);
793 $this->assertEquals(3, $content->Scope->tsfe->sys_language_uid, 'sys_language_uid doesn\'t match');
794 $this->assertEquals(3, $content->Scope->tsfe->sys_language_content, 'sys_language_content doesn\'t match');
795 $this->assertEquals($sysLanguageMode, $content->Scope->tsfe->sys_language_mode, 'sys_language_mode doesn\t match');
796 $this->assertEquals($sysLanguageContentOL, $content->Scope->tsfe->sys_language_contentOL, 'sys_language_contentOL doesn\t match');
797 }
798
799 /**
800 * Helper function to ease asserting that rest of the data set is not visible
801 *
802 * @param array $visibleHeaders
803 * @return array
804 */
805 protected function getNonVisibleHeaders(array $visibleHeaders): array
806 {
807 $allElements = [
808 'Regular Element #1',
809 'Regular Element #2',
810 'Regular Element #3',
811 'Hidden Element #4',
812 '[Translate to Dansk:] Regular Element #1',
813 '[Translate to Dansk:] Regular Element #3',
814 '[DK] Without default language',
815 '[DK] UnHidden Element #4',
816 '[DE] Without default language',
817 '[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1',
818 '[Translate to Polski:] Regular Element #1',
819 '[PL] Without default language',
820 '[PL] Hidden Regular Element #2'
821 ];
822 return array_diff($allElements, $visibleHeaders);
823 }
824
825 /**
826 * Adds TypoScript setup snippet to the existing template record
827 *
828 * @param int $pageId
829 * @param string $typoScript
830 */
831 protected function addTypoScriptToTemplateRecord(int $pageId, string $typoScript)
832 {
833 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('sys_template');
834
835 $template = $connection->select(['*'], 'sys_template', ['pid' => $pageId, 'root' => 1])->fetch();
836 if (empty($template)) {
837 $this->fail('Cannot find root template on page with id: "' . $pageId . '"');
838 }
839 $updateFields['config'] = $template['config'] . LF . $typoScript;
840 $connection->update(
841 'sys_template',
842 $updateFields,
843 ['uid' => $template['uid']]
844 );
845 }
846 }