[!!!][FEATURE] TypoScript select is now translated by default 70/41370/11
authorBenjamin Mack <benni@typo3.org>
Wed, 15 Jul 2015 21:28:05 +0000 (23:28 +0200)
committerBenjamin Mack <benni@typo3.org>
Thu, 16 Jul 2015 15:58:44 +0000 (17:58 +0200)
The TypoScript .select option which is used for Content Objects
like "CONTENT", has the property "languageField". This allows
to set the field that has the information about the sys_language_uid
value in order to have only records shown that are translated or
on -1 (show in all languages).

In the past, this option had to be set explicitly but is now turned
on by default, but can turned off, if this behavior is not desired.

Besides this patch adds some basic unit tests for the function and
resolves and issue with groupBy which popped up because of the tests.

Resolves: #68191
Releases: master
Change-Id: I36765d9e1e8a8b49fdc05700caa1e2e3f613a06d
Reviewed-on: http://review.typo3.org/41370
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
typo3/sysext/core/Documentation/Changelog/master/Feature-68191-TypoScriptSelectOptionLanguageFieldIsActiveByDefault.rst [new file with mode: 0644]
typo3/sysext/css_styled_content/static/setup.txt
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-68191-TypoScriptSelectOptionLanguageFieldIsActiveByDefault.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-68191-TypoScriptSelectOptionLanguageFieldIsActiveByDefault.rst
new file mode 100644 (file)
index 0000000..dfe1642
--- /dev/null
@@ -0,0 +1,58 @@
+==============================================================================
+Feature: #68191 - TypoScript .select option languageField is active by default
+==============================================================================
+
+Description
+===========
+
+The TypoScript .select option which is used for Content Objects like "CONTENT", has the property "languageField". This option allows to set the name of the database field that has the information about the sys_language_uid value in order to have only records shown that are translated or set to "-1" (show in all langauges) when showing translated pages.
+
+Previously this functionality had to be set explicitly:
+
+.. code-block:: typoscript
+
+       config.sys_language_uid = 2
+       page.10 = CONTENT
+       page.10 {
+               table = tt_content
+               select.where = colPos=0
+               select.languageField = sys_language_uid
+               renderObj = TEXT
+               renderObj.field = header
+               renderObj.htmlSpecialChars = 1
+       }
+
+The languageField line is not necessary anymore, as the information is now fetched automatically from the TCA information structure:
+
+.. code-block:: typoscript
+
+       config.sys_language_uid = 2
+       page.10 = CONTENT
+       page.10 {
+               table = tt_content
+               select.where = colPos=0
+               renderObj = TEXT
+               renderObj.field = header
+               renderObj.htmlSpecialChars = 1
+       }
+
+If the functionality should be disabled, this can be achieved like this:
+
+.. code-block:: typoscript
+
+       config.sys_language_uid = 2
+       page.10 = CONTENT
+       page.10 {
+               table = tt_content
+               select.where = colPos=0
+               select.languageField = 0
+               renderObj = TEXT
+               renderObj.field = header
+               renderObj.htmlSpecialChars = 1
+       }
+
+
+Impact
+======
+
+All records that have language-relevant information in the TCA "ctrl"-section displayed via .select in the frontend on translated pages are now translated by default.
index 8fd2fbd..33d76d7 100644 (file)
@@ -12,7 +12,6 @@ styles.content.get {
        table = tt_content
        select.orderBy = sorting
        select.where = colPos=0
-       select.languageField = sys_language_uid
 }
 
 # get content, left
