location = $location; if (!is_array($languages)) $languages = array($languages); $this->translatedLanguages = $this->listLanguages(); $languages[]=self::DEFAULT_LANGUAGE; $this->languages = $languages; foreach ($languages as $language) { if (empty($language)) continue; if ($this->load($language)) { $this->language = $language; break; } } } /* @return la liste des langues avec une traduction */ protected function listLanguages() { $translatedLanguages = array(); $files = glob($this->location.'/'.self::LOCALE_DIR.'/*.json'); if (is_array($files)) { foreach($files as $file){ preg_match('/([a-z]{2})\.json$/', $file, $matches); assert('!empty($matches)'); $translatedLanguages [] = $matches[1]; } } return $translatedLanguages; } /* Charge la traduction * @param language la langue sélectionnée * @return TRUE si le chargement s'est bien fait, FALSE sinon */ protected function load($language) { if (!preg_match('/^[a-z]{2}$/', $language)) { error_log("Invalid language: '$language'"); return false; } $trans = $this->loadFile($language); if (empty($trans)) return false; assert('in_array($language, $this->translatedLanguages)'); if ($language!=self::DEFAULT_LANGUAGE) { $defaultTrans = $this->loadFile(self::DEFAULT_LANGUAGE); assert('!empty($defaultTrans)'); $trans = array_merge($defaultTrans, $trans); } $this->trans = $trans; return true; } /* Charge un fichier * @param $language Le fichier de langue concerné * @return Tableau associatif contenant les traductions */ protected function loadFile($language) { $fileName = $this->location.'/'.self::LOCALE_DIR.'/'.$language.'.json'; $content = @file_get_contents($fileName); if (empty($content)) { $translations = array(); } else { $translations = json_decode($content, true); foreach ($translations as $id => $translation) { if (empty($translation)) { # Retire les traductions vides afin qu'elles soient # traduites dans une autre langue si possible. unset($translations[$id]); } } if (!empty($content) && empty($translations)) error_log("Error while loading '$fileName'"); } return $translations; } /* Retourne la traduction et substitue les variables. * get('TEST_TRANS', array('4')) * Retournera 'Nombre : 4' si TEST_TRANS == 'Nombre : $1' */ function get($key, $args=array()) { if (isset($this->trans[$key])&&!empty($this->trans[$key])) { $value = $this->trans[$key]; for($i=0;$itrans = array_merge($this->trans, $other->trans); } /* @return la version Json des traductions */ function getJson() { return json_encode($this->trans); } /* @return un tableau des langues préférées */ static function getHttpAcceptLanguages($httpAcceptLanguage=Null) { /** Exemple de directive : * eo,fr;q=0.8,fr-FR;q=0.6,en-US;q=0.4,en;q=0.2 * Les langues sont séparées entre elles par des virgules. * Chaque langue est séparée du coefficient, si présent, par un point-virgule. */ // Suppose que les langues préférées sont en premier. if (is_null($httpAcceptLanguage)) $httpAcceptLanguage = @$_SERVER['HTTP_ACCEPT_LANGUAGE']; $languageList = array(); foreach (explode(',', $httpAcceptLanguage) as $language) { $languageList[] = substr($language, 0, 2); // fr-FR;q=0.6 --> fr } return array_unique($languageList); // en-US,en-UK --> en, en --> en } } // Initialise le singleton, avec les langues possibles function i18n_init($languages, $location){ global $i18n,$i18n_js; if (!isset($i18n)) { // Charge d'abord les traductions de base $i18n = new Translation(dirname(__FILE__), $languages); // Charge ensuite la traduction demandée (celle du thème courant) $i18n->append(new Translation($location, $languages)); $i18n_js = $i18n->getJson(); } return $i18n->language; } // Appel rapide de la traduction function _t($key,$args=array(),$debug=false){ global $i18n; return $i18n->get($key, $args); } ?>