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

Source for file xml.php

Documentation is available at xml.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * Contains the Translation2_Admin_Container_xml 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.  * @author    Olivier Guilyardi <olivier@samalyse.com>
  34.  * @copyright 2004-2007 Lorenzo Alberton, Olivier Guilyardi
  35.  * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
  36.  * @version   CVS: $Id: xml.php,v 1.18 2007/11/10 00:02:50 quipo Exp $
  37.  * @link      http://pear.php.net/package/Translation2
  38.  */
  39.  
  40. /**
  41.  * require Translation2_Container_xml class
  42.  */
  43. require_once 'Translation2/Container/xml.php';
  44.  
  45. require_once 'XML/Util.php';
  46.  
  47. /**
  48.  * Storage driver for storing/fetching data to/from a XML file
  49.  *
  50.  * @category  Internationalization
  51.  * @package   Translation2
  52.  * @author    Lorenzo Alberton <l.alberton@quipo.it>
  53.  * @author    Olivier Guilyardi <olivier@samalyse.com>
  54.  * @copyright 2004-2007 Lorenzo Alberton, Olivier Guilyardi
  55.  * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
  56.  * @link      http://pear.php.net/package/Translation2
  57.  */
  58. {
  59.     // {{{ class vars
  60.     
  61.     /**
  62.      * Whether _saveData() is already registered at shutdown or not
  63.      * @var boolean 
  64.      */
  65.     var $_isScheduledSaving = false;
  66.  
  67.     // }}}
  68.     // {{{ addLang()
  69.  
  70.     /**
  71.      * Does nothing (here for compatibility with the container interface)
  72.      *
  73.      * @param array $langData language data
  74.      * @param array $options  language options
  75.      *
  76.      * @return true|PEAR_Error
  77.      */
  78.     function addLang($langData$options = array())
  79.     {
  80.         return true;
  81.     }
  82.  
  83.     // }}}
  84.     // {{{ addLangToList()
  85.  
  86.     /**
  87.      * Creates a new entry in the <languages> section
  88.      *
  89.      * @param array $langData array('lang_id'    => 'en',
  90.      *                               'name'       => 'english',
  91.      *                               'meta'       => 'some meta info',
  92.      *                               'error_text' => 'not available',
  93.      *                               'encoding'   => 'iso-8859-1',
  94.      *               );
  95.      *
  96.      * @return true|PEAR_Error
  97.      */
  98.     function addLangToList($langData)
  99.     {
  100.         $validInput = array(
  101.             'name'       => '',
  102.             'meta'       => '',
  103.             'error_text' => '',
  104.             'encoding'   => 'iso-8859-1',
  105.         );
  106.         
  107.         foreach ($validInput as $key => $val{
  108.             if (isset($langData[$key])) $validInput[$key$langData[$key];
  109.         }
  110.         
  111.         $this->_data['languages'][$langData['lang_id']] $validInput;
  112.         return $this->_scheduleSaving();
  113.     }
  114.  
  115.     // }}}
  116.     // {{{ updateLang()
  117.  
  118.     /**
  119.      * Update the lang info in the langsAvail table
  120.      *
  121.      * @param array $langData array [@see addLangToList()]
  122.      *
  123.      * @return true|PEAR_Error
  124.      */
  125.     function updateLang($langData)
  126.     {
  127.         $allFields = array//'lang_id',
  128.             'name''meta''error_text''encoding',
  129.         );
  130.         foreach ($allFields as $field{
  131.             if (isset($this->_data['languages'][$langData['lang_id']][$field])) {
  132.                 $this->_data['languages'][$langData['lang_id']][$field$langData[$field];
  133.             }
  134.         }
  135.         $success $this->_scheduleSaving();
  136.         $this->fetchLangs();  //update memory cache
  137.         return $success;
  138.     }
  139.  
  140.     // }}}
  141.     // {{{ add()
  142.  
  143.     /**
  144.      * Add a new entry in the strings table.
  145.      *
  146.      * @param string $stringID    string ID
  147.      * @param string $pageID      page/group ID
  148.      * @param array  $stringArray Associative array with string translations.
  149.      *                Sample format: array('en' => 'sample', 'it' => 'esempio')
  150.      *
  151.      * @return true|PEAR_Error
  152.      */
  153.     function add($stringID$pageID$stringArray)
  154.     {
  155.         $langs array_intersect(
  156.             array_keys($stringArray),
  157.             $this->getLangs('ids')
  158.         );
  159.  
  160.         $pageID is_null($pageID'#NULL'  $pageID;
  161.         $pageID = empty($pageID)   '#EMPTY' $pageID;
  162.  
  163.         if (!array_key_exists($pageID$this->_data['pages'])) {
  164.             $this->_data['pages'][$pageID= array();
  165.         }
  166.         if (!array_key_exists($stringID$this->_data['pages'][$pageID])) {
  167.             $this->_data['pages'][$pageID][$stringID= array();
  168.         }
  169.         foreach ($langs as $lang{
  170.             $this->_data['pages'][$pageID][$stringID][$lang$stringArray[$lang];
  171.         }
  172.         
  173.         return $this->_scheduleSaving();
  174.     }
  175.  
  176.     // }}}
  177.     // {{{ update()
  178.  
  179.     /**
  180.      * Update an existing entry in the strings table.
  181.      *
  182.      * @param string $stringID    string ID
  183.      * @param string $pageID      page/group ID
  184.      * @param array  $stringArray Associative array with string translations.
  185.      *                Sample format: array('en' => 'sample', 'it' => 'esempio')
  186.      *
  187.      * @return true|PEAR_Error
  188.      */
  189.     function update($stringID$pageID$stringArray)
  190.     {
  191.         return $this->add($stringID$pageID$stringArray);
  192.     }
  193.  
  194.     // }}}
  195.     // {{{ remove()
  196.  
  197.     /**
  198.      * Remove an entry from the strings table.
  199.      *
  200.      * @param string $stringID string ID
  201.      * @param string $pageID   page/group ID
  202.      *
  203.      * @return true|PEAR_Error
  204.      */
  205.     function remove($stringID$pageID)
  206.     {
  207.         $pageID is_null($pageID'#NULL' $pageID;
  208.         $pageID = empty($pageID'#EMPTY' $pageID;
  209.  
  210.         unset ($this->_data['pages'][$pageID][$stringID]);
  211.         if (!count($this->_data['pages'][$pageID])) {
  212.             unset ($this->_data['pages'][$pageID]);
  213.         }
  214.  
  215.         return $this->_scheduleSaving();
  216.     }
  217.  
  218.     // }}}
  219.     // {{{ removeLang()
  220.  
  221.     /**
  222.      * Remove all the entries for the given lang from the strings table.
  223.      *
  224.      * @param string  $langID language ID
  225.      * @param boolean $force  (ignored)
  226.      *
  227.      * @return true|PEAR_Error
  228.      */
  229.     function removeLang($langID$force = true)
  230.     {
  231.         // remove lang metadata 
  232.         unset($this->_data['languages'][$langID]);
  233.  
  234.         // remove the entries
  235.         foreach (array_keys($this->_data['pages']as $pageID{
  236.             foreach (array_keys($this->_data['pages'][$pageID]as $stringID{
  237.                 if (array_key_exists($langID$this->_data['pages'][$pageID][$stringID])) {
  238.                     unset($this->_data['pages'][$pageID][$stringID][$langID]);
  239.                 }
  240.             }
  241.         }
  242.         return $this->_scheduleSaving();
  243.     }
  244.  
  245.     // }}}
  246.     // {{{ removePage()
  247.  
  248.     /**
  249.      * Remove all the strings in the given page/group
  250.      *
  251.      * @param string $pageID page/group ID
  252.      *
  253.      * @return true|PEAR_Error
  254.      */
  255.     function removePage($pageID = null)
  256.     {
  257.         $pageID is_null($pageID'#NULL' $pageID;
  258.         $pageID = empty($pageID'#EMPTY' $pageID;
  259.  
  260.         unset ($this->_data['pages'][$pageID]);
  261.  
  262.         return $this->_scheduleSaving();
  263.     }
  264.  
  265.     // }}}
  266.     // {{{ getPageNames()
  267.  
  268.     /**
  269.      * Get a list of all the pageIDs.
  270.      *
  271.      * @return array 
  272.      */
  273.     function getPageNames()
  274.     {
  275.         $pages array_keys($this->_data['pages']);
  276.         $k array_search('#NULL'$pages);
  277.         if ($k !== false && !is_null($k)) {
  278.             $pages[$k= null;
  279.         }
  280.         $k array_search('#EMPTY'$pages);
  281.         if ($k !== false && !is_null($k)) {
  282.             $pages[$k'';
  283.         }
  284.         return $pages;
  285.     }
  286.  
  287.     // }}}
  288.     // {{{ _scheduleSaving()
  289.     
  290.     /**
  291.      * Prepare data saving
  292.      *
  293.      * This methods registers _saveData() as a PEAR shutdown function. This
  294.      * is to avoid saving multiple times if the programmer makes several
  295.      * changes.
  296.      * 
  297.      * @return true|PEAR_Error
  298.      * @access private
  299.      * @see Translation2_Admin_Container_xml::_saveData()
  300.      */
  301.     function _scheduleSaving()
  302.     {
  303.         if ($this->options['save_on_shutdown']{
  304.             if (!$this->_isScheduledSaving{
  305.                 // save the changes on shutdown
  306.                 register_shutdown_function(array(&$this'_saveData'));
  307.                 $this->_isScheduledSaving = true;
  308.             }
  309.             return true;
  310.         }
  311.         
  312.         // save the changes now
  313.         return $this->_saveData();
  314.     }
  315.  
  316.     // }}}
  317.     // {{{ _saveData()
  318.     
  319.     /**
  320.      * Serialize and save the updated tranlation data to the XML file
  321.      *
  322.      * @return boolean | PEAR_Error
  323.      * @access private
  324.      * @see Translation2_Admin_Container_xml::_scheduleSaving()
  325.      */
  326.     function _saveData()
  327.     {
  328.         if ($this->options['save_on_shutdown']{
  329.             $data =$this->_data;
  330.         else {
  331.             $data =  $this->_data;
  332.         }
  333.         
  334.         $this->_convertEncodings('to_xml'$data);
  335.         $this->_convertLangEncodings('to_xml'$data);
  336.         
  337.         // Serializing
  338.         
  339.         $xml "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n" .
  340.                "<!DOCTYPE translation2 [\n" TRANSLATION2_DTD . "]>\n\n" .
  341.                "<translation2>\n" .
  342.                "  <languages>\n";
  343.  
  344.         foreach ($data['languages'as $lang => $spec{
  345.             extract ($spec);
  346.             $xml .= "    <lang id=\"$lang\">\n" .
  347.                     "      <name>" 
  348.                     ($name ' ' . XML_Util::replaceEntities($name' ' ''
  349.                     "</name>\n" .
  350.                     "      <meta>" 
  351.                     ($meta ' ' . XML_Util::replaceEntities($meta' ' ""
  352.                     "</meta>\n" .
  353.                     "      <error_text>" 
  354.                     ($error_text 
  355.                         ? ' ' . XML_Util::replaceEntities($error_text' ' 
  356.                         : ""
  357.                     "</error_text>\n" .
  358.                     "      <encoding>" ($encoding ? " $encoding " : ""
  359.                     "</encoding>\n" .  
  360.                     "    </lang>\n";
  361.         }
  362.  
  363.         $xml .= "  </languages>\n" .
  364.                 "  <pages>\n";
  365.  
  366.         foreach ($data['pages'as $page => $strings{
  367.             $xml .= "    <page key=\"" . XML_Util::replaceEntities($page
  368.                     "\">\n";
  369.             foreach ($strings as $str_id => $translations{
  370.                 $xml .= "      <string key=\"" 
  371.                         XML_Util::replaceEntities($str_id"\">\n";
  372.                 foreach ($translations as $lang => $str{
  373.                     $xml .= "        <tr lang=\"$lang\"> " .
  374.                             XML_Util::replaceEntities($str" </tr>\n";
  375.                 }
  376.                 $xml .= "      </string>\n";
  377.             }
  378.             $xml .= "    </page>\n";
  379.         }
  380.  
  381.         $xml .= "  </pages>\n" .
  382.                 "</translation2>\n";
  383.  
  384.         unset ($data);
  385.         
  386.         // Saving
  387.  
  388.         if (!$f fopen ($this->_filename'w')) {
  389.             return $this->raiseError(sprintf(
  390.                     'Unable to open the XML file ("%s") for writing',
  391.                     $this->_filename
  392.                 ),
  393.                 TRANSLATION2_ERROR_CANNOT_WRITE_FILE,
  394.                 PEAR_ERROR_TRIGGER,
  395.                 E_USER_ERROR
  396.             );
  397.         }
  398.         @flock($fLOCK_EX);
  399.         fwrite ($f$xml);
  400.         //@flock($f, LOCK_UN);
  401.         fclose ($f);
  402.         return true;
  403.     }
  404.  
  405.     // }}}
  406. }
  407. ?>

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