index de33592..a790952 100644 (file)
@@ -8058,18 +8058,25 @@ class ContentObjectRenderer {
                if ($where) {
                        $query .= ' AND ' . $where;
                }
-               if ($conf['languageField']) {
+
+               // Check if the table is translatable, and set the language field by default from the TCA information
+               $languageField = '';
+               if (!empty($conf['languageField']) || !isset($conf['languageField'])) {
+                       if (isset($conf['languageField']) && !empty($GLOBALS['TCA'][$table]['columns'][$conf['languageField']])) {
+                               $languageField = $conf['languageField'];
+                       } elseif (!empty($GLOBALS['TCA'][$table]['ctrl']['languageField']) && !empty($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'])) {
+                               $languageField = $table . '.' . $GLOBALS['TCA'][$table]['ctrl']['languageField'];
+                       }
+               }
+
+               if (!empty($languageField)) {
                        // The sys_language record UID of the content of the page
                        $sys_language_content = (int)$GLOBALS['TSFE']->sys_language_content;
 
-                       if ($GLOBALS['TSFE']->sys_language_contentOL
-                               && isset($GLOBALS['TCA'][$table])
-                               && !empty($GLOBALS['TCA'][$table]['ctrl']['languageField'])
-                               && !empty($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'])
-                       ) {
+                       if ($GLOBALS['TSFE']->sys_language_contentOL && !empty($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'])) {
                                // Sys language content is set to zero/-1 - and it is expected that whatever routine processes the output will
                                // OVERLAY the records with localized versions!
-                               $languageQuery = $conf['languageField'] . ' IN (0,-1)';
+                               $languageQuery = $languageField . ' IN (0,-1)';
                                // Use this option to include records that don't have a default translation
                                // (originalpointerfield is 0 and the language field contains the requested language)
                                $includeRecordsWithoutDefaultTranslation = isset($conf['includeRecordsWithoutDefaultTranslation.']) ?
@@ -8077,10 +8084,10 @@ class ContentObjectRenderer {
                                        $conf['includeRecordsWithoutDefaultTranslation'];
                                if (!empty(trim($includeRecordsWithoutDefaultTranslation))) {
                                        $languageQuery .= ' OR (' . $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] . ' = 0 AND ' .
-                                               $conf['languageField'] . ' = ' . $sys_language_content . ')';
+                                               $languageField . ' = ' . $sys_language_content . ')';
                                }
                        } else {
-                               $languageQuery = $conf['languageField'] . ' = ' . $sys_language_content;
+                               $languageQuery = $languageField . ' = ' . $sys_language_content;
                        }
                        $query .= ' AND (' . $languageQuery . ')';
                }
@@ -8104,6 +8111,7 @@ class ContentObjectRenderer {
                // GROUP BY
                if (trim($conf['groupBy'])) {
                        $queryParts['GROUPBY'] = isset($conf['groupBy.']) ? trim($this->stdWrap($conf['groupBy'], $conf['groupBy.'])) : trim($conf['groupBy']);
+                       $query .= ' GROUP BY ' . $queryParts['GROUPBY'];
                }
                // ORDER BY
                if (trim($conf['orderBy'])) {
index 8f6b9fd..0725f36 100644 (file)
@@ -20,6 +20,7 @@ use TYPO3\CMS\Core\Core\ApplicationContext;
 use TYPO3\CMS\Core\Log\LogManager;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\AbstractContentObject;
+use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
 
 /**
  * Testcase for TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
@@ -3565,4 +3566,98 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                );
        }
 
+       /**
+        * @return array
+        */
+       public function getWhereReturnCorrectQueryDataProvider() {
+               return array(
+                       array(
+                               array(
+                                       'tt_content' => array(
+                                               'ctrl' => array(
+                                               ),
+                                               'columns' => array(
+                                               )
+                                       ),
+                               ),
+                               'tt_content',
+                               array(
+                                       'uidInList' => '42',
+                                       'pidInList' => 43,
+                                       'where' => 'tt_content.cruser_id=5',
+                                       'andWhere' => 'tt_content.crdate>0',
+                                       'groupBy' => 'tt_content.title',
+                                       'orderBy' => 'tt_content.sorting',
+                               ),
+                               'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5 AND tt_content.crdate>0 GROUP BY tt_content.title ORDER BY tt_content.sorting',
+                       ),
+                       array(
+                               array(
+                                       'tt_content' => array(
+                                               'ctrl' => array(
+                                                       'delete' => 'deleted',
+                                                       'enablecolumns' => array(
+                                                               'disabled' => 'hidden',
+                                                               'starttime' => 'startdate',
+                                                               'endtime' => 'enddate',
+                                                       ),
+                                                       'languageField' => 'sys_language_uid',
+                                                       'transOrigPointerField' => 'l18n_parent',
+                                               ),
+                                               'columns' => array(
+                                               )
+                                       ),
+                               ),
+                               'tt_content',
+                               array(
+                                       'uidInList' => 42,
+                                       'pidInList' => 43,
+                                       'where' => 'tt_content.cruser_id=5',
+                                       'andWhere' => 'tt_content.crdate>0',
+                                       'groupBy' => 'tt_content.title',
+                                       'orderBy' => 'tt_content.sorting',
+                               ),
+                               'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5 AND (tt_content.sys_language_uid = 13) AND tt_content.crdate>0 AND tt_content.deleted=0 AND tt_content.hidden=0 AND tt_content.startdate<=4242 AND (tt_content.enddate=0 OR tt_content.enddate>4242) GROUP BY tt_content.title ORDER BY tt_content.sorting',
+                       ),
+                       array(
+                               array(
+                                       'tt_content' => array(
+                                               'ctrl' => array(
+                                                       'languageField' => 'sys_language_uid',
+                                                       'transOrigPointerField' => 'l18n_parent',
+                                               ),
+                                               'columns' => array(
+                                               )
+                                       ),
+                               ),
+                               'tt_content',
+                               array(
+                                       'uidInList' => 42,
+                                       'pidInList' => 43,
+                                       'where' => 'tt_content.cruser_id=5',
+                                       'languageField' => 0,
+                               ),
+                               'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5',
+                       ),
+               );
+       }
+
+       /**
+        * @test
+        * @param array $tca
+        * @param string $table
+        * @param array $configuration
+        * @param string $expectedResult
+        * @dataProvider getWhereReturnCorrectQueryDataProvider
+        */
+       public function getWhereReturnCorrectQuery($tca, $table, $configuration, $expectedResult) {
+               $GLOBALS['TCA'] = $tca;
+               $GLOBALS['SIM_ACCESS_TIME'] = '4242';
+               $GLOBALS['TSFE']->sys_language_content = 13;
+               /** @var \PHPUnit_Framework_MockObject_MockObject|ContentObjectRenderer $contentObjectRenderer */
+               $contentObjectRenderer = $this->getMock(ContentObjectRenderer::class, array('checkPidArray'));
+               $contentObjectRenderer->expects($this->any())->method('checkPidArray')->willReturn(explode(',', $configuration['pidInList']));
+               $this->assertEquals($expectedResult, $contentObjectRenderer->getWhere($table, $configuration));
+       }
+
 }