diff options
Diffstat (limited to 'text.class')
-rw-r--r-- | text.class | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/text.class b/text.class new file mode 100644 index 0000000..2011a0b --- /dev/null +++ b/text.class @@ -0,0 +1,422 @@ +<?php +/* +** $Id$ +** +** ITools - the Internet Tools Library +** +** Copyright (C) 1995-2003 by the ITools Authors. +** This program is free software; you can redistribute it and/or +** modify it under the terms of either the GNU General Public License +** or the GNU Lesser General Public License, as published by the Free +** Software Foundation. See http://www.gnu.org/licenses/ for details. +** +*/ + +class it_text extends it_db_record +{ + var $defaultlanguage; /* Preferred language (without cookie) */ + var $actlanguage; /* Selected language */ + var $actlanguagename; /* Name of selected language */ + var $languages = array(); /* Active languages */ + var $languages_available = array(); /* Available languages */ + var $language_failsafe; /* First available language */ + var $debug; /* Non-empty if debug mode is desired */ + var $cookiename; /* Name of the language cookie, default is "LANGUAGE" */ + var $unknown_labels = array(); /* array for spooling unknown labels in + debug mode */ + +/** + * Constructor + * @param $defaultlanguage Optional default language to use + * @param $tablename Optional name of text database table (default: 'it_texts') + * @param $debug Optional debug mode: display label of unknown texts, set to 'label' to always display labels instead of actual text + * @param $db Optional database object, defaults to global $it_db + * @param $cookiename Optional cookie name (default: 'LANGUAGE') + */ +function it_text($defaultlanguage='de', $tablename='it_texts', $debug='', $db=0, $cookiename='LANGUAGE') +{ + $this->debug = $debug; + $this->cookiename = $cookiename; + + /* Create database objects */ + if (is_object($db)) + $table = new it_db_table($db, $tablename); + else + $table = new it_db_table($GLOBALS['it_db'], $tablename); + $this->it_db_record($table, 'Label'); + + /* Get array of supported languages and their names */ + if (!$this->read('_')) + internal_error("Can't read language names"); + $languages = explode(',', $table->field_names()); + while (list($index, $code) = each($languages)) + { + if ($code != 'Label') + { + /* If a language's "_" field is unset, ignore it */ + if ($languagename = $this->data[$code]) + { + $this->languages_available[$code] = $languagename; + /* Only use a language in browser/cookie detection below if it's not diasbled by a leading '-' */ + if (substr($languagename, 0, 1) != '-') + { + $this->languages[$code] = $languagename; + if (!isset($this->language_failsafe)) + $this->language_failsafe = $code; + } + } + } + } + + /* Set our default language according to browser preference */ + if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) + { + /* SQL field names can't contain "-" so we change these to "_" */ + $languages = explode(',', strtr($_SERVER['HTTP_ACCEPT_LANGUAGE'], '-', '_')); + while (list($key, $lang) = each($languages)) + { + if (isset($this->languages[$lang])) + { + $this->defaultlanguage = $lang; + debug("Got language from browser: {$this->defaultlanguage}", 6); + break; + } + else + { + $short = substr($lang, 0, 2); + if (isset($this->languages[$short])) + { + $this->defaultlanguage = $short; + debug("Got language family from browser: {$this->defaultlanguage}", 6); + break; + } + } + } + if (count($this->languages) == 0) + debug("No active languages found!", 5); + } + + /* If no language matched, use the one that was supplied by our caller */ + if (!isset($this->defaultlanguage)) + $this->defaultlanguage = $defaultlanguage; + + /* If language is still invalid, use the first one from our database */ + if (!$this->languages[$this->defaultlanguage]) + { + debug("Bad language \"{$this->defaultlanguage}\", using first entry \"{$this->languages[$this->language_failsafe]}\"", 5); + $this->defaultlanguage = $this->language_failsafe; + } + + /* If a cookie is set, we use its value as our active language */ + if (isset($_COOKIE[$this->cookiename]) && ($cookie = $_COOKIE[$this->cookiename])) + { + if ($this->languages[$cookie]) /* Is this language available? */ + { + $this->actlanguage = $cookie; + debug("Got language from cookie: {$this->actlanguage}", 6); + } + } + + /* If the cookie supplied no valid language, we use our calculated default language */ + if (!isset($this->actlanguage)) + $this->actlanguage = $this->defaultlanguage; + + /* And finally, record the name of our active language. */ + $this->actlanguagename = $this->languages[$this->actlanguage]; + + debug("Used language is {$this->actlanguagename}, default language is {$this->defaultlanguage}.", 6); +} + + +/** + * Return a text in the selected language. + * @param $label Label of text to return + * @param $raw Optional unused obsolete parameter + * @param $language Optional language to return text in. + * @return Localized text string + */ +function text($label, $raw=0, $language='') +{ + if ($this->debug === 'label') + return $label; + + if ($this->read($label)) + { + if ($language == '') + $language = $this->actlanguage; + + /* + ** If field is NULL, consider it undefined (and return label if in + ** debug mode). That's why we can't call safe_get_field() here. + */ + if (isset($this->data[$language])) + return $this->data[$language]; + } + + if ($this->debug) + { + $this->unknown_labels[] = $label; + return "<blink>$label</blink>"; + } + else + return $this->label_unknown($label); +} + + +/** + * Localized function called when a label is not found + * overload this if for example you want to have a silent error behaviour + * @param $label Text label that was not found in database + */ +function label_unknown($label) +{ + internal_error("No text found for label \"$label\""); +} + + +/** + * Return a text in the selected language, with correctly encoded umlauts. + * Replaces variables of the form {obj.var} with value, e.g. {user.name} + * NOTE: Invalid object names or non-existing variables are simply deleted. + * @param $label Label of text to return + * @param $values Associative array containing values to fill in + * @param $language Optional language to return text in. + * @return Localized text string with variables replaced by their values + */ +function etext($label, $values=null, $language='') +{ + return it_text_transmogrify($this->text($label, false, $language), is_array($values) ? $values : null); +} + + +/** + * Change language + * @param $language New language to set + * @param $setcookie Optional flag if a cookie is to be set (default: true) + */ +function set_language($language, $setcookie=true) +{ + /* If set to an invalid language (via forged GET?) we delete the cookie */ + if ($this->languages_available[$language]) + { + if (!$this->languages[$language]) + debug('Selected an existing but currently disabled language!', 6); + $this->actlanguage = $language; + if ($setcookie) + SetCookie($this->cookiename, $this->actlanguage, time() + 31536000, '/'); /* 1 Year */ + } + else + { + $this->actlanguage = $this->defaultlanguage; + if ($setcookie) + SetCookie($this->cookiename, '', time() + 31536000, '/'); + } +} + + +/** + * Get active language + * @return currently active language + */ +function get_language() +{ + return $this->actlanguage; +} + + +/** + * Get default language + * @return default language + */ +function get_default_language() +{ + return $this->defaultlanguage; +} + + +/** + * Check if a text entry for a specific label exists + * @param $label Label to check + */ +function text_exists($label) +{ + if ($this->read($label)) + return 1; + return 0; +} + + +/** + * when running it_text in debug mode, you can use this to die (internal_error) + * in case there were unknown labels with a list of all unknown labels + */ +function checkout_unknown_labels() +{ + if (count($this->unknown_labels) > 0) + { + $debug_text = 'No text found for labels:<br>'; + reset ($this->unknown_labels); + while($a = each($this->unknown_labels)) + $debug_text .= $a[1]."<br>"; + + internal_error($debug_text); + } + else + return 0; +} + + +/** + * Replaces special chars with their TeX equivalent + * @param $text Text to convert from ISO-8859-1 to TeX encoding + * @param $convertlinebreaks Whether to convert LFs to TeX linebreaks + * @return TeX encoded text to be inserted into TeX template + */ +function texify($text, $convertlinebreaks = true) +{ + $translation = array + ( + 'À' => '{\`A}', + 'Á' => "{\'A}", + 'Â' => '{\^A}', + 'Ã' => '{\~A}', + 'Ä' => '{\"A}', + 'Ç' => '{\c C}', + 'È' => '{\`E}', + 'É' => "{\'E}", + 'Ê' => '{\^E}', + 'Ë' => '{\"E}', + 'Ì' => '{\`I}', + 'Í' => "{\'I}", + 'Î' => '{\^I}', + 'Ï' => '{\"I}', + 'Ñ' => '{\~N}', + 'Ò' => '{\`O}', + 'Ó' => "{\'O}", + 'Ô' => '{\^O}', + 'Õ' => '{\~O}', + 'Ö' => '{\"O}', + 'Ù' => '{\`U}', + 'Ú' => "{\'U}", + 'Û' => '{\^U}', + 'Ü' => '{\"U}', + 'ß' => '{\ss}', + 'à' => '{\`a}', + 'á' => "{\'a}", + 'â' => '{\^a}', + 'ã' => '{\~a}', + 'ä' => '{\"a}', + 'ç' => '{\c c}', + 'è' => '{\`e}', + 'é' => "{\'e}", + 'ê' => '{\^e}', + 'ë' => '{\"e}', + 'ì' => '{\`i}', + 'í' => "{\'i}", + 'î' => '{\^i}', + 'ï' => '{\"i}', + 'ñ' => '{\~n}', + 'ò' => '{\`o}', + 'ó' => "{\'o}", + 'ô' => '{\^o}', + 'õ' => '{\~o}', + 'ö' => '{\"o}', + 'ù' => '{\`u}', + 'ú' => "{\'u}", + 'û' => '{\^u}', + 'ü' => '{\"u}', + 'ÿ' => '{\"y}', + '"' => "''", + '\\' => '/', + '%' => '\%', + '$' => '\$', + '#' => '\#', + '&' => '\&', + '_' => '\_', + '^' => '', + ); + + if ($convertlinebreaks) + $translation["\n"] = "\\\\\n"; + + return strtr($text, $translation); +} + +} /* End class it_text */ + + +/* + * Globally available functions without need for object + */ + +/* + * Replaces variables of the form {obj.var} with value, e.g. {user.name} + * NOTE: Invalid object names or non-existing variables are simply deleted. + */ +function it_text_transmogrify($text, $values=array()) +{ + while (preg_match('/{([\w.]+)}/', $text, $regs)) + { + $path = explode('.', $regs[1]); + if ($values) + $value =& $values; + else + $value =& $GLOBALS; + + /* Recurse into nested arrays/object members */ + foreach ($path as $key) + { + if (is_object($value)) + $value =& $value->$key; + else + $value =& $value[$key]; + } + + $text = str_replace($regs[0], $value, $text); + } + + return $text; +} + + +/* + * Shortcut to $it_text->Text() + */ +function T($label, $raw=0, $language='') +{ + return $GLOBALS['it_text']->text($label, $raw, $language); +} + + +/* + * Shortcut to $it_text->etext() + */ +function ET($label, $values=null, $language='') +{ + return $GLOBALS['it_text']->etext($label, $values, $language); +} + +/** + * Shortcut to $it_text->get_language() + */ +function T_lang() +{ + return $GLOBALS['it_text']->get_language(); +} + +/** + * Shortcut to $it_text->get_language() + */ +function T_set_language($language, $setcookie=true) +{ + return $GLOBALS['it_text']->set_language($language, $setcookie); +} + +/** + * Shortcut to $it_text->text_exists() + */ +function T_exists($label) +{ + return $GLOBALS['it_text']->text_exists($label); +} +?> |