Project

General

Profile

Actions

Bug #32573

closed

locallangXMLOverride is broken since the switch to XLIFF

Added by Lars no-lastname-given almost 13 years ago. Updated almost 13 years ago.

Status:
Closed
Priority:
Must have
Category:
-
Target version:
Start date:
2011-12-14
Due date:
% Done:

100%

Estimated time:
TYPO3 Version:
4.6
PHP Version:
5.3
Tags:
Complexity:
Is Regression:
Sprint Focus:

Description

Since TYPO3 4.6 the locallangXMLOverride mechanism does not work like before v4.6. There are some issues while loading translations from XML files, e.g. the target language will be mixed with the default language.

I use the following line oh php code to configure the override in a localconf-file:

$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['path/to/originalTranslationFile.xml'][] = 'path/to/otherTranslationFile.xml'

The content of the original translation file "originalTranslationFile.xml" is this:

    <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
    <T3locallang>
        <data type="array">
            <languageKey index="default" type="array">
                <label index="test_label_one">one (default)</label>
                <label index="test_label_two">two (default)</label>
            </languageKey>

            <languageKey index="de" type="array">
                <label index="test_label_one">eins (german)</label>
                <label index="test_label_two">zwei (german)</label>
            </languageKey>
        </data>
    </T3locallang>

The content of the translation file "otherTranslationFile.xml", which is used to override translations, is this:

    <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
    <T3locallang>
        <data type="array">
            <languageKey index="fr" type="array">
                <label index="test_label_one">une (française)</label>
            </languageKey>
        </data>
    </T3locallang>

My testcase in typoscript is something like this, it only outputs two translations via the TS-TEXT object:

    config {
        linkVars = L
        sys_language_uid = 0
        language = en
        locale_all = en_EN.UTF-8
        htmlTag_langKey = en
    }

    # DE
    [globalVar=GP:L=1]
        config {
            sys_language_uid = 1
            language = de
            locale_all = de_DE.UTF-8
            htmlTag_langKey = de
        }
    [global]

    # FR
    [globalVar = GP:L = 2]
        config {
            sys_language_uid = 2
            language = fr
            locale_all = fr_FR.UTF-8
            htmlTag_langKey = fr
        }
    [global]

    page = PAGE
    page.typeNum = 0

    page.10 = TEXT
    page.10.data = LLL:path/to/originalTranslationFile.xml:test_label_one
    page.10.wrap = | <br />

    page.20 = TEXT
    page.20.data = LLL:path/to/originalTranslationFile.xml:test_label_two

The output in english (the default language) is this:

une (française) // << that's wrong! It must be "one (default)"
two (default)

In german:

une (française) // << that's wrong! It must be "eins (german)"
zwei (german)

In french:

une (française)
two (default)

Also do tests with this "otherTranslationFile.xml" files:
otherTranslationFile V2:

    <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
    <T3locallang>
        <data type="array">
            <languageKey index="default" type="array">
                <label index="test_label_one">one (default NEW)</label>
                <label index="test_label_two">two (default NEW)</label>
            </languageKey>

            <languageKey index="de" type="array">
                <label index="test_label_one">eins (german NEW)</label>
            </languageKey>

            <languageKey index="fr" type="array">
                <label index="test_label_one">une (française)</label>
            </languageKey>
        </data>
    </T3locallang>

otherTranslationFile V3:

    <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
    <T3locallang>
        <data type="array">
            <languageKey index="default" type="array">
                <label index="test_label_two">two (default NEW)</label>
            </languageKey>

            <languageKey index="de" type="array">
                <label index="test_label_one">eins (german NEW)</label>
            </languageKey>

            <languageKey index="fr" type="array">
                <label index="test_label_one">une (française)</label>
            </languageKey>
        </data>
    </T3locallang>

