0

Je cite le livre CakePHP (ver 1.3):CakePHP, i18n, Retrieve des services de traduction pour les modèles associés

Notez que seuls les champs du modèle que vous font directement sur find sera traduit. Les modèles attachés via des associations ne seront pas traduits car le déclenchement des rappels sur les modèles associés n'est actuellement pas pris en charge.

Quelqu'un a-t-il trouvé une solution pour cela?

Si non pourriez-vous me donner quelques pointeurs concernant le scénario simple suivant.

J'ai 2 modèles:

Projet, Catégorie.
Projet HABTM Catégorie

J'ai correctement configuré la table i18n et j'ai quelques entrées dans la base de données, toutes traduites. Quand je récupère un projet, il récupère la traduction mais pas la catégorie traduite car comme il est dit dans le livre cakephp, les modèles attachés via des associations ne seront pas traduits.

Répondre

0

OK J'ai trouvé une solution. Ce qui est la plupart du temps une solution de contournement. J'aurais dû y penser plus tôt.

Ce que je fais est le suivant. Je trouve tous les projets et récursivement toutes les catégories associées aux projets. Maintenant, puisque cakephp ne traduit pas de catégories, j'utilise les résultats de la requête initiale et j'effectue un second uniquement pour les catégories, mais en utilisant les valeurs de l'identifiant de catégorie que j'ai trouvées lors de la première requête. Maintenant, cakephp traduit les catégories car je ne fais que les chercher et je peux faire traduire leurs données.

Pour le moment, je suis d'accord avec cette solution, mais ce serait bien si first cakephp rendait le comportement de traduction prêt à l'emploi ou si quelqu'un avait un comportement qui pourrait supporter la récupération de la traduction sur les modèles associés.

+0

Il n'y a pas de meilleure solution dans 1.3? – kicaj

+1

Je ne pense pas qu'il existe une meilleure solution dans 2.0.Il s'agit d'une erreur ou d'un défaut ** majeur **, il ajoute effectivement 300% + ballonnement supplémentaire au contrôleur, et il est incroyablement ennuyeux de devoir le faire tout le temps car je travaille exclusivement avec des sites Web multilingues, à peu près tous mes modèles utilisent le Comportement _Translate_, il y a sûrement une meilleure solution là-bas? – brndnmg

3

J'ai une autre solution de contournement; Je ne sais pas si elle est mieux ou pire style ou la performance sage, seulement qu'il convient l'objectif des « modèles de graisse, les contrôleurs maigres »:

AppModel.php

public function getTranslatedModelField($id = 0, $field) { 

     $res = false; 

     $db = $this->getDataSource(); 
     $tmp = $db->fetchAll('SELECT content from s2h_i18n WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1', 
      array($this->alias, Configure::read('Config.language'), $id, $field) 
     );  
     if (!empty($tmp)) { 
      $res = $tmp[0]['s2h_i18n']['content']; 
     } 
     return $res; 
} 

SomeModel.php

public function afterFind($results, $primary = false) { 

     foreach ($results as $key => $val) { 
      if (isset($val['SomeOtherModel']) && isset($val['SomeOtherModel']['id'])) { 
       $results[$key]['SomeOtherModel']['name'] = 
    $this->SomeOtherModel->getTranslatedModelField($val['SomeOtherModel']['id'], 'name'); 
      } 
      // other possible queries for other models and/or fields 
     } 

     return $results; 
    } 
0

Je généralise la partie afterFind un peu, de sorte qu'il saisit automatiquement les champs de traduire des modèles associéstableau, et utilise un éventail de modèles associés à (potentiellement) traduisons:

public function afterFind($results, $primary = false){ 

    $modelsToTranslate = array("SomeModel", "AnotherModel"); 

    foreach ($results as $key => $val){ 
     foreach($modelsToTranslate as $mtt){ 
      if (isset($val[$mtt])){ 
       foreach($val[$mtt] as $fieldname => $fieldval){ 
        foreach ($this->$mtt->actsAs["Translate"] as $fieldToTranslate){ 
         $results[$key][$mtt][$fieldname][$fieldToTranslate] = $this->$mtt->getTranslatedModelField($val[$mtt][$fieldname]['id'], $fieldToTranslate); 
        } 
       }    
      }    
     } 
    } 
    return $results; 
} 
0

Je pris solution ci-dessus et généralisée des deux fonctions un peu, maintenant il doit être utilisé en même temps que le traduire le comportement et les deux fonctions doivent aller dans le model.php - tout le reste devrait fonctionner par lui-même:

public function getTranslatedModelField($id = 0, $field) { 
    $res = false; 
    $translateTable = (isset($this->translateTable))?$this->translateTable:"i18n"; 

    $db = $this->getDataSource(); 
    $tmp = $db->fetchAll(
     "SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1", 
     array($this->alias, Configure::read('Config.language'), $id, $field) 
    ); 
    if (!empty($tmp)) { 
     $res = $tmp[0][$translateTable]['content']; 
    } 
    return $res; 
} 

public function afterFind($results, $primary = false) { 

    if($primary == false && array_key_exists('Translate', $this->actsAs)) { 
     foreach ($results as $key => $val) { 
      if (isset($val[$this->name]) && isset($val[$this->name]['id'])) { 
       foreach($this->actsAs['Translate'] as $translationfield) { 
        $results[$key][$this->name][$translationfield] = 
        $this->getTranslatedModelField($val[$this->name]['id'], $translationfield); 
       } 
      } else if($key == 'id' && is_numeric($val)) { 
       foreach($this->actsAs['Translate'] as $translationfield) { 
        $results[$translationfield] = 
        $this->getTranslatedModelField($val, $translationfield); 
       }     
      } 
     } 
    } 

    return $results; 
} 
Questions connexes