Source for file idioma.classe.php

Documentation is available at idioma.classe.php

  1. <?php
  2.  
  3.     /**
  4.      * Provê internacionalização ao framework OpenMind
  5.      *
  6.      * Busca o idioma a ser utilizado em:
  7.      * - Configurações do browser cliente
  8.      * - Preferências do usuário (objeto preferências)
  9.      * - Configuração
  10.      * @see preferencia
  11.      * @see i18n_METHOD
  12.      * 
  13.      *  Também fornece métodos para recuperação de strings traduzidas e manutenção das mesmas.
  14.      *
  15.      * @copyright 2008 Soomp
  16.      * @author Marcio Merlone <mmerlone@gmail.com>
  17.      * @version 0.1
  18.      * @since 23/05/2006
  19.      * @package i18n
  20.      */
  21.     /* $Id: idioma.classe.php,v 1.11 2007/05/29 19:17:25 mmerlone Exp $ */
  22.  
  23.     /**
  24.      * Limpa a string de idioma aceita pelo browser, removendo o fator de qualidade, ou seja remove ";q=08"
  25.      * @param string idioma aceita pelo browser
  26.      * @return string idioma sem o ;q=08 em minúsculas
  27.      */
  28.     function trimLang(&$string){
  29.         if(strlen($string2){
  30.             $string substr($string02);
  31.         }
  32.         return strtolower($string);
  33.     }
  34.  
  35.     require_once(CFG_LOCAL_FRAMEWORK.'model.classe.php');
  36.     /**
  37.      * Define o algoritmo para definição do idioma
  38.      * e métodos para busca de strings conforme mecanismo solicitado no config.
  39.      * A preferência de idioma será salva em $_SESSION['lang'] sempre.
  40.      * Cada objeto que utilizar esta informção definirá sua própria variável
  41.      * (ex: smarty: $sm->strLang;)
  42.      * <code>
  43.      * require_once('idioma.classe.php');
  44.      * $idioma = new idioma();
  45.      * $string = $idioma->getString(array('id' => 9, 'value' => 'Texto a ser traduzido'));
  46.      * $string2 = $idioma->getString(2);
  47.      * </code>
  48.      * @todo Implementar mecanismos plain, hash e xml
  49.      * @todo Implementar métodos get/set para manutenção de strings
  50.      * @author Marcio Merlone <mmerlone@gmail.com>
  51.      */
  52.     class idioma extends model{
  53.  
  54.  
  55.         /**
  56.          * @var string $_strTable nome da tabela com os dados
  57.          */
  58.         protected $_strTable = 'TB_IDIOMA';
  59.         /**
  60.          * @var string $_strFldPk nome do campo com o pk
  61.          */
  62.         protected $_strFldPk = 'PK_I18N';
  63.         /**
  64.          * @var string $_strFldNo nome do campo com o nome
  65.          */
  66.         protected $_strFldNo = 'NO_I18N';
  67.         /**
  68.          * @var boolean $_boolUserDb define se deve-se utilizar a conexão db de usuários
  69.          */
  70.         protected $_boolUserDb = false;
  71.         /**
  72.          * @var string $strOrdCampo campo padrão de ordenação
  73.          */
  74.         public $strOrdCampo = 'NO_I18N';
  75.  
  76.         /**
  77.          * @var string $strLang armazena a string com o idioma a ser utilizado
  78.          *  $_SERVER['HTTP_ACCEPT_LANGUAGE'] = "pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3"
  79.          *  Pode vir do browser, do config ou das preferências.
  80.          * @link http://www.ietf.org/rfc/rfc3066.txt
  81.          */
  82.         public $strLang = 'pt';
  83.         /**
  84.          * @var string $strLangTpl armazena a string com o idioma a ser utilizado caso não seja encontrada
  85.          *  a localização de alguma string específica para $this->strLang (provavelmente sempre pt)
  86.          *  É o idioma do template.
  87.          * @uses i18n_TPL
  88.          */
  89.         public $strLangTpl = i18n_TPL;
  90.         /**
  91.          * @var array Armazena o array com a intersecção das línguas definidas no browser com as disponíveis
  92.          */
  93.         private $_arrLangs array();
  94.         /**
  95.          * @var bool $_default se é definido i18n_LANG no config ou não - [true|false]
  96.          */
  97.         private $_default;
  98.         /**
  99.          * @var string Armazena o método para escolha de idioma - [browser|pref|config|'null']
  100.          *  Se nulo desabilita internacionalização
  101.          */
  102.         private $_method;
  103.         /**
  104.          * @var string Armazena o método de armazenamento de idiomas - [db|php|plain|hash|xml]
  105.          *  caso nulo implica em não internacionlização
  106.          */
  107.         private $_store;
  108.         /**
  109.          * @var string armazena a origem efetiva da string $this->strLang - read-only, para debug
  110.          */
  111.         private $_origin;
  112.         /**
  113.          * @var object $instance instância da classe
  114.          */
  115.         private static $instance null;
  116.  
  117.         /**
  118.          * Define o idioma a ser utilizado pelo framework
  119.          * @uses i18n_METHOD
  120.          * @uses i18n_STORE
  121.          * @uses _setLang
  122.          */
  123.         public function __construct({
  124.             parent::__construct();
  125.             if(defined('i18n_METHOD'&& !is_null(i18n_METHOD&& i18n_METHOD != ''){
  126.                 $this->_setMethod();
  127.                 $this->_setStorage();
  128.                 $this->_default (defined('i18n_LANG'&& !is_null(i18n_LANG&& i18n_LANG != ''true false;
  129.                 $this->_setLang();
  130.             }
  131.         }
  132.  
  133.         /**
  134.          * Singleton
  135.          */
  136.         public static function getInstance(){
  137.             if (is_null(self::$instance)){
  138.                 if(isset($_SESSION['idioma'])){
  139.                     self::$instance unserialize($_SESSION['idioma']);
  140.                 }else{
  141.                     self::$instance new idioma();
  142.                 }
  143.             }
  144.             return self::$instance;
  145.         }
  146.  
  147.         /**
  148.          * Busca a tradução de um texto conforme método definido no config.
  149.          * Caso não exista tradução, usa-se o 'value' do array
  150.          * Também efetua substituição de variáveis na string desde que exista
  151.          * 'vars' => array('var' => 'value') dentro de $arrI18n.
  152.          * 
  153.          * @param mixed $arrI18n array com os dados para busca da string ou uma string
  154.          * @param string $strLang idioma a buscar
  155.          * @return string texto traduzido se possível
  156.          * @uses i18n_STORE
  157.          * @uses _getStringDb
  158.          * @uses _getStringPhp
  159.          * 
  160.          *  Formato de $arrI18n:
  161.          *  <code>
  162.          *  $arrI18n = array('id' => 23, 'value' => 'Texto a traduzir com $var1', 'vars' => array('var1' => 'valor1'))
  163.          *  </code>
  164.          */
  165.         public function getString($arrI18n$strLang null){
  166.  
  167.             $strLang is_null($strLang$this->strLang : $strLang;
  168.  
  169.             /**
  170.              * Caso $this->_store == null ou não definido usa-se pt e não considera internacionalização
  171.              */
  172.             if($this->_store){
  173.  
  174.                 switch(i18n_STORE){
  175.                     case 'db':
  176.                         $i18n $this->_getStringDb($arrI18n$strLang);
  177.                         break;
  178.  
  179.                     case 'php':
  180.                         $i18n $this->_getStringPhp($arrI18n$strLang);
  181.                         break;
  182.  
  183.                     case 'plain':
  184.                         trigger_error('getString: Método de armazenamento de idiomas "'.i18n_STORE.'" ainda não foi implementado.'E_USER_WARNING);
  185.                         $this->_method null;
  186.                         $i18n null;
  187.                         break;
  188.  
  189.                     case 'hash':
  190.                         trigger_error('getString: Método de armazenamento de idiomas "'.i18n_STORE.'" ainda não foi implementado.'E_USER_WARNING);
  191.                         $this->_method null;
  192.                         $i18n null;
  193.                         break;
  194.  
  195.                     case 'xml':
  196.                         trigger_error('getString: Método de armazenamento de idiomas "'.i18n_STORE.'" ainda não foi implementado.'E_USER_WARNING);
  197.                         $this->_method null;
  198.                         $i18n null;
  199.                         break;
  200.                 }
  201.             }else{
  202.                 $i18n null;
  203.             }
  204.  
  205.             /**
  206.              * Trata retorno null
  207.              */
  208.             if(is_null($i18n)){
  209.                 if(is_array($arrI18n)){
  210.                     $i18n $arrI18n['value'];
  211.                 }else{
  212.                     $i18n $arrI18n;
  213.                 }
  214.             }
  215.  
  216.             /**
  217.              * Substitui variáveis caso existam
  218.              */
  219.             if(isset($arrI18n['vars']&& is_array($arrI18n['vars']&& !empty($arrI18n['vars'])){
  220.                 $i18n compileString($arrI18n['vars']$i18n);
  221.             }
  222.             return $i18n;
  223.         }
  224.  
  225.         /**
  226.          * Valida a string armazenada no config em i18n_METHOD
  227.          */
  228.         private function _setMethod(){
  229.             $arrMethods array('browser'    => 1,
  230.                                 'pref'        => 1,
  231.                                 'config'    => 1);
  232.  
  233.             if(isset($arrMethods[i18n_METHOD])){
  234.                 $this->_method i18n_METHOD;
  235.             }else{
  236.                 trigger_error('__construct: Método de detecção de idioma "'.i18n_METHOD.'" não existe - verifique o config.php!'E_USER_WARNING);
  237.                 $this->_method 'browser'// Usa do browser pois é o mais provável que sempre exista.
  238.             }
  239.         }
  240.  
  241.         /**
  242.          * Valida a string armazenada no config em i18n_STORE
  243.          */
  244.         private function _setStorage(){
  245.             $arrStores array('db'        => 1,
  246.                                'php'    => 1,
  247.                                'plain'    => 1,
  248.                                'hash'    => 1,
  249.                                'xml'    => 1);
  250.  
  251.             if((defined('i18n_STORE'&& isset($arrStores[i18n_STORE])) || is_null(i18n_STORE)){
  252.                 $this->_store i18n_STORE;
  253.             }else{
  254.                 trigger_error('__construct: Método de armazenamento de idioma "'.i18n_STORE.'" não existe - verifique o config.php! Desabilitando funções de internacionalização.'E_USER_WARNING);
  255.                 $this->_store  null// Nulo implica em não internacionlização
  256.             }
  257.         }
  258.  
  259.         /**
  260.          * Determina o idioma a ser utilizado
  261.          * @uses getLangs
  262.          * @uses i18n_LANG
  263.          * @uses trimLang
  264.          */
  265.         private function _setLang(){
  266.  
  267.             if($this->_store){
  268.  
  269.                 if($this->_method == 'browser'){
  270.                     $arrBrowserAcceptLang explode(','$_SERVER['HTTP_ACCEPT_LANGUAGE']);
  271.                     array_walk($arrBrowserAcceptLang'trimLang');
  272.                     $this->_arrLangs array_values(array_intersect($arrBrowserAcceptLang$this->getLangs()));
  273.  
  274.                     /**
  275.                      * Define como o primeiro idioma em comum entre as disponíveis
  276.                      * e o solicitado pelo browser
  277.                      */
  278.                     if(!empty($this->_arrLangs)){
  279.                         $this->strLang = $this->_arrLangs[0];
  280.                         $this->_origin 'browser';
  281.  
  282.                     /**
  283.                      * Utiliza o idioma default configurado
  284.                      */
  285.                     }elseif($this->_default){
  286.                         $this->strLang = i18n_LANG;
  287.                         $this->_origin 'browser -> i18n_LANG';
  288.  
  289.                     /**
  290.                      * Utiliza o idioma dos templates
  291.                      */
  292.                     }else{
  293.                         $this->strLang = $this->strLangTpl;
  294.                         $this->_origin 'browser -> fallback';
  295.                     }
  296.  
  297.                 /**
  298.                  * Utiliza o idioma default configurado
  299.                  */
  300.                 }elseif($this->_method == 'config' && $this->_default){
  301.                     $this->strLang    = i18n_LANG;
  302.                     $this->_origin    'config';
  303.  
  304.                 }else{
  305.                     trigger_error('_setLang: O método para definição de idioma "'.$this->_method.'" falhou, usando '.$this->strLangTplE_USER_WARNING);
  306.                     $this->strLang    = $this->strLangTpl;
  307.                     $this->_origin    'falha';
  308.  
  309.                 }
  310.             }else{
  311.                 $this->strLang = $this->strLangTpl;
  312.             }
  313.         }
  314.  
  315.  
  316.  
  317.         /*****************************************************************************
  318.          * 
  319.          * Métodos auxiliares de definição de idiomas
  320.          * 
  321.          * Conforme o mecanismo de definição de idioma no config.php i18n_METHOD
  322.          * busca os idiomas disponíveis no projeto. São métodos auxiliares do método
  323.          * privado principal getLangs.
  324.          * Devem sempre retornar um array comum com as strings dos idiomas suportados
  325.          * como valores do array.
  326.          * 
  327.          */
  328.  
  329.         /**
  330.          * Retorna as localizações disponíveis no framework/projeto
  331.          * @return array Array com os idiomas disponíveis para o framework
  332.          * @uses _getLangsDb
  333.          * @uses _getLangsPhp
  334.          * @uses i18n_STORE
  335.          * @uses i18n_TPL
  336.          */
  337.         public function getLangs(){
  338.             /**
  339.              * @todo implementar mecanismo cfme armazenamento das linguas disponiveis
  340.              */
  341.             $arrRet array(i18n_TPL);
  342.  
  343.             switch(i18n_STORE){
  344.                 case 'db':
  345.                     $this->_getLangsDb($arrRet);
  346.                     break;
  347.  
  348.                 case 'php':
  349.                     $this->_getLangsPhp($arrRet);
  350.                     break;
  351.  
  352.                 case 'plain':
  353.                     trigger_error('getLangs: Método de armazenamento de idiomas "'.i18n_STORE.'" ainda não foi implementado. Usando o texto original.'E_USER_WARNING);
  354.                     break;
  355.  
  356.                 case 'hash':
  357.                     trigger_error('getLangs: Método de armazenamento de idiomas "'.i18n_STORE.'" ainda não foi implementado. Usando o texto original.'E_USER_WARNING);
  358.                     break;
  359.  
  360.                 case 'xml':
  361.                     trigger_error('getLangs: Método de armazenamento de idiomas "'.i18n_STORE.'" ainda não foi implementado. Usando o texto original.'E_USER_WARNING);
  362.                     break;
  363.             }
  364.             return $arrRet;
  365.         }
  366.  
  367.         /**
  368.          * Coleta os idiomas disponíveis no banco de dados
  369.          * @param array $arrRet por referência o array atual com as strings de idiomas.
  370.          * @uses i18n_STORE_DB_WHERE
  371.          * @uses i18n_STORE_DB_TABLE
  372.          */
  373.         private function _getLangsDb(&$arrRet){
  374.             if($db &$this->getDb()){
  375.                 $qry 'SELECT DISTINCT(LANG_i18N) FROM TB_IDIOMA';
  376.                 if($arrLangs $db->GetAll($qry)){
  377.                     foreach($arrLangs as $arrTmp){
  378.                         if(!in_array($arrTmp['LANG_i18N']$arrRet)){
  379.                             array_push($arrRet$arrTmp['LANG_i18N']);
  380.                         }
  381.                     }
  382.                 }
  383.             }else{
  384.                 trigger_error('_getStringDb: Erro ao conectar no banco de dados.'E_USER_WARNING);
  385.             }
  386.         }
  387.  
  388.         /**
  389.          * Retorna os idiomas disponíveis em arquivos php
  390.          * @param array $arrRet Array com as strings de idiomas suportadas
  391.          * @uses i18N_STORE_PHP_FILE
  392.          */
  393.         private function _getLangsPhp(&$arrRet){
  394.             if(defined('i18N_STORE_PHP_FILE'&& !is_null(i18N_STORE_PHP_FILE&& i18N_STORE_PHP_FILE != ''){
  395.                 $langDir dirname(i18N_STORE_PHP_FILE);
  396.                 if (is_dir($langDir&& $handle opendir($langDir)) {
  397.                     $re '/'.str_replace('LANG''(.*)'addcslashes(basename(i18N_STORE_PHP_FILE)'./+-')).'/';
  398.                     while (false !== ($file readdir($handle))) {
  399.                         if ($file != "." && $file != ".." && filesize($langDir.'/'.$file0{
  400.                             preg_match($re$file$match);
  401.                             if(!empty($match&& !in_array($match[1]$arrRet)){
  402.                                 array_push($arrRet$match[1]);
  403.                             }
  404.                         }
  405.                     }
  406.                     closedir($handle);
  407.                 }else{
  408.                     trigger_error('O diretório '.$langDir.' não existe!'E_USER_WARNING);
  409.                 }
  410.             }else{
  411.                 trigger_error('getLangs: Defina i18N_STORE_PHP_FILE no config.php. Desabilitando internacionalização.'E_USER_WARNING);
  412.                 $this->_method null;
  413.             }
  414.         }
  415.  
  416.  
  417.  
  418.         /*****************************************************************************
  419.          * 
  420.          * Métodos auxiliares de busca de texto
  421.          * 
  422.          * São sub-métodos auxiliares do método principal getString
  423.          * Cada método é implementado de acordo com os mecanismos de
  424.          * busca de strings i18n_METHOD
  425.          * 
  426.          * Cada método SEMPRE receberá 2 parâmetros:
  427.          * - $arrI18n = array com os dados para busca da string
  428.          * - $strLang    = idioma para o qual buscar a i18n
  429.          * 
  430.          * Cada método deverá sempre retornar uma de duas possibilidades:
  431.          * - A string traduzida para o idioma solicitado OU
  432.          * - NULL caso não encontre a tradução. O método público getString
  433.          * irá tratar a ausência de tradução.
  434.          * 
  435.          */
  436.  
  437.         /**
  438.          * Busca a tradução de um texto utilizando o banco de dados dado o ID ou o TEXTO
  439.          * a ser traduzido. Se omitido 'id', usa 'value' para busca.
  440.          * 
  441.          * @param mixed $arrI18n array com os dados para busca da string ou a própria string
  442.          * @param string idioma a ser utilizado
  443.          * @return string texto traduzido se possível ou null
  444.          * @uses i18n_STORE_DB_PK
  445.          * @uses i18n_STORE_DB_NO
  446.          * @uses i18n_STORE_DB_STR
  447.          * @uses i18n_STORE_DB_TABLE
  448.          * @uses i18n_STORE_DB_WHERE
  449.          *  Formato de $arrI18n:
  450.          *  <code>
  451.          *  $arrI18n = array('id' => 23, 'value' => 'texto a traduzir')
  452.          *  </code>
  453.          */
  454.         private function _getStringDb($arrI18n$strLang){
  455.  
  456.             if($db &$this->getDb()){
  457.                 if(is_array($arrI18n)){
  458.                     if(isset($arrI18n['id']&& $arrI18n['id']){
  459.                         $campo 'PK_I18N';
  460.                         $where $arrI18n['id'];
  461.                     }else{
  462.                         $campo 'NO_I18N';
  463.                         $where $db->qstr($arrI18n['value']);
  464.                     }
  465.                 }else{
  466.                     $campo 'NO_I18N';
  467.                     $where $db->qstr($arrI18n);
  468.                 }
  469.                 $qry 'SELECT LO_I18N FROM TB_IDIOMA WHERE '.$campo.'="'.$where.'" AND LANG_I18N ="'.$strLang.'"';
  470.                 $arrRet    $db->GetRow($qry);
  471.                 return isset($arrRet['LO_I18N']$arrRet['LO_I18N'null;
  472.             }else{
  473.                 trigger_error('_getStringDb: Erro ao conectar no banco de dados.'E_USER_WARNING);
  474.                 return null;
  475.             }
  476.         }
  477.  
  478.         /**
  479.          * Busca a tradução de um texto utilizando um arquivo php dado o ID a ser traduzido
  480.          * Este método não suporta busca pelo TEXTO.
  481.          * 
  482.          * @param mixed $arrI18n array com os dados para busca da string ou a própria string
  483.          * @param string idioma a ser utilizado
  484.          * @return string texto traduzido se possível ou null
  485.          * @uses CFG_DEBUG
  486.          * @uses i18N_STORE_PHP_FILE
  487.          */
  488.         private function _getStringPhp($arrI18n$strLang){
  489.             /**
  490.              * $_SESSION[$strLang] armazena o array com as strings l10n array(id => 'texto');
  491.              */
  492.             if(is_numeric($arrI18n)){
  493.                 $i $arrI18n;
  494.             }elseif(is_array($arrI18n)){
  495.                 $i $arrI18n['id'];
  496.             }else{
  497.                 return null;
  498.             }
  499.             
  500.             if(!isset($_SESSION[$strLang]|| (defined('CFG_DEBUG'&& !CFG_DEBUG)){
  501.                 if(defined('i18N_STORE_PHP_FILE'&& !is_null(i18N_STORE_PHP_FILE&& i18N_STORE_PHP_FILE != ''){
  502.                     $file str_replace('LANG'$strLangi18N_STORE_PHP_FILE);
  503.                     if(is_file($file)){
  504.                         require_once($file);
  505.                         if(isset($arrStrings&& !empty($arrStrings)){
  506.                             $_SESSION[$strLang$arrStrings;
  507.                         }
  508.                     }else{
  509.                         trigger_error('_getStringPhp: Arquivo de idiomas &quot;'.$file.'&quot; não encontrado! Verifique i18N_STORE_PHP_FILE no config.php.'E_USER_WARNING);
  510.                     }
  511.                 }else{
  512.                     trigger_error('_getStringPhp: Defina i18N_STORE_PHP_FILE no config.php. Desabilitando internacionalização.'E_USER_WARNING);
  513.                     $this->_method null;
  514.                 }
  515.             }
  516.             return isset($_SESSION[$strLang][$i]$_SESSION[$strLang][$inull;
  517.         }
  518.  
  519.     }
  520. ?>

Documentation generated on Sun, 09 Mar 2008 23:52:12 -0300 by phpDocumentor 1.4.0

SourceForge.net Logo Support This Project