Archive for category CakePHP

CakePHP : Translate Behaviour : Fixing Nested Translation Problem

If you ever tried to use Translation Behaviour of CakePHP you should realize that Translate Behavior does not support nested translations for the model relations. I’ve found one article that shows how to fix a similar translation problem on related models at http://groups.google.com/group/cake-php/browse_thread/thread/9b7e60900269643b%29.

Unfortunately it was not a complete solution that you can implement easily but it gave me a good approach to help the model to request nested queries to make Translate Behaviour work.

I need to warn you that this solution is not a really good one but until CakePHP team fix this issue on one of the future releases of CakePHP this would help you a lot.

Here is the code:

class AppModel extends Model {

    var $_findMethods = array('all' => true, 'first' => true, 'count' => true,
		'neighbors' => true, 'list' => true, 'threaded' => true, 'translated' => true);

    function _findTranslated($state, $query, $results = array()) {
        if ($state == 'before') {
            return array_merge($query, array(
                //'fields' => array('id', 'name'),
                //'recursive' => -1
            ));
        } elseif ($state == 'after') {
            if (empty($results)) {
                return $results;
            }

            // get the model's belongs to relation model names
            $belongsTo = Set::extract($this->belongsTo, '/@*');

            if(!empty($belongsTo) && isset($belongsTo[0]) && is_array($belongsTo[0]))
                $belongsTo = $belongsTo[0];

            if(!empty($belongsTo))
                foreach($results as &$result)
                {
                    foreach($belongsTo as $modelName)
                    {
                        if(isset($result[$modelName]) &&
                            isset($result[$modelName]['id']) &&
                            !empty($result[$modelName]['id']))
                        {

                            $data = $this->$modelName->find('first', array(
                                'conditions' => array(
                                    $modelName.'.id' => $result[$modelName]['id']
                                ),
                                'recursive' => -1
                            ));

                            if(!empty($data))
                                $result[$modelName] = $data[$modelName];
                        }
                    }
                }

            return $results;
        }
    }
}

What you need to do is just implement the _findTranslated method on your model or on AppModel for general usage with the $_findMethods private variable and instead of using regular find methods for example:

$this->Post->find('all');

You should use:

$this->Post->find('translated');

And the result will look as the same above but with translated inner relations.

Not: I have not implement all types of the relations yet but if you find hard to add such relations let me know, I’ll do my best.

I hope this could help you. Please leave me some responses to make sure is helpful.

Thank you for reading this article.

No Comments