[FEATURE] Improved translation handling for statement generation
authorNicole Cordes <n.cordes@biz-design.biz>
Thu, 5 Apr 2012 17:24:34 +0000 (19:24 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 14 Aug 2012 19:48:23 +0000 (21:48 +0200)
When selecting items in a language other than default one, the
relations (e.g. for IRRE) can not be resolved correctly. This
fix adds the current language if handling is enabled for the chosen
table. Besides it corrects the ordering of items as it selects all
possible ones. For correct overlay the origin is fetched before.

Change-Id: Ibcfe83314c0f2fff54348d9ffab97cd7546779ca
Resolves: #32072
Resolves: #32216
Releases: 6.0
Reviewed-on: http://review.typo3.org/10188
Reviewed-by: Jochen Rau
Tested-by: Jochen Rau
Reviewed-by: Stefan Neufeind
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
typo3/sysext/extbase/Tests/Unit/Persistence/Storage/Typo3DbBackendTest.php

index 46b4386..e008c34 100644 (file)
@@ -846,8 +846,31 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
         */
        protected function addSysLanguageStatement($tableName, array &$sql) {
                if (is_array($GLOBALS['TCA'][$tableName]['ctrl'])) {
-                       if (isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== NULL) {
-                               $sql['additionalWhereClause'][] = $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . ' IN (0,-1)';
+                       if(isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== NULL) {
+
+                                       // Select all entries for the current language
+                               $additionalWhereClause = $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . ' IN (' .
+                                       $GLOBALS['TSFE']->sys_language_uid . ',-1)';
+
+                                       // If any language is set -> get those entries which are not translated yet
+                                       // They will be removed by t3lib_page::getRecordOverlay if not matching overlay mode
+                               if ($GLOBALS['TSFE']->sys_language_uid && isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])) {
+                                       $additionalWhereClause .= ' OR (' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=0 AND ' .
+                                               $tableName . '.uid NOT IN (' .
+                                                       'SELECT ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'] .
+                                                       ' FROM ' . $tableName .
+                                                       ' WHERE ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'] . '>0 AND ' .
+                                                               $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '>0';
+
+                                               // Add delete clause to ensure all entries are loaded
+                                       if (isset($GLOBALS['TCA'][$tableName]['ctrl']['delete'])) {
+                                               $additionalWhereClause .= ' AND ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] . '=0';
+                                       }
+
+                                       $additionalWhereClause .= '))';
+                               }
+
+                               $sql['additionalWhereClause'][] = '(' . $additionalWhereClause . ')';
                        }
                }
        }
@@ -996,6 +1019,23 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
                        } elseif ($source instanceof Tx_Extbase_Persistence_QOM_JoinInterface) {
                                $tableName = $source->getRight()->getSelectorName();
                        }
