= $version; return browserDetect('Konqueror/'); } // MacOSX Safari has certain limitations. Need detection and patches. // * no , only function isBrowserSafari($version = false) { $found = browserDetect('Spoofer/'); $found = browserDetect('AppleWebKit/') or $found; if ($version) return $found and browserVersion() >= $version; return $found; } function isBrowserOpera($version = false) { if ($version) return browserDetect('Opera/') and browserVersion() >= $version; return browserDetect('Opera/'); } /** * If $LANG is undefined: * Smart client language detection, based on our supported languages * HTTP_ACCEPT_LANGUAGE="de-at,en;q=0.5" * => "de" * We should really check additionally if the i18n HomePage version is defined. * So must defer this to the request loop. */ function guessing_lang($languages = false) { if (!$languages) { // make this faster $languages = array("en", "de", "es", "fr", "it", "ja", "zh", "nl", "sv"); } $accept = false; if (isset($GLOBALS['request'])) // in fixup-dynamic-config there's no request yet $accept = $GLOBALS['request']->get('HTTP_ACCEPT_LANGUAGE'); elseif (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE']; if ($accept) { $lang_list = array(); $list = explode(",", $accept); for ($i = 0; $i < count($list); $i++) { $pos = strchr($list[$i], ";"); if ($pos === false) { // No Q it is only a locale... $lang_list[$list[$i]] = 100; } else { // Has a Q rating $q = explode(";", $list[$i]); $loc = $q[0]; $q = explode("=", $q[1]); $lang_list[$loc] = $q[1] * 100; } } // sort by q desc arsort($lang_list); // compare with languages, ignoring sublang and charset foreach ($lang_list as $lang => $q) { if (in_array($lang, $languages)) return $lang; // de_DE.iso8859-1@euro => de_DE.iso8859-1, de_DE, de // de-DE => de-DE, de foreach (array('@', '.', '_') as $sep) { if (($tail = strchr($lang, $sep))) { $lang_short = substr($lang, 0, -strlen($tail)); if (in_array($lang_short, $languages)) return $lang_short; } } if ($pos = strpos($lang, "-") and in_array(substr($lang, 0, $pos), $languages)) return substr($lang, 0, $pos); } } return $languages[0]; } /** * Smart setlocale(). * * This is a version of the builtin setlocale() which is * smart enough to try some alternatives... * * @param mixed $category * @param string $locale * @return string The new locale, or false if unable * to set the requested locale. * @see setlocale * [56ms] */ function guessing_setlocale($category, $locale) { $alt = array('en' => array('C', 'en_US', 'en_GB', 'en_AU', 'en_CA', 'english'), 'de' => array('de_DE', 'de_DE', 'de_DE@euro', 'de_AT@euro', 'de_AT', 'German_Austria.1252', 'deutsch', 'german', 'ge'), 'es' => array('es_ES', 'es_MX', 'es_AR', 'spanish'), 'nl' => array('nl_NL', 'dutch'), 'fr' => array('fr_FR', 'français', 'french'), 'it' => array('it_IT'), 'sv' => array('sv_SE'), 'ja.utf-8' => array('ja_JP', 'ja_JP.utf-8', 'japanese'), 'ja.euc-jp' => array('ja_JP', 'ja_JP.eucJP', 'japanese.euc'), 'zh' => array('zh_TW', 'zh_CN'), ); if (!$locale or $locale == 'C') { // do the reverse: return the detected locale collapsed to our LANG $locale = setlocale($category, ''); if ($locale) { if (strstr($locale, '_')) list ($lang) = explode('_', $locale); else $lang = $locale; if (strlen($lang) > 2) { foreach ($alt as $try => $locs) { if (in_array($locale, $locs) or in_array($lang, $locs)) { //if (empty($GLOBALS['LANG'])) $GLOBALS['LANG'] = $try; return $try; } } } } } if (strlen($locale) == 2) $lang = $locale; else list ($lang) = explode('_', $locale); if (!isset($alt[$lang])) return false; foreach ($alt[$lang] as $try) { if ($res = setlocale($category, $try)) return $res; // Try with charset appended... $try = $try . '.' . 'UTF-8'; if ($res = setlocale($category, $try)) return $res; foreach (array(".", '@', '_') as $sep) { if ($i = strpos($try, $sep)) { $try = substr($try, 0, $i); if (($res = setlocale($category, $try))) return $res; } } } return false; // A standard locale name is typically of the form // language[_territory][.codeset][@modifier], where language is // an ISO 639 language code, territory is an ISO 3166 country code, // and codeset is a character set or encoding identifier like // ISO-8859-1 or UTF-8. } // [99ms] function update_locale($loc) { if ($loc == 'C' or $loc == 'en') { return ''; } // $LANG or DEFAULT_LANGUAGE is too less information, at least on unix for // setlocale(), for bindtextdomain() to succeed. $setlocale = guessing_setlocale(LC_ALL, $loc); // [56ms] if (!$setlocale) { // system has no locale for this language, so gettext might fail $setlocale = FileFinder::_get_lang(); list ($setlocale,) = explode('_', $setlocale, 2); $setlocale = guessing_setlocale(LC_ALL, $setlocale); // try again if (!$setlocale) $setlocale = $loc; } // Try to put new locale into environment (so any // programs we run will get the right locale.) if (function_exists('bindtextdomain')) { // If PHP is in safe mode, this is not allowed, // so hide errors... @putenv("LC_ALL=$setlocale"); @putenv("LANG=$loc"); @putenv("LANGUAGE=$loc"); } // To get the POSIX character classes in the PCRE's (e.g. // [[:upper:]]) to match extended characters (e.g. GrüßGott), we have // to set the locale, using setlocale(). // // The problem is which locale to set? We would like to recognize all // upper-case characters in the iso-8859-1 character set as upper-case // characters --- not just the ones which are in the current $LANG. // // As it turns out, at least on my system (Linux/glibc-2.2) as long as // you setlocale() to anything but "C" it works fine. (I'm not sure // whether this is how it's supposed to be, or whether this is a bug // in the libc...) // // We don't currently use the locale setting for anything else, so for // now, just set the locale to US English. // // FIXME: Not all environments may support en_US? We should probably // have a list of locales to try. if (setlocale(LC_CTYPE, 0) == 'C') { $x = setlocale(LC_CTYPE, 'en_US.UTF-8'); } else { $x = setlocale(LC_CTYPE, $setlocale); } return $loc; } function deduce_script_name() { $s = &$_SERVER; $script = @$s['SCRIPT_NAME']; if (empty($script) or $script[0] != '/') { // Some places (e.g. Lycos) only supply a relative name in // SCRIPT_NAME, but give what we really want in SCRIPT_URL. if (!empty($s['SCRIPT_URL'])) $script = $s['SCRIPT_URL']; } return $script; } function IsProbablyRedirectToIndex() { // This might be a redirect to the DirectoryIndex, // e.g. REQUEST_URI = /dir/?some_action got redirected // to SCRIPT_NAME = /dir/index.php // In this case, the proper virtual path is still // $SCRIPT_NAME, since pages appear at // e.g. /dir/index.php/HomePage. $requri = preg_replace('/\?.*$/', '', $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI']); $requri = preg_quote($requri, '%'); return preg_match("%^${requri}[^/]*$%", $GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); } // needed < php5 // by bradhuizenga at softhome dot net from the php docs if (!function_exists('str_ireplace')) { function str_ireplace($find, $replace, $string) { if (!is_array($find)) $find = array($find); if (!is_array($replace)) { if (!is_array($find)) $replace = array($replace); else { // this will duplicate the string into an array the size of $find $c = count($find); $rString = $replace; unset($replace); for ($i = 0; $i < $c; $i++) { $replace[$i] = $rString; } } } foreach ($find as $fKey => $fItem) { $between = explode(strtolower($fItem), strtolower($string)); $pos = 0; foreach ($between as $bKey => $bItem) { $between[$bKey] = substr($string, $pos, strlen($bItem)); $pos += strlen($bItem) + strlen($fItem); } $string = implode($replace[$fKey], $between); } return ($string); } } // htmlspecialchars_decode exists for PHP >= 5.1 if (!function_exists('htmlspecialchars_decode')) { function htmlspecialchars_decode($text) { return strtr($text, array_flip(get_html_translation_table(HTML_SPECIALCHARS))); } } /** * safe php4 definition for clone. * php5 copies objects by reference, but we need to clone "deep copy" in some places. * (BlockParser) * We need to eval it as workaround for the php5 parser. * See http://www.acko.net/node/54 */ if (!check_php_version(5)) { eval(' function clone($object) { return $object; } '); } function getUploadFilePath() { if (defined('UPLOAD_FILE_PATH')) { // Force creation of the returned directory if it does not exist. if (!file_exists(UPLOAD_FILE_PATH)) { mkdir(UPLOAD_FILE_PATH, 0775, true); } if (string_ends_with(UPLOAD_FILE_PATH, "/") or string_ends_with(UPLOAD_FILE_PATH, "\\") ) { return UPLOAD_FILE_PATH; } else { return UPLOAD_FILE_PATH . "/"; } } return defined('PHPWIKI_DIR') ? PHPWIKI_DIR . "/uploads/" : realpath(dirname(__FILE__) . "/../uploads/"); } function getUploadDataPath() { if (defined('UPLOAD_DATA_PATH')) { return string_ends_with(UPLOAD_DATA_PATH, "/") ? UPLOAD_DATA_PATH : UPLOAD_DATA_PATH . "/"; } return SERVER_URL . (string_ends_with(DATA_PATH, "/") ? '' : "/") . DATA_PATH . '/uploads/'; } // Local Variables: // mode: php // tab-width: 8 // c-basic-offset: 4 // c-hanging-comment-ender-p: nil // indent-tabs-mode: nil // End: