home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Translation2 / Admin / Container / xml.php < prev   
Encoding:
PHP Script  |  2008-07-02  |  12.9 KB  |  408 lines

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