+
+                               // If current row is a translation select its parent
+                       if (isset($GLOBALS['TCA'][$tableName]) && isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) &&
+                               isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])) {
+
+                               if (isset($row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']]) &&
+                                       $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] > 0) {
+
+                                       $row = $this->databaseHandle->exec_SELECTgetSingleRow(
+                                               $tableName . '.*',
+                                               $tableName,
+                                               $tableName . '.uid=' . $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] . ' AND ' .
+                                                       $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=0'
+                                       );
+                               }
+                       }
+
                        $this->pageSelectObject->versionOL($tableName, $row, TRUE);
                        if ($this->pageSelectObject->versioningPreview && isset($row['_ORIG_uid'])) {
                                $row['uid'] = $row['_ORIG_uid'];
index 4202c6e..004754b 100644 (file)
 class Tx_Extbase_Tests_Unit_Persistence_Storage_Typo3DbBackendTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
 
        /**
+        * Enable backup of global and system variables
+        *
+        * @var boolean
+        */
+       protected $backupGlobals = true;
+
+       /**
+        * Exclude TYPO3_DB from backup/ restore of $GLOBALS
+        * because resource types cannot be handled during serializing
+        *
+        * @var array
+        */
+       protected $backupGlobalsBlacklist = array('TYPO3_DB');
+
+       /**
         * This is the data provider for the statement generation with a basic comparison
         *
         * @return array An array of data
@@ -90,6 +105,118 @@ class Tx_Extbase_Tests_Unit_Persistence_Storage_Typo3DbBackendTest extends Tx_Ex
        /**
         * @test
         */
+       public function addSysLanguageStatementWorksForDefaultLanguage() {
+               $table = uniqid('tx_coretest_table');
+               $GLOBALS['TCA'][$table]['ctrl'] = array(
+                       'languageField' => 'sys_language_uid'
+               );
+
+               $tsfe = $this->getMock('tslib_fe', array(), array(), '', false);
+               $tsfe->sys_language_uid = 0;
+               $GLOBALS['TSFE'] = $tsfe;
+
+               $sql = array();
+               $mockTypo3DbBackend = $this->getMock(
+                       $this->buildAccessibleProxy('Tx_Extbase_Persistence_Storage_Typo3DbBackend'),
+                       array('dummy'),
+                       array(),
+                       '',
+                       false);
+               $mockTypo3DbBackend->_callRef('addSysLanguageStatement', $table, $sql);
+
+               $expectedSql = array('additionalWhereClause' => array('(' . $table . '.sys_language_uid IN (0,-1))'));
+
+               $this->assertSame($expectedSql, $sql);
+       }
+
+       /**
+        * @test
+        */
+       public function addSysLanguageStatementWorksForDefaultLanguageWithoutDeleteStatementReturned() {
+               $table = uniqid('tx_coretest_table');
+               $GLOBALS['TCA'][$table]['ctrl'] = array(
+                       'languageField' => 'sys_language_uid',
+                       'delete' => 'deleted'
+               );
+
+               $tsfe = $this->getMock('tslib_fe', array(), array(), '', false);
+               $tsfe->sys_language_uid = 0;
+               $GLOBALS['TSFE'] = $tsfe;
+
+               $sql = array();
+               $mockTypo3DbBackend = $this->getMock(
+                       $this->buildAccessibleProxy('Tx_Extbase_Persistence_Storage_Typo3DbBackend'),
+                       array('dummy'),
+                       array(),
+                       '',
+                       false);
+               $mockTypo3DbBackend->_callRef('addSysLanguageStatement', $table, $sql);
+
+               $expectedSql = array('additionalWhereClause' => array('(' . $table . '.sys_language_uid IN (0,-1))'));
+
+               $this->assertSame($expectedSql, $sql);
+       }
+
+       /**
+        * @test
+        */
+       public function addSysLanguageStatementWorksForForeignLanguageWithoutSubselection() {
+               $table = uniqid('tx_coretest_table');
+               $GLOBALS['TCA'][$table]['ctrl'] = array(
+                       'languageField' => 'sys_language_uid'
+               );
+
+               $tsfe = $this->getMock('tslib_fe', array(), array(), '', false);
+               $tsfe->sys_language_uid = 2;
+               $GLOBALS['TSFE'] = $tsfe;
+
+               $sql = array();
+               $mockTypo3DbBackend = $this->getMock(
+                       $this->buildAccessibleProxy('Tx_Extbase_Persistence_Storage_Typo3DbBackend'),
+                       array('dummy'),
+                       array(),
+                       '',
+                       false);
+               $mockTypo3DbBackend->_callRef('addSysLanguageStatement', $table, $sql);
+
+               $expectedSql = array('additionalWhereClause' => array('(' . $table . '.sys_language_uid IN (2,-1))'));
+
+               $this->assertSame($expectedSql, $sql);
+       }
+
+       /**
+        * @test
+        */
+       public function addSysLanguageStatementWorksForForeignLanguageWithSubselectionWithoutDeleteStatementReturned() {
+               $table = uniqid('tx_coretest_table');
+               $GLOBALS['TCA'][$table]['ctrl'] = array(
+                       'languageField' => 'sys_language_uid',
+                       'transOrigPointerField' => 'l18n_parent'
+               );
+
+               $tsfe = $this->getMock('tslib_fe', array(), array(), '', false);
+               $tsfe->sys_language_uid = 2;
+               $GLOBALS['TSFE'] = $tsfe;
+
+               $sql = array();
+               $mockTypo3DbBackend = $this->getMock(
+                       $this->buildAccessibleProxy('Tx_Extbase_Persistence_Storage_Typo3DbBackend'),
+                       array('dummy'),
+                       array(),
+                       '',
+                       false);
+               $mockTypo3DbBackend->_callRef('addSysLanguageStatement', $table, $sql);
+
+               $expectedSql = array('additionalWhereClause' => array('(' . $table . '.sys_language_uid IN (2,-1) OR (' .
+                       $table . '.sys_language_uid=0 AND ' . $table . '.uid NOT IN (SELECT ' . $table . '.l18n_parent FROM ' . $table .
+                       ' WHERE ' . $table . '.l18n_parent>0 AND ' . $table . '.sys_language_uid>0)))'));
+
+               $this->assertSame($expectedSql, $sql);
+       }
+
+       /**
+        * @test
+        */
        public function orderStatementGenerationWorks() {
                $mockSource = $this->getMock('Tx_Extbase_Persistence_QOM_Selector', array('getNodeTypeName'), array(), '', FALSE);
                $mockSource->expects($this->any())->method('getNodeTypeName')->will($this->returnValue('Tx_MyExt_ClassName'));