Fixed bug #15383: [Unit tests] Add tests for t3lib_div::validEmail
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_div.php
index 0f9fc0a..d90994b 100644 (file)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2010 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -276,8 +276,8 @@ final class t3lib_div {
         * @return      array           Returns the GET vars merged recursively onto the POST vars.
         */
        public static function _GPmerged($parameter) {
-               $postParameter = is_array($_POST[$parameter]) ? $_POST[$parameter] : array();
-               $getParameter  = is_array($_GET[$parameter])  ? $_GET[$parameter]  : array();
+               $postParameter = (isset($_POST[$parameter]) && is_array($_POST[$parameter])) ? $_POST[$parameter] : array();
+               $getParameter  = (isset($_GET[$parameter]) && is_array($_GET[$parameter])) ? $_GET[$parameter] : array();
 
                $mergedParameters = self::array_merge_recursive_overrule($getParameter, $postParameter);
                self::stripSlashesOnArray($mergedParameters);
@@ -1070,6 +1070,36 @@ final class t3lib_div {
        }
 
        /**
+        * Returns a proper HMAC on a given input string and secret TYPO3 encryption key.
+        *
+        * @param       string          Input string to create HMAC from
+        * @return      string          resulting (hexadecimal) HMAC currently with a length of 40 (HMAC-SHA-1)
+        */
+       public static function hmac($input) {
+               $hashAlgorithm = 'sha1';
+               $hashBlocksize = 64;
+               $hmac = '';
+
+               if (extension_loaded('hash') && function_exists('hash_hmac') && function_exists('hash_algos') && in_array($hashAlgorithm, hash_algos())) {
+                       $hmac = hash_hmac($hashAlgorithm, $input, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
+               } else {
+                               // outer padding
+                       $opad = str_repeat(chr(0x5C), $hashBlocksize);
+                               // innner padding
+                       $ipad = str_repeat(chr(0x36), $hashBlocksize);
+                       if (strlen($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) > $hashBlocksize) {
+                                       // keys longer than blocksize are shorten
+                               $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])), $hashBlocksize, chr(0x00));
+                       } else {
+                                       // keys shorter than blocksize are zero-padded
+                               $key = str_pad($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], $hashBlocksize, chr(0x00));
+                       }
+                       $hmac = call_user_func($hashAlgorithm, ($key^$opad) . pack('H*', call_user_func($hashAlgorithm, ($key^$ipad) . $input)));
+               }
+               return $hmac;
+       }
+
+       /**
         * Takes comma-separated lists and arrays and removes all duplicates
         * If a value in the list is trim(empty), the value is ignored.
         * Usage: 16
@@ -1104,15 +1134,16 @@ final class t3lib_div {
         */
        public static function split_fileref($fileref)  {
                $reg = array();
-               if (preg_match('/(.*\/)(.*)$/',$fileref,$reg)   )       {
+               if (preg_match('/(.*\/)(.*)$/', $fileref, $reg)) {
                        $info['path'] = $reg[1];
                        $info['file'] = $reg[2];
                } else {
                        $info['path'] = '';
                        $info['file'] = $fileref;
                }
-               $reg='';
-               if (    preg_match('/(.*)\.([^\.]*$)/',$info['file'],$reg)      )       {
+
+               $reg = '';
+               if (!is_dir($fileref) && preg_match('/(.*)\.([^\.]*$)/', $info['file'], $reg)) {
                        $info['filebody'] = $reg[1];
                        $info['fileext'] = strtolower($reg[2]);
                        $info['realFileext'] = $reg[2];
@@ -1204,7 +1235,23 @@ final class t3lib_div {
                self::logDeprecatedFunction();
 
                $value = strtoupper($string);
-               return strtr($value, 'áéúíâêûôîæøåäöü', 'ÁÉÚÍÄËÜÖÏÆØÅÄÖÜ');
+               return strtr($value, array(
+                       chr(225) => chr(193),
+                       chr(233) => chr(201),
+                       chr(250) => chr(218),
+                       chr(237) => chr(205),
+                       chr(226) => chr(196),
+                       chr(234) => chr(203),
+                       chr(251) => chr(220),
+                       chr(244) => chr(214),
+                       chr(238) => chr(207),
+                       chr(230) => chr(198),
+                       chr(248) => chr(216),
+                       chr(229) => chr(197),
+                       chr(228) => chr(196),
+                       chr(246) => chr(214),
+                       chr(252) => chr(220),
+               ));
        }
 
        /**
@@ -1220,9 +1267,9 @@ final class t3lib_div {
        public static function convUmlauts($str)        {
                self::logDeprecatedFunction();
 
-               $pat  = array ( '/ä/',  '/Ä/',  '/ö/',  '/Ö/',  '/ü/',  '/Ü/',  '/ß/',  '/å/',  '/Å/',  '/ø/',  '/Ø/',  '/æ/',  '/Æ/'   );
-               $repl = array ( 'ae',   'Ae',   'oe',   'Oe',   'ue',   'Ue',   'ss',   'aa',   'AA',   'oe',   'OE',   'ae',   'AE'    );
-               return preg_replace($pat,$repl,$str);
+               $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));
+               $replace = array ('ae', 'Ae', 'oe', 'Oe', 'ue', 'Ue', 'ss', 'aa', 'AA', 'oe', 'OE', 'ae', 'AE');
+               return str_replace($pattern, $replace, $str);
        }
 
        /**
@@ -1552,16 +1599,38 @@ final class t3lib_div {
                if (TYPO3_OS != 'WIN' && ($fh = @fopen('/dev/urandom', 'rb'))) {
                        $output = fread($fh, $count);
                        fclose($fh);
+               } elseif (TYPO3_OS == 'WIN') {
+                       if (class_exists('COM')) {
+                               try {
+                                       $com = new COM('CAPICOM.Utilities.1');
+                                       $output = base64_decode($com->GetRandom($count, 0));
+                               } catch(Exception $e) {
+                                       // CAPICOM not installed
+                               }
+                       }
+                       if ($output === '' && version_compare(PHP_VERSION, '5.3.0', '>=')) {
+                               if (function_exists('mcrypt_create_iv')) {
+                                       $output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
+                               } elseif (function_exists('openssl_random_pseudo_bytes')) {
+                                       $isStrong = null;
+                                       $output = openssl_random_pseudo_bytes($count, $isStrong);
+                                               // skip ssl since it wasn't using the strong algo
+                                       if ($isStrong !== TRUE) {
+                                               $output = '';
+                                       }
+                               }
+                       }
                }
 
-                       // fallback if /dev/urandom is not available
+                       // fallback if other random byte generation failed until now
                if (!isset($output{$count - 1})) {
                                // We initialize with the somewhat random.
                        $randomState = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']
-                                                       . microtime() . getmypid();
+                                                       . base_convert(memory_get_usage() % pow(10, 6), 10, 2)
+                                                       . microtime() . uniqid('') . getmypid();
                        while (!isset($output{$count - 1})) {
-                               $randomState = md5(microtime() . mt_rand() . $randomState);
-                               $output .= md5(mt_rand() . $randomState, true);
+                               $randomState = sha1(microtime() . mt_rand() . $randomState);
+                               $output .= sha1(mt_rand() . $randomState, true);
                        }
                        $output = substr($output, strlen($output) - $count, $count);
                }
@@ -1569,6 +1638,16 @@ final class t3lib_div {
        }
 
        /**
+        * Returns a hex representation of a random byte string.
+        *
+        * @param               integer  Number of hex characters to return
+        * @return              string   Random Bytes
+        */
+       public static function getRandomHexString($count) {
+               return substr(bin2hex(self::generateRandomBytes(intval(($count + 1) / 2))), 0, $count);
+       }
+
+       /**
         * Returns a given string with underscores as UpperCamelCase.
         * Example: Converts blog_example to BlogExample
         *
@@ -1781,7 +1860,6 @@ final class t3lib_div {
                                unset($array[$k]);
                        }
                }
-               reset($array);
                return $array;
        }
 
@@ -2045,7 +2123,7 @@ final class t3lib_div {
                                $differenceArray[$key] = $value;
                        } elseif (is_array($value)) {
                                if (is_array($array2[$key])) {
-                                       $differenceArray[$key] = t3lib_div::arrayDiffAssocRecursive($value, $array2[$key]);
+                                       $differenceArray[$key] = self::arrayDiffAssocRecursive($value, $array2[$key]);
                                }
                        }
                }
@@ -2787,6 +2865,7 @@ final class t3lib_div {
                        curl_setopt($ch, CURLOPT_HTTPGET, $includeHeader == 2 ? 'HEAD' : 'GET');
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                        curl_setopt($ch, CURLOPT_FAILONERROR, 1);
+                       curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, max(0, intval($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlTimeout'])));
 
                                // may fail (PHP 5.2.0+ and 5.1.5+) when open_basedir or safe_mode are enabled
                        $followLocation = @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
@@ -2961,20 +3040,55 @@ final class t3lib_div {
        }
 
        /**
-        * Sets the file system mode and group ownership of file.
-        *
-        * @param string $file
-        *               the path of an existing file, must not be escaped
+        * Sets the file system mode and group ownership of a file or a folder.
         *
-        * @return void
+        * @param   string   Absolute filepath of file or folder, must not be escaped.
+        * @param   boolean  If set, also fixes permissions of files and folders in the folder (if $path is a folder)
+        * @return  mixed    TRUE on success, FALSE on error, always TRUE on Windows OS
         */
-       public static function fixPermissions($file)    {
-               if (@is_file($file) && TYPO3_OS!='WIN') {
-                       @chmod($file, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask']));             // "@" is there because file is not necessarily OWNED by the user
-                       if($GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'])    {       // skip this if createGroup is empty
-                               @chgrp($file, $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup']);                // "@" is there because file is not necessarily OWNED by the user
+       public static function fixPermissions($path, $recursive = FALSE) {
+               if (TYPO3_OS != 'WIN') {
+                       $result = FALSE;
+                       if (self::isAllowedAbsPath($path)) {
+                               if (@is_file($path)) {
+                                               // "@" is there because file is not necessarily OWNED by the user
+                                       $result = @chmod($path, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask']));
+                               } elseif (@is_dir($path)) {
+                                       $path = preg_replace('|/$|', '', $path);
+                                               // "@" is there because file is not necessarily OWNED by the user
+                                       $result = @chmod($path, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
+                               }
+
+                                       // Set createGroup if not empty
+                               if($GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup']) {
+                                               // "@" is there because file is not necessarily OWNED by the user
+                                       $changeGroupResult = @chgrp($path, $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup']);
+                                       $result = $changeGroupResult ? $result : FALSE;
+                               }
+
+                                       // Call recursive if recursive flag if set and $path is directory
+                               if ($recursive && @is_dir($path)) {
+                                       $handle = opendir($path);
+                                       while (($file = readdir($handle)) !== FALSE) {
+                                               unset($recursionResult);
+                                               if ($file !== '.' && $file !== '..') {
+                                                       if (@is_file($path . '/' . $file)) {
+                                                               $recursionResult = self::fixPermissions($path . '/' . $file);
+                                                       } elseif (@is_dir($path . '/' . $file)) {
+                                                               $recursionResult = self::fixPermissions($path . '/' . $file, TRUE);
+                                                       }
+                                                       if (isset($recursionResult) && !$recursionResult) {
+                                                               $result = FALSE;
+                                                       }
+                                               }
+                                       }
+                                       closedir($handle);
+                               }
                        }
+               } else {
+                       $result = TRUE;
                }
+               return $result;
        }
 
        /**
@@ -3022,24 +3136,20 @@ final class t3lib_div {
        }
 
        /**
-        * Wrapper function for mkdir, setting folder permissions according to $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] and group ownership according to $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup']
-        * Usage: 6
+        * Wrapper function for mkdir.
+        * Sets folder permissions according to $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']
+        * and group ownership according to $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup']
         *
         * @param       string          Absolute path to folder, see PHP mkdir() function. Removes trailing slash internally.
         * @return      boolean         TRUE if @mkdir went well!
         */
-       public static function mkdir($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
-
-                       if($GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'])    {       // skip this if createGroup is empty
-                               @chgrp($theNewFolder, $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup']);
-                       }
-                       return true;
-               } else {
-                       return false;
+       public static function mkdir($newFolder) {
+               $newFolder = preg_replace('|/$|', '', $newFolder);
+               $result = @mkdir($newFolder, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
+               if ($result) {
+                       self::fixPermissions($newFolder);
                }
+               return $result;
        }
 
        /**
@@ -3351,7 +3461,68 @@ final class t3lib_div {
        }
 
 
+       /**
+        * Function for static version numbers on files, based on the filemtime
+        *
+        * This will make the filename automatically change when a file is
+        * changed, and by that re-cached by the browser. If the file does not
+        * exist physically the original file passed to the function is
+        * returned without the timestamp.
+        *
+        * Behaviour is influenced by the setting
+        * TYPO3_CONF_VARS[TYPO3_MODE][versionNumberInFilename]
+        * = true (BE) / "embed" (FE) : modify filename
+        * = false (BE) / "querystring" (FE) : add timestamp as parameter
+        *
+        * @param string $file Relative path to file including all potential query parameters (not htmlspecialchared yet)
+        * @param boolean $forceQueryString If settings would suggest to embed in filename, this parameter allows us to force the versioning to occur in the query string. This is needed for scriptaculous.js which cannot have a different filename in order to load its modules (?load=...)
+        * @return Relative path with version filename including the timestamp
+        * @author Lars Houmark <lars@houmark.com>
+        */
+       public static function createVersionNumberedFilename($file, $forceQueryString = FALSE) {
+               $lookupFile = explode('?', $file);
+               $path = self::resolveBackPath(self::dirname(PATH_thisScript) .'/'. $lookupFile[0]);
+
+               if (TYPO3_MODE == 'FE') {
+                       $mode = strtolower($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['versionNumberInFilename']);
+                       if ($mode === 'embed') {
+                               $mode = TRUE;
+                       } else if ($mode === 'querystring') {
+                               $mode = FALSE;
+                       } else {
+                               $doNothing = TRUE;
+                       }
+               } else {
+                       $mode = $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['versionNumberInFilename'];
+               }
+
+               if (! file_exists($path) || $doNothing) {
+                               // File not found, return filename unaltered
+                       $fullName = $file;
+
+               } else if (! $mode || $forceQueryString) {
+                               // If use of .htaccess rule is not configured,
+                               // we use the default query-string method
+                       if ($lookupFile[1]) {
+                               $separator = '&';
+                       } else {
+                               $separator = '?';
+                       }
+                       $fullName = $file . $separator . filemtime($path);
+
+               } else {
+                               // Change the filename
+                       $name = explode('.', $lookupFile[0]);
+                       $extension = array_pop($name);
 
+                       array_push($name, filemtime($path), $extension);
+                       $fullName = implode('.', $name);
+                               // append potential query string
+                       $fullName .= $lookupFile[1] ? '?' . $lookupFile[1] : '';
+               }
+
+               return $fullName;
+       }
 
 
 
@@ -3397,7 +3568,7 @@ final class t3lib_div {
                        $result='
                        <table border="1" cellpadding="1" cellspacing="0" bgcolor="white">';
                        if (count($array_in) == 0)      {
-                               $result.= '<tr><td><font face="Verdana,Arial" size="1"><b>EMPTY!</b></font></td></tr>';
+                               $result.= '<tr><td><font face="Verdana,Arial" size="1"><strong>EMPTY!</strong></font></td></tr>';
                        } else  {
                                foreach ($array_in as $key => $val)     {
                                        $result.= '<tr>
@@ -3454,37 +3625,106 @@ final class t3lib_div {
         * Usage: 8
         *
         * @param       mixed           Variable to print
-        * @param       mixed           If the parameter is a string it will be used as header. Otherwise number of break tags to apply after (positive integer) or before (negative integer) the output.
+        * @param       string          The header.
+        * @param       string          Group for the debug console
         * @return      void
         */
-       public static function debug($var='',$brOrHeader=0)     {
+       public static function debug($var = '', $header = '', $group = 'Debug') {
                        // buffer the output of debug if no buffering started before
                if (ob_get_level()==0) {
                        ob_start();
                }
+               $debug = '';
 
-               if ($brOrHeader && !self::testInt($brOrHeader)) {
-                       echo '<table class="typo3-debug" border="0" cellpadding="0" cellspacing="0" bgcolor="white" style="border:0px; margin-top:3px; margin-bottom:3px;"><tr><td style="background-color:#bbbbbb; font-family: verdana,arial; font-weight: bold; font-size: 10px;">'.htmlspecialchars((string)$brOrHeader).'</td></tr><tr><td>';
-               } elseif ($brOrHeader<0)        {
-                       for($a=0;$a<abs(intval($brOrHeader));$a++){echo '<br />';}
+               if ($header) {
+                       $debug .= '
+                       <table class="typo3-debug" border="0" cellpadding="0" cellspacing="0" bgcolor="white" style="border:0px; margin-top:3px; margin-bottom:3px;">
+                               <tr>
+                                       <td style="background-color:#bbbbbb; font-family: verdana,arial; font-weight: bold; font-size: 10px;">' .
+                                               htmlspecialchars((string) $header) .
+                                       '</td>
+                               </tr>
+                               <tr>
+                                       <td>';
                }
 
                if (is_array($var))     {
-                       self::print_array($var);
-               } elseif (is_object($var))      {
-                       echo '<b>|Object:<pre>';
-                       print_r($var);
-                       echo '</pre>|</b>';
-               } elseif ((string)$var!='')     {
-                       echo '<b>|'.htmlspecialchars((string)$var).'|</b>';
+                       $debug .= self::view_array($var);
+               } elseif (is_object($var)) {
+                       $debug .=  '<strong>|Object:<pre>';
+                       $debug .= print_r($var, TRUE);
+                       $debug .=  '</pre>|</strong>';
+               } elseif ((string) $var !== '') {
+                       $debug .= '<strong>|' . htmlspecialchars((string)$var) . '|</strong>';
                } else {
-                       echo '<b>| debug |</b>';
+                       $debug .= '<strong>| debug |</strong>';
                }
 
-               if ($brOrHeader && !self::testInt($brOrHeader)) {
-                       echo '</td></tr></table>';
-               } elseif ($brOrHeader>0)        {
-                       for($a=0;$a<intval($brOrHeader);$a++){echo '<br />';}
+               if ($header) {
+                       $debug .=  '
+                                       </td>
+                               </tr>
+                       </table>';
+               }
+
+               if (TYPO3_MODE === 'BE') {
+                       $group = htmlspecialchars($group);
+
+                       if ($header !== '') {
+                               $tabHeader = htmlspecialchars($header);
+                       } else {
+                               $tabHeader = 'Debug';
+                       }
+
+                       if (is_object($var)) {
+                               $debug = str_replace(
+                                       array('"', '/', '<', "\n", "\r"),
+                                       array('\"', '\/', '\<', '<br />', ''),
+                                       $debug
+                               );
+                       } else {
+                               $debug = str_replace(
+                                       array('"', '/', '<', "\n", "\r"),
+                                       array('\"', '\/', '\<', '', ''),
+                                       $debug
+                               );
+                       }
+
+                       $script = '
+                               (function debug() {
+                                       var debugMessage = "' . $debug . '";
+                                       var header = "' . $tabHeader . '";
+                                       var group = "' . $group . '";
+
+                                       if (typeof Ext !== "object" && (top && typeof top.Ext !== "object")) {
+                                               document.write(debugMessage);
+                                               return;
+                                       }
+
+                                       if (top && typeof Ext !== "object") {
+                                               Ext = top.Ext;
+                                       }
+
+                                       Ext.onReady(function() {
+                                               var TYPO3ViewportInstance = null;
+
+                                               if (top && top.TYPO3 && typeof top.TYPO3.Backend === "object") {
+                                                       TYPO3ViewportInstance = top.TYPO3.Backend;
+                                               } else if (typeof TYPO3 === "object" && typeof TYPO3.Backend === "object") {
+                                                       TYPO3ViewportInstance = TYPO3.Backend;
+                                               }
+
+                                               if (TYPO3ViewportInstance !== null) {
+                                                       TYPO3ViewportInstance.DebugConsole.addTab(debugMessage, header, group);
+                                               } else {
+                                                       document.write(debugMessage);
+                                               }
+                                       });
+                               })();
+                       ';
+                       echo self::wrapJS($script);
+               } else {
+                       echo $debug;
                }
        }
 
@@ -4008,6 +4248,8 @@ final class t3lib_div {
         */
        public static function getHostname($requestHost=TRUE)   {
                $host = '';
+                       // If not called from the command-line, resolve on getIndpEnv()
+                       // Note that TYPO3_REQUESTTYPE is not used here as it may not yet be defined
                if ($requestHost && (!defined('TYPO3_cliMode') || !TYPO3_cliMode))      {
                        $host = self::getIndpEnv('HTTP_HOST');
                }
@@ -4856,7 +5098,7 @@ final class t3lib_div {
                        if ($errorMode == 2) {
                                throw new Exception($errorMsg);
                        } elseif(!$errorMode)   {
-                               debug($errorMsg, 1);
+                               debug($errorMsg, 't3lib_div::callUserFunction');
                        }
                        return false;
                }
@@ -4897,7 +5139,7 @@ final class t3lib_div {
                                        if ($errorMode == 2) {
                                                throw new Exception($errorMsg);
                                        } elseif(!$errorMode)   {
-                                               debug($errorMsg, 1);
+                                               debug($errorMsg, 't3lib_div::callUserFunction');
                                        }
                                }
                        } else {
@@ -4905,7 +5147,7 @@ final class t3lib_div {
                                if ($errorMode == 2) {
                                        throw new Exception($errorMsg);
                                } elseif(!$errorMode)   {
-                                       debug($errorMsg, 1);
+                                       debug($errorMsg, 't3lib_div::callUserFunction');
                                }
                        }
                } else {        // Function
@@ -4916,7 +5158,7 @@ final class t3lib_div {
                                if ($errorMode == 2) {
                                        throw new Exception($errorMsg);
                                } elseif(!$errorMode)   {
-                                       debug($errorMsg, 1);
+                                       debug($errorMsg, 't3lib_div::callUserFunction');
                                }
                        }
                }
@@ -4963,7 +5205,7 @@ final class t3lib_div {
                                !self::isFirstPartOfStr(trim($class),$checkPrefix) &&
                                !self::isFirstPartOfStr(trim($class),'tx_')
                                )       {
-                               if (!$silent)   debug("Class '".$class."' was not prepended with '".$checkPrefix."'",1);
+                               if (!$silent)   debug("Class '".$class."' was not prepended with '".$checkPrefix."'", 't3lib_div::getUserObj');
                                return FALSE;
                        }
 
@@ -4978,7 +5220,7 @@ final class t3lib_div {
 
                                return $classObj;
                        } else {
-                               if (!$silent)   debug("<strong>ERROR:</strong> No class named: ".$class,1);
+                               if (!$silent)   debug("<strong>ERROR:</strong> No class named: ".$class, 't3lib_div::getUserObj');
                        }
                }
        }
@@ -5207,12 +5449,9 @@ final class t3lib_div {
                // So we stick to LF in all cases.
                $headers = trim(implode(LF, self::trimExplode(LF, $headers, true)));    // Make sure no empty lines are there.
 
-               $ret = @mail($email, $subject, $message, $headers);
-               if (!$ret)      {
-                       self::sysLog('Mail to "'.$email.'" could not be sent (Subject: "'.$subject.'").', 'Core', 3);
+
+               return t3lib_utility_Mail::mail($email, $subject, $message, $headers);
                }
-               return $ret;
-       }
 
        /**
         * Implementation of quoted-printable encode.
@@ -5405,6 +5644,7 @@ final class t3lib_div {
                global $TYPO3_CONF_VARS;
 
                        // for CLI logging name is <fqdn-hostname>:<TYPO3-path>
+                       // Note that TYPO3_REQUESTTYPE is not used here as it may not yet be defined
                if (defined('TYPO3_cliMode') && TYPO3_cliMode)  {
                        $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = self::getHostname($requestHost=FALSE).':'.PATH_site;
                }
@@ -5427,7 +5667,6 @@ final class t3lib_div {
                        list($type,$destination) = explode(',',$log,3);
 
                        if ($type == 'syslog')  {
-                               define_syslog_variables();
                                if (TYPO3_OS == 'WIN')  {
                                        $facility = LOG_USER;
                                } else {
@@ -5466,7 +5705,8 @@ final class t3lib_div {
                }
 
                        // do custom logging
-               if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
+               if (isset($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog']) &&
+                               is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
                        $params = array('msg'=>$msg, 'extKey'=>$extKey, 'backTrace'=>debug_backtrace(), 'severity'=>$severity);
                        $fakeThis = FALSE;
                        foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod)       {
@@ -5502,7 +5742,7 @@ final class t3lib_div {
                                // send message per mail
                        elseif ($type == 'mail')        {
                                list($to,$from) = explode('/',$destination);
-                               mail($to, 'Warning - error in TYPO3 installation',
+                               t3lib_utility_Mail::mail($to, 'Warning - error in TYPO3 installation',
                                        'Host: '.$TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'].LF.
                                        'Extension: '.$extKey.LF.
                                        'Severity: '.$severity.LF.
@@ -5559,24 +5799,53 @@ final class t3lib_div {
                        return;
                }
 
-               // write a longer message to the deprecation log
-               $destination = PATH_typo3conf . '/deprecation_' . self::shortMD5(PATH_site . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) . '.log';
-               $file = @fopen($destination, 'a');
-               if ($file) {
-                       $date = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] . ' ' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] . ': ');
-                       flock($file, LOCK_EX);  // try locking, but ignore if not available (eg. on NFS and FAT)
-                       @fwrite($file, $date.$msg.LF);
-                       flock($file, LOCK_UN);    // release the lock
-                       @fclose($file);
+               $log = $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'];
+               $date = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] . ' ' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] . ': ');
+
+                       // legacy values (no strict comparison, $log can be boolean, string or int)
+               if ($log === TRUE || $log == '1') {
+                       $log = 'file';
+               }
+
+               if (stripos($log, 'file') !== FALSE) {
+                               // write a longer message to the deprecation log
+                       $destination = self::getDeprecationLogFileName();
+                       $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 . $msg . LF);
+                               flock($file, LOCK_UN);    // release the lock
+                               @fclose($file);
+                       }
+               }
+
+               if (stripos($log, 'devlog') !== FALSE) {
+                               // copy message also to the developer log
+                       self::devLog($msg, 'Core', self::SYSLOG_SEVERITY_WARNING);
                }
 
-               // copy message also to the developer log
-               self::devLog($msg, 'Core', self::SYSLOG_SEVERITY_WARNING);
+               if (stripos($log, 'console') !== FALSE) {
+                       self::debug($msg, $date, 'Deprecation Log');
+               }
+       }
+
+       /**
+        * Gets the absolute path to the deprecation log file.
+        *
+        * @return      string  absolute path to the deprecation log file
+        */
+       public static function getDeprecationLogFileName() {
+               return PATH_typo3conf .
+                       'deprecation_' .
+                       self::shortMD5(
+                               PATH_site . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']
+                       ) .
+                       '.log';
        }
 
        /**
         * Logs a call to a deprecated function.
-        * The log message will b etaken from the annotation.
+        * The log message will btaken from the annotation.
         * @return      void
         */
        public static function logDeprecatedFunction() {
@@ -5591,29 +5860,20 @@ final class t3lib_div {
                } else {
                        $function = new ReflectionFunction($trail[1]['function']);
                }
-               if (!$msg) {
-                       if (preg_match('/@deprecated\s+(.*)/', $function->getDocComment(), $match)) {
-                               $msg = $match[1];
-                       }
+
+               $msg = '';
+               if (preg_match('/@deprecated\s+(.*)/', $function->getDocComment(), $match)) {
+                       $msg = $match[1];
                }
 
-               // trigger PHP error with a short message: <function> is deprecated (called from <source>, defined in <source>)
+                       // trigger PHP error with a short message: <function> is deprecated (called from <source>, defined in <source>)
                $errorMsg = 'Function ' . $trail[1]['function'];
                if ($trail[1]['class']) {
                        $errorMsg .= ' of class ' . $trail[1]['class'];
                }
                $errorMsg .= ' is deprecated (called from '.$trail[1]['file'] . '#' . $trail[1]['line'] . ', defined in ' . $function->getFileName() . '#' . $function->getStartLine() . ')';
 
-// michael@typo3.org: Temporary disabled until error handling is implemented (follows later this week...)
-/*
-               if (defined('E_USER_DEPRECATED')) {
-                       trigger_error($errorMsg, E_USER_DEPRECATED);    // PHP 5.3
-               } else {
-                       trigger_error($errorMsg, E_USER_NOTICE);        // PHP 5.2
-               }
-*/
-
-               // write a longer message to the deprecation log: <function> <annotion> - <trace> (<source>)
+                       // write a longer message to the deprecation log: <function> <annotion> - <trace> (<source>)
                $logMsg = $trail[1]['class'] . $trail[1]['type'] . $trail[1]['function'];
                $logMsg .= '() - ' . $msg.' - ' . self::debug_trail();
                $logMsg .= ' (' . substr($function->getFileName(), strlen(PATH_site)) . '#' . $function->getStartLine() . ')';
@@ -5768,9 +6028,7 @@ final class t3lib_div {
         * @return      void
         */
        public static function cleanOutputBuffers() {
-               while (ob_get_level()) {
-                       ob_end_clean();
-               }
+               while (ob_end_clean());
                header('Content-Encoding: None', TRUE);
        }
 
@@ -5783,9 +6041,7 @@ final class t3lib_div {
        public static function flushOutputBuffers() {
                $obContent = '';
 
-               while (ob_get_level()) {
-                       $obContent .= ob_get_clean();
-               }
+               while ($obContent .= ob_get_clean());
 
                        // if previously a "Content-Encoding: whatever" has been set, we have to unset it
                if (!headers_sent()) {