Overview

Packages

  • Framework
  • PHP

Classes

  • Application
  • Chronometre
  • Config
  • Controleur
  • Debug
  • GestionnaireException
  • I18n
  • Log
  • Modele
  • Registre
  • SquelettePhp
  • Url

Functions

  • autoloadAppliDefaut
  • autoloadFw
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: // declare(encoding='UTF-8');
  3: /**
  4:  * I18n permet de traduire une application à partir de données stockées dans des fichiers ini.
  5:  * Si vous souhaitez utiliser le fonctionnement par défaut vous devrez :
  6:  * - déposer les fichiers ini dans le dossier définit par la variable de config "chemin_i18n".
  7:  * - nommer les fichiers selon la forme "locale.ini" (Ex.: fr.ini ou fr_CH.ini ).
  8:  *
  9:  * Elle offre l'accès en lecture seule aux paramètres de des fichiers ini.
 10:  * C'est une Singleton. Une seule classe de traduction peut être instanciée par Application.
 11:  *
 12:  * @category    PHP 5.2
 13:  * @package     Framework
 14:  * @author      Jean-Pascal MILCENT <jpm@tela-botanica.org>
 15:  * @copyright   Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
 16:  * @license     GNU-GPL-v3 <http://www.gnu.org/licenses/gpl.html>
 17:  * @license     CECILL-v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt>
 18:  */
 19: 
 20: class I18n {
 21:     /** Format de traduction utilisant les fichier .ini */
 22:     const FORMAT_INI = '.ini';
 23: 
 24:     /** Instance de la classe pointant sur elle même (pour le pattern singleton) */
 25:     private static $instance = null;
 26: 
 27:     /** Fichiers de traduction disponibles. */
 28:     private static $traductions = array();
 29: 
 30:     /** Langue courrante utilisée par l'application. */
 31:     private static $langue = null;
 32: 
 33:     private function __construct() {
 34:         self::verifierParametresConfig();
 35:         self::trouverLangue();
 36:     }
 37: 
 38:     /**
 39:      * Accesseur pour la valeur d'une traduction
 40:      * @param string $param le nom du paramètre
 41:      * @return string la valeur du paramètre
 42:      */
 43:     public static function get($identifiant, $langue = null) {
 44:         self::verifierCreationInstance();
 45:         $texte = '';
 46: 
 47:         // Récupération de la langue actuellement demandée
 48:         $langue_a_charger = self::$langue;
 49:         if (!is_null($langue)) {
 50:             $langue_a_charger = $langue;
 51:         }
 52: 
 53:         if (!isset(self::$traductions[$langue_a_charger])) {
 54:             // Tentative de chargement du fichier de traduction
 55:             $chargement = self::charger($langue_a_charger);
 56:             if ($chargement === false) {
 57:                 $m = "Le fichier d'i18n pour la langue '$langue_a_charger' demandée n'a pas été trouvé.";
 58:                 self::ajouterErreur($m);
 59:             }
 60:         }
 61: 
 62:         // Recherche de la langue dans le tableau des traductions
 63:         if (isset(self::$traductions[$langue_a_charger]) && self::$traductions[$langue_a_charger] !== false) {
 64:             // Recherche de la traduction demandée
 65:             $valeur = self::getValeur($identifiant, self::$traductions[$langue_a_charger]);
 66:             if ($valeur !== false) {
 67:                 $texte = $valeur;
 68:             } else {
 69:                 $m = "Le traduction n'existe pas pour l'identifiant '$identifiant' demandé.";
 70:                 self::ajouterErreur($m);
 71:             }
 72:         }
 73: 
 74:         return $texte;
 75:     }
 76: 
 77:     /**
 78:      * Charge un fichier ini dans le tableau des paramètres de l'appli
 79:      * @param string $fichier_ini le nom du fichier à charger
 80:      * @return boolean true, si le fichier a été trouvé et correctement chargé, sinon false.
 81:      */
 82:     public static function charger($langue, $fichier = null, $format = self::FORMAT_INI) {
 83:         self::verifierCreationInstance();
 84:         $ok = false;
 85: 
 86:         // Création du chemin vers le fichier de traduction par défaut
 87:         if (is_null($fichier)) {
 88:             $fichier = Config::get('chemin_i18n').$langue.$format;
 89:         }
 90: 
 91:         // Chargement
 92:         if ($format == self::FORMAT_INI) {
 93:             $ok = self::chargerFichierIni($fichier, $langue);
 94:         } else {
 95:             $m = "Le format '$format' de fichier de traduction n'est pas pris en compte par le Framework.";
 96:             self::ajouterErreur($m);
 97:         }
 98: 
 99:         return $ok;
100:     }
101: 
102:     /**
103:      * Définit la langue utiliser pour rechercher une traduction.
104:      * @param string $fichier_ini le nom du fichier à charger
105:      * @return array le fichier ini parsé
106:      */
107:     public static function setLangue($langue) {
108:         self::verifierCreationInstance();
109:         self::$langue = $langue;
110:     }
111: 
112:     /**
113:      * Renvoie la valeur demandé grâce une chaine de paramètres
114:      * @param string $param la chaine identifiante
115:      * @param array $i18n le tableau de traductions
116:      * @return mixed la valeur correspondante à la chaine identifiante si elle est trouvée, sinon false.
117:      */
118:     private static function getValeur($param, $i18n) {
119:         if ($param === null) {
120:             return false;
121:         } else {
122:             if (isset($i18n[$param])) {
123:                 return $i18n[$param];
124:             } else if (strpos($param, '.') !== false) {
125:                 $pieces = explode('.', $param, 2);
126:                 if (strlen($pieces[0]) && strlen($pieces[1])) {
127:                     if (isset($i18n[$pieces[0]])) {
128:                        if (is_array($i18n[$pieces[0]])) {
129:                             return self::getValeur($pieces[1], $i18n[$pieces[0]]);
130:                        }
131:                     }
132:                 }
133:             } else {
134:                 return false;
135:             }
136:         }
137:     }
138: 
139:     /**
140:      * Parse le fichier ini donné en paramètre
141:      * @param string $fichier_ini nom du fichier ini à parser
142:      * @param string $langue la langue correspondant au fichier
143:      * @return boolean true si le chargement c'est bien passé, sinon false.
144:      */
145:     private static function chargerFichierIni($fichier_ini, $langue) {
146:         self::$traductions[$langue] = false;
147:         if (file_exists($fichier_ini)) {
148:             $ini = parse_ini_file($fichier_ini, true);
149:             Debug::printr($ini, 'Avant :');
150:             $ini = self::analyserTableauIni($ini);
151:             Debug::printr($ini, 'Aprés :');
152:             self::$traductions[$langue] = $ini;
153:         }
154:         return (self::$traductions[$langue] === false) ?  false : true;
155:     }
156: 
157:     /**
158:      * Analyse un tableau de traductions pour évaluer les clés.
159:      * @param array $i18n le tableau de traductions
160:      * @return array le tableau analysé et modifié si nécessaire.
161:      */
162:     private static function analyserTableauIni($i18n = array()) {
163:         //ATTENTION : il est important de passer la valeur par référence car nous la modifions dynamiquement dans la boucle
164:         foreach ($i18n as $cle => &$valeur) {
165:             if (is_array($valeur)) {
166:                 $i18n[$cle] = self::analyserTableauIni($valeur);
167:             } else {
168:                 $i18n = self::evaluerCle($i18n, $cle, $valeur);
169:             }
170:         }
171:         return $i18n;
172:     }
173: 
174:     /**
175:      * Dans le cas des chaines de traduction à sous clé (ex.: cle.souscle), cette méthode
176:      * évalue les valeurs correspondantes et créée les sous tableaux associés.
177:      * @param array $i18n tableau de traductions (par référence)
178:      * @param string $cle la cle dans le tableau
179:      * @param string $valeur la valeur à affecter
180:      */
181:     private static function evaluerCle($i18n, $cle, $valeur) {
182:         if (strpos($cle, '.') !== false) {
183:             unset($i18n[$cle]);
184:             $pieces = explode('.', $cle, 2);
185:             if (strlen($pieces[0]) && strlen($pieces[1])) {
186:                 if (isset($i18n[$pieces[0]]) && !is_array($i18n[$pieces[0]])) {
187:                     $m = "Ne peut pas créer de sous-clé pour '{$pieces[0]}' car la clé existe déjà";
188:                     trigger_error($m, E_USER_WARNING);
189:                 } else {
190:                     $i18n[$pieces[0]][$pieces[1]] = $valeur;
191:                     $i18n[$pieces[0]] = self::evaluerCle($i18n[$pieces[0]], $pieces[1], $valeur);
192:                 }
193:             } else {
194:                 $m = "Clé invalide '$cle'";
195:                 trigger_error($m, E_USER_WARNING);
196:             }
197:         } else {
198:             $i18n[$cle] = $valeur;
199:         }
200:         return $i18n;
201:     }
202: 
203:     /**
204:      * Cherche l'information sur la langue demandée par l'application
205:      */
206:     private static function trouverLangue() {
207:         if (isset($_GET[Config::get('i18n_url_parametre')])) {
208:             self::$langue = $_GET[Config::get('i18n_url_parametre')];
209:         } else {
210:             self::$langue = Config::get('i18n_langue_defaut');
211:         }
212:     }
213: 
214:     /**
215:      * Vérifie si l'instance de classe à été crée, si non la crée
216:      */
217:     private static function verifierCreationInstance() {
218:         if (empty(self::$instance)) {
219:             self::$instance = new I18n();
220:         }
221:     }
222: 
223:     /**
224:      * Vérifie que tous les paramêtres de config nécessaires au fonctionnement de cette classe existe dans les fichiers
225:      * de configurations.
226:      */
227:     private static function verifierParametresConfig() {
228:         $ok = true;
229:         $parametres = array('chemin_i18n', 'i18n_url_parametre', 'i18n_langue_defaut');
230:         foreach ($parametres as $param) {
231:             if (is_null(Config::get($param))) {
232:                 $m = "L'utilisation de la classe I18n nécessite de définir '$param' dans un fichier de configuration.";
233:                 self::ajouterErreur($m);
234:                 $ok = false;
235:             }
236:         }
237:         return $ok;
238:     }
239: 
240:     /**
241:      * Ajouter une message d'erreur
242:      */
243:     private static function ajouterErreur($m, $e = E_USER_WARNING) {
244:         if (Config::get('fw_debogage') === true) {
245:             trigger_error($m, $e);
246:         }
247:     }
248: }
TBFramework - v0.2 API documentation generated by ApiGen 2.8.0