Behavior pour un système multilangue

Bonjour,

j’ai utilisé jusque là la classe I18nActiveRecord pour gérer mes sites en multilangue.

L’inconvénient c’est d’avoir à modifier la base de données et se retrouver avec des tables du style:


- article

---- id

---- id_auteur

---- titre

---- contenu


- article_lang

---- id

---- id_article

---- lang

---- titre

---- contenu

A chaque fois on se retrouve avec deux tables contenant du texte.

Le soucis aussi est lorsqu’on souhaite utiliser les relations


$utilisateur->dernierArticle->titre

ne fonctionne pas puisqu’on n’est pas initialisé la class avec localized().

Bref, c’est une parenthèse pour ceux qui connaissent cette classe.

Voici mon modèle de table,

par exemple:




- article

---- id

---- id_auteur

---- date_creation




- article_texte

---- id_article // clé primaire composite sur id_article et lang

---- lang 

---- titre

---- contenu

Et j’aimerai simplifier la gestion à l’aide d’un behavior, par exemple: echo $article->titre;

ou echo $utilisateur->dernierArticle->titre; Qui piochera dans la table article_texte.

Quelle serait la meilleure solution? Je ne parviens pas à utiliser __get dans mon behavior?

Je vais continuer ma réflexion mais je m’étonne de ne pas trouver ce genre de chose dans les forums, comment construisez-vous vos sites multilangue? Pour ma part ça représente bien 75% des projets.

Merci d’avance!

Clem

En fait dans ma classe


class Test extends CActiveRecord

J’ai




public function behaviors()

	{

		return array(

			'I18nTexteBehavior', array(

				'class' => 'ext.I18nTexteBehavior'

			)

		);

	}

et Dans I18nTexteBehavior


 public function __get($name)

	{

		var_dump($name); exit;

	}

Mais ça ne fonctionne pas, la __get de cette classe n’est pas appelée, c’est celle de CActiveRecord qui est prise en compte. ?!

Pour ça, je ne vois pas le problème. C’est juste obligatoire d’avoir deux tables pour pouvoir traduire un message. En tout cas je ne connais pas d’autres moyens.

Cela est gérable à l’aide de la propriete behaviors qui est instancié lorsque la méthode init de ta classe est appelée. Ce qui n’est peut être pas le cas pour toi dans ta classe I18nTexteBehavior?

Après avoir jeté un coup d’oeil à l’extension que tu utilises, j’ai été surpris de voir qu’il n’existait pas de doc. Je n’arriverais pas à travailler sans support technique en cas de besoin.

Donc même si ce n’est pas une réponse à ton problème (désolé pour ça), je te conseillerais de regarder cette extension.

A priori, la méthode __get du behavior n’est pas appelée parce que les méthodes des behaviors ne priment pas sur celles de leur propriétaire.

Pour le cas en question, j’ai dernièrement appris que tu peux déclarer dans la méthode canGetProperty($name) si un attribut peut être demandé pour le behavior, et s’il répond oui pour le nom de cet attribut, à ce moment-là la méthode __get du behavior sera appelée quand tu essaies d’y accéder (lien).

Pour ce qui est des façons de gérer l’internationalisation, j’ai une autre approche qui est de créer trois modèles à part - Text, Translation et Language (basés sur des tables bien sûr).

Text contient bien sûr du texte (celui qui apparaîtra s’il n’y a pas de traduction), avec une clé primaire; Translation contient un foreign key pour Text, un code langue (qui référencie la table Language) et la traduction.

Du coup, pour tous les textes dans toutes les tables qui ont besoin d’être traduit, au lieu d’y mettre un champs texte je mets un champs clé qui référencie la table Text.

Tout ça fait que je peux facilement rajouter autant de traductions que je veux dans autant de langues que je veux, avec toujours un texte de recours s’il n’y a pas de traduction pour un truc en particulier.

Les désavantages sont que je suis obligé de passer par un champs TEXT pour tous ces textes (pas de VARCHAR(10) pour les plus petits donc), mais d’après ce que j’ai pu lire l’impacte sur la taille n’est pas énorme, mais il y a peut-être de soucis pour indexer un tel champs, et que c’est un peu plus complexe à gérer au niveau des joins sur les tables.

Je me suis auqnd même fait un petit behavior qui me permet d’accéder facilement à tous ces champs dans un CActiveRecord comme si le texte ou la traduction était un attribut directe du modèle.