MetaModels / attribute_translatedalias

The translated alias attribute
GNU Lesser General Public License v3.0
0 stars 4 forks source link

Alias not saved in tl_metamodel_translatedtext #7

Closed Teetrinker closed 8 years ago

Teetrinker commented 10 years ago

When the alias is not changed in the secondary languages, it will not be inserted into tl_metamodel_translatedtext. When I edit another language and save it, the alias of this language is not inserted into tl_metamodel_translatedtext if it is still the same as in the first language. When I change the alias of the second language, it is saved, when I change it back to be identical with the alias of the first language, it is saved as well.

This is not really a bug, more a mild inconsistency.

However, it complicates third party development, for example solutions for the combination of MM and [changelanguage]. Therefore, I suggest that aliases are always saved into tl_metamodel_translatedtext, even if identical.

See also the forum discussion: https://community.contao.org/de/showthread.php?45678-3-1-x-MM-mit-Sprachwechsler-funktioniert-nicht

discordier commented 10 years ago

We have no way to determine that the data has been changed and therefore needs to be changed.

As you might know, all values use the value from the fallback language as initial value. Same goes for the "alias". When there has been no change, there is no reason for DC General to store the value to the database, as from it's point of view, there has been no change (the value is still the same as the one it loaded from MetaModels). The only solution would be to pass alwaysSave => true for this very property (of which I do not recall right now if it is implemented in DcGeneral).

So if you really need this feature, please file an PR, I will have to postpone this to future otherwise. :) In the end, MetaModels is not intended to be queried on the raw database tables like you did in your forum post.

In fact, something like this (untested code written from memory) would be better then (according to your specific problem in the forum):

//*** z_myproject/config/config.php 
// hook 
 $GLOBALS['TL_HOOKS']['translateUrlParameters'][] = array('MySpace\TranslatorHelper', 'translateMMUrls'); 
//*** z_myproject/classes/TranslatorHelper.php
namespace MySpace; 

class TranslatorHelper extends \Frontend 
{ 
    /** 
     * Hook callback for changelanguage extension to support language switching on product reader page 
     */     
    public function translateMMUrls($arrParams, $strLanguage, $arrRootPage)
    {
        // Remove index.php fragment from uri and drop query parameters as we are not interested in those.
        list($fullUri) = explode('?', str_replace('index.php/', '', \Environment::get('request')), 2);
        // Handle remaining arguments, and do that only if there are exactly two.
        $uri = explode('/', $fullUri);
        if (count($uri) == 2) { // 1. part is alias of MM (to be checked if correct), 2. part is alias of item.
            $metaModel = \MetaModels\Factory::getByTableName('mm_something');
            $attribute = $metaModel->getAttribute('alias'); // your attribute name here.
            // Only for safety here - You most definitely know that your alias is translated. ;)
            if (!in_array('MetaModels\Attribute\ITranslated', class_implements($attribute)) {
                return $arrParams;
            }   
            $ids = $attribute->searchForInLanguages($uri[1], array($GLOBALS['TL_LANGUAGE']));
            if (count($ids) == 1) {
                $item  = $metaModel->findById($ids[0]);
                $value = $item->parseAttribute('alias');
                // Override URL parameter now.
                $GLOBALS['TL_AUTO_ITEM'][] = $value;
                $arrParams['url'][$value]  = $value;
        } 
        return $arrParams; 
    } 
}

This way you lever the responsibility of resolving all the values up to MetaModels and therefore are independant of the concrete implementation of the used attribute. Now the Alias may be a translated text, a translated long text or any other translated value, including selects etc.

Hope this helps to clearify things a bit.

Teetrinker commented 9 years ago

Hi discordier. Thanks a lot for the example code! I implemented it and it works for the most part.

        if(count($uri) == 2){       
            $metaModel = \MetaModels\Factory::byTableName('mm_project');
            $attribute = $metaModel->getAttribute('alias'); // your attribute name here.

            // TODO: implement correct
            // Only for safety here - You most definitely know that your alias is translated. ;)
            //if (!in_array('MetaModels\Attribute\ITranslated', class_implements($attribute)) {
            //    return $arrParams;
            //}  

        $ids = $attribute->searchForInLanguages($uri[1], array($strLanguage)  );

        if (count($ids) == 1) {
            $item  = $metaModel->findById($ids[0]);     
            $value = $item->parseAttribute('alias');
            // Override URL parameter now.
            $GLOBALS['TL_AUTO_ITEM'][] = $value;
            $arrParams['url'][$value]  = $value;
            return $arrParams;                  
        }
        $arrParams['url'][$value] = $uri[1];
        return $arrParams;
    }
amenk commented 9 years ago

I am trying to put that into a module...

amenk commented 9 years ago

https://github.com/iMi-digital/imi_mm_changelanguage

zonky2 commented 8 years ago

@Teetrinker kann das Ticket damit geschlossen werden oder noch aktuell?

discordier commented 8 years ago

contao-community-alliance/dc-general#174