CakePHP Translate Behavior со связанными моделями

Я ищу лучшее решение для использования Translate Behavior / i18n для связанных моделей (hasOne, hasMany или HABTM). CakePHP 1.x и 2.x не поддерживают это.

Мое решение очень уродливое, но работает:

    if(Configure::read('Config.language') !== DEFAULT_LANGUAGE) {
        $this->{$this->modelClass}->locale = array(Configure::read('Config.language'), DEFAULT_LANGUAGE);

        if(is_array($this->{$this->modelClass}->belongsTo)) {
            foreach($this->{$this->modelClass}->belongsTo as $relation => $model) {
                $this->{$this->modelClass}->$model['className']->locale = array(Configure::read('Config.language'), DEFAULT_LANGUAGE);
            }
        } elseif(is_array($this->{$this->modelClass}->hasOne)) {
            foreach($this->{$this->modelClass}->hasOne as $relation => $model) {
                $this->{$this->modelClass}->$model['className']->locale = array(Configure::read('Config.language'), DEFAULT_LANGUAGE);
            }
        } elseif(is_array($this->{$this->modelClass}->hasMany)) {
            foreach($this->{$this->modelClass}->hasMany as $relation => $model) {
                $this->{$this->modelClass}->$model['className']->locale = array(Configure::read('Config.language'), DEFAULT_LANGUAGE);
            }
        }
    } else {
        $this->{$this->modelClass}->locale = DEFAULT_LANGUAGE;
    }

Может быть, у вас есть лучшее решение, и вы можете показать мне :)


person kicaj    schedule 05.08.2013    source источник


Ответы (2)


Это решение, которое я придумал.

// app/Model/AppModel.php
public function afterFind($results, $primary = false) {
    // if getting associated data
    if($primary === false) {
        // check for translate behavior
        foreach(array_keys($this->actsAs) as $behavior) {
            if(preg_match('/^(T|t)ranslate$/', $behavior)) {
                // set locale to lookup translation
                $currentLanguage = Configure::read('Config.language');
                if($currentLanguage !== DEFAULT_LANGUAGE) {
                    $this->locale = array($currentLanguage, DEFAULT_LANGUAGE);  
                } else {
                    $this->locale = $currentLanguage;   
                }
                // if multi-dimensional array
                if(count($results) != count($results, COUNT_RECURSIVE)) {
                    foreach($results as &$model) {
                        if(is_array($model)){
                            // if multiple models
                            if(isset($model[$this->name][0])) {
                                foreach($model[$this->name] as &$associatedModel) {
                                    // get model with translations
                                    $res = $this->find('first', array(
                                        'conditions' => array("{$this->alias}.{$this->primaryKey} = ".$associatedModel[$this->primaryKey]),
                                        'contain' => false
                                    ));
                                    // add translated fields to results
                                    $diff = array_diff_assoc($res[$this->name], $associatedModel);
                                    if(count($diff)) {
                                        $associatedModel = array_merge($associatedModel, $diff);
                                    }
                                }
                            } else if(!empty($model[$this->name])) {
                                // get model with translations
                                $res = $this->find('first', array(
                                    'conditions' => array("{$this->alias}.{$this->primaryKey} = ".$model[$this->name][$this->primaryKey]),
                                    'contain' => false
                                ));
                                // add translated fields to results
                                $diff = array_diff_assoc($res[$this->name], $model[$this->name]);
                                if(count($diff)) {
                                    $model[$this->name] = array_merge($model[$this->name], $diff);
                                }
                            }
                        }
                    }
                } else {
                    // get model with translations
                    $res = $this->find('first', array(
                        'conditions' => array("{$this->alias}.{$this->primaryKey} = ".$results[$this->primaryKey]),
                        'contain' => false
                    ));
                    // add translated fields to results
                    $diff = array_diff_assoc($res[$this->name], $results);
                    if(count($diff)) {
                        $results = array_merge($results, $diff);
                    }
                }
            }
        }           
    }
    return $results;
}
person Devin Crossman    schedule 26.08.2013
comment
Смотрится намного лучше, буду тестировать. - person kicaj; 26.08.2013

Я использовал этот метод afterFind в своей модели плагина, но отличий нет.

это моя функция admin_index в моем контроллере:

    $this->Certificate->locale = $this->Session->read('Config.language');
    $this->Certificate->CertificateType->locale =  $this->Session->read('Config.language');
    $this->Certificate->recursive = 0;
    $this->set('certificates', $this->paginate());

но принадлежащая модель (CertificateType) не переведена! это свело меня с ума в эти дни.

person cybercoder    schedule 12.09.2013