[BUGFIX] Honor l18n_cfg settings in PageRepository
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Functional / Page / PageRepositoryTest.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Tests\Functional\Page;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Prophecy\Argument;
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Frontend\Page\PageRepository;
21 use TYPO3\CMS\Frontend\Page\PageRepositoryGetPageHookInterface;
22
23 /**
24 * Test case
25 */
26 class PageRepositoryTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
27 {
28 protected $coreExtensionsToLoad = ['frontend'];
29
30 /**
31 * @var \TYPO3\CMS\Frontend\Page\PageRepository
32 */
33 protected $pageRepo;
34
35 protected function setUp()
36 {
37 parent::setUp();
38 $GLOBALS['TSFE']->gr_list = '';
39 $this->importDataSet(__DIR__ . '/../Fixtures/pages.xml');
40 $this->pageRepo = new PageRepository();
41 $this->pageRepo->init(false);
42 }
43
44 /**
45 * @test
46 */
47 public function getMenuSingleUidRoot()
48 {
49 $rows = $this->pageRepo->getMenu(1, 'uid, title');
50 $this->assertArrayHasKey(2, $rows);
51 $this->assertArrayHasKey(3, $rows);
52 $this->assertArrayHasKey(4, $rows);
53 $this->assertCount(3, $rows);
54 }
55
56 /**
57 * @test
58 */
59 public function getMenuSingleUidSubpage()
60 {
61 $rows = $this->pageRepo->getMenu(2, 'uid, title');
62 $this->assertArrayHasKey(5, $rows);
63 $this->assertArrayHasKey(6, $rows);
64 $this->assertArrayHasKey(7, $rows);
65 $this->assertCount(3, $rows);
66 }
67
68 /**
69 * @test
70 */
71 public function getMenuMultipleUid()
72 {
73 $rows = $this->pageRepo->getMenu([2, 3], 'uid, title');
74 $this->assertArrayHasKey(5, $rows);
75 $this->assertArrayHasKey(6, $rows);
76 $this->assertArrayHasKey(7, $rows);
77 $this->assertArrayHasKey(8, $rows);
78 $this->assertArrayHasKey(9, $rows);
79 $this->assertCount(5, $rows);
80 }
81
82 /**
83 * @test
84 */
85 public function getMenuPageOverlay()
86 {
87 $this->pageRepo->sys_language_uid = 1;
88
89 $rows = $this->pageRepo->getMenu([2, 3], 'uid, title');
90 $this->assertEquals('Attrappe 1-2-5', $rows[5]['title']);
91 $this->assertEquals('Attrappe 1-2-6', $rows[6]['title']);
92 $this->assertEquals('Dummy 1-2-7', $rows[7]['title']);
93 $this->assertEquals('Dummy 1-3-8', $rows[8]['title']);
94 $this->assertEquals('Attrappe 1-3-9', $rows[9]['title']);
95 $this->assertCount(5, $rows);
96 }
97
98 /**
99 * @test
100 */
101 public function getPageReturnsEmptyArrayWithHideIfDefaultLanguage()
102 {
103 $row = $this->pageRepo->getPage(501);
104 $this->assertSame([], $row);
105 }
106
107 /**
108 * @test
109 */
110 public function getPageOverlayById()
111 {
112 $row = $this->pageRepo->getPageOverlay(1, 1);
113 $this->assertOverlayRow($row);
114 $this->assertEquals('Wurzel 1', $row['title']);
115 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
116 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
117 }
118
119 /**
120 * @test
121 */
122 public function getPageOverlayByIdWithoutTranslation()
123 {
124 $row = $this->pageRepo->getPageOverlay(4, 1);
125 $this->assertInternalType('array', $row);
126 $this->assertCount(0, $row);
127 }
128
129 /**
130 * @test
131 */
132 public function getPageOverlayByRow()
133 {
134 $orig = $this->pageRepo->getPage(1);
135 $row = $this->pageRepo->getPageOverlay($orig, 1);
136 $this->assertOverlayRow($row);
137 $this->assertEquals(1, $row['uid']);
138 $this->assertEquals('Wurzel 1', $row['title']);
139 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
140 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
141 }
142
143 /**
144 * @test
145 */
146 public function getPageOverlayByRowWithoutTranslation()
147 {
148 $orig = $this->pageRepo->getPage(4);
149 $row = $this->pageRepo->getPageOverlay($orig, 1);
150 $this->assertInternalType('array', $row);
151 $this->assertEquals(4, $row['uid']);
152 $this->assertEquals('Dummy 1-4', $row['title']);//original title
153 }
154
155 /**
156 * @test
157 */
158 public function getPagesOverlayByIdSingle()
159 {
160 $this->pageRepo->sys_language_uid = 1;
161 $rows = $this->pageRepo->getPagesOverlay([1]);
162 $this->assertInternalType('array', $rows);
163 $this->assertCount(1, $rows);
164 $this->assertArrayHasKey(0, $rows);
165
166 $row = $rows[0];
167 $this->assertOverlayRow($row);
168 $this->assertEquals('Wurzel 1', $row['title']);
169 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
170 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
171 }
172
173 /**
174 * @test
175 */
176 public function getPagesOverlayByIdMultiple()
177 {
178 $this->pageRepo->sys_language_uid = 1;
179 $rows = $this->pageRepo->getPagesOverlay([1, 5]);
180 $this->assertInternalType('array', $rows);
181 $this->assertCount(2, $rows);
182 $this->assertArrayHasKey(0, $rows);
183 $this->assertArrayHasKey(1, $rows);
184
185 $row = $rows[0];
186 $this->assertOverlayRow($row);
187 $this->assertEquals('Wurzel 1', $row['title']);
188 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
189 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
190
191 $row = $rows[1];
192 $this->assertOverlayRow($row);
193 $this->assertEquals('Attrappe 1-2-5', $row['title']);
194 $this->assertEquals('904', $row['_PAGES_OVERLAY_UID']);
195 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
196 }
197
198 /**
199 * @test
200 */
201 public function getPagesOverlayByIdMultipleSomeNotOverlaid()
202 {
203 $this->pageRepo->sys_language_uid = 1;
204 $rows = $this->pageRepo->getPagesOverlay([1, 4, 5, 8]);
205 $this->assertInternalType('array', $rows);
206 $this->assertCount(2, $rows);
207 $this->assertArrayHasKey(0, $rows);
208 $this->assertArrayHasKey(2, $rows);
209
210 $row = $rows[0];
211 $this->assertOverlayRow($row);
212 $this->assertEquals('Wurzel 1', $row['title']);
213
214 $row = $rows[2];
215 $this->assertOverlayRow($row);
216 $this->assertEquals('Attrappe 1-2-5', $row['title']);
217 }
218
219 /**
220 * @test
221 */
222 public function getPagesOverlayByRowSingle()
223 {
224 $origRow = $this->pageRepo->getPage(1);
225
226 $this->pageRepo->sys_language_uid = 1;
227 $rows = $this->pageRepo->getPagesOverlay([$origRow]);
228 $this->assertInternalType('array', $rows);
229 $this->assertCount(1, $rows);
230 $this->assertArrayHasKey(0, $rows);
231
232 $row = $rows[0];
233 $this->assertOverlayRow($row);
234 $this->assertEquals('Wurzel 1', $row['title']);
235 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
236 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
237 }
238
239 /**
240 * @test
241 */
242 public function getPagesOverlayByRowMultiple()
243 {
244 $orig1 = $this->pageRepo->getPage(1);
245 $orig2 = $this->pageRepo->getPage(5);
246
247 $this->pageRepo->sys_language_uid = 1;
248 $rows = $this->pageRepo->getPagesOverlay([1 => $orig1, 5 => $orig2]);
249 $this->assertInternalType('array', $rows);
250 $this->assertCount(2, $rows);
251 $this->assertArrayHasKey(1, $rows);
252 $this->assertArrayHasKey(5, $rows);
253
254 $row = $rows[1];
255 $this->assertOverlayRow($row);
256 $this->assertEquals('Wurzel 1', $row['title']);
257 $this->assertEquals('901', $row['_PAGES_OVERLAY_UID']);
258 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
259
260 $row = $rows[5];
261 $this->assertOverlayRow($row);
262 $this->assertEquals('Attrappe 1-2-5', $row['title']);
263 $this->assertEquals('904', $row['_PAGES_OVERLAY_UID']);
264 $this->assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
265 }
266
267 /**
268 * @test
269 */
270 public function getPagesOverlayByRowMultipleSomeNotOverlaid()
271 {
272 $orig1 = $this->pageRepo->getPage(1);
273 $orig2 = $this->pageRepo->getPage(7);
274 $orig3 = $this->pageRepo->getPage(9);
275
276 $this->pageRepo->sys_language_uid = 1;
277 $rows = $this->pageRepo->getPagesOverlay([$orig1, $orig2, $orig3]);
278 $this->assertInternalType('array', $rows);
279 $this->assertCount(3, $rows);
280 $this->assertArrayHasKey(0, $rows);
281 $this->assertArrayHasKey(1, $rows);
282 $this->assertArrayHasKey(2, $rows);
283
284 $row = $rows[0];
285 $this->assertOverlayRow($row);
286 $this->assertEquals('Wurzel 1', $row['title']);
287
288 $row = $rows[1];
289 $this->assertNotOverlayRow($row);
290 $this->assertEquals('Dummy 1-2-7', $row['title']);
291
292 $row = $rows[2];
293 $this->assertOverlayRow($row);
294 $this->assertEquals('Attrappe 1-3-9', $row['title']);
295 }
296
297 /**
298 * Tests whether the getPage Hook is called correctly.
299 *
300 * @test
301 */
302 public function isGetPageHookCalled()
303 {
304 // Create a hook mock object
305 $getPageHookProphet = $this->prophesize(\stdClass::class);
306 $getPageHookProphet->willImplement(PageRepositoryGetPageHookInterface::class);
307 $getPageHookProphet->getPage_preProcess(42, false, Argument::type(PageRepository::class))->shouldBeCalled();
308 $getPageHookMock = $getPageHookProphet->reveal();
309 $className = get_class($getPageHookMock);
310
311 // Register hook mock object
312 GeneralUtility::addInstance($className, $getPageHookMock);
313 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPage'][] = $className;
314 $this->pageRepo->getPage(42, false);
315 }
316
317 /**
318 * @test
319 */
320 public function initSetsPublicPropertyCorrectlyForWorkspacePreview()
321 {
322 $this->pageRepo->versioningWorkspaceId = 2;
323 $this->pageRepo->init(false);
324
325 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages');
326
327 $expectedSQL = sprintf(
328 ' AND (%s = 0) AND ((%s = 0) OR (%s = 2))',
329 $connection->quoteIdentifier('pages.deleted'),
330 $connection->quoteIdentifier('pages.t3ver_wsid'),
331 $connection->quoteIdentifier('pages.t3ver_wsid')
332 );
333
334 $this->assertSame($expectedSQL, $this->pageRepo->where_hid_del);
335 }
336
337 /**
338 * @test
339 */
340 public function initSetsPublicPropertyCorrectlyForLive()
341 {
342 $GLOBALS['SIM_ACCESS_TIME'] = 123;
343
344 $this->pageRepo->versioningWorkspaceId = 0;
345 $this->pageRepo->init(false);
346
347 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages');
348 $expectedSQL = sprintf(
349 ' AND (%s = 0) AND (%s <= 0) AND (%s = 0) AND (%s <= 123) AND ((%s = 0) OR (%s > 123))',
350 $connection->quoteIdentifier('pages.deleted'),
351 $connection->quoteIdentifier('pages.t3ver_state'),
352 $connection->quoteIdentifier('pages.hidden'),
353 $connection->quoteIdentifier('pages.starttime'),
354 $connection->quoteIdentifier('pages.endtime'),
355 $connection->quoteIdentifier('pages.endtime')
356 );
357
358 $this->assertSame($expectedSQL, $this->pageRepo->where_hid_del);
359 }
360
361 ////////////////////////////////
362 // Tests concerning workspaces
363 ////////////////////////////////
364
365 /**
366 * @test
367 */
368 public function previewShowsPagesFromLiveAndCurrentWorkspace()
369 {
370 // initialization
371 $wsid = 987654321;
372
373 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
374 $this->pageRepo->versioningWorkspaceId = $wsid;
375 $this->pageRepo->init(false);
376
377 $pageRec = $this->pageRepo->getPage(11);
378
379 $this->assertEquals(11, $pageRec['uid']);
380 $this->assertEquals(11, $pageRec['t3ver_oid']);
381 $this->assertEquals(987654321, $pageRec['t3ver_wsid']);
382 $this->assertEquals(-1, $pageRec['t3ver_state']);
383 $this->assertSame('First draft version', $pageRec['t3ver_label']);
384 }
385
386 /**
387 * @test
388 */
389 public function getWorkspaceVersionReturnsTheCorrectMethod()
390 {
391 // initialization
392 $wsid = 987654321;
393
394 // simulate calls from \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->fetch_the_id()
395 $this->pageRepo->versioningWorkspaceId = $wsid;
396 $this->pageRepo->init(false);
397
398 $pageRec = $this->pageRepo->getWorkspaceVersionOfRecord($wsid, 'pages', 11);
399
400 $this->assertEquals(12, $pageRec['uid']);
401 $this->assertEquals(11, $pageRec['t3ver_oid']);
402 $this->assertEquals(987654321, $pageRec['t3ver_wsid']);
403 $this->assertEquals(-1, $pageRec['t3ver_state']);
404 $this->assertSame('First draft version', $pageRec['t3ver_label']);
405 }
406
407 ////////////////////////////////
408 // Tests concerning versioning
409 ////////////////////////////////
410
411 /**
412 * @test
413 */
414 public function enableFieldsHidesVersionedRecordsAndPlaceholders()
415 {
416 $table = $this->getUniqueId('aTable');
417 $GLOBALS['TCA'][$table] = [
418 'ctrl' => [
419 'versioningWS' => true
420 ]
421 ];
422
423 $this->pageRepo->versioningWorkspaceId = 0;
424 $this->pageRepo->init(false);
425
426 $conditions = $this->pageRepo->enableFields($table);
427 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
428
429 $this->assertThat(
430 $conditions,
431 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)'),
432 'Versioning placeholders'
433 );
434 $this->assertThat(
435 $conditions,
436 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)'),
437 'Records from page -1'
438 );
439 }
440
441 /**
442 * @test
443 */
444 public function enableFieldsDoesNotHidePlaceholdersInPreview()
445 {
446 $table = $this->getUniqueId('aTable');
447 $GLOBALS['TCA'][$table] = [
448 'ctrl' => [
449 'versioningWS' => true
450 ]
451 ];
452
453 $this->pageRepo->versioningWorkspaceId = 13;
454 $this->pageRepo->init(false);
455
456 $conditions = $this->pageRepo->enableFields($table);
457 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
458
459 $this->assertThat(
460 $conditions,
461 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)')),
462 'No versioning placeholders'
463 );
464 $this->assertThat(
465 $conditions,
466 $this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)'),
467 'Records from page -1'
468 );
469 }
470
471 /**
472 * @test
473 */
474 public function enableFieldsDoesFilterToCurrentAndLiveWorkspaceForRecordsInPreview()
475 {
476 $table = $this->getUniqueId('aTable');
477 $GLOBALS['TCA'][$table] = [
478 'ctrl' => [
479 'versioningWS' => true
480 ]
481 ];
482
483 $this->pageRepo->versioningWorkspaceId = 2;
484 $this->pageRepo->init(false);
485
486 $conditions = $this->pageRepo->enableFields($table);
487 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
488
489 $this->assertThat(
490 $conditions,
491 $this->stringContains(' AND ((' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 2))'),
492 'No versioning placeholders'
493 );
494 }
495
496 /**
497 * @test
498 */
499 public function enableFieldsDoesNotHideVersionedRecordsWhenCheckingVersionOverlays()
500 {
501 $table = $this->getUniqueId('aTable');
502 $GLOBALS['TCA'][$table] = [
503 'ctrl' => [
504 'versioningWS' => true
505 ]
506 ];
507
508 $this->pageRepo->versioningWorkspaceId = 23;
509 $this->pageRepo->init(false);
510
511 $conditions = $this->pageRepo->enableFields($table, -1, [], true);
512 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
513
514 $this->assertThat(
515 $conditions,
516 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)')),
517 'No versioning placeholders'
518 );
519 $this->assertThat(
520 $conditions,
521 $this->logicalNot($this->stringContains(' AND (' . $connection->quoteIdentifier($table . '.pid') . ' <> -1)')),
522 'No records from page -1'
523 );
524 }
525
526 protected function assertOverlayRow($row)
527 {
528 $this->assertInternalType('array', $row);
529
530 $this->assertArrayHasKey('_PAGES_OVERLAY', $row);
531 $this->assertArrayHasKey('_PAGES_OVERLAY_UID', $row);
532 $this->assertArrayHasKey('_PAGES_OVERLAY_LANGUAGE', $row);
533
534 $this->assertTrue($row['_PAGES_OVERLAY']);
535 }
536
537 protected function assertNotOverlayRow($row)
538 {
539 $this->assertInternalType('array', $row);
540
541 $this->assertFalse(isset($row['_PAGES_OVERLAY']));
542 $this->assertFalse(isset($row['_PAGES_OVERLAY_UID']));
543 $this->assertFalse(isset($row['_PAGES_OVERLAY_LANGUAGE']));
544 }
545 }