Translation2
[ class tree: Translation2 ] [ index: Translation2 ] [ all elements ]

Source for file Translation2.php

Documentation is available at Translation2.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * Contains the Translation2 base class
  6.  *
  7.  * PHP versions 4 and 5
  8.  *
  9.  * LICENSE: Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. The name of the author may not be used to endorse or promote products
  17.  *    derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
  20.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
  23.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  26.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * @category  Internationalization
  31.  * @package   Translation2
  32.  * @author    Lorenzo Alberton <l.alberton@quipo.it>
  33.  * @copyright 2004-2008 Lorenzo Alberton
  34.  * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
  35.  * @version   CVS: $Id: Translation2.php,v 1.40 2008/02/02 18:02:26 quipo Exp $
  36.  * @link      http://pear.php.net/package/Translation2
  37.  */
  38.  
  39. /**
  40.  * require PEAR base class
  41.  */
  42. require_once 'PEAR.php';
  43.  
  44. /**
  45.  * Allows redefinition of the default pageID.
  46.  * This constant is needed to allow both NULL and EMPTY pageID values
  47.  * and to have them match
  48.  */
  49. if (!defined('TRANSLATION2_DEFAULT_PAGEID')) {
  50.     define('TRANSLATION2_DEFAULT_PAGEID''translation2_default_pageID');
  51. }
  52. /**
  53.  * Class Error codes
  54.  */
  55. define('TRANSLATION2_ERROR',                      -1);
  56. define('TRANSLATION2_ERROR_METHOD_NOT_SUPPORTED'-2);
  57. define('TRANSLATION2_ERROR_CANNOT_CONNECT',       -3);
  58. define('TRANSLATION2_ERROR_CANNOT_FIND_FILE',     -4);
  59. define('TRANSLATION2_ERROR_DOMAIN_NOT_SET',       -5);
  60. define('TRANSLATION2_ERROR_INVALID_PATH',         -6);
  61. define('TRANSLATION2_ERROR_CANNOT_CREATE_DIR',    -7);
  62. define('TRANSLATION2_ERROR_CANNOT_WRITE_FILE',    -8);
  63. define('TRANSLATION2_ERROR_UNKNOWN_LANG',         -9);
  64. define('TRANSLATION2_ERROR_ENCODING_CONVERSION'-10);
  65. define('TRANSLATION2_ERROR_UNSUPPORTED',         -11);
  66.  
  67. /**
  68.  * Translation2 base class
  69.  *
  70.  * This class provides an easy way to retrieve all the strings
  71.  * for a multilingual site or application from a data source
  72.  * (i.e. a db, an xml file or a gettext file).
  73.  *
  74.  * @category  Internationalization
  75.  * @package   Translation2
  76.  * @author    Lorenzo Alberton <l.alberton@quipo.it>
  77.  * @copyright 2004-2008 Lorenzo Alberton
  78.  * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
  79.  * @link      http://pear.php.net/package/Translation2
  80.  */
  81. {
  82.     // {{{ class vars
  83.  
  84.     /**
  85.      * Storage object
  86.      * @var object 
  87.      * @access protected
  88.      */
  89.     var $storage = '';
  90.  
  91.     /**
  92.      * Class options
  93.      * @var array 
  94.      */
  95.     var $options = array();
  96.  
  97.     /**
  98.      * Default lang
  99.      * @var array 
  100.      * @access protected
  101.      */
  102.     var $lang = array();
  103.  
  104.     /**
  105.      * Current pageID
  106.      * @var string 
  107.      * @access protected
  108.      */
  109.     var $currentPageID = null;
  110.  
  111.     /**
  112.      * Array of parameters for the adapter class
  113.      * @var array 
  114.      * @access protected
  115.      */
  116.     var $params = array();
  117.  
  118.     // }}}
  119.     // {{{ Constructor
  120.  
  121.     /**
  122.      * Constructor
  123.      */
  124.     function Translation2()
  125.     {
  126.         if (func_num_args()) {
  127.             $msg '<b>Translation2 error:</b>'
  128.                   .' Don\'t use the constructor - use factory()';
  129.             trigger_error($msgE_USER_ERROR);
  130.         }
  131.     }
  132.  
  133.     // }}}
  134.     // {{{ factory()
  135.  
  136.     /**
  137.      * Return a Translation2 instance already initialized
  138.      *
  139.      * @param string $driver  Type of the storage driver
  140.      * @param mixed  $options Additional options for the storage driver
  141.      *                         (example: if you are using DB as the storage
  142.      *                         driver, you have to pass the dsn string here)
  143.      * @param array  $params  Array of parameters for the adapter class
  144.      *                         (i.e. you can set here the mappings between your
  145.      *                         table/field names and the ones used by this class)
  146.      *
  147.      * @return object Translation2 instance or PEAR_Error on failure
  148.      * @static
  149.      */
  150.     function factory($driver$options ''$params = array())
  151.     {
  152.         $tr = new Translation2;
  153.         $tr->storage = Translation2::_storageFactory($driver$options);
  154.         if (PEAR::isError($tr->storage)) {
  155.             return $tr->storage;
  156.         }
  157.         $tr->_setDefaultOptions();
  158.         $tr->_parseOptions($params);
  159.         $tr->storage->_parseOptions($params);
  160.         return $tr;
  161.     }
  162.  
  163.     // }}}
  164.     // {{{ _storageFactory()
  165.  
  166.     /**
  167.      * Return a storage driver based on $driver and $options
  168.      *
  169.      * @param string $driver  Type of storage class to return
  170.      * @param string $options Optional parameters for the storage class
  171.      *
  172.      * @return object Object   Storage object
  173.      * @static
  174.      * @access private
  175.      */
  176.     function _storageFactory($driver$options '')
  177.     {
  178.         $storage_path  'Translation2/Container/'.strtolower($driver).'.php';
  179.         $storage_class 'Translation2_Container_'.strtolower($driver);
  180.         include_once $storage_path;
  181.         $storage = new $storage_class;
  182.         $err $storage->init($options);
  183.         if (PEAR::isError($err)) {
  184.             return $err;
  185.         }
  186.         return $storage;
  187.     }
  188.  
  189.     // }}}
  190.     // {{{ setContainerOptions()
  191.  
  192.     /**
  193.      * Set some storage driver options
  194.      *
  195.      * @param array $options array of options
  196.      *
  197.      * @return void 
  198.      * @access protected
  199.      */
  200.     function setContainerOptions($options)
  201.     {
  202.         $this->storage->_parseOptions($options);
  203.     }
  204.  
  205.     // }}}
  206.     // {{{ _setDefaultOptions()
  207.  
  208.     /**
  209.      * Set some default options
  210.      *
  211.      * @return void 
  212.      * @access private
  213.      */
  214.     function _setDefaultOptions()
  215.     {
  216.         $this->options['ParameterPrefix']   '&&';
  217.         $this->options['ParameterPostfix']  '&&';
  218.         $this->options['ParameterAutoFree'= true;
  219.         $this->options['prefetch']          = true;
  220.     }
  221.  
  222.     // }}}
  223.     // {{{ _parseOptions()
  224.  
  225.     /**
  226.      * Parse options passed to the base class
  227.      *
  228.      * @param array $array options
  229.      *
  230.      * @return void 
  231.      * @access private
  232.      */
  233.     function _parseOptions($array)
  234.     {
  235.         foreach ($array as $key => $value{
  236.             if (isset($this->options[$key])) {
  237.                 $this->options[$key$value;
  238.             }
  239.         }
  240.     }
  241.  
  242.     // }}}
  243.     // {{{ getDecorator()
  244.  
  245.     /**
  246.      * Return an instance of a decorator
  247.      *
  248.      * This method is used to get a decorator instance.
  249.      * A decorator can be seen as a filter, i.e. something that can change
  250.      * or handle the values of the objects/vars that pass through.
  251.      *
  252.      * @param string $decorator Name of the decorator
  253.      *
  254.      * @return object Decorator object reference
  255.      */
  256.     function getDecorator($decorator)
  257.     {
  258.         $decorator_path  'Translation2/Decorator/'.$decorator.'.php';
  259.         $decorator_class 'Translation2_Decorator_'.$decorator;
  260.         include_once $decorator_path;
  261.         if (func_num_args(> 1{
  262.             $obj func_get_arg(1);
  263.             $new_decorator = new $decorator_class($obj);
  264.         else {
  265.             $new_decorator = new $decorator_class($this);
  266.         }
  267.         return $new_decorator;
  268.     }
  269.  
  270.     // }}}
  271.     // {{{ setCharset()
  272.  
  273.     /**
  274.      * Set charset used to read/store the translations
  275.      *
  276.      * @param string $charset character set (encoding)
  277.      *
  278.      * @return void|PEAR_Error
  279.      */
  280.     function setCharset($charset)
  281.     {
  282.         $res $this->storage->setCharset($charset);
  283.         if (PEAR::isError($res)) {
  284.             return $res;
  285.         }
  286.     }
  287.  
  288.     // }}}
  289.     // {{{ setLang()
  290.  
  291.     /**
  292.      * Set default lang
  293.      *
  294.      * Set the language that shall be used when retrieving strings.
  295.      *
  296.      * @param string $langID language code (for instance, 'en' or 'it')
  297.      *
  298.      * @return void|PEAR_Error
  299.      */
  300.     function setLang($langID)
  301.     {
  302.         $res $this->storage->setLang($langID);
  303.         if (PEAR::isError($res)) {
  304.             return $res;
  305.         }
  306.         $this->lang = $res;
  307.     }
  308.  
  309.     // }}}
  310.     // {{{ setPageID($pageID)
  311.  
  312.     /**
  313.      * Set default page
  314.      *
  315.      * Set the page (aka "group of strings") that shall be used when retrieving strings.
  316.      * If you set it, you don't have to state it in each get() call.
  317.      *
  318.      * @param string $pageID ID of the default page
  319.      *
  320.      * @return void 
  321.      */
  322.     function setPageID($pageID = null)
  323.     {
  324.         $this->currentPageID = $pageID;
  325.     }
  326.  
  327.     // }}}
  328.     // {{{ getLang()
  329.  
  330.     /**
  331.      * get lang info
  332.      *
  333.      * Get some extra information about the language (its full name,
  334.      * the localized error text, ...)
  335.      *
  336.      * @param string $langID language ID
  337.      * @param string $format ['name', 'meta', 'error_text', 'array']
  338.      *
  339.      * @return mixed [string | array], depending on $format
  340.      */
  341.     function getLang($langID = null$format 'name')
  342.     {
  343.         if (is_null($langID)) {
  344.             if (!isset($this->lang['id'])) {
  345.                 $msg 'Translation2::getLang(): unknown language "'.$langID.'".'
  346.                       .' Use Translation2::setLang() to set a default language.';
  347.                 return $this->storage->raiseError($msgTRANSLATION2_ERROR_UNKNOWN_LANG);
  348.             }
  349.             $langID $this->lang['id'];
  350.         }
  351.         $lang $this->storage->getLangData($langID);
  352.         if ($format == 'array'{
  353.             return $lang;
  354.         elseif (isset($lang[$format])) {
  355.             return $lang[$format];
  356.         elseif (isset($lang['name'])) {
  357.             return $lang['name'];
  358.         }
  359.         $msg 'Translation2::getLang(): unknown language "'.$langID.'".'
  360.               .' Use Translation2::setLang() to set a default language.';
  361.         return $this->storage->raiseError($msgTRANSLATION2_ERROR_UNKNOWN_LANG);
  362.     }
  363.  
  364.     // }}}
  365.     // {{{ getLangs()
  366.  
  367.     /**
  368.      * get langs
  369.      *
  370.      * Get some extra information about the languages (their full names,
  371.      * the localized error text, their codes, ...)
  372.      *
  373.      * @param string $format ['ids', 'names', 'array']
  374.      *
  375.      * @return array 
  376.      */
  377.     function getLangs($format 'name')
  378.     {
  379.         return $this->storage->getLangs($format);
  380.     }
  381.  
  382.     // }}}
  383.     // {{{ setParams()
  384.  
  385.     /**
  386.      * Set parameters for next string
  387.      *
  388.      * Set the replacement for the parameters in the string(s).
  389.      * Parameter delimiters are customizable.
  390.      *
  391.      * @param array $params array of replacement parameters
  392.      *
  393.      * @return void 
  394.      */
  395.     function setParams($params = null)
  396.     {
  397.         if (empty($params)) {
  398.             $this->params = array();
  399.         elseif (is_array($params)) {
  400.             $this->params = $params;
  401.         else {
  402.             $this->params = array($params);
  403.         }
  404.     }
  405.  
  406.     // }}}
  407.     // {{{ _replaceParams()
  408.  
  409.     /**
  410.      * Replace parameters in strings
  411.      *
  412.      * @param mixed $strings strings where the replacements must occur
  413.      *
  414.      * @return mixed 
  415.      * @access protected
  416.      */
  417.     function _replaceParams($strings)
  418.     {
  419.         if (empty($strings|| is_object($strings|| !count($this->params)) {
  420.             return $strings;
  421.         }
  422.         if (is_array($strings)) {
  423.             foreach ($strings as $key => $string{
  424.                 $strings[$key$this->_replaceParams($string);
  425.             }
  426.         else {
  427.             if (strpos($strings$this->options['ParameterPrefix']!== false{
  428.                 foreach ($this->params as $name => $value{
  429.                     $strings str_replace($this->options['ParameterPrefix']
  430.                                            . $name $this->options['ParameterPostfix'],
  431.                                            $value,
  432.                                            $strings);
  433.                 }
  434.                 if ($this->options['ParameterAutoFree']{
  435.                     $this->params = array();
  436.                 }
  437.             }
  438.         }
  439.         return $strings;
  440.     }
  441.  
  442.     // }}}
  443.     // {{{ replaceEmptyStringsWithKeys()
  444.  
  445.     /**
  446.      * Replace empty strings with their stringID
  447.      *
  448.      * @param array $strings array of strings to be replaced if empty
  449.      *
  450.      * @return array 
  451.      * @static
  452.      */
  453.     function replaceEmptyStringsWithKeys($strings)
  454.     {
  455.         if (!is_array($strings)) {
  456.             return $strings;
  457.         }
  458.         foreach ($strings as $key => $string{
  459.             if (empty($string)) {
  460.                 $strings[$key$key;
  461.             }
  462.         }
  463.         return $strings;
  464.     }
  465.  
  466.     // }}}
  467.     // {{{ getRaw()
  468.  
  469.     /**
  470.      * Get translated string (as-is)
  471.      *
  472.      * @param string $stringID    ID of the string to be translated
  473.      * @param string $pageID      ID of the page/group containing the string
  474.      * @param string $langID      ID of the language
  475.      * @param string $defaultText Text to display when the string is empty
  476.      *
  477.      * @return string|PEAR_Error
  478.      */
  479.     function getRaw($stringID$pageID = TRANSLATION2_DEFAULT_PAGEID$langID = null$defaultText '')
  480.     {
  481.         $pageID ($pageID == TRANSLATION2_DEFAULT_PAGEID ? $this->currentPageID : $pageID);
  482.         $str $this->storage->getOne($stringID$pageID$langID);
  483.         if (empty($str)) {
  484.             $str $defaultText;
  485.         }
  486.         return $str;
  487.     }
  488.  
  489.     // }}}
  490.     // {{{ get()
  491.  
  492.     /**
  493.      * Get translated string
  494.      *
  495.      * First check if the string is cached, if not => fetch the page
  496.      * from the container and cache it for later use.
  497.      * If the string is empty, check the fallback language; if
  498.      * the latter is empty too, then return the $defaultText.
  499.      *
  500.      * @param string $stringID    ID of the string
  501.      * @param string $pageID      ID of the page/group containing the string
  502.      * @param string $langID      ID of the language
  503.      * @param string $defaultText Text to display when the string is empty
  504.      *                NB: This parameter is only used in the DefaultText decorator
  505.      *
  506.      * @return string 
  507.      */
  508.     function get($stringID$pageID = TRANSLATION2_DEFAULT_PAGEID$langID = null$defaultText '')
  509.     {
  510.         $str $this->getRaw($stringID$pageID$langID);
  511.         if (PEAR::isError($str)) {
  512.             return $str;
  513.         }
  514.         return $this->_replaceParams($str);
  515.     }
  516.  
  517.     // }}}
  518.     // {{{ getRawPage()
  519.  
  520.     /**
  521.      * Get the array of strings in a page
  522.      *
  523.      * Fetch the page (aka "group of strings) from the container,
  524.      * without applying any formatting and without replacing the parameters
  525.      *
  526.      * @param string $pageID ID of the page/group containing the string
  527.      * @param string $langID ID of the language
  528.      *
  529.      * @return array 
  530.      */
  531.     function getRawPage($pageID = TRANSLATION2_DEFAULT_PAGEID$langID = null)
  532.     {
  533.         $pageID ($pageID == TRANSLATION2_DEFAULT_PAGEID ? $this->currentPageID : $pageID);
  534.         return $this->storage->getPage($pageID$langID);
  535.     }
  536.  
  537.     // }}}
  538.     // {{{ getPage()
  539.  
  540.     /**
  541.      * Get an entire group of strings
  542.      *
  543.      * Same as getRawPage, but resort to fallback language and
  544.      * replace parameters when needed
  545.      *
  546.      * @param string $pageID ID of the page/group containing the string
  547.      * @param string $langID ID of the language
  548.      *
  549.      * @return array 
  550.      */
  551.     function getPage($pageID = TRANSLATION2_DEFAULT_PAGEID$langID = null)
  552.     {
  553.         $pageData $this->getRawPage($pageID$langID);
  554.         return $this->_replaceParams($pageData);
  555.     }
  556.  
  557.     // }}}
  558.     // {{{ getStringID()
  559.  
  560.     /**
  561.      * Get the stringID for the given string. This method is the reverse of get().
  562.      *
  563.      * @param string $string This is NOT the stringID, this is a real string.
  564.      *                The method will search for its matching stringID, and then
  565.      *                it will return the associate string in the selected language.
  566.      * @param string $pageID ID of the page/group containing the string
  567.      *
  568.      * @return string 
  569.      */
  570.     function getStringID($string$pageID = TRANSLATION2_DEFAULT_PAGEID)
  571.     {
  572.         $pageID ($pageID == TRANSLATION2_DEFAULT_PAGEID ? $this->currentPageID : $pageID);
  573.         return $this->storage->getStringID($string$pageID);
  574.     }
  575.  
  576.     // }}}
  577.     // {{{ __clone()
  578.  
  579.     /**
  580.      * Clone internal object references
  581.      *
  582.      * This method is called automatically by PHP5
  583.      *
  584.      * @return void 
  585.      * @access protected
  586.      */
  587.     function __clone()
  588.     {
  589.         $this->storage = clone($this->storage);
  590.     }
  591.  
  592.     // }}}
  593. }
  594. ?>

Documentation generated on Tue, 06 May 2008 06:00:41 -0400 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.