From ca76395aba30cd07489fe49daadb3bb121f2c25f Mon Sep 17 00:00:00 2001 From: Peter Dias Date: Tue, 27 Apr 2021 13:15:29 +0800 Subject: [PATCH 1/4] MDL-53544 lib: Remove old Typo3 files --- lib/typo3/class.t3lib_cs.php | 2367 --- lib/typo3/class.t3lib_div.php | 5839 ------ lib/typo3/class.t3lib_l10n_locales.php | 285 - lib/typo3/class.t3lib_utility_debug.php | 387 - lib/typo3/csconvtbl/ascii.tbl | 0 lib/typo3/csconvtbl/big5.tbl | 13778 -------------- lib/typo3/csconvtbl/euc-kr.tbl | 17048 ----------------- lib/typo3/csconvtbl/gb2312.tbl | 21792 ---------------------- lib/typo3/csconvtbl/iso-8859-1.tbl | 96 - lib/typo3/csconvtbl/iso-8859-10.tbl | 303 - lib/typo3/csconvtbl/iso-8859-11.tbl | 87 - lib/typo3/csconvtbl/iso-8859-13.tbl | 299 - lib/typo3/csconvtbl/iso-8859-14.tbl | 301 - lib/typo3/csconvtbl/iso-8859-15.tbl | 96 - lib/typo3/csconvtbl/iso-8859-16.tbl | 299 - lib/typo3/csconvtbl/iso-8859-2.tbl | 96 - lib/typo3/csconvtbl/iso-8859-3.tbl | 89 - lib/typo3/csconvtbl/iso-8859-4.tbl | 96 - lib/typo3/csconvtbl/iso-8859-5.tbl | 96 - lib/typo3/csconvtbl/iso-8859-6.tbl | 51 - lib/typo3/csconvtbl/iso-8859-7.tbl | 90 - lib/typo3/csconvtbl/iso-8859-8.tbl | 58 - lib/typo3/csconvtbl/iso-8859-9.tbl | 96 - lib/typo3/csconvtbl/koi8-r.tbl | 302 - lib/typo3/csconvtbl/readme.txt | 187 - lib/typo3/csconvtbl/shift_jis.tbl | 7915 -------- lib/typo3/csconvtbl/windows-1250.tbl | 123 - lib/typo3/csconvtbl/windows-1251.tbl | 127 - lib/typo3/csconvtbl/windows-1252.tbl | 123 - lib/typo3/csconvtbl/windows-1253.tbl | 111 - lib/typo3/csconvtbl/windows-1254.tbl | 121 - lib/typo3/csconvtbl/windows-1255.tbl | 105 - lib/typo3/csconvtbl/windows-1256.tbl | 128 - lib/typo3/csconvtbl/windows-1257.tbl | 116 - lib/typo3/csconvtbl/windows-1258.tbl | 119 - lib/typo3/csconvtbl/windows-874.tbl | 97 - lib/typo3/interface.t3lib_singleton.php | 40 - lib/typo3/readme_moodle.txt | 30 - lib/typo3/unidata/SpecialCasing.txt | 256 - lib/typo3/unidata/Translit.txt | 310 - lib/typo3/unidata/UnicodeData.txt | 19336 ------------------- 41 files changed, 93195 deletions(-) delete mode 100644 lib/typo3/class.t3lib_cs.php delete mode 100644 lib/typo3/class.t3lib_div.php delete mode 100644 lib/typo3/class.t3lib_l10n_locales.php delete mode 100644 lib/typo3/class.t3lib_utility_debug.php delete mode 100644 lib/typo3/csconvtbl/ascii.tbl delete mode 100644 lib/typo3/csconvtbl/big5.tbl delete mode 100644 lib/typo3/csconvtbl/euc-kr.tbl delete mode 100644 lib/typo3/csconvtbl/gb2312.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-1.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-10.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-11.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-13.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-14.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-15.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-16.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-2.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-3.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-4.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-5.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-6.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-7.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-8.tbl delete mode 100644 lib/typo3/csconvtbl/iso-8859-9.tbl delete mode 100644 lib/typo3/csconvtbl/koi8-r.tbl delete mode 100644 lib/typo3/csconvtbl/readme.txt delete mode 100644 lib/typo3/csconvtbl/shift_jis.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1250.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1251.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1252.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1253.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1254.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1255.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1256.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1257.tbl delete mode 100644 lib/typo3/csconvtbl/windows-1258.tbl delete mode 100644 lib/typo3/csconvtbl/windows-874.tbl delete mode 100644 lib/typo3/interface.t3lib_singleton.php delete mode 100644 lib/typo3/readme_moodle.txt delete mode 100644 lib/typo3/unidata/SpecialCasing.txt delete mode 100644 lib/typo3/unidata/Translit.txt delete mode 100644 lib/typo3/unidata/UnicodeData.txt diff --git a/lib/typo3/class.t3lib_cs.php b/lib/typo3/class.t3lib_cs.php deleted file mode 100644 index d22acf6617b..00000000000 --- a/lib/typo3/class.t3lib_cs.php +++ /dev/null @@ -1,2367 +0,0 @@ - - * @author Martin Kutschker - */ - - -/** - * Notes on UTF-8 - * - * Functions working on UTF-8 strings: - * - * - strchr/strstr - * - strrchr - * - substr_count - * - implode/explode/join - * - * Functions nearly working on UTF-8 strings: - * - * - strlen: returns the length in BYTES, if you need the length in CHARACTERS use utf8_strlen - * - trim/ltrim/rtrim: the second parameter 'charlist' won't work for characters not contained in 7-bit ASCII - * - strpos/strrpos: they return the BYTE position, if you need the CHARACTER position use utf8_strpos/utf8_strrpos - * - htmlentities: charset support for UTF-8 only since PHP 4.3.0 - * - preg_*: Support compiled into PHP by default nowadays, but could be unavailable, need to use modifier - * - * Functions NOT working on UTF-8 strings: - * - * - str*cmp - * - stristr - * - stripos - * - substr - * - strrev - * - split/spliti - * - ... - * - */ -/** - * Class for conversion between charsets - * - * @author Kasper Skårhøj - * @author Martin Kutschker - * @package TYPO3 - * @subpackage t3lib - */ -class t3lib_cs { - - /** - * @var t3lib_l10n_Locales - */ - protected $locales; - - var $noCharByteVal = 63; // ASCII Value for chars with no equivalent. - - // This is the array where parsed conversion tables are stored (cached) - var $parsedCharsets = array(); - - // An array where case folding data will be stored (cached) - var $caseFolding = array(); - - // An array where charset-to-ASCII mappings are stored (cached) - var $toASCII = array(); - - // This tells the converter which charsets has two bytes per char: - var $twoByteSets = array( - 'ucs-2' => 1, // 2-byte Unicode - ); - - // This tells the converter which charsets has four bytes per char: - var $fourByteSets = array( - 'ucs-4' => 1, // 4-byte Unicode - 'utf-32' => 1, // 4-byte Unicode (limited to the 21-bits of UTF-16) - ); - - // This tells the converter which charsets use a scheme like the Extended Unix Code: - var $eucBasedSets = array( - 'gb2312' => 1, // Chinese, simplified. - 'big5' => 1, // Chinese, traditional. - 'euc-kr' => 1, // Korean - 'shift_jis' => 1, // Japanese - WARNING: Shift-JIS includes half-width katakana single-bytes characters above 0x80! - ); - - // see http://developer.apple.com/documentation/macos8/TextIntlSvcs/TextEncodingConversionManager/TEC1.5/TEC.b0.html - // http://czyborra.com/charsets/iso8859.html - var $synonyms = array( - 'us' => 'ascii', - 'us-ascii' => 'ascii', - 'cp819' => 'iso-8859-1', - 'ibm819' => 'iso-8859-1', - 'iso-ir-100' => 'iso-8859-1', - 'iso-ir-101' => 'iso-8859-2', - 'iso-ir-109' => 'iso-8859-3', - 'iso-ir-110' => 'iso-8859-4', - 'iso-ir-144' => 'iso-8859-5', - 'iso-ir-127' => 'iso-8859-6', - 'iso-ir-126' => 'iso-8859-7', - 'iso-ir-138' => 'iso-8859-8', - 'iso-ir-148' => 'iso-8859-9', - 'iso-ir-157' => 'iso-8859-10', - 'iso-ir-179' => 'iso-8859-13', - 'iso-ir-199' => 'iso-8859-14', - 'iso-ir-203' => 'iso-8859-15', - 'csisolatin1' => 'iso-8859-1', - 'csisolatin2' => 'iso-8859-2', - 'csisolatin3' => 'iso-8859-3', - 'csisolatin5' => 'iso-8859-9', - 'csisolatin8' => 'iso-8859-14', - 'csisolatin9' => 'iso-8859-15', - 'csisolatingreek' => 'iso-8859-7', - 'iso-celtic' => 'iso-8859-14', - 'latin1' => 'iso-8859-1', - 'latin2' => 'iso-8859-2', - 'latin3' => 'iso-8859-3', - 'latin5' => 'iso-8859-9', - 'latin6' => 'iso-8859-10', - 'latin8' => 'iso-8859-14', - 'latin9' => 'iso-8859-15', - 'l1' => 'iso-8859-1', - 'l2' => 'iso-8859-2', - 'l3' => 'iso-8859-3', - 'l5' => 'iso-8859-9', - 'l6' => 'iso-8859-10', - 'l8' => 'iso-8859-14', - 'l9' => 'iso-8859-15', - 'cyrillic' => 'iso-8859-5', - 'arabic' => 'iso-8859-6', - 'tis-620' => 'iso-8859-11', - 'win874' => 'windows-874', - 'win1250' => 'windows-1250', - 'win1251' => 'windows-1251', - 'win1252' => 'windows-1252', - 'win1253' => 'windows-1253', - 'win1254' => 'windows-1254', - 'win1255' => 'windows-1255', - 'win1256' => 'windows-1256', - 'win1257' => 'windows-1257', - 'win1258' => 'windows-1258', - 'cp1250' => 'windows-1250', - 'cp1251' => 'windows-1251', - 'cp1252' => 'windows-1252', - 'ms-ee' => 'windows-1250', - 'ms-ansi' => 'windows-1252', - 'ms-greek' => 'windows-1253', - 'ms-turk' => 'windows-1254', - 'winbaltrim' => 'windows-1257', - 'koi-8ru' => 'koi-8r', - 'koi8r' => 'koi-8r', - 'cp878' => 'koi-8r', - 'mac' => 'macroman', - 'macintosh' => 'macroman', - 'euc-cn' => 'gb2312', - 'x-euc-cn' => 'gb2312', - 'euccn' => 'gb2312', - 'cp936' => 'gb2312', - 'big-5' => 'big5', - 'cp950' => 'big5', - 'eucjp' => 'euc-jp', - 'sjis' => 'shift_jis', - 'shift-jis' => 'shift_jis', - 'cp932' => 'shift_jis', - 'cp949' => 'euc-kr', - 'utf7' => 'utf-7', - 'utf8' => 'utf-8', - 'utf16' => 'utf-16', - 'utf32' => 'utf-32', - 'utf8' => 'utf-8', - 'ucs2' => 'ucs-2', - 'ucs4' => 'ucs-4', - ); - - // mapping of iso-639-1 language codes to script names - var $lang_to_script = array( - // iso-639-1 language codes, see http://www.loc.gov/standards/iso639-2/php/code_list.php - 'af' => 'west_european', //Afrikaans - 'ar' => 'arabic', - 'bg' => 'cyrillic', // Bulgarian - 'bs' => 'east_european', // Bosnian - 'cs' => 'east_european', // Czech - 'da' => 'west_european', // Danish - 'de' => 'west_european', // German - 'es' => 'west_european', // Spanish - 'et' => 'estonian', - 'eo' => 'unicode', // Esperanto - 'eu' => 'west_european', // Basque - 'fa' => 'arabic', // Persian - 'fi' => 'west_european', // Finish - 'fo' => 'west_european', // Faroese - 'fr' => 'west_european', // French - 'ga' => 'west_european', // Irish - 'gl' => 'west_european', // Galician - 'gr' => 'greek', - 'he' => 'hebrew', // Hebrew (since 1998) - 'hi' => 'unicode', // Hindi - 'hr' => 'east_european', // Croatian - 'hu' => 'east_european', // Hungarian - 'iw' => 'hebrew', // Hebrew (til 1998) - 'is' => 'west_european', // Icelandic - 'it' => 'west_european', // Italian - 'ja' => 'japanese', - 'ka' => 'unicode', // Georgian - 'kl' => 'west_european', // Greenlandic - 'km' => 'unicode', // Khmer - 'ko' => 'korean', - 'lt' => 'lithuanian', - 'lv' => 'west_european', // Latvian/Lettish - 'nl' => 'west_european', // Dutch - 'no' => 'west_european', // Norwegian - 'nb' => 'west_european', // Norwegian Bokmal - 'nn' => 'west_european', // Norwegian Nynorsk - 'pl' => 'east_european', // Polish - 'pt' => 'west_european', // Portuguese - 'ro' => 'east_european', // Romanian - 'ru' => 'cyrillic', // Russian - 'sk' => 'east_european', // Slovak - 'sl' => 'east_european', // Slovenian - 'sr' => 'cyrillic', // Serbian - 'sv' => 'west_european', // Swedish - 'sq' => 'albanian', // Albanian - 'th' => 'thai', - 'uk' => 'cyrillic', // Ukranian - 'vi' => 'vietnamese', - 'zh' => 'chinese', - // MS language codes, see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_language_strings.asp - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceinternational5/html/wce50conLanguageIdentifiersandLocales.asp - 'afk'=> 'west_european', // Afrikaans - 'ara' => 'arabic', - 'bgr' => 'cyrillic', // Bulgarian - 'cat' => 'west_european', // Catalan - 'chs' => 'simpl_chinese', - 'cht' => 'trad_chinese', - 'csy' => 'east_european', // Czech - 'dan' => 'west_european', // Danisch - 'deu' => 'west_european', // German - 'dea' => 'west_european', // German (Austrian) - 'des' => 'west_european', // German (Swiss) - 'ena' => 'west_european', // English (Australian) - 'enc' => 'west_european', // English (Canadian) - 'eng' => 'west_european', // English - 'enz' => 'west_european', // English (New Zealand) - 'enu' => 'west_european', // English (United States) - 'euq' => 'west_european', // Basque - 'fos' => 'west_european', // Faroese - 'far' => 'arabic', // Persian - 'fin' => 'west_european', // Finish - 'fra' => 'west_european', // French - 'frb' => 'west_european', // French (Belgian) - 'frc' => 'west_european', // French (Canadian) - 'frs' => 'west_european', // French (Swiss) - 'geo' => 'unicode', // Georgian - 'glg' => 'west_european', // Galician - 'ell' => 'greek', - 'heb' => 'hebrew', - 'hin' => 'unicode', // Hindi - 'hun' => 'east_european', // Hungarian - 'isl' => 'west_euorpean', // Icelandic - 'ita' => 'west_european', // Italian - 'its' => 'west_european', // Italian (Swiss) - 'jpn' => 'japanese', - 'khm' => 'unicode', // Khmer - 'kor' => 'korean', - 'lth' => 'lithuanian', - 'lvi' => 'west_european', // Latvian/Lettish - 'msl' => 'west_european', // Malay - 'nlb' => 'west_european', // Dutch (Belgian) - 'nld' => 'west_european', // Dutch - 'nor' => 'west_european', // Norwegian (bokmal) - 'non' => 'west_european', // Norwegian (nynorsk) - 'plk' => 'east_european', // Polish - 'ptg' => 'west_european', // Portuguese - 'ptb' => 'west_european', // Portuguese (Brazil) - 'rom' => 'east_european', // Romanian - 'rus' => 'cyrillic', // Russian - 'slv' => 'east_european', // Slovenian - 'sky' => 'east_european', // Slovak - 'srl' => 'east_european', // Serbian (Latin) - 'srb' => 'cyrillic', // Serbian (Cyrillic) - 'esp' => 'west_european', // Spanish (trad. sort) - 'esm' => 'west_european', // Spanish (Mexican) - 'esn' => 'west_european', // Spanish (internat. sort) - 'sve' => 'west_european', // Swedish - 'sqi' => 'albanian', // Albanian - 'tha' => 'thai', - 'trk' => 'turkish', - 'ukr' => 'cyrillic', // Ukrainian - // English language names - 'afrikaans' => 'west_european', - 'albanian' => 'albanian', - 'arabic' => 'arabic', - 'basque' => 'west_european', - 'bosnian' => 'east_european', - 'bulgarian' => 'east_european', - 'catalan' => 'west_european', - 'croatian' => 'east_european', - 'czech' => 'east_european', - 'danish' => 'west_european', - 'dutch' => 'west_european', - 'english' => 'west_european', - 'esperanto' => 'unicode', - 'estonian' => 'estonian', - 'faroese' => 'west_european', - 'farsi' => 'arabic', - 'finnish' => 'west_european', - 'french' => 'west_european', - 'galician' => 'west_european', - 'georgian' => 'unicode', - 'german' => 'west_european', - 'greek' => 'greek', - 'greenlandic' => 'west_european', - 'hebrew' => 'hebrew', - 'hindi' => 'unicode', - 'hungarian' => 'east_european', - 'icelandic' => 'west_european', - 'italian' => 'west_european', - 'khmer' => 'unicode', - 'latvian' => 'west_european', - 'lettish' => 'west_european', - 'lithuanian' => 'lithuanian', - 'malay' => 'west_european', - 'norwegian' => 'west_european', - 'persian' => 'arabic', - 'polish' => 'east_european', - 'portuguese' => 'west_european', - 'russian' => 'cyrillic', - 'romanian' => 'east_european', - 'serbian' => 'cyrillic', - 'slovak' => 'east_european', - 'slovenian' => 'east_european', - 'spanish' => 'west_european', - 'svedish' => 'west_european', - 'that' => 'thai', - 'turkish' => 'turkish', - 'ukrainian' => 'cyrillic', - ); - - // mapping of language (family) names to charsets on Unix - var $script_to_charset_unix = array( - 'west_european' => 'iso-8859-1', - 'estonian' => 'iso-8859-1', - 'east_european' => 'iso-8859-2', - 'baltic' => 'iso-8859-4', - 'cyrillic' => 'iso-8859-5', - 'arabic' => 'iso-8859-6', - 'greek' => 'iso-8859-7', - 'hebrew' => 'iso-8859-8', - 'turkish' => 'iso-8859-9', - 'thai' => 'iso-8859-11', // = TIS-620 - 'lithuanian' => 'iso-8859-13', - 'chinese' => 'gb2312', // = euc-cn - 'japanese' => 'euc-jp', - 'korean' => 'euc-kr', - 'simpl_chinese' => 'gb2312', - 'trad_chinese' => 'big5', - 'vietnamese' => '', - 'unicode' => 'utf-8', - 'albanian' => 'utf-8' - ); - - // mapping of language (family) names to charsets on Windows - var $script_to_charset_windows = array( - 'east_european' => 'windows-1250', - 'cyrillic' => 'windows-1251', - 'west_european' => 'windows-1252', - 'greek' => 'windows-1253', - 'turkish' => 'windows-1254', - 'hebrew' => 'windows-1255', - 'arabic' => 'windows-1256', - 'baltic' => 'windows-1257', - 'estonian' => 'windows-1257', - 'lithuanian' => 'windows-1257', - 'vietnamese' => 'windows-1258', - 'thai' => 'cp874', - 'korean' => 'cp949', - 'chinese' => 'gb2312', - 'japanese' => 'shift_jis', - 'simpl_chinese' => 'gb2312', - 'trad_chinese' => 'big5', - 'albanian' => 'windows-1250', - 'unicode' => 'utf-8' - ); - - // mapping of locale names to charsets - var $locale_to_charset = array( - 'japanese.euc' => 'euc-jp', - 'ja_jp.ujis' => 'euc-jp', - 'korean.euc' => 'euc-kr', - 'sr@Latn' => 'iso-8859-2', - 'zh_cn' => 'gb2312', - 'zh_hk' => 'big5', - 'zh_tw' => 'big5', - ); - - // TYPO3 specific: Array with the system charsets used for each system language in TYPO3: - // Empty values means "iso-8859-1" - var $charSetArray = array( - 'af' => '', - 'ar' => 'iso-8859-6', - 'ba' => 'iso-8859-2', - 'bg' => 'windows-1251', - 'br' => '', - 'ca' => 'iso-8859-15', - 'ch' => 'gb2312', - 'cs' => 'windows-1250', - 'cz' => 'windows-1250', - 'da' => '', - 'de' => '', - 'dk' => '', - 'el' => 'iso-8859-7', - 'eo' => 'utf-8', - 'es' => '', - 'et' => 'iso-8859-4', - 'eu' => '', - 'fa' => 'utf-8', - 'fi' => '', - 'fo' => 'utf-8', - 'fr' => '', - 'fr_CA' => '', - 'ga' => '', - 'ge' => 'utf-8', - 'gl' => '', - 'gr' => 'iso-8859-7', - 'he' => 'utf-8', - 'hi' => 'utf-8', - 'hk' => 'big5', - 'hr' => 'windows-1250', - 'hu' => 'iso-8859-2', - 'is' => 'utf-8', - 'it' => '', - 'ja' => 'shift_jis', - 'jp' => 'shift_jis', - 'ka' => 'utf-8', - 'kl' => 'utf-8', - 'km' => 'utf-8', - 'ko' => 'euc-kr', - 'kr' => 'euc-kr', - 'lt' => 'windows-1257', - 'lv' => 'utf-8', - 'ms' => '', - 'my' => '', - 'nl' => '', - 'no' => '', - 'pl' => 'iso-8859-2', - 'pt' => '', - 'pt_BR' => '', - 'qc' => '', - 'ro' => 'iso-8859-2', - 'ru' => 'windows-1251', - 'se' => '', - 'si' => 'windows-1250', - 'sk' => 'windows-1250', - 'sl' => 'windows-1250', - 'sq' => 'utf-8', - 'sr' => 'utf-8', - 'sv' => '', - 'th' => 'iso-8859-11', - 'tr' => 'iso-8859-9', - 'ua' => 'windows-1251', - 'uk' => 'windows-1251', - 'vi' => 'utf-8', - 'vn' => 'utf-8', - 'zh' => 'big5', - ); - - // TYPO3 specific: Array with the iso names used for each system language in TYPO3: - // Missing keys means: same as TYPO3 - // @deprecated since TYPO3 4.6, will be removed in TYPO3 6.0 - use t3lib_l10n_Locales::getIsoMapping() - var $isoArray = array( - 'ba' => 'bs', - 'br' => 'pt_BR', - 'ch' => 'zh_CN', - 'cz' => 'cs', - 'dk' => 'da', - 'si' => 'sl', - 'se' => 'sv', - 'gl' => 'kl', - 'gr' => 'el', - 'hk' => 'zh_HK', - 'kr' => 'ko', - 'ua' => 'uk', - 'jp' => 'ja', - 'qc' => 'fr_CA', - 'vn' => 'vi', - 'ge' => 'ka', - 'ga' => 'gl', - ); - - /** - * Default constructor. - */ - public function __construct() { - $this->locales = t3lib_div::makeInstance('t3lib_l10n_Locales'); - } - - /** - * Normalize - changes input character set to lowercase letters. - * - * @param string Input charset - * @return string Normalized charset - * @author Martin Kutschker - */ - function parse_charset($charset) { - $charset = trim(strtolower($charset)); - if (isset($this->synonyms[$charset])) { - $charset = $this->synonyms[$charset]; - } - - return $charset; - } - - /** - * Get the charset of a locale. - * - * ln language - * ln_CN language / country - * ln_CN.cs language / country / charset - * ln_CN.cs@mod language / country / charset / modifier - * - * @param string Locale string - * @return string Charset resolved for locale string - * @author Martin Kutschker - */ - function get_locale_charset($locale) { - $locale = strtolower($locale); - - // exact locale specific charset? - if (isset($this->locale_to_charset[$locale])) { - return $this->locale_to_charset[$locale]; - } - - // get modifier - list($locale, $modifier) = explode('@', $locale); - - // locale contains charset: use it - list($locale, $charset) = explode('.', $locale); - if ($charset) { - return $this->parse_charset($charset); - } - - // modifier is 'euro' (after charset check, because of xx.utf-8@euro) - if ($modifier == 'euro') { - return 'iso-8859-15'; - } - - // get language - list($language, $country) = explode('_', $locale); - if (isset($this->lang_to_script[$language])) { - $script = $this->lang_to_script[$language]; - } - - if (TYPO3_OS == 'WIN') { - $cs = $this->script_to_charset_windows[$script] ? $this->script_to_charset_windows[$script] : 'windows-1252'; - } else { - $cs = $this->script_to_charset_unix[$script] ? $this->script_to_charset_unix[$script] : 'utf-8'; - } - - return $cs; - } - - - /******************************************** - * - * Charset Conversion functions - * - ********************************************/ - - /** - * Convert from one charset to another charset. - * - * @param string Input string - * @param string From charset (the current charset of the string) - * @param string To charset (the output charset wanted) - * @param boolean If set, then characters that are not available in the destination character set will be encoded as numeric entities - * @return string Converted string - * @see convArray() - */ - function conv($str, $fromCS, $toCS, $useEntityForNoChar = 0) { - if ($fromCS == $toCS) { - return $str; - } - - // PHP-libs don't support fallback to SGML entities, but UTF-8 handles everything - if ($toCS == 'utf-8' || !$useEntityForNoChar) { - switch ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_convMethod']) { - case 'mbstring': - $conv_str = mb_convert_encoding($str, $toCS, $fromCS); - if (FALSE !== $conv_str) { - return $conv_str; - } // returns FALSE for unsupported charsets - break; - - case 'iconv': - $conv_str = iconv($fromCS, $toCS . '//TRANSLIT', $str); - if (FALSE !== $conv_str) { - return $conv_str; - } - break; - - case 'recode': - $conv_str = recode_string($fromCS . '..' . $toCS, $str); - if (FALSE !== $conv_str) { - return $conv_str; - } - break; - } - // fallback to TYPO3 conversion - } - - if ($fromCS != 'utf-8') { - $str = $this->utf8_encode($str, $fromCS); - } - if ($toCS != 'utf-8') { - $str = $this->utf8_decode($str, $toCS, $useEntityForNoChar); - } - return $str; - } - - /** - * Convert all elements in ARRAY with type string from one charset to another charset. - * NOTICE: Array is passed by reference! - * - * @param string Input array, possibly multidimensional - * @param string From charset (the current charset of the string) - * @param string To charset (the output charset wanted) - * @param boolean If set, then characters that are not available in the destination character set will be encoded as numeric entities - * @return void - * @see conv() - */ - function convArray(&$array, $fromCS, $toCS, $useEntityForNoChar = 0) { - foreach ($array as $key => $value) { - if (is_array($array[$key])) { - $this->convArray($array[$key], $fromCS, $toCS, $useEntityForNoChar); - } elseif (is_string($array[$key])) { - $array[$key] = $this->conv($array[$key], $fromCS, $toCS, $useEntityForNoChar); - } - } - } - - /** - * Converts $str from $charset to UTF-8 - * - * @param string String in local charset to convert to UTF-8 - * @param string Charset, lowercase. Must be found in csconvtbl/ folder. - * @return string Output string, converted to UTF-8 - */ - function utf8_encode($str, $charset) { - - if ($charset === 'utf-8') { - return $str; - } - - // Charset is case-insensitive. - if ($this->initCharset($charset)) { // Parse conv. table if not already... - $strLen = strlen($str); - $outStr = ''; - - for ($a = 0; $a < $strLen; $a++) { // Traverse each char in string. - $chr = substr($str, $a, 1); - $ord = ord($chr); - if (isset($this->twoByteSets[$charset])) { // If the charset has two bytes per char - $ord2 = ord($str[$a + 1]); - $ord = $ord << 8 | $ord2; // assume big endian - - if (isset($this->parsedCharsets[$charset]['local'][$ord])) { // If the local char-number was found in parsed conv. table then we use that, otherwise 127 (no char?) - $outStr .= $this->parsedCharsets[$charset]['local'][$ord]; - } else { - $outStr .= chr($this->noCharByteVal); - } // No char exists - $a++; - } elseif ($ord > 127) { // If char has value over 127 it's a multibyte char in UTF-8 - if (isset($this->eucBasedSets[$charset])) { // EUC uses two-bytes above 127; we get both and advance pointer and make $ord a 16bit int. - if ($charset != 'shift_jis' || ($ord < 0xA0 || $ord > 0xDF)) { // Shift-JIS: chars between 160 and 223 are single byte - $a++; - $ord2 = ord(substr($str, $a, 1)); - $ord = $ord * 256 + $ord2; - } - } - - if (isset($this->parsedCharsets[$charset]['local'][$ord])) { // If the local char-number was found in parsed conv. table then we use that, otherwise 127 (no char?) - $outStr .= $this->parsedCharsets[$charset]['local'][$ord]; - } else { - $outStr .= chr($this->noCharByteVal); - } // No char exists - } else { - $outStr .= $chr; - } // ... otherwise it's just ASCII 0-127 and one byte. Transparent - } - return $outStr; - } - } - - /** - * Converts $str from UTF-8 to $charset - * - * @param string String in UTF-8 to convert to local charset - * @param string Charset, lowercase. Must be found in csconvtbl/ folder. - * @param boolean If set, then characters that are not available in the destination character set will be encoded as numeric entities - * @return string Output string, converted to local charset - */ - function utf8_decode($str, $charset, $useEntityForNoChar = 0) { - - if ($charset === 'utf-8') { - return $str; - } - - // Charset is case-insensitive. - if ($this->initCharset($charset)) { // Parse conv. table if not already... - $strLen = strlen($str); - $outStr = ''; - $buf = ''; - for ($a = 0, $i = 0; $a < $strLen; $a++, $i++) { // Traverse each char in UTF-8 string. - $chr = substr($str, $a, 1); - $ord = ord($chr); - if ($ord > 127) { // This means multibyte! (first byte!) - if ($ord & 64) { // Since the first byte must have the 7th bit set we check that. Otherwise we might be in the middle of a byte sequence. - - $buf = $chr; // Add first byte - for ($b = 0; $b < 8; $b++) { // for each byte in multibyte string... - $ord = $ord << 1; // Shift it left and ... - if ($ord & 128) { // ... and with 8th bit - if that is set, then there are still bytes in sequence. - $a++; // Increase pointer... - $buf .= substr($str, $a, 1); // ... and add the next char. - } else { - break; - } - } - - if (isset($this->parsedCharsets[$charset]['utf8'][$buf])) { // If the UTF-8 char-sequence is found then... - $mByte = $this->parsedCharsets[$charset]['utf8'][$buf]; // The local number - if ($mByte > 255) { // If the local number is greater than 255 we will need to split the byte (16bit word assumed) in two chars. - $outStr .= chr(($mByte >> 8) & 255) . chr($mByte & 255); - } else { - $outStr .= chr($mByte); - } - } elseif ($useEntityForNoChar) { // Create num entity: - $outStr .= '&#' . $this->utf8CharToUnumber($buf, 1) . ';'; - } else { - $outStr .= chr($this->noCharByteVal); - } // No char exists - } else { - $outStr .= chr($this->noCharByteVal); - } // No char exists (MIDDLE of MB sequence!) - } else { - $outStr .= $chr; - } // ... otherwise it's just ASCII 0-127 and one byte. Transparent - } - return $outStr; - } - } - - /** - * Converts all chars > 127 to numeric entities. - * - * @param string Input string - * @return string Output string - */ - function utf8_to_entities($str) { - $strLen = strlen($str); - $outStr = ''; - $buf = ''; - for ($a = 0; $a < $strLen; $a++) { // Traverse each char in UTF-8 string. - $chr = substr($str, $a, 1); - $ord = ord($chr); - if ($ord > 127) { // This means multibyte! (first byte!) - if ($ord & 64) { // Since the first byte must have the 7th bit set we check that. Otherwise we might be in the middle of a byte sequence. - $buf = $chr; // Add first byte - for ($b = 0; $b < 8; $b++) { // for each byte in multibyte string... - $ord = $ord << 1; // Shift it left and ... - if ($ord & 128) { // ... and with 8th bit - if that is set, then there are still bytes in sequence. - $a++; // Increase pointer... - $buf .= substr($str, $a, 1); // ... and add the next char. - } else { - break; - } - } - - $outStr .= '&#' . $this->utf8CharToUnumber($buf, 1) . ';'; - } else { - $outStr .= chr($this->noCharByteVal); - } // No char exists (MIDDLE of MB sequence!) - } else { - $outStr .= $chr; - } // ... otherwise it's just ASCII 0-127 and one byte. Transparent - } - - return $outStr; - } - - /** - * Converts numeric entities (UNICODE, eg. decimal (Ӓ) or hexadecimal ()) to UTF-8 multibyte chars - * - * @param string Input string, UTF-8 - * @param boolean If set, then all string-HTML entities (like & or £ will be converted as well) - * @return string Output string - */ - function entities_to_utf8($str, $alsoStdHtmlEnt = FALSE) { - // Workaround for #39287: 3rd parameter for get_html_translation_table() was only added in PHP 5.3.4 and later - // see http://php.net/manual/en/function.get-html-translation-table.php - $applyPhpCompatibilityFix = version_compare(phpversion(), '5.3.4', '<'); - - if ($alsoStdHtmlEnt) { - if ($applyPhpCompatibilityFix === TRUE) { - $trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES, ENT_COMPAT)); - } else { - $trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES, ENT_COMPAT, 'UTF-8')); - } - } - - $token = md5(microtime()); - $parts = explode($token, preg_replace('/(&([#[:alnum:]]*);)/', $token . '${2}' . $token, $str)); - foreach ($parts as $k => $v) { - // only take every second element - if ($k % 2 === 0) { - continue; - } - - $position = 0; - if (substr($v, $position, 1) == '#') { // Dec or hex entities: - $position++; - if (substr($v, $position, 1) == 'x') { - $v = hexdec(substr($v, ++$position)); - } else { - $v = substr($v, $position); - } - $parts[$k] = $this->UnumberToChar($v); - } elseif ($alsoStdHtmlEnt && isset($trans_tbl['&' . $v . ';'])) { // Other entities: - $v = $trans_tbl['&' . $v . ';']; - if ($applyPhpCompatibilityFix === TRUE) { - $v = $this->utf8_encode($v, 'iso-8859-1'); - } - $parts[$k] = $v; - } else { // No conversion: - $parts[$k] = '&' . $v . ';'; - } - } - - return implode('', $parts); - } - - /** - * Converts all chars in the input UTF-8 string into integer numbers returned in an array - * - * @param string Input string, UTF-8 - * @param boolean If set, then all HTML entities (like & or £ or { or 㽝) will be detected as characters. - * @param boolean If set, then instead of integer numbers the real UTF-8 char is returned. - * @return array Output array with the char numbers - */ - function utf8_to_numberarray($str, $convEntities = 0, $retChar = 0) { - // If entities must be registered as well...: - if ($convEntities) { - $str = $this->entities_to_utf8($str, 1); - } - // Do conversion: - $strLen = strlen($str); - $outArr = array(); - $buf = ''; - for ($a = 0; $a < $strLen; $a++) { // Traverse each char in UTF-8 string. - $chr = substr($str, $a, 1); - $ord = ord($chr); - if ($ord > 127) { // This means multibyte! (first byte!) - if ($ord & 64) { // Since the first byte must have the 7th bit set we check that. Otherwise we might be in the middle of a byte sequence. - $buf = $chr; // Add first byte - for ($b = 0; $b < 8; $b++) { // for each byte in multibyte string... - $ord = $ord << 1; // Shift it left and ... - if ($ord & 128) { // ... and with 8th bit - if that is set, then there are still bytes in sequence. - $a++; // Increase pointer... - $buf .= substr($str, $a, 1); // ... and add the next char. - } else { - break; - } - } - - $outArr[] = $retChar ? $buf : $this->utf8CharToUnumber($buf); - } else { - $outArr[] = $retChar ? chr($this->noCharByteVal) : $this->noCharByteVal; - } // No char exists (MIDDLE of MB sequence!) - } else { - $outArr[] = $retChar ? chr($ord) : $ord; - } // ... otherwise it's just ASCII 0-127 and one byte. Transparent - } - - return $outArr; - } - - /** - * Converts a UNICODE number to a UTF-8 multibyte character - * Algorithm based on script found at From: http://czyborra.com/utf/ - * Unit-tested by Kasper - * - * The binary representation of the character's integer value is thus simply spread across the bytes and the number of high bits set in the lead byte announces the number of bytes in the multibyte sequence: - * - * bytes | bits | representation - * 1 | 7 | 0vvvvvvv - * 2 | 11 | 110vvvvv 10vvvvvv - * 3 | 16 | 1110vvvv 10vvvvvv 10vvvvvv - * 4 | 21 | 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv - * 5 | 26 | 111110vv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv - * 6 | 31 | 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv - * - * @param integer UNICODE integer - * @return string UTF-8 multibyte character string - * @see utf8CharToUnumber() - */ - function UnumberToChar($cbyte) { - $str = ''; - - if ($cbyte < 0x80) { - $str .= chr($cbyte); - } else { - if ($cbyte < 0x800) { - $str .= chr(0xC0 | ($cbyte >> 6)); - $str .= chr(0x80 | ($cbyte & 0x3F)); - } else { - if ($cbyte < 0x10000) { - $str .= chr(0xE0 | ($cbyte >> 12)); - $str .= chr(0x80 | (($cbyte >> 6) & 0x3F)); - $str .= chr(0x80 | ($cbyte & 0x3F)); - } else { - if ($cbyte < 0x200000) { - $str .= chr(0xF0 | ($cbyte >> 18)); - $str .= chr(0x80 | (($cbyte >> 12) & 0x3F)); - $str .= chr(0x80 | (($cbyte >> 6) & 0x3F)); - $str .= chr(0x80 | ($cbyte & 0x3F)); - } else { - if ($cbyte < 0x4000000) { - $str .= chr(0xF8 | ($cbyte >> 24)); - $str .= chr(0x80 | (($cbyte >> 18) & 0x3F)); - $str .= chr(0x80 | (($cbyte >> 12) & 0x3F)); - $str .= chr(0x80 | (($cbyte >> 6) & 0x3F)); - $str .= chr(0x80 | ($cbyte & 0x3F)); - } else { - if ($cbyte < 0x80000000) { - $str .= chr(0xFC | ($cbyte >> 30)); - $str .= chr(0x80 | (($cbyte >> 24) & 0x3F)); - $str .= chr(0x80 | (($cbyte >> 18) & 0x3F)); - $str .= chr(0x80 | (($cbyte >> 12) & 0x3F)); - $str .= chr(0x80 | (($cbyte >> 6) & 0x3F)); - $str .= chr(0x80 | ($cbyte & 0x3F)); - } else { // Cannot express a 32-bit character in UTF-8 - $str .= chr($this->noCharByteVal); - } - } - } - } - } - } - return $str; - } - - /** - * Converts a UTF-8 Multibyte character to a UNICODE number - * Unit-tested by Kasper - * - * @param string UTF-8 multibyte character string - * @param boolean If set, then a hex. number is returned. - * @return integer UNICODE integer - * @see UnumberToChar() - */ - function utf8CharToUnumber($str, $hex = 0) { - $ord = ord(substr($str, 0, 1)); // First char - - if (($ord & 192) == 192) { // This verifyes that it IS a multi byte string - $binBuf = ''; - for ($b = 0; $b < 8; $b++) { // for each byte in multibyte string... - $ord = $ord << 1; // Shift it left and ... - if ($ord & 128) { // ... and with 8th bit - if that is set, then there are still bytes in sequence. - $binBuf .= substr('00000000' . decbin(ord(substr($str, $b + 1, 1))), -6); - } else { - break; - } - } - $binBuf = substr('00000000' . decbin(ord(substr($str, 0, 1))), -(6 - $b)) . $binBuf; - - $int = bindec($binBuf); - } else { - $int = $ord; - } - - return $hex ? 'x' . dechex($int) : $int; - } - - - /******************************************** - * - * Init functions - * - ********************************************/ - - /** - * This will initialize a charset for use if it's defined in the PATH_t3lib.'csconvtbl/' folder - * This function is automatically called by the conversion functions - * - * PLEASE SEE: http://www.unicode.org/Public/MAPPINGS/ - * - * @param string The charset to be initialized. Use lowercase charset always (the charset must match exactly with a filename in csconvtbl/ folder ([charset].tbl) - * @return integer Returns '1' if already loaded. Returns FALSE if charset conversion table was not found. Returns '2' if the charset conversion table was found and parsed. - * @access private - */ - function initCharset($charset) { - // Only process if the charset is not yet loaded: - if (!is_array($this->parsedCharsets[$charset])) { - - // Conversion table filename: - $charsetConvTableFile = PATH_t3lib . 'csconvtbl/' . $charset . '.tbl'; - - // If the conversion table is found: - if ($charset && t3lib_div::validPathStr($charsetConvTableFile) && @is_file($charsetConvTableFile)) { - // Cache file for charsets: - // Caching brought parsing time for gb2312 down from 2400 ms to 150 ms. For other charsets we are talking 11 ms down to zero. - $cacheFile = t3lib_div::getFileAbsFileName('typo3temp/cs/charset_' . $charset . '.tbl'); - if ($cacheFile && @is_file($cacheFile)) { - $this->parsedCharsets[$charset] = unserialize(t3lib_div::getUrl($cacheFile)); - } else { - // Parse conversion table into lines: - $lines = t3lib_div::trimExplode(LF, t3lib_div::getUrl($charsetConvTableFile), 1); - // Initialize the internal variable holding the conv. table: - $this->parsedCharsets[$charset] = array('local' => array(), 'utf8' => array()); - // traverse the lines: - $detectedType = ''; - foreach ($lines as $value) { - if (trim($value) && substr($value, 0, 1) != '#') { // Comment line or blanks are ignored. - - // Detect type if not done yet: (Done on first real line) - // The "whitespaced" type is on the syntax "0x0A 0x000A #LINE FEED" while "ms-token" is like "B9 = U+00B9 : SUPERSCRIPT ONE" - if (!$detectedType) { - $detectedType = preg_match('/[[:space:]]*0x([[:alnum:]]*)[[:space:]]+0x([[:alnum:]]*)[[:space:]]+/', $value) ? 'whitespaced' : 'ms-token'; - } - - if ($detectedType == 'ms-token') { - list($hexbyte, $utf8) = preg_split('/[=:]/', $value, 3); - } elseif ($detectedType == 'whitespaced') { - $regA = array(); - preg_match('/[[:space:]]*0x([[:alnum:]]*)[[:space:]]+0x([[:alnum:]]*)[[:space:]]+/', $value, $regA); - $hexbyte = $regA[1]; - $utf8 = 'U+' . $regA[2]; - } - $decval = hexdec(trim($hexbyte)); - if ($decval > 127) { - $utf8decval = hexdec(substr(trim($utf8), 2)); - $this->parsedCharsets[$charset]['local'][$decval] = $this->UnumberToChar($utf8decval); - $this->parsedCharsets[$charset]['utf8'][$this->parsedCharsets[$charset]['local'][$decval]] = $decval; - } - } - } - if ($cacheFile) { - t3lib_div::writeFileToTypo3tempDir($cacheFile, serialize($this->parsedCharsets[$charset])); - } - } - return 2; - } else { - return FALSE; - } - } else { - return 1; - } - } - - /** - * This function initializes all UTF-8 character data tables. - * - * PLEASE SEE: http://www.unicode.org/Public/UNIDATA/ - * - * @param string Mode ("case", "ascii", ...) - * @return integer Returns FALSE on error, a TRUE value on success: 1 table already loaded, 2, cached version, 3 table parsed (and cached). - * @access private - */ - function initUnicodeData($mode = NULL) { - // cache files - $cacheFileCase = t3lib_div::getFileAbsFileName('typo3temp/cs/cscase_utf-8.tbl'); - $cacheFileASCII = t3lib_div::getFileAbsFileName('typo3temp/cs/csascii_utf-8.tbl'); - - // Only process if the tables are not yet loaded - switch ($mode) { - case 'case': - if (is_array($this->caseFolding['utf-8'])) { - return 1; - } - - // Use cached version if possible - if ($cacheFileCase && @is_file($cacheFileCase)) { - $this->caseFolding['utf-8'] = unserialize(t3lib_div::getUrl($cacheFileCase)); - return 2; - } - break; - - case 'ascii': - if (is_array($this->toASCII['utf-8'])) { - return 1; - } - - // Use cached version if possible - if ($cacheFileASCII && @is_file($cacheFileASCII)) { - $this->toASCII['utf-8'] = unserialize(t3lib_div::getUrl($cacheFileASCII)); - return 2; - } - break; - } - - // process main Unicode data file - $unicodeDataFile = PATH_t3lib . 'unidata/UnicodeData.txt'; - if (!(t3lib_div::validPathStr($unicodeDataFile) && @is_file($unicodeDataFile))) { - return FALSE; - } - - $fh = fopen($unicodeDataFile, 'rb'); - if (!$fh) { - return FALSE; - } - - // key = utf8 char (single codepoint), value = utf8 string (codepoint sequence) - // note: we use the UTF-8 characters here and not the Unicode numbers to avoid conversion roundtrip in utf8_strtolower/-upper) - $this->caseFolding['utf-8'] = array(); - $utf8CaseFolding =& $this->caseFolding['utf-8']; // a shorthand - $utf8CaseFolding['toUpper'] = array(); - $utf8CaseFolding['toLower'] = array(); - $utf8CaseFolding['toTitle'] = array(); - - $decomposition = array(); // array of temp. decompositions - $mark = array(); // array of chars that are marks (eg. composing accents) - $number = array(); // array of chars that are numbers (eg. digits) - $omit = array(); // array of chars to be omitted (eg. Russian hard sign) - - while (!feof($fh)) { - $line = fgets($fh, 4096); - // has a lot of info - list($char, $name, $cat, , , $decomp, , , $num, , , , $upper, $lower, $title,) = explode(';', rtrim($line)); - - $ord = hexdec($char); - if ($ord > 0xFFFF) { - break; - } // only process the BMP - - $utf8_char = $this->UnumberToChar($ord); - - if ($upper) { - $utf8CaseFolding['toUpper'][$utf8_char] = $this->UnumberToChar(hexdec($upper)); - } - if ($lower) { - $utf8CaseFolding['toLower'][$utf8_char] = $this->UnumberToChar(hexdec($lower)); - } - // store "title" only when different from "upper" (only a few) - if ($title && $title != $upper) { - $utf8CaseFolding['toTitle'][$utf8_char] = $this->UnumberToChar(hexdec($title)); - } - - switch ($cat[0]) { - case 'M': // mark (accent, umlaut, ...) - $mark["U+$char"] = 1; - break; - - case 'N': // numeric value - if ($ord > 0x80 && $num != '') { - $number["U+$char"] = $num; - } - } - - // accented Latin letters without "official" decomposition - $match = array(); - if (preg_match('/^LATIN (SMALL|CAPITAL) LETTER ([A-Z]) WITH/', $name, $match) && !$decomp) { - $c = ord($match[2]); - if ($match[1] == 'SMALL') { - $c += 32; - } - - $decomposition["U+$char"] = array(dechex($c)); - continue; - } - - $match = array(); - if (preg_match('/(<.*>)? *(.+)/', $decomp, $match)) { - switch ($match[1]) { - case '': // add parenthesis as circle replacement, eg (1) - $match[2] = '0028 ' . $match[2] . ' 0029'; - break; - - case '': // add square brackets as square replacement, eg [1] - $match[2] = '005B ' . $match[2] . ' 005D'; - break; - - case '': // ignore multi char decompositions that start with a space - if (preg_match('/^0020 /', $match[2])) { - continue 2; - } - break; - - // ignore Arabic and vertical layout presentation decomposition - case '': - case '': - case '': - case '': - case '': - continue 2; - } - $decomposition["U+$char"] = explode(' ', $match[2]); - } - } - fclose($fh); - - // process additional Unicode data for casing (allow folded characters to expand into a sequence) - $specialCasingFile = PATH_t3lib . 'unidata/SpecialCasing.txt'; - if (t3lib_div::validPathStr($specialCasingFile) && @is_file($specialCasingFile)) { - $fh = fopen($specialCasingFile, 'rb'); - if ($fh) { - while (!feof($fh)) { - $line = fgets($fh, 4096); - if ($line[0] != '#' && trim($line) != '') { - - list($char, $lower, $title, $upper, $cond) = t3lib_div::trimExplode(';', $line); - if ($cond == '' || $cond[0] == '#') { - $utf8_char = $this->UnumberToChar(hexdec($char)); - if ($char != $lower) { - $arr = explode(' ', $lower); - for ($i = 0; isset($arr[$i]); $i++) { - $arr[$i] = $this->UnumberToChar(hexdec($arr[$i])); - } - $utf8CaseFolding['toLower'][$utf8_char] = implode('', $arr); - } - if ($char != $title && $title != $upper) { - $arr = explode(' ', $title); - for ($i = 0; isset($arr[$i]); $i++) { - $arr[$i] = $this->UnumberToChar(hexdec($arr[$i])); - } - $utf8CaseFolding['toTitle'][$utf8_char] = implode('', $arr); - } - if ($char != $upper) { - $arr = explode(' ', $upper); - for ($i = 0; isset($arr[$i]); $i++) { - $arr[$i] = $this->UnumberToChar(hexdec($arr[$i])); - } - $utf8CaseFolding['toUpper'][$utf8_char] = implode('', $arr); - } - } - } - } - fclose($fh); - } - } - - // process custom decompositions - $customTranslitFile = PATH_t3lib . 'unidata/Translit.txt'; - if (t3lib_div::validPathStr($customTranslitFile) && @is_file($customTranslitFile)) { - $fh = fopen($customTranslitFile, 'rb'); - if ($fh) { - while (!feof($fh)) { - $line = fgets($fh, 4096); - if ($line[0] != '#' && trim($line) != '') { - list($char, $translit) = t3lib_div::trimExplode(';', $line); - if (!$translit) { - $omit["U+$char"] = 1; - } - $decomposition["U+$char"] = explode(' ', $translit); - - } - } - fclose($fh); - } - } - - // decompose and remove marks; inspired by unac (Loic Dachary ) - foreach ($decomposition as $from => $to) { - $code_decomp = array(); - - while ($code_value = array_shift($to)) { - if (isset($decomposition["U+$code_value"])) { // do recursive decomposition - foreach (array_reverse($decomposition["U+$code_value"]) as $cv) { - array_unshift($to, $cv); - } - } elseif (!isset($mark["U+$code_value"])) { // remove mark - array_push($code_decomp, $code_value); - } - } - if (count($code_decomp) || isset($omit[$from])) { - $decomposition[$from] = $code_decomp; - } else { - unset($decomposition[$from]); - } - } - - // create ascii only mapping - $this->toASCII['utf-8'] = array(); - $ascii =& $this->toASCII['utf-8']; - - foreach ($decomposition as $from => $to) { - $code_decomp = array(); - while ($code_value = array_shift($to)) { - $ord = hexdec($code_value); - if ($ord > 127) { - continue 2; - } // skip decompositions containing non-ASCII chars - else - { - array_push($code_decomp, chr($ord)); - } - } - $ascii[$this->UnumberToChar(hexdec(str_replace('U+', '0x', $from)))] = join('', $code_decomp); - } - - // add numeric decompositions - foreach ($number as $from => $to) { - $utf8_char = $this->UnumberToChar(hexdec(str_replace('U+', '0x', $from))); - if (!isset($ascii[$utf8_char])) { - $ascii[$utf8_char] = $to; - } - } - - if ($cacheFileCase) { - t3lib_div::writeFileToTypo3tempDir($cacheFileCase, serialize($utf8CaseFolding)); - } - - if ($cacheFileASCII) { - t3lib_div::writeFileToTypo3tempDir($cacheFileASCII, serialize($ascii)); - } - - return 3; - } - - /** - * This function initializes the folding table for a charset other than UTF-8. - * This function is automatically called by the case folding functions. - * - * @param string Charset for which to initialize case folding. - * @return integer Returns FALSE on error, a TRUE value on success: 1 table already loaded, 2, cached version, 3 table parsed (and cached). - * @access private - */ - function initCaseFolding($charset) { - // Only process if the case table is not yet loaded: - if (is_array($this->caseFolding[$charset])) { - return 1; - } - - // Use cached version if possible - $cacheFile = t3lib_div::getFileAbsFileName('typo3temp/cs/cscase_' . $charset . '.tbl'); - if ($cacheFile && @is_file($cacheFile)) { - $this->caseFolding[$charset] = unserialize(t3lib_div::getUrl($cacheFile)); - return 2; - } - - // init UTF-8 conversion for this charset - if (!$this->initCharset($charset)) { - return FALSE; - } - - // UTF-8 case folding is used as the base conversion table - if (!$this->initUnicodeData('case')) { - return FALSE; - } - - $nochar = chr($this->noCharByteVal); - foreach ($this->parsedCharsets[$charset]['local'] as $ci => $utf8) { - // reconvert to charset (don't use chr() of numeric value, might be muli-byte) - $c = $this->utf8_decode($utf8, $charset); - - // $cc = $this->conv($this->caseFolding['utf-8']['toUpper'][$utf8], 'utf-8', $charset); - $cc = $this->utf8_decode($this->caseFolding['utf-8']['toUpper'][$utf8], $charset); - if ($cc != '' && $cc != $nochar) { - $this->caseFolding[$charset]['toUpper'][$c] = $cc; - } - - // $cc = $this->conv($this->caseFolding['utf-8']['toLower'][$utf8], 'utf-8', $charset); - $cc = $this->utf8_decode($this->caseFolding['utf-8']['toLower'][$utf8], $charset); - if ($cc != '' && $cc != $nochar) { - $this->caseFolding[$charset]['toLower'][$c] = $cc; - } - - // $cc = $this->conv($this->caseFolding['utf-8']['toTitle'][$utf8], 'utf-8', $charset); - $cc = $this->utf8_decode($this->caseFolding['utf-8']['toTitle'][$utf8], $charset); - if ($cc != '' && $cc != $nochar) { - $this->caseFolding[$charset]['toTitle'][$c] = $cc; - } - } - - // add the ASCII case table - for ($i = ord('a'); $i <= ord('z'); $i++) { - $this->caseFolding[$charset]['toUpper'][chr($i)] = chr($i - 32); - } - for ($i = ord('A'); $i <= ord('Z'); $i++) { - $this->caseFolding[$charset]['toLower'][chr($i)] = chr($i + 32); - } - - if ($cacheFile) { - t3lib_div::writeFileToTypo3tempDir($cacheFile, serialize($this->caseFolding[$charset])); - } - - return 3; - } - - /** - * This function initializes the to-ASCII conversion table for a charset other than UTF-8. - * This function is automatically called by the ASCII transliteration functions. - * - * @param string Charset for which to initialize conversion. - * @return integer Returns FALSE on error, a TRUE value on success: 1 table already loaded, 2, cached version, 3 table parsed (and cached). - * @access private - */ - function initToASCII($charset) { - // Only process if the case table is not yet loaded: - if (is_array($this->toASCII[$charset])) { - return 1; - } - - // Use cached version if possible - $cacheFile = t3lib_div::getFileAbsFileName('typo3temp/cs/csascii_' . $charset . '.tbl'); - if ($cacheFile && @is_file($cacheFile)) { - $this->toASCII[$charset] = unserialize(t3lib_div::getUrl($cacheFile)); - return 2; - } - - // init UTF-8 conversion for this charset - if (!$this->initCharset($charset)) { - return FALSE; - } - - // UTF-8/ASCII transliteration is used as the base conversion table - if (!$this->initUnicodeData('ascii')) { - return FALSE; - } - - $nochar = chr($this->noCharByteVal); - foreach ($this->parsedCharsets[$charset]['local'] as $ci => $utf8) { - // reconvert to charset (don't use chr() of numeric value, might be muli-byte) - $c = $this->utf8_decode($utf8, $charset); - - if (isset($this->toASCII['utf-8'][$utf8])) { - $this->toASCII[$charset][$c] = $this->toASCII['utf-8'][$utf8]; - } - } - - if ($cacheFile) { - t3lib_div::writeFileToTypo3tempDir($cacheFile, serialize($this->toASCII[$charset])); - } - - return 3; - } - - - /******************************************** - * - * String operation functions - * - ********************************************/ - - /** - * Returns a part of a string. - * Unit-tested by Kasper (single byte charsets only) - * - * @param string The character set - * @param string Character string - * @param integer Start position (character position) - * @param integer Length (in characters) - * @return string The substring - * @see substr(), mb_substr() - * @author Martin Kutschker - */ - function substr($charset, $string, $start, $len = NULL) { - if ($len === 0 || $string === '') { - return ''; - } - - if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'mbstring') { - // cannot omit $len, when specifying charset - if ($len == NULL) { - $enc = mb_internal_encoding(); // save internal encoding - mb_internal_encoding($charset); - $str = mb_substr($string, $start); - mb_internal_encoding($enc); // restore internal encoding - - return $str; - } - else { - return mb_substr($string, $start, $len, $charset); - } - } elseif ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'iconv') { - // cannot omit $len, when specifying charset - if ($len == NULL) { - $enc = iconv_get_encoding('internal_encoding'); // save internal encoding - iconv_set_encoding('internal_encoding', $charset); - $str = iconv_substr($string, $start); - iconv_set_encoding('internal_encoding', $enc); // restore internal encoding - - return $str; - } - else { - return iconv_substr($string, $start, $len, $charset); - } - } elseif ($charset == 'utf-8') { - return $this->utf8_substr($string, $start, $len); - } elseif ($this->eucBasedSets[$charset]) { - return $this->euc_substr($string, $start, $charset, $len); - } elseif ($this->twoByteSets[$charset]) { - return substr($string, $start * 2, $len * 2); - } elseif ($this->fourByteSets[$charset]) { - return substr($string, $start * 4, $len * 4); - } - - // treat everything else as single-byte encoding - return $len === NULL ? substr($string, $start) : substr($string, $start, $len); - } - - /** - * Counts the number of characters. - * Unit-tested by Kasper (single byte charsets only) - * - * @param string The character set - * @param string Character string - * @return integer The number of characters - * @see strlen() - * @author Martin Kutschker - */ - function strlen($charset, $string) { - if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'mbstring') { - return mb_strlen($string, $charset); - } elseif ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'iconv') { - return iconv_strlen($string, $charset); - } elseif ($charset == 'utf-8') { - return $this->utf8_strlen($string); - } elseif ($this->eucBasedSets[$charset]) { - return $this->euc_strlen($string, $charset); - } elseif ($this->twoByteSets[$charset]) { - return strlen($string) / 2; - } elseif ($this->fourByteSets[$charset]) { - return strlen($string) / 4; - } - // treat everything else as single-byte encoding - return strlen($string); - } - - /** - * Method to crop strings using the mb_substr function. - * - * @param string The character set - * @param string String to be cropped - * @param integer Crop length (in characters) - * @param string Crop signifier - * @return string The shortened string - * @see mb_strlen(), mb_substr() - */ - protected function cropMbstring($charset, $string, $len, $crop = '') { - if (intval($len) === 0 || mb_strlen($string, $charset) <= abs($len)) { - return $string; - } - - if ($len > 0) { - $string = mb_substr($string, 0, $len, $charset) . $crop; - } else { - $string = $crop . mb_substr($string, $len, mb_strlen($string, $charset), $charset); - } - - return $string; - } - - /** - * Truncates a string and pre-/appends a string. - * Unit tested by Kasper - * - * @param string The character set - * @param string Character string - * @param integer Length (in characters) - * @param string Crop signifier - * @return string The shortened string - * @see substr(), mb_strimwidth() - * @author Martin Kutschker - */ - function crop($charset, $string, $len, $crop = '') { - if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'mbstring') { - return $this->cropMbstring($charset, $string, $len, $crop); - } - - if (intval($len) == 0) { - return $string; - } - - if ($charset == 'utf-8') { - $i = $this->utf8_char2byte_pos($string, $len); - } elseif ($this->eucBasedSets[$charset]) { - $i = $this->euc_char2byte_pos($string, $len, $charset); - } else { - if ($len > 0) { - $i = $len; - } else { - $i = strlen($string) + $len; - if ($i <= 0) { - $i = FALSE; - } - } - } - - if ($i === FALSE) { // $len outside actual string length - return $string; - } else { - if ($len > 0) { - if (strlen($string[$i])) { - return substr($string, 0, $i) . $crop; - - } - } else { - if (strlen($string[$i - 1])) { - return $crop . substr($string, $i); - } - } - - /* - if (abs($len)<$this->strlen($charset,$string)) { // Has to use ->strlen() - otherwise multibyte strings ending with a multibyte char will return TRUE here (which is not a catastrophe, but...) - if ($len > 0) { - return substr($string,0,$i).$crop; - } else { - return $crop.substr($string,$i); - } - } - */ - } - return $string; - } - - /** - * Cuts a string short at a given byte length. - * - * @param string The character set - * @param string Character string - * @param integer The byte length - * @return string The shortened string - * @see mb_strcut() - * @author Martin Kutschker - */ - function strtrunc($charset, $string, $len) { - if ($len <= 0) { - return ''; - } - - if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'mbstring') { - return mb_strcut($string, 0, $len, $charset); - } elseif ($charset == 'utf-8') { - return $this->utf8_strtrunc($string, $len); - } elseif ($this->eucBasedSets[$charset]) { - return $this->euc_strtrunc($string, $len, $charset); - } elseif ($this->twoByteSets[$charset]) { - if ($len % 2) { - $len--; - } // don't cut at odd positions - } elseif ($this->fourByteSets[$charset]) { - $x = $len % 4; - $len -= $x; // realign to position dividable by four - } - // treat everything else as single-byte encoding - return substr($string, 0, $len); - } - - /** - * Translates all characters of a string into their respective case values. - * Unlike strtolower() and strtoupper() this method is locale independent. - * Note that the string length may change! - * eg. lower case German "ß" (sharp S) becomes upper case "SS" - * Unit-tested by Kasper - * Real case folding is language dependent, this method ignores this fact. - * - * @param string Character set of string - * @param string Input string to convert case for - * @param string Case keyword: "toLower" means lowercase conversion, anything else is uppercase (use "toUpper" ) - * @return string The converted string - * @author Martin Kutschker - * @see strtolower(), strtoupper() - */ - function conv_case($charset, $string, $case) { - if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'mbstring') { - if ($case == 'toLower') { - $string = mb_strtolower($string, $charset); - } else { - $string = mb_strtoupper($string, $charset); - } - } elseif ($charset == 'utf-8') { - $string = $this->utf8_char_mapping($string, 'case', $case); - } elseif (isset($this->eucBasedSets[$charset])) { - $string = $this->euc_char_mapping($string, $charset, 'case', $case); - } else { - // treat everything else as single-byte encoding - $string = $this->sb_char_mapping($string, $charset, 'case', $case); - } - - return $string; - } - - /** - * Equivalent of lcfirst/ucfirst but using character set. - * - * @param string $charset - * @param string $string - * @param string $case - * @return string - * @see t3lib_cs::conv_case() - */ - public function convCaseFirst($charset, $string, $case) { - $firstChar = $this->substr($charset, $string, 0, 1); - $firstChar = $this->conv_case($charset, $firstChar, $case); - $remainder = $this->substr($charset, $string, 1); - return $firstChar . $remainder; - } - - /** - * Converts special chars (like æøåÆØÅ, umlauts etc) to ascii equivalents (usually double-bytes, like æ => ae etc.) - * - * @param string $charset Character set of string - * @param string $string Input string to convert - * @return string The converted string - */ - function specCharsToASCII($charset, $string) { - if ($charset == 'utf-8') { - $string = $this->utf8_char_mapping($string, 'ascii'); - } elseif (isset($this->eucBasedSets[$charset])) { - $string = $this->euc_char_mapping($string, $charset, 'ascii'); - } else { - // treat everything else as single-byte encoding - $string = $this->sb_char_mapping($string, $charset, 'ascii'); - } - - return $string; - } - - - /** - * converts the language codes that we get from the client (usually HTTP_ACCEPT_LANGUAGE) - * into a TYPO3-readable language code - * @param $languageCodesList list of language codes. something like 'de,en-us;q=0.9,de-de;q=0.7,es-cl;q=0.6,en;q=0.4,es;q=0.3,zh;q=0.1' - * see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 - * @return string a preferred language that TYPO3 supports, or "default" if none found - * @author Benjamin Mack (benni.typo3.org) - */ - public function getPreferredClientLanguage($languageCodesList) { - $allLanguageCodes = array(); - $selectedLanguage = 'default'; - - // get all languages where TYPO3 code is the same as the ISO code - foreach ($this->charSetArray as $typo3Lang => $charSet) { - $allLanguageCodes[$typo3Lang] = $typo3Lang; - } - - // get all languages where TYPO3 code differs from ISO code - // or needs the country part - // the iso codes will here overwrite the default typo3 language in the key - foreach ($this->locales->getIsoMapping() as $typo3Lang => $isoLang) { - $isoLang = join('-', explode('_', $isoLang)); - $allLanguageCodes[$typo3Lang] = $isoLang; - } - - // move the iso codes to the (because we're comparing the keys with "isset" later on) - $allLanguageCodes = array_flip($allLanguageCodes); - - - $preferredLanguages = t3lib_div::trimExplode(',', $languageCodesList); - // order the preferred languages after they key - $sortedPreferredLanguages = array(); - foreach ($preferredLanguages as $preferredLanguage) { - $quality = 1.0; - if (strpos($preferredLanguage, ';q=') !== FALSE) { - list($preferredLanguage, $quality) = explode(';q=', $preferredLanguage); - } - $sortedPreferredLanguages[$preferredLanguage] = $quality; - } - - // loop through the languages, with the highest priority first - arsort($sortedPreferredLanguages, SORT_NUMERIC); - foreach ($sortedPreferredLanguages as $preferredLanguage => $quality) { - if (isset($allLanguageCodes[$preferredLanguage])) { - $selectedLanguage = $allLanguageCodes[$preferredLanguage]; - break; - } - - // strip the country code from the end - list($preferredLanguage, $preferredCountry) = explode('-', $preferredLanguage); - if (isset($allLanguageCodes[$preferredLanguage])) { - $selectedLanguage = $allLanguageCodes[$preferredLanguage]; - break; - } - } - if (!$selectedLanguage || $selectedLanguage == 'en') { - $selectedLanguage = 'default'; - } - return $selectedLanguage; - } - - - /******************************************** - * - * Internal string operation functions - * - ********************************************/ - - /** - * Maps all characters of a string in a single byte charset. - * - * @param string the string - * @param string the charset - * @param string mode: 'case' (case folding) or 'ascii' (ASCII transliteration) - * @param string 'case': conversion 'toLower' or 'toUpper' - * @return string the converted string - * @author Martin Kutschker - */ - function sb_char_mapping($str, $charset, $mode, $opt = '') { - switch ($mode) { - case 'case': - if (!$this->initCaseFolding($charset)) { - return $str; - } // do nothing - $map =& $this->caseFolding[$charset][$opt]; - break; - - case 'ascii': - if (!$this->initToASCII($charset)) { - return $str; - } // do nothing - $map =& $this->toASCII[$charset]; - break; - - default: - return $str; - } - - $out = ''; - for ($i = 0; strlen($str[$i]); $i++) { - $c = $str[$i]; - if (isset($map[$c])) { - $out .= $map[$c]; - } else { - $out .= $c; - } - } - - return $out; - } - - - /******************************************** - * - * Internal UTF-8 string operation functions - * - ********************************************/ - - /** - * Returns a part of a UTF-8 string. - * Unit-tested by Kasper and works 100% like substr() / mb_substr() for full range of $start/$len - * - * @param string UTF-8 string - * @param integer Start position (character position) - * @param integer Length (in characters) - * @return string The substring - * @see substr() - * @author Martin Kutschker - */ - function utf8_substr($str, $start, $len = NULL) { - if (!strcmp($len, '0')) { - return ''; - } - - $byte_start = $this->utf8_char2byte_pos($str, $start); - if ($byte_start === FALSE) { - if ($start > 0) { - return FALSE; // $start outside string length - } else { - $start = 0; - } - } - - $str = substr($str, $byte_start); - - if ($len != NULL) { - $byte_end = $this->utf8_char2byte_pos($str, $len); - if ($byte_end === FALSE) // $len outside actual string length - { - return $len < 0 ? '' : $str; - } // When length is less than zero and exceeds, then we return blank string. - else - { - return substr($str, 0, $byte_end); - } - } - else { - return $str; - } - } - - /** - * Counts the number of characters of a string in UTF-8. - * Unit-tested by Kasper and works 100% like strlen() / mb_strlen() - * - * @param string UTF-8 multibyte character string - * @return integer The number of characters - * @see strlen() - * @author Martin Kutschker - */ - function utf8_strlen($str) { - $n = 0; - for ($i = 0; strlen($str[$i]); $i++) { - $c = ord($str[$i]); - if (!($c & 0x80)) // single-byte (0xxxxxx) - { - $n++; - } - elseif (($c & 0xC0) == 0xC0) // multi-byte starting byte (11xxxxxx) - { - $n++; - } - } - return $n; - } - - /** - * Truncates a string in UTF-8 short at a given byte length. - * - * @param string UTF-8 multibyte character string - * @param integer the byte length - * @return string the shortened string - * @see mb_strcut() - * @author Martin Kutschker - */ - function utf8_strtrunc($str, $len) { - $i = $len - 1; - if (ord($str[$i]) & 0x80) { // part of a multibyte sequence - for (; $i > 0 && !(ord($str[$i]) & 0x40); $i--) { - // find the first byte - ; - } - if ($i <= 0) { - return ''; - } // sanity check - for ($bc = 0, $mbs = ord($str[$i]); $mbs & 0x80; $mbs = $mbs << 1) { - // calculate number of bytes - $bc++; - } - if ($bc + $i > $len) { - return substr($str, 0, $i); - } - // fallthru: multibyte char fits into length - } - return substr($str, 0, $len); - } - - /** - * Find position of first occurrence of a string, both arguments are in UTF-8. - * - * @param string UTF-8 string to search in - * @param string UTF-8 string to search for - * @param integer Positition to start the search - * @return integer The character position - * @see strpos() - * @author Martin Kutschker - */ - function utf8_strpos($haystack, $needle, $offset = 0) { - if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'mbstring') { - return mb_strpos($haystack, $needle, $offset, 'utf-8'); - } elseif ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'iconv') { - return iconv_strpos($haystack, $needle, $offset, 'utf-8'); - } - - $byte_offset = $this->utf8_char2byte_pos($haystack, $offset); - if ($byte_offset === FALSE) { - return FALSE; - } // offset beyond string length - - $byte_pos = strpos($haystack, $needle, $byte_offset); - if ($byte_pos === FALSE) { - return FALSE; - } // needle not found - - return $this->utf8_byte2char_pos($haystack, $byte_pos); - } - - /** - * Find position of last occurrence of a char in a string, both arguments are in UTF-8. - * - * @param string UTF-8 string to search in - * @param string UTF-8 character to search for (single character) - * @return integer The character position - * @see strrpos() - * @author Martin Kutschker - */ - function utf8_strrpos($haystack, $needle) { - if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'mbstring') { - return mb_strrpos($haystack, $needle, 'utf-8'); - } elseif ($GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] == 'iconv') { - return iconv_strrpos($haystack, $needle, 'utf-8'); - } - - $byte_pos = strrpos($haystack, $needle); - if ($byte_pos === FALSE) { - return FALSE; - } // needle not found - - return $this->utf8_byte2char_pos($haystack, $byte_pos); - } - - /** - * Translates a character position into an 'absolute' byte position. - * Unit tested by Kasper. - * - * @param string UTF-8 string - * @param integer Character position (negative values start from the end) - * @return integer Byte position - * @author Martin Kutschker - */ - function utf8_char2byte_pos($str, $pos) { - $n = 0; // number of characters found - $p = abs($pos); // number of characters wanted - - if ($pos >= 0) { - $i = 0; - $d = 1; - } else { - $i = strlen($str) - 1; - $d = -1; - } - - for (; strlen($str[$i]) && $n < $p; $i += $d) { - $c = (int) ord($str[$i]); - if (!($c & 0x80)) // single-byte (0xxxxxx) - { - $n++; - } - elseif (($c & 0xC0) == 0xC0) // multi-byte starting byte (11xxxxxx) - { - $n++; - } - } - if (!strlen($str[$i])) { - return FALSE; - } // offset beyond string length - - if ($pos >= 0) { - // skip trailing multi-byte data bytes - while ((ord($str[$i]) & 0x80) && !(ord($str[$i]) & 0x40)) { - $i++; - } - } else { - // correct offset - $i++; - } - - return $i; - } - - /** - * Translates an 'absolute' byte position into a character position. - * Unit tested by Kasper. - * - * @param string UTF-8 string - * @param integer byte position - * @return integer character position - * @author Martin Kutschker - */ - function utf8_byte2char_pos($str, $pos) { - $n = 0; // number of characters - for ($i = $pos; $i > 0; $i--) { - $c = (int) ord($str[$i]); - if (!($c & 0x80)) // single-byte (0xxxxxx) - { - $n++; - } - elseif (($c & 0xC0) == 0xC0) // multi-byte starting byte (11xxxxxx) - { - $n++; - } - } - if (!strlen($str[$i])) { - return FALSE; - } // offset beyond string length - - return $n; - } - - /** - * Maps all characters of an UTF-8 string. - * - * @param string UTF-8 string - * @param string mode: 'case' (case folding) or 'ascii' (ASCII transliteration) - * @param string 'case': conversion 'toLower' or 'toUpper' - * @return string the converted string - * @author Martin Kutschker - */ - function utf8_char_mapping($str, $mode, $opt = '') { - if (!$this->initUnicodeData($mode)) { - return $str; - } // do nothing - - $out = ''; - switch ($mode) { - case 'case': - $map =& $this->caseFolding['utf-8'][$opt]; - break; - - case 'ascii': - $map =& $this->toASCII['utf-8']; - break; - - default: - return $str; - } - - for ($i = 0; strlen($str[$i]); $i++) { - $c = ord($str[$i]); - if (!($c & 0x80)) // single-byte (0xxxxxx) - { - $mbc = $str[$i]; - } - elseif (($c & 0xC0) == 0xC0) { // multi-byte starting byte (11xxxxxx) - for ($bc = 0; $c & 0x80; $c = $c << 1) { - $bc++; - } // calculate number of bytes - $mbc = substr($str, $i, $bc); - $i += $bc - 1; - } - - if (isset($map[$mbc])) { - $out .= $map[$mbc]; - } else { - $out .= $mbc; - } - } - - return $out; - } - - - /******************************************** - * - * Internal EUC string operation functions - * - * Extended Unix Code: - * ASCII compatible 7bit single bytes chars - * 8bit two byte chars - * - * Shift-JIS is treated as a special case. - * - ********************************************/ - - /** - * Cuts a string in the EUC charset family short at a given byte length. - * - * @param string EUC multibyte character string - * @param integer the byte length - * @param string the charset - * @return string the shortened string - * @see mb_strcut() - * @author Martin Kutschker - */ - function euc_strtrunc($str, $len, $charset) { - $sjis = ($charset == 'shift_jis'); - for ($i = 0; strlen($str[$i]) && $i < $len; $i++) { - $c = ord($str[$i]); - if ($sjis) { - if (($c >= 0x80 && $c < 0xA0) || ($c >= 0xE0)) { - $i++; - } // advance a double-byte char - } - else { - if ($c >= 0x80) { - $i++; - } // advance a double-byte char - } - } - if (!strlen($str[$i])) { - return $str; - } // string shorter than supplied length - - if ($i > $len) { - return substr($str, 0, $len - 1); // we ended on a first byte - } else { - return substr($str, 0, $len); - } - } - - /** - * Returns a part of a string in the EUC charset family. - * - * @param string EUC multibyte character string - * @param integer start position (character position) - * @param string the charset - * @param integer length (in characters) - * @return string the substring - * @author Martin Kutschker - */ - function euc_substr($str, $start, $charset, $len = NULL) { - $byte_start = $this->euc_char2byte_pos($str, $start, $charset); - if ($byte_start === FALSE) { - return FALSE; - } // $start outside string length - - $str = substr($str, $byte_start); - - if ($len != NULL) { - $byte_end = $this->euc_char2byte_pos($str, $len, $charset); - if ($byte_end === FALSE) // $len outside actual string length - { - return $str; - } - else - { - return substr($str, 0, $byte_end); - } - } - else { - return $str; - } - } - - /** - * Counts the number of characters of a string in the EUC charset family. - * - * @param string EUC multibyte character string - * @param string the charset - * @return integer the number of characters - * @see strlen() - * @author Martin Kutschker - */ - function euc_strlen($str, $charset) { - $sjis = ($charset == 'shift_jis'); - $n = 0; - for ($i = 0; strlen($str[$i]); $i++) { - $c = ord($str[$i]); - if ($sjis) { - if (($c >= 0x80 && $c < 0xA0) || ($c >= 0xE0)) { - $i++; - } // advance a double-byte char - } - else { - if ($c >= 0x80) { - $i++; - } // advance a double-byte char - } - - $n++; - } - - return $n; - } - - /** - * Translates a character position into an 'absolute' byte position. - * - * @param string EUC multibyte character string - * @param integer character position (negative values start from the end) - * @param string the charset - * @return integer byte position - * @author Martin Kutschker - */ - function euc_char2byte_pos($str, $pos, $charset) { - $sjis = ($charset == 'shift_jis'); - $n = 0; // number of characters seen - $p = abs($pos); // number of characters wanted - - if ($pos >= 0) { - $i = 0; - $d = 1; - } else { - $i = strlen($str) - 1; - $d = -1; - } - - for (; strlen($str[$i]) && $n < $p; $i += $d) { - $c = ord($str[$i]); - if ($sjis) { - if (($c >= 0x80 && $c < 0xA0) || ($c >= 0xE0)) { - $i += $d; - } // advance a double-byte char - } - else { - if ($c >= 0x80) { - $i += $d; - } // advance a double-byte char - } - - $n++; - } - if (!strlen($str[$i])) { - return FALSE; - } // offset beyond string length - - if ($pos < 0) { - $i++; - } // correct offset - - return $i; - } - - /** - * Maps all characters of a string in the EUC charset family. - * - * @param string EUC multibyte character string - * @param string the charset - * @param string mode: 'case' (case folding) or 'ascii' (ASCII transliteration) - * @param string 'case': conversion 'toLower' or 'toUpper' - * @return string the converted string - * @author Martin Kutschker - */ - function euc_char_mapping($str, $charset, $mode, $opt = '') { - switch ($mode) { - case 'case': - if (!$this->initCaseFolding($charset)) { - return $str; - } // do nothing - $map =& $this->caseFolding[$charset][$opt]; - break; - - case 'ascii': - if (!$this->initToASCII($charset)) { - return $str; - } // do nothing - $map =& $this->toASCII[$charset]; - break; - - default: - return $str; - } - - $sjis = ($charset == 'shift_jis'); - $out = ''; - for ($i = 0; strlen($str[$i]); $i++) { - $mbc = $str[$i]; - $c = ord($mbc); - - if ($sjis) { - if (($c >= 0x80 && $c < 0xA0) || ($c >= 0xE0)) { // a double-byte char - $mbc = substr($str, $i, 2); - $i++; - } - } - else { - if ($c >= 0x80) { // a double-byte char - $mbc = substr($str, $i, 2); - $i++; - } - } - - if (isset($map[$mbc])) { - $out .= $map[$mbc]; - } else { - $out .= $mbc; - } - } - - return $out; - } - -} - -if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_cs.php'])) { - include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_cs.php']); -} - -?> diff --git a/lib/typo3/class.t3lib_div.php b/lib/typo3/class.t3lib_div.php deleted file mode 100644 index ad761763f0d..00000000000 --- a/lib/typo3/class.t3lib_div.php +++ /dev/null @@ -1,5839 +0,0 @@ - - * @package TYPO3 - * @subpackage t3lib - */ -final class t3lib_div { - - // Severity constants used by t3lib_div::sysLog() - const SYSLOG_SEVERITY_INFO = 0; - const SYSLOG_SEVERITY_NOTICE = 1; - const SYSLOG_SEVERITY_WARNING = 2; - const SYSLOG_SEVERITY_ERROR = 3; - const SYSLOG_SEVERITY_FATAL = 4; - - const ENV_TRUSTED_HOSTS_PATTERN_ALLOW_ALL = '.*'; - const ENV_TRUSTED_HOSTS_PATTERN_SERVER_NAME = 'SERVER_NAME'; - - /** - * State of host header value security check - * in order to avoid unnecessary multiple checks during one request - * - * @var bool - */ - static protected $allowHostHeaderValue = FALSE; - - /** - * Singleton instances returned by makeInstance, using the class names as - * array keys - * - * @var array - */ - protected static $singletonInstances = array(); - - /** - * Instances returned by makeInstance, using the class names as array keys - * - * @var array - */ - protected static $nonSingletonInstances = array(); - - /** - * Register for makeInstance with given class name and final class names to reduce number of class_exists() calls - * - * @var array Given class name => final class name - */ - protected static $finalClassNameRegister = array(); - - /************************* - * - * GET/POST Variables - * - * Background: - * Input GET/POST variables in PHP may have their quotes escaped with "\" or not depending on configuration. - * TYPO3 has always converted quotes to BE escaped if the configuration told that they would not be so. - * But the clean solution is that quotes are never escaped and that is what the functions below offers. - * Eventually TYPO3 should provide this in the global space as well. - * In the transitional phase (or forever..?) we need to encourage EVERY to read and write GET/POST vars through the API functions below. - * - *************************/ - - /** - * Returns the 'GLOBAL' value of incoming data from POST or GET, with priority to POST (that is equalent to 'GP' order) - * Strips slashes from all output, both strings and arrays. - * To enhancement security in your scripts, please consider using t3lib_div::_GET or t3lib_div::_POST if you already - * know by which method your data is arriving to the scripts! - * - * @param string $var GET/POST var to return - * @return mixed POST var named $var and if not set, the GET var of the same name. - */ - public static function _GP($var) { - if (empty($var)) { - return; - } - $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var]; - if (isset($value)) { - if (is_array($value)) { - self::stripSlashesOnArray($value); - } else { - $value = stripslashes($value); - } - } - return $value; - } - - /** - * Returns the global arrays $_GET and $_POST merged with $_POST taking precedence. - * - * @param string $parameter Key (variable name) from GET or POST vars - * @return array Returns the GET vars merged recursively onto the POST vars. - */ - public static function _GPmerged($parameter) { - $postParameter = (isset($_POST[$parameter]) && is_array($_POST[$parameter])) ? $_POST[$parameter] : array(); - $getParameter = (isset($_GET[$parameter]) && is_array($_GET[$parameter])) ? $_GET[$parameter] : array(); - - $mergedParameters = self::array_merge_recursive_overrule($getParameter, $postParameter); - self::stripSlashesOnArray($mergedParameters); - - return $mergedParameters; - } - - /** - * Returns the global $_GET array (or value from) normalized to contain un-escaped values. - * ALWAYS use this API function to acquire the GET variables! - * - * @param string $var Optional pointer to value in GET array (basically name of GET var) - * @return mixed If $var is set it returns the value of $_GET[$var]. If $var is NULL (default), returns $_GET itself. In any case *slashes are stipped from the output!* - * @see _POST(), _GP(), _GETset() - */ - public static function _GET($var = NULL) { - $value = ($var === NULL) ? $_GET : (empty($var) ? NULL : $_GET[$var]); - if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting. - if (is_array($value)) { - self::stripSlashesOnArray($value); - } else { - $value = stripslashes($value); - } - } - return $value; - } - - /** - * Returns the global $_POST array (or value from) normalized to contain un-escaped values. - * ALWAYS use this API function to acquire the $_POST variables! - * - * @param string $var Optional pointer to value in POST array (basically name of POST var) - * @return mixed If $var is set it returns the value of $_POST[$var]. If $var is NULL (default), returns $_POST itself. In any case *slashes are stipped from the output!* - * @see _GET(), _GP() - */ - public static function _POST($var = NULL) { - $value = ($var === NULL) ? $_POST : (empty($var) ? NULL : $_POST[$var]); - if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting. - if (is_array($value)) { - self::stripSlashesOnArray($value); - } else { - $value = stripslashes($value); - } - } - return $value; - } - - /** - * Writes input value to $_GET. - * - * @param mixed $inputGet - * array or single value to write to $_GET. Values should NOT be - * escaped at input time (but will be escaped before writing - * according to TYPO3 standards). - * @param string $key - * alternative key; If set, this will not set the WHOLE GET array, - * but only the key in it specified by this value! - * You can specify to replace keys on deeper array levels by - * separating the keys with a pipe. - * Example: 'parentKey|childKey' will result in - * array('parentKey' => array('childKey' => $inputGet)) - * - * @return void - */ - public static function _GETset($inputGet, $key = '') { - // adds slashes since TYPO3 standard currently is that slashes - // must be applied (regardless of magic_quotes setting) - if (is_array($inputGet)) { - self::addSlashesOnArray($inputGet); - } else { - $inputGet = addslashes($inputGet); - } - - if ($key != '') { - if (strpos($key, '|') !== FALSE) { - $pieces = explode('|', $key); - $newGet = array(); - $pointer =& $newGet; - foreach ($pieces as $piece) { - $pointer =& $pointer[$piece]; - } - $pointer = $inputGet; - $mergedGet = self::array_merge_recursive_overrule( - $_GET, $newGet - ); - - $_GET = $mergedGet; - $GLOBALS['HTTP_GET_VARS'] = $mergedGet; - } else { - $_GET[$key] = $inputGet; - $GLOBALS['HTTP_GET_VARS'][$key] = $inputGet; - } - } elseif (is_array($inputGet)) { - $_GET = $inputGet; - $GLOBALS['HTTP_GET_VARS'] = $inputGet; - } - } - - /** - * Wrapper for the RemoveXSS function. - * Removes potential XSS code from an input string. - * - * Using an external class by Travis Puderbaugh - * - * @param string $string Input string - * @return string Input string with potential XSS code removed - */ - public static function removeXSS($string) { - require_once(PATH_typo3 . 'contrib/RemoveXSS/RemoveXSS.php'); - $string = RemoveXSS::process($string); - return $string; - } - - - /************************* - * - * IMAGE FUNCTIONS - * - *************************/ - - - /** - * Compressing a GIF file if not already LZW compressed. - * This function is a workaround for the fact that ImageMagick and/or GD does not compress GIF-files to their minimun size (that is RLE or no compression used) - * - * The function takes a file-reference, $theFile, and saves it again through GD or ImageMagick in order to compress the file - * GIF: - * If $type is not set, the compression is done with ImageMagick (provided that $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'] is pointing to the path of a lzw-enabled version of 'convert') else with GD (should be RLE-enabled!) - * If $type is set to either 'IM' or 'GD' the compression is done with ImageMagick and GD respectively - * PNG: - * No changes. - * - * $theFile is expected to be a valid GIF-file! - * The function returns a code for the operation. - * - * @param string $theFile Filepath - * @param string $type See description of function - * @return string Returns "GD" if GD was used, otherwise "IM" if ImageMagick was used. If nothing done at all, it returns empty string. - */ - public static function gif_compress($theFile, $type) { - $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX']; - $returnCode = ''; - if ($gfxConf['gif_compress'] && strtolower(substr($theFile, -4, 4)) == '.gif') { // GIF... - if (($type == 'IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw']) { // IM - // use temporary file to prevent problems with read and write lock on same file on network file systems - $temporaryName = dirname($theFile) . '/' . md5(uniqid()) . '.gif'; - // rename could fail, if a simultaneous thread is currently working on the same thing - if (@rename($theFile, $temporaryName)) { - $cmd = self::imageMagickCommand('convert', '"' . $temporaryName . '" "' . $theFile . '"', $gfxConf['im_path_lzw']); - t3lib_utility_Command::exec($cmd); - unlink($temporaryName); - } - - $returnCode = 'IM'; - if (@is_file($theFile)) { - self::fixPermissions($theFile); - } - } elseif (($type == 'GD' || !$type) && $gfxConf['gdlib'] && !$gfxConf['gdlib_png']) { // GD - $tempImage = imageCreateFromGif($theFile); - imageGif($tempImage, $theFile); - imageDestroy($tempImage); - $returnCode = 'GD'; - if (@is_file($theFile)) { - self::fixPermissions($theFile); - } - } - } - return $returnCode; - } - - /** - * Converts a png file to gif. - * This converts a png file to gif IF the FLAG $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] is set TRUE. - * - * @param string $theFile the filename with path - * @return string new filename - */ - public static function png_to_gif_by_imagemagick($theFile) { - if ($GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] - && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] - && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'] - && strtolower(substr($theFile, -4, 4)) == '.png' - && @is_file($theFile)) { // IM - $newFile = substr($theFile, 0, -4) . '.gif'; - $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']); - t3lib_utility_Command::exec($cmd); - $theFile = $newFile; - if (@is_file($newFile)) { - self::fixPermissions($newFile); - } - // unlink old file?? May be bad idea because TYPO3 would then recreate the file every time as - // TYPO3 thinks the file is not generated because it's missing!! So do not unlink $theFile here!! - } - return $theFile; - } - - /** - * Returns filename of the png/gif version of the input file (which can be png or gif). - * If input file type does not match the wanted output type a conversion is made and temp-filename returned. - * - * @param string $theFile Filepath of image file - * @param boolean $output_png If set, then input file is converted to PNG, otherwise to GIF - * @return string If the new image file exists, its filepath is returned - */ - public static function read_png_gif($theFile, $output_png = FALSE) { - if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] && @is_file($theFile)) { - $ext = strtolower(substr($theFile, -4, 4)); - if ( - ((string) $ext == '.png' && $output_png) || - ((string) $ext == '.gif' && !$output_png) - ) { - return $theFile; - } else { - $newFile = PATH_site . 'typo3temp/readPG_' . md5($theFile . '|' . filemtime($theFile)) . ($output_png ? '.png' : '.gif'); - $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']); - t3lib_utility_Command::exec($cmd); - if (@is_file($newFile)) { - self::fixPermissions($newFile); - return $newFile; - } - } - } - } - - - /************************* - * - * STRING FUNCTIONS - * - *************************/ - - /** - * Truncates a string with appended/prepended "..." and takes current character set into consideration. - * - * @param string $string string to truncate - * @param integer $chars must be an integer with an absolute value of at least 4. if negative the string is cropped from the right end. - * @param string $appendString appendix to the truncated string - * @return string cropped string - */ - public static function fixed_lgd_cs($string, $chars, $appendString = '...') { - if (is_object($GLOBALS['LANG'])) { - return $GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet, $string, $chars, $appendString); - } elseif (is_object($GLOBALS['TSFE'])) { - $charSet = ($GLOBALS['TSFE']->renderCharset != '' ? $GLOBALS['TSFE']->renderCharset : $GLOBALS['TSFE']->defaultCharSet); - return $GLOBALS['TSFE']->csConvObj->crop($charSet, $string, $chars, $appendString); - } else { - // this case should not happen - $csConvObj = self::makeInstance('t3lib_cs'); - return $csConvObj->crop('utf-8', $string, $chars, $appendString); - } - } - - /** - * Breaks up a single line of text for emails - * - * @param string $str The string to break up - * @param string $newlineChar The string to implode the broken lines with (default/typically \n) - * @param integer $lineWidth The line width - * @return string reformatted text - * @deprecated since TYPO3 4.6, will be removed in TYPO3 6.0 - Use t3lib_utility_Mail::breakLinesForEmail() - */ - public static function breakLinesForEmail($str, $newlineChar = LF, $lineWidth = 76) { - self::logDeprecatedFunction(); - return t3lib_utility_Mail::breakLinesForEmail($str, $newlineChar, $lineWidth); - } - - /** - * Match IP number with list of numbers with wildcard - * Dispatcher method for switching into specialised IPv4 and IPv6 methods. - * - * @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR - * @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168). If list is "*" no check is done and the function returns TRUE immediately. An empty list always returns FALSE. - * @return boolean TRUE if an IP-mask from $list matches $baseIP - */ - public static function cmpIP($baseIP, $list) { - $list = trim($list); - if ($list === '') { - return FALSE; - } elseif ($list === '*') { - return TRUE; - } - if (strpos($baseIP, ':') !== FALSE && self::validIPv6($baseIP)) { - return self::cmpIPv6($baseIP, $list); - } else { - return self::cmpIPv4($baseIP, $list); - } - } - - /** - * Match IPv4 number with list of numbers with wildcard - * - * @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR - * @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168), could also contain IPv6 addresses - * @return boolean TRUE if an IP-mask from $list matches $baseIP - */ - public static function cmpIPv4($baseIP, $list) { - $IPpartsReq = explode('.', $baseIP); - if (count($IPpartsReq) == 4) { - $values = self::trimExplode(',', $list, 1); - - foreach ($values as $test) { - $testList = explode('/', $test); - if (count($testList) == 2) { - list($test, $mask) = $testList; - } else { - $mask = FALSE; - } - - if (intval($mask)) { - // "192.168.3.0/24" - $lnet = ip2long($test); - $lip = ip2long($baseIP); - $binnet = str_pad(decbin($lnet), 32, '0', STR_PAD_LEFT); - $firstpart = substr($binnet, 0, $mask); - $binip = str_pad(decbin($lip), 32, '0', STR_PAD_LEFT); - $firstip = substr($binip, 0, $mask); - $yes = (strcmp($firstpart, $firstip) == 0); - } else { - // "192.168.*.*" - $IPparts = explode('.', $test); - $yes = 1; - foreach ($IPparts as $index => $val) { - $val = trim($val); - if (($val !== '*') && ($IPpartsReq[$index] !== $val)) { - $yes = 0; - } - } - } - if ($yes) { - return TRUE; - } - } - } - return FALSE; - } - - /** - * Match IPv6 address with a list of IPv6 prefixes - * - * @param string $baseIP is the current remote IP address for instance - * @param string $list is a comma-list of IPv6 prefixes, could also contain IPv4 addresses - * @return boolean TRUE if an baseIP matches any prefix - */ - public static function cmpIPv6($baseIP, $list) { - $success = FALSE; // Policy default: Deny connection - $baseIP = self::normalizeIPv6($baseIP); - - $values = self::trimExplode(',', $list, 1); - foreach ($values as $test) { - $testList = explode('/', $test); - if (count($testList) == 2) { - list($test, $mask) = $testList; - } else { - $mask = FALSE; - } - - if (self::validIPv6($test)) { - $test = self::normalizeIPv6($test); - $maskInt = intval($mask) ? intval($mask) : 128; - if ($mask === '0') { // special case; /0 is an allowed mask - equals a wildcard - $success = TRUE; - } elseif ($maskInt == 128) { - $success = ($test === $baseIP); - } else { - $testBin = self::IPv6Hex2Bin($test); - $baseIPBin = self::IPv6Hex2Bin($baseIP); - $success = TRUE; - - // modulo is 0 if this is a 8-bit-boundary - $maskIntModulo = $maskInt % 8; - $numFullCharactersUntilBoundary = intval($maskInt / 8); - - if (substr($testBin, 0, $numFullCharactersUntilBoundary) !== substr($baseIPBin, 0, $numFullCharactersUntilBoundary)) { - $success = FALSE; - } elseif ($maskIntModulo > 0) { - // if not an 8-bit-boundary, check bits of last character - $testLastBits = str_pad(decbin(ord(substr($testBin, $numFullCharactersUntilBoundary, 1))), 8, '0', STR_PAD_LEFT); - $baseIPLastBits = str_pad(decbin(ord(substr($baseIPBin, $numFullCharactersUntilBoundary, 1))), 8, '0', STR_PAD_LEFT); - if (strncmp($testLastBits, $baseIPLastBits, $maskIntModulo) != 0) { - $success = FALSE; - } - } - } - } - if ($success) { - return TRUE; - } - } - return FALSE; - } - - /** - * Transform a regular IPv6 address from hex-representation into binary - * - * @param string $hex IPv6 address in hex-presentation - * @return string Binary representation (16 characters, 128 characters) - * @see IPv6Bin2Hex() - */ - public static function IPv6Hex2Bin($hex) { - // use PHP-function if PHP was compiled with IPv6-support - if (defined('AF_INET6')) { - $bin = inet_pton($hex); - } else { - $hex = self::normalizeIPv6($hex); - $hex = str_replace(':', '', $hex); // Replace colon to nothing - $bin = pack("H*" , $hex); - } - return $bin; - } - - /** - * Transform an IPv6 address from binary to hex-representation - * - * @param string $bin IPv6 address in hex-presentation - * @return string Binary representation (16 characters, 128 characters) - * @see IPv6Hex2Bin() - */ - public static function IPv6Bin2Hex($bin) { - // use PHP-function if PHP was compiled with IPv6-support - if (defined('AF_INET6')) { - $hex = inet_ntop($bin); - } else { - $hex = unpack("H*" , $bin); - $hex = chunk_split($hex[1], 4, ':'); - // strip last colon (from chunk_split) - $hex = substr($hex, 0, -1); - // IPv6 is now in normalized form - // compress it for easier handling and to match result from inet_ntop() - $hex = self::compressIPv6($hex); - } - return $hex; - - } - - /** - * Normalize an IPv6 address to full length - * - * @param string $address Given IPv6 address - * @return string Normalized address - * @see compressIPv6() - */ - public static function normalizeIPv6($address) { - $normalizedAddress = ''; - $stageOneAddress = ''; - - // according to RFC lowercase-representation is recommended - $address = strtolower($address); - - // normalized representation has 39 characters (0000:0000:0000:0000:0000:0000:0000:0000) - if (strlen($address) == 39) { - // already in full expanded form - return $address; - } - - $chunks = explode('::', $address); // Count 2 if if address has hidden zero blocks - if (count($chunks) == 2) { - $chunksLeft = explode(':', $chunks[0]); - $chunksRight = explode(':', $chunks[1]); - $left = count($chunksLeft); - $right = count($chunksRight); - - // Special case: leading zero-only blocks count to 1, should be 0 - if ($left == 1 && strlen($chunksLeft[0]) == 0) { - $left = 0; - } - - $hiddenBlocks = 8 - ($left + $right); - $hiddenPart = ''; - $h = 0; - while ($h < $hiddenBlocks) { - $hiddenPart .= '0000:'; - $h++; - } - - if ($left == 0) { - $stageOneAddress = $hiddenPart . $chunks[1]; - } else { - $stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1]; - } - } else { - $stageOneAddress = $address; - } - - // normalize the blocks: - $blocks = explode(':', $stageOneAddress); - $divCounter = 0; - foreach ($blocks as $block) { - $tmpBlock = ''; - $i = 0; - $hiddenZeros = 4 - strlen($block); - while ($i < $hiddenZeros) { - $tmpBlock .= '0'; - $i++; - } - $normalizedAddress .= $tmpBlock . $block; - if ($divCounter < 7) { - $normalizedAddress .= ':'; - $divCounter++; - } - } - return $normalizedAddress; - } - - - /** - * Compress an IPv6 address to the shortest notation - * - * @param string $address Given IPv6 address - * @return string Compressed address - * @see normalizeIPv6() - */ - public static function compressIPv6($address) { - // use PHP-function if PHP was compiled with IPv6-support - if (defined('AF_INET6')) { - $bin = inet_pton($address); - $address = inet_ntop($bin); - } else { - $address = self::normalizeIPv6($address); - - // append one colon for easier handling - // will be removed later - $address .= ':'; - - // according to IPv6-notation the longest match - // of a package of '0000:' may be replaced with ':' - // (resulting in something like '1234::abcd') - for ($counter = 8; $counter > 1; $counter--) { - $search = str_repeat('0000:', $counter); - if (($pos = strpos($address, $search)) !== FALSE) { - $address = substr($address, 0, $pos) . ':' . substr($address, $pos + ($counter*5)); - break; - } - } - - // up to 3 zeros in the first part may be removed - $address = preg_replace('/^0{1,3}/', '', $address); - // up to 3 zeros at the beginning of other parts may be removed - $address = preg_replace('/:0{1,3}/', ':', $address); - - // strip last colon (from chunk_split) - $address = substr($address, 0, -1); - } - return $address; - } - - /** - * Validate a given IP address. - * - * Possible format are IPv4 and IPv6. - * - * @param string $ip IP address to be tested - * @return boolean TRUE if $ip is either of IPv4 or IPv6 format. - */ - public static function validIP($ip) { - return (filter_var($ip, FILTER_VALIDATE_IP) !== FALSE); - } - - /** - * Validate a given IP address to the IPv4 address format. - * - * Example for possible format: 10.0.45.99 - * - * @param string $ip IP address to be tested - * @return boolean TRUE if $ip is of IPv4 format. - */ - public static function validIPv4($ip) { - return (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== FALSE); - } - - /** - * Validate a given IP address to the IPv6 address format. - * - * Example for possible format: 43FB::BB3F:A0A0:0 | ::1 - * - * @param string $ip IP address to be tested - * @return boolean TRUE if $ip is of IPv6 format. - */ - public static function validIPv6($ip) { - return (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE); - } - - /** - * Match fully qualified domain name with list of strings with wildcard - * - * @param string $baseHost A hostname or an IPv4/IPv6-address (will by reverse-resolved; typically REMOTE_ADDR) - * @param string $list A comma-list of domain names to match with. *-wildcard allowed but cannot be part of a string, so it must match the full host name (eg. myhost.*.com => correct, myhost.*domain.com => wrong) - * @return boolean TRUE if a domain name mask from $list matches $baseIP - */ - public static function cmpFQDN($baseHost, $list) { - $baseHost = trim($baseHost); - if (empty($baseHost)) { - return FALSE; - } - if (self::validIPv4($baseHost) || self::validIPv6($baseHost)) { - // resolve hostname - // note: this is reverse-lookup and can be randomly set as soon as somebody is able to set - // the reverse-DNS for his IP (security when for example used with REMOTE_ADDR) - $baseHostName = gethostbyaddr($baseHost); - if ($baseHostName === $baseHost) { - // unable to resolve hostname - return FALSE; - } - } else { - $baseHostName = $baseHost; - } - $baseHostNameParts = explode('.', $baseHostName); - - $values = self::trimExplode(',', $list, 1); - - foreach ($values as $test) { - $hostNameParts = explode('.', $test); - - // to match hostNameParts can only be shorter (in case of wildcards) or equal - if (count($hostNameParts) > count($baseHostNameParts)) { - continue; - } - - $yes = TRUE; - foreach ($hostNameParts as $index => $val) { - $val = trim($val); - if ($val === '*') { - // wildcard valid for one or more hostname-parts - - $wildcardStart = $index + 1; - // wildcard as last/only part always matches, otherwise perform recursive checks - if ($wildcardStart < count($hostNameParts)) { - $wildcardMatched = FALSE; - $tempHostName = implode('.', array_slice($hostNameParts, $index + 1)); - while (($wildcardStart < count($baseHostNameParts)) && (!$wildcardMatched)) { - $tempBaseHostName = implode('.', array_slice($baseHostNameParts, $wildcardStart)); - $wildcardMatched = self::cmpFQDN($tempBaseHostName, $tempHostName); - $wildcardStart++; - } - if ($wildcardMatched) { - // match found by recursive compare - return TRUE; - } else { - $yes = FALSE; - } - } - } elseif ($baseHostNameParts[$index] !== $val) { - // in case of no match - $yes = FALSE; - } - } - if ($yes) { - return TRUE; - } - } - return FALSE; - } - - /** - * Checks if a given URL matches the host that currently handles this HTTP request. - * Scheme, hostname and (optional) port of the given URL are compared. - * - * @param string $url: URL to compare with the TYPO3 request host - * @return boolean Whether the URL matches the TYPO3 request host - */ - public static function isOnCurrentHost($url) { - return (stripos($url . '/', self::getIndpEnv('TYPO3_REQUEST_HOST') . '/') === 0); - } - - /** - * Check for item in list - * Check if an item exists in a comma-separated list of items. - * - * @param string $list comma-separated list of items (string) - * @param string $item item to check for - * @return boolean TRUE if $item is in $list - */ - public static function inList($list, $item) { - return (strpos(',' . $list . ',', ',' . $item . ',') !== FALSE ? TRUE : FALSE); - } - - /** - * Removes an item from a comma-separated list of items. - * - * @param string $element element to remove - * @param string $list comma-separated list of items (string) - * @return string new comma-separated list of items - */ - public static function rmFromList($element, $list) { - $items = explode(',', $list); - foreach ($items as $k => $v) { - if ($v == $element) { - unset($items[$k]); - } - } - return implode(',', $items); - } - - /** - * Expand a comma-separated list of integers with ranges (eg 1,3-5,7 becomes 1,3,4,5,7). - * Ranges are limited to 1000 values per range. - * - * @param string $list comma-separated list of integers with ranges (string) - * @return string new comma-separated list of items - */ - public static function expandList($list) { - $items = explode(',', $list); - $list = array(); - foreach ($items as $item) { - $range = explode('-', $item); - if (isset($range[1])) { - $runAwayBrake = 1000; - for ($n = $range[0]; $n <= $range[1]; $n++) { - $list[] = $n; - - $runAwayBrake--; - if ($runAwayBrake <= 0) { - break; - } - } - } else { - $list[] = $item; - } - } - return implode(',', $list); - } - - /** - * Forces the integer $theInt into the boundaries of $min and $max. If the $theInt is 'FALSE' then the $zeroValue is applied. - * - * @param integer $theInt Input value - * @param integer $min Lower limit - * @param integer $max Higher limit - * @param integer $zeroValue Default value if input is FALSE. - * @return integer The input value forced into the boundaries of $min and $max - * @deprecated since TYPO3 4.6, will be removed in TYPO3 6.0 - Use t3lib_utility_Math::forceIntegerInRange() instead - */ - public static function intInRange($theInt, $min, $max = 2000000000, $zeroValue = 0) { - self::logDeprecatedFunction(); - return t3lib_utility_Math::forceIntegerInRange($theInt, $min, $max, $zeroValue); - } - - /** - * Returns the $integer if greater than zero, otherwise returns zero. - * - * @param integer $theInt Integer string to process - * @return integer - * @deprecated since TYPO3 4.6, will be removed in TYPO3 6.0 - Use t3lib_utility_Math::convertToPositiveInteger() instead - */ - public static function intval_positive($theInt) { - self::logDeprecatedFunction(); - return t3lib_utility_Math::convertToPositiveInteger($theInt); - } - - /** - * Returns an integer from a three part version number, eg '4.12.3' -> 4012003 - * - * @param string $verNumberStr Version number on format x.x.x - * @return integer Integer version of version number (where each part can count to 999) - * @deprecated since TYPO3 4.6, will be removed in TYPO3 6.1 - Use t3lib_utility_VersionNumber::convertVersionNumberToInteger() instead - */ - public static function int_from_ver($verNumberStr) { - // Deprecation log is activated only for TYPO3 4.7 and above - if (t3lib_utility_VersionNumber::convertVersionNumberToInteger(TYPO3_version) >= 4007000) { - self::logDeprecatedFunction(); - } - return t3lib_utility_VersionNumber::convertVersionNumberToInteger($verNumberStr); - } - - /** - * Returns TRUE if the current TYPO3 version (or compatibility version) is compatible to the input version - * Notice that this function compares branches, not versions (4.0.1 would be > 4.0.0 although they use the same compat_version) - * - * @param string $verNumberStr Minimum branch number required (format x.y / e.g. "4.0" NOT "4.0.0"!) - * @return boolean Returns TRUE if this setup is compatible with the provided version number - * @todo Still needs a function to convert versions to branches - */ - public static function compat_version($verNumberStr) { - $currVersionStr = $GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'] : TYPO3_branch; - - if (t3lib_utility_VersionNumber::convertVersionNumberToInteger($currVersionStr) < t3lib_utility_VersionNumber::convertVersionNumberToInteger($verNumberStr)) { - return FALSE; - } else { - return TRUE; - } - } - - /** - * Makes a positive integer hash out of the first 7 chars from the md5 hash of the input - * - * @param string $str String to md5-hash - * @return integer Returns 28bit integer-hash - */ - public static function md5int($str) { - return hexdec(substr(md5($str), 0, 7)); - } - - /** - * Returns the first 10 positions of the MD5-hash (changed from 6 to 10 recently) - * - * @param string $input Input string to be md5-hashed - * @param integer $len The string-length of the output - * @return string Substring of the resulting md5-hash, being $len chars long (from beginning) - */ - public static function shortMD5($input, $len = 10) { - return substr(md5($input), 0, $len); - } - - /** - * Returns a proper HMAC on a given input string and secret TYPO3 encryption key. - * - * @param string $input Input string to create HMAC from - * @param string $additionalSecret additionalSecret to prevent hmac beeing used in a different context - * @return string resulting (hexadecimal) HMAC currently with a length of 40 (HMAC-SHA-1) - */ - public static function hmac($input, $additionalSecret = '') { - $hashAlgorithm = 'sha1'; - $hashBlocksize = 64; - $hmac = ''; - $secret = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . $additionalSecret; - if (extension_loaded('hash') && function_exists('hash_hmac') && function_exists('hash_algos') && in_array($hashAlgorithm, hash_algos())) { - $hmac = hash_hmac($hashAlgorithm, $input, $secret); - } else { - // outer padding - $opad = str_repeat(chr(0x5C), $hashBlocksize); - // inner padding - $ipad = str_repeat(chr(0x36), $hashBlocksize); - if (strlen($secret) > $hashBlocksize) { - // keys longer than block size are shorten - $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $secret)), $hashBlocksize, chr(0)); - } else { - // keys shorter than block size are zero-padded - $key = str_pad($secret, $hashBlocksize, chr(0)); - } - $hmac = call_user_func($hashAlgorithm, ($key ^ $opad) . pack('H*', call_user_func($hashAlgorithm, ($key ^ $ipad) . $input))); - } - return $hmac; - } - - /** - * Takes comma-separated lists and arrays and removes all duplicates - * If a value in the list is trim(empty), the value is ignored. - * - * @param string $in_list Accept multiple parameters which can be comma-separated lists of values and arrays. - * @param mixed $secondParameter: Dummy field, which if set will show a warning! - * @return string Returns the list without any duplicates of values, space around values are trimmed - */ - public static function uniqueList($in_list, $secondParameter = NULL) { - if (is_array($in_list)) { - throw new InvalidArgumentException( - 'TYPO3 Fatal Error: t3lib_div::uniqueList() does NOT support array arguments anymore! Only string comma lists!', - 1270853885 - ); - } - if (isset($secondParameter)) { - throw new InvalidArgumentException( - 'TYPO3 Fatal Error: t3lib_div::uniqueList() does NOT support more than a single argument value anymore. You have specified more than one!', - 1270853886 - ); - } - - return implode(',', array_unique(self::trimExplode(',', $in_list, 1))); - } - - /** - * Splits a reference to a file in 5 parts - * - * @param string $fileref Filename/filepath to be analysed - * @return array Contains keys [path], [file], [filebody], [fileext], [realFileext] - */ - public static function split_fileref($fileref) { - $reg = array(); - if (preg_match('/(.*\/)(.*)$/', $fileref, $reg)) { - $info['path'] = $reg[1]; - $info['file'] = $reg[2]; - } else { - $info['path'] = ''; - $info['file'] = $fileref; - } - - $reg = ''; - if (!is_dir($fileref) && preg_match('/(.*)\.([^\.]*$)/', $info['file'], $reg)) { - $info['filebody'] = $reg[1]; - $info['fileext'] = strtolower($reg[2]); - $info['realFileext'] = $reg[2]; - } else { - $info['filebody'] = $info['file']; - $info['fileext'] = ''; - } - reset($info); - return $info; - } - - /** - * Returns the directory part of a path without trailing slash - * If there is no dir-part, then an empty string is returned. - * Behaviour: - * - * '/dir1/dir2/script.php' => '/dir1/dir2' - * '/dir1/' => '/dir1' - * 'dir1/script.php' => 'dir1' - * 'd/script.php' => 'd' - * '/script.php' => '' - * '' => '' - * - * @param string $path Directory name / path - * @return string Processed input value. See function description. - */ - public static function dirname($path) { - $p = self::revExplode('/', $path, 2); - return count($p) == 2 ? $p[0] : ''; - } - - /** - * Modifies a HTML Hex color by adding/subtracting $R,$G and $B integers - * - * @param string $color A hexadecimal color code, #xxxxxx - * @param integer $R Offset value 0-255 - * @param integer $G Offset value 0-255 - * @param integer $B Offset value 0-255 - * @return string A hexadecimal color code, #xxxxxx, modified according to input vars - * @see modifyHTMLColorAll() - */ - public static function modifyHTMLColor($color, $R, $G, $B) { - // This takes a hex-color (# included!) and adds $R, $G and $B to the HTML-color (format: #xxxxxx) and returns the new color - $nR = t3lib_utility_Math::forceIntegerInRange(hexdec(substr($color, 1, 2)) + $R, 0, 255); - $nG = t3lib_utility_Math::forceIntegerInRange(hexdec(substr($color, 3, 2)) + $G, 0, 255); - $nB = t3lib_utility_Math::forceIntegerInRange(hexdec(substr($color, 5, 2)) + $B, 0, 255); - return '#' . - substr('0' . dechex($nR), -2) . - substr('0' . dechex($nG), -2) . - substr('0' . dechex($nB), -2); - } - - /** - * Modifies a HTML Hex color by adding/subtracting $all integer from all R/G/B channels - * - * @param string $color A hexadecimal color code, #xxxxxx - * @param integer $all Offset value 0-255 for all three channels. - * @return string A hexadecimal color code, #xxxxxx, modified according to input vars - * @see modifyHTMLColor() - */ - public static function modifyHTMLColorAll($color, $all) { - return self::modifyHTMLColor($color, $all, $all, $all); - } - - /** - * Tests if the input can be interpreted as integer. - * - * @param mixed $var Any input variable to test - * @return boolean Returns TRUE if string is an integer - * @deprecated since TYPO3 4.6, will be removed in TYPO3 6.0 - Use t3lib_utility_Math::canBeInterpretedAsInteger() instead - */ - public static function testInt($var) { - self::logDeprecatedFunction(); - - return t3lib_utility_Math::canBeInterpretedAsInteger($var); - } - - /** - * Returns TRUE if the first part of $str matches the string $partStr - * - * @param string $str Full string to check - * @param string $partStr Reference string which must be found as the "first part" of the full string - * @return boolean TRUE if $partStr was found to be equal to the first part of $str - */ - public static function isFirstPartOfStr($str, $partStr) { - return $partStr != '' && strpos((string) $str, (string) $partStr, 0) === 0; - } - - /** - * Formats the input integer $sizeInBytes as bytes/kilobytes/megabytes (-/K/M) - * - * @param integer $sizeInBytes Number of bytes to format. - * @param string $labels Labels for bytes, kilo, mega and giga separated by vertical bar (|) and possibly encapsulated in "". Eg: " | K| M| G" (which is the default value) - * @return string Formatted representation of the byte number, for output. - */ - public static function formatSize($sizeInBytes, $labels = '') { - - // Set labels: - if (strlen($labels) == 0) { - $labels = ' | K| M| G'; - } else { - $labels = str_replace('"', '', $labels); - } - $labelArr = explode('|', $labels); - - // Find size: - if ($sizeInBytes > 900) { - if ($sizeInBytes > 900000000) { // GB - $val = $sizeInBytes / (1024 * 1024 * 1024); - return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[3]; - } - elseif ($sizeInBytes > 900000) { // MB - $val = $sizeInBytes / (1024 * 1024); - return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[2]; - } else { // KB - $val = $sizeInBytes / (1024); - return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[1]; - } - } else { // Bytes - return $sizeInBytes . $labelArr[0]; - } - } - - /** - * Returns microtime input to milliseconds - * - * @param string $microtime Microtime - * @return integer Microtime input string converted to an integer (milliseconds) - */ - public static function convertMicrotime($microtime) { - $parts = explode(' ', $microtime); - return round(($parts[0] + $parts[1]) * 1000); - } - - /** - * This splits a string by the chars in $operators (typical /+-*) and returns an array with them in - * - * @param string $string Input string, eg "123 + 456 / 789 - 4" - * @param string $operators Operators to split by, typically "/+-*" - * @return array Array with operators and operands separated. - * @see tslib_cObj::calc(), tslib_gifBuilder::calcOffset() - */ - public static function splitCalc($string, $operators) { - $res = Array(); - $sign = '+'; - while ($string) { - $valueLen = strcspn($string, $operators); - $value = substr($string, 0, $valueLen); - $res[] = Array($sign, trim($value)); - $sign = substr($string, $valueLen, 1); - $string = substr($string, $valueLen + 1); - } - reset($res); - return $res; - } - - /** - * Calculates the input by +,-,*,/,%,^ with priority to + and - - * - * @param string $string Input string, eg "123 + 456 / 789 - 4" - * @return integer Calculated value. Or error string. - * @see calcParenthesis() - * @deprecated since TYPO3 4.6, will be removed in TYPO3 6.0 - Use t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction() instead - */ - public static function calcPriority($string) { - self::logDeprecatedFunction(); - - return t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction($string); - } - - /** - * Calculates the input with parenthesis levels - * - * @param string $string Input string, eg "(123 + 456) / 789 - 4" - * @return integer Calculated value. Or error string. - * @see calcPriority(), tslib_cObj::stdWrap() - * @deprecated since TYPO3 4.6, will be removed in TYPO3 6.0 - Use t3lib_utility_Math::calculateWithParentheses() instead - */ - public static function calcParenthesis($string) { - self::logDeprecatedFunction(); - - return t3lib_utility_Math::calculateWithParentheses($string); - } - - /** - * Inverse version of htmlspecialchars() - * - * @param string $value Value where >, <, " and & should be converted to regular chars. - * @return string Converted result. - */ - public static function htmlspecialchars_decode($value) { - $value = str_replace('>', '>', $value); - $value = str_replace('<', '<', $value); - $value = str_replace('"', '"', $value); - $value = str_replace('&', '&', $value); - return $value; - } - - /** - * Re-converts HTML entities if they have been converted by htmlspecialchars() - * - * @param string $str String which contains eg. "&amp;" which should stay "&". Or "&#1234;" to "Ӓ". Or "&#x1b;" to "" - * @return string Converted result. - */ - public static function deHSCentities($str) { - return preg_replace('/&([#[:alnum:]]*;)/', '&\1', $str); - } - - /** - * This function is used to escape any ' -characters when transferring text to JavaScript! - * - * @param string $string String to escape - * @param boolean $extended If set, also backslashes are escaped. - * @param string $char The character to escape, default is ' (single-quote) - * @return string Processed input string - */ - public static function slashJS($string, $extended = FALSE, $char = "'") { - if ($extended) { - $string = str_replace("\\", "\\\\", $string); - } - return str_replace($char, "\\" . $char, $string); - } - - /** - * Version of rawurlencode() where all spaces (%20) are re-converted to space-characters. - * Useful when passing text to JavaScript where you simply url-encode it to get around problems with syntax-errors, linebreaks etc. - * - * @param string $str String to raw-url-encode with spaces preserved - * @return string Rawurlencoded result of input string, but with all %20 (space chars) converted to real spaces. - */ - public static function rawUrlEncodeJS($str) { - return str_replace('%20', ' ', rawurlencode($str)); - } - - /** - * rawurlencode which preserves "/" chars - * Useful when file paths should keep the "/" chars, but have all other special chars encoded. - * - * @param string $str Input string - * @return string Output string - */ - public static function rawUrlEncodeFP($str) { - return str_replace('%2F', '/', rawurlencode($str)); - } - - /** - * Checking syntax of input email address - * - * @param string $email Input string to evaluate - * @return boolean Returns TRUE if the $email address (input string) is valid - */ - public static function validEmail($email) { - // enforce maximum length to prevent libpcre recursion crash bug #52929 in PHP - // fixed in PHP 5.3.4; length restriction per SMTP RFC 2821 - if (strlen($email) > 320) { - return FALSE; - } - require_once(PATH_typo3 . 'contrib/idna/idna_convert.class.php'); - $IDN = new idna_convert(array('idn_version' => 2008)); - - return (filter_var($IDN->encode($email), FILTER_VALIDATE_EMAIL) !== FALSE); - } - - /** - * Checks if current e-mail sending method does not accept recipient/sender name - * in a call to PHP mail() function. Windows version of mail() and mini_sendmail - * program are known not to process such input correctly and they cause SMTP - * errors. This function will return TRUE if current mail sending method has - * problem with recipient name in recipient/sender argument for mail(). - * - * TODO: 4.3 should have additional configuration variable, which is combined - * by || with the rest in this function. - * - * @return boolean TRUE if mail() does not accept recipient name - */ - public static function isBrokenEmailEnvironment() { - return TYPO3_OS == 'WIN' || (FALSE !== strpos(ini_get('sendmail_path'), 'mini_sendmail')); - } - - /** - * Changes from/to arguments for mail() function to work in any environment. - * - * @param string $address Address to adjust - * @return string Adjusted address - * @see t3lib_::isBrokenEmailEnvironment() - */ - public static function normalizeMailAddress($address) { - if (self::isBrokenEmailEnvironment() && FALSE !== ($pos1 = strrpos($address, '<'))) { - $pos2 = strpos($address, '>', $pos1); - $address = substr($address, $pos1 + 1, ($pos2 ? $pos2 : strlen($address)) - $pos1 - 1); - } - return $address; - } - - /** - * Formats a string for output between