[BUGFIX] Fix template rootline for translated pages 74/21174/4
authorAlexander Stehlik <alexander.stehlik@googlemail.com>
Fri, 31 May 2013 15:07:00 +0000 (17:07 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Sat, 15 Jun 2013 12:38:31 +0000 (14:38 +0200)
The TypoScript template rootline in the Frontend will not be
changed any more if a different sys_language_uid is used.

The data of the current rootLine will be overwritten with the
translated rootLine data.

Resolves: #48300
Releases: 6.2, 6.1
Change-Id: I38bd4a6f3d3c2f15712003b1d1a1334284ebe9b0
Reviewed-on: https://review.typo3.org/21174
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
typo3/sysext/core/Classes/TypoScript/TemplateService.php
typo3/sysext/core/Tests/Unit/TypoScript/TemplateServiceTest.php
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
typo3/sysext/frontend/Tests/Unit/Controller/TypoScriptFrontendControllerTest.php

index 48126fe..e01637e 100644 (file)
@@ -697,6 +697,38 @@ class TemplateService {
        }
 
        /**
+        * This function can be used to update the data of the current rootLine
+        * e.g. when a different language is used.
+        *
+        * This function must not be used if there are different pages in the
+        * rootline as before!
+        *
+        * @param array $fullRootLine Array containing the FULL rootline (up to the TYPO3 root)
+        * @return void
+        * @throws \RuntimeException If the given $fullRootLine does not contain all pages that are in the current template rootline
+        */
+       public function updateRootlineData($fullRootLine) {
+               if (!is_array($this->rootLine) || count($this->rootLine) === 0) {
+                       return;
+               }
+
+               $fullRootLineByUid = array();
+               foreach ($fullRootLine as $rootLineData) {
+                       $fullRootLineByUid[$rootLineData['uid']] = $rootLineData;
+               }
+
+               foreach ($this->rootLine as $level => $dataArray) {
+                       $currentUid = $dataArray['uid'];
+
+                       if (!array_key_exists($currentUid, $fullRootLineByUid)) {
+                               throw new \RuntimeException(sprintf('The full rootLine does not contain data for the page with the uid %d that is contained in the template rootline.', $currentUid), 1370419654);
+                       }
+
+                       $this->rootLine[$level] = $fullRootLineByUid[$currentUid];
+               }
+       }
+
+       /**
         * Includes static template records (from static_template table, loaded through a hook) and static template files (from extensions) for the input template record row.
         *
         * @param string $idList A list of already processed template ids including the current; The list is on the form "[prefix]_[uid]" where [prefix] is "sys" for "sys_template" records, "static" for "static_template" records and "ext_" for static include files (from extensions). The list is used to check that the recursive inclusion of templates does not go into circles: Simply it is used to NOT include a template record/file which has already BEEN included somewhere in the recursion.
index 5440d5c..5ec8bfd 100644 (file)
@@ -44,12 +44,18 @@ class TemplateServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        protected $templateService;
 
        /**
+        * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface|\TYPO3\CMS\Core\TypoScript\TemplateService
+        */
+       protected $templateServiceMock;
+
+       /**
         * Sets up this test case.
         *
         * @return void
         */
        protected function setUp() {
                $this->templateService = new \TYPO3\CMS\Core\TypoScript\TemplateService();
+               $this->templateServiceMock = $this->getAccessibleMock('\\TYPO3\\CMS\\Core\\TypoScript\\TemplateService', array('dummy'));
        }
 
        /**
@@ -59,6 +65,7 @@ class TemplateServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         */
        protected function tearDown() {
                unset($this->templateService);
+               unset($this->templateServiceMock);
        }
 
        /**
@@ -112,6 +119,50 @@ class TemplateServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                );
        }
 
+       /**
+        * @test
+        */
+       public function updateRootlineDataOverwritesOwnArrayData() {
+               $originalRootline = array(
+                       0 => array('uid' => 2, 'title' => 'originalTitle'),
+                       1 => array('uid' => 3, 'title' => 'originalTitle2'),
+               );
+
+               $updatedRootline = array(
+                       0 => array('uid' => 1, 'title' => 'newTitle'),
+                       1 => array('uid' => 2, 'title' => 'newTitle2'),
+                       2 => array('uid' => 3, 'title' => 'newTitle3'),
+               );
+
+               $expectedRootline = array(
+                       0 => array('uid' => 2, 'title' => 'newTitle2'),
+                       1 => array('uid' => 3, 'title' => 'newTitle3'),
+               );
+
+               $this->templateServiceMock->_set('rootLine', $originalRootline);
+               $this->templateServiceMock->updateRootlineData($updatedRootline);
+               $this->assertEquals($expectedRootline, $this->templateServiceMock->_get('rootLine'));
+       }
+
+       /**
+        * @test
+        * @expectedException \RuntimeException
+        */
+       public function updateRootlineDataWithInvalidNewRootlineThrowsException() {
+               $originalRootline = array(
+                       0 => array('uid' => 2, 'title' => 'originalTitle'),
+                       1 => array('uid' => 3, 'title' => 'originalTitle2'),
+               );
+
+               $newInvalidRootline = array(
+                       0 => array('uid' => 1, 'title' => 'newTitle'),
+                       1 => array('uid' => 2, 'title' => 'newTitle2'),
+               );
+
+               $this->templateServiceMock->_set('rootLine', $originalRootline);
+               $this->templateServiceMock->updateRootlineData($newInvalidRootline);
+       }
+
 }
 
 ?>
\ No newline at end of file
index 13ade45..6402beb 100644 (file)
@@ -2574,11 +2574,9 @@ class TypoScriptFrontendController {
         * Updating content of the two rootLines IF the language key is set!
         */
        protected function updateRootLinesWithTranslations() {
-               if ($this->sys_language_uid && is_array($this->tmpl->rootLine)) {
-                       $this->tmpl->rootLine = array_reverse($this->sys_page->getRootLine($this->id, $this->MP));
-               }
-               if ($this->sys_language_uid && is_array($this->rootLine)) {
+               if ($this->sys_language_uid) {
                        $this->rootLine = $this->sys_page->getRootLine($this->id, $this->MP);
+                       $this->tmpl->updateRootlineData($this->rootLine);
                }
        }
 
index fbbcf0f..2328561 100644 (file)
@@ -180,31 +180,6 @@ class TypoScriptFrontendControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCas
                $this->assertSame($expectedId, $this->fixture->id);
        }
 
-       /**
-        * @test
-        */
-       public function translationOfRootLinesSetsTheTemplateRootLineToReversedVersionOfMainRootLine() {
-               $rootLine = array(
-                                       array('uid' => 1),
-                                       array('uid' => 2)
-                               );
-               $pageContextMock = $this->getMock('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
-               $templateServiceMock = $this->getMock('TYPO3\\CMS\\Core\\TypoScript\\TemplateService');
-               $pageContextMock
-                       ->expects($this->any())
-                       ->method('getRootline')
-                       ->will($this->returnValue($rootLine));
-               $this->fixture->_set('sys_page', $pageContextMock);
-               $this->fixture->_set('tmpl', $templateServiceMock);
-               $this->fixture->sys_language_uid = 1;
-               $this->fixture->rootLine = array();
-               $this->fixture->tmpl->rootLine = array();
-
-               $this->fixture->_call('updateRootLinesWithTranslations');
-               $this->assertSame($rootLine, $this->fixture->rootLine);
-               $this->assertSame(array_reverse($rootLine), $this->fixture->tmpl->rootLine);
-       }
-
 }
 
 ?>
\ No newline at end of file