[BUGFIX] sectionIndex menu is not i18n ready
authorStefan Galinski <stefan.galinski@gmail.com>
Wed, 16 May 2012 15:42:36 +0000 (17:42 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 7 Aug 2012 19:10:39 +0000 (21:10 +0200)
Change-Id: I34281d801f292530a1618d8b38eafac22b02b511
Fixes: #36616
Releases: 6.0, 4.7
Reviewed-on: http://review.typo3.org/11249
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Markus Klein
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
t3lib/class.t3lib_page.php
typo3/sysext/cms/tests/tslib/class.tslib_menuTest.php [new file with mode: 0644]
typo3/sysext/cms/tslib/class.tslib_menu.php

index 5f0e22c..333ed21 100644 (file)
@@ -306,6 +306,7 @@ class t3lib_pageSelect {
                                if (is_array($row)) {
                                        $row['_PAGES_OVERLAY'] = TRUE;
                                        $row['_PAGES_OVERLAY_UID'] = $row['uid'];
+                                       $row['_PAGES_OVERLAY_LANGUAGE'] = $lUid;
 
                                                // Unset vital fields that are NOT allowed to be overlaid:
                                        unset($row['uid']);
diff --git a/typo3/sysext/cms/tests/tslib/class.tslib_menuTest.php b/typo3/sysext/cms/tests/tslib/class.tslib_menuTest.php
new file mode 100644 (file)
index 0000000..0800a36
--- /dev/null
@@ -0,0 +1,211 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Stefan Galinski <stefan.galinski@gmail.com>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Testcase for the "tslib_menu" class in the TYPO3 Core.
+ *
+ * @package TYPO3
+ * @subpackage tslib
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+class tslib_menuTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
+       /**
+        * @var tslib_menu
+        */
+       private $fixture = NULL;
+
+       /**
+        * @var array
+        */
+       private $backupGlobalVariables = array();
+
+       public function setUp() {
+               $proxy = $this->buildAccessibleProxy('tslib_menu');
+               $this->fixture = new $proxy;
+
+               $backupGlobalVariables['TYPO3_DB'] = $GLOBALS['TYPO3_DB'];
+               $GLOBALS['TYPO3_DB'] = $this->getMock('t3lib_db');
+
+               $backupGlobalVariables['TSFE'] = $GLOBALS['TSFE'];
+               $GLOBALS['TSFE'] = $this->getMock('tslib_fe');
+       }
+
+       public function tearDown() {
+               foreach ($this->backupGlobalVariables as $key => $data) {
+                       $GLOBALS[$key] = $data;
+               }
+
+               unset($this->fixture);
+       }
+
+       ////////////////////////////////
+       // Tests concerning sectionIndex
+       ////////////////////////////////
+
+       /**
+        * Prepares a test for the method sectionIndex
+        *
+        * @return void
+        */
+       protected function prepareSectionIndexTest() {
+               $this->fixture->sys_page = $this->getMock('t3lib_pageSelect');
+               $this->fixture->parent_cObj = $this->getMock('tslib_cObj');
+       }
+
+       /**
+        * @test
+        */
+       public function sectionIndexReturnsEmptyArrayIfTheRequestedPageCouldNotBeFetched() {
+               $this->prepareSectionIndexTest();
+
+               $this->fixture->sys_page->expects($this->once())->method('getPage')
+                       ->will($this->returnValue(NULL));
+
+               $result = $this->fixture->_call('sectionIndex', 'field');
+               $this->assertEquals($result, array());
+       }
+
+       /**
+        * @test
+        */
+       public function sectionIndexUsesTheInternalIdIfNoPageIdWasGiven() {
+               $this->prepareSectionIndexTest();
+
+               $this->fixture->id = 10;
+               $this->fixture->sys_page->expects($this->once())->method('getPage')
+                       ->will($this->returnValue(NULL))->with(10);
+
+               $result = $this->fixture->_call('sectionIndex', 'field');
+               $this->assertEquals($result, array());
+       }
+
+       /**
+        * @test
+        * @expectedException UnexpectedValueException
+        */
+       public function sectionIndexThrowsAnExceptionIfTheInternalQueryFails() {
+               $this->prepareSectionIndexTest();
+
+               $this->fixture->sys_page->expects($this->once())->method('getPage')
+                       ->will($this->returnValue(array()));
+
+               $this->fixture->parent_cObj->expects($this->once())->method('exec_getQuery')
+                       ->will($this->returnValue(0));
+
+               $this->fixture->_call('sectionIndex', 'field');
+       }
+
+       /**
+        * @test
+        */
+       public function sectionIndexReturnsOverlaidRowBasedOnTheLanguageOfTheGivenPage() {
+               $this->prepareSectionIndexTest();
+
+               $this->fixture->mconf['sectionIndex.']['type'] = 'all';
+               $GLOBALS['TSFE']->sys_language_contentOL = 1;
+
+               $this->fixture->sys_page->expects($this->once())->method('getPage')
+                       ->will($this->returnValue(array('_PAGES_OVERLAY_LANGUAGE' => 1)));
+
+               $this->fixture->parent_cObj->expects($this->once())->method('exec_getQuery')
+                       ->will($this->returnValue(1));
+
+               $GLOBALS['TYPO3_DB']->expects($this->exactly(2))->method('sql_fetch_assoc')
+                       ->will($this->onConsecutiveCalls(
+                               $this->returnValue(array('uid' => 0, 'header' => 'NOT_OVERLAID')),
+                               $this->returnValue(FALSE))
+                       );
+
+               $this->fixture->sys_page->expects($this->once())->method('getRecordOverlay')
+                       ->will($this->returnValue(array('uid' => 0, 'header' => 'OVERLAID')));
+
+               $result = $this->fixture->_call('sectionIndex', 'field');
+               $this->assertEquals($result[0]['title'], 'OVERLAID');
+       }
+
+       /**
+        * @return array
+        */
+       public function sectionIndexFiltersDataProvider() {
+               return array(
+                       'unfiltered fields' => array(
+                               1, array(
+                                       'sectionIndex' => 1,
+                                       'header' => 'foo',
+                                       'header_layout' => 1,
+                               ),
+                       ),
+                       'with unset section index' => array(
+                               0, array(
+                                       'sectionIndex' => 0,
+                                       'header' => 'foo',
+                                       'header_layout' => 1,
+                               ),
+                       ),
+                       'with unset header' => array(
+                               0, array(
+                                       'sectionIndex' => 1,
+                                       'header' => '',
+                                       'header_layout' => 1,
+                               ),
+                       ),
+                       'with header layout 100' => array(
+                               0, array(
+                                       'sectionIndex' => 1,
+                                       'header' => 'foo',
+                                       'header_layout' => 100,
+                               ),
+                       ),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider sectionIndexFiltersDataProvider
+        * @param integer $expectedAmount
+        * @param array $dataRow
+        */
+       public function sectionIndexFilters($expectedAmount, array $dataRow) {
+               $this->prepareSectionIndexTest();
+
+               $this->fixture->mconf['sectionIndex.']['type'] = 'header';
+
+               $this->fixture->sys_page->expects($this->once())->method('getPage')
+                       ->will($this->returnValue(array()));
+
+               $this->fixture->parent_cObj->expects($this->once())->method('exec_getQuery')
+                       ->will($this->returnValue(1));
+
+               $GLOBALS['TYPO3_DB']->expects($this->exactly(2))->method('sql_fetch_assoc')
+                       ->will($this->onConsecutiveCalls(
+                               $this->returnValue($dataRow),
+                               $this->returnValue(FALSE))
+                       );
+
+               $result = $this->fixture->_call('sectionIndex', 'field');
+               $this->assertCount($expectedAmount, $result);
+       }
+}
+?>
\ No newline at end of file
index 3a22bad..3db75ef 100644 (file)
@@ -1759,72 +1759,78 @@ class tslib_menu {
         * Generates a list of content objects with sectionIndex enabled
         * available on a specific page
         *
-        * Used for menu's with sectionIndex enabled
+        * Used for menus with sectionIndex enabled
         *
         * @param string $altSortField Alternative sorting field
         * @param integer $pid The page id to search for sections
+        * @throws UnexpectedValueException if the query to fetch the content elements unexpectedly fails
         * @return array
         */
        protected function sectionIndex($altSortField, $pid = NULL) {
-               $where = 'colPos=0';
-
-               if (!$pid) {
-                       $pid = $this->id;
-                       if ($GLOBALS['TSFE']->sys_language_uid && count($this->sys_page->getPageOverlay($pid))) {
-                               $where .= ' AND sys_language_uid=' . intval($GLOBALS['TSFE']->sys_language_uid);
-                       } else {
-                               $where .= ' AND sys_language_uid=0';
-                       }
+               $pid = intval($pid ? $pid : $this->id);
+               $basePageRow = $this->sys_page->getPage($pid);
+               if (!is_array($basePageRow)) {
+                       return array();
                }
 
                $selectSetup = array(
                        'pidInList' => $pid,
                        'orderBy' => $altSortField,
-                       'where' => $where,
-                       'andWhere' => 'sectionIndex<>0'
+                       'languageField' => 'sys_language_uid',
+                       'where' => 'colPos=0'
                );
-               switch ($this->mconf['sectionIndex.']['type']) {
-                       case 'all':
-                               unset($selectSetup['andWhere']);
-                       break;
-                       case 'header':
-                               $selectSetup['andWhere'] .= ' AND header_layout<>100 AND header!=""';
-                       break;
-               }
-               $basePageRow = $this->sys_page->getPage($pid);
-               $result = array();
-               if (is_array($basePageRow)) {
-                       $res = $this->parent_cObj->exec_getQuery('tt_content', $selectSetup);
 
-                       while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
-                               $GLOBALS['TSFE']->sys_page->versionOL('tt_content', $row);
-
-                               if (is_array($row)) {
-                                       $result[$row['uid']] = $basePageRow;
-                                       $result[$row['uid']]['title'] = $row['header'];
-                                       $result[$row['uid']]['nav_title'] = $row['header'];
-                                       $result[$row['uid']]['subtitle'] = $row['subheader'];
-                                       $result[$row['uid']]['starttime'] = $row['starttime'];
-                                       $result[$row['uid']]['endtime'] = $row['endtime'];
-                                       $result[$row['uid']]['fe_group'] = $row['fe_group'];
-                                       $result[$row['uid']]['media'] = $row['media'];
+               $resource = $this->parent_cObj->exec_getQuery('tt_content', $selectSetup);
+               if (!$resource) {
+                       $message = 'SectionIndex: Query to fetch the content elements failed!';
+                       throw new UnexpectedValueException($message, 1337334849);
+               }
 
-                                       $result[$row['uid']]['header_layout'] = $row['header_layout'];
-                                       $result[$row['uid']]['bodytext'] = $row['bodytext'];
-                                       $result[$row['uid']]['image'] = $row['image'];
+               $result = array();
+               while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resource)) {
+                       $this->sys_page->versionOL('tt_content', $row);
+
+                       if ($GLOBALS['TSFE']->sys_language_contentOL && $basePageRow['_PAGES_OVERLAY_LANGUAGE']) {
+                               $row = $this->sys_page->getRecordOverlay(
+                                       'tt_content',
+                                       $row,
+                                       $basePageRow['_PAGES_OVERLAY_LANGUAGE'],
+                                       $GLOBALS['TSFE']->sys_language_contentOL
+                               );
+                       }
 
-                                       $result[$row['uid']]['sectionIndex_uid'] = $row['uid'];
+                       if ($this->mconf['sectionIndex.']['type'] !== 'all') {
+                               $doIncludeInSectionIndex = ($row['sectionIndex'] >= 1);
+                               $doHeaderCheck = ($this->mconf['sectionIndex.']['type'] === 'header');
+                               $isValidHeader = (intval($row['header_layout']) !== 100 && trim($row['header']) !== '');
+                               if (!$doIncludeInSectionIndex || ($doHeaderCheck && !$isValidHeader)) {
+                                       continue;
                                }
                        }
 
-                       if (is_resource($res)) {
-                               $GLOBALS['TYPO3_DB']->sql_free_result($res);
+                       if (is_array($row)) {
+                               $uid = $row['uid'];
+                               $result[$uid] = $basePageRow;
+                               $result[$uid]['title'] = $row['header'];
+                               $result[$uid]['nav_title'] = $row['header'];
+                               $result[$uid]['subtitle'] = $row['subheader'];
+                               $result[$uid]['starttime'] = $row['starttime'];
+                               $result[$uid]['endtime'] = $row['endtime'];
+                               $result[$uid]['fe_group'] = $row['fe_group'];
+                               $result[$uid]['media'] = $row['media'];
+
+                               $result[$uid]['header_layout'] = $row['header_layout'];
+                               $result[$uid]['bodytext'] = $row['bodytext'];
+                               $result[$uid]['image'] = $row['image'];
+
+                               $result[$uid]['sectionIndex_uid'] = $uid;
                        }
                }
 
+               $GLOBALS['TYPO3_DB']->sql_free_result($resource);
+
                return $result;
        }
-
 }
 
 /**