Blame | Letzte Änderung | Log anzeigen | RSS feed
<?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 varsvar $_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 demandif (!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)) {//skipcontinue;}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;}// }}}}?>