Viewing file: gettext.php (18.15 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/** * Contains the Translation2_Admin_Container_gettext class * * PHP versions 4 and 5 * * LICENSE: Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @category Internationalization * @package Translation2 * @author Lorenzo Alberton <l.alberton@quipo.it> * @author Michael Wallner <mike@php.net> * @copyright 2004-2007 Lorenzo Alberton, Michael Wallner * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) * @version CVS: $Id: gettext.php 305985 2010-12-05 22:55:33Z clockwerx $ * @link http://pear.php.net/package/Translation2 */
/** * require Translation2_Container_gettext class */ require_once 'Translation2/Container/gettext.php';
/** * Storage driver for storing/fetching data to/from a gettext file * * This storage driver requires the gettext extension * * @category Internationalization * @package Translation2 * @author Lorenzo Alberton <l.alberton@quipo.it> * @author Michael Wallner <mike@php.net> * @copyright 2004-2007 Lorenzo Alberton, Michael Wallner * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) * @version CVS: $Id: gettext.php 305985 2010-12-05 22:55:33Z clockwerx $ * @link http://pear.php.net/package/Translation2 */ class Translation2_Admin_Container_gettext extends Translation2_Container_gettext { // {{{ class vars
var $_bulk = false; var $_queue = array(); var $_fields = array('name', 'meta', 'error_text', 'encoding');
// }}} // {{{ addLang()
/** * Creates a new entry in the langs_avail .ini file. * * @param array $langData language data * @param string $path path to gettext data dir * * @return mixed Returns true on success or PEAR_Error on failure. */ function addLang($langData, $path = null) { if (!isset($path) || !is_string($path)) { $path = $this->_domains[$this->options['default_domain']]; }
$path .= '/'. $langData['lang_id'] . '/LC_MESSAGES';
if (!is_dir($path)) { include_once 'System.php'; if (!System::mkdir(array('-p', $path))) { return $this->raiseError(sprintf( 'Cannot create new language in path "%s"', $path ), TRANSLATION2_ERROR_CANNOT_CREATE_DIR ); } }
return true; }
// }}} // {{{ addLangToList()
/** * Creates a new entry in the langsAvail .ini file. * If the file doesn't exist yet, it is created. * * @param array $langData array('lang_id' => 'en', * 'name' => 'english', * 'meta' => 'some meta info', * 'error_text' => 'not available' * 'encoding' => 'iso-8859-1', * ); * * @return true|PEAR_Error on failure */ function addLangToList($langData) { if (PEAR::isError($changed = $this->_updateLangData($langData))) { return $changed; } return $changed ? $this->_writeLangsAvailFile() : true; }
// }}} // {{{ add()
/** * Add a new entry in the strings domain. * * @param string $stringID string ID * @param string $pageID page/group ID * @param array $strings Associative array with string translations. * Sample format: array('en' => 'sample', 'it' => 'esempio') * * @return true|PEAR_Error on failure */ function add($stringID, $pageID, $strings) { if (!isset($pageID)) { $pageID = $this->options['default_domain']; }
$langs = array_intersect(array_keys($strings), $this->getLangs('ids'));
if (!count($langs)) { return true; // really? }
if ($this->_bulk) { foreach ($strings as $lang => $string) { if (in_array($lang, $langs)) { $this->_queue['add'][$pageID][$lang][$stringID] = $string; } } return true; } else { $add = array(); foreach ($strings as $lang => $string) { if (in_array($lang, $langs)) { $add[$pageID][$lang][$stringID] = $string; } } return $this->_add($add); } }
// }}} // {{{ remove()
/** * Remove an entry from the domain. * * @param string $stringID string ID * @param string $pageID page/group ID * * @return true|PEAR_Error on failure */ function remove($stringID, $pageID) { if (!isset($pageID)) { $pageID = $this->options['default_domain']; }
if ($this->_bulk) { $this->_queue['remove'][$pageID][$stringID] = true; return true; } else { $tmp = array($pageID => array($stringID => true)); return $this->_remove($tmp); }
}
// }}} // {{{ removePage
/** * Remove all the strings in the given page/group (domain) * * @param string $pageID page/group ID * @param string $path path to gettext data dir * * @return mixed true on success, PEAR_Error on failure */ function removePage($pageID = null, $path = null) { if (!isset($pageID)) { $pageID = $this->options['default_domain']; }
if (!isset($path)) { if (!empty($this->_domains[$pageID])) { $path = $this->_domains[$pageID]; } else { $path = $this->_domains[$this->options['default_domain']]; } }
if (PEAR::isError($e = $this->_removeDomain($pageID))) { return $e; } $this->fetchLangs(); foreach ($this->langs as $langID => $lang) { $domain_file = $path .'/'. $langID .'/LC_MESSAGES/'. $pageID .'.'; if (!@unlink($domain_file.'mo') || !@unlink($domain_file.'po')) { return $this->raiseError('Cannot delete page ' . $pageID. ' (file '.$domain_file.'.*)', TRANSLATION2_ERROR ); } }
return true; }
// }}} // {{{ update()
/** * Update * * Alias for Translation2_Admin_Container_gettext::add() * * @param string $stringID string ID * @param string $pageID page/group ID * @param array $strings strings * * @return mixed * @access public * @see add() */ function update($stringID, $pageID, $strings) { return $this->add($stringID, $pageID, $strings); }
// }}} // {{{ removeLang()
/** * Remove Language * * @param string $langID language ID * @param bool $force (unused) * * @return true|PEAR_Error * @access public */ function removeLang($langID, $force = false) { include_once 'System.php'; foreach ((array) $this->_domains as $domain => $path) { if (is_dir($fp = $path .'/'. $langID)) { if (PEAR::isError($e = System::rm(array('-rf', $fp))) || !$e) { return $e ? $e : PEAR::raiseError(sprintf( 'Could not remove language "%s" from domain "%s" '. 'in path "%s" (probably insufficient permissions)', $langID, $domain, $path ), TRANSLATION2_ERROR ); } } } return true; }
// }}} // {{{ updateLang()
/** * Update the lang info in the langs_avail file * * @param array $langData language data * * @return mixed Returns true on success or PEAR_Error on failure. * @access public */ function updateLang($langData) { if (PEAR::isError($changed = $this->_updateLangData($langData))) { return $changed; } return $changed ? $this->_writeLangsAvailFile() : true; }
// }}} // {{{ getPageNames()
/** * Get a list of all the domains * * @return array * @access public */ function getPageNames() { return array_keys($this->_domains); }
// }}} // {{{ begin()
/** * Begin * * @return void * @access public */ function begin() { $this->_bulk = true; }
// }}} // {{{ commit()
/** * Commit * * @return true|PEAR_Error on failure. * @access public */ function commit() { $this->_bulk = false; if (isset($this->_queue['remove'])) { if (PEAR::isError($e = $this->_remove($this->_queue['remove']))) { return $e; } } if (isset($this->_queue['add'])) { if (PEAR::isError($e = $this->_add($this->_queue['add']))) { return $e; } } return true; }
// }}} // {{{ _add()
/** * Add * * @param array &$bulk array('pageID' => array([languages])) * * @return true|PEAR_Error on failure. * @access private */ function _add(&$bulk) { include_once 'File/Gettext.php'; $gtFile = &File_Gettext::factory($this->options['file_type']); $langs = $this->getLangs('array');
foreach ((array) $bulk as $pageID => $languages) { //create the new domain on demand if (!isset($this->_domains[$pageID])) { if (PEAR::isError($e = $this->_addDomain($pageID))) { return $e; } } $path = $this->_domains[$pageID]; if ($path[strlen($path)-1] != '/' && $path[strlen($path)-1] != '\\') { $path .= '/'; } $file = '/LC_MESSAGES/'. $pageID .'.'. $this->options['file_type'];
foreach ($languages as $lang => $strings) {
if (is_file($path . $lang . $file)) { if (PEAR::isError($e = $gtFile->load($path . $lang . $file))) { return $e; } }
if (!isset($gtFile->meta['Content-Type'])) { $gtFile->meta['Content-Type'] = 'text/plain; charset='; if (isset($langs[$lang]['encoding'])) { $gtFile->meta['Content-Type'] .= $langs[$lang]['encoding']; } else { $gtFile->meta['Content-Type'] .= $this->options['default_encoding']; } }
foreach ($strings as $stringID => $string) { $gtFile->strings[$stringID] = $string; }
if (PEAR::isError($e = $gtFile->save($path . $lang . $file))) { return $e; }
//refresh cache $this->cachedDomains[$lang][$pageID] = $gtFile->strings; } }
$bulk = null; return true; }
// }}} // {{{ _remove()
/** * Remove * * @param array &$bulk array('pageID' => array([languages])) * * @return true|PEAR_Error on failure. * @access private */ function _remove(&$bulk) { include_once 'File/Gettext.php'; $gtFile = &File_Gettext::factory($this->options['file_type']);
foreach ($this->getLangs('ids') as $lang) { foreach ((array) $bulk as $pageID => $stringIDs) { $file = sprintf( '%s/%s/LC_MESSAGES/%s.%s', $this->_domains[$pageID], $lang, $pageID, $this->options['file_type'] );
if (is_file($file)) { if (PEAR::isError($e = $gtFile->load($file))) { return $e; }
foreach (array_keys($stringIDs) as $stringID) { unset($gtFile->strings[$stringID]); }
if (PEAR::isError($e = $gtFile->save($file))) { return $e; }
//refresh cache $this->cachedDomains[$lang][$pageID] = $gtFile->strings; } } }
$bulk = null; return true; }
// }}} // {{{ _addDomain()
/** * Add the path-to-the-new-domain to the domains-path-INI-file * * @param string $pageID domain name * * @return true|PEAR_Error on failure * @access private */ function _addDomain($pageID) { $domain_path = count($this->_domains) ? reset($this->_domains) : 'locale/';
if (!is_resource($f = fopen($this->options['domains_path_file'], 'a'))) { return $this->raiseError(sprintf( 'Cannot write to domains path INI file "%s"', $this->options['domains_path_file'] ), TRANSLATION2_ERROR_CANNOT_WRITE_FILE ); }
$CRLF = $this->options['carriage_return'];
while (true) { if (@flock($f, LOCK_EX)) { fwrite($f, $CRLF . $pageID . ' = ' . $domain_path . $CRLF); @flock($f, LOCK_UN); fclose($f); break; } }
$this->_domains[$pageID] = $domain_path;
return true; }
// }}} // {{{ _removeDomain()
/** * Remove the path-to-the-domain from the domains-path-INI-file * * @param string $pageID domain name * * @return true|PEAR_Error on failure * @access private */ function _removeDomain($pageID) { $domain_path = count($this->_domains) ? reset($this->_domains) : 'locale/';
if (!is_resource($f = fopen($this->options['domains_path_file'], 'r+'))) { return $this->raiseError(sprintf( 'Cannot write to domains path INI file "%s"', $this->options['domains_path_file'] ), TRANSLATION2_ERROR_CANNOT_WRITE_FILE ); }
$CRLF = $this->options['carriage_return'];
while (true) { if (@flock($f, LOCK_EX)) { $pages = file($this->options['domains_path_file']); foreach ($pages as $page) { if (preg_match('/^'.$pageID.'\s*=/', $page)) { //skip continue; } fwrite($f, $page . $CRLF); } fflush($f); ftruncate($f, ftell($f)); @flock($f, LOCK_UN); fclose($f); break; } }
unset($this->_domains[$pageID]);
return true; }
// }}} // {{{ _writeLangsAvailFile()
/** * Write the langs_avail INI file * * @return true|PEAR_Error on failure. * @access private */ function _writeLangsAvailFile() { if (PEAR::isError($langs = $this->getLangs())) { return $langs; }
if (!is_resource($f = fopen($this->options['langs_avail_file'], 'w'))) { return $this->raiseError(sprintf( 'Cannot write to available langs INI file "%s"', $this->options['langs_avail_file'] ), TRANSLATION2_ERROR_CANNOT_WRITE_FILE ); } $CRLF = $this->options['carriage_return'];
@flock($f, LOCK_EX);
foreach ($langs as $id => $data) { fwrite($f, '['. $id .']'. $CRLF); foreach ($this->_fields as $k) { if (isset($data[$k])) { fwrite($f, $k . ' = ' . $data[$k] . $CRLF); } } fwrite($f, $CRLF); }
@flock($f, LOCK_UN); fclose($f); return true; }
// }}} // {{{ _updateLangData()
/** * Update Lang Data * * @param array $langData language data * * @return true|PEAR_Error on failure. * @access private */ function _updateLangData($langData) { if (PEAR::isError($langs = $this->getLangs())) { return $langs; }
$lang = &$langs[$langData['lang_id']]; $changed = false; foreach ($this->_fields as $k) { if ( isset($langData[$k]) && (!isset($lang[$k]) || $langData[$k] != $lang[$k])) { $lang[$k] = $langData[$k]; $changed = true; } }
if ($changed) { $lang['id'] = $langData['lang_id']; $this->langs = $langs; } return $changed; }
// }}} } ?>
|