After a lot of debugging i had replace the body of method "t3lib_l10n_parser_Llxml::doParsingFromRootForElement" with this:

    protected function doParsingFromRootForElement(SimpleXMLElement $root, $element) {
        $bodyOfFileTag = $root->data->languageKey;

            // Check if the source llxml file contains localized records
        $localizedBodyOfFileTag = $root->data->xpath("languageKey[@index='" . $this->languageKey . "']");
        if ($element === 'target' && count($localizedBodyOfFileTag) === 0)
            return array();

        $parsedData = $this->getParsedDataForElement($bodyOfFileTag, $element);
        if ($element === 'source')
            return $parsedData;

        if ($element === 'target' && isset($localizedBodyOfFileTag[0]) && $localizedBodyOfFileTag[0] instanceof SimpleXMLElement) {
            $parsedTargetData = $this->getParsedDataForElement($localizedBodyOfFileTag[0], $element);
            $mergedData = array_merge($parsedData, $parsedTargetData);

            if ($this->languageKey === 'default') {
                foreach (array_keys($mergedData) as $key) {
                    if (!isset($parsedData[$key])) {
                        unset($mergedData[$key]);
                    }
                }
            } else {
                foreach (array_keys($mergedData) as $key) {
                    if (!isset($parsedTargetData[$key])) {
                        unset($mergedData[$key]);
                    }
                }
            }

            return $mergedData;
        }

        return $parsedData;
    }

This does work for my test cases very well, but i can imagine that there is a better way then unset all unneeded keys.

i also do a little optimization if the method was loading the translations for $element = 'source'.

Actions #1

Updated by Xavier Perseguers almost 13 years ago

  • Subject changed from Bug in locallangXMLOverride mechanism since TYPO3 4.6 to locallangXMLOverride is broken since the switch to XLIFF
Actions #2

Updated by Gerrit Code Review almost 13 years ago

  • Status changed from New to Under Review

Patch set 1 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269

Actions #3

Updated by Lars no-lastname-given almost 13 years ago

I'm sorry, but the bug is a bit difficult. A fact is, that the result has changed from TYPO3 v4.5 to 4.6.

Currently i am using this version of the method "t3lib_l10n_parser_llxml::doParsingFromRootForElement":


    protected function doParsingFromRootForElement(SimpleXMLElement $root, $element) {
        $bodyOfFileTag = $root->data->languageKey;

            // Check if the source llxml file contains localized records
        $localizedBodyOfFileTag = $root->data->xpath("languageKey[@index='" . $this->languageKey . "']");

            // If no records found return empty array
        if ($element === 'target' && count($localizedBodyOfFileTag) === 0)
            return array();

        $parsedData = $this->getParsedDataForElement($bodyOfFileTag, $element);
        if ($element === 'target' && isset($localizedBodyOfFileTag[0]) && $localizedBodyOfFileTag[0] instanceof SimpleXMLElement) {
            $parsedTargetData = $this->getParsedDataForElement($localizedBodyOfFileTag[0], $element);

            $mergedData = array_merge($parsedData, $parsedTargetData);
            if ($this->languageKey === 'default') {
                $mergedData = array_intersect_key($mergedData, $parsedTargetData);
                $parsedData = array_intersect_key($mergedData, $parsedData);
            } else{
                $parsedData = array_intersect_key($mergedData, $parsedTargetData);
            }
        }

        return $parsedData;
    }

We have to test it with many cases like adding (new!) and overwriting translations (or whole new languages) inside the default- and any other languages.

Actions #4

Updated by Gerrit Code Review almost 13 years ago

Patch set 2 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269

Actions #5

Updated by Gerrit Code Review almost 13 years ago

Patch set 3 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269

Actions #6

Updated by Gerrit Code Review almost 13 years ago

Patch set 4 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269

Actions #7

Updated by Gerrit Code Review almost 13 years ago

Patch set 5 for branch master has been pushed to the review server.
It is available at http://review.typo3.org/7269

Actions #8

Updated by Lars no-lastname-given almost 13 years ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100
Actions #9

Updated by Xavier Perseguers almost 13 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF