Added argument to debugRows() so it can return HTML instead of echo'ing
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_div.php
index ff2c523..bfa3888 100755 (executable)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2007 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -487,13 +487,13 @@ class t3lib_div {
         * Truncate string
         * Returns a new string of max. $chars length.
         * If the string is longer, it will be truncated and appended with '...'.
-        * DEPRECATED. Works ONLY for single-byte charsets! USE t3lib_div::fixed_lgd_cs() instead
         * Usage: 39
         *
         * @param       string          string to truncate
         * @param       integer         must be an integer with an absolute value of at least 4. if negative the string is cropped from the right end.
         * @param       string          String to append to the output if it is truncated, default is '...'
         * @return      string          new string
+        * @deprecated          Works ONLY for single-byte charsets! USE t3lib_div::fixed_lgd_cs() instead
         * @see fixed_lgd_pre()
         */
        function fixed_lgd($string,$origChars,$preStr='...')    {
@@ -513,12 +513,12 @@ class t3lib_div {
         * Returns a new string of max. $chars length.
         * If the string is longer, it will be truncated and prepended with '...'.
         * This works like fixed_lgd, but is truncated in the start of the string instead of the end
-        * DEPRECATED. Use either fixed_lgd() or fixed_lgd_cs() (with negative input value for $chars)
         * Usage: 6
         *
         * @param       string          string to truncate
         * @param       integer         must be an integer of at least 4
         * @return      string          new string
+        * @deprecated          Use either fixed_lgd() or fixed_lgd_cs() (with negative input value for $chars)
         * @see fixed_lgd()
         */
        function fixed_lgd_pre($string,$chars)  {
@@ -550,13 +550,14 @@ class t3lib_div {
         * @param       string          The string to break up
         * @param       string          The string to implode the broken lines with (default/typically \n)
         * @param       integer         The line length
+        * @deprecated          Use PHP function wordwrap()
         * @return      string
         */
        function breakTextForEmail($str,$implChar="\n",$charWidth=76)   {
                $lines = explode(chr(10),$str);
                $outArr=array();
                while(list(,$lStr)=each($lines))        {
-                       $outArr = array_merge($outArr,t3lib_div::breakLinesForEmail($lStr,$implChar,$charWidth));
+                       $outArr[] = t3lib_div::breakLinesForEmail($lStr,$implChar,$charWidth);
                }
                return implode(chr(10),$outArr);
        }
@@ -927,13 +928,15 @@ class t3lib_div {
 
        /**
         * Returns true if the current TYPO3 version (or compatibility version) is compatible to the input version
+        * Notice that this function compares branches, not versions (4.0.1 would be > 4.0.0 although they use the same compat_version)
         *
-        * @param       string          Minimum version number required (format x.y.z)
-        * @return      boolean         true or false
+        * @param       string          Minimum branch number required (format x.y / e.g. "4.0" NOT "4.0.0"!)
+        * @return      boolean         Returns true if this setup is compatible with the provided version number
+        * @todo        Still needs a function to convert versions to branches
         */
        function compat_version($verNumberStr)  {
                global $TYPO3_CONF_VARS;
-               $currVersionStr = $TYPO3_CONF_VARS['SYS']['compat_version']?$TYPO3_CONF_VARS['SYS']['compat_version']:TYPO3_version;
+               $currVersionStr = $TYPO3_CONF_VARS['SYS']['compat_version'] ? $TYPO3_CONF_VARS['SYS']['compat_version'] : TYPO3_branch;
 
                if (t3lib_div::int_from_ver($currVersionStr) < t3lib_div::int_from_ver($verNumberStr))  {
                        return FALSE;
@@ -1080,11 +1083,11 @@ class t3lib_div {
 
        /**
         * strtoupper which converts danish (and other characters) characters as well
-        * (DEPRECATED, use t3lib_cs::conv_case() instead or for HTML output, wrap your content in <span class="uppercase">...</span>)
         * Usage: 0
         *
         * @param       string          String to process
         * @return      string
+        * @deprecated          Use t3lib_cs::conv_case() instead or for HTML output, wrap your content in <span class="uppercase">...</span>)
         * @ignore
         */
        function danish_strtoupper($string)     {
@@ -1095,11 +1098,11 @@ class t3lib_div {
        /**
         * Change umlaut characters to plain ASCII with normally two character target
         * Only known characters will be converted, so don't expect a result for any character.
-        * (DEPRECATED: Works only for western europe single-byte charsets! Use t3lib_cs::specCharsToASCII() instead!)
         *
         * ä => ae, Ö => Oe
         *
         * @param       string          String to convert.
+        * @deprecated          Works only for western europe single-byte charsets! Use t3lib_cs::specCharsToASCII() instead!
         * @return      string
         */
        function convUmlauts($str)      {
@@ -1461,13 +1464,12 @@ class t3lib_div {
 
        /**
         * Remove duplicate values from an array
-        * This function is deprecated, use the PHP function array_unique instead
         * Usage: 0
         *
         * @param       array           Array of values to make unique
         * @return      array
         * @ignore
-        * @deprecated
+        * @deprecated          Use the PHP function array_unique instead
         */
        function uniqueArray($valueArray)       {
                return array_unique($valueArray);
@@ -1644,7 +1646,7 @@ class t3lib_div {
         * @param       array           First array
         * @param       array           Second array, overruling the first array
         * @param       boolean         If set, keys that are NOT found in $arr0 (first array) will not be set. Thus only existing value can/will be overruled from second array.
-        * @param       boolean         If set, values from $arr1 will overrule if they are empty. Default: true
+        * @param       boolean         If set, values from $arr1 will overrule if they are empty or zero. Default: true
         * @return      array           Resulting array where $arr1 values has overruled $arr0 values
         */
        function array_merge_recursive_overrule($arr0,$arr1,$notAddKeys=0,$includeEmtpyValues=true) {
@@ -1652,17 +1654,17 @@ class t3lib_div {
                while(list($key,$val) = each($arr1)) {
                        if(is_array($arr0[$key])) {
                                if (is_array($arr1[$key]))      {
-                                       $arr0[$key] = t3lib_div::array_merge_recursive_overrule($arr0[$key],$arr1[$key],$notAddKeys);
+                                       $arr0[$key] = t3lib_div::array_merge_recursive_overrule($arr0[$key],$arr1[$key],$notAddKeys,$includeEmtpyValues);
                                }
                        } else {
                                if ($notAddKeys) {
                                        if (isset($arr0[$key])) {
-                                               if ($includeEmtpyValues OR $val) {
+                                               if ($includeEmtpyValues || $val) {
                                                        $arr0[$key] = $val;
                                                }
                                        }
                                } else {
-                                       if ($includeEmtpyValues OR $val) {
+                                       if ($includeEmtpyValues || $val) {
                                                $arr0[$key] = $val;
                                        }
                                }
@@ -1696,15 +1698,35 @@ class t3lib_div {
        function csvValues($row,$delim=',',$quote='"')  {
                reset($row);
                $out=array();
-               while(list(,$value)=each($row)) {
-                       list($valPart) = explode(chr(10),$value);
-                       $valPart = trim($valPart);
-                       $out[]=str_replace($quote,$quote.$quote,$valPart);
+               foreach ($row as $value) {
+                       $out[] = str_replace($quote, $quote.$quote, $value);
                }
                $str = $quote.implode($quote.$delim.$quote,$out).$quote;
                return $str;
        }
 
+       /**
+        * Removes dots "." from end of a key identifier of TypoScript styled array.
+        * array('key.' => array('property.' => 'value')) --> array('key' => array('property' => 'value'))
+        *
+        * @param       array   $ts: TypoScript configuration array
+        * @return      array   TypoScript configuration array without dots at the end of all keys
+        */
+       function removeDotsFromTS($ts) {
+               $out = array();
+               if (is_array($ts)) {
+                       foreach ($ts as $key => $value) {
+                               if (is_array($value)) {
+                                       $key = rtrim($key, '.');
+                                       $out[$key] = t3lib_div::removeDotsFromTS($value);
+                               } else {
+                                       $out[$key] = $value;
+                               }
+                       }
+               }
+               return $out;
+       }
+
 
 
 
@@ -1944,7 +1966,7 @@ class t3lib_div {
                }
                return $tagi['ch'];
        }
-       
+
        /**
         * Turns PHP array into XML. See array2xml()
         *
@@ -1956,18 +1978,18 @@ class t3lib_div {
         * @see xml2array(),array2xml()
         */
        function array2xml_cs($array,$docTag='phparray',$options=array(),$charset='')   {
-               
+
                        // Figure out charset if not given explicitly:
                if (!$charset)  {
                        if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'])  {       // First priority: forceCharset! If set, this will be authoritative!
                                $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
                        } elseif (is_object($GLOBALS['LANG']))  {
-                               $charset = $GLOBALS['LANG']->charSet;   // If "LANG" is around, that will hold the current charset 
+                               $charset = $GLOBALS['LANG']->charSet;   // If "LANG" is around, that will hold the current charset
                        } else {
-                               $charset = 'iso-8859-1';        // THIS is just a hopeful guess! 
-                       }               
+                               $charset = 'iso-8859-1';        // THIS is just a hopeful guess!
+                       }
                }
-               
+
                        // Return XML:
                return '<?xml version="1.0" encoding="'.htmlspecialchars($charset).'" standalone="yes" ?>'.chr(10).
                                t3lib_div::array2xml($array,'',0,$docTag,0, $options);
@@ -1982,7 +2004,7 @@ class t3lib_div {
         * Numeric keys are stored with the default tagname "numIndex" but can be overridden to other formats)
         * The function handles input values from the PHP array in a binary-safe way; All characters below 32 (except 9,10,13) will trigger the content to be converted to a base64-string
         * The PHP variable type of the data IS preserved as long as the types are strings, arrays, integers and booleans. Strings are the default type unless the "type" attribute is set.
-        * The output XML has been tested with the PHP XML-parser and parses OK under all tested circumstances with 4.x versions. However, with PHP5 there seems to be the need to add an XML prologue a la <?xml version="1.0" encoding="[charset]" standalone="yes" ?> - otherwise UTF-8 is assumed! Unfortunately, many times the output from this function is used without adding that prologue meaning that non-ASCII characters will break the parsing!! This suchs of course! Effectively it means that the prologue should always be prepended setting the right characterset, alternatively the system should always run as utf-8! 
+        * The output XML has been tested with the PHP XML-parser and parses OK under all tested circumstances with 4.x versions. However, with PHP5 there seems to be the need to add an XML prologue a la <?xml version="1.0" encoding="[charset]" standalone="yes" ?> - otherwise UTF-8 is assumed! Unfortunately, many times the output from this function is used without adding that prologue meaning that non-ASCII characters will break the parsing!! This suchs of course! Effectively it means that the prologue should always be prepended setting the right characterset, alternatively the system should always run as utf-8!
         * However using MSIE to read the XML output didn't always go well: One reason could be that the character encoding is not observed in the PHP data. The other reason may be if the tag-names are invalid in the eyes of MSIE. Also using the namespace feature will make MSIE break parsing. There might be more reasons...
         * Usage: 5
         *
@@ -1990,7 +2012,7 @@ class t3lib_div {
         * @param       string          tag-prefix, eg. a namespace prefix like "T3:"
         * @param       integer         Current recursion level. Don't change, stay at zero!
         * @param       string          Alternative document tag. Default is "phparray".
-        * @param       integer         If set, the number of spaces corresponding to this number is used for indenting, otherwise a single chr(9) (TAB) is used
+        * @param       integer         If greater than zero, then the number of spaces corresponding to this number is used for indenting, if less than zero - no indentation, if zero - a single chr(9) (TAB) is used
         * @param       array           Options for the compilation. Key "useNindex" => 0/1 (boolean: whether to use "n0, n1, n2" for num. indexes); Key "useIndexTagForNum" => "[tag for numerical indexes]"; Key "useIndexTagForAssoc" => "[tag for associative indexes"; Key "parentTagMap" => array('parentTag' => 'thisLevelTag')
         * @param       string          Stack data. Don't touch.
         * @return      string          An XML string made from the input content in the array.
@@ -2005,6 +2027,7 @@ class t3lib_div {
                        // Set indenting mode:
                $indentChar = $spaceInd ? ' ' : chr(9);
                $indentN = $spaceInd>0 ? $spaceInd : 1;
+               $nl = ($spaceInd >= 0 ? chr(10) : '');
 
                        // Init output variable:
                $output='';
@@ -2055,7 +2078,7 @@ class t3lib_div {
                                                $clearStackPath = FALSE;
                                        }
 
-                                       $content = chr(10).
+                                       $content = $nl .
                                                                t3lib_div::array2xml(
                                                                        $v,
                                                                        $NSprefix,
@@ -2069,34 +2092,41 @@ class t3lib_div {
                                                                                'path' => $clearStackPath ? '' : $stackData['path'].'/'.$tagName,
                                                                        )
                                                                ).
-                                                               str_pad('',($level+1)*$indentN,$indentChar);
+                                                               ($spaceInd >= 0 ? str_pad('',($level+1)*$indentN,$indentChar) : '');
                                        if ((int)$options['disableTypeAttrib']!=2)      {       // Do not set "type = array". Makes prettier XML but means that empty arrays are not restored with xml2array
                                                $attr.=' type="array"';
                                        }
                                } else {        // Just a value:
 
                                                // Look for binary chars:
-                                       if (strcspn($v,$binaryChars) != strlen($v))     {       // Go for base64 encoding if the initial segment NOT matching any binary char has the same length as the whole string!
+                                       $vLen = strlen($v);     // check for length, because PHP 5.2.0 may crash when first argument of strcspn is empty
+                                       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!
                                                        // If the value contained binary chars then we base64-encode it an set an attribute to notify this situation:
-                                               $content = chr(10).chunk_split(base64_encode($v));
+                                               $content = $nl.chunk_split(base64_encode($v));
                                                $attr.=' base64="1"';
                                        } else {
                                                        // Otherwise, just htmlspecialchar the stuff:
                                                $content = htmlspecialchars($v);
                                                $dType = gettype($v);
-                                               if ($dType!='string' && !$options['disableTypeAttrib']) { $attr.=' type="'.$dType.'"'; }
+                                               if ($dType == 'string') {
+                                                       if ($options['useCDATA'] && $content != $v) {
+                                                               $content = '<![CDATA[' . $v . ']]>';
+                                                       }
+                                               } elseif (!$options['disableTypeAttrib']) {
+                                                       $attr.= ' type="'.$dType.'"';
+                                               }
                                        }
                                }
 
                                        // Add the element to the output string:
-                               $output.=str_pad('',($level+1)*$indentN,$indentChar).'<'.$NSprefix.$tagName.$attr.'>'.$content.'</'.$NSprefix.$tagName.'>'.chr(10);
+                               $output.=($spaceInd >= 0 ? str_pad('',($level+1)*$indentN,$indentChar) : '').'<'.$NSprefix.$tagName.$attr.'>'.$content.'</'.$NSprefix.$tagName.'>'.$nl;
                        }
                }
 
                        // If we are at the outer-most level, then we finally wrap it all in the document tags and return that as the value:
                if (!$level)    {
                        $output =
-                               '<'.$docTag.'>'.chr(10).
+                               '<'.$docTag.'>'.$nl.
                                $output.
                                '</'.$docTag.'>';
                }
@@ -2126,14 +2156,18 @@ class t3lib_div {
                xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
                xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
 
-                       // PHP5 fix of charset awareness:
-                       // Problem is: PHP5 apparently detects the charset of the XML file (or defaults to utf-8) and will AUTOMATICALLY convert the content to either utf-8, iso-8859-1 or us-ascii. PHP4 just passed the content through without taking action regarding the charset.
-                       // In TYPO3 we expect that the charset of XML content is NOT handled in the parser but internally in TYPO3 instead. Therefore it would be very nice if PHP5 could be configured to NOT process the charset of the files. But this is not possible for now.
-                       // What we do here fixes the problem but ONLY if the charset is utf-8, iso-8859-1 or us-ascii. That should work for most TYPO3 installations, in particular if people use utf-8 which we highly recommend.
-               if ((double)phpversion()>=5)    {
-                       $ereg_result = array();
-                       ereg('^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"',substr($string,0,200),$ereg_result);
-                       $theCharset = $ereg_result[1] ? $ereg_result[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1');
+                       //  PHP4 doesn't like Unicode byte order marks (BOM), so we have to check for them
+                       // The BOM check comes first, so that the PHP5 preg_match() below doesn't have to check for it
+               if(substr($string,0,3)=="\xEF\xBB\xBF") {
+                       xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'utf-8');
+               }
+                       // PHP 4.x: output charset is the same as the input charset, charsets are handled transparently if not specified in xml_parser_create()
+                       // PHP 5.0.0 & 5.0.1: default output charset is ISO-8859-1, only ASCII, ISO-8859-1 and UTF-8 are supported!!!
+                       // PHP 5.0.2+: default output charset is UTF-8  , only ASCII, ISO-8859-1 and UTF-8 are supported!!!
+               elseif ((double)phpversion()>=5)        {
+                       $match = array();
+                       preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/',substr($string,0,200),$match);
+                       $theCharset = $match[1] ? $match[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1');
                        xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset);  // us-ascii / utf-8 / iso-8859-1
                }
 
@@ -2299,63 +2333,90 @@ class t3lib_div {
         * Usage: 83
         *
         * @param       string          Filepath/URL to read
-        * @param       integer         Whether the HTTP header should be fetched or not. 0=disable, 1=fetch header+content, 2=fetch header only (will be ignored when using CURL)
+        * @param       integer         Whether the HTTP header should be fetched or not. 0=disable, 1=fetch header+content, 2=fetch header only
+        * @param       array           HTTP headers to be used in the request
         * @return      string          The content from the resource given as input.
         */
-       function getURL($url, $includeHeader=0) {
-               $content = '';
+       function getURL($url, $includeHeader = 0, $requestHeaders = false)      {
+               $content = false;
 
                        // (Proxy support implemented by Arco <arco@appeltaart.mine.nu>)
-               if ((substr($url,0,7)=='http://') && ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse']=='1'))      {
-                       // External URL without error checking.
+               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse'] == '1' && preg_match('/^https?:\/\//', $url)) {
+                               // External URL without error checking.
                        $ch = curl_init();
-                       if (!$ch)       { return false; }
+                       if (!$ch)       {
+                               return false;
+                       }
 
-                       curl_setopt ($ch,CURLOPT_URL, $url);
-                       curl_setopt ($ch,CURLOPT_HEADER, $includeHeader?1:0);
-                       curl_setopt ($ch,CURLOPT_RETURNTRANSFER, 1);
+                       curl_setopt($ch, CURLOPT_URL, $url);
+                       curl_setopt($ch, CURLOPT_HEADER, $includeHeader ? 1 : 0);
+                       curl_setopt($ch, CURLOPT_NOBODY, $includeHeader == 2 ? 1 : 0);
+                       curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
+                       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+                       curl_setopt($ch, CURLOPT_FAILONERROR, 1);
+                       if (is_array($requestHeaders))  {
+                               curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders);
+                       }
 
-                       if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']) {
-                               curl_setopt ($ch, CURLOPT_PROXY, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']);
+                       if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer'])      {
+                               curl_setopt($ch, CURLOPT_PROXY, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']);
 
-                               // I don't know if it will be needed
-                               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']) {
-                                       curl_setopt ($ch, CURLOPT_HTTPPROXYTUNNEL, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel'] );
+                                       // Not sure if this is needed
+                               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel'])      {
+                                       curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']);
                                }
-                               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']) {
-                                       curl_setopt ($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass'] );
+                               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass'])    {
+                                       curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']);
                                }
                        }
-                       $content=curl_exec ($ch);
-                       curl_close ($ch);
+                       $content = curl_exec($ch);
+                       curl_close($ch);
 
                } elseif ($includeHeader)       {
                        $parsedURL = parse_url($url);
-                       if (!t3lib_div::inList('ftp,ftps,http,https,gopher,telnet', $parsedURL['scheme']))      { return false; }
+                       if (!t3lib_div::inList('ftp,ftps,http,https,gopher,telnet', $parsedURL['scheme']))      {
+                               return false;
+                       }
 
-                       $fp = @fsockopen($parsedURL['host'], ($parsedURL['port']>0 ? $parsedURL['port'] : 80), $errno, $errstr, $timeout=2);
-                       if (!$fp)       { return false; }
+                       $fp = @fsockopen($parsedURL['host'], ($parsedURL['port'] > 0 ? $parsedURL['port'] : 80), $errno, $errstr, 2.0);
+                       if (!$fp)       {
+                               return false;
+                       }
 
-                       $msg = 'GET '.$parsedURL['path'].($parsedURL['query'] ? '?'.$parsedURL['query'] : '')." HTTP/1.0\r\nHost: ".$parsedURL['host']."\r\n\r\n";
-                       fputs ($fp, $msg);
+                       $msg = 'GET ' . $parsedURL['path'] .
+                                       ($parsedURL['query'] ? '?' . $parsedURL['query'] : '') .
+                                       ' HTTP/1.0' . "\r\n" . 'Host: ' .
+                                       $parsedURL['host'] . "\r\n\r\n";
+                       fputs($fp, $msg);
                        while (!feof($fp))      {
-                               $line = fgets ($fp,2048);
-                               $content.=$line;
-                               if ($includeHeader==2 && !strlen(trim($line)))  { break; }      // Stop at the first empty line (= end of header)
+                               $line = fgets($fp, 2048);
+                               $content.= $line;
+                               if ($includeHeader == 2 && !strlen(trim($line)))        {
+                                       break;  // Stop at the first empty line (= end of header)
+                               }
                        }
-                       fclose ($fp);
-
-               } elseif (function_exists('file_get_contents')) {
-                       $content = @file_get_contents($url);
-
-               } elseif ($fd = @fopen($url,'rb'))    {
-                       while (!feof($fd))      {
-                               $content.=fread($fd, 4096);
+                       fclose($fp);
+
+               } elseif (is_array($requestHeaders))    {
+                       $ctx = stream_context_create(array(
+                                               'http' => array(
+                                                       'header' => implode("\r\n", $requestHeaders)
+                                               )
+                                       )
+                               );
+                       if (version_compare(phpversion(), '5.0', '>=')) {
+                               $content = @file_get_contents($url, false, $ctx);
                        }
-                       fclose($fd);
-
-               } else {
-                       return false;
+                       elseif (false !== ($fd = @fopen($url, 'rb', false, $ctx)))      {
+                               $content = '';
+                               while (!feof($fd))      {
+                                       $content.= @fread($fd, 4096);
+                               }
+                               fclose($fd);
+                       }
+               }
+               else    {
+                       $content = @file_get_contents($url);
                }
 
                return $content;
@@ -2455,7 +2516,7 @@ class t3lib_div {
         * @return      boolean         TRUE if @mkdir went well!
         */
        function mkdir($theNewFolder)   {
-               $theNewFolder = ereg_replace('\/$','',$theNewFolder);
+               $theNewFolder = preg_replace('|/$|','',$theNewFolder);
                if (mkdir($theNewFolder, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']))){
                        chmod($theNewFolder, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'])); //added this line, because the mode at 'mkdir' has a strange behaviour sometimes
 
@@ -2488,6 +2549,40 @@ class t3lib_div {
        }
 
        /**
+        * Wrapper function for rmdir, allowing recursive deletion of folders and files
+        *
+        * @param       string          Absolute path to folder, see PHP rmdir() function. Removes trailing slash internally.
+        * @param       boolean         Allow deletion of non-empty directories
+        * @return      boolean         true if @rmdir went well!
+        */
+       function rmdir($path,$removeNonEmpty=false)     {
+               $OK = false;
+               $path = preg_replace('|/$|','',$path);  // Remove trailing slash
+
+               if (file_exists($path)) {
+                       $OK = true;
+
+                       if (is_dir($path))      {
+                               if ($removeNonEmpty==true && $handle = opendir($path))  {
+                                       while ($OK && false !== ($file = readdir($handle)))     {
+                                               if ($file=='.' || $file=='..') continue;
+                                               $OK = t3lib_div::rmdir($path.'/'.$file,$removeNonEmpty);
+                                       }
+                                       closedir($handle);
+                               }
+                               if ($OK)        { $OK = rmdir($path); }
+
+                       } else {        // If $dirname is a file, simply remove it
+                               $OK = unlink($path);
+                       }
+
+                       clearstatcache();
+               }
+
+               return $OK;
+       }
+
+       /**
         * Returns an array with the names of folders in a specific path
         * Will return 'error' (string) if there were an error with reading directory content.
         * Usage: 11
@@ -2518,9 +2613,10 @@ class t3lib_div {
         * @param       string          $extensionList is the comma list of extensions to read only (blank = all)
         * @param       boolean         If set, then the path is prepended the filenames. Otherwise only the filenames are returned in the array
         * @param       string          $order is sorting: 1= sort alphabetically, 'mtime' = sort by modification time.
+        * @param       string          A comma seperated list of filenames to exclude, no wildcards
         * @return      array           Array of the files found
         */
-       function getFilesInDir($path,$extensionList='',$prependPath=0,$order='')        {
+       function getFilesInDir($path,$extensionList='',$prependPath=0,$order='',$excludePattern='')     {
 
                        // Initialize variabels:
                $filearray = array();
@@ -2536,9 +2632,9 @@ class t3lib_div {
                                        if (@is_file($path.'/'.$entry)) {
                                                $fI = pathinfo($entry);
                                                $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)
-                                               if (!$extensionList || t3lib_div::inList($extensionList,strtolower($fI['extension'])))  {
+                                               if ((!strlen($extensionList) || t3lib_div::inList($extensionList,strtolower($fI['extension']))) && (!strlen($excludePattern) || !preg_match('/^'.$excludePattern.'$/',$entry))) {
                                                    $filearray[$key]=($prependPath?$path.'/':'').$entry;
-                                                       if ($order=='mtime') {$sortarray[$key]=filemtime($path.'/'.$entry);}
+                                                               if ($order=='mtime') {$sortarray[$key]=filemtime($path.'/'.$entry);}
                                                                elseif ($order) {$sortarray[$key]=$entry;}
                                                }
                                        }
@@ -2572,17 +2668,18 @@ class t3lib_div {
         * @param       string          $extList: Comma list of file extensions: Only files with extensions in this list (if applicable) will be selected.
         * @param       boolean         $regDirs: If set, directories are also included in output.
         * @param       integer         $recursivityLevels: The number of levels to dig down...
+        * @param string                $excludePattern: regex pattern of files/directories to exclude
         * @return      array           An array with the found files/directories.
         */
-       function getAllFilesAndFoldersInPath($fileArr,$path,$extList='',$regDirs=0,$recursivityLevels=99)       {
+       function getAllFilesAndFoldersInPath($fileArr,$path,$extList='',$regDirs=0,$recursivityLevels=99,$excludePattern='')    {
                if ($regDirs)   $fileArr[] = $path;
-               $fileArr = array_merge($fileArr, t3lib_div::getFilesInDir($path,$extList,1,1));
+               $fileArr = array_merge($fileArr, t3lib_div::getFilesInDir($path,$extList,1,1,$excludePattern));
 
                $dirs = t3lib_div::get_dirs($path);
                if (is_array($dirs) && $recursivityLevels>0)    {
                        foreach ($dirs as $subdirs)     {
-                               if ((string)$subdirs!=''      {
-                                       $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$path.$subdirs.'/',$extList,$regDirs,$recursivityLevels-1);
+                               if ((string)$subdirs!='' && (!strlen($excludePattern) || !preg_match('/^'.$excludePattern.'$/',$subdirs)))      {
+                                       $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$path.$subdirs.'/',$extList,$regDirs,$recursivityLevels-1,$excludePattern);
                                }
                        }
                }
@@ -2724,7 +2821,11 @@ class t3lib_div {
                        }
                        $result.= '</table>';
                } else  {
-                       $result  = false;
+                       $result  = '<table border="1" cellpadding="1" cellspacing="0" bgcolor="white">
+                               <tr>
+                                       <td><font face="Verdana,Arial" size="1" color="red">'.nl2br(htmlspecialchars((string)$array_in)).'<br /></font></td>
+                               </tr>
+                       </table>';      // Output it as a string.
                }
                return $result;
        }
@@ -2785,18 +2886,16 @@ class t3lib_div {
         * @return      string
         */
        function debug_trail()  {
-               if (function_exists('debug_backtrace')) {
-                       $trail = debug_backtrace();
-                       $trail = array_reverse($trail);
-                       array_pop($trail);
-
-                       $path = array();
-                       foreach($trail as $dat) {
-                               $path[] = $dat['class'].$dat['type'].$dat['function'];
-                       }
+               $trail = debug_backtrace();
+               $trail = array_reverse($trail);
+               array_pop($trail);
+
+               $path = array();
+               foreach($trail as $dat) {
+                       $path[] = $dat['class'].$dat['type'].$dat['function'];
+               }
 
-                       return implode(' // ',$path);
-               } else return 'N/A';
+               return implode(' // ',$path);
        }
 
        /**
@@ -2804,9 +2903,10 @@ class t3lib_div {
         *
         * @param       array           Array of arrays with similar keys
         * @param       string          Table header
+        * @param       boolean         If TRUE, will return content instead of echo'ing out.
         * @return      void            Outputs to browser.
         */
-       function debugRows($rows,$header='')    {
+       function debugRows($rows,$header='',$returnHTML=FALSE)  {
                if (is_array($rows))    {
                        reset($rows);
                        $firstEl = current($rows);
@@ -2830,7 +2930,7 @@ class t3lib_div {
                                        $tCells = array();
                                        foreach($headerColumns as $key) {
                                                $tCells[] = '
-                                                       <td><font face="Verdana,Arial" size="1">'.htmlspecialchars($singleRow[$key]).'</font></td>';
+                                                       <td><font face="Verdana,Arial" size="1">'.(is_array($singleRow[$key]) ? t3lib_div::debugRows($singleRow[$key],'',TRUE) : htmlspecialchars($singleRow[$key])).'</font></td>';
                                        }
                                        $tRows[] = '
                                                <tr>'.implode('',$tCells).'
@@ -2840,7 +2940,7 @@ class t3lib_div {
                                $table = '
                                        <table border="1" cellpadding="1" cellspacing="0" bgcolor="white">'.implode('',$tRows).'
                                        </table>';
-                               echo $table;
+                               if ($returnHTML)        return $table; else echo $table;
                        } else debug('Empty array of rows',$header);
                } else debug('No array of rows',$header);
        }
@@ -2988,15 +3088,16 @@ class t3lib_div {
                                SCRIPT_FILENAME =       Absolute filename of script             (Differs between windows/unix). On windows 'C:\\blabla\\blabl\\' will be converted to 'C:/blabla/blabl/'
 
                        Special extras:
-                               TYPO3_HOST_ONLY =               [host]                  = 192.168.1.4
-                               TYPO3_PORT              =               [port]                  = 8080 (blank if 80, taken from host value)
+                               TYPO3_HOST_ONLY =               [host] = 192.168.1.4
+                               TYPO3_PORT =                    [port] = 8080 (blank if 80, taken from host value)
                                TYPO3_REQUEST_HOST =    [scheme]://[host][:[port]]
-                               TYPO3_REQUEST_URL =             [scheme]://[host][:[port]][path]?[query]        (sheme will by default be 'http' until we can detect if it's https -
+                               TYPO3_REQUEST_URL =             [scheme]://[host][:[port]][path]?[query] (scheme will by default be "http" until we can detect something different)
                                TYPO3_REQUEST_SCRIPT =  [scheme]://[host][:[port]][path_script]
                                TYPO3_REQUEST_DIR =             [scheme]://[host][:[port]][path_dir]
                                TYPO3_SITE_URL =                [scheme]://[host][:[port]][path_dir] of the TYPO3 website frontend
                                TYPO3_SITE_SCRIPT =     [script / Speaking URL] of the TYPO3 website
-                               TYPO3_DOCUMENT_ROOT     =       Absolute path of root of documents:     TYPO3_DOCUMENT_ROOT.SCRIPT_NAME = SCRIPT_FILENAME (typically)
+                               TYPO3_DOCUMENT_ROOT =   Absolute path of root of documents: TYPO3_DOCUMENT_ROOT.SCRIPT_NAME = SCRIPT_FILENAME (typically)
+                               TYPO3_SSL =                     Returns TRUE if this session uses SSL (HTTPS)
 
                        Notice: [fragment] is apparently NEVER available to the script!
 
@@ -3012,7 +3113,7 @@ class t3lib_div {
 
                $retVal = '';
 
-               switch((string)$getEnvName)     {
+               switch ((string)$getEnvName)    {
                        case 'SCRIPT_NAME':
                                $retVal = (php_sapi_name()=='cgi'||php_sapi_name()=='cgi-fcgi')&&($_SERVER['ORIG_PATH_INFO']?$_SERVER['ORIG_PATH_INFO']:$_SERVER['PATH_INFO']) ? ($_SERVER['ORIG_PATH_INFO']?$_SERVER['ORIG_PATH_INFO']:$_SERVER['PATH_INFO']) : ($_SERVER['ORIG_SCRIPT_NAME']?$_SERVER['ORIG_SCRIPT_NAME']:$_SERVER['SCRIPT_NAME']);
                        break;
@@ -3021,7 +3122,10 @@ class t3lib_div {
                        break;
                        case 'REQUEST_URI':
                                        // Typical application of REQUEST_URI is return urls, forms submitting to itself etc. Example: returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))
-                               if (!$_SERVER['REQUEST_URI'])   {       // This is for ISS/CGI which does not have the REQUEST_URI available.
+                               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)
+                                       list($v,$n) = explode('|',$GLOBALS['TYPO3_CONF_VARS']['SYS']['requestURIvar']);
+                                       $retVal = $GLOBALS[$v][$n];
+                               } elseif (!$_SERVER['REQUEST_URI'])     {       // This is for ISS/CGI which does not have the REQUEST_URI available.
                                        $retVal = '/'.ereg_replace('^/','',t3lib_div::getIndpEnv('SCRIPT_NAME')).
                                                ($_SERVER['QUERY_STRING']?'?'.$_SERVER['QUERY_STRING']:'');
                                } else $retVal = $_SERVER['REQUEST_URI'];
@@ -3095,7 +3199,7 @@ class t3lib_div {
                                $retVal = substr(t3lib_div::getIndpEnv('TYPO3_REQUEST_URL'),strlen(t3lib_div::getIndpEnv('TYPO3_SITE_URL')));
                        break;
                        case 'TYPO3_SSL':
-                               $retVal = $_SERVER['SSL_SESSION_ID'] || !strcmp($_SERVER['HTTPS'],'on') ? TRUE : FALSE;
+                               $retVal = $_SERVER['SSL_SESSION_ID'] || !strcmp($_SERVER['HTTPS'],'on') || !strcmp($_SERVER['HTTPS'],'1') ? TRUE : FALSE;       // see http://bugs.typo3.org/view.php?id=3909
                        break;
                        case '_ARRAY':
                                $out = array();
@@ -3161,7 +3265,7 @@ class t3lib_div {
                        $bInfo['BROWSER']= 'konqu';
                } elseif (strstr($useragent,'Opera'))   {
                        $bInfo['BROWSER']= 'opera';
-               } elseif (strstr($useragent,'MSIE 4') || strstr($useragent,'MSIE 5') || strstr($useragent,'MSIE 6'))    {
+               } elseif (preg_match('/MSIE [4567]/', $useragent))      {
                        $bInfo['BROWSER']= 'msie';
                } elseif (strstr($useragent,'Mozilla/4') || strstr($useragent,'Mozilla/5'))     {
                        $bInfo['BROWSER']='net';
@@ -3171,7 +3275,8 @@ class t3lib_div {
                        switch($bInfo['BROWSER'])       {
                                case 'net':
                                        $bInfo['VERSION']= doubleval(substr($useragent,8));
-                                       if (strstr($useragent,'Netscape6/')) {$bInfo['VERSION']=doubleval(substr(strstr($useragent,'Netscape6/'),10));}
+                                       if (strstr($useragent,'Netscape6/')) {$bInfo['VERSION'] = doubleval(substr(strstr($useragent,'Netscape6/'),10));}       // Will we ever know if this was a typo or intention...?! :-(
+                                       if (strstr($useragent,'Netscape/6')) {$bInfo['VERSION'] = doubleval(substr(strstr($useragent,'Netscape/6'),10));}
                                        if (strstr($useragent,'Netscape/7')) {$bInfo['VERSION']=doubleval(substr(strstr($useragent,'Netscape/7'),9));}
                                break;
                                case 'msie':
@@ -3202,6 +3307,37 @@ class t3lib_div {
                return $bInfo;
        }
 
+       /**
+        * Get the fully-qualified domain name of the host.
+        * Usage: 2
+        *
+        * @param       boolean         Use request host (when not in CLI mode).
+        * @return      string          The fully-qualified host name.
+        */
+       function getHostname($requestHost=TRUE) {
+               $host = '';
+               if ($requestHost && (!defined('TYPO3_cliMode') || !TYPO3_cliMode))      {
+                       $host = $_SERVER['HTTP_HOST'];
+               }
+               if (!$host)     {
+                               // will fail for PHP 4.1 and 4.2
+                       $host = @php_uname('n');
+                               // 'n' is ignored in broken installations
+                       if (strpos($host, ' ')) $host = '';
+               }
+                       // we have not found a FQDN yet
+               if ($host && strpos('.',$host) === FALSE)       {
+                       $ip = gethostbyname($host);
+                               // we got an IP address
+                       if ($ip != $host)       {
+                               $fqdn = gethostbyaddr($ip);
+                               if ($ip != $fqdn)       $host = $fqdn;
+                       }
+               }
+               if (!$host)     $host = 'localhost.localdomain';
+
+               return $host;
+       }
 
 
 
@@ -3272,11 +3408,11 @@ class t3lib_div {
         * Usage: 14
         *
         * @param       string          Filepath to evaluate
-        * @return      boolean         True, if no '//', '..' or '\' is in the $theFile
+        * @return      boolean         True, if no '//', '\', '/../' is in the $theFile and $theFile doesn't begin with '../'
         * @todo        Possible improvement: Should it rawurldecode the string first to check if any of these characters is encoded ?
         */
        function validPathStr($theFile) {
-               if (!strstr($theFile,'//') && !strstr($theFile,'..') && !strstr($theFile,'\\')) return true;
+               if (!strstr($theFile,'//') && !strstr($theFile,'\\') && !preg_match('#(?:^\.\.|/\.\./)#',$theFile))     return true;
        }
 
        /**
@@ -3434,7 +3570,7 @@ class t3lib_div {
         * Used to create the cHash value
         *
         * @param       string          Query-parameters: "&xxx=yyy&zzz=uuu"
-        * @return      array           Array with key/value pairs of query-parameters WITHOUT a certain list of variable names (like id, type, no_cache etc) and WITH a variable, encryptionKey, specific for this server/installation
+        * @return      array           Array with key/value pairs of query-parameters WITHOUT a certain list of variable names (like id, type, no_cache etc.) and WITH a variable, encryptionKey, specific for this server/installation
         * @see tslib_fe::makeCacheHash(), tslib_cObj::typoLink()
         */
        function cHashParams($addQueryParams) {
@@ -3444,7 +3580,7 @@ class t3lib_div {
                $pA = array();
                foreach($params as $theP)       {
                        $pKV = explode('=', $theP);     // Splitting single param by '=' sign
-                       if (!t3lib_div::inList('id,type,no_cache,cHash,MP,ftu',$pKV[0]))        {
+                       if (!t3lib_div::inList('id,type,no_cache,cHash,MP,ftu',$pKV[0]) && !preg_match('/TSFE_ADMIN_PANEL\[.*?\]/',$pKV[0]))    {
                                $pA[rawurldecode($pKV[0])] = (string)rawurldecode($pKV[1]);
                        }
                }
@@ -3552,7 +3688,7 @@ class t3lib_div {
                                                // 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:
                                        if (!isset($xmlContent['data'][$langKey]))      {
                                                $LOCAL_LANG[$langKey] = t3lib_div::llXmlAutoFileName($fileRef, $langKey);
-                                       } else {
+                                       } else {
                                                $LOCAL_LANG[$langKey] = $xmlContent['data'][$langKey];
                                        }
 
@@ -3628,16 +3764,15 @@ class t3lib_div {
         * @return      string          Returns the filename reference for the language unless error occured (or local mode is used) in which case it will be NULL
         */
        function llXmlAutoFileName($fileRef,$language)  {
-
                        // Analyse file reference:
                $location = 'typo3conf/l10n/'.$language.'/';    // Default location of translations
-               if (t3lib_div::isFirstPartOfStr($fileRef,PATH_site.TYPO3_mainDir.'sysext/'))    {       // Is system:
-                       $validatedPrefix = PATH_site.TYPO3_mainDir.'sysext/';
+               if (t3lib_div::isFirstPartOfStr($fileRef,PATH_typo3.'sysext/')) {       // Is system:
+                       $validatedPrefix = PATH_typo3.'sysext/';
                        #$location = 'EXT:csh_'.$language.'/';  // For system extensions translations are found in "csh_*" extensions (language packs)
-               } elseif (t3lib_div::isFirstPartOfStr($fileRef,PATH_site.TYPO3_mainDir.'ext/')) {       // Is global:
-                       $validatedPrefix = PATH_site.TYPO3_mainDir.'ext/';
-               } elseif (t3lib_div::isFirstPartOfStr($fileRef,PATH_site.'typo3conf/ext/'))     {       // Is local:
-                       $validatedPrefix = PATH_site.'typo3conf/ext/';
+               } elseif (t3lib_div::isFirstPartOfStr($fileRef,PATH_typo3.'ext/'))      {       // Is global:
+                       $validatedPrefix = PATH_typo3.'ext/';
+               } elseif (t3lib_div::isFirstPartOfStr($fileRef,PATH_typo3conf.'ext/'))  {       // Is local:
+                       $validatedPrefix = PATH_typo3conf.'ext/';
                } else {
                        $validatedPrefix = '';
                }
@@ -3666,6 +3801,10 @@ class t3lib_div {
         * 1) must be configured table (the ctrl-section configured),
         * 2) columns must not be an array (which it is always if whole table loaded), and
         * 3) there is a value for dynamicConfigFile (filename in typo3conf)
+        *
+        * Note: For the frontend this loads only 'ctrl' and 'feInterface' parts.
+        * For complete TCA use $GLOBALS['TSFE']->includeTCA() instead.
+        *
         * Usage: 84
         *
         * @param       string          Table name for which to load the full TCA array part into the global $TCA
@@ -3758,11 +3897,10 @@ class t3lib_div {
 
                        // Check persistent object and if found, call directly and exit.
                if (is_array($GLOBALS['T3_VAR']['callUserFunction'][$funcName]))        {
-                       return call_user_func(
+                       return call_user_func_array(
                                                array(&$GLOBALS['T3_VAR']['callUserFunction'][$funcName]['obj'],
                                                        $GLOBALS['T3_VAR']['callUserFunction'][$funcName]['method']),
-                                               $params,
-                                               $ref
+                                               array(&$params, &$ref)
                                        );
                }
 
@@ -3770,7 +3908,7 @@ class t3lib_div {
                if (strstr($funcName,':'))      {
                        list($file,$funcRef) = t3lib_div::revExplode(':',$funcName,2);
                        $requireFile = t3lib_div::getFileAbsFileName($file);
-                       if ($requireFile) require_once($requireFile);
+                       if ($requireFile) t3lib_div::requireOnce($requireFile);
                } else {
                        $funcRef = $funcName;
                }
@@ -3819,10 +3957,9 @@ class t3lib_div {
                                                );
                                        }
                                                // Call method:
-                                       $content = call_user_func(
+                                       $content = call_user_func_array(
                                                array(&$classObj, $parts[1]),
-                                               $params,
-                                               $ref
+                                               array(&$params, &$ref)
                                        );
                                } else {
                                        if (!$silent)   debug("<strong>ERROR:</strong> No method name '".$parts[1]."' in class ".$parts[0],1);
@@ -3832,7 +3969,7 @@ class t3lib_div {
                        }
                } else {        // Function
                        if (function_exists($funcRef))  {
-                               $content = call_user_func($funcRef, $params, $ref);
+                               $content = call_user_func_array($funcRef, array(&$params, &$ref));
                        } else {
                                if (!$silent)   debug("<strong>ERROR:</strong> No function named: ".$funcRef,1);
                        }
@@ -3862,7 +3999,7 @@ class t3lib_div {
                        if (strstr($classRef,':'))      {
                                list($file,$class) = t3lib_div::revExplode(':',$classRef,2);
                                $requireFile = t3lib_div::getFileAbsFileName($file);
-                               if ($requireFile)       require_once($requireFile);
+                               if ($requireFile)       t3lib_div::requireOnce($requireFile);
                        } else {
                                $class = $classRef;
                        }
@@ -3907,9 +4044,18 @@ class t3lib_div {
         * Usage: 447
         *
         * @param       string          Class name to instantiate
-        * @return      object          The object
+        * @return      object          A reference to the object
         */
        function &makeInstance($className)      {
+
+                       // Load class file if not found:
+               if (!class_exists($className))  {
+                       if (substr($className,0,6)=='t3lib_')   {
+                               t3lib_div::requireOnce(PATH_t3lib.'class.'.strtolower($className).'.php');
+                       }
+               }
+
+                       // Return object.
                return class_exists('ux_'.$className) ? t3lib_div::makeInstance('ux_'.$className) : new $className;
        }
 
@@ -3955,7 +4101,7 @@ class t3lib_div {
                        } else {
                                $requireFile = t3lib_div::getFileAbsFileName($info['classFile']);
                                if (@is_file($requireFile)) {
-                                       require_once ($requireFile);
+                                       t3lib_div::requireOnce ($requireFile);
                                        $obj = t3lib_div::makeInstance($info['className']);
                                        if (is_object($obj)) {
                                                if(!@is_callable(array($obj,'init')))   {
@@ -3985,8 +4131,18 @@ class t3lib_div {
        }
 
        /**
+        * Require a class for TYPO3
+        * Useful to require classes from inside other classes (not global scope). A limited set of global variables are available (see function)
+        */
+       function requireOnce($requireFile)      {
+               global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
+
+               require_once ($requireFile);
+       }
+
+       /**
         * Simple substitute for the PHP function mail() which allows you to specify encoding and character set
-        * The fifth parameter, $enc, will allow you to specify 'base64' encryption for the output (set $enc=base64)
+        * The fifth parameter ($encoding) will allow you to specify 'base64' encryption for the output (set $encoding=base64)
         * Further the output has the charset set to ISO-8859-1 by default.
         * Usage: 4
         *
@@ -3995,11 +4151,11 @@ class t3lib_div {
         * @param       string          Message content, non-encoded. (see PHP function mail())
         * @param       string          Headers, separated by chr(10)
         * @param       string          Encoding type: "base64", "quoted-printable", "8bit". Default value is "quoted-printable".
-        * @param       string          Charset used in encoding-headers (only if $enc is set to a valid value which produces such a header)
+        * @param       string          Charset used in encoding-headers (only if $encoding is set to a valid value which produces such a header)
         * @param       boolean         If set, the header content will not be encoded.
-        * @return      void
+        * @return      boolean         True if mail was accepted for delivery, false otherwise
         */
-       function plainMailEncoded($email,$subject,$message,$headers='',$enc='',$charset='',$dontEncodeHeader=false)     {
+       function plainMailEncoded($email,$subject,$message,$headers='',$encoding='quoted-printable',$charset='',$dontEncodeHeader=false)        {
                if (!$charset)  {
                        $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'ISO-8859-1';
                }
@@ -4010,7 +4166,7 @@ class t3lib_div {
                        foreach (explode(chr(10),$headers) as $line)    {       // Split the header in lines and convert each line separately
                                $parts = explode(': ',$line,2); // Field tags must not be encoded
                                if (count($parts)==2)   {
-                                       $parts[1] = t3lib_div::encodeHeader($parts[1],$enc,$charset);
+                                       $parts[1] = t3lib_div::encodeHeader($parts[1],$encoding,$charset);
                                        $newHeaders[] = implode(': ',$parts);
                                } else {
                                        $newHeaders[] = $line;  // Should never happen - is such a mail header valid? Anyway, just add the unchanged line...
@@ -4019,11 +4175,11 @@ class t3lib_div {
                        $headers = implode(chr(10),$newHeaders);
                        unset($newHeaders);
 
-                       $email = t3lib_div::encodeHeader($email,$enc,$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>")
-                       $subject = t3lib_div::encodeHeader($subject,$enc,$charset);
+                       $email = t3lib_div::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>")
+                       $subject = t3lib_div::encodeHeader($subject,$encoding,$charset);
                }
 
-               switch ((string)$enc)   {
+               switch ((string)$encoding)      {
                        case 'base64':
                                $headers=trim($headers).chr(10).
                                'Mime-Version: 1.0'.chr(10).
@@ -4056,7 +4212,11 @@ class t3lib_div {
 
                $headers=trim(implode($linebreak,t3lib_div::trimExplode(chr(10),$headers,1)));  // Make sure no empty lines are there.
 
-               mail($email,$subject,$message,$headers);
+               $ret = @mail($email,$subject,$message,$headers);
+               if (!$ret)      {
+                       t3lib_div::sysLog('Mail to "'.$email.'" could not be sent (Subject: "'.$subject.'").', 'Core', 3);
+               }
+               return $ret;
        }
 
        /**
@@ -4116,7 +4276,7 @@ class t3lib_div {
         * @param       string          Charset used for encoding
         * @return      string          The encoded string
         */
-       function encodeHeader($line,$enc='',$charset='ISO-8859-1')      {
+       function encodeHeader($line,$enc='quoted-printable',$charset='ISO-8859-1')      {
                        // Avoid problems if "###" is found in $line (would conflict with the placeholder which is used below)
                if (strstr($line,'###'))        return $line;
 
@@ -4140,6 +4300,7 @@ class t3lib_div {
                                                $qpValue = str_replace(' ','_',$qpValue);       // Encoded words in the header should not contain non-encoded spaces. "_" is a shortcut for "=20". See RFC 2047 for details.
                                                $part = '=?'.$charset.'?Q?'.$qpValue.'?=';
                                        }
+                               break;
                        }
                        $line = str_replace($oldPart, $part, $line);
                }
@@ -4161,25 +4322,28 @@ class t3lib_div {
         */
        function substUrlsInPlainText($message,$urlmode='76',$index_script_url='')      {
                        // Substitute URLs with shorter links:
-               $urlSplit=explode('http://',$message);
-               reset($urlSplit);
-               while(list($c,$v)=each($urlSplit))      {
-                       if ($c) {
-                               $newParts = preg_split('/\s|[<>"{}|\\\^`()\']/', $v, 2);
-                               $newURL='http://'.$newParts[0];
-                                       switch((string)$urlmode)        {
+               foreach (array('http','https') as $protocol)    {
+                       $urlSplit = explode($protocol.'://',$message);
+                       reset($urlSplit);
+                       while (list($c,$v) = each($urlSplit))   {
+                               if ($c) {
+                                       $newParts = preg_split('/\s|[<>"{}|\\\^`()\']/', $v, 2);
+                                       $newURL = $protocol.'://'.$newParts[0];
+
+                                       switch ((string)$urlmode)       {
                                                case 'all':
-                                                       $newURL=t3lib_div::makeRedirectUrl($newURL,0,$index_script_url);
+                                                       $newURL = t3lib_div::makeRedirectUrl($newURL,0,$index_script_url);
                                                break;
                                                case '76':
-                                                       $newURL=t3lib_div::makeRedirectUrl($newURL,76,$index_script_url);
+                                                       $newURL = t3lib_div::makeRedirectUrl($newURL,76,$index_script_url);
                                                break;
                                        }
-                               $urlSplit[$c]=$newURL.substr($v,strlen($newParts[0]));
+                                       $urlSplit[$c] = $newURL . substr($v,strlen($newParts[0]));
+                               }
                        }
+                       $message = implode('',$urlSplit);
                }
 
-               $message=implode('',$urlSplit);
                return $message;
        }
 
@@ -4210,6 +4374,7 @@ class t3lib_div {
                        $inUrl=($index_script_url ? $index_script_url : t3lib_div::getIndpEnv('TYPO3_REQUEST_DIR').'index.php').
                                '?RDCT='.$md5;
                }
+
                return $inUrl;
        }
 
@@ -4237,25 +4402,18 @@ class t3lib_div {
 
                        // for CLI logging name is <fqdn-hostname>:<TYPO3-path>
                if (defined('TYPO3_cliMode') && TYPO3_cliMode)  {
-                               // find FQDN
-                       $host = php_uname('n');
-                       if (strpos($host,'.') === FALSE)        {
-                               $ip = gethostbyname($host);
-                               $fqdn = gethostbyaddr($ip);
-                               if ($ip != $fqdn)       $host = $fqdn;
-                       }
-                       $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = $TYPO3_CONF_VARS['SYS']['systemLogHost'] = $host.':'.PATH_site;
+                       $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = t3lib_div::getHostname($requestHost=FALSE).':'.PATH_site;
                }
-                       // for Web logging name is <protocol>://<request-hostame>
+                       // for Web logging name is <protocol>://<request-hostame>/<site-path>
                else {
-                       $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
+                       $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
                }
 
                        // init custom logging
                if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
                        $params = array('initLog'=>TRUE);
                        $fakeThis = FALSE;
-                       foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod)        {
+                       foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod)       {
                                t3lib_div::callUserFunction($hookMethod,$params,$fakeThis);
                        }
                }
@@ -4304,12 +4462,9 @@ class t3lib_div {
 
                        // do custom logging
                if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
-                       $params = array('msg'=>$msg, 'extKey'=>$extKey);
-                       if (function_exists('debug_backtrace')) {
-                               $params['backTrace'] = debug_backtrace();
-                       }
+                       $params = array('msg'=>$msg, 'extKey'=>$extKey, 'backTrace'=>debug_backtrace());
                        $fakeThis = FALSE;
-                       foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod)        {
+                       foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod)       {
                                t3lib_div::callUserFunction($hookMethod,$params,$fakeThis);
                        }
                }
@@ -4317,6 +4472,9 @@ class t3lib_div {
                        // TYPO3 logging enabled?
                if (!$TYPO3_CONF_VARS['SYS']['systemLog'])      return;
 
+               $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
+               $timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
+
                        // use all configured logging options
                foreach (explode(';',$TYPO3_CONF_VARS['SYS']['systemLog'],2) as $log)   {
                        list($type,$destination,$level) = explode(',',$log,4);
@@ -4331,7 +4489,7 @@ class t3lib_div {
                                $file = fopen($destination, 'a');
                                if ($file)     {
                                        flock($file, LOCK_EX);  // try locking, but ignore if not available (eg. on NFS and FAT)
-                                       fwrite($file, date('d/m/Y i:H').$msgLine.chr(10));
+                                       fwrite($file, date($dateFormat.' '.$timeFormat).$msgLine.chr(10));
                                        flock($file, LOCK_UN);    // release the lock
                                        fclose($file);
                                }
@@ -4395,12 +4553,13 @@ class t3lib_div {
         */
        function arrayToLogString($arr, $valueList=array(), $valueLength=20) {
                $str = '';
-               if(is_array($arr)) {
-                       if (!is_array($valueList)) {
-                               $valueList = explode(',', $valueList);
+               if (is_array($arr))     {
+                       if (!is_array($valueList))      {
+                               $valueList = t3lib_div::trimExplode(',', $valueList, 1);
                        }
-                       foreach($arr as $key => $value) {
-                               if (!count($valueList) OR (count($valueList) AND in_array($key, $valueList))) {
+                       $valListCnt = count($valueList);
+                       foreach ($arr as $key => $value)        {
+                               if (!$valListCnt || in_array($key, $valueList)) {
                                        $str .= (string)$key.trim(': '.t3lib_div::fixed_lgd(str_replace("\n",'|',(string)$value), $valueLength)).'; ';
                                }
                        }
@@ -4491,7 +4650,7 @@ class t3lib_div {
 
 
        /**
-        * Quotes a string for usage as JS parameter. Depends wheter the value is used in script tags (it doesn't need/must not get htmlspecialchared in this case)
+        * Quotes a string for usage as JS parameter. Depends wheter the value is used in script tags (it doesn't need/must not get htmlspecialchar'ed in this case)
         *
         * @param       string          The string to encode.
         * @param       boolean         If the values get's used in <script> tags.