[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/ -> AkLocaleManager.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   4  // +----------------------------------------------------------------------+
   5  // | Akelos Framework - http://www.akelos.org                             |
   6  // +----------------------------------------------------------------------+
   7  // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
   8  // | Released under the GNU Lesser General Public License, see LICENSE.txt|
   9  // +----------------------------------------------------------------------+
  10  
  11  /**
  12   * @package ActiveSupport
  13   * @subpackage I18n-L10n
  14   * @author Bermi Ferrer <bermi a.t akelos c.om>
  15   * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
  16   * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  17   */
  18  
  19  if(!defined('AK_AVAILABLE_LOCALES')){
  20      define('AK_AVAILABLE_LOCALES',AK_FRAMEWORK_LANGUAGE);
  21  }
  22  
  23  require_once (AK_LIB_DIR.DS.'AkObject.php');
  24  
  25  defined('AK_FRAMEWORK_LANGUAGE') ? null : define('AK_FRAMEWORK_LANGUAGE', 'en');
  26  
  27  class AkLocaleManager extends AkObject
  28  {
  29  
  30      var $available_locales = array(AK_FRAMEWORK_LANGUAGE=>array(AK_FRAMEWORK_LANGUAGE));
  31      var $browser_lang = array(AK_FRAMEWORK_LANGUAGE);
  32  
  33      function init()
  34      {
  35          if(AK_AVAILABLE_LOCALES == 'auto'){
  36              $this->available_locales = $this->_getAvailableLocales();
  37          }elseif(AK_AVAILABLE_LOCALES != 'en'){
  38              $this->available_locales = $this->_parseLocaleConfigString(AK_AVAILABLE_LOCALES);
  39          }
  40      }
  41  
  42      function _getAvailableLocales()
  43      {
  44          static $available_locales;
  45  
  46          if(empty($available_locales)){
  47              $available_locales = array();
  48              $d = dir(AK_CONFIG_DIR.DS.'locales');
  49              while (false !== ($entry = $d->read())) {
  50                  if (preg_match('/\\.php$/', $entry)){
  51                      $locale = str_replace('.php','',$entry);
  52                      $available_locales[$locale] = array($locale);
  53                  }
  54              }
  55              $d->close();
  56          }
  57  
  58          return $available_locales;
  59      }
  60  
  61      function _parseLocaleConfigString($locale_settings)
  62      {
  63          $locale_settings = trim(str_replace(' ','',$locale_settings));
  64          $locale_settings = str_replace(array(';','(',')'), array(',','~','',''),$locale_settings);
  65          $available_locales = strstr($locale_settings,',') ? explode(',',$locale_settings) : array($locale_settings);
  66          $locales = array();
  67          foreach ($available_locales as $locale_string){
  68              if(strstr($locale_string,'~')){
  69                  $tmp_arr = explode('~',$locale_string);
  70                  $locale_string = $tmp_arr[0];
  71                  $locale_alias = array($locale_string);
  72                  if(strstr($tmp_arr[1],'|')){
  73                      $locale_alias = array_merge($locale_alias, explode('|',$tmp_arr[1]));
  74                  }else{
  75                      $locale_alias = array_merge($locale_alias, array($tmp_arr[1]));
  76                  }
  77              }else {
  78                  $locale_alias = array($locale_string);
  79              }
  80  
  81  
  82              $locales[trim($locale_string)] = $locale_alias;
  83          }
  84  
  85          return $locales;
  86      }
  87  
  88      function getBrowserLanguages()
  89      {
  90          $browser_accepted_languages = str_replace('-','_', strtolower(preg_replace('/q=[0-9\.]+,*/','',@$_SERVER['HTTP_ACCEPT_LANGUAGE'])));
  91          $browser_languages = (array_diff(split(';|,',$browser_accepted_languages.','), array('')));
  92          if(empty($browser_languages)){
  93              return array($this->_getDefaultLocale());
  94          }
  95          return array_unique($browser_languages);
  96      }
  97  
  98  
  99      function getDefaultLanguageForUser()
 100      {
 101          $browser_languages = $this->getBrowserLanguages();
 102  
 103          // First run for full locale (en_us, en_uk)
 104          foreach ($browser_languages as $browser_language){
 105              if(isset($this->available_locales[$browser_language])){
 106                  return $browser_language;
 107              }
 108          }
 109  
 110          // Second run for only language code (en, es)
 111          foreach ($browser_languages as $browser_language){
 112              if($pos = strpos($browser_language,'_')){
 113                  $browser_language = substr($browser_language,0, $pos);
 114                  if(isset($this->available_locales[$browser_language])){
 115                      return $browser_language;
 116                  }
 117              }
 118          }
 119          return $this->_getDefaultLocale();
 120      }
 121  
 122      function _getDefaultLocale()
 123      {
 124          $available_locales = $this->available_locales;
 125          $default_locale = array_shift($available_locales);
 126          return is_array($default_locale) ? $default_locale[0] : $default_locale;
 127      }
 128  
 129  
 130      function getUsedLanguageEntries($lang_entry = null, $controller = null)
 131      {
 132          static $_locale_entries = array();
 133  
 134          if(isset($controller)){
 135              $_locale_entries[$controller][$lang_entry] = $lang_entry;
 136          } else {
 137              $_locale_entries[$lang_entry] = $lang_entry;
 138          }
 139  
 140          if(!isset($lang_entry)){
 141              return $_locale_entries;
 142          }
 143      }
 144  
 145      /**
 146       * @todo Refactor this method
 147       */
 148      function updateLocaleFiles()
 149      {
 150          $new_core_entries = array();
 151          $new_controller_entries = array();
 152          $new_controller_files = array();
 153          $used_entries = AkLocaleManager::getUsedLanguageEntries();
 154          require(AK_CONFIG_DIR.DS.'locales'.DS.AK_FRAMEWORK_LANGUAGE.'.php');
 155          $core_dictionary = $dictionary;
 156          $controllers_dictionaries = array();
 157  
 158          foreach ($used_entries as $k=>$v){
 159              // This is a controller file
 160              if(is_array($v)){
 161                  if(!isset($controllers_dictionaries[$k])){
 162                      $controller = $k;
 163                      $module_lang_file = AK_APP_DIR.DS.'locales'.DS.$controller.DS.AK_FRAMEWORK_LANGUAGE.'.php';
 164                      if(is_file($module_lang_file)){
 165                          require($module_lang_file);
 166                          $controllers_dictionaries[$controller] = array_merge((array)$dictionary, (array)$v);
 167                          $existing_controllers_dictionaries[$controller] = (array)$dictionary;
 168                      }else{
 169                          $controllers_dictionaries[$controller] = (array)$v;
 170                          $new_controller_files[$controller] = $module_lang_file;
 171                      }
 172                  }
 173              }else {
 174                  if(!isset($core_dictionary[$k])){
 175                      $new_core_entries[$k] = $k;
 176                  }
 177              }
 178          }
 179  
 180          $dictionary_file = '';
 181          foreach ($new_controller_files as $controller=>$file_name){
 182              $dictionary_file = "<?php\n\n// File created on: ".date("Y-m-d G:i:s",Ak::time())."\n\n\$dictionary = array();\n\n";
 183              foreach ($controllers_dictionaries[$controller] as $k=>$entry){
 184                  $entry = str_replace("'","\\'",$entry);
 185                  $dictionary_file .= "\n\$dictionary['$entry'] = '$entry';";
 186              }
 187              unset($controllers_dictionaries[$controller]);
 188              $dictionary_file .= "\n\n\n?>";
 189              Ak::file_put_contents($file_name,$dictionary_file);
 190          }
 191  
 192          // Module files
 193          foreach ((array)$controllers_dictionaries as $controller => $controller_entries){
 194              $dictionary_file = '';
 195              foreach ($controller_entries as $entry){
 196                  if($entry == '' || isset($existing_controllers_dictionaries[$controller][$entry])) {
 197                      continue;
 198                  }
 199                  $entry = str_replace("'","\\'",$entry);
 200                  $dictionary_file .= "\n\$dictionary['$entry'] = '$entry';";
 201              }
 202              if($dictionary_file != ''){
 203                  $original_file = Ak::file_get_contents(AK_APP_DIR.DS.'locales'.DS.$controller.DS.AK_FRAMEWORK_LANGUAGE.'.php');
 204                  $original_file = rtrim($original_file,"?> \n\r");
 205                  $new_entries = "\n\n// ".date("Y-m-d G:i:s",Ak::time())."\n\n".$dictionary_file."\n\n\n?>\n";
 206                  $dictionary_file = $original_file.$new_entries;
 207                  Ak::file_put_contents(AK_APP_DIR.DS.'locales'.DS.$controller.DS.AK_FRAMEWORK_LANGUAGE.'.php', $dictionary_file);
 208  
 209                  foreach (Ak::langs() as $lang){
 210                      if($lang != AK_FRAMEWORK_LANGUAGE){
 211                          $lang_file = @Ak::file_get_contents(AK_APP_DIR.DS.'locales'.DS.$controller.DS.$lang.'.php');
 212                          if(empty($lang_file)){
 213                              $dictionary_file = $original_file;
 214                          }else{
 215                              $lang_file = rtrim($lang_file,"?> \n\r");
 216                              $dictionary_file = $lang_file;
 217                          }
 218                          Ak::file_put_contents(AK_APP_DIR.DS.'locales'.DS.$controller.DS.$lang.'.php', $dictionary_file.$new_entries);
 219                      }
 220                  }
 221              }
 222          }
 223  
 224          // Core locale files
 225          $dictionary_file = '';
 226          foreach ($new_core_entries as $core_entry){
 227              if($core_entry == '') {
 228                  continue;
 229              }
 230              $core_entry = str_replace("'","\\'",$core_entry);
 231              $dictionary_file .= "\n\$dictionary['$core_entry'] = '$core_entry';";
 232          }
 233          if($dictionary_file != ''){
 234              $original_file = Ak::file_get_contents(AK_CONFIG_DIR.DS.'locales'.DS.AK_FRAMEWORK_LANGUAGE.'.php');
 235              $original_file = rtrim($original_file,"?> \n\r");
 236              $new_entries = "\n\n// ".date("Y-m-d G:i:s",Ak::time())."\n\n".$dictionary_file."\n\n\n?>\n";
 237              $dictionary_file = $original_file.$new_entries;
 238              Ak::file_put_contents(AK_CONFIG_DIR.DS.'locales'.DS.AK_FRAMEWORK_LANGUAGE.'.php', $dictionary_file);
 239              foreach (Ak::langs() as $lang){
 240                  if($lang != AK_FRAMEWORK_LANGUAGE){
 241                      $lang_file = Ak::file_get_contents(AK_CONFIG_DIR.DS.'locales'.DS.$lang.'.php');
 242                      if(empty($lang_file)){
 243                          $dictionary_file = str_replace("\$locale['description'] = 'English';","\$locale['description'] = '$lang';", $original_file);
 244                      }else{
 245                          $lang_file = rtrim($lang_file,"?> \n\r");
 246                          $dictionary_file = $lang_file;
 247                      }
 248                      Ak::file_put_contents(AK_CONFIG_DIR.DS.'locales'.DS.$lang.'.php', $dictionary_file.$new_entries);
 249                  }
 250              }
 251          }
 252      }
 253  
 254  
 255  
 256      /**
 257       * The following functions are for handling i18n when using url based interfaces
 258       */
 259  
 260  
 261      function initApplicationInternationalization(&$Request)
 262      {
 263          if(!defined('AK_APP_LOCALES')){
 264              define('AK_APP_LOCALES',join(',',array_keys($this->available_locales)));
 265          }
 266          $lang = $this->_getLocaleForRequest($Request);
 267  
 268          $this->rememberNavigationLanguage($lang);
 269  
 270          $Request->_request['lang'] = $lang;
 271          $Request->lang = $lang;
 272      }
 273  
 274      /**
 275       * Returns an array which locales enabled on the public website.
 276       * In order to define available languages you must define AK_PUBLIC_LOCALES 
 277       * which a comma-separated list of locales
 278       *
 279       * @return array
 280       */
 281      function getPublicLocales()
 282      {
 283          static $public_locales;
 284          if(empty($public_locales)){
 285              $public_locales = defined('AK_PUBLIC_LOCALES') ?
 286              Ak::toArray(AK_PUBLIC_LOCALES) :
 287              array_keys($this->available_locales);
 288          }
 289          return $public_locales;
 290      }
 291  
 292      function _getLocaleForRequest(&$Request)
 293      {
 294          $lang = $this->getNavigationLanguage();
 295  
 296          if($url_locale = $this->getLangFromUrl($Request)){
 297              $lang = $this->getLocaleFromAlias($url_locale);
 298          }
 299  
 300          if(!$this->_canUseLocaleOnCurrentRequest($lang, $Request)){
 301              $lang = array_shift($this->getPublicLocales());
 302          }elseif (empty($lang)){
 303              $lang = array_shift($this->getPublicLocales());
 304          }
 305  
 306          // This way we store on get_url_locale and on lang the value of $lang on
 307          // a static variable for accessing it application wide
 308          empty($url_locale) ? null : Ak::get_url_locale($url_locale);
 309          Ak::lang($lang);
 310  
 311          return $lang;
 312      }
 313  
 314      function _canUseLocaleOnCurrentRequest($lang, &$Request)
 315      {
 316          return in_array($lang, $this->getPublicLocales());
 317      }
 318  
 319  
 320      function getLangFromUrl(&$Request)
 321      {
 322          $lang = false;
 323  
 324          if(isset($Request->lang)){
 325              return $Request->lang;
 326          }
 327  
 328          if(isset($Request->ak)){
 329              $regex_arr = array();
 330              $match = false;
 331  
 332              foreach ($this->available_locales as $lang=>$aliases){
 333                  foreach ($aliases as $alias){
 334                      $regex_arr[] = '('.$alias.')(\/){1}';
 335                  }
 336              }
 337              $regex = '/^('.join('|',$regex_arr).'){1}/';
 338  
 339              if (preg_match($regex, trim($Request->ak,'/').'/', $match)){
 340                  $lang = trim($match[0],'/');
 341                  if(empty($lang)){
 342                      unset($Request->_request['ak'], $Request->ak);
 343                  }else{
 344                      $Request->ak = $Request->_request['ak'] = ltrim(substr_replace(trim($Request->ak,'/'),'',0,strlen($lang)), '/');
 345                  }
 346              }else {
 347                  return false;
 348              }
 349          }
 350  
 351          $lang = isset($Request->lang) ? $Request->lang : $lang;
 352  
 353          return $lang;
 354      }
 355  
 356      function rememberNavigationLanguage($lang)
 357      {
 358          if(isset($_SESSION) && !empty($lang)){
 359              $_SESSION['lang'] = $lang;
 360          }
 361      }
 362  
 363      function getNavigationLanguage()
 364      {
 365          if(!isset($_SESSION['lang'])){
 366              $this->browser_lang = $this->getDefaultLanguageForUser();
 367              return $this->getDefaultLanguageForUser();
 368          }else{
 369              return $_SESSION['lang'];
 370          }
 371      }
 372  
 373      function getLocaleFromAlias($alias)
 374      {
 375          foreach ($this->available_locales  as $locale=>$locale_arr){
 376              if(in_array($alias,$locale_arr)){
 377                  return $locale;
 378              }
 379          }
 380  
 381          return false;
 382      }
 383  
 384  }
 385  
 386  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6