Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/typo3/class.t3lib_div.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00205         // a tabulator
00206 define('TAB', chr(9));
00207         // a linefeed
00208 define('LF', chr(10));
00209         // a carriage return
00210 define('CR', chr(13));
00211         // a CR-LF combination
00212 define('CRLF', CR . LF);
00213 
00230 final class t3lib_div {
00231 
00232                 // Severity constants used by t3lib_div::sysLog()
00233         const SYSLOG_SEVERITY_INFO = 0;
00234         const SYSLOG_SEVERITY_NOTICE = 1;
00235         const SYSLOG_SEVERITY_WARNING = 2;
00236         const SYSLOG_SEVERITY_ERROR = 3;
00237         const SYSLOG_SEVERITY_FATAL = 4;
00238 
00245         protected static $singletonInstances = array();
00246 
00252         protected static $nonSingletonInstances = array();
00253 
00259         protected static $finalClassNameRegister = array();
00260 
00261         /*************************
00262          *
00263          * GET/POST Variables
00264          *
00265          * Background:
00266          * Input GET/POST variables in PHP may have their quotes escaped with "\" or not depending on configuration.
00267          * TYPO3 has always converted quotes to BE escaped if the configuration told that they would not be so.
00268          * But the clean solution is that quotes are never escaped and that is what the functions below offers.
00269          * Eventually TYPO3 should provide this in the global space as well.
00270          * In the transitional phase (or forever..?) we need to encourage EVERY to read and write GET/POST vars through the API functions below.
00271          *
00272          *************************/
00273 
00284         public static function _GP($var) {
00285                 if (empty($var)) {
00286                         return;
00287                 }
00288                 $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var];
00289                 if (isset($value)) {
00290                         if (is_array($value)) {
00291                                 self::stripSlashesOnArray($value);
00292                         } else {
00293                                 $value = stripslashes($value);
00294                         }
00295                 }
00296                 return $value;
00297         }
00298 
00305         public static function _GPmerged($parameter) {
00306                 $postParameter = (isset($_POST[$parameter]) && is_array($_POST[$parameter])) ? $_POST[$parameter] : array();
00307                 $getParameter = (isset($_GET[$parameter]) && is_array($_GET[$parameter])) ? $_GET[$parameter] : array();
00308 
00309                 $mergedParameters = self::array_merge_recursive_overrule($getParameter, $postParameter);
00310                 self::stripSlashesOnArray($mergedParameters);
00311 
00312                 return $mergedParameters;
00313         }
00314 
00324         public static function _GET($var = NULL) {
00325                 $value = ($var === NULL) ? $_GET : (empty($var) ? NULL : $_GET[$var]);
00326                 if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
00327                         if (is_array($value)) {
00328                                 self::stripSlashesOnArray($value);
00329                         } else {
00330                                 $value = stripslashes($value);
00331                         }
00332                 }
00333                 return $value;
00334         }
00335 
00345         public static function _POST($var = NULL) {
00346                 $value = ($var === NULL) ? $_POST : (empty($var) ? NULL : $_POST[$var]);
00347                 if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
00348                         if (is_array($value)) {
00349                                 self::stripSlashesOnArray($value);
00350                         } else {
00351                                 $value = stripslashes($value);
00352                         }
00353                 }
00354                 return $value;
00355         }
00356 
00375         public static function _GETset($inputGet, $key = '') {
00376                         // adds slashes since TYPO3 standard currently is that slashes
00377                         // must be applied (regardless of magic_quotes setting)
00378                 if (is_array($inputGet)) {
00379                         self::addSlashesOnArray($inputGet);
00380                 } else {
00381                         $inputGet = addslashes($inputGet);
00382                 }
00383 
00384                 if ($key != '') {
00385                         if (strpos($key, '|') !== FALSE) {
00386                                 $pieces = explode('|', $key);
00387                                 $newGet = array();
00388                                 $pointer =& $newGet;
00389                                 foreach ($pieces as $piece) {
00390                                         $pointer =& $pointer[$piece];
00391                                 }
00392                                 $pointer = $inputGet;
00393                                 $mergedGet = self::array_merge_recursive_overrule(
00394                                         $_GET, $newGet
00395                                 );
00396 
00397                                 $_GET = $mergedGet;
00398                                 $GLOBALS['HTTP_GET_VARS'] = $mergedGet;
00399                         } else {
00400                                 $_GET[$key] = $inputGet;
00401                                 $GLOBALS['HTTP_GET_VARS'][$key] = $inputGet;
00402                         }
00403                 } elseif (is_array($inputGet)) {
00404                         $_GET = $inputGet;
00405                         $GLOBALS['HTTP_GET_VARS'] = $inputGet;
00406                 }
00407         }
00408 
00420         public static function GPvar($var, $strip = 0) {
00421                 self::logDeprecatedFunction();
00422 
00423                 if (empty($var)) {
00424                         return;
00425                 }
00426                 $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var];
00427                 if (isset($value) && is_string($value)) {
00428                         $value = stripslashes($value);
00429                 } // Originally check '&& get_magic_quotes_gpc() ' but the values of $_GET are always slashed regardless of get_magic_quotes_gpc() because HTTP_POST/GET_VARS are run through addSlashesOnArray in the very beginning of index_ts.php eg.
00430                 if ($strip && isset($value) && is_array($value)) {
00431                         self::stripSlashesOnArray($value);
00432                 }
00433                 return $value;
00434         }
00435 
00445         public static function GParrayMerged($var) {
00446                 self::logDeprecatedFunction();
00447 
00448                 return self::_GPmerged($var);
00449         }
00450 
00460         public static function removeXSS($string) {
00461                 require_once(PATH_typo3 . 'contrib/RemoveXSS/RemoveXSS.php');
00462                 $string = RemoveXSS::process($string);
00463                 return $string;
00464         }
00465 
00466 
00467         /*************************
00468          *
00469          * IMAGE FUNCTIONS
00470          *
00471          *************************/
00472 
00473 
00493         public static function gif_compress($theFile, $type) {
00494                 $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
00495                 $returnCode = '';
00496                 if ($gfxConf['gif_compress'] && strtolower(substr($theFile, -4, 4)) == '.gif') { // GIF...
00497                         if (($type == 'IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw']) { // IM
00498                                         // use temporary file to prevent problems with read and write lock on same file on network file systems
00499                                 $temporaryName  =  dirname($theFile) . '/' . md5(uniqid()) . '.gif';
00500                                         // rename could fail, if a simultaneous thread is currently working on the same thing
00501                                 if (@rename($theFile, $temporaryName)) {
00502                                         $cmd = self::imageMagickCommand('convert', '"' . $temporaryName . '" "' . $theFile . '"', $gfxConf['im_path_lzw']);
00503                                         t3lib_utility_Command::exec($cmd);
00504                                         unlink($temporaryName);
00505                                 }
00506 
00507                                 $returnCode = 'IM';
00508                                 if (@is_file($theFile)) {
00509                                         self::fixPermissions($theFile);
00510                                 }
00511                         } elseif (($type == 'GD' || !$type) && $gfxConf['gdlib'] && !$gfxConf['gdlib_png']) { // GD
00512                                 $tempImage = imageCreateFromGif($theFile);
00513                                 imageGif($tempImage, $theFile);
00514                                 imageDestroy($tempImage);
00515                                 $returnCode = 'GD';
00516                                 if (@is_file($theFile)) {
00517                                         self::fixPermissions($theFile);
00518                                 }
00519                         }
00520                 }
00521                 return $returnCode;
00522         }
00523 
00532         public static function png_to_gif_by_imagemagick($theFile) {
00533                 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif']
00534                                 && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im']
00535                                 && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']
00536                                 && strtolower(substr($theFile, -4, 4)) == '.png'
00537                                 && @is_file($theFile)) { // IM
00538                         $newFile = substr($theFile, 0, -4) . '.gif';
00539                         $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']);
00540                         t3lib_utility_Command::exec($cmd);
00541                         $theFile = $newFile;
00542                         if (@is_file($newFile)) {
00543                                 self::fixPermissions($newFile);
00544                         }
00545                                 // unlink old file?? May be bad idea bacause 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!!
00546                 }
00547                 return $theFile;
00548         }
00549 
00559         public static function read_png_gif($theFile, $output_png = 0) {
00560                 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] && @is_file($theFile)) {
00561                         $ext = strtolower(substr($theFile, -4, 4));
00562                         if (
00563                                 ((string) $ext == '.png' && $output_png) ||
00564                                 ((string) $ext == '.gif' && !$output_png)
00565                         ) {
00566                                 return $theFile;
00567                         } else {
00568                                 $newFile = PATH_site . 'typo3temp/readPG_' . md5($theFile . '|' . filemtime($theFile)) . ($output_png ? '.png' : '.gif');
00569                                 $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']);
00570                                 t3lib_utility_Command::exec($cmd);
00571                                 if (@is_file($newFile)) {
00572                                         self::fixPermissions($newFile);
00573                                         return $newFile;
00574                                 }
00575                         }
00576                 }
00577         }
00578 
00579 
00580         /*************************
00581          *
00582          * STRING FUNCTIONS
00583          *
00584          *************************/
00585 
00599         public static function fixed_lgd($string, $origChars, $preStr = '...') {
00600                 self::logDeprecatedFunction();
00601 
00602                 $chars = abs($origChars);
00603                 if ($chars >= 4) {
00604                         if (strlen($string) > $chars) {
00605                                 return $origChars < 0 ?
00606                                                 $preStr . trim(substr($string, -($chars - 3))) :
00607                                                 trim(substr($string, 0, $chars - 3)) . $preStr;
00608                         }
00609                 }
00610                 return $string;
00611         }
00612 
00626         public static function fixed_lgd_pre($string, $chars) {
00627                 self::logDeprecatedFunction();
00628 
00629                 return strrev(self::fixed_lgd(strrev($string), $chars));
00630         }
00631 
00641         public static function fixed_lgd_cs($string, $chars, $appendString = '...') {
00642                 if (is_object($GLOBALS['LANG'])) {
00643                         return $GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet, $string, $chars, $appendString);
00644                 } elseif (is_object($GLOBALS['TSFE'])) {
00645                         $charSet = ($GLOBALS['TSFE']->renderCharset != '' ? $GLOBALS['TSFE']->renderCharset : $GLOBALS['TSFE']->defaultCharSet);
00646                         return $GLOBALS['TSFE']->csConvObj->crop($charSet, $string, $chars, $appendString);
00647                 } else {
00648                                 // this case should not happen
00649                         $csConvObj = self::makeInstance('t3lib_cs');
00650                         return $csConvObj->crop('iso-8859-1', $string, $chars, $appendString);
00651                 }
00652         }
00653 
00664         public static function breakTextForEmail($str, $implChar = LF, $charWidth = 76) {
00665                 self::logDeprecatedFunction();
00666 
00667                 $lines = explode(LF, $str);
00668                 $outArr = array();
00669                 foreach ($lines as $lStr) {
00670                         $outArr[] = self::breakLinesForEmail($lStr, $implChar, $charWidth);
00671                 }
00672                 return implode(LF, $outArr);
00673         }
00674 
00685         public static function breakLinesForEmail($str, $implChar = LF, $charWidth = 76) {
00686                 $lines = array();
00687                 $l = $charWidth;
00688                 $p = 0;
00689                 while (strlen($str) > $p) {
00690                         $substr = substr($str, $p, $l);
00691                         if (strlen($substr) == $l) {
00692                                 $count = count(explode(' ', trim(strrev($substr))));
00693                                 if ($count > 1) { // OK...
00694                                         $parts = explode(' ', strrev($substr), 2);
00695                                         $theLine = strrev($parts[1]);
00696                                 } else {
00697                                         $afterParts = explode(' ', substr($str, $l + $p), 2);
00698                                         $theLine = $substr . $afterParts[0];
00699                                 }
00700                                 if (!strlen($theLine)) {
00701                                         break;
00702                                 } // Error, because this would keep us in an endless loop.
00703                         } else {
00704                                 $theLine = $substr;
00705                         }
00706 
00707                         $lines[] = trim($theLine);
00708                         $p += strlen($theLine);
00709                         if (!trim(substr($str, $p, $l))) {
00710                                 break;
00711                         } // added...
00712                 }
00713                 return implode($implChar, $lines);
00714         }
00715 
00725         public static function cmpIP($baseIP, $list) {
00726                 $list = trim($list);
00727                 if ($list === '') {
00728                         return FALSE;
00729                 } elseif ($list === '*') {
00730                         return TRUE;
00731                 }
00732                 if (strpos($baseIP, ':') !== FALSE && self::validIPv6($baseIP)) {
00733                         return self::cmpIPv6($baseIP, $list);
00734                 } else {
00735                         return self::cmpIPv4($baseIP, $list);
00736                 }
00737         }
00738 
00746         public static function cmpIPv4($baseIP, $list) {
00747                 $IPpartsReq = explode('.', $baseIP);
00748                 if (count($IPpartsReq) == 4) {
00749                         $values = self::trimExplode(',', $list, 1);
00750 
00751                         foreach ($values as $test) {
00752                                 list($test, $mask) = explode('/', $test);
00753 
00754                                 if (intval($mask)) {
00755                                                 // "192.168.3.0/24"
00756                                         $lnet = ip2long($test);
00757                                         $lip = ip2long($baseIP);
00758                                         $binnet = str_pad(decbin($lnet), 32, '0', STR_PAD_LEFT);
00759                                         $firstpart = substr($binnet, 0, $mask);
00760                                         $binip = str_pad(decbin($lip), 32, '0', STR_PAD_LEFT);
00761                                         $firstip = substr($binip, 0, $mask);
00762                                         $yes = (strcmp($firstpart, $firstip) == 0);
00763                                 } else {
00764                                                 // "192.168.*.*"
00765                                         $IPparts = explode('.', $test);
00766                                         $yes = 1;
00767                                         foreach ($IPparts as $index => $val) {
00768                                                 $val = trim($val);
00769                                                 if (strcmp($val, '*') && strcmp($IPpartsReq[$index], $val)) {
00770                                                         $yes = 0;
00771                                                 }
00772                                         }
00773                                 }
00774                                 if ($yes) {
00775                                         return TRUE;
00776                                 }
00777                         }
00778                 }
00779                 return FALSE;
00780         }
00781 
00789         public static function cmpIPv6($baseIP, $list) {
00790                 $success = FALSE; // Policy default: Deny connection
00791                 $baseIP = self::normalizeIPv6($baseIP);
00792 
00793                 $values = self::trimExplode(',', $list, 1);
00794                 foreach ($values as $test) {
00795                         $testList = explode('/', $test);
00796                         if (count($testList) == 2) {
00797                                 list($test, $mask) = $testList;
00798                         } else {
00799                                 $mask = FALSE;
00800                         }
00801 
00802                         if (self::validIPv6($test)) {
00803                                 $test = self::normalizeIPv6($test);
00804                                 $maskInt = intval($mask) ? intval($mask) : 128;
00805                                 if ($mask === '0') { // special case; /0 is an allowed mask - equals a wildcard
00806                                         $success = TRUE;
00807                                 } elseif ($maskInt == 128) {
00808                                         $success = ($test === $baseIP);
00809                                 } else {
00810                                         $testBin = self::IPv6Hex2Bin($test);
00811                                         $baseIPBin = self::IPv6Hex2Bin($baseIP);
00812                                         $success = TRUE;
00813 
00814                                         // modulo is 0 if this is a 8-bit-boundary
00815                                         $maskIntModulo = $maskInt % 8;
00816                                         $numFullCharactersUntilBoundary = intval($maskInt / 8);
00817 
00818                                         if (substr($testBin, 0, $numFullCharactersUntilBoundary) !== substr($baseIPBin, 0, $numFullCharactersUntilBoundary)) {
00819                                                 $success = FALSE;
00820                                         } elseif ($maskIntModulo > 0) {
00821                                                 // if not an 8-bit-boundary, check bits of last character
00822                                                 $testLastBits = str_pad(decbin(ord(substr($testBin, $numFullCharactersUntilBoundary, 1))), 8, '0', STR_PAD_LEFT);
00823                                                 $baseIPLastBits = str_pad(decbin(ord(substr($baseIPBin, $numFullCharactersUntilBoundary, 1))), 8, '0', STR_PAD_LEFT);
00824                                                 if (strncmp($testLastBits, $baseIPLastBits, $maskIntModulo) != 0) {
00825                                                         $success = FALSE;
00826                                                 }
00827                                         }
00828                                 }
00829                         }
00830                         if ($success) {
00831                                 return TRUE;
00832                         }
00833                 }
00834                 return FALSE;
00835         }
00836 
00844         public static function IPv6Hex2Bin($hex) {
00845                 // normalized representation has 39 characters (0000:0000:0000:0000:0000:0000:0000:0000)
00846                 if (strlen($hex) < 39) {
00847                         $hex = self::normalizeIPv6($hex);
00848                 }
00849                 $hex = str_replace(':', '', $hex); // Replace colon to nothing
00850                 $bin = pack("H*" , $hex);
00851                 return $bin;
00852         }
00853 
00860         public static function normalizeIPv6($address) {
00861                 $normalizedAddress = '';
00862                 $stageOneAddress = '';
00863 
00864                 $chunks = explode('::', $address); // Count 2 if if address has hidden zero blocks
00865                 if (count($chunks) == 2) {
00866                         $chunksLeft = explode(':', $chunks[0]);
00867                         $chunksRight = explode(':', $chunks[1]);
00868                         $left = count($chunksLeft);
00869                         $right = count($chunksRight);
00870 
00871                                 // Special case: leading zero-only blocks count to 1, should be 0
00872                         if ($left == 1 && strlen($chunksLeft[0]) == 0) {
00873                                 $left = 0;
00874                         }
00875 
00876                         $hiddenBlocks = 8 - ($left + $right);
00877                         $hiddenPart = '';
00878                         $h = 0;
00879                         while ($h < $hiddenBlocks) {
00880                                 $hiddenPart .= '0000:';
00881                                 $h++;
00882                         }
00883 
00884                         if ($left == 0) {
00885                                 $stageOneAddress = $hiddenPart . $chunks[1];
00886                         } else {
00887                                 $stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1];
00888                         }
00889                 } else {
00890                         $stageOneAddress = $address;
00891                 }
00892 
00893                         // normalize the blocks:
00894                 $blocks = explode(':', $stageOneAddress);
00895                 $divCounter = 0;
00896                 foreach ($blocks as $block) {
00897                         $tmpBlock = '';
00898                         $i = 0;
00899                         $hiddenZeros = 4 - strlen($block);
00900                         while ($i < $hiddenZeros) {
00901                                 $tmpBlock .= '0';
00902                                 $i++;
00903                         }
00904                         $normalizedAddress .= $tmpBlock . $block;
00905                         if ($divCounter < 7) {
00906                                 $normalizedAddress .= ':';
00907                                 $divCounter++;
00908                         }
00909                 }
00910                 return $normalizedAddress;
00911         }
00912 
00921         public static function validIP($ip) {
00922                 return (filter_var($ip, FILTER_VALIDATE_IP) !== FALSE);
00923         }
00924 
00933         public static function validIPv4($ip) {
00934                 return (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== FALSE);
00935         }
00936 
00945         public static function validIPv6($ip) {
00946                 return (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE);
00947         }
00948 
00956         public static function cmpFQDN($baseHost, $list) {
00957                 $baseHost = trim($baseHost);
00958                 if (empty($baseHost)) {
00959                         return FALSE;
00960                 }
00961                 if (self::validIPv4($baseHost) || self::validIPv6($baseHost)) {
00962                                 // resolve hostname
00963                                 // note: this is reverse-lookup and can be randomly set as soon as somebody is able to set
00964                                 // the reverse-DNS for his IP (security when for example used with REMOTE_ADDR)
00965                         $baseHostName = gethostbyaddr($baseHost);
00966                         if ($baseHostName === $baseHost) {
00967                                         // unable to resolve hostname
00968                                 return FALSE;
00969                         }
00970                 } else {
00971                         $baseHostName = $baseHost;
00972                 }
00973                 $baseHostNameParts = explode('.', $baseHostName);
00974 
00975                 $values = self::trimExplode(',', $list, 1);
00976 
00977                 foreach ($values as $test) {
00978                         $hostNameParts = explode('.', $test);
00979 
00980                                 // to match hostNameParts can only be shorter (in case of wildcards) or equal
00981                         if (count($hostNameParts) > count($baseHostNameParts)) {
00982                                 continue;
00983                         }
00984 
00985                         $yes = TRUE;
00986                         foreach ($hostNameParts as $index => $val) {
00987                                 $val = trim($val);
00988                                 if ($val === '*') {
00989                                                 // wildcard valid for one or more hostname-parts
00990 
00991                                         $wildcardStart = $index + 1;
00992                                                 // wildcard as last/only part always matches, otherwise perform recursive checks
00993                                         if ($wildcardStart < count($hostNameParts)) {
00994                                                 $wildcardMatched = FALSE;
00995                                                 $tempHostName = implode('.', array_slice($hostNameParts, $index + 1));
00996                                                 while (($wildcardStart < count($baseHostNameParts)) && (!$wildcardMatched)) {
00997                                                         $tempBaseHostName = implode('.', array_slice($baseHostNameParts, $wildcardStart));
00998                                                         $wildcardMatched = self::cmpFQDN($tempBaseHostName, $tempHostName);
00999                                                         $wildcardStart++;
01000                                                 }
01001                                                 if ($wildcardMatched) {
01002                                                                 // match found by recursive compare
01003                                                         return TRUE;
01004                                                 } else {
01005                                                         $yes = FALSE;
01006                                                 }
01007                                         }
01008                                 } elseif ($baseHostNameParts[$index] !== $val) {
01009                                                 // in case of no match
01010                                         $yes = FALSE;
01011                                 }
01012                         }
01013                         if ($yes) {
01014                                 return TRUE;
01015                         }
01016                 }
01017                 return FALSE;
01018         }
01019 
01027         public static function isOnCurrentHost($url) {
01028                 return (stripos($url . '/', self::getIndpEnv('TYPO3_REQUEST_HOST') . '/') === 0);
01029         }
01030 
01040         public static function inList($list, $item) {
01041                 return (strpos(',' . $list . ',', ',' . $item . ',') !== FALSE ? TRUE : FALSE);
01042         }
01043 
01052         public static function rmFromList($element, $list) {
01053                 $items = explode(',', $list);
01054                 foreach ($items as $k => $v) {
01055                         if ($v == $element) {
01056                                 unset($items[$k]);
01057                         }
01058                 }
01059                 return implode(',', $items);
01060         }
01061 
01070         public static function expandList($list) {
01071                 $items = explode(',', $list);
01072                 $list = array();
01073                 foreach ($items as $item) {
01074                         $range = explode('-', $item);
01075                         if (isset($range[1])) {
01076                                 $runAwayBrake = 1000;
01077                                 for ($n = $range[0]; $n <= $range[1]; $n++) {
01078                                         $list[] = $n;
01079 
01080                                         $runAwayBrake--;
01081                                         if ($runAwayBrake <= 0) {
01082                                                 break;
01083                                         }
01084                                 }
01085                         } else {
01086                                 $list[] = $item;
01087                         }
01088                 }
01089                 return implode(',', $list);
01090         }
01091 
01102         public static function intInRange($theInt, $min, $max = 2000000000, $zeroValue = 0) {
01103                         // Returns $theInt as an integer in the integerspace from $min to $max
01104                 $theInt = intval($theInt);
01105                 if ($zeroValue && !$theInt) {
01106                         $theInt = $zeroValue;
01107                 } // If the input value is zero after being converted to integer, zeroValue may set another default value for it.
01108                 if ($theInt < $min) {
01109                         $theInt = $min;
01110                 }
01111                 if ($theInt > $max) {
01112                         $theInt = $max;
01113                 }
01114                 return $theInt;
01115         }
01116 
01124         public static function intval_positive($theInt) {
01125                 $theInt = intval($theInt);
01126                 if ($theInt < 0) {
01127                         $theInt = 0;
01128                 }
01129                 return $theInt;
01130         }
01131 
01142         public static function int_from_ver($verNumberStr) {
01143                 $verParts = explode('.', $verNumberStr);
01144                 return intval((int) $verParts[0] . str_pad((int) $verParts[1], 3, '0', STR_PAD_LEFT) . str_pad((int) $verParts[2], 3, '0', STR_PAD_LEFT));
01145         }
01146 
01155         public static function compat_version($verNumberStr) {
01156                 global $TYPO3_CONF_VARS;
01157                 $currVersionStr = $TYPO3_CONF_VARS['SYS']['compat_version'] ? $TYPO3_CONF_VARS['SYS']['compat_version'] : TYPO3_branch;
01158 
01159                 if (self::int_from_ver($currVersionStr) < self::int_from_ver($verNumberStr)) {
01160                         return FALSE;
01161                 } else {
01162                         return TRUE;
01163                 }
01164         }
01165 
01173         public static function md5int($str) {
01174                 return hexdec(substr(md5($str), 0, 7));
01175         }
01176 
01186         public static function shortMD5($input, $len = 10) {
01187                 return substr(md5($input), 0, $len);
01188         }
01189 
01196         public static function hmac($input) {
01197                 $hashAlgorithm = 'sha1';
01198                 $hashBlocksize = 64;
01199                 $hmac = '';
01200 
01201                 if (extension_loaded('hash') && function_exists('hash_hmac') && function_exists('hash_algos') && in_array($hashAlgorithm, hash_algos())) {
01202                         $hmac = hash_hmac($hashAlgorithm, $input, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
01203                 } else {
01204                                 // outer padding
01205                         $opad = str_repeat(chr(0x5C), $hashBlocksize);
01206                                 // innner padding
01207                         $ipad = str_repeat(chr(0x36), $hashBlocksize);
01208                         if (strlen($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) > $hashBlocksize) {
01209                                         // keys longer than blocksize are shorten
01210                                 $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])), $hashBlocksize, chr(0x00));
01211                         } else {
01212                                         // keys shorter than blocksize are zero-padded
01213                                 $key = str_pad($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], $hashBlocksize, chr(0x00));
01214                         }
01215                         $hmac = call_user_func($hashAlgorithm, ($key ^ $opad) . pack('H*', call_user_func($hashAlgorithm, ($key ^ $ipad) . $input)));
01216                 }
01217                 return $hmac;
01218         }
01219 
01229         public static function uniqueList($in_list, $secondParameter = NULL) {
01230                 if (is_array($in_list)) {
01231                         throw new InvalidArgumentException(
01232                                 'TYPO3 Fatal Error: t3lib_div::uniqueList() does NOT support array arguments anymore! Only string comma lists!',
01233                                 1270853885
01234                         );
01235                 }
01236                 if (isset($secondParameter)) {
01237                         throw new InvalidArgumentException(
01238                                 'TYPO3 Fatal Error: t3lib_div::uniqueList() does NOT support more than a single argument value anymore. You have specified more than one!',
01239                                 1270853886
01240                         );
01241                 }
01242 
01243                 return implode(',', array_unique(self::trimExplode(',', $in_list, 1)));
01244         }
01245 
01253         public static function split_fileref($fileref) {
01254                 $reg = array();
01255                 if (preg_match('/(.*\/)(.*)$/', $fileref, $reg)) {
01256                         $info['path'] = $reg[1];
01257                         $info['file'] = $reg[2];
01258                 } else {
01259                         $info['path'] = '';
01260                         $info['file'] = $fileref;
01261                 }
01262 
01263                 $reg = '';
01264                 if (!is_dir($fileref) && preg_match('/(.*)\.([^\.]*$)/', $info['file'], $reg)) {
01265                         $info['filebody'] = $reg[1];
01266                         $info['fileext'] = strtolower($reg[2]);
01267                         $info['realFileext'] = $reg[2];
01268                 } else {
01269                         $info['filebody'] = $info['file'];
01270                         $info['fileext'] = '';
01271                 }
01272                 reset($info);
01273                 return $info;
01274         }
01275 
01292         public static function dirname($path) {
01293                 $p = self::revExplode('/', $path, 2);
01294                 return count($p) == 2 ? $p[0] : '';
01295         }
01296 
01308         public static function modifyHTMLColor($color, $R, $G, $B) {
01309                         // This takes a hex-color (# included!) and adds $R, $G and $B to the HTML-color (format: #xxxxxx) and returns the new color
01310                 $nR = self::intInRange(hexdec(substr($color, 1, 2)) + $R, 0, 255);
01311                 $nG = self::intInRange(hexdec(substr($color, 3, 2)) + $G, 0, 255);
01312                 $nB = self::intInRange(hexdec(substr($color, 5, 2)) + $B, 0, 255);
01313                 return '#' .
01314                                 substr('0' . dechex($nR), -2) .
01315                                 substr('0' . dechex($nG), -2) .
01316                                 substr('0' . dechex($nB), -2);
01317         }
01318 
01328         public static function modifyHTMLColorAll($color, $all) {
01329                 return self::modifyHTMLColor($color, $all, $all, $all);
01330         }
01331 
01340         public static function rm_endcomma($string) {
01341                 self::logDeprecatedFunction();
01342 
01343                 return rtrim($string, ',');
01344         }
01345 
01355         public static function danish_strtoupper($string) {
01356                 self::logDeprecatedFunction();
01357 
01358                 $value = strtoupper($string);
01359                 return strtr($value, array(
01360                         chr(225) => chr(193),
01361                         chr(233) => chr(201),
01362                         chr(250) => chr(218),
01363                         chr(237) => chr(205),
01364                         chr(226) => chr(196),
01365                         chr(234) => chr(203),
01366                         chr(251) => chr(220),
01367                         chr(244) => chr(214),
01368                         chr(238) => chr(207),
01369                         chr(230) => chr(198),
01370                         chr(248) => chr(216),
01371                         chr(229) => chr(197),
01372                         chr(228) => chr(196),
01373                         chr(246) => chr(214),
01374                         chr(252) => chr(220),
01375                 ));
01376         }
01377 
01388         public static function convUmlauts($str) {
01389                 self::logDeprecatedFunction();
01390 
01391                 $pattern = array(chr(228), chr(196), chr(246), chr(214), chr(252), chr(220), chr(223), chr(229), chr(197), chr(248), chr(216), chr(230), chr(198));
01392                 $replace = array('ae', 'Ae', 'oe', 'Oe', 'ue', 'Ue', 'ss', 'aa', 'AA', 'oe', 'OE', 'ae', 'AE');
01393                 return str_replace($pattern, $replace, $str);
01394         }
01395 
01402         public static function testInt($var) {
01403                 if ($var === '') {
01404                         return FALSE;
01405                 }
01406                 return (string) intval($var) === (string) $var;
01407         }
01408 
01417         public static function isFirstPartOfStr($str, $partStr) {
01418                 return $partStr != '' && strpos((string) $str, (string) $partStr, 0) === 0;
01419         }
01420 
01429         public static function formatSize($sizeInBytes, $labels = '') {
01430 
01431                         // Set labels:
01432                 if (strlen($labels) == 0) {
01433                         $labels = ' | K| M| G';
01434                 } else {
01435                         $labels = str_replace('"', '', $labels);
01436                 }
01437                 $labelArr = explode('|', $labels);
01438 
01439                         // Find size:
01440                 if ($sizeInBytes > 900) {
01441                         if ($sizeInBytes > 900000000) { // GB
01442                                 $val = $sizeInBytes / (1024 * 1024 * 1024);
01443                                 return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[3];
01444                         }
01445                         elseif ($sizeInBytes > 900000) { // MB
01446                                 $val = $sizeInBytes / (1024 * 1024);
01447                                 return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[2];
01448                         } else { // KB
01449                                 $val = $sizeInBytes / (1024);
01450                                 return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[1];
01451                         }
01452                 } else { // Bytes
01453                         return $sizeInBytes . $labelArr[0];
01454                 }
01455         }
01456 
01464         public static function convertMicrotime($microtime) {
01465                 $parts = explode(' ', $microtime);
01466                 return round(($parts[0] + $parts[1]) * 1000);
01467         }
01468 
01478         public static function splitCalc($string, $operators) {
01479                 $res = Array();
01480                 $sign = '+';
01481                 while ($string) {
01482                         $valueLen = strcspn($string, $operators);
01483                         $value = substr($string, 0, $valueLen);
01484                         $res[] = Array($sign, trim($value));
01485                         $sign = substr($string, $valueLen, 1);
01486                         $string = substr($string, $valueLen + 1);
01487                 }
01488                 reset($res);
01489                 return $res;
01490         }
01491 
01500         public static function calcPriority($string) {
01501                 $string = preg_replace('/[[:space:]]*/', '', $string); // removing all whitespace
01502                 $string = '+' . $string; // Ensuring an operator for the first entrance
01503                 $qm = '\*\/\+-^%';
01504                 $regex = '([' . $qm . '])([' . $qm . ']?[0-9\.]*)';
01505                         // split the expression here:
01506                 $reg = array();
01507                 preg_match_all('/' . $regex . '/', $string, $reg);
01508 
01509                 reset($reg[2]);
01510                 $number = 0;
01511                 $Msign = '+';
01512                 $err = '';
01513                 $buffer = doubleval(current($reg[2]));
01514                 next($reg[2]); // Advance pointer
01515 
01516                 while (list($k, $v) = each($reg[2])) {
01517                         $v = doubleval($v);
01518                         $sign = $reg[1][$k];
01519                         if ($sign == '+' || $sign == '-') {
01520                                 $number = $Msign == '-' ? $number -= $buffer : $number += $buffer;
01521                                 $Msign = $sign;
01522                                 $buffer = $v;
01523                         } else {
01524                                 if ($sign == '/') {
01525                                         if ($v) {
01526                                                 $buffer /= $v;
01527                                         } else {
01528                                                 $err = 'dividing by zero';
01529                                         }
01530                                 }
01531                                 if ($sign == '%') {
01532                                         if ($v) {
01533                                                 $buffer %= $v;
01534                                         } else {
01535                                                 $err = 'dividing by zero';
01536                                         }
01537                                 }
01538                                 if ($sign == '*') {
01539                                         $buffer *= $v;
01540                                 }
01541                                 if ($sign == '^') {
01542                                         $buffer = pow($buffer, $v);
01543                                 }
01544                         }
01545                 }
01546                 $number = $Msign == '-' ? $number -= $buffer : $number += $buffer;
01547                 return $err ? 'ERROR: ' . $err : $number;
01548         }
01549 
01558         public static function calcParenthesis($string) {
01559                 $securC = 100;
01560                 do {
01561                         $valueLenO = strcspn($string, '(');
01562                         $valueLenC = strcspn($string, ')');
01563                         if ($valueLenC == strlen($string) || $valueLenC < $valueLenO) {
01564                                 $value = self::calcPriority(substr($string, 0, $valueLenC));
01565                                 $string = $value . substr($string, $valueLenC + 1);
01566                                 return $string;
01567                         } else {
01568                                 $string = substr($string, 0, $valueLenO) . self::calcParenthesis(substr($string, $valueLenO + 1));
01569                         }
01570                                 // Security:
01571                         $securC--;
01572                         if ($securC <= 0) {
01573                                 break;
01574                         }
01575                 } while ($valueLenO < strlen($string));
01576                 return $string;
01577         }
01578 
01586         public static function htmlspecialchars_decode($value) {
01587                 $value = str_replace('&gt;', '>', $value);
01588                 $value = str_replace('&lt;', '<', $value);
01589                 $value = str_replace('&quot;', '"', $value);
01590                 $value = str_replace('&amp;', '&', $value);
01591                 return $value;
01592         }
01593 
01601         public static function deHSCentities($str) {
01602                 return preg_replace('/&amp;([#[:alnum:]]*;)/', '&\1', $str);
01603         }
01604 
01614         public static function slashJS($string, $extended = 0, $char = "'") {
01615                 if ($extended) {
01616                         $string = str_replace("\\", "\\\\", $string);
01617                 }
01618                 return str_replace($char, "\\" . $char, $string);
01619         }
01620 
01629         public static function rawUrlEncodeJS($str) {
01630                 return str_replace('%20', ' ', rawurlencode($str));
01631         }
01632 
01641         public static function rawUrlEncodeFP($str) {
01642                 return str_replace('%2F', '/', rawurlencode($str));
01643         }
01644 
01652         public static function validEmail($email) {
01653                         // enforce maximum length to prevent libpcre recursion crash bug #52929 in PHP
01654                         // fixed in PHP 5.2+ later than Sept 2010; length restriction per SMTP RFC 2821
01655                 if (strlen($email) > 320) {
01656                         return FALSE;
01657                 }
01658                 return (filter_var($email, FILTER_VALIDATE_EMAIL) !== FALSE);
01659         }
01660 
01673         public static function isBrokenEmailEnvironment() {
01674                 return TYPO3_OS == 'WIN' || (FALSE !== strpos(ini_get('sendmail_path'), 'mini_sendmail'));
01675         }
01676 
01684         public static function normalizeMailAddress($address) {
01685                 if (self::isBrokenEmailEnvironment() && FALSE !== ($pos1 = strrpos($address, '<'))) {
01686                         $pos2 = strpos($address, '>', $pos1);
01687                         $address = substr($address, $pos1 + 1, ($pos2 ? $pos2 : strlen($address)) - $pos1 - 1);
01688                 }
01689                 return $address;
01690         }
01691 
01701         public static function formatForTextarea($content) {
01702                 return LF . htmlspecialchars($content);
01703         }
01704 
01714         public static function strtoupper($str) {
01715                 return strtr((string) $str, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
01716         }
01717 
01727         public static function strtolower($str) {
01728                 return strtr((string) $str, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
01729         }
01730 
01739         public static function generateRandomBytes($count) {
01740                 $output = '';
01741                         // /dev/urandom is available on many *nix systems and is considered
01742                         // the best commonly available pseudo-random source.
01743                 if (TYPO3_OS != 'WIN' && ($fh = @fopen('/dev/urandom', 'rb'))) {
01744                         $output = fread($fh, $count);
01745                         fclose($fh);
01746                 } elseif (TYPO3_OS == 'WIN') {
01747                         if (class_exists('COM')) {
01748                                 try {
01749                                         $com = new COM('CAPICOM.Utilities.1');
01750                                         $output = base64_decode($com->GetRandom($count, 0));
01751                                 } catch (Exception $e) {
01752                                         // CAPICOM not installed
01753                                 }
01754                         }
01755                         if ($output === '' && version_compare(PHP_VERSION, '5.3.0', '>=')) {
01756                                 if (function_exists('mcrypt_create_iv')) {
01757                                         $output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
01758                                 } elseif (function_exists('openssl_random_pseudo_bytes')) {
01759                                         $isStrong = NULL;
01760                                         $output = openssl_random_pseudo_bytes($count, $isStrong);
01761                                                 // skip ssl since it wasn't using the strong algo
01762                                         if ($isStrong !== TRUE) {
01763                                                 $output = '';
01764                                         }
01765                                 }
01766                         }
01767                 }
01768 
01769                         // fallback if other random byte generation failed until now
01770                 if (!isset($output{$count - 1})) {
01771                                 // We initialize with the somewhat random.
01772                         $randomState = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']
01773                                         . base_convert(memory_get_usage() % pow(10, 6), 10, 2)
01774                                         . microtime() . uniqid('') . getmypid();
01775                         while (!isset($output{$count - 1})) {
01776                                 $randomState = sha1(microtime() . mt_rand() . $randomState);
01777                                 $output .= sha1(mt_rand() . $randomState, TRUE);
01778                         }
01779                         $output = substr($output, strlen($output) - $count, $count);
01780                 }
01781                 return $output;
01782         }
01783 
01790         public static function getRandomHexString($count) {
01791                 return substr(bin2hex(self::generateRandomBytes(intval(($count + 1) / 2))), 0, $count);
01792         }
01793 
01801         public static function underscoredToUpperCamelCase($string) {
01802                 $upperCamelCase = str_replace(' ', '', ucwords(str_replace('_', ' ', self::strtolower($string))));
01803                 return $upperCamelCase;
01804         }
01805 
01813         public static function underscoredToLowerCamelCase($string) {
01814                 $upperCamelCase = str_replace(' ', '', ucwords(str_replace('_', ' ', self::strtolower($string))));
01815                 $lowerCamelCase = self::lcfirst($upperCamelCase);
01816                 return $lowerCamelCase;
01817         }
01818 
01826         public static function camelCaseToLowerCaseUnderscored($string) {
01827                 return self::strtolower(preg_replace('/(?<=\w)([A-Z])/', '_\\1', $string));
01828         }
01829 
01837         public static function lcfirst($string) {
01838                 return self::strtolower(substr($string, 0, 1)) . substr($string, 1);
01839         }
01840 
01847         public static function isValidUrl($url) {
01848                 return (filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED) !== FALSE);
01849         }
01850 
01851 
01852         /*************************
01853          *
01854          * ARRAY FUNCTIONS
01855          *
01856          *************************/
01857 
01881         public static function inArray(array $in_array, $item) {
01882                 foreach ($in_array as $val) {
01883                         if (!is_array($val) && !strcmp($val, $item)) {
01884                                 return TRUE;
01885                         }
01886                 }
01887                 return FALSE;
01888         }
01889 
01903         public static function intExplode($delimiter, $string, $onlyNonEmptyValues = FALSE, $limit = 0) {
01904                 $explodedValues = self::trimExplode($delimiter, $string, $onlyNonEmptyValues, $limit);
01905                 return array_map('intval', $explodedValues);
01906         }
01907 
01918         public static function revExplode($delimiter, $string, $count = 0) {
01919                 $explodedValues = explode($delimiter, strrev($string), $count);
01920                 $explodedValues = array_map('strrev', $explodedValues);
01921                 return array_reverse($explodedValues);
01922         }
01923 
01940         public static function trimExplode($delim, $string, $removeEmptyValues = FALSE, $limit = 0) {
01941                 $explodedValues = explode($delim, $string);
01942 
01943                 $result = array_map('trim', $explodedValues);
01944 
01945                 if ($removeEmptyValues) {
01946                         $temp = array();
01947                         foreach ($result as $value) {
01948                                 if ($value !== '') {
01949                                         $temp[] = $value;
01950                                 }
01951                         }
01952                         $result = $temp;
01953                 }
01954 
01955                 if ($limit != 0) {
01956                         if ($limit < 0) {
01957                                 $result = array_slice($result, 0, $limit);
01958                         } elseif (count($result) > $limit) {
01959                                 $lastElements = array_slice($result, $limit - 1);
01960                                 $result = array_slice($result, 0, $limit - 1);
01961                                 $result[] = implode($delim, $lastElements);
01962                         }
01963                 }
01964 
01965                 return $result;
01966         }
01967 
01977         public static function uniqueArray(array $valueArray) {
01978                 self::logDeprecatedFunction();
01979 
01980                 return array_unique($valueArray);
01981         }
01982 
01991         public static function removeArrayEntryByValue(array $array, $cmpValue) {
01992                 foreach ($array as $k => $v) {
01993                         if (is_array($v)) {
01994                                 $array[$k] = self::removeArrayEntryByValue($v, $cmpValue);
01995                         } elseif (!strcmp($v, $cmpValue)) {
01996                                 unset($array[$k]);
01997                         }
01998                 }
01999                 return $array;
02000         }
02001 
02025         public static function keepItemsInArray(array $array, $keepItems, $getValueFunc = NULL) {
02026                 if ($array) {
02027                                 // Convert strings to arrays:
02028                         if (is_string($keepItems)) {
02029                                 $keepItems = self::trimExplode(',', $keepItems);
02030                         }
02031                                 // create_function() returns a string:
02032                         if (!is_string($getValueFunc)) {
02033                                 $getValueFunc = NULL;
02034                         }
02035                                 // Do the filtering:
02036                         if (is_array($keepItems) && count($keepItems)) {
02037                                 foreach ($array as $key => $value) {
02038                                                 // Get the value to compare by using the callback function:
02039                                         $keepValue = (isset($getValueFunc) ? $getValueFunc($value) : $value);
02040                                         if (!in_array($keepValue, $keepItems)) {
02041                                                 unset($array[$key]);
02042                                         }
02043                                 }
02044                         }
02045                 }
02046                 return $array;
02047         }
02048 
02061         public static function implodeArrayForUrl($name, array $theArray, $str = '', $skipBlank = FALSE, $rawurlencodeParamName = FALSE) {
02062                 foreach ($theArray as $Akey => $AVal) {
02063                         $thisKeyName = $name ? $name . '[' . $Akey . ']' : $Akey;
02064                         if (is_array($AVal)) {
02065                                 $str = self::implodeArrayForUrl($thisKeyName, $AVal, $str, $skipBlank, $rawurlencodeParamName);
02066                         } else {
02067                                 if (!$skipBlank || strcmp($AVal, '')) {
02068                                         $str .= '&' . ($rawurlencodeParamName ? rawurlencode($thisKeyName) : $thisKeyName) .
02069                                                         '=' . rawurlencode($AVal);
02070                                 }
02071                         }
02072                 }
02073                 return $str;
02074         }
02075 
02084         public static function explodeUrl2Array($string, $multidim = FALSE) {
02085                 $output = array();
02086                 if ($multidim) {
02087                         parse_str($string, $output);
02088                 } else {
02089                         $p = explode('&', $string);
02090                         foreach ($p as $v) {
02091                                 if (strlen($v)) {
02092                                         list($pK, $pV) = explode('=', $v, 2);
02093                                         $output[rawurldecode($pK)] = rawurldecode($pV);
02094                                 }
02095                         }
02096                 }
02097                 return $output;
02098         }
02099 
02110         public static function compileSelectedGetVarsFromArray($varList, array $getArray, $GPvarAlt = 1) {
02111                 $keys = self::trimExplode(',', $varList, 1);
02112                 $outArr = array();
02113                 foreach ($keys as $v) {
02114                         if (isset($getArray[$v])) {
02115                                 $outArr[$v] = $getArray[$v];
02116                         } elseif ($GPvarAlt) {
02117                                 $outArr[$v] = self::_GP($v);
02118                         }
02119                 }
02120                 return $outArr;
02121         }
02122 
02133         public static function addSlashesOnArray(array &$theArray) {
02134                 foreach ($theArray as &$value) {
02135                         if (is_array($value)) {
02136                                 self::addSlashesOnArray($value);
02137                         } else {
02138                                 $value = addslashes($value);
02139                         }
02140                         unset($value);
02141                 }
02142                 reset($theArray);
02143         }
02144 
02155         public static function stripSlashesOnArray(array &$theArray) {
02156                 foreach ($theArray as &$value) {
02157                         if (is_array($value)) {
02158                                 self::stripSlashesOnArray($value);
02159                         } else {
02160                                 $value = stripslashes($value);
02161                         }
02162                         unset($value);
02163                 }
02164                 reset($theArray);
02165         }
02166 
02175         public static function slashArray(array $arr, $cmd) {
02176                 if ($cmd == 'strip') {
02177                         self::stripSlashesOnArray($arr);
02178                 }
02179                 if ($cmd == 'add') {
02180                         self::addSlashesOnArray($arr);
02181                 }
02182                 return $arr;
02183         }
02184 
02190         function remapArrayKeys(&$array, $mappingTable) {
02191                 if (is_array($mappingTable)) {
02192                         foreach ($mappingTable as $old => $new) {
02193                                 if ($new && isset($array[$old])) {
02194                                         $array[$new] = $array[$old];
02195                                         unset ($array[$old]);
02196                                 }
02197                         }
02198                 }
02199         }
02200 
02201 
02215         public static function array_merge_recursive_overrule(array $arr0, array $arr1, $notAddKeys = 0, $includeEmtpyValues = TRUE) {
02216                 foreach ($arr1 as $key => $val) {
02217                         if (is_array($arr0[$key])) {
02218                                 if (is_array($arr1[$key])) {
02219                                         $arr0[$key] = self::array_merge_recursive_overrule($arr0[$key], $arr1[$key], $notAddKeys, $includeEmtpyValues);
02220                                 }
02221                         } else {
02222                                 if ($notAddKeys) {
02223                                         if (isset($arr0[$key])) {
02224                                                 if ($includeEmtpyValues || $val) {
02225                                                         $arr0[$key] = $val;
02226                                                 }
02227                                         }
02228                                 } else {
02229                                         if ($includeEmtpyValues || $val) {
02230                                                 $arr0[$key] = $val;
02231                                         }
02232                                 }
02233                         }
02234                 }
02235                 reset($arr0);
02236                 return $arr0;
02237         }
02238 
02247         public static function array_merge(array $arr1, array $arr2) {
02248                 return $arr2 + $arr1;
02249         }
02250 
02259         public static function arrayDiffAssocRecursive(array $array1, array $array2) {
02260                 $differenceArray = array();
02261                 foreach ($array1 as $key => $value) {
02262                         if (!array_key_exists($key, $array2)) {
02263                                 $differenceArray[$key] = $value;
02264                         } elseif (is_array($value)) {
02265                                 if (is_array($array2[$key])) {
02266                                         $differenceArray[$key] = self::arrayDiffAssocRecursive($value, $array2[$key]);
02267                                 }
02268                         }
02269                 }
02270 
02271                 return $differenceArray;
02272         }
02273 
02283         public static function csvValues(array $row, $delim = ',', $quote = '"') {
02284                 reset($row);
02285                 $out = array();
02286                 foreach ($row as $value) {
02287                         $out[] = str_replace($quote, $quote . $quote, $value);
02288                 }
02289                 $str = $quote . implode($quote . $delim . $quote, $out) . $quote;
02290                 return $str;
02291         }
02292 
02301         public static function array2json(array $jsonArray) {
02302                 self::logDeprecatedFunction();
02303 
02304                 return json_encode($jsonArray);
02305         }
02306 
02314         public static function removeDotsFromTS(array $ts) {
02315                 $out = array();
02316                 foreach ($ts as $key => $value) {
02317                         if (is_array($value)) {
02318                                 $key = rtrim($key, '.');
02319                                 $out[$key] = self::removeDotsFromTS($value);
02320                         } else {
02321                                 $out[$key] = $value;
02322                         }
02323                 }
02324                 return $out;
02325         }
02326 
02333         public static function naturalKeySortRecursive(&$array) {
02334                 if (!is_array($array)) {
02335                         return FALSE;
02336                 }
02337                 uksort($array, 'strnatcasecmp');
02338                 foreach ($array as $key => $value) {
02339                         self::naturalKeySortRecursive($array[$key]);
02340                 }
02341                 return TRUE;
02342         }
02343 
02344 
02345         /*************************
02346          *
02347          * HTML/XML PROCESSING
02348          *
02349          *************************/
02350 
02360         public static function get_tag_attributes($tag) {
02361                 $components = self::split_tag_attributes($tag);
02362                 $name = ''; // attribute name is stored here
02363                 $valuemode = FALSE;
02364                 $attributes = array();
02365                 foreach ($components as $key => $val) {
02366                         if ($val != '=') { // Only if $name is set (if there is an attribute, that waits for a value), that valuemode is enabled. This ensures that the attribute is assigned it's value
02367                                 if ($valuemode) {
02368                                         if ($name) {
02369                                                 $attributes[$name] = $val;
02370                                                 $name = '';
02371                                         }
02372                                 } else {
02373                                         if ($key = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $val))) {
02374                                                 $attributes[$key] = '';
02375                                                 $name = $key;
02376                                         }
02377                                 }
02378                                 $valuemode = FALSE;
02379                         } else {
02380                                 $valuemode = TRUE;
02381                         }
02382                 }
02383                 return $attributes;
02384         }
02385 
02394         public static function split_tag_attributes($tag) {
02395                 $tag_tmp = trim(preg_replace('/^<[^[:space:]]*/', '', trim($tag)));
02396                         // Removes any > in the end of the string
02397                 $tag_tmp = trim(rtrim($tag_tmp, '>'));
02398 
02399                 $value = array();
02400                 while (strcmp($tag_tmp, '')) { // Compared with empty string instead , 030102
02401                         $firstChar = substr($tag_tmp, 0, 1);
02402                         if (!strcmp($firstChar, '"') || !strcmp($firstChar, "'")) {
02403                                 $reg = explode($firstChar, $tag_tmp, 3);
02404                                 $value[] = $reg[1];
02405                                 $tag_tmp = trim($reg[2]);
02406                         } elseif (!strcmp($firstChar, '=')) {
02407                                 $value[] = '=';
02408                                 $tag_tmp = trim(substr($tag_tmp, 1)); // Removes = chars.
02409                         } else {
02410                                         // There are '' around the value. We look for the next ' ' or '>'
02411                                 $reg = preg_split('/[[:space:]=]/', $tag_tmp, 2);
02412                                 $value[] = trim($reg[0]);
02413                                 $tag_tmp = trim(substr($tag_tmp, strlen($reg[0]), 1) . $reg[1]);
02414                         }
02415                 }
02416                 reset($value);
02417                 return $value;
02418         }
02419 
02429         public static function implodeAttributes(array $arr, $xhtmlSafe = FALSE, $dontOmitBlankAttribs = FALSE) {
02430                 if ($xhtmlSafe) {
02431                         $newArr = array();
02432                         foreach ($arr as $p => $v) {
02433                                 if (!isset($newArr[strtolower($p)])) {
02434                                         $newArr[strtolower($p)] = htmlspecialchars($v);
02435                                 }
02436                         }
02437                         $arr = $newArr;
02438                 }
02439                 $list = array();
02440                 foreach ($arr as $p => $v) {
02441                         if (strcmp($v, '') || $dontOmitBlankAttribs) {
02442                                 $list[] = $p . '="' . $v . '"';
02443                         }
02444                 }
02445                 return implode(' ', $list);
02446         }
02447 
02458         public static function implodeParams(array $arr, $xhtmlSafe = FALSE, $dontOmitBlankAttribs = FALSE) {
02459                 self::logDeprecatedFunction();
02460 
02461                 return self::implodeAttributes($arr, $xhtmlSafe, $dontOmitBlankAttribs);
02462         }
02463 
02475         public static function wrapJS($string, $linebreak = TRUE) {
02476                 if (trim($string)) {
02477                                 // <script wrapped in nl?
02478                         $cr = $linebreak ? LF : '';
02479 
02480                                 // remove nl from the beginning
02481                         $string = preg_replace('/^\n+/', '', $string);
02482                                 // re-ident to one tab using the first line as reference
02483                         $match = array();
02484                         if (preg_match('/^(\t+)/', $string, $match)) {
02485                                 $string = str_replace($match[1], TAB, $string);
02486                         }
02487                         $string = $cr . '<script type="text/javascript">
02488 /*<![CDATA[*/
02489 ' . $string . '
02490 /*]]>*/
02491 </script>' . $cr;
02492                 }
02493                 return trim($string);
02494         }
02495 
02496 
02506         public static function xml2tree($string, $depth = 999) {
02507                 $parser = xml_parser_create();
02508                 $vals = array();
02509                 $index = array();
02510 
02511                 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
02512                 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
02513                 xml_parse_into_struct($parser, $string, $vals, $index);
02514 
02515                 if (xml_get_error_code($parser)) {
02516                         return 'Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser));
02517                 }
02518                 xml_parser_free($parser);
02519 
02520                 $stack = array(array());
02521                 $stacktop = 0;
02522                 $startPoint = 0;
02523 
02524                 $tagi = array();
02525                 foreach ($vals as $key => $val) {
02526                         $type = $val['type'];
02527 
02528                                 // open tag:
02529                         if ($type == 'open' || $type == 'complete') {
02530                                 $stack[$stacktop++] = $tagi;
02531 
02532                                 if ($depth == $stacktop) {
02533                                         $startPoint = $key;
02534                                 }
02535 
02536                                 $tagi = array('tag' => $val['tag']);
02537 
02538                                 if (isset($val['attributes'])) {
02539                                         $tagi['attrs'] = $val['attributes'];
02540                                 }
02541                                 if (isset($val['value'])) {
02542                                         $tagi['values'][] = $val['value'];
02543                                 }
02544                         }
02545                                 // finish tag:
02546                         if ($type == 'complete' || $type == 'close') {
02547                                 $oldtagi = $tagi;
02548                                 $tagi = $stack[--$stacktop];
02549                                 $oldtag = $oldtagi['tag'];
02550                                 unset($oldtagi['tag']);
02551 
02552                                 if ($depth == ($stacktop + 1)) {
02553                                         if ($key - $startPoint > 0) {
02554                                                 $partArray = array_slice(
02555                                                         $vals,
02556                                                                 $startPoint + 1,
02557                                                                 $key - $startPoint - 1
02558                                                 );
02559                                                 #$oldtagi=array('XMLvalue'=>self::xmlRecompileFromStructValArray($partArray));
02560                                                 $oldtagi['XMLvalue'] = self::xmlRecompileFromStructValArray($partArray);
02561                                         } else {
02562                                                 $oldtagi['XMLvalue'] = $oldtagi['values'][0];
02563                                         }
02564                                 }
02565 
02566                                 $tagi['ch'][$oldtag][] = $oldtagi;
02567                                 unset($oldtagi);
02568                         }
02569                                 // cdata
02570                         if ($type == 'cdata') {
02571                                 $tagi['values'][] = $val['value'];
02572                         }
02573                 }
02574                 return $tagi['ch'];
02575         }
02576 
02587         public static function array2xml_cs(array $array, $docTag = 'phparray', array $options = array(), $charset = '') {
02588 
02589                         // Figure out charset if not given explicitly:
02590                 if (!$charset) {
02591                         if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) { // First priority: forceCharset! If set, this will be authoritative!
02592                                 $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
02593                         } elseif (is_object($GLOBALS['LANG'])) {
02594                                 $charset = $GLOBALS['LANG']->charSet; // If "LANG" is around, that will hold the current charset
02595                         } else {
02596                                 $charset = 'iso-8859-1'; // THIS is just a hopeful guess!
02597                         }
02598                 }
02599 
02600                         // Return XML:
02601                 return '<?xml version="1.0" encoding="' . htmlspecialchars($charset) . '" standalone="yes" ?>' . LF .
02602                                 self::array2xml($array, '', 0, $docTag, 0, $options);
02603         }
02604 
02628         public static function array2xml(array $array, $NSprefix = '', $level = 0, $docTag = 'phparray', $spaceInd = 0, array $options = array(), array $stackData = array()) {
02629                         // The list of byte values which will trigger binary-safe storage. If any value has one of these char values in it, it will be encoded in base64
02630                 $binaryChars = chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8) .
02631                                 chr(11) . chr(12) . chr(14) . chr(15) . chr(16) . chr(17) . chr(18) . chr(19) .
02632                                 chr(20) . chr(21) . chr(22) . chr(23) . chr(24) . chr(25) . chr(26) . chr(27) . chr(28) . chr(29) .
02633                                 chr(30) . chr(31);
02634                         // Set indenting mode:
02635                 $indentChar = $spaceInd ? ' ' : TAB;
02636                 $indentN = $spaceInd > 0 ? $spaceInd : 1;
02637                 $nl = ($spaceInd >= 0 ? LF : '');
02638 
02639                         // Init output variable:
02640                 $output = '';
02641 
02642                         // Traverse the input array
02643                 foreach ($array as $k => $v) {
02644                         $attr = '';
02645                         $tagName = $k;
02646 
02647                                 // Construct the tag name.
02648                         if (isset($options['grandParentTagMap'][$stackData['grandParentTagName'] . '/' . $stackData['parentTagName']])) { // Use tag based on grand-parent + parent tag name
02649                                 $attr .= ' index="' . htmlspecialchars($tagName) . '"';
02650                                 $tagName = (string) $options['grandParentTagMap'][$stackData['grandParentTagName'] . '/' . $stackData['parentTagName']];
02651                         } elseif (isset($options['parentTagMap'][$stackData['parentTagName'] . ':_IS_NUM']) && self::testInt($tagName)) { // Use tag based on parent tag name + if current tag is numeric
02652                                 $attr .= ' index="' . htmlspecialchars($tagName) . '"';
02653                                 $tagName = (string) $options['parentTagMap'][$stackData['parentTagName'] . ':_IS_NUM'];
02654                         } elseif (isset($options['parentTagMap'][$stackData['parentTagName'] . ':' . $tagName])) { // Use tag based on parent tag name + current tag
02655                                 $attr .= ' index="' . htmlspecialchars($tagName) . '"';
02656                                 $tagName = (string) $options['parentTagMap'][$stackData['parentTagName'] . ':' . $tagName];
02657                         } elseif (isset($options['parentTagMap'][$stackData['parentTagName']])) { // Use tag based on parent tag name:
02658                                 $attr .= ' index="' . htmlspecialchars($tagName) . '"';
02659                                 $tagName = (string) $options['parentTagMap'][$stackData['parentTagName']];
02660                         } elseif (!strcmp(intval($tagName), $tagName)) { // If integer...;
02661                                 if ($options['useNindex']) { // If numeric key, prefix "n"
02662                                         $tagName = 'n' . $tagName;
02663                                 } else { // Use special tag for num. keys:
02664                                         $attr .= ' index="' . $tagName . '"';
02665                                         $tagName = $options['useIndexTagForNum'] ? $options['useIndexTagForNum'] : 'numIndex';
02666                                 }
02667                         } elseif ($options['useIndexTagForAssoc']) { // Use tag for all associative keys:
02668                                 $attr .= ' index="' . htmlspecialchars($tagName) . '"';
02669                                 $tagName = $options['useIndexTagForAssoc'];
02670                         }
02671 
02672                                 // The tag name is cleaned up so only alphanumeric chars (plus - and _) are in there and not longer than 100 chars either.
02673                         $tagName = substr(preg_replace('/[^[:alnum:]_-]/', '', $tagName), 0, 100);
02674 
02675                                 // If the value is an array then we will call this function recursively:
02676                         if (is_array($v)) {
02677 
02678                                         // Sub elements:
02679                                 if ($options['alt_options'][$stackData['path'] . '/' . $tagName]) {
02680                                         $subOptions = $options['alt_options'][$stackData['path'] . '/' . $tagName];
02681                                         $clearStackPath = $subOptions['clearStackPath'];
02682                                 } else {
02683                                         $subOptions = $options;
02684                                         $clearStackPath = FALSE;
02685                                 }
02686 
02687                                 $content = $nl .
02688                                                 self::array2xml(
02689                                                         $v,
02690                                                         $NSprefix,
02691                                                                 $level + 1,
02692                                                         '',
02693                                                         $spaceInd,
02694                                                         $subOptions,
02695                                                         array(
02696                                                                 'parentTagName' => $tagName,
02697                                                                 'grandParentTagName' => $stackData['parentTagName'],
02698                                                                 'path' => $clearStackPath ? '' : $stackData['path'] . '/' . $tagName,
02699                                                         )
02700                                                 ) .
02701                                                 ($spaceInd >= 0 ? str_pad('', ($level + 1) * $indentN, $indentChar) : '');
02702                                 if ((int) $options['disableTypeAttrib'] != 2) { // Do not set "type = array". Makes prettier XML but means that empty arrays are not restored with xml2array
02703                                         $attr .= ' type="array"';
02704                                 }
02705                         } else { // Just a value:
02706 
02707                                         // Look for binary chars:
02708                                 $vLen = strlen($v); // check for length, because PHP 5.2.0 may crash when first argument of strcspn is empty
02709                                 if ($vLen && strcspn($v, $binaryChars) != $vLen) { // Go for base64 encoding if the initial segment NOT matching any binary char has the same length as the whole string!
02710                                                 // If the value contained binary chars then we base64-encode it an set an attribute to notify this situation:
02711                                         $content = $nl . chunk_split(base64_encode($v));
02712                                         $attr .= ' base64="1"';
02713                                 } else {
02714                                                 // Otherwise, just htmlspecialchar the stuff:
02715                                         $content = htmlspecialchars($v);
02716                                         $dType = gettype($v);
02717                                         if ($dType == 'string') {
02718                                                 if ($options['useCDATA'] && $content != $v) {
02719                                                         $content = '<![CDATA[' . $v . ']]>';
02720                                                 }
02721                                         } elseif (!$options['disableTypeAttrib']) {
02722                                                 $attr .= ' type="' . $dType . '"';
02723                                         }
02724                                 }
02725                         }
02726 
02727                                 // Add the element to the output string:
02728                         $output .= ($spaceInd >= 0 ? str_pad('', ($level + 1) * $indentN, $indentChar) : '') . '<' . $NSprefix . $tagName . $attr . '>' . $content . '</' . $NSprefix . $tagName . '>' . $nl;
02729                 }
02730 
02731                         // If we are at the outer-most level, then we finally wrap it all in the document tags and return that as the value:
02732                 if (!$level) {
02733                         $output =
02734                                         '<' . $docTag . '>' . $nl .
02735                                                         $output .
02736                                                         '</' . $docTag . '>';
02737                 }
02738 
02739                 return $output;
02740         }
02741 
02755         public static function xml2array($string, $NSprefix = '', $reportDocTag = FALSE) {
02756                 static $firstLevelCache = array();
02757 
02758                 $identifier = md5($string . $NSprefix . ($reportDocTag ? '1' : '0'));
02759 
02760                         // look up in first level cache
02761                 if (!empty($firstLevelCache[$identifier])) {
02762                         $array = $firstLevelCache[$identifier];
02763                 } else {
02764                                 // look up in second level cache
02765                         $cacheContent = t3lib_pageSelect::getHash($identifier, 0);
02766                         $array = unserialize($cacheContent);
02767 
02768                         if ($array === FALSE) {
02769                                 $array = self::xml2arrayProcess($string, $NSprefix, $reportDocTag);
02770                                 t3lib_pageSelect::storeHash($identifier, serialize($array), 'ident_xml2array');
02771                         }
02772                                 // store content in first level cache
02773                         $firstLevelCache[$identifier] = $array;
02774                 }
02775                 return $array;
02776         }
02777 
02789         protected function xml2arrayProcess($string, $NSprefix = '', $reportDocTag = FALSE) {
02790                 global $TYPO3_CONF_VARS;
02791 
02792                         // Create parser:
02793                 $parser = xml_parser_create();
02794                 $vals = array();
02795                 $index = array();
02796 
02797                 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
02798                 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
02799 
02800                         // default output charset is UTF-8, only ASCII, ISO-8859-1 and UTF-8 are supported!!!
02801                 $match = array();
02802                 preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/', substr($string, 0, 200), $match);
02803                 $theCharset = $match[1] ? $match[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1');
02804                 xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset); // us-ascii / utf-8 / iso-8859-1
02805 
02806                         // Parse content:
02807                 xml_parse_into_struct($parser, $string, $vals, $index);
02808 
02809                         // If error, return error message:
02810                 if (xml_get_error_code($parser)) {
02811                         return 'Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser));
02812                 }
02813                 xml_parser_free($parser);
02814 
02815                         // Init vars:
02816                 $stack = array(array());
02817                 $stacktop = 0;
02818                 $current = array();
02819                 $tagName = '';
02820                 $documentTag = '';
02821 
02822                         // Traverse the parsed XML structure:
02823                 foreach ($vals as $key => $val) {
02824 
02825                                 // First, process the tag-name (which is used in both cases, whether "complete" or "close")
02826                         $tagName = $val['tag'];
02827                         if (!$documentTag) {
02828                                 $documentTag = $tagName;
02829                         }
02830 
02831                                 // Test for name space:
02832                         $tagName = ($NSprefix && substr($tagName, 0, strlen($NSprefix)) == $NSprefix) ? substr($tagName, strlen($NSprefix)) : $tagName;
02833 
02834                                 // Test for numeric tag, encoded on the form "nXXX":
02835                         $testNtag = substr($tagName, 1); // Closing tag.
02836                         $tagName = (substr($tagName, 0, 1) == 'n' && !strcmp(intval($testNtag), $testNtag)) ? intval($testNtag) : $tagName;
02837 
02838                                 // Test for alternative index value:
02839                         if (strlen($val['attributes']['index'])) {
02840                                 $tagName = $val['attributes']['index'];
02841                         }
02842 
02843                                 // Setting tag-values, manage stack:
02844                         switch ($val['type']) {
02845                                 case 'open': // If open tag it means there is an array stored in sub-elements. Therefore increase the stackpointer and reset the accumulation array:
02846                                         $current[$tagName] = array(); // Setting blank place holder
02847                                         $stack[$stacktop++] = $current;
02848                                         $current = array();
02849                                         break;
02850                                 case 'close': // If the tag is "close" then it is an array which is closing and we decrease the stack pointer.
02851                                         $oldCurrent = $current;
02852                                         $current = $stack[--$stacktop];
02853                                         end($current); // Going to the end of array to get placeholder key, key($current), and fill in array next:
02854                                         $current[key($current)] = $oldCurrent;
02855                                         unset($oldCurrent);
02856                                         break;
02857                                 case 'complete': // If "complete", then it's a value. If the attribute "base64" is set, then decode the value, otherwise just set it.
02858                                         if ($val['attributes']['base64']) {
02859                                                 $current[$tagName] = base64_decode($val['value']);
02860                                         } else {
02861                                                 $current[$tagName] = (string) $val['value']; // Had to cast it as a string - otherwise it would be evaluate false if tested with isset()!!
02862 
02863                                                         // Cast type:
02864                                                 switch ((string) $val['attributes']['type']) {
02865                                                         case 'integer':
02866                                                                 $current[$tagName] = (integer) $current[$tagName];
02867                                                                 break;
02868                                                         case 'double':
02869                                                                 $current[$tagName] = (double) $current[$tagName];
02870                                                                 break;
02871                                                         case 'boolean':
02872                                                                 $current[$tagName] = (bool) $current[$tagName];
02873                                                                 break;
02874                                                         case 'array':
02875                                                                 $current[$tagName] = array(); // MUST be an empty array since it is processed as a value; Empty arrays would end up here because they would have no tags inside...
02876                                                                 break;
02877                                                 }
02878                                         }
02879                                         break;
02880                         }
02881                 }
02882 
02883                 if ($reportDocTag) {
02884                         $current[$tagName]['_DOCUMENT_TAG'] = $documentTag;
02885                 }
02886 
02887                         // Finally return the content of the document tag.
02888                 return $current[$tagName];
02889         }
02890 
02898         public static function xmlRecompileFromStructValArray(array $vals) {
02899                 $XMLcontent = '';
02900 
02901                 foreach ($vals as $val) {
02902                         $type = $val['type'];
02903 
02904                                 // open tag:
02905                         if ($type == 'open' || $type == 'complete') {
02906                                 $XMLcontent .= '<' . $val['tag'];
02907                                 if (isset($val['attributes'])) {
02908                                         foreach ($val['attributes'] as $k => $v) {
02909                                                 $XMLcontent .= ' ' . $k . '="' . htmlspecialchars($v) . '"';
02910                                         }
02911                                 }
02912                                 if ($type == 'complete') {
02913                                         if (isset($val['value'])) {
02914                                                 $XMLcontent .= '>' . htmlspecialchars($val['value']) . '</' . $val['tag'] . '>';
02915                                         } else {
02916                                                 $XMLcontent .= '/>';
02917                                         }
02918                                 } else {
02919                                         $XMLcontent .= '>';
02920                                 }
02921 
02922                                 if ($type == 'open' && isset($val['value'])) {
02923                                         $XMLcontent .= htmlspecialchars($val['value']);
02924                                 }
02925                         }
02926                                 // finish tag:
02927                         if ($type == 'close') {
02928                                 $XMLcontent .= '</' . $val['tag'] . '>';
02929                         }
02930                                 // cdata
02931                         if ($type == 'cdata') {
02932                                 $XMLcontent .= htmlspecialchars($val['value']);
02933                         }
02934                 }
02935 
02936                 return $XMLcontent;
02937         }
02938 
02946         public static function xmlGetHeaderAttribs($xmlData) {
02947                 $match = array();
02948                 if (preg_match('/^\s*<\?xml([^>]*)\?>/', $xmlData, $match)) {
02949                         return self::get_tag_attributes($match[1]);
02950                 }
02951         }
02952 
02960         public static function minifyJavaScript($script, &$error = '') {
02961                 require_once(PATH_typo3 . 'contrib/jsmin/jsmin.php');
02962                 try {
02963                         $error = '';
02964                         $script = trim(JSMin::minify(str_replace(CR, '', $script)));
02965                 }
02966                 catch (JSMinException $e) {
02967                         $error = 'Error while minifying JavaScript: ' . $e->getMessage();
02968                         self::devLog($error, 't3lib_div', 2,
02969                                 array('JavaScript' => $script, 'Stack trace' => $e->getTrace()));
02970                 }
02971                 return $script;
02972         }
02973 
02974 
02975         /*************************
02976          *
02977          * FILES FUNCTIONS
02978          *
02979          *************************/
02980 
02992         public static function getUrl($url, $includeHeader = 0, $requestHeaders = FALSE, &$report = NULL) {
02993                 $content = FALSE;
02994 
02995                 if (isset($report)) {
02996                         $report['error'] = 0;
02997                         $report['message'] = '';
02998                 }
02999 
03000                         // use cURL for: http, https, ftp, ftps, sftp and scp
03001                 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse'] == '1' && preg_match('/^(?:http|ftp)s?|s(?:ftp|cp):/', $url)) {
03002                         if (isset($report)) {
03003                                 $report['lib'] = 'cURL';
03004                         }
03005 
03006                                 // External URL without error checking.
03007                         $ch = curl_init();
03008                         if (!$ch) {
03009                                 if (isset($report)) {
03010                                         $report['error'] = -1;
03011                                         $report['message'] = 'Couldn\'t initialize cURL.';
03012                                 }
03013                                 return FALSE;
03014                         }
03015 
03016                         curl_setopt($ch, CURLOPT_URL, $url);
03017                         curl_setopt($ch, CURLOPT_HEADER, $includeHeader ? 1 : 0);
03018                         curl_setopt($ch, CURLOPT_NOBODY, $includeHeader == 2 ? 1 : 0);
03019                         curl_setopt($ch, CURLOPT_HTTPGET, $includeHeader == 2 ? 'HEAD' : 'GET');
03020                         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
03021                         curl_setopt($ch, CURLOPT_FAILONERROR, 1);
03022                         curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, max(0, intval($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlTimeout'])));
03023 
03024                                 // may fail (PHP 5.2.0+ and 5.1.5+) when open_basedir or safe_mode are enabled
03025                         $followLocation = @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
03026 
03027                         if (is_array($requestHeaders)) {
03028                                 curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders);
03029                         }
03030 
03031                                 // (Proxy support implemented by Arco <arco@appeltaart.mine.nu>)
03032                         if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']) {
03033                                 curl_setopt($ch, CURLOPT_PROXY, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']);
03034 
03035                                 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']) {
03036                                         curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']);
03037                                 }
03038                                 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']) {
03039                                         curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']);
03040                                 }
03041                         }
03042                         $content = curl_exec($ch);
03043                         if (isset($report)) {
03044                                 if ($content === FALSE) {
03045                                         $report['error'] = curl_errno($ch);
03046                                         $report['message'] = curl_error($ch);
03047                                 } else {
03048                                         $curlInfo = curl_getinfo($ch);
03049                                                 // We hit a redirection but we couldn't follow it
03050                                         if (!$followLocation && $curlInfo['status'] >= 300 && $curlInfo['status'] < 400) {
03051                                                 $report['error'] = -1;
03052                                                 $report['message'] = 'Couldn\'t follow location redirect (either PHP configuration option safe_mode or open_basedir is in effect).';
03053                                         } elseif ($includeHeader) {
03054                                                         // Set only for $includeHeader to work exactly like PHP variant
03055                                                 $report['http_code'] = $curlInfo['http_code'];
03056                                                 $report['content_type'] = $curlInfo['content_type'];
03057                                         }
03058                                 }
03059                         }
03060                         curl_close($ch);
03061 
03062                 } elseif ($includeHeader) {
03063                         if (isset($report)) {
03064                                 $report['lib'] = 'socket';
03065                         }
03066                         $parsedURL = parse_url($url);
03067                         if (!preg_match('/^https?/', $parsedURL['scheme'])) {
03068                                 if (isset($report)) {
03069                                         $report['error'] = -1;
03070                                         $report['message'] = 'Reading headers is not allowed for this protocol.';
03071                                 }
03072                                 return FALSE;
03073                         }
03074                         $port = intval($parsedURL['port']);
03075                         if ($port < 1) {
03076                                 if ($parsedURL['scheme'] == 'http') {
03077                                         $port = ($port > 0 ? $port : 80);
03078                                         $scheme = '';
03079                                 } else {
03080                                         $port = ($port > 0 ? $port : 443);
03081                                         $scheme = 'ssl://';
03082                                 }
03083                         }
03084                         $errno = 0;
03085                                 // $errstr = '';
03086                         $fp = @fsockopen($scheme . $parsedURL['host'], $port, $errno, $errstr, 2.0);
03087                         if (!$fp || $errno > 0) {
03088                                 if (isset($report)) {
03089                                         $report['error'] = $errno ? $errno : -1;
03090                                         $report['message'] = $errno ? ($errstr ? $errstr : 'Socket error.') : 'Socket initialization error.';
03091                                 }
03092                                 return FALSE;
03093                         }
03094                         $method = ($includeHeader == 2) ? 'HEAD' : 'GET';
03095                         $msg = $method . ' ' . (isset($parsedURL['path']) ? $parsedURL['path'] : '/') .
03096                                         ($parsedURL['query'] ? '?' . $parsedURL['query'] : '') .
03097                                         ' HTTP/1.0' . CRLF . 'Host: ' .
03098                                         $parsedURL['host'] . "\r\nConnection: close\r\n";
03099                         if (is_array($requestHeaders)) {
03100                                 $msg .= implode(CRLF, $requestHeaders) . CRLF;
03101                         }
03102                         $msg .= CRLF;
03103 
03104                         fputs($fp, $msg);
03105                         while (!feof($fp)) {
03106                                 $line = fgets($fp, 2048);
03107                                 if (isset($report)) {
03108                                         if (preg_match('|^HTTP/\d\.\d +(\d+)|', $line, $status)) {
03109                                                 $report['http_code'] = $status[1];
03110                                         }
03111                                         elseif (preg_match('/^Content-Type: *(.*)/i', $line, $type)) {
03112                                                 $report['content_type'] = $type[1];
03113                                         }
03114                                 }
03115                                 $content .= $line;
03116                                 if (!strlen(trim($line))) {
03117                                         break; // Stop at the first empty line (= end of header)
03118                                 }
03119                         }
03120                         if ($includeHeader != 2) {
03121                                 $content .= stream_get_contents($fp);
03122                         }
03123                         fclose($fp);
03124 
03125                 } elseif (is_array($requestHeaders)) {
03126                         if (isset($report)) {
03127                                 $report['lib'] = 'file/context';
03128                         }
03129                         $parsedURL = parse_url($url);
03130                         if (!preg_match('/^https?/', $parsedURL['scheme'])) {
03131                                 if (isset($report)) {
03132                                         $report['error'] = -1;
03133                                         $report['message'] = 'Sending request headers is not allowed for this protocol.';
03134                                 }
03135                                 return FALSE;
03136                         }
03137                         $ctx = stream_context_create(array(
03138                                 'http' => array(
03139                                         'header' => implode(CRLF, $requestHeaders)
03140                                 )
03141                         )
03142                         );
03143                         $content = @file_get_contents($url, FALSE, $ctx);
03144                         if ($content === FALSE && isset($report)) {
03145                                 $phpError = error_get_last();
03146                                 $report['error'] = $phpError['type'];
03147                                 $report['message'] = $phpError['message'];
03148                         }
03149                 } else {
03150                         if (isset($report)) {
03151                                 $report['lib'] = 'file';
03152                         }
03153                         $content = @file_get_contents($url);
03154                         if ($content === FALSE && isset($report)) {
03155                                 if (function_exists('error_get_last')) {
03156                                         $phpError = error_get_last();
03157                                         $report['error'] = $phpError['type'];
03158                                         $report['message'] = $phpError['message'];
03159                                 } else {
03160                                         $report['error'] = -1;
03161                                         $report['message'] = 'Couldn\'t get URL.';
03162                                 }
03163                         }
03164                 }
03165 
03166                 return $content;
03167         }
03168 
03177         public static function writeFile($file, $content) {
03178                 if (!@is_file($file)) {
03179                         $changePermissions = TRUE;
03180                 }
03181 
03182                 if ($fd = fopen($file, 'wb')) {
03183                         $res = fwrite($fd, $content);
03184                         fclose($fd);
03185 
03186                         if ($res === FALSE) {
03187                                 return FALSE;
03188                         }
03189 
03190                         if ($changePermissions) { // Change the permissions only if the file has just been created
03191                                 self::fixPermissions($file);
03192                         }
03193 
03194                         return TRUE;
03195                 }
03196 
03197                 return FALSE;
03198         }
03199 
03207         public static function fixPermissions($path, $recursive = FALSE) {
03208                 if (TYPO3_OS != 'WIN') {
03209                         $result = FALSE;
03210 
03211                                 // Make path absolute
03212                         if (!self::isAbsPath($path)) {
03213                                 $path = self::getFileAbsFileName($path, FALSE);
03214                         }
03215 
03216                         if (self::isAllowedAbsPath($path)) {
03217                                 if (@is_file($path)) {
03218                                                 // "@" is there because file is not necessarily OWNED by the user
03219                                         $result = @chmod($path, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask']));
03220                                 } elseif (@is_dir($path)) {
03221                                         $path = preg_replace('|/$|', '', $path);
03222                                                 // "@" is there because file is not necessarily OWNED by the user
03223                                         $result = @chmod($path, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
03224                                 }
03225 
03226                                         // Set createGroup if not empty
03227                                 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup']) {
03228                                                 // "@" is there because file is not necessarily OWNED by the user
03229                                         $changeGroupResult = @chgrp($path, $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup']);
03230                                         $result = $changeGroupResult ? $result : FALSE;
03231                                 }
03232 
03233                                         // Call recursive if recursive flag if set and $path is directory
03234                                 if ($recursive && @is_dir($path)) {
03235                                         $handle = opendir($path);
03236                                         while (($file = readdir($handle)) !== FALSE) {
03237                                                 $recursionResult = NULL;
03238                                                 if ($file !== '.' && $file !== '..') {
03239                                                         if (@is_file($path . '/' . $file)) {
03240                                                                 $recursionResult = self::fixPermissions($path . '/' . $file);
03241                                                         } elseif (@is_dir($path . '/' . $file)) {
03242                                                                 $recursionResult = self::fixPermissions($path . '/' . $file, TRUE);
03243                                                         }
03244                                                         if (isset($recursionResult) && !$recursionResult) {
03245                                                                 $result = FALSE;
03246                                                         }
03247                                                 }
03248                                         }
03249                                         closedir($handle);
03250                                 }
03251                         }
03252                 } else {
03253                         $result = TRUE;
03254                 }
03255                 return $result;
03256         }
03257 
03266         public static function writeFileToTypo3tempDir($filepath, $content) {
03267 
03268                         // Parse filepath into directory and basename:
03269                 $fI = pathinfo($filepath);
03270                 $fI['dirname'] .= '/';
03271 
03272                         // Check parts:
03273                 if (self::validPathStr($filepath) && $fI['basename'] && strlen($fI['basename']) < 60) {
03274                         if (defined('PATH_site')) {
03275                                 $dirName = PATH_site . 'typo3temp/'; // Setting main temporary directory name (standard)
03276                                 if (@is_dir($dirName)) {
03277                                         if (self::isFirstPartOfStr($fI['dirname'], $dirName)) {
03278 
03279                                                         // Checking if the "subdir" is found:
03280                                                 $subdir = substr($fI['dirname'], strlen($dirName));
03281                                                 if ($subdir) {
03282                                                         if (preg_match('/^[[:alnum:]_]+\/$/', $subdir) || preg_match('/^[[:alnum:]_]+\/[[:alnum:]_]+\/$/', $subdir)) {
03283                                                                 $dirName .= $subdir;
03284                                                                 if (!@is_dir($dirName)) {
03285                                                                         self::mkdir_deep(PATH_site . 'typo3temp/', $subdir);
03286                                                                 }
03287                                                         } else {
03288                                                                 return 'Subdir, "' . $subdir . '", was NOT on the form "[[:alnum:]_]/" or  "[[:alnum:]_]/[[:alnum:]_]/"';
03289                                                         }
03290                                                 }
03291                                                         // Checking dir-name again (sub-dir might have been created):
03292                                                 if (@is_dir($dirName)) {
03293                                                         if ($filepath == $dirName . $fI['basename']) {
03294                                                                 self::writeFile($filepath, $content);
03295                                                                 if (!@is_file($filepath)) {
03296                                                                         return 'File not written to disk! Write permission error in filesystem?';
03297                                                                 }
03298                                                         } else {
03299                                                                 return 'Calculated filelocation didn\'t match input $filepath!';
03300                                                         }
03301                                                 } else {
03302                                                         return '"' . $dirName . '" is not a directory!';
03303                                                 }
03304                                         } else {
03305                                                 return '"' . $fI['dirname'] . '" was not within directory PATH_site + "typo3temp/"';
03306                                         }
03307                                 } else {
03308                                         return 'PATH_site + "typo3temp/" was not a directory!';
03309                                 }
03310                         } else {
03311                                 return 'PATH_site constant was NOT defined!';
03312                         }
03313                 } else {
03314                         return 'Input filepath "' . $filepath . '" was generally invalid!';
03315                 }
03316         }
03317 
03326         public static function mkdir($newFolder) {
03327                 $newFolder = preg_replace('|/$|', '', $newFolder);
03328                 $result = @mkdir($newFolder, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
03329                 if ($result) {
03330                         self::fixPermissions($newFolder);
03331                 }
03332                 return $result;
03333         }
03334 
03342         public static function mkdir_deep($destination, $deepDir) {
03343                 $allParts = self::trimExplode('/', $deepDir, 1);
03344                 $root = '';
03345                 foreach ($allParts as $part) {
03346                         $root .= $part . '/';
03347                         if (!is_dir($destination . $root)) {
03348                                 self::mkdir($destination . $root);
03349                                 if (!@is_dir($destination . $root)) {
03350                                         return 'Error: The directory "' . $destination . $root . '" could not be created...';
03351                                 }
03352                         }
03353                 }
03354         }
03355 
03363         public static function rmdir($path, $removeNonEmpty = FALSE) {
03364                 $OK = FALSE;
03365                 $path = preg_replace('|/$|', '', $path); // Remove trailing slash
03366 
03367                 if (file_exists($path)) {
03368                         $OK = TRUE;
03369 
03370                         if (is_dir($path)) {
03371                                 if ($removeNonEmpty == TRUE && $handle = opendir($path)) {
03372                                         while ($OK && FALSE !== ($file = readdir($handle))) {
03373                                                 if ($file == '.' || $file == '..') {
03374                                                         continue;
03375                                                 }
03376                                                 $OK = self::rmdir($path . '/' . $file, $removeNonEmpty);
03377                                         }
03378                                         closedir($handle);
03379                                 }
03380                                 if ($OK) {
03381                                         $OK = rmdir($path);
03382                                 }
03383 
03384                         } else { // If $dirname is a file, simply remove it
03385                                 $OK = unlink($path);
03386                         }
03387 
03388                         clearstatcache();
03389                 }
03390 
03391                 return $OK;
03392         }
03393 
03402         public static function get_dirs($path) {
03403                 if ($path) {
03404                         if (is_dir($path)) {
03405                                 $dir = scandir($path);
03406                                 $dirs = array();
03407                                 foreach ($dir as $entry) {
03408                                         if (is_dir($path . '/' . $entry) && $entry != '..' && $entry != '.') {
03409                                                 $dirs[] = $entry;
03410                                         }
03411                                 }
03412                         } else {
03413                                 $dirs = 'error';
03414                         }
03415                 }
03416                 return $dirs;
03417         }
03418 
03430         public static function getFilesInDir($path, $extensionList = '', $prependPath = 0, $order = '', $excludePattern = '') {
03431 
03432                         // Initialize variabels:
03433                 $filearray = array();
03434                 $sortarray = array();
03435                 $path = rtrim($path, '/');
03436 
03437                         // Find files+directories:
03438                 if (@is_dir($path)) {
03439                         $extensionList = strtolower($extensionList);
03440                         $d = dir($path);
03441                         if (is_object($d)) {
03442                                 while ($entry = $d->read()) {
03443                                         if (@is_file($path . '/' . $entry)) {
03444                                                 $fI = pathinfo($entry);
03445                                                 $key = md5($path . '/' . $entry); // Don't change this ever - extensions may depend on the fact that the hash is an md5 of the path! (import/export extension)
03446                                                 if ((!strlen($extensionList) || self::inList($extensionList, strtolower($fI['extension']))) && (!strlen($excludePattern) || !preg_match('/^' . $excludePattern . '$/', $entry))) {
03447                                                         $filearray[$key] = ($prependPath ? $path . '/' : '') . $entry;
03448                                                         if ($order == 'mtime') {
03449                                                                 $sortarray[$key] = filemtime($path . '/' . $entry);
03450                                                         }
03451                                                         elseif ($order) {
03452                                                                 $sortarray[$key] = $entry;
03453                                                         }
03454                                                 }
03455                                         }
03456                                 }
03457                                 $d->close();
03458                         } else {
03459                                 return 'error opening path: "' . $path . '"';
03460                         }
03461                 }
03462 
03463                         // Sort them:
03464                 if ($order) {
03465                         asort($sortarray);
03466                         $newArr = array();
03467                         foreach ($sortarray as $k => $v) {
03468                                 $newArr[$k] = $filearray[$k];
03469                         }
03470                         $filearray = $newArr;
03471                 }
03472 
03473                         // Return result
03474                 reset($filearray);
03475                 return $filearray;
03476         }
03477 
03490         public static function getAllFilesAndFoldersInPath(array $fileArr, $path, $extList = '', $regDirs = 0, $recursivityLevels = 99, $excludePattern = '') {
03491                 if ($regDirs) {
03492                         $fileArr[] = $path;
03493                 }
03494                 $fileArr = array_merge($fileArr, self::getFilesInDir($path, $extList, 1, 1, $excludePattern));
03495 
03496                 $dirs = self::get_dirs($path);
03497                 if (is_array($dirs) && $recursivityLevels > 0) {
03498                         foreach ($dirs as $subdirs) {
03499                                 if ((string) $subdirs != '' && (!strlen($excludePattern) || !preg_match('/^' . $excludePattern . '$/', $subdirs))) {
03500                                         $fileArr = self::getAllFilesAndFoldersInPath($fileArr, $path . $subdirs . '/', $extList, $regDirs, $recursivityLevels - 1, $excludePattern);
03501                                 }
03502                         }
03503                 }
03504                 return $fileArr;
03505         }
03506 
03515         public static function removePrefixPathFromList(array $fileArr, $prefixToRemove) {
03516                 foreach ($fileArr as $k => &$absFileRef) {
03517                         if (self::isFirstPartOfStr($absFileRef, $prefixToRemove)) {
03518                                 $absFileRef = substr($absFileRef, strlen($prefixToRemove));
03519                         } else {
03520                                 return 'ERROR: One or more of the files was NOT prefixed with the prefix-path!';
03521                         }
03522                 }
03523                 return $fileArr;
03524         }
03525 
03533         public static function fixWindowsFilePath($theFile) {
03534                 return str_replace('//', '/', str_replace('\\', '/', $theFile));
03535         }
03536 
03545         public static function resolveBackPath($pathStr) {
03546                 $parts = explode('/', $pathStr);
03547                 $output = array();
03548                 $c = 0;
03549                 foreach ($parts as $pV) {
03550                         if ($pV == '..') {
03551                                 if ($c) {
03552                                         array_pop($output);
03553                                         $c--;
03554                                 } else {
03555                                         $output[] = $pV;
03556                                 }
03557                         } else {
03558                                 $c++;
03559                                 $output[] = $pV;
03560                         }
03561                 }
03562                 return implode('/', $output);
03563         }
03564 
03575         public static function locationHeaderUrl($path) {
03576                 $uI = parse_url($path);
03577                 if (substr($path, 0, 1) == '/') { // relative to HOST
03578                         $path = self::getIndpEnv('TYPO3_REQUEST_HOST') . $path;
03579                 } elseif (!$uI['scheme']) { // No scheme either
03580                         $path = self::getIndpEnv('TYPO3_REQUEST_DIR') . $path;
03581                 }
03582                 return $path;
03583         }
03584 
03595         public static function getMaxUploadFileSize($localLimit = 0) {
03596                         // don't allow more than the global max file size at all
03597                 $t3Limit = (intval($localLimit > 0 ? $localLimit : $GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize']));
03598                         // as TYPO3 is handling the file size in KB, multiply by 1024 to get bytes
03599                 $t3Limit = $t3Limit * 1024;
03600 
03601                         // check for PHP restrictions of the maximum size of one of the $_FILES
03602                 $phpUploadLimit = self::getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
03603                         // check for PHP restrictions of the maximum $_POST size
03604                 $phpPostLimit = self::getBytesFromSizeMeasurement(ini_get('post_max_size'));
03605                         // if the total amount of post data is smaller (!) than the upload_max_filesize directive,
03606                         // then this is the real limit in PHP
03607                 $phpUploadLimit = ($phpPostLimit < $phpUploadLimit ? $phpPostLimit : $phpUploadLimit);
03608 
03609                         // is the allowed PHP limit (upload_max_filesize) lower than the TYPO3 limit?, also: revert back to KB
03610                 return floor($phpUploadLimit < $t3Limit ? $phpUploadLimit : $t3Limit) / 1024;
03611         }
03612 
03619         public static function getBytesFromSizeMeasurement($measurement) {
03620                 if (stripos($measurement, 'G')) {
03621                         $bytes = doubleval($measurement) * 1024 * 1024 * 1024;
03622                 } else {
03623                         if (stripos($measurement, 'M')) {
03624                                 $bytes = doubleval($measurement) * 1024 * 1024;
03625                         } else {
03626                                 if (stripos($measurement, 'K')) {
03627                                         $bytes = doubleval($measurement) * 1024;
03628                                 } else {
03629                                         $bytes = doubleval($measurement);
03630                                 }
03631                         }
03632                 }
03633                 return $bytes;
03634         }
03635 
03642         public static function getMaximumPathLength() {
03643                 $maximumPathLength = 0;
03644 
03645                 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
03646                                 // rough assumptions
03647                         if (TYPO3_OS == 'WIN') {
03648                                         // WIN is usually 255, Vista 260, although NTFS can hold about 2k
03649                                 $maximumPathLength = 255;
03650                         } else {
03651                                 $maximumPathLength = 2048;
03652                         }
03653                 } else {
03654                                 // precise information is available since PHP 5.3
03655                         $maximumPathLength = PHP_MAXPATHLEN;
03656                 }
03657 
03658                 return $maximumPathLength;
03659         }
03660 
03661 
03680         public static function createVersionNumberedFilename($file, $forceQueryString = FALSE) {
03681                 $lookupFile = explode('?', $file);
03682                 $path = self::resolveBackPath(self::dirname(PATH_thisScript) . '/' . $lookupFile[0]);
03683 
03684                 if (TYPO3_MODE == 'FE') {
03685                         $mode = strtolower($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['versionNumberInFilename']);
03686                         if ($mode === 'embed') {
03687                                 $mode = TRUE;
03688                         } else {
03689                                 if ($mode === 'querystring') {
03690                                         $mode = FALSE;
03691                                 } else {
03692                                         $doNothing = TRUE;
03693                                 }
03694                         }
03695                 } else {
03696                         $mode = $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['versionNumberInFilename'];
03697                 }
03698 
03699                 if (!file_exists($path) || $doNothing) {
03700                                 // File not found, return filename unaltered
03701                         $fullName = $file;
03702 
03703                 } else {
03704                         if (!$mode || $forceQueryString) {
03705                                         // If use of .htaccess rule is not configured,
03706                                         // we use the default query-string method
03707                                 if ($lookupFile[1]) {
03708                                         $separator = '&';
03709                                 } else {
03710                                         $separator = '?';
03711                                 }
03712                                 $fullName = $file . $separator . filemtime($path);
03713 
03714                         } else {
03715                                         // Change the filename
03716                                 $name = explode('.', $lookupFile[0]);
03717                                 $extension = array_pop($name);
03718 
03719                                 array_push($name, filemtime($path), $extension);
03720                                 $fullName = implode('.', $name);
03721                                         // append potential query string
03722                                 $fullName .= $lookupFile[1] ? '?' . $lookupFile[1] : '';
03723                         }
03724                 }
03725 
03726                 return $fullName;
03727         }
03728 
03729 
03730         /*************************
03731          *
03732          * DEBUG helper FUNCTIONS
03733          *
03734          *************************/
03735 
03736         /* Deprecated since 4.5, use t3lib_utility_Debug */
03737 
03738 
03748         public static function debug_ordvalue($string, $characters = 100) {
03749                 self::logDeprecatedFunction();
03750                 return t3lib_utility_Debug::ordinalValue($string, $characters);
03751         }
03752 
03763         public static function view_array($array_in) {
03764                 self::logDeprecatedFunction();
03765                 return t3lib_utility_Debug::viewArray($array_in);
03766         }
03767 
03777         public static function print_array($array_in) {
03778                 self::logDeprecatedFunction();
03779                 t3lib_utility_Debug::printArray($array_in);
03780         }
03781 
03795         public static function debug($var = '', $header = '', $group = 'Debug') {
03796                 self::logDeprecatedFunction();
03797                 t3lib_utility_Debug::debug($var, $header, $group);
03798         }
03799 
03806         public static function debug_trail() {
03807                 self::logDeprecatedFunction();
03808                 return t3lib_utility_Debug::debugTrail();
03809         }
03810 
03820         public static function debugRows($rows, $header = '', $returnHTML = FALSE) {
03821                 self::logDeprecatedFunction();
03822                 return t3lib_utility_Debug::debugRows($rows, $header, $returnHTML);
03823         }
03824 
03825 
03826         /*************************
03827          *
03828          * SYSTEM INFORMATION
03829          *
03830          *************************/
03831 
03838         public static function getThisUrl() {
03839                 $p = parse_url(self::getIndpEnv('TYPO3_REQUEST_SCRIPT')); // Url of this script
03840                 $dir = self::dirname($p['path']) . '/'; // Strip file
03841                 $url = str_replace('//', '/', $p['host'] . ($p['port'] ? ':' . $p['port'] : '') . $dir);
03842                 return $url;
03843         }
03844 
03854         public static function linkThisScript(array $getParams = array()) {
03855                 $parts = self::getIndpEnv('SCRIPT_NAME');
03856                 $params = self::_GET();
03857 
03858                 foreach ($getParams as $key => $value) {
03859                         if ($value !== '') {
03860                                 $params[$key] = $value;
03861                         } else {
03862                                 unset($params[$key]);
03863                         }
03864                 }
03865 
03866                 $pString = self::implodeArrayForUrl('', $params);
03867 
03868                 return $pString ? $parts . '?' . preg_replace('/^&/', '', $pString) : $parts;
03869         }
03870 
03880         public static function linkThisUrl($url, array $getParams = array()) {
03881                 $parts = parse_url($url);
03882                 $getP = array();
03883                 if ($parts['query']) {
03884                         parse_str($parts['query'], $getP);
03885                 }
03886                 $getP = self::array_merge_recursive_overrule($getP, $getParams);
03887                 $uP = explode('?', $url);
03888 
03889                 $params = self::implodeArrayForUrl('', $getP);
03890                 $outurl = $uP[0] . ($params ? '?' . substr($params, 1) : '');
03891 
03892                 return $outurl;
03893         }
03894 
03903         public static function getIndpEnv($getEnvName) {
03904                 /*
03905                         Conventions:
03906                         output from parse_url():
03907                         URL:    http://username:password@192.168.1.4:8080/typo3/32/temp/phpcheck/index.php/arg1/arg2/arg3/?arg1,arg2,arg3&p1=parameter1&p2[key]=value#link1
03908                                 [scheme] => 'http'
03909                                 [user] => 'username'
03910                                 [pass] => 'password'
03911                                 [host] => '192.168.1.4'
03912                                 [port] => '8080'
03913                                 [path] => '/typo3/32/temp/phpcheck/index.php/arg1/arg2/arg3/'
03914                                 [query] => 'arg1,arg2,arg3&p1=parameter1&p2[key]=value'
03915                                 [fragment] => 'link1'
03916 
03917                                 Further definition: [path_script] = '/typo3/32/temp/phpcheck/index.php'
03918                                                                         [path_dir] = '/typo3/32/temp/phpcheck/'
03919                                                                         [path_info] = '/arg1/arg2/arg3/'
03920                                                                         [path] = [path_script/path_dir][path_info]
03921 
03922 
03923                         Keys supported:
03924 
03925                         URI______:
03926                                 REQUEST_URI             =       [path]?[query]          = /typo3/32/temp/phpcheck/index.php/arg1/arg2/arg3/?arg1,arg2,arg3&p1=parameter1&p2[key]=value
03927                                 HTTP_HOST               =       [host][:[port]]         = 192.168.1.4:8080
03928                                 SCRIPT_NAME             =       [path_script]++         = /typo3/32/temp/phpcheck/index.php             // NOTICE THAT SCRIPT_NAME will return the php-script name ALSO. [path_script] may not do that (eg. '/somedir/' may result in SCRIPT_NAME '/somedir/index.php')!
03929                                 PATH_INFO               =       [path_info]                     = /arg1/arg2/arg3/
03930                                 QUERY_STRING    =       [query]                         = arg1,arg2,arg3&p1=parameter1&p2[key]=value
03931                                 HTTP_REFERER    =       [scheme]://[host][:[port]][path]        = http://192.168.1.4:8080/typo3/32/temp/phpcheck/index.php/arg1/arg2/arg3/?arg1,arg2,arg3&p1=parameter1&p2[key]=value
03932                                                                                 (Notice: NO username/password + NO fragment)
03933 
03934                         CLIENT____:
03935                                 REMOTE_ADDR             =       (client IP)
03936                                 REMOTE_HOST             =       (client host)
03937                                 HTTP_USER_AGENT =       (client user agent)
03938                                 HTTP_ACCEPT_LANGUAGE    = (client accept language)
03939 
03940                         SERVER____:
03941                                 SCRIPT_FILENAME =       Absolute filename of script             (Differs between windows/unix). On windows 'C:\\blabla\\blabl\\' will be converted to 'C:/blabla/blabl/'
03942 
03943                         Special extras:
03944                                 TYPO3_HOST_ONLY =               [host] = 192.168.1.4
03945                                 TYPO3_PORT =                    [port] = 8080 (blank if 80, taken from host value)
03946                                 TYPO3_REQUEST_HOST =            [scheme]://[host][:[port]]
03947                                 TYPO3_REQUEST_URL =             [scheme]://[host][:[port]][path]?[query] (scheme will by default be "http" until we can detect something different)
03948                                 TYPO3_REQUEST_SCRIPT =          [scheme]://[host][:[port]][path_script]
03949                                 TYPO3_REQUEST_DIR =             [scheme]://[host][:[port]][path_dir]
03950                                 TYPO3_SITE_URL =                [scheme]://[host][:[port]][path_dir] of the TYPO3 website frontend
03951                                 TYPO3_SITE_PATH =               [path_dir] of the TYPO3 website frontend
03952                                 TYPO3_SITE_SCRIPT =             [script / Speaking URL] of the TYPO3 website
03953                                 TYPO3_DOCUMENT_ROOT =           Absolute path of root of documents: TYPO3_DOCUMENT_ROOT.SCRIPT_NAME = SCRIPT_FILENAME (typically)
03954                                 TYPO3_SSL =                     Returns TRUE if this session uses SSL/TLS (https)
03955                                 TYPO3_PROXY =                   Returns TRUE if this session runs over a well known proxy
03956 
03957                         Notice: [fragment] is apparently NEVER available to the script!
03958 
03959 
03960                         Testing suggestions:
03961                         - Output all the values.
03962                         - In the script, make a link to the script it self, maybe add some parameters and click the link a few times so HTTP_REFERER is seen
03963                         - ALSO TRY the script from the ROOT of a site (like 'http://www.mytest.com/' and not 'http://www.mytest.com/test/' !!)
03964 
03965                 */
03966 
03967                 #               if ($getEnvName=='HTTP_REFERER')        return '';
03968 
03969                 $retVal = '';
03970 
03971                 switch ((string) $getEnvName) {
03972                         case 'SCRIPT_NAME':
03973                                 $retVal = (PHP_SAPI == 'fpm-fcgi' || PHP_SAPI == 'cgi' || PHP_SAPI == 'cgi-fcgi') &&
03974                                                 ($_SERVER['ORIG_PATH_INFO'] ? $_SERVER['ORIG_PATH_INFO'] : $_SERVER['PATH_INFO']) ?
03975                                                 ($_SERVER['ORIG_PATH_INFO'] ? $_SERVER['ORIG_PATH_INFO'] : $_SERVER['PATH_INFO']) :
03976                                                 ($_SERVER['ORIG_SCRIPT_NAME'] ? $_SERVER['ORIG_SCRIPT_NAME'] : $_SERVER['SCRIPT_NAME']);
03977                                         // add a prefix if TYPO3 is behind a proxy: ext-domain.com => int-server.com/prefix
03978                                 if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
03979                                         if (self::getIndpEnv('TYPO3_SSL') && $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL']) {
03980                                                 $retVal = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL'] . $retVal;
03981                                         } elseif ($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefix']) {
03982                                                 $retVal = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefix'] . $retVal;
03983                                         }
03984                                 }
03985                                 break;
03986                         case 'SCRIPT_FILENAME':
03987                                 $retVal = str_replace('//', '/', str_replace('\\', '/',
03988                                         (PHP_SAPI == 'fpm-fcgi' || PHP_SAPI == 'cgi' || PHP_SAPI == 'isapi' || PHP_SAPI == 'cgi-fcgi') &&
03989                                                         ($_SERVER['ORIG_PATH_TRANSLATED'] ? $_SERVER['ORIG_PATH_TRANSLATED'] : $_SERVER['PATH_TRANSLATED']) ?
03990                                                         ($_SERVER['ORIG_PATH_TRANSLATED'] ? $_SERVER['ORIG_PATH_TRANSLATED'] : $_SERVER['PATH_TRANSLATED']) :
03991                                                         ($_SERVER['ORIG_SCRIPT_FILENAME'] ? $_SERVER['ORIG_SCRIPT_FILENAME'] : $_SERVER['SCRIPT_FILENAME'])));
03992 
03993                                 break;
03994                         case 'REQUEST_URI':
03995                                         // Typical application of REQUEST_URI is return urls, forms submitting to itself etc. Example: returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))
03996                                 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['requestURIvar']) { // This is for URL rewriters that store the original URI in a server variable (eg ISAPI_Rewriter for IIS: HTTP_X_REWRITE_URL)
03997                                         list($v, $n) = explode('|', $GLOBALS['TYPO3_CONF_VARS']['SYS']['requestURIvar']);
03998                                         $retVal = $GLOBALS[$v][$n];
03999                                 } elseif (!$_SERVER['REQUEST_URI']) { // This is for ISS/CGI which does not have the REQUEST_URI available.
04000                                         $retVal = '/' . ltrim(self::getIndpEnv('SCRIPT_NAME'), '/') .
04001                                                         ($_SERVER['QUERY_STRING'] ? '?' . $_SERVER['QUERY_STRING'] : '');
04002                                 } else {
04003                                         $retVal = $_SERVER['REQUEST_URI'];
04004                                 }
04005                                         // add a prefix if TYPO3 is behind a proxy: ext-domain.com => int-server.com/prefix
04006                                 if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
04007                                         if (self::getIndpEnv('TYPO3_SSL') && $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL']) {
04008                                                 $retVal = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL'] . $retVal;
04009                                         } elseif ($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefix']) {
04010                                                 $retVal = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefix'] . $retVal;
04011                                         }
04012                                 }
04013                                 break;
04014                         case 'PATH_INFO':
04015                                         // $_SERVER['PATH_INFO']!=$_SERVER['SCRIPT_NAME'] is necessary because some servers (Windows/CGI) are seen to set PATH_INFO equal to script_name
04016                                         // Further, there must be at least one '/' in the path - else the PATH_INFO value does not make sense.
04017                                         // IF 'PATH_INFO' never works for our purpose in TYPO3 with CGI-servers, then 'PHP_SAPI=='cgi'' might be a better check. Right now strcmp($_SERVER['PATH_INFO'],t3lib_div::getIndpEnv('SCRIPT_NAME')) will always return false for CGI-versions, but that is only as long as SCRIPT_NAME is set equal to PATH_INFO because of PHP_SAPI=='cgi' (see above)
04018                                         //                              if (strcmp($_SERVER['PATH_INFO'],self::getIndpEnv('SCRIPT_NAME')) && count(explode('/',$_SERVER['PATH_INFO']))>1)       {
04019                                 if (PHP_SAPI != 'cgi' && PHP_SAPI != 'cgi-fcgi' && PHP_SAPI != 'fpm-fcgi') {
04020                                         $retVal = $_SERVER['PATH_INFO'];
04021                                 }
04022                                 break;
04023                         case 'TYPO3_REV_PROXY':
04024                                 $retVal = self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP']);
04025                                 break;
04026                         case 'REMOTE_ADDR':
04027                                 $retVal = $_SERVER['REMOTE_ADDR'];
04028                                 if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
04029                                         $ip = self::trimExplode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
04030                                                 // choose which IP in list to use
04031                                         if (count($ip)) {
04032                                                 switch ($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyHeaderMultiValue']) {
04033                                                         case 'last':
04034                                                                 $ip = array_pop($ip);
04035                                                                 break;
04036                                                         case 'first':
04037                                                                 $ip = array_shift($ip);
04038                                                                 break;
04039                                                         case 'none':
04040                                                         default:
04041                                                                 $ip = '';
04042                                                                 break;
04043                                                 }
04044                                         }
04045                                         if (self::validIP($ip)) {
04046                                                 $retVal = $ip;
04047                                         }
04048                                 }
04049                                 break;
04050                         case 'HTTP_HOST':
04051                                 $retVal = $_SERVER['HTTP_HOST'];
04052                                 if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
04053                                         $host = self::trimExplode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
04054                                                 // choose which host in list to use
04055                                         if (count($host)) {
04056                                                 switch ($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyHeaderMultiValue']) {
04057                                                         case 'last':
04058                                                                 $host = array_pop($host);
04059                                                                 break;
04060                                                         case 'first':
04061                                                                 $host = array_shift($host);
04062                                                                 break;
04063                                                         case 'none':
04064                                                         default:
04065                                                                 $host = '';
04066                                                                 break;
04067                                                 }
04068                                         }
04069                                         if ($host) {
04070                                                 $retVal = $host;
04071                                         }
04072                                 }
04073                                 break;
04074                                 // These are let through without modification
04075                         case 'HTTP_REFERER':
04076                         case 'HTTP_USER_AGENT':
04077                         case 'HTTP_ACCEPT_ENCODING':
04078                         case 'HTTP_ACCEPT_LANGUAGE':
04079                         case 'REMOTE_HOST':
04080                         case 'QUERY_STRING':
04081                                 $retVal = $_SERVER[$getEnvName];
04082                                 break;
04083                         case 'TYPO3_DOCUMENT_ROOT':
04084                                         // Get the web root (it is not the root of the TYPO3 installation)
04085                                         // The absolute path of the script can be calculated with TYPO3_DOCUMENT_ROOT + SCRIPT_FILENAME
04086                                         // Some CGI-versions (LA13CGI) and mod-rewrite rules on MODULE versions will deliver a 'wrong' DOCUMENT_ROOT (according to our description). Further various aliases/mod_rewrite rules can disturb this as well.
04087                                         // Therefore the DOCUMENT_ROOT is now always calculated as the SCRIPT_FILENAME minus the end part shared with SCRIPT_NAME.
04088                                 $SFN = self::getIndpEnv('SCRIPT_FILENAME');
04089                                 $SN_A = explode('/', strrev(self::getIndpEnv('SCRIPT_NAME')));
04090                                 $SFN_A = explode('/', strrev($SFN));
04091                                 $acc = array();
04092                                 foreach ($SN_A as $kk => $vv) {
04093                                         if (!strcmp($SFN_A[$kk], $vv)) {
04094                                                 $acc[] = $vv;
04095                                         } else {
04096                                                 break;
04097                                         }
04098                                 }
04099                                 $commonEnd = strrev(implode('/', $acc));
04100                                 if (strcmp($commonEnd, '')) {
04101                                         $DR = substr($SFN, 0, -(strlen($commonEnd) + 1));
04102                                 }
04103                                 $retVal = $DR;
04104                                 break;
04105                         case 'TYPO3_HOST_ONLY':
04106                                 $httpHost = self::getIndpEnv('HTTP_HOST');
04107                                 $httpHostBracketPosition = strpos($httpHost, ']');
04108                                 $retVal = ($httpHostBracketPosition !== FALSE) ? substr($httpHost, 0, ($httpHostBracketPosition + 1)) : array_shift(explode(':', $httpHost));
04109                                 break;
04110                         case 'TYPO3_PORT':
04111                                 $httpHost = self::getIndpEnv('HTTP_HOST');
04112                                 $httpHostOnly = self::getIndpEnv('TYPO3_HOST_ONLY');
04113                                 $retVal = (strlen($httpHost) > strlen($httpHostOnly)) ? substr($httpHost, strlen($httpHostOnly) + 1) : '';
04114                                 break;
04115                         case 'TYPO3_REQUEST_HOST':
04116                                 $retVal = (self::getIndpEnv('TYPO3_SSL') ? 'https://' : 'http://') .
04117                                                 self::getIndpEnv('HTTP_HOST');
04118                                 break;
04119                         case 'TYPO3_REQUEST_URL':
04120                                 $retVal = self::getIndpEnv('TYPO3_REQUEST_HOST') . self::getIndpEnv('REQUEST_URI');
04121                                 break;
04122                         case 'TYPO3_REQUEST_SCRIPT':
04123                                 $retVal = self::getIndpEnv('TYPO3_REQUEST_HOST') . self::getIndpEnv('SCRIPT_NAME');
04124                                 break;
04125                         case 'TYPO3_REQUEST_DIR':
04126                                 $retVal = self::getIndpEnv('TYPO3_REQUEST_HOST') . self::dirname(self::getIndpEnv('SCRIPT_NAME')) . '/';
04127                                 break;
04128                         case 'TYPO3_SITE_URL':
04129                                 if (defined('PATH_thisScript') && defined('PATH_site')) {
04130                                         $lPath = substr(dirname(PATH_thisScript), strlen(PATH_site)) . '/';
04131                                         $url = self::getIndpEnv('TYPO3_REQUEST_DIR');
04132                                         $siteUrl = substr($url, 0, -strlen($lPath));
04133                                         if (substr($siteUrl, -1) != '/') {
04134                                                 $siteUrl .= '/';
04135                                         }
04136                                         $retVal = $siteUrl;
04137                                 }
04138                                 break;
04139                         case 'TYPO3_SITE_PATH':
04140                                 $retVal = substr(self::getIndpEnv('TYPO3_SITE_URL'), strlen(self::getIndpEnv('TYPO3_REQUEST_HOST')));
04141                                 break;
04142                         case 'TYPO3_SITE_SCRIPT':
04143                                 $retVal = substr(self::getIndpEnv('TYPO3_REQUEST_URL'), strlen(self::getIndpEnv('TYPO3_SITE_URL')));
04144                                 break;
04145                         case 'TYPO3_SSL':
04146                                 $proxySSL = trim($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxySSL']);
04147                                 if ($proxySSL == '*') {
04148                                         $proxySSL = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'];
04149                                 }
04150                                 if (self::cmpIP($_SERVER['REMOTE_ADDR'], $proxySSL)) {
04151                                         $retVal = TRUE;
04152                                 } else {
04153                                         $retVal = $_SERVER['SSL_SESSION_ID'] || !strcasecmp($_SERVER['HTTPS'], 'on') || !strcmp($_SERVER['HTTPS'], '1') ? TRUE : FALSE; // see http://bugs.typo3.org/view.php?id=3909
04154                                 }
04155                                 break;
04156                         case '_ARRAY':
04157                                 $out = array();
04158                                         // Here, list ALL possible keys to this function for debug display.
04159                                 $envTestVars = self::trimExplode(',', '
04160                                         HTTP_HOST,
04161                                         TYPO3_HOST_ONLY,
04162                                         TYPO3_PORT,
04163                                         PATH_INFO,
04164                                         QUERY_STRING,
04165                                         REQUEST_URI,
04166                                         HTTP_REFERER,
04167                                         TYPO3_REQUEST_HOST,
04168                                         TYPO3_REQUEST_URL,
04169                                         TYPO3_REQUEST_SCRIPT,
04170                                         TYPO3_REQUEST_DIR,
04171                                         TYPO3_SITE_URL,
04172                                         TYPO3_SITE_SCRIPT,
04173                                         TYPO3_SSL,
04174                                         TYPO3_REV_PROXY,
04175                                         SCRIPT_NAME,
04176                                         TYPO3_DOCUMENT_ROOT,
04177                                         SCRIPT_FILENAME,
04178                                         REMOTE_ADDR,
04179                                         REMOTE_HOST,
04180                                         HTTP_USER_AGENT,
04181                                         HTTP_ACCEPT_LANGUAGE', 1);
04182                                 foreach ($envTestVars as $v) {
04183                                         $out[$v] = self::getIndpEnv($v);
04184                                 }
04185                                 reset($out);
04186                                 $retVal = $out;
04187                                 break;
04188                 }
04189                 return $retVal;
04190         }
04191 
04197         public static function milliseconds() {
04198                 return round(microtime(TRUE) * 1000);
04199         }
04200 
04208         public static function clientInfo($useragent = '') {
04209                 if (!$useragent) {
04210                         $useragent = self::getIndpEnv('HTTP_USER_AGENT');
04211                 }
04212 
04213                 $bInfo = array();
04214                         // Which browser?
04215                 if (strpos($useragent, 'Konqueror') !== FALSE) {
04216                         $bInfo['BROWSER'] = 'konqu';
04217                 } elseif (strpos($useragent, 'Opera') !== FALSE) {
04218                         $bInfo['BROWSER'] = 'opera';
04219                 } elseif (strpos($useragent, 'MSIE') !== FALSE) {
04220                         $bInfo['BROWSER'] = 'msie';
04221                 } elseif (strpos($useragent, 'Mozilla') !== FALSE) {
04222                         $bInfo['BROWSER'] = 'net';
04223                 } elseif (strpos($useragent, 'Flash') !== FALSE) {
04224                         $bInfo['BROWSER'] = 'flash';
04225                 }
04226                 if ($bInfo['BROWSER']) {
04227                                 // Browser version
04228                         switch ($bInfo['BROWSER']) {
04229                                 case 'net':
04230                                         $bInfo['VERSION'] = doubleval(substr($useragent, 8));
04231                                         if (strpos($useragent, 'Netscape6/') !== FALSE) {
04232                                                 $bInfo['VERSION'] = doubleval(substr(strstr($useragent, 'Netscape6/'), 10));
04233                                         } // Will we ever know if this was a typo or intention...?! :-(
04234                                         if (strpos($useragent, 'Netscape/6') !== FALSE) {
04235                                                 $bInfo['VERSION'] = doubleval(substr(strstr($useragent, 'Netscape/6'), 10));
04236                                         }
04237                                         if (strpos($useragent, 'Netscape/7') !== FALSE) {
04238                                                 $bInfo['VERSION'] = doubleval(substr(strstr($useragent, 'Netscape/7'), 9));
04239                                         }
04240                                         break;
04241                                 case 'msie':
04242                                         $tmp = strstr($useragent, 'MSIE');
04243                                         $bInfo['VERSION'] = doubleval(preg_replace('/^[^0-9]*/', '', substr($tmp, 4)));
04244                                         break;
04245                                 case 'opera':
04246                                         $tmp = strstr($useragent, 'Opera');
04247                                         $bInfo['VERSION'] = doubleval(preg_replace('/^[^0-9]*/', '', substr($tmp, 5)));
04248                                         break;
04249                                 case 'konqu':
04250                                         $tmp = strstr($useragent, 'Konqueror/');
04251                                         $bInfo['VERSION'] = doubleval(substr($tmp, 10));
04252                                         break;
04253                         }
04254                         // Client system
04255                         if (strpos($useragent, 'Win') !== FALSE) {
04256                                 $bInfo['SYSTEM'] = 'win';
04257                         } elseif (strpos($useragent, 'Mac') !== FALSE) {
04258                                 $bInfo['SYSTEM'] = 'mac';
04259                         } elseif (strpos($useragent, 'Linux') !== FALSE || strpos($useragent, 'X11') !== FALSE || strpos($useragent, 'SGI') !== FALSE || strpos($useragent, ' SunOS ') !== FALSE || strpos($useragent, ' HP-UX ') !== FALSE) {
04260                                 $bInfo['SYSTEM'] = 'unix';
04261                         }
04262                 }
04263                 // Is true if the browser supports css to format forms, especially the width
04264                 $bInfo['FORMSTYLE'] = ($bInfo['BROWSER'] == 'msie' || ($bInfo['BROWSER'] == 'net' && $bInfo['VERSION'] >= 5) || $bInfo['BROWSER'] == 'opera' || $bInfo['BROWSER'] == 'konqu');
04265 
04266                 return $bInfo;
04267         }
04268 
04276         public static function getHostname($requestHost = TRUE) {
04277                 $host = '';
04278                         // If not called from the command-line, resolve on getIndpEnv()
04279                         // Note that TYPO3_REQUESTTYPE is not used here as it may not yet be defined
04280                 if ($requestHost && (!defined('TYPO3_cliMode') || !TYPO3_cliMode)) {
04281                         $host = self::getIndpEnv('HTTP_HOST');
04282                 }
04283                 if (!$host) {
04284                                 // will fail for PHP 4.1 and 4.2
04285                         $host = @php_uname('n');
04286                                 // 'n' is ignored in broken installations
04287                         if (strpos($host, ' ')) {
04288                                 $host = '';
04289                         }
04290                 }
04291                         // we have not found a FQDN yet
04292                 if ($host && strpos($host, '.') === FALSE) {
04293                         $ip = gethostbyname($host);
04294                                 // we got an IP address
04295                         if ($ip != $host) {
04296                                 $fqdn = gethostbyaddr($ip);
04297                                 if ($ip != $fqdn) {
04298                                         $host = $fqdn;
04299                                 }
04300                         }
04301                 }
04302                 if (!$host) {
04303                         $host = 'localhost.localdomain';
04304                 }
04305 
04306                 return $host;
04307         }
04308 
04309 
04310         /*************************
04311          *
04312          * TYPO3 SPECIFIC FUNCTIONS
04313          *
04314          *************************/
04315 
04325         public static function getFileAbsFileName($filename, $onlyRelative = TRUE, $relToTYPO3_mainDir = FALSE) {
04326                 if (!strcmp($filename, '')) {
04327                         return '';
04328                 }
04329 
04330                 if ($relToTYPO3_mainDir) {
04331                         if (!defined('PATH_typo3')) {
04332                                 return '';
04333                         }
04334                         $relPathPrefix = PATH_typo3;
04335                 } else {
04336                         $relPathPrefix = PATH_site;
04337                 }
04338                 if (substr($filename, 0, 4) == 'EXT:') { // extension
04339                         list($extKey, $local) = explode('/', substr($filename, 4), 2);
04340                         $filename = '';
04341                         if (strcmp($extKey, '') && t3lib_extMgm::isLoaded($extKey) && strcmp($local, '')) {
04342                                 $filename = t3lib_extMgm::extPath($extKey) . $local;
04343                         }
04344                 } elseif (!self::isAbsPath($filename)) { // relative. Prepended with $relPathPrefix
04345                         $filename = $relPathPrefix . $filename;
04346                 } elseif ($onlyRelative && !self::isFirstPartOfStr($filename, $relPathPrefix)) { // absolute, but set to blank if not allowed
04347                         $filename = '';
04348                 }
04349                 if (strcmp($filename, '') && self::validPathStr($filename)) { // checks backpath.
04350                         return $filename;
04351                 }
04352         }
04353 
04367         public static function validPathStr($theFile) {
04368                 if (strpos($theFile, '//') === FALSE && strpos($theFile, '\\') === FALSE && !preg_match('#(?:^\.\.|/\.\./|[[:cntrl:]])#', $theFile)) {
04369                         return TRUE;
04370                 }
04371         }
04372 
04380         public static function isAbsPath($path) {
04381                         // on Windows also a path starting with a drive letter is absolute: X:/
04382                 if (TYPO3_OS === 'WIN' && substr($path, 1, 2) === ':/') {
04383                         return TRUE;
04384                 }
04385 
04386                         // path starting with a / is always absolute, on every system
04387                 return (substr($path, 0, 1) === '/');
04388         }
04389 
04397         public static function isAllowedAbsPath($path) {
04398                 if (self::isAbsPath($path) &&
04399                                 self::validPathStr($path) &&
04400                                 (self::isFirstPartOfStr($path, PATH_site)
04401                                                 ||
04402                                                 ($GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath'] && self::isFirstPartOfStr($path, $GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath']))
04403                                 )
04404                 ) {
04405                         return TRUE;
04406                 }
04407         }
04408 
04416         public static function verifyFilenameAgainstDenyPattern($filename) {
04417                         // Filenames are not allowed to contain control characters
04418                 if (preg_match('/[[:cntrl:]]/', $filename)) {
04419                         return FALSE;
04420                 }
04421 
04422                 if (strcmp($filename, '') && strcmp($GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'], '')) {
04423                         $result = preg_match('/' . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'] . '/i', $filename);
04424                         if ($result) {
04425                                 return FALSE;
04426                         } // so if a matching filename is found, return FALSE;
04427                 }
04428                 return TRUE;
04429         }
04430 
04440         public static function sanitizeLocalUrl($url = '') {
04441                 $sanitizedUrl = '';
04442                 $decodedUrl = rawurldecode($url);
04443 
04444                 if (!empty($url) && self::removeXSS($decodedUrl) === $decodedUrl) {
04445                         $testAbsoluteUrl = self::resolveBackPath($decodedUrl);
04446                         $testRelativeUrl = self::resolveBackPath(
04447                                 self::dirname(self::getIndpEnv('SCRIPT_NAME')) . '/' . $decodedUrl
04448                         );
04449 
04450                                 // Pass if URL is on the current host:
04451                         if (self::isValidUrl($decodedUrl)) {
04452                                 if (self::isOnCurrentHost($decodedUrl) && strpos($decodedUrl, self::getIndpEnv('TYPO3_SITE_URL')) === 0) {
04453                                         $sanitizedUrl = $url;
04454                                 }
04455                                 // Pass if URL is an absolute file path:
04456                         } elseif (self::isAbsPath($decodedUrl) && self::isAllowedAbsPath($decodedUrl)) {
04457                                 $sanitizedUrl = $url;
04458                                 // Pass if URL is absolute and below TYPO3 base directory:
04459                         } elseif (strpos($testAbsoluteUrl, self::getIndpEnv('TYPO3_SITE_PATH')) === 0 && substr($decodedUrl, 0, 1) === '/') {
04460                                 $sanitizedUrl = $url;
04461                                 // Pass if URL is relative and below TYPO3 base directory:
04462                         } elseif (strpos($testRelativeUrl, self::getIndpEnv('TYPO3_SITE_PATH')) === 0 && substr($decodedUrl, 0, 1) !== '/') {
04463                                 $sanitizedUrl = $url;
04464                         }
04465                 }
04466 
04467                 if (!empty($url) && empty($sanitizedUrl)) {
04468                         self::sysLog('The URL "' . $url . '" is not considered to be local and was denied.', 'Core', self::SYSLOG_SEVERITY_NOTICE);
04469                 }
04470 
04471                 return $sanitizedUrl;
04472         }
04473 
04484         public static function upload_copy_move($source, $destination) {
04485                 if (is_uploaded_file($source)) {
04486                         $uploaded = TRUE;
04487                                 // Return the value of move_uploaded_file, and if false the temporary $source is still around so the user can use unlink to delete it:
04488                         $uploadedResult = move_uploaded_file($source, $destination);
04489                 } else {
04490                         $uploaded = FALSE;
04491                         @copy($source, $destination);
04492                 }
04493 
04494                 self::fixPermissions($destination); // Change the permissions of the file
04495 
04496                         // If here the file is copied and the temporary $source is still around, so when returning false the user can try unlink to delete the $source
04497                 return $uploaded ? $uploadedResult : FALSE;
04498         }
04499 
04510         public static function upload_to_tempfile($uploadedFileName) {
04511                 if (is_uploaded_file($uploadedFileName)) {
04512                         $tempFile = self::tempnam('upload_temp_');
04513                         move_uploaded_file($uploadedFileName, $tempFile);
04514                         return @is_file($tempFile) ? $tempFile : '';
04515                 }
04516         }
04517 
04528         public static function unlink_tempfile($uploadedTempFileName) {
04529                 if ($uploadedTempFileName && self::validPathStr($uploadedTempFileName) && self::isFirstPartOfStr($uploadedTempFileName, PATH_site . 'typo3temp/') && @is_file($uploadedTempFileName)) {
04530                         if (unlink($uploadedTempFileName)) {
04531                                 return TRUE;
04532                         }
04533                 }
04534         }
04535 
04546         public static function tempnam($filePrefix) {
04547                 return tempnam(PATH_site . 'typo3temp/', $filePrefix);
04548         }
04549 
04559         public static function stdAuthCode($uid_or_record, $fields = '', $codeLength = 8) {
04560 
04561                 if (is_array($uid_or_record)) {
04562                         $recCopy_temp = array();
04563                         if ($fields) {
04564                                 $fieldArr = self::trimExplode(',', $fields, 1);
04565                                 foreach ($fieldArr as $k => $v) {
04566                                         $recCopy_temp[$k] = $uid_or_record[$v];
04567                                 }
04568                         } else {
04569                                 $recCopy_temp = $uid_or_record;
04570                         }
04571                         $preKey = implode('|', $recCopy_temp);
04572                 } else {
04573                         $preKey = $uid_or_record;
04574                 }
04575 
04576                 $authCode = $preKey . '||' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
04577                 $authCode = substr(md5($authCode), 0, $codeLength);
04578                 return $authCode;
04579         }
04580 
04589         public static function cHashParams($addQueryParams) {
04590                 $params = explode('&', substr($addQueryParams, 1)); // Splitting parameters up
04591 
04592                         // Make array:
04593                 $pA = array();
04594                 foreach ($params as $theP) {
04595                         $pKV = explode('=', $theP); // Splitting single param by '=' sign
04596                         if (!self::inList('id,type,no_cache,cHash,MP,ftu', $pKV[0]) && !preg_match('/TSFE_ADMIN_PANEL\[.*?\]/', $pKV[0])) {
04597                                 $pA[rawurldecode($pKV[0])] = (string) rawurldecode($pKV[1]);
04598                         }
04599                 }
04600                         // Hook: Allows to manipulate the parameters which are taken to build the chash:
04601                 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['cHashParamsHook'])) {
04602                         $cHashParamsHook =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['cHashParamsHook'];
04603                         if (is_array($cHashParamsHook)) {
04604                                 $hookParameters = array(
04605                                         'addQueryParams' => &$addQueryParams,
04606                                         'params' => &$params,
04607                                         'pA' => &$pA,
04608                                 );
04609                                 $hookReference = NULL;
04610                                 foreach ($cHashParamsHook as $hookFunction) {
04611                                         self::callUserFunction($hookFunction, $hookParameters, $hookReference);
04612                                 }
04613                         }
04614                 }
04615                         // Finish and sort parameters array by keys:
04616                 $pA['encryptionKey'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
04617                 ksort($pA);
04618 
04619                 return $pA;
04620         }
04621 
04629         public static function generateCHash($addQueryParams) {
04630                 $cHashParams = self::cHashParams($addQueryParams);
04631                 $cHash = self::calculateCHash($cHashParams);
04632                 return $cHash;
04633         }
04634 
04641         public static function calculateCHash($params) {
04642                 $cHash = md5(serialize($params));
04643                 return $cHash;
04644         }
04645 
04652         public static function hideIfNotTranslated($l18n_cfg_fieldValue) {
04653                 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['hidePagesIfNotTranslatedByDefault']) {
04654                         return $l18n_cfg_fieldValue & 2 ? FALSE : TRUE;
04655                 } else {
04656                         return $l18n_cfg_fieldValue & 2 ? TRUE : FALSE;
04657                 }
04658         }
04659 
04670         public static function readLLfile($fileRef, $langKey, $charset = '', $errorMode = 0) {
04671 
04672                 $result = FALSE;
04673                 $file = self::getFileAbsFileName($fileRef);
04674                 if ($file) {
04675                         $baseFile = preg_replace('/\.(php|xml)$/', '', $file);
04676 
04677                         if (@is_file($baseFile . '.xml')) {
04678                                 $LOCAL_LANG = self::readLLXMLfile($baseFile . '.xml', $langKey, $charset);
04679                         } elseif (@is_file($baseFile . '.php')) {
04680                                 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] || $charset) {
04681                                         $LOCAL_LANG = self::readLLPHPfile($baseFile . '.php', $langKey, $charset);
04682                                 } else {
04683                                         include($baseFile . '.php');
04684                                         if (is_array($LOCAL_LANG)) {
04685                                                 $LOCAL_LANG = array('default' => $LOCAL_LANG['default'], $langKey => $LOCAL_LANG[$langKey]);
04686                                         }
04687                                 }
04688                         } else {
04689                                 $errorMsg = 'File "' . $fileRef . '" not found!';
04690                                 if ($errorMode == 2) {
04691                                         throw new t3lib_exception($errorMsg);
04692                                 } elseif (!$errorMode) {
04693                                         self::sysLog($errorMsg, 'Core', self::SYSLOG_SEVERITY_ERROR);
04694                                 }
04695                                 $fileNotFound = TRUE;
04696                         }
04697 
04698 
04699                         $overrides = array();
04700                         $fileRefWithoutExtension = preg_replace('/\.(php|xml)$/', '', $fileRef);
04701 
04702                         if (is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$fileRefWithoutExtension . '.php'])) {
04703                                 $overrides = array_merge($overrides, $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$fileRefWithoutExtension . '.php']);
04704                         }
04705                         if (is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$fileRefWithoutExtension . '.xml'])) {
04706                                 $overrides = array_merge($overrides, $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$fileRefWithoutExtension . '.xml']);
04707                         }
04708 
04709                         if (count($overrides) > 0) {
04710                                 foreach ($overrides as $overrideFile) {
04711                                         $languageOverrideFileName = self::getFileAbsFileName($overrideFile);
04712                                         if (@is_file($languageOverrideFileName)) {
04713                                                 $languageOverrideArray = self::readLLXMLfile($languageOverrideFileName, $langKey, $charset);
04714                                                 $LOCAL_LANG = self::array_merge_recursive_overrule($LOCAL_LANG, $languageOverrideArray);
04715                                         }
04716                                 }
04717                         }
04718                 }
04719                 if ($fileNotFound !== TRUE) {
04720                         $result = is_array($LOCAL_LANG) ? $LOCAL_LANG : array();
04721                 }
04722                 return $result;
04723         }
04724 
04734         public static function readLLPHPfile($fileRef, $langKey, $charset = '') {
04735 
04736                 if (is_object($GLOBALS['LANG'])) {
04737                         $csConvObj = $GLOBALS['LANG']->csConvObj;
04738                 } elseif (is_object($GLOBALS['TSFE'])) {
04739                         $csConvObj = $GLOBALS['TSFE']->csConvObj;
04740                 } else {
04741                         $csConvObj = self::makeInstance('t3lib_cs');
04742                 }
04743 
04744                 if (@is_file($fileRef) && $langKey) {
04745 
04746                                 // Set charsets:
04747                         $sourceCharset = $csConvObj->parse_charset($csConvObj->charSetArray[$langKey] ? $csConvObj->charSetArray[$langKey] : 'iso-8859-1');
04748                         if ($charset) {
04749                                 $targetCharset = $csConvObj->parse_charset($charset);
04750                         } elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) {
04751                                         // when forceCharset is set, we store ALL labels in this charset!!!
04752                                 $targetCharset = $csConvObj->parse_charset($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']);
04753                         } else {
04754                                 $targetCharset = $csConvObj->parse_charset($csConvObj->charSetArray[$langKey] ? $csConvObj->charSetArray[$langKey] : 'iso-8859-1');
04755                         }
04756 
04757                                 // Cache file name:
04758                         $hashSource = substr($fileRef, strlen(PATH_site)) . '|' . date('d-m-Y H:i:s', filemtime($fileRef)) . '|version=2.3';
04759                         $cacheFileName = PATH_site . 'typo3temp/llxml/' .
04760                                         substr(basename($fileRef), 10, 15) .
04761                                         '_' . self::shortMD5($hashSource) . '.' . $langKey . '.' . $targetCharset . '.cache';
04762                                 // Check if cache file exists...
04763                         if (!@is_file($cacheFileName)) { // ... if it doesn't, create content and write it:
04764                                 $LOCAL_LANG = NULL;
04765                                         // Get PHP data
04766                                 include($fileRef);
04767                                 if (!is_array($LOCAL_LANG)) {
04768                                         $fileName = substr($fileRef, strlen(PATH_site));
04769                                         throw new RuntimeException(
04770                                                 'TYPO3 Fatal Error: "' . $fileName . '" is no TYPO3 language file!',
04771                                                 1270853900
04772                                         );
04773                                 }
04774 
04775                                         // converting the default language (English)
04776                                         // this needs to be done for a few accented loan words and extension names
04777                                 if (is_array($LOCAL_LANG['default']) && $targetCharset != 'iso-8859-1') {
04778                                         foreach ($LOCAL_LANG['default'] as &$labelValue) {
04779                                                 $labelValue = $csConvObj->conv($labelValue, 'iso-8859-1', $targetCharset);
04780                                         }
04781                                 }
04782 
04783                                 if ($langKey != 'default' && is_array($LOCAL_LANG[$langKey]) && $sourceCharset != $targetCharset) {
04784                                         foreach ($LOCAL_LANG[$langKey] as &$labelValue) {
04785                                                 $labelValue = $csConvObj->conv($labelValue, $sourceCharset, $targetCharset);
04786                                         }
04787                                 }
04788 
04789                                         // Cache the content now:
04790                                 $serContent = array('origFile' => $hashSource, 'LOCAL_LANG' => array('default' => $LOCAL_LANG['default'], $langKey => $LOCAL_LANG[$langKey]));
04791                                 $res = self::writeFileToTypo3tempDir($cacheFileName, serialize($serContent));
04792                                 if ($res) {
04793                                         throw new RuntimeException(
04794                                                 'TYPO3 Fatal Error: "' . $res,
04795                                                 1270853901
04796                                         );
04797                                 }
04798                         } else {
04799                                         // Get content from cache:
04800                                 $serContent = unserialize(self::getUrl($cacheFileName));
04801                                 $LOCAL_LANG = $serContent['LOCAL_LANG'];
04802                         }
04803 
04804                         return $LOCAL_LANG;
04805                 }
04806         }
04807 
04817         public static function readLLXMLfile($fileRef, $langKey, $charset = '') {
04818 
04819                 if (is_object($GLOBALS['LANG'])) {
04820                         $csConvObj = $GLOBALS['LANG']->csConvObj;
04821                 } elseif (is_object($GLOBALS['TSFE'])) {
04822                         $csConvObj = $GLOBALS['TSFE']->csConvObj;
04823                 } else {
04824                         $csConvObj = self::makeInstance('t3lib_cs');
04825                 }
04826 
04827                 $LOCAL_LANG = NULL;
04828                 if (@is_file($fileRef) && $langKey) {
04829 
04830                                 // Set charset:
04831                         if ($charset) {
04832                                 $targetCharset = $csConvObj->parse_charset($charset);
04833                         } elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) {
04834                                         // when forceCharset is set, we store ALL labels in this charset!!!
04835                                 $targetCharset = $csConvObj->parse_charset($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']);
04836                         } else {
04837                                 $targetCharset = $csConvObj->parse_charset($csConvObj->charSetArray[$langKey] ? $csConvObj->charSetArray[$langKey] : 'iso-8859-1');
04838                         }
04839 
04840                                 // Cache file name:
04841                         $hashSource = substr($fileRef, strlen(PATH_site)) . '|' . date('d-m-Y H:i:s', filemtime($fileRef)) . '|version=2.3';
04842                         $cacheFileName = PATH_site . 'typo3temp/llxml/' .
04843                                         substr(basename($fileRef), 10, 15) .
04844                                         '_' . self::shortMD5($hashSource) . '.' . $langKey . '.' . $targetCharset . '.cache';
04845 
04846                                 // Check if cache file exists...
04847                         if (!@is_file($cacheFileName)) { // ... if it doesn't, create content and write it:
04848 
04849                                         // Read XML, parse it.
04850                                 $xmlString = self::getUrl($fileRef);
04851                                 $xmlContent = self::xml2array($xmlString);
04852                                 if (!is_array($xmlContent)) {
04853                                         $fileName = substr($fileRef, strlen(PATH_site));
04854                                         throw new RuntimeException(
04855                                                 'TYPO3 Fatal Error: The file "' . $fileName . '" is no TYPO3 language file!',
04856                                                 1270853902
04857                                         );
04858                                 }
04859 
04860                                         // Set default LOCAL_LANG array content:
04861                                 $LOCAL_LANG = array();
04862                                 $LOCAL_LANG['default'] = $xmlContent['data']['default'];
04863 
04864                                         // converting the default language (English)
04865                                         // this needs to be done for a few accented loan words and extension names
04866                                         // NOTE: no conversion is done when in UTF-8 mode!
04867                                 if (is_array($LOCAL_LANG['default']) && $targetCharset != 'utf-8') {
04868                                         foreach ($LOCAL_LANG['default'] as &$labelValue) {
04869                                                 $labelValue = $csConvObj->utf8_decode($labelValue, $targetCharset);
04870                                         }
04871                                         unset($labelValue);
04872                                 }
04873 
04874                                         // converting other languages to their "native" charsets
04875                                         // NOTE: no conversion is done when in UTF-8 mode!
04876                                 if ($langKey != 'default') {
04877 
04878                                                 // If no entry is found for the language key, then force a value depending on meta-data setting. By default an automated filename will be used:
04879                                         $LOCAL_LANG[$langKey] = self::llXmlAutoFileName($fileRef, $langKey);
04880                                         $localized_file = self::getFileAbsFileName($LOCAL_LANG[$langKey]);
04881                                         if (!@is_file($localized_file) && isset($xmlContent['data'][$langKey])) {
04882                                                 $LOCAL_LANG[$langKey] = $xmlContent['data'][$langKey];
04883                                         }
04884 
04885                                                 // Checking if charset should be converted.
04886                                         if (is_array($LOCAL_LANG[$langKey]) && $targetCharset != 'utf-8') {
04887                                                 foreach ($LOCAL_LANG[$langKey] as $labelKey => $labelValue) {
04888                                                         $LOCAL_LANG[$langKey][$labelKey] = $csConvObj->utf8_decode($labelValue, $targetCharset);
04889                                                 }
04890                                         }
04891                                 }
04892 
04893                                         // Cache the content now:
04894                                 $serContent = array('origFile' => $hashSource, 'LOCAL_LANG' => array('default' => $LOCAL_LANG['default'], $langKey => $LOCAL_LANG[$langKey]));
04895                                 $res = self::writeFileToTypo3tempDir($cacheFileName, serialize($serContent));
04896                                 if ($res) {
04897                                         throw new RuntimeException(
04898                                                 'TYPO3 Fatal Error: ' . $res,
04899                                                 1270853903
04900                                         );
04901                                 }
04902                         } else {
04903                                         // Get content from cache:
04904                                 $serContent = unserialize(self::getUrl($cacheFileName));
04905                                 $LOCAL_LANG = $serContent['LOCAL_LANG'];
04906                         }
04907 
04908                                 // Checking for EXTERNAL file for non-default language:
04909                         if ($langKey != 'default' && is_string($LOCAL_LANG[$langKey]) && strlen($LOCAL_LANG[$langKey])) {
04910 
04911                                         // Look for localized file:
04912                                 $localized_file = self::getFileAbsFileName($LOCAL_LANG[$langKey]);
04913                                 if ($localized_file && @is_file($localized_file)) {
04914 
04915                                                 // Cache file name:
04916                                         $hashSource = substr($localized_file, strlen(PATH_site)) . '|' . date('d-m-Y H:i:s', filemtime($localized_file)) . '|version=2.3';
04917                                         $cacheFileName = PATH_site . 'typo3temp/llxml/EXT_' .
04918                                                         substr(basename($localized_file), 10, 15) .
04919                                                         '_' . self::shortMD5($hashSource) . '.' . $langKey . '.' . $targetCharset . '.cache';
04920 
04921                                                 // Check if cache file exists...
04922                                         if (!@is_file($cacheFileName)) { // ... if it doesn't, create content and write it:
04923 
04924                                                         // Read and parse XML content:
04925                                                 $local_xmlString = self::getUrl($localized_file);
04926                                                 $local_xmlContent = self::xml2array($local_xmlString);
04927                                                 if (!is_array($local_xmlContent)) {
04928                                                         $fileName = substr($localized_file, strlen(PATH_site));
04929                                                         throw new RuntimeException(
04930                                                                 'TYPO3 Fatal Error: The file "' . $fileName . '" is no TYPO3 language file!',
04931                                                                 1270853904
04932                                                         );
04933                                                 }
04934                                                 $LOCAL_LANG[$langKey] = is_array($local_xmlContent['data'][$langKey]) ? $local_xmlContent['data'][$langKey] : array();
04935 
04936                                                         // Checking if charset should be converted.
04937                                                 if (is_array($LOCAL_LANG[$langKey]) && $targetCharset != 'utf-8') {
04938                                                         foreach ($LOCAL_LANG[$langKey] as $labelKey => $labelValue) {
04939                                                                 $LOCAL_LANG[$langKey][$labelKey] = $csConvObj->utf8_decode($labelValue, $targetCharset);
04940                                                         }
04941                                                 }
04942 
04943                                                         // Cache the content now:
04944                                                 $serContent = array('extlang' => $langKey, 'origFile' => $hashSource, 'EXT_DATA' => $LOCAL_LANG[$langKey]);
04945                                                 $res = self::writeFileToTypo3tempDir($cacheFileName, serialize($serContent));
04946                                                 if ($res) {
04947                                                         throw new RuntimeException(
04948                                                                 'TYPO3 Fatal Error: ' . $res,
04949                                                                 1270853905
04950                                                         );
04951                                                 }
04952                                         } else {
04953                                                         // Get content from cache:
04954                                                 $serContent = unserialize(self::getUrl($cacheFileName));
04955                                                 $LOCAL_LANG[$langKey] = $serContent['EXT_DATA'];
04956                                         }
04957                                 } else {
04958                                         $LOCAL_LANG[$langKey] = array();
04959                                 }
04960                         }
04961 
04962                         return $LOCAL_LANG;
04963                 }
04964         }
04965 
04973         public static function llXmlAutoFileName($fileRef, $language) {
04974                         // Analyse file reference:
04975                 $location = 'typo3conf/l10n/' . $language . '/'; // Default location of translations
04976                 if (self::isFirstPartOfStr($fileRef, PATH_typo3 . 'sysext/')) { // Is system:
04977                         $validatedPrefix = PATH_typo3 . 'sysext/';
04978                         #$location = 'EXT:csh_'.$language.'/';  // For system extensions translations are found in "csh_*" extensions (language packs)
04979                 } elseif (self::isFirstPartOfStr($fileRef, PATH_typo3 . 'ext/')) { // Is global:
04980                         $validatedPrefix = PATH_typo3 . 'ext/';
04981                 } elseif (self::isFirstPartOfStr($fileRef, PATH_typo3conf . 'ext/')) { // Is local:
04982                         $validatedPrefix = PATH_typo3conf . 'ext/';
04983                 } else {
04984                         $validatedPrefix = '';
04985                 }
04986 
04987                 if ($validatedPrefix) {
04988 
04989                                 // Divide file reference into extension key, directory (if any) and base name:
04990                         list($file_extKey, $file_extPath) = explode('/', substr($fileRef, strlen($validatedPrefix)), 2);
04991                         $temp = self::revExplode('/', $file_extPath, 2);
04992                         if (count($temp) == 1) {
04993                                 array_unshift($temp, '');
04994                         } // Add empty first-entry if not there.
04995                         list($file_extPath, $file_fileName) = $temp;
04996 
04997                                 // The filename is prefixed with "[language key]." because it prevents the llxmltranslate tool from detecting it.
04998                         return $location .
04999                                         $file_extKey . '/' .
05000                                         ($file_extPath ? $file_extPath . '/' : '') .
05001                                         $language . '.' . $file_fileName;
05002                 } else {
05003                         return NULL;
05004                 }
05005         }
05006 
05007 
05024         public static function loadTCA($table) {
05025                 global $TCA;
05026 
05027                 if (isset($TCA[$table])) {
05028                         $tca = &$TCA[$table];
05029                         if (!$tca['columns']) {
05030                                 $dcf = $tca['ctrl']['dynamicConfigFile'];
05031                                 if ($dcf) {
05032                                         if (!strcmp(substr($dcf, 0, 6), 'T3LIB:')) {
05033                                                 include(PATH_t3lib . 'stddb/' . substr($dcf, 6));
05034                                         } elseif (self::isAbsPath($dcf) && @is_file($dcf)) { // Absolute path...
05035                                                 include($dcf);
05036                                         } else {
05037                                                 include(PATH_typo3conf . $dcf);
05038                                         }
05039                                 }
05040                         }
05041                 }
05042         }
05043 
05053         public static function resolveSheetDefInDS($dataStructArray, $sheet = 'sDEF') {
05054                 if (!is_array($dataStructArray)) {
05055                         return 'Data structure must be an array';
05056                 }
05057 
05058                 if (is_array($dataStructArray['sheets'])) {
05059                         $singleSheet = FALSE;
05060                         if (!isset($dataStructArray['sheets'][$sheet])) {
05061                                 $sheet = 'sDEF';
05062                         }
05063                         $dataStruct = $dataStructArray['sheets'][$sheet];
05064 
05065                                 // If not an array, but still set, then regard it as a relative reference to a file:
05066                         if ($dataStruct && !is_array($dataStruct)) {
05067                                 $file = self::getFileAbsFileName($dataStruct);
05068                                 if ($file && @is_file($file)) {
05069                                         $dataStruct = self::xml2array(self::getUrl($file));
05070                                 }
05071                         }
05072                 } else {
05073                         $singleSheet = TRUE;
05074                         $dataStruct = $dataStructArray;
05075                         if (isset($dataStruct['meta'])) {
05076                                 unset($dataStruct['meta']);
05077                         } // Meta data should not appear there.
05078                         $sheet = 'sDEF'; // Default sheet
05079                 }
05080                 return array($dataStruct, $sheet, $singleSheet);
05081         }
05082 
05090         public static function resolveAllSheetsInDS(array $dataStructArray) {
05091                 if (is_array($dataStructArray['sheets'])) {
05092                         $out = array('sheets' => array());
05093                         foreach ($dataStructArray['sheets'] as $sheetId => $sDat) {
05094                                 list($ds, $aS) = self::resolveSheetDefInDS($dataStructArray, $sheetId);
05095                                 if ($sheetId == $aS) {
05096                                         $out['sheets'][$aS] = $ds;
05097                                 }
05098                         }
05099                 } else {
05100                         list($ds) = self::resolveSheetDefInDS($dataStructArray);
05101                         $out = array('sheets' => array('sDEF' => $ds));
05102                 }
05103                 return $out;
05104         }
05105 
05119         public static function callUserFunction($funcName, &$params, &$ref, $checkPrefix = 'user_', $errorMode = 0) {
05120                 global $TYPO3_CONF_VARS;
05121                 $content = FALSE;
05122 
05123                         // Check persistent object and if found, call directly and exit.
05124                 if (is_array($GLOBALS['T3_VAR']['callUserFunction'][$funcName])) {
05125                         return call_user_func_array(
05126                                 array(&$GLOBALS['T3_VAR']['callUserFunction'][$funcName]['obj'],
05127                                         $GLOBALS['T3_VAR']['callUserFunction'][$funcName]['method']),
05128                                 array(&$params, &$ref)
05129                         );
05130                 }
05131 
05132                         // Check file-reference prefix; if found, require_once() the file (should be library of code)
05133                 if (strpos($funcName, ':') !== FALSE) {
05134                         list($file, $funcRef) = self::revExplode(':', $funcName, 2);
05135                         $requireFile = self::getFileAbsFileName($file);
05136                         if ($requireFile) {
05137                                 self::requireOnce($requireFile);
05138                         }
05139                 } else {
05140                         $funcRef = $funcName;
05141                 }
05142 
05143                         // Check for persistent object token, "&"
05144                 if (substr($funcRef, 0, 1) == '&') {
05145                         $funcRef = substr($funcRef, 1);
05146                         $storePersistentObject = TRUE;
05147                 } else {
05148                         $storePersistentObject = FALSE;
05149                 }
05150 
05151                         // Check prefix is valid:
05152                 if ($checkPrefix && !self::hasValidClassPrefix($funcRef, array($checkPrefix))) {
05153                         $errorMsg = "Function/class '$funcRef' was not prepended with '$checkPrefix'";
05154                         if ($errorMode == 2) {
05155                                 throw new Exception($errorMsg);
05156                         } elseif (!$errorMode) {
05157                                 debug($errorMsg, 't3lib_div::callUserFunction');
05158                         }
05159                         return FALSE;
05160                 }
05161 
05162                         // Call function or method:
05163                 $parts = explode('->', $funcRef);
05164                 if (count($parts) == 2) { // Class
05165 
05166                                 // Check if class/method exists:
05167                         if (class_exists($parts[0])) {
05168 
05169                                         // Get/Create object of class:
05170                                 if ($storePersistentObject) { // Get reference to current instance of class:
05171                                         if (!is_object($GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]])) {
05172                                                 $GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]] = self::makeInstance($parts[0]);
05173                                         }
05174                                         $classObj = $GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]];
05175                                 } else { // Create new object:
05176                                         $classObj = self::makeInstance($parts[0]);
05177                                 }
05178 
05179                                 if (method_exists($classObj, $parts[1])) {
05180 
05181                                                 // If persistent object should be created, set reference:
05182                                         if ($storePersistentObject) {
05183                                                 $GLOBALS['T3_VAR']['callUserFunction'][$funcName] = array(
05184                                                         'method' => $parts[1],
05185                                                         'obj' => &$classObj
05186                                                 );
05187                                         }
05188                                                 // Call method:
05189                                         $content = call_user_func_array(
05190                                                 array(&$classObj, $parts[1]),
05191                                                 array(&$params, &$ref)
05192                                         );
05193                                 } else {
05194                                         $errorMsg = "<strong>ERROR:</strong> No method name '" . $parts[1] . "' in class " . $parts[0];
05195                                         if ($errorMode == 2) {
05196                                                 throw new Exception($errorMsg);
05197                                         } elseif (!$errorMode) {
05198                                                 debug($errorMsg, 't3lib_div::callUserFunction');
05199                                         }
05200                                 }
05201                         } else {
05202                                 $errorMsg = "<strong>ERROR:</strong> No class named: " . $parts[0];
05203                                 if ($errorMode == 2) {
05204                                         throw new Exception($errorMsg);
05205                                 } elseif (!$errorMode) {
05206                                         debug($errorMsg, 't3lib_div::callUserFunction');
05207                                 }
05208                         }
05209                 } else { // Function
05210                         if (function_exists($funcRef)) {
05211                                 $content = call_user_func_array($funcRef, array(&$params, &$ref));
05212                         } else {
05213                                 $errorMsg = "<strong>ERROR:</strong> No function named: " . $funcRef;
05214                                 if ($errorMode == 2) {
05215                                         throw new Exception($errorMsg);
05216                                 } elseif (!$errorMode) {
05217                                         debug($errorMsg, 't3lib_div::callUserFunction');
05218                                 }
05219                         }
05220                 }
05221                 return $content;
05222         }
05223 
05235         public static function getUserObj($classRef, $checkPrefix = 'user_', $silent = FALSE) {
05236                 global $TYPO3_CONF_VARS;
05237                         // Check persistent object and if found, call directly and exit.
05238                 if (is_object($GLOBALS['T3_VAR']['getUserObj'][$classRef])) {
05239                         return $GLOBALS['T3_VAR']['getUserObj'][$classRef];
05240                 } else {
05241 
05242                                 // Check file-reference prefix; if found, require_once() the file (should be library of code)
05243                         if (strpos($classRef, ':') !== FALSE) {
05244                                 list($file, $class) = self::revExplode(':', $classRef, 2);
05245                                 $requireFile = self::getFileAbsFileName($file);
05246                                 if ($requireFile) {
05247                                         self::requireOnce($requireFile);
05248                                 }
05249                         } else {
05250                                 $class = $classRef;
05251                         }
05252 
05253                                 // Check for persistent object token, "&"
05254                         if (substr($class, 0, 1) == '&') {
05255                                 $class = substr($class, 1);
05256                                 $storePersistentObject = TRUE;
05257                         } else {
05258                                 $storePersistentObject = FALSE;
05259                         }
05260 
05261                                 // Check prefix is valid:
05262                         if ($checkPrefix && !self::hasValidClassPrefix($class, array($checkPrefix))) {
05263                                 if (!$silent) {
05264                                         debug("Class '" . $class . "' was not prepended with '" . $checkPrefix . "'", 't3lib_div::getUserObj');
05265                                 }
05266                                 return FALSE;
05267                         }
05268 
05269                                 // Check if class exists:
05270                         if (class_exists($class)) {
05271                                 $classObj = self::makeInstance($class);
05272 
05273                                         // If persistent object should be created, set reference:
05274                                 if ($storePersistentObject) {
05275                                         $GLOBALS['T3_VAR']['getUserObj'][$classRef] = $classObj;
05276                                 }
05277 
05278                                 return $classObj;
05279                         } else {
05280                                 if (!$silent) {
05281                                         debug("<strong>ERROR:</strong> No class named: " . $class, 't3lib_div::getUserObj');
05282                                 }
05283                         }
05284                 }
05285         }
05286 
05294         public static function hasValidClassPrefix($classRef, array $additionalPrefixes = array()) {
05295                 $hasValidPrefix = FALSE;
05296                 $validPrefixes = array('tx_', 'Tx_', $GLOBALS['TYPO3_CONF_VARS']['FE']['userFuncClassPrefix']);
05297                 $classRef = trim($classRef);
05298 
05299                 if (count($additionalPrefixes)) {
05300                         $validPrefixes = array_merge($validPrefixes, $additionalPrefixes);
05301                 }
05302 
05303                 foreach ($validPrefixes as $prefixToCheck) {
05304                         if (self::isFirstPartOfStr($classRef, $prefixToCheck)) {
05305                                 $hasValidPrefix = TRUE;
05306                                 break;
05307                         }
05308                 }
05309 
05310                 return $hasValidPrefix;
05311         }
05312 
05326         public static function makeInstance($className) {
05327                 if ($className === '') {
05328                         throw new InvalidArgumentException('$classname must not be empty.', 1288965219);
05329                 }
05330 
05331                         // Determine final class name which must be instantiated, this takes XCLASS handling
05332                         // into account. Cache in a local array to save some cycles for consecutive calls.
05333                 if (!isset(self::$finalClassNameRegister[$className])) {
05334                         self::$finalClassNameRegister[$className] = self::getClassName($className);
05335                 }
05336                 $finalClassName = self::$finalClassNameRegister[$className];
05337 
05338                         // Return singleton instance if it is already registered
05339                 if (isset(self::$singletonInstances[$finalClassName])) {
05340                         return self::$singletonInstances[$finalClassName];
05341                 }
05342 
05343                         // Return instance if it has been injected by addInstance()
05344                 if (isset(self::$nonSingletonInstances[$finalClassName])
05345                         && !empty(self::$nonSingletonInstances[$finalClassName])
05346                 ) {
05347                         return array_shift(self::$nonSingletonInstances[$finalClassName]);
05348                 }
05349 
05350                         // Create new instance and call constructor with parameters
05351                 if (func_num_args() > 1) {
05352                         $constructorArguments = func_get_args();
05353                         array_shift($constructorArguments);
05354 
05355                         $reflectedClass = new ReflectionClass($finalClassName);
05356                         $instance = $reflectedClass->newInstanceArgs($constructorArguments);
05357                 } else {
05358                         $instance = new $finalClassName;
05359                 }
05360 
05361                         // Register new singleton instance
05362                 if ($instance instanceof t3lib_Singleton) {
05363                         self::$singletonInstances[$finalClassName] = $instance;
05364                 }
05365 
05366                 return $instance;
05367         }
05368 
05378         public static function makeInstanceClassName($className) {
05379                 self::logDeprecatedFunction();
05380 
05381                 return (class_exists($className) && class_exists('ux_' . $className, FALSE) ? self::makeInstanceClassName('ux_' . $className) : $className);
05382         }
05383 
05391         protected function getClassName($className) {
05392                 if (class_exists($className)) {
05393                         while (class_exists('ux_' . $className, FALSE)) {
05394                                 $className = 'ux_' . $className;
05395                         }
05396                 }
05397 
05398                 return $className;
05399         }
05400 
05416         public static function setSingletonInstance($className, t3lib_Singleton $instance) {
05417                 self::checkInstanceClassName($className, $instance);
05418                 self::$singletonInstances[$className] = $instance;
05419         }
05420 
05438         public static function addInstance($className, $instance) {
05439                 self::checkInstanceClassName($className, $instance);
05440 
05441                 if ($instance instanceof t3lib_Singleton) {
05442                         throw new InvalidArgumentException(
05443                                 '$instance must not be an instance of t3lib_Singleton. ' .
05444                                         'For setting singletons, please use setSingletonInstance.',
05445                                 1288969325
05446                         );
05447                 }
05448 
05449                 if (!isset(self::$nonSingletonInstances[$className])) {
05450                         self::$nonSingletonInstances[$className] = array();
05451                 }
05452                 self::$nonSingletonInstances[$className][] = $instance;
05453         }
05454 
05464         protected static function checkInstanceClassName($className, $instance) {
05465                 if ($className === '') {
05466                         throw new InvalidArgumentException('$className must not be empty.', 1288967479);
05467                 }
05468                 if (!($instance instanceof $className)) {
05469                         throw new InvalidArgumentException(
05470                                 '$instance must be an instance of ' . $className . ', but actually is an instance of ' . get_class($instance) . '.',
05471                                 1288967686
05472                         );
05473                 }
05474         }
05475 
05487         public static function purgeInstances() {
05488                 self::$singletonInstances = array();
05489                 self::$nonSingletonInstances = array();
05490         }
05491 
05502         public static function makeInstanceService($serviceType, $serviceSubType = '', $excludeServiceKeys = array()) {
05503                 global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
05504 
05505                 $error = FALSE;
05506 
05507                 if (!is_array($excludeServiceKeys)) {
05508                         $excludeServiceKeys = self::trimExplode(',', $excludeServiceKeys, 1);
05509                 }
05510                 while ($info = t3lib_extMgm::findService($serviceType, $serviceSubType, $excludeServiceKeys)) {
05511 
05512                                 // Check persistent object and if found, call directly and exit.
05513                         if (is_object($GLOBALS['T3_VAR']['makeInstanceService'][$info['className']])) {
05514                                         // reset service and return object
05515                                 $T3_VAR['makeInstanceService'][$info['className']]->reset();
05516                                 return $GLOBALS['T3_VAR']['makeInstanceService'][$info['className']];
05517 
05518                                 // include file and create object
05519                         } else {
05520                                 $requireFile = self::getFileAbsFileName($info['classFile']);
05521                                 if (@is_file($requireFile)) {
05522                                         self::requireOnce($requireFile);
05523                                         $obj = self::makeInstance($info['className']);
05524                                         if (is_object($obj)) {
05525                                                 if (!@is_callable(array($obj, 'init'))) {
05526                                                                 // use silent logging??? I don't think so.
05527                                                         die ('Broken service:' . t3lib_utility_Debug::viewArray($info));
05528                                                 }
05529                                                 $obj->info = $info;
05530                                                 if ($obj->init()) { // service available?
05531 
05532                                                                 // create persistent object
05533                                                         $T3_VAR['makeInstanceService'][$info['className']] = $obj;
05534 
05535                                                                 // needed to delete temp files
05536                                                         register_shutdown_function(array(&$obj, '__destruct'));
05537 
05538                                                         return $obj; // object is passed as reference by function definition
05539                                                 }
05540                                                 $error = $obj->getLastErrorArray();
05541                                                 unset($obj);
05542                                         }
05543                                 }
05544                         }
05545                                 // deactivate the service
05546                         t3lib_extMgm::deactivateService($info['serviceType'], $info['serviceKey']);
05547                 }
05548                 return $error;
05549         }
05550 
05555         public static function requireOnce($requireFile) {
05556                 global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
05557 
05558                 require_once ($requireFile);
05559         }
05560 
05569         public static function requireFile($requireFile) {
05570                 global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
05571                 require $requireFile;
05572         }
05573 
05589         public static function plainMailEncoded($email, $subject, $message, $headers = '', $encoding = 'quoted-printable', $charset = '', $dontEncodeHeader = FALSE) {
05590                 if (!$charset) {
05591                         $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'ISO-8859-1';
05592                 }
05593 
05594                 $email = self::normalizeMailAddress($email);
05595                 if (!$dontEncodeHeader) {
05596                                 // Mail headers must be ASCII, therefore we convert the whole header to either base64 or quoted_printable
05597                         $newHeaders = array();
05598                         foreach (explode(LF, $headers) as $line) { // Split the header in lines and convert each line separately
05599                                 $parts = explode(': ', $line, 2); // Field tags must not be encoded
05600                                 if (count($parts) == 2) {
05601                                         if (0 == strcasecmp($parts[0], 'from')) {
05602                                                 $parts[1] = self::normalizeMailAddress($parts[1]);
05603                                         }
05604                                         $parts[1] = self::encodeHeader($parts[1], $encoding, $charset);
05605                                         $newHeaders[] = implode(': ', $parts);
05606                                 } else {
05607                                         $newHeaders[] = $line; // Should never happen - is such a mail header valid? Anyway, just add the unchanged line...
05608                                 }
05609                         }
05610                         $headers = implode(LF, $newHeaders);
05611                         unset($newHeaders);
05612 
05613                         $email = self::encodeHeader($email, $encoding, $charset); // Email address must not be encoded, but it could be appended by a name which should be so (e.g. "Kasper Skårhøj <kasperYYYY@typo3.com>")
05614                         $subject = self::encodeHeader($subject, $encoding, $charset);
05615                 }
05616 
05617                 switch ((string) $encoding) {
05618                         case 'base64':
05619                                 $headers = trim($headers) . LF .
05620                                                 'Mime-Version: 1.0' . LF .
05621                                                 'Content-Type: text/plain; charset="' . $charset . '"' . LF .
05622                                                 'Content-Transfer-Encoding: base64';
05623 
05624                                 $message = trim(chunk_split(base64_encode($message . LF))) . LF; // Adding LF because I think MS outlook 2002 wants it... may be removed later again.
05625                                 break;
05626                         case '8bit':
05627                                 $headers = trim($headers) . LF .
05628                                                 'Mime-Version: 1.0' . LF .
05629                                                 'Content-Type: text/plain; charset=' . $charset . LF .
05630                                                 'Content-Transfer-Encoding: 8bit';
05631                                 break;
05632                         case 'quoted-printable':
05633                         default:
05634                                 $headers = trim($headers) . LF .
05635                                                 'Mime-Version: 1.0' . LF .
05636                                                 'Content-Type: text/plain; charset=' . $charset . LF .
05637                                                 'Content-Transfer-Encoding: quoted-printable';
05638 
05639                                 $message = self::quoted_printable($message);
05640                                 break;
05641                 }
05642 
05643                         // Headers must be separated by CRLF according to RFC 2822, not just LF.
05644                         // But many servers (Gmail, for example) behave incorectly and want only LF.
05645                         // So we stick to LF in all cases.
05646                 $headers = trim(implode(LF, self::trimExplode(LF, $headers, TRUE))); // Make sure no empty lines are there.
05647 
05648 
05649                 return t3lib_utility_Mail::mail($email, $subject, $message, $headers);
05650         }
05651 
05662         public static function quoted_printable($string, $maxlen = 76) {
05663                         // Make sure the string contains only Unix linebreaks
05664                 $string = str_replace(CRLF, LF, $string); // Replace Windows breaks (\r\n)
05665                 $string = str_replace(CR, LF, $string); // Replace Mac breaks (\r)
05666 
05667                 $linebreak = LF; // Default line break for Unix systems.
05668                 if (TYPO3_OS == 'WIN') {
05669                         $linebreak = CRLF; // Line break for Windows. This is needed because PHP on Windows systems send mails via SMTP instead of using sendmail, and thus the linebreak needs to be \r\n.
05670                 }
05671 
05672                 $newString = '';
05673                 $theLines = explode(LF, $string); // Split lines
05674                 foreach ($theLines as $val) {
05675                         $newVal = '';
05676                         $theValLen = strlen($val);
05677                         $len = 0;
05678                         for ($index = 0; $index < $theValLen; $index++) { // Walk through each character of this line
05679                                 $char = substr($val, $index, 1);
05680                                 $ordVal = ord($char);
05681                                 if ($len > ($maxlen - 4) || ($len > ($maxlen - 14) && $ordVal == 32)) {
05682                                         $newVal .= '=' . $linebreak; // Add a line break
05683                                         $len = 0; // Reset the length counter
05684                                 }
05685                                 if (($ordVal >= 33 && $ordVal <= 60) || ($ordVal >= 62 && $ordVal <= 126) || $ordVal == 9 || $ordVal == 32) {
05686                                         $newVal .= $char; // This character is ok, add it to the message
05687                                         $len++;
05688                                 } else {
05689                                         $newVal .= sprintf('=%02X', $ordVal); // Special character, needs to be encoded
05690                                         $len += 3;
05691                                 }
05692                         }
05693                         $newVal = preg_replace('/' . chr(32) . '$/', '=20', $newVal); // Replaces a possible SPACE-character at the end of a line
05694                         $newVal = preg_replace('/' . TAB . '$/', '=09', $newVal); // Replaces a possible TAB-character at the end of a line
05695                         $newString .= $newVal . $linebreak;
05696                 }
05697                 return preg_replace('/' . $linebreak . '$/', '', $newString); // Remove last newline
05698         }
05699 
05709         public static function encodeHeader($line, $enc = 'quoted-printable', $charset = 'iso-8859-1') {
05710                         // Avoid problems if "###" is found in $line (would conflict with the placeholder which is used below)
05711                 if (strpos($line, '###') !== FALSE) {
05712                         return $line;
05713                 }
05714                         // Check if any non-ASCII characters are found - otherwise encoding is not needed
05715                 if (!preg_match('/[^' . chr(32) . '-' . chr(127) . ']/', $line)) {
05716                         return $line;
05717                 }
05718                         // Wrap email addresses in a special marker
05719                 $line = preg_replace('/([^ ]+@[^ ]+)/', '###$1###', $line);
05720 
05721                 $matches = preg_split('/(.?###.+###.?|\(|\))/', $line, -1, PREG_SPLIT_NO_EMPTY);
05722                 foreach ($matches as $part) {
05723                         $oldPart = $part;
05724                         switch ((string) $enc) {
05725                                 case 'base64':
05726                                         $part = '=?' . $charset . '?B?' . base64_encode($part) . '?=';
05727                                         break;
05728                                 case 'quoted-printable':
05729                                 default:
05730                                         $qpValue = self::quoted_printable($part, 1000);
05731                                         if ($part != $qpValue) {
05732                                                         // Encoded words in the header should not contain non-encoded:
05733                                                         // * spaces. "_" is a shortcut for "=20". See RFC 2047 for details.
05734                                                         // * question mark. See RFC 1342 (http://tools.ietf.org/html/rfc1342)
05735                                                 $search = array(' ', '?');
05736                                                 $replace = array('_', '=3F');
05737                                                 $qpValue = str_replace($search, $replace, $qpValue);
05738                                                 $part = '=?' . $charset . '?Q?' . $qpValue . '?=';
05739                                         }
05740                                         break;
05741                         }
05742                         $line = str_replace($oldPart, $part, $line);
05743                 }
05744                 $line = preg_replace('/###(.+?)###/', '$1', $line); // Remove the wrappers
05745 
05746                 return $line;
05747         }
05748 
05760         public static function substUrlsInPlainText($message, $urlmode = '76', $index_script_url = '') {
05761                         // Substitute URLs with shorter links:
05762                 foreach (array('http', 'https') as $protocol) {
05763                         $urlSplit = explode($protocol . '://', $message);
05764                         foreach ($urlSplit as $c => &$v) {
05765                                 if ($c) {
05766                                         $newParts = preg_split('/\s|[<>"{}|\\\^`()\']/', $v, 2);
05767                                         $newURL = $protocol . '://' . $newParts[0];
05768 
05769                                         switch ((string) $urlmode) {
05770                                                 case 'all':
05771                                                         $newURL = self::makeRedirectUrl($newURL, 0, $index_script_url);
05772                                                         break;
05773                                                 case '76':
05774                                                         $newURL = self::makeRedirectUrl($newURL, 76, $index_script_url);
05775                                                         break;
05776                                         }
05777                                         $v = $newURL . substr($v, strlen($newParts[0]));
05778                                 }
05779                         }
05780                         $message = implode('', $urlSplit);
05781                 }
05782 
05783                 return $message;
05784         }
05785 
05795         public static function makeRedirectUrl($inUrl, $l = 0, $index_script_url = '') {
05796                 if (strlen($inUrl) > $l) {
05797                         $md5 = substr(md5($inUrl), 0, 20);
05798                         $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
05799                                 '*',
05800                                 'cache_md5params',
05801                                         'md5hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($md5, 'cache_md5params')
05802                         );
05803                         if (!$count) {
05804                                 $insertFields = array(
05805                                         'md5hash' => $md5,
05806                                         'tstamp' => $GLOBALS['EXEC_TIME'],
05807                                         'type' => 2,
05808                                         'params' => $inUrl
05809                                 );
05810 
05811                                 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_md5params', $insertFields);
05812                         }
05813                         $inUrl = ($index_script_url ? $index_script_url : self::getIndpEnv('TYPO3_REQUEST_DIR') . 'index.php') .
05814                                         '?RDCT=' . $md5;
05815                 }
05816 
05817                 return $inUrl;
05818         }
05819 
05827         public static function freetypeDpiComp($font_size) {
05828                 $dpi = intval($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi']);
05829                 if ($dpi != 72) {
05830                         $font_size = $font_size / $dpi * 72;
05831                 }
05832                 return $font_size;
05833         }
05834 
05841         public static function initSysLog() {
05842                 global $TYPO3_CONF_VARS;
05843 
05844                         // for CLI logging name is <fqdn-hostname>:<TYPO3-path>
05845                         // Note that TYPO3_REQUESTTYPE is not used here as it may not yet be defined
05846                 if (defined('TYPO3_cliMode') && TYPO3_cliMode) {
05847                         $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = self::getHostname($requestHost = FALSE) . ':' . PATH_site;
05848                 }
05849                         // for Web logging name is <protocol>://<request-hostame>/<site-path>
05850                 else {
05851                         $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = self::getIndpEnv('TYPO3_SITE_URL');
05852                 }
05853 
05854                         // init custom logging
05855                 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
05856                         $params = array('initLog' => TRUE);
05857                         $fakeThis = FALSE;
05858                         foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod) {
05859                                 self::callUserFunction($hookMethod, $params, $fakeThis);
05860                         }
05861                 }
05862 
05863                         // init TYPO3 logging
05864                 foreach (explode(';', $TYPO3_CONF_VARS['SYS']['systemLog'], 2) as $log) {
05865                         list($type, $destination) = explode(',', $log, 3);
05866 
05867                         if ($type == 'syslog') {
05868                                 if (TYPO3_OS == 'WIN') {
05869                                         $facility = LOG_USER;
05870                                 } else {
05871                                         $facility = constant('LOG_' . strtoupper($destination));
05872                                 }
05873                                 openlog($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'], LOG_ODELAY, $facility);
05874                         }
05875                 }
05876 
05877                 $TYPO3_CONF_VARS['SYS']['systemLogLevel'] = self::intInRange($TYPO3_CONF_VARS['SYS']['systemLogLevel'], 0, 4);
05878                 $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogInit'] = TRUE;
05879         }
05880 
05892         public static function sysLog($msg, $extKey, $severity = 0) {
05893                 global $TYPO3_CONF_VARS;
05894 
05895                 $severity = self::intInRange($severity, 0, 4);
05896 
05897                         // is message worth logging?
05898                 if (intval($TYPO3_CONF_VARS['SYS']['systemLogLevel']) > $severity) {
05899                         return;
05900                 }
05901 
05902                         // initialize logging
05903                 if (!$TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogInit']) {
05904                         self::initSysLog();
05905                 }
05906 
05907                         // do custom logging
05908                 if (isset($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog']) &&
05909                                 is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
05910                         $params = array('msg' => $msg, 'extKey' => $extKey, 'backTrace' => debug_backtrace(), 'severity' => $severity);
05911                         $fakeThis = FALSE;
05912                         foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod) {
05913                                 self::callUserFunction($hookMethod, $params, $fakeThis);
05914                         }
05915                 }
05916 
05917                         // TYPO3 logging enabled?
05918                 if (!$TYPO3_CONF_VARS['SYS']['systemLog']) {
05919                         return;
05920                 }
05921 
05922                 $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
05923                 $timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
05924 
05925                         // use all configured logging options
05926                 foreach (explode(';', $TYPO3_CONF_VARS['SYS']['systemLog'], 2) as $log) {
05927                         list($type, $destination, $level) = explode(',', $log, 4);
05928 
05929                                 // is message worth logging for this log type?
05930                         if (intval($level) > $severity) {
05931                                 continue;
05932                         }
05933 
05934                         $msgLine = ' - ' . $extKey . ': ' . $msg;
05935 
05936                                 // write message to a file
05937                         if ($type == 'file') {
05938                                 $file = fopen($destination, 'a');
05939                                 if ($file) {
05940                                         flock($file, LOCK_EX); // try locking, but ignore if not available (eg. on NFS and FAT)
05941                                         fwrite($file, date($dateFormat . ' ' . $timeFormat) . $msgLine . LF);
05942                                         flock($file, LOCK_UN); // release the lock
05943                                         fclose($file);
05944                                         self::fixPermissions($destination);
05945                                 }
05946                         }
05947                                 // send message per mail
05948                         elseif ($type == 'mail') {
05949                                 list($to, $from) = explode('/', $destination);
05950                                 if (!t3lib_div::validEmail($from)) {
05951                                         $from = t3lib_utility_Mail::getSystemFrom();
05952                                 }
05954                                 $mail = t3lib_div::makeInstance('t3lib_mail_Message');
05955                                 $mail->setTo($to)
05956                                                 ->setFrom($from)
05957                                                 ->setSubject('Warning - error in TYPO3 installation')
05958                                                 ->setBody('Host: ' . $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] . LF .
05959                                                                 'Extension: ' . $extKey . LF .
05960                                                                 'Severity: ' . $severity . LF .
05961                                                                 LF . $msg
05962                                 );
05963                                 $mail->send();
05964                         }
05965                                 // use the PHP error log
05966                         elseif ($type == 'error_log') {
05967                                 error_log($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] . $msgLine, 0);
05968                         }
05969                                 // use the system log
05970                         elseif ($type == 'syslog') {
05971                                 $priority = array(LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT);
05972                                 syslog($priority[(int) $severity], $msgLine);
05973                         }
05974                 }
05975         }
05976 
05991         public static function devLog($msg, $extKey, $severity = 0, $dataVar = FALSE) {
05992                 global $TYPO3_CONF_VARS;
05993 
05994                 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['devLog'])) {
05995                         $params = array('msg' => $msg, 'extKey' => $extKey, 'severity' => $severity, 'dataVar' => $dataVar);
05996                         $fakeThis = FALSE;
05997                         foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['devLog'] as $hookMethod) {
05998                                 self::callUserFunction($hookMethod, $params, $fakeThis);
05999                         }
06000                 }
06001         }
06002 
06009         public static function deprecationLog($msg) {
06010                 if (!$GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog']) {
06011                         return;
06012                 }
06013 
06014                 $log = $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'];
06015                 $date = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] . ' ' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] . ': ');
06016 
06017                         // legacy values (no strict comparison, $log can be boolean, string or int)
06018                 if ($log === TRUE || $log == '1') {
06019                         $log = 'file';
06020                 }
06021 
06022                 if (stripos($log, 'file') !== FALSE) {
06023                                 // write a longer message to the deprecation log
06024                         $destination = self::getDeprecationLogFileName();
06025                         $file = @fopen($destination, 'a');
06026                         if ($file) {
06027                                 flock($file, LOCK_EX); // try locking, but ignore if not available (eg. on NFS and FAT)
06028                                 @fwrite($file, $date . $msg . LF);
06029                                 flock($file, LOCK_UN); // release the lock
06030                                 @fclose($file);
06031                                 self::fixPermissions($destination);
06032                         }
06033                 }
06034 
06035                 if (stripos($log, 'devlog') !== FALSE) {
06036                                 // copy message also to the developer log
06037                         self::devLog($msg, 'Core', self::SYSLOG_SEVERITY_WARNING);
06038                 }
06039 
06040                         // do not use console in login screen
06041                 if (stripos($log, 'console') !== FALSE && isset($GLOBALS['BE_USER']->user['uid'])) {
06042                         t3lib_utility_Debug::debug($msg, $date, 'Deprecation Log');
06043                 }
06044         }
06045 
06051         public static function getDeprecationLogFileName() {
06052                 return PATH_typo3conf .
06053                                 'deprecation_' .
06054                                 self::shortMD5(
06055                                         PATH_site . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']
06056                                 ) .
06057                                 '.log';
06058         }
06059 
06065         public static function logDeprecatedFunction() {
06066                 if (!$GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog']) {
06067                         return;
06068                 }
06069 
06070                 $trail = debug_backtrace();
06071 
06072                 if ($trail[1]['type']) {
06073                         $function = new ReflectionMethod($trail[1]['class'], $trail[1]['function']);
06074                 } else {
06075                         $function = new ReflectionFunction($trail[1]['function']);
06076                 }
06077 
06078                 $msg = '';
06079                 if (preg_match('/@deprecated\s+(.*)/', $function->getDocComment(), $match)) {
06080                         $msg = $match[1];
06081                 }
06082 
06083                         // trigger PHP error with a short message: <function> is deprecated (called from <source>, defined in <source>)
06084                 $errorMsg = 'Function ' . $trail[1]['function'];
06085                 if ($trail[1]['class']) {
06086                         $errorMsg .= ' of class ' . $trail[1]['class'];
06087                 }
06088                 $errorMsg .= ' is deprecated (called from ' . $trail[1]['file'] . '#' . $trail[1]['line'] . ', defined in ' . $function->getFileName() . '#' . $function->getStartLine() . ')';
06089 
06090                         // write a longer message to the deprecation log: <function> <annotion> - <trace> (<source>)
06091                 $logMsg = $trail[1]['class'] . $trail[1]['type'] . $trail[1]['function'];
06092                 $logMsg .= '() - ' . $msg.' - ' . t3lib_utility_Debug::debugTrail();
06093                 $logMsg .= ' (' . substr($function->getFileName(), strlen(PATH_site)) . '#' . $function->getStartLine() . ')';
06094                 self::deprecationLog($logMsg);
06095         }
06096 
06106         public static function arrayToLogString(array $arr, $valueList = array(), $valueLength = 20) {
06107                 $str = '';
06108                 if (!is_array($valueList)) {
06109                         $valueList = self::trimExplode(',', $valueList, 1);
06110                 }
06111                 $valListCnt = count($valueList);
06112                 foreach ($arr as $key => $value) {
06113                         if (!$valListCnt || in_array($key, $valueList)) {
06114                                 $str .= (string) $key . trim(': ' . self::fixed_lgd_cs(str_replace(LF, '|', (string) $value), $valueLength)) . '; ';
06115                         }
06116                 }
06117                 return $str;
06118         }
06119 
06128         public static function imageMagickCommand($command, $parameters, $path = '') {
06129                 return t3lib_utility_Command::imageMagickCommand($command, $parameters, $path);
06130         }
06131 
06139         public static function unQuoteFilenames($parameters, $unQuote = FALSE) {
06140                 $paramsArr = explode(' ', trim($parameters));
06141 
06142                 $quoteActive = -1; // Whenever a quote character (") is found, $quoteActive is set to the element number inside of $params. A value of -1 means that there are not open quotes at the current position.
06143                 foreach ($paramsArr as $k => $v) {
06144                         if ($quoteActive > -1) {
06145                                 $paramsArr[$quoteActive] .= ' ' . $v;
06146                                 unset($paramsArr[$k]);
06147                                 if (substr($v, -1) === $paramsArr[$quoteActive][0]) {
06148                                         $quoteActive = -1;
06149                                 }
06150                         } elseif (!trim($v)) {
06151                                 unset($paramsArr[$k]); // Remove empty elements
06152 
06153                         } elseif (preg_match('/^(["\'])/', $v) && substr($v, -1) !== $v[0]) {
06154                                 $quoteActive = $k;
06155                         }
06156                 }
06157 
06158                 if ($unQuote) {
06159                         foreach ($paramsArr as $key => &$val) {
06160                                 $val = preg_replace('/(^"|"$)/', '', $val);
06161                                 $val = preg_replace('/(^\'|\'$)/', '', $val);
06162 
06163                         }
06164                 }
06165                         // return reindexed array
06166                 return array_values($paramsArr);
06167         }
06168 
06169 
06183         static public function quoteJSvalue($value, $withinCData = FALSE) {
06184                 $escapedValue = addcslashes(
06185                         $value, '\'' . '"' . '\\' . TAB . LF . CR
06186                 );
06187                 if (!$withinCData) {
06188                         $escapedValue = htmlspecialchars($escapedValue);
06189                 }
06190                 return '\'' . $escapedValue . '\'';
06191         }
06192 
06193 
06199         public static function cleanOutputBuffers() {
06200                 while (ob_end_clean()) {
06201                         ;
06202                 }
06203                 header('Content-Encoding: None', TRUE);
06204         }
06205 
06206 
06212         public static function flushOutputBuffers() {
06213                 $obContent = '';
06214 
06215                 while ($obContent .= ob_get_clean()) {
06216                         ;
06217                 }
06218 
06219                         // if previously a "Content-Encoding: whatever" has been set, we have to unset it
06220                 if (!headers_sent()) {
06221                         $headersList = headers_list();
06222                         foreach ($headersList as $header) {
06223                                         // split it up at the :
06224                                 list($key, $value) = self::trimExplode(':', $header, TRUE);
06225                                         // check if we have a Content-Encoding other than 'None'
06226                                 if (strtolower($key) === 'content-encoding' && strtolower($value) !== 'none') {
06227                                         header('Content-Encoding: None');
06228                                         break;
06229                                 }
06230                         }
06231                 }
06232                 echo $obContent;
06233         }
06234 }
06235 
06236 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations