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.42 2008/11/14 16:18:50 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 true|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.         return true;
  308.     }
  309.  
  310.     // }}}
  311.     // {{{ setPageID($pageID)
  312.  
  313.     /**
  314.      * Set default page
  315.      *
  316.      * Set the page (aka "group of strings") that shall be used when retrieving strings.
  317.      * If you set it, you don't have to state it in each get() call.
  318.      *
  319.      * @param string $pageID ID of the default page
  320.      *
  321.      * @return self 
  322.      */
  323.     function setPageID($pageID = null)
  324.     {
  325.         $this->currentPageID = $pageID;
  326.         return $this;
  327.     }
  328.  
  329.     // }}}
  330.     // {{{ getLang()
  331.  
  332.     /**
  333.      * get lang info
  334.      *
  335.      * Get some extra information about the language (its full name,
  336.      * the localized error text, ...)
  337.      *
  338.      * @param string $langID language ID
  339.      * @param string $format ['name', 'meta', 'error_text', 'array']
  340.      *
  341.      * @return mixed [string | array], depending on $format
  342.      */
  343.     function getLang($langID = null$format 'name')
  344.     {
  345.         if (is_null($langID)) {
  346.             if (!isset($this->lang['id'])) {
  347.                 $msg 'Translation2::getLang(): unknown language "'.$langID.'".'
  348.                       .' Use Translation2::setLang() to set a default language.';
  349.                 return $this->storage->raiseError($msgTRANSLATION2_ERROR_UNKNOWN_LANG);
  350.             }
  351.             $langID $this->lang['id'];
  352.         }
  353.         $lang $this->storage->getLangData($langID);
  354.         if ($format == 'array'{
  355.             return $lang;
  356.         elseif (isset($lang[$format])) {
  357.             return $lang[$format];
  358.         elseif (isset($lang['name'])) {
  359.             return $lang['name'];
  360.         }
  361.         $msg 'Translation2::getLang(): unknown language "'.$langID.'".'
  362.               .' Use Translation2::setLang() to set a default language.';
  363.         return $this->storage->raiseError($msgTRANSLATION2_ERROR_UNKNOWN_LANG);
  364.     }
  365.  
  366.     // }}}
  367.     // {{{ getLangs()
  368.  
  369.     /**
  370.      * get langs
  371.      *
  372.      * Get some extra information about the languages (their full names,
  373.      * the localized error text, their codes, ...)
  374.      *
  375.      * @param string $format ['ids', 'names', 'array']
  376.      *
  377.      * @return array|PEAR_Error
  378.      */
  379.     function getLangs($format 'name')
  380.     {
  381.         return $this->storage->getLangs($format);
  382.     }
  383.  
  384.     // }}}
  385.     // {{{ setParams()
  386.  
  387.     /**
  388.      * Set parameters for next string
  389.      *
  390.      * Set the replacement for the parameters in the string(s).
  391.      * Parameter delimiters are customizable.
  392.      *
  393.      * @param array $params array of replacement parameters
  394.      *
  395.      * @return self 
  396.      */
  397.     function setParams($params = null)
  398.     {
  399.         if (empty($params)) {
  400.             $this->params = array();
  401.         elseif (is_array($params)) {
  402.             $this->params = $params;
  403.         else {
  404.             $this->params = array($params);
  405.         }
  406.         return $this;
  407.     }
  408.  
  409.     // }}}
  410.     // {{{ _replaceParams()
  411.  
  412.     /**
  413.      * Replace parameters in strings
  414.      *
  415.      * @param mixed $strings strings where the replacements must occur
  416.      *
  417.      * @return mixed 
  418.      * @access protected
  419.      */
  420.     function _replaceParams($strings)
  421.     {
  422.         if (empty($strings|| is_object($strings|| !count($this->params)) {
  423.             return $strings;
  424.         }
  425.         if (is_array($strings)) {
  426.             foreach ($strings as $key => $string{
  427.                 $strings[$key$this->_replaceParams($string);
  428.             }
  429.         else {
  430.             if (strpos($strings$this->options['ParameterPrefix']!== false{
  431.                 foreach ($this->params as $name => $value{
  432.                     $strings str_replace($this->options['ParameterPrefix']
  433.                                            . $name $this->options['ParameterPostfix'],
  434.                                            $value,
  435.                                            $strings);
  436.                 }
  437.                 if ($this->options['ParameterAutoFree']{
  438.                     $this->params = array();
  439.                 }
  440.             }
  441.         }
  442.         return $strings;
  443.     }
  444.  
  445.     // }}}
  446.     // {{{ replaceEmptyStringsWithKeys()
  447.  
  448.     /**
  449.      * Replace empty strings with their stringID
  450.      *
  451.      * @param array $strings array of strings to be replaced if empty
  452.      *
  453.      * @return array 
  454.      * @static
  455.      */
  456.     function replaceEmptyStringsWithKeys($strings)
  457.     {
  458.         if (!is_array($strings)) {
  459.             return $strings;
  460.         }
  461.         foreach ($strings as $key => $string{
  462.             if (empty($string)) {
  463.                 $strings[$key$key;
  464.             }
  465.         }
  466.         return $strings;
  467.     }
  468.  
  469.     // }}}
  470.     // {{{ getRaw()
  471.  
  472.     /**
  473.      * Get translated string (as-is)
  474.      *
  475.      * @param string $stringID    ID of the string to be translated
  476.      * @param string $pageID      ID of the page/group containing the string
  477.      * @param string $langID      ID of the language
  478.      * @param string $defaultText Text to display when the string is empty
  479.      *
  480.      * @return string|PEAR_Error
  481.      */
  482.     function getRaw($stringID$pageID = TRANSLATION2_DEFAULT_PAGEID$langID = null$defaultText '')
  483.     {
  484.         $pageID ($pageID == TRANSLATION2_DEFAULT_PAGEID ? $this->currentPageID : $pageID);
  485.         $str $this->storage->getOne($stringID$pageID$langID);
  486.         if (empty($str)) {
  487.             $str $defaultText;
  488.         }
  489.         return $str;
  490.     }
  491.  
  492.     // }}}
  493.     // {{{ get()
  494.  
  495.     /**
  496.      * Get translated string
  497.      *
  498.      * First check if the string is cached, if not => fetch the page
  499.      * from the container and cache it for later use.
  500.      * If the string is empty, check the fallback language; if
  501.      * the latter is empty too, then return the $defaultText.
  502.      *
  503.      * @param string $stringID    ID of the string
  504.      * @param string $pageID      ID of the page/group containing the string
  505.      * @param string $langID      ID of the language
  506.      * @param string $defaultText Text to display when the string is empty
  507.      *                NB: This parameter is only used in the DefaultText decorator
  508.      *
  509.      * @return string 
  510.      */
  511.     function get($stringID$pageID = TRANSLATION2_DEFAULT_PAGEID$langID = null$defaultText '')
  512.     {
  513.         $str $this->getRaw($stringID$pageID$langID);
  514.         if (PEAR::isError($str)) {
  515.             return $str;
  516.         }
  517.         return $this->_replaceParams($str);
  518.     }
  519.  
  520.     // }}}
  521.     // {{{ getRawPage()
  522.  
  523.     /**
  524.      * Get the array of strings in a page
  525.      *
  526.      * Fetch the page (aka "group of strings) from the container,
  527.      * without applying any formatting and without replacing the parameters
  528.      *
  529.      * @param string $pageID ID of the page/group containing the string
  530.      * @param string $langID ID of the language
  531.      *
  532.      * @return array 
  533.      */
  534.     function getRawPage($pageID = TRANSLATION2_DEFAULT_PAGEID$langID = null)
  535.     {
  536.         $pageID ($pageID == TRANSLATION2_DEFAULT_PAGEID ? $this->currentPageID : $pageID);
  537.         return $this->storage->getPage($pageID$langID);
  538.     }
  539.  
  540.     // }}}
  541.     // {{{ getPage()
  542.  
  543.     /**
  544.      * Get an entire group of strings
  545.      *
  546.      * Same as getRawPage, but resort to fallback language and
  547.      * replace parameters when needed
  548.      *
  549.      * @param string $pageID ID of the page/group containing the string
  550.      * @param string $langID ID of the language
  551.      *
  552.      * @return array 
  553.      */
  554.     function getPage($pageID = TRANSLATION2_DEFAULT_PAGEID$langID = null)
  555.     {
  556.         $pageData $this->getRawPage($pageID$langID);
  557.         return $this->_replaceParams($pageData);
  558.     }
  559.  
  560.     // }}}
  561.     // {{{ getStringID()
  562.  
  563.     /**
  564.      * Get the stringID for the given string. This method is the reverse of get().
  565.      *
  566.      * @param string $string This is NOT the stringID, this is a real string.
  567.      *                The method will search for its matching stringID, and then
  568.      *                it will return the associate string in the selected language.
  569.      * @param string $pageID ID of the page/group containing the string
  570.      *
  571.      * @return string 
  572.      */
  573.     function getStringID($string$pageID = TRANSLATION2_DEFAULT_PAGEID)
  574.     {
  575.         $pageID ($pageID == TRANSLATION2_DEFAULT_PAGEID ? $this->currentPageID : $pageID);
  576.         return $this->storage->getStringID($string$pageID);
  577.     }
  578.  
  579.     // }}}
  580.     // {{{ __clone()
  581.  
  582.     /**
  583.      * Clone internal object references
  584.      *
  585.      * This method is called automatically by PHP5
  586.      *
  587.      * @return void 
  588.      * @access protected
  589.      */
  590.     function __clone()
  591.     {
  592.         $this->storage = clone($this->storage);
  593.     }
  594.  
  595.     // }}}
  596. }
  597. ?>

Documentation generated on Fri, 14 Nov 2008 11:30:33 -0500 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.