Project

General

Profile

Actions

Bug #61543

closed

Language Fallback fails when displaying records, which have translation for other languages but not the current language

Added by Andre Rinas over 9 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Must have
Assignee:
Category:
-
Target version:
-
Start date:
2014-09-11
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
6.2
PHP Version:
Tags:
Complexity:
Is Regression:
No
Sprint Focus:

Description

We are building on an extension with extbase and found something special:

If you have for example 3 Languages (en = 0, de =1, fr = 2) and

you create 4 Records in english and nothing else
- > all 4 records are showing up in all 3 languages in english

If you create translation for records in fr you then:
- > all 4 records showing in english => right
- > all 4 records showing in french => right
- > none record showing in german => wrong!

After some debugging we found out that addSysLanguageStatement in file:
/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbQueryParser.php

makes the error.

if ($mode === 'strict') {
    $additionalWhereClause = $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=-1' .
        ' OR (' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . ' = ' . (int)$querySettings->getLanguageUid() .
        ' AND ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'] . '=0' .
        ') OR (' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=0' .
        ' AND ' . $tableName . '.uid 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'] . '=' . (int)$querySettings->getLanguageUid() ;
} else {
    $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';

 }

The marked line is excluding uid's for fallback, if any translation for the record is found, but it has to remove only records that are in the current language.
The line should be deleted or extended.

So if you are in german (sys_language_uid = 1 in my example) it should be:
' AND ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=1';


Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Bug #62155: IRRE at localized records not working properly with Extbase/Fluid Rejected2014-10-10

Actions
Actions #1

Updated by Andre Rinas over 9 years ago

You can fix this bug with an XClass like so:

Add this to your ext_localconf.php

$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser'] = array(
    'className' => 'Tx_MyExt_XClass_Typo3DbQueryParser'
);

Add Typo3DbQueryParser.php with the following content to /Classes/XClasses/

<?php

class Tx_MyExt_XClass_Typo3DbQueryParser extends \TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser
{

    /**
     * Builds the language field statement
     *
     * @param string $tableName The database table name
     * @param array &$sql The query parts
     * @param QuerySettingsInterface $querySettings The TYPO3 CMS specific query settings
     * @return void
     */
    protected function addSysLanguageStatement($tableName, array &$sql, $querySettings) {

        if (is_array($GLOBALS['TCA'][$tableName]['ctrl'])) {
            if (!empty($GLOBALS['TCA'][$tableName]['ctrl']['languageField'])) {
                // Select all entries for the current language
                $additionalWhereClause = $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . ' IN (' . (int)$querySettings->getLanguageUid() . ',-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 (isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])
                    && $querySettings->getLanguageUid() > 0
                ) {

                    $mode = $querySettings->getLanguageMode();
                    if ($mode === 'strict') {
                        $additionalWhereClause = $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=-1' .
                            ' OR (' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . ' = ' . (int)$querySettings->getLanguageUid() .
                            ' AND ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'] . '=0' .
                            ') OR (' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=0' .
                            ' AND ' . $tableName . '.uid 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'] . '=' . (int)$querySettings->getLanguageUid() ;
                    } else {
                        $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'] . '='.(int)$querySettings->getLanguageUid();
                            //see https://forge.typo3.org/issues/61543
                            //' 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 . ')';
            }
        }
    }
}


Remember to rename the Classnames to your Extkeys!

Actions #2

Updated by Riccardo De Contardi almost 9 years ago

  • Status changed from New to Needs Feedback
  • Assignee set to Andre Rinas

Hi Andre,

is there work left to do on this topic? Could this be closed? Thank you!

Actions #3

Updated by Andre Rinas almost 9 years ago

Riccardo De Contardi wrote:

is there work left to do on this topic? Could this be closed? Thank you!

Hi Riccardo, the problem is fixed. You can see it in the file i named above.

Actions #4

Updated by Alexander Opitz over 8 years ago

Did you mean you fixed it with your XClassing or did you mean it was resolved in TYPO3s core?

Actions #5

Updated by Andre Rinas over 8 years ago

Hey, yes it was fixed by the core team already, not with my xclass. You could have looked at the mentioned line above to see that it was fixed.

Actions #6

Updated by Riccardo De Contardi over 8 years ago

  • Status changed from Needs Feedback to Closed
Actions

Also available in: Atom PDF