/src/typo3_src-4.0.7/t3lib/class.t3lib_div.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2007 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00232 class t3lib_div {
00233 
00234 
00235 
00236 
00237 
00238         /*************************
00239          *
00240          * GET/POST Variables
00241          *
00242          * Background:
00243          * Input GET/POST variables in PHP may have their quotes escaped with "\" or not depending on configuration.
00244          * TYPO3 has always converted quotes to BE escaped if the configuration told that they would not be so.
00245          * But the clean solution is that quotes are never escaped and that is what the functions below offers.
00246          * Eventually TYPO3 should provide this in the global space as well.
00247          * In the transitional phase (or forever..?) we need to encourage EVERY to read and write GET/POST vars through the API functions below.
00248          *
00249          *************************/
00250 
00262         function _GP($var)      {
00263                 if(empty($var)) return;
00264                 $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var];
00265                 if (isset($value))      {
00266                         if (is_array($value))   { t3lib_div::stripSlashesOnArray($value); } else { $value = stripslashes($value); }
00267                 }
00268                 return $value;
00269         }
00270 
00280         function _GET($var=NULL)        {
00281                 $value = ($var === NULL) ? $_GET : (empty($var) ? NULL : $_GET[$var]);
00282                 if (isset($value))      {       // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
00283                         if (is_array($value))   { t3lib_div::stripSlashesOnArray($value); } else { $value = stripslashes($value); }
00284                 }
00285                 return $value;
00286         }
00287 
00297         function _POST($var=NULL)       {
00298                 $value = ($var === NULL) ? $_POST : (empty($var) ? NULL : $_POST[$var]);
00299                 if (isset($value))      {       // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
00300                         if (is_array($value))   { t3lib_div::stripSlashesOnArray($value); } else { $value = stripslashes($value); }
00301                 }
00302                 return $value;
00303         }
00304 
00313         function _GETset($inputGet,$key='')     {
00314                         // ADDS slashes since TYPO3 standard currently is that slashes MUST be applied (regardless of magic_quotes setting).
00315                 if (strcmp($key,''))    {
00316                         if (is_array($inputGet))        { t3lib_div::addSlashesOnArray($inputGet); } else { $inputGet = addslashes($inputGet); }
00317                         $GLOBALS['HTTP_GET_VARS'][$key] = $_GET[$key] = $inputGet;
00318                 } elseif (is_array($inputGet)){
00319                         t3lib_div::addSlashesOnArray($inputGet);
00320                         $GLOBALS['HTTP_GET_VARS'] = $_GET = $inputGet;
00321                 }
00322         }
00323 
00336         function GPvar($var,$strip=0)   {
00337                 if(empty($var)) return;
00338                 $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var];
00339                 if (isset($value) && is_string($value)) { $value = stripslashes($value); }      // Originally check '&& get_magic_quotes_gpc() ' but the values of $_GET are always slashed regardless of get_magic_quotes_gpc() because HTTP_POST/GET_VARS are run through addSlashesOnArray in the very beginning of index_ts.php eg.
00340                 if ($strip && isset($value) && is_array($value)) { t3lib_div::stripSlashesOnArray($value); }
00341                 return $value;
00342         }
00343 
00353         function GParrayMerged($var)    {
00354                 $postA = is_array($_POST[$var]) ? $_POST[$var] : array();
00355                 $getA = is_array($_GET[$var]) ? $_GET[$var] : array();
00356                 $mergedA = t3lib_div::array_merge_recursive_overrule($getA,$postA);
00357                 t3lib_div::stripSlashesOnArray($mergedA);
00358                 return $mergedA;
00359         }
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370         /*************************
00371          *
00372          * IMAGE FUNCTIONS
00373          *
00374          *************************/
00375 
00376 
00397         function gif_compress($theFile, $type)  {
00398                 $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
00399                 $returnCode='';
00400                 if ($gfxConf['gif_compress'] && strtolower(substr($theFile,-4,4))=='.gif')      {       // GIF...
00401                         if (($type=='IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw'])       {       // IM
00402                                 $cmd = t3lib_div::imageMagickCommand('convert', '"'.$theFile.'" "'.$theFile.'"', $gfxConf['im_path_lzw']);
00403                                 exec($cmd);
00404 
00405                                 $returnCode='IM';
00406                         } elseif (($type=='GD' || !$type) && $gfxConf['gdlib'] && !$gfxConf['gdlib_png'])       {       // GD
00407                                 $tempImage = imageCreateFromGif($theFile);
00408                                 imageGif($tempImage, $theFile);
00409                                 imageDestroy($tempImage);
00410                                 $returnCode='GD';
00411                         }
00412                 }
00413                 return $returnCode;
00414         }
00415 
00425         function png_to_gif_by_imagemagick($theFile)    {
00426                 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif']
00427                         && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im']
00428                         && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']
00429                         && strtolower(substr($theFile,-4,4))=='.png'
00430                         && @is_file($theFile))  {       // IM
00431                                 $newFile = substr($theFile,0,-4).'.gif';
00432                                 $cmd = t3lib_div::imageMagickCommand('convert', '"'.$theFile.'" "'.$newFile.'"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']);
00433                                 exec($cmd);
00434                                 $theFile = $newFile;
00435                                         // unlink old file?? May be bad idea bacause TYPO3 would then recreate the file every time as TYPO3 thinks the file is not generated because it's missing!! So do not unlink $theFile here!!
00436                 }
00437                 return $theFile;
00438         }
00439 
00450         function read_png_gif($theFile,$output_png=0)   {
00451                 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] && @is_file($theFile))     {
00452                         $ext = strtolower(substr($theFile,-4,4));
00453                         if (
00454                                         ((string)$ext=='.png' && $output_png)   ||
00455                                         ((string)$ext=='.gif' && !$output_png)
00456                                 )       {
00457                                 return $theFile;
00458                         } else {
00459                                 $newFile = PATH_site.'typo3temp/readPG_'.md5($theFile.'|'.filemtime($theFile)).($output_png?'.png':'.gif');
00460                                 exec($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path'].'convert "'.$theFile.'" "'.$newFile.'"');
00461                                 if (@is_file($newFile)) return $newFile;
00462                         }
00463                 }
00464         }
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480         /*************************
00481          *
00482          * STRING FUNCTIONS
00483          *
00484          *************************/
00485 
00500         function fixed_lgd($string,$origChars,$preStr='...')    {
00501                 $chars = abs($origChars);
00502                 if ($chars >= 4)        {
00503                         if(strlen($string)>$chars)  {
00504                                 return $origChars < 0 ?
00505                                         $preStr.trim(substr($string, -($chars-3))) :
00506                                         trim(substr($string, 0, $chars-3)).$preStr;
00507                         }
00508                 }
00509                 return $string;
00510         }
00511 
00526         function fixed_lgd_pre($string,$chars)  {
00527                 return strrev(t3lib_div::fixed_lgd(strrev($string),$chars));
00528         }
00529 
00540         function fixed_lgd_cs($string,$chars)   {
00541                 if (is_object($GLOBALS['LANG']))        {
00542                         return $GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet,$string,$chars,'...');
00543                 } else {
00544                         return t3lib_div::fixed_lgd($string, $chars);
00545                 }
00546         }
00547 
00558         function breakTextForEmail($str,$implChar="\n",$charWidth=76)   {
00559                 $lines = explode(chr(10),$str);
00560                 $outArr=array();
00561                 while(list(,$lStr)=each($lines))        {
00562                         $outArr[] = t3lib_div::breakLinesForEmail($lStr,$implChar,$charWidth);
00563                 }
00564                 return implode(chr(10),$outArr);
00565         }
00566 
00577         function breakLinesForEmail($str,$implChar="\n",$charWidth=76)  {
00578                 $lines=array();
00579                 $l=$charWidth;
00580                 $p=0;
00581                 while(strlen($str)>$p)  {
00582                         $substr=substr($str,$p,$l);
00583                         if (strlen($substr)==$l)        {
00584                                 $count = count(explode(' ',trim(strrev($substr))));
00585                                 if ($count>1)   {       // OK...
00586                                         $parts = explode(' ',strrev($substr),2);
00587                                         $theLine = strrev($parts[1]);
00588                                 } else {
00589                                         $afterParts = explode(' ',substr($str,$l+$p),2);
00590                                         $theLine = $substr.$afterParts[0];
00591                                 }
00592                                 if (!strlen($theLine))  {break; }       // Error, because this would keep us in an endless loop.
00593                         } else {
00594                                 $theLine=$substr;
00595                         }
00596 
00597                         $lines[]=trim($theLine);
00598                         $p+=strlen($theLine);
00599                         if (!trim(substr($str,$p,$l)))  break;  // added...
00600                 }
00601                 return implode($implChar,$lines);
00602         }
00603 
00613         function cmpIP($baseIP, $list)  {
00614                 if ($list==='*')        return TRUE;
00615                 if (strstr($baseIP, ':') && t3lib_div::validIPv6($baseIP))      {
00616                         return t3lib_div::cmpIPv6($baseIP, $list);
00617                 } else {
00618                         return t3lib_div::cmpIPv4($baseIP, $list);
00619                 }
00620         }
00621 
00629         function cmpIPv4($baseIP, $list)        {
00630                 $IPpartsReq = explode('.',$baseIP);
00631                 if (count($IPpartsReq)==4)      {
00632                         $values = t3lib_div::trimExplode(',',$list,1);
00633 
00634                         foreach($values as $test)       {
00635                                 list($test,$mask) = explode('/',$test);
00636 
00637                                 if(intval($mask)) {
00638                                                 // "192.168.3.0/24"
00639                                         $lnet = ip2long($test);
00640                                         $lip = ip2long($baseIP);
00641                                         $binnet = str_pad( decbin($lnet),32,'0','STR_PAD_LEFT');
00642                                         $firstpart = substr($binnet,0,$mask);
00643                                         $binip = str_pad( decbin($lip),32,'0','STR_PAD_LEFT');
00644                                         $firstip = substr($binip,0,$mask);
00645                                         $yes = (strcmp($firstpart,$firstip)==0);
00646                                 } else {
00647                                                 // "192.168.*.*"
00648                                         $IPparts = explode('.',$test);
00649                                         $yes = 1;
00650                                         reset($IPparts);
00651                                         while(list($index,$val)=each($IPparts)) {
00652                                                 $val = trim($val);
00653                                                 if (strcmp($val,'*') && strcmp($IPpartsReq[$index],$val))       {
00654                                                         $yes=0;
00655                                                 }
00656                                         }
00657                                 }
00658                                 if ($yes) return true;
00659                         }
00660                 }
00661                 return false;
00662         }
00663 
00671         function cmpIPv6($baseIP, $list)        {
00672                 $success = false;       // Policy default: Deny connection
00673                 $baseIP = t3lib_div::normalizeIPv6($baseIP);
00674 
00675                 $values = t3lib_div::trimExplode(',',$list,1);
00676                 foreach ($values as $test)      {
00677                         list($test,$mask) = explode('/',$test);
00678                         if (t3lib_div::validIPv6($test))        {
00679                                 $test = t3lib_div::normalizeIPv6($test);
00680                                 if (intval($mask))      {
00681                                         switch ($mask) {        // test on /48 /64
00682                                                 case '48':
00683                                                         $testBin = substr(t3lib_div::IPv6Hex2Bin($test), 0, 48);
00684                                                         $baseIPBin = substr(t3lib_div::IPv6Hex2Bin($baseIP), 0, 48);
00685                                                         $success = strcmp($testBin, $baseIPBin)==0 ? true : false;
00686                                                 break;
00687                                                 case '64':
00688                                                         $testBin = substr(t3lib_div::IPv6Hex2Bin($test), 0, 64);
00689                                                         $baseIPBin = substr(t3lib_div::IPv6Hex2Bin($baseIP), 0, 64);
00690                                                         $success = strcmp($testBin, $baseIPBin)==0 ? true : false;
00691                                                 break;
00692                                                 default:
00693                                                         $success = false;
00694                                         }
00695                                 } else {
00696                                         if (t3lib_div::validIPv6($test))        {       // test on full ip address 128 bits
00697                                                 $testBin = t3lib_div::IPv6Hex2Bin($test);
00698                                                 $baseIPBin = t3lib_div::IPv6Hex2Bin($baseIP);
00699                                                 $success = strcmp($testBin, $baseIPBin)==0 ? true : false;
00700                                         }
00701                                 }
00702                         }
00703                         if ($success) return true;
00704                 }
00705                 return false;
00706         }
00707 
00714         function IPv6Hex2Bin ($hex)     {
00715                 $bin = '';
00716                 $hex = str_replace(':', '', $hex);      // Replace colon to nothing
00717                 for ($i=0; $i<strlen($hex); $i=$i+2)    {
00718                         $bin.= chr(hexdec(substr($hex, $i, 2)));
00719                 }
00720                 return $bin;
00721         }
00722 
00729         function normalizeIPv6($address)        {
00730                 $normalizedAddress = '';
00731                 $stageOneAddress = '';
00732 
00733                 $chunks = explode('::', $address);      // Count 2 if if address has hidden zero blocks
00734                 if (count($chunks)==2)  {
00735                         $chunksLeft = explode(':', $chunks[0]);
00736                         $chunksRight = explode(':', $chunks[1]);
00737                         $left = count($chunksLeft);
00738                         $right = count($chunksRight);
00739 
00740                                 // Special case: leading zero-only blocks count to 1, should be 0
00741                         if ($left==1 && strlen($chunksLeft[0])==0)      $left=0;
00742 
00743                         $hiddenBlocks = 8 - ($left + $right);
00744                         $hiddenPart = '';
00745                         while ($h<$hiddenBlocks)        {
00746                                 $hiddenPart .= '0000:';
00747                                 $h++;
00748                         }
00749 
00750                         if ($left == 0) {
00751                                 $stageOneAddress = $hiddenPart . $chunks[1];
00752                         } else {
00753                                 $stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1];
00754                         }
00755                 } else $stageOneAddress = $address;
00756 
00757                         // normalize the blocks:
00758                 $blocks = explode(':', $stageOneAddress);
00759                 $divCounter = 0;
00760                 foreach ($blocks as $block)     {
00761                         $tmpBlock = '';
00762                         $i = 0;
00763                         $hiddenZeros = 4 - strlen($block);
00764                         while ($i < $hiddenZeros)       {
00765                                 $tmpBlock .= '0';
00766                                 $i++;
00767                         }
00768                         $normalizedAddress .= $tmpBlock . $block;
00769                         if ($divCounter < 7)    {
00770                                 $normalizedAddress .= ':';
00771                                 $divCounter++;
00772                         }
00773                 }
00774                 return $normalizedAddress;
00775         }
00776 
00785         function validIPv6($ip) {
00786                 $uppercaseIP = strtoupper($ip);
00787 
00788                 $regex = '/^(';
00789                 $regex.= '(([\dA-F]{1,4}:){7}[\dA-F]{1,4})|';
00790                 $regex.= '(([\dA-F]{1,4}){1}::([\dA-F]{1,4}:){1,5}[\dA-F]{1,4})|';
00791                 $regex.= '(([\dA-F]{1,4}:){2}:([\dA-F]{1,4}:){1,4}[\dA-F]{1,4})|';
00792                 $regex.= '(([\dA-F]{1,4}:){3}:([\dA-F]{1,4}:){1,3}[\dA-F]{1,4})|';
00793                 $regex.= '(([\dA-F]{1,4}:){4}:([\dA-F]{1,4}:){1,2}[\dA-F]{1,4})|';
00794                 $regex.= '(([\dA-F]{1,4}:){5}:([\dA-F]{1,4}:){0,1}[\dA-F]{1,4})|';
00795                 $regex.= '(::([\dA-F]{1,4}:){0,6}[\dA-F]{1,4})';
00796                 $regex.= ')$/';
00797 
00798                 return preg_match($regex, $uppercaseIP) ? true : false;
00799         }
00800 
00808         function cmpFQDN($baseIP, $list)        {
00809                 if (count(explode('.',$baseIP))==4)     {
00810                         $resolvedHostName = explode('.', gethostbyaddr($baseIP));
00811                         $values = t3lib_div::trimExplode(',',$list,1);
00812 
00813                         foreach($values as $test)       {
00814                                 $hostNameParts = explode('.',$test);
00815                                 $yes = 1;
00816 
00817                                 foreach($hostNameParts as $index => $val)       {
00818                                         $val = trim($val);
00819                                         if (strcmp($val,'*') && strcmp($resolvedHostName[$index],$val)) {
00820                                                 $yes=0;
00821                                         }
00822                                 }
00823                                 if ($yes) return true;
00824                         }
00825                 }
00826                 return false;
00827         }
00828 
00838         function inList($list,$item)    {
00839                 return strstr(','.$list.',', ','.$item.',') ? true : false;
00840         }
00841 
00850         function rmFromList($element,$list)     {
00851                 $items = explode(',',$list);
00852                 while(list($k,$v)=each($items)) {
00853                         if ($v==$element)       {unset($items[$k]);}
00854                 }
00855                 return implode(',',$items);
00856         }
00857 
00866         function expandList($list)      {
00867                 $items = explode(',',$list);
00868                 $list = array();
00869                 while(list(,$item)=each($items))        {
00870                         $range = explode('-',$item);
00871                         if (isset($range[1]))   {
00872                                 $runAwayBrake = 1000;
00873                                 for ($n=$range[0]; $n<=$range[1]; $n++) {
00874                                         $list[] = $n;
00875 
00876                                         $runAwayBrake--;
00877                                         if ($runAwayBrake<=0)   break;
00878                                 }
00879                         } else {
00880                                 $list[] = $item;
00881                         }
00882                 }
00883 
00884                 return implode(',',$list);
00885         }
00886 
00897         function intInRange($theInt,$min,$max=2000000000,$zeroValue=0)  {
00898                 // Returns $theInt as an integer in the integerspace from $min to $max
00899                 $theInt = intval($theInt);
00900                 if ($zeroValue && !$theInt)     {$theInt=$zeroValue;}   // If the input value is zero after being converted to integer, zeroValue may set another default value for it.
00901                 if ($theInt<$min){$theInt=$min;}
00902                 if ($theInt>$max){$theInt=$max;}
00903                 return $theInt;
00904         }
00905 
00913         function intval_positive($theInt)       {
00914                 $theInt = intval($theInt);
00915                 if ($theInt<0){$theInt=0;}
00916                 return $theInt;
00917         }
00918 
00926         function int_from_ver($verNumberStr)    {
00927                 $verParts = explode('.',$verNumberStr);
00928                 return intval((int)$verParts[0].str_pad((int)$verParts[1],3,'0',STR_PAD_LEFT).str_pad((int)$verParts[2],3,'0',STR_PAD_LEFT));
00929         }
00930 
00939         function compat_version($verNumberStr)  {
00940                 global $TYPO3_CONF_VARS;
00941                 $currVersionStr = $TYPO3_CONF_VARS['SYS']['compat_version'] ? $TYPO3_CONF_VARS['SYS']['compat_version'] : TYPO3_branch;
00942 
00943                 if (t3lib_div::int_from_ver($currVersionStr) < t3lib_div::int_from_ver($verNumberStr))  {
00944                         return FALSE;
00945                 } else {
00946                         return TRUE;
00947                 }
00948         }
00949 
00957         function md5int($str)   {
00958                 return hexdec(substr(md5($str),0,7));
00959         }
00960 
00970         function shortMD5($input, $len=10)      {
00971                 return substr(md5($input),0,$len);
00972         }
00973 
00983         function uniqueList($in_list, $secondParameter=NULL)    {
00984                 if (is_array($in_list)) die('t3lib_div::uniqueList() does NOT support array arguments anymore! Only string comma lists!');
00985                 if (isset($secondParameter))    die('t3lib_div::uniqueList() does NOT support more than a single argument value anymore. You have specified more than one.');
00986 
00987                 return implode(',',array_unique(t3lib_div::trimExplode(',',$in_list,1)));
00988         }
00989 
00997         function split_fileref($fileref)        {
00998                 $reg = array();
00999                 if (    ereg('(.*/)(.*)$',$fileref,$reg)        )       {
01000                         $info['path'] = $reg[1];
01001                         $info['file'] = $reg[2];
01002                 } else {
01003                         $info['path'] = '';
01004                         $info['file'] = $fileref;
01005                 }
01006                 $reg='';
01007                 if (    ereg('(.*)\.([^\.]*$)',$info['file'],$reg)      )       {
01008                         $info['filebody'] = $reg[1];
01009                         $info['fileext'] = strtolower($reg[2]);
01010                         $info['realFileext'] = $reg[2];
01011                 } else {
01012                         $info['filebody'] = $info['file'];
01013                         $info['fileext'] = '';
01014                 }
01015                 reset($info);
01016                 return $info;
01017         }
01018 
01035         function dirname($path) {
01036                 $p=t3lib_div::revExplode('/',$path,2);
01037                 return count($p)==2?$p[0]:'';
01038         }
01039 
01051         function modifyHTMLColor($color,$R,$G,$B)       {
01052                 // This takes a hex-color (# included!) and adds $R, $G and $B to the HTML-color (format: #xxxxxx) and returns the new color
01053                 $nR = t3lib_div::intInRange(hexdec(substr($color,1,2))+$R,0,255);
01054                 $nG = t3lib_div::intInRange(hexdec(substr($color,3,2))+$G,0,255);
01055                 $nB = t3lib_div::intInRange(hexdec(substr($color,5,2))+$B,0,255);
01056                 return '#'.
01057                         substr('0'.dechex($nR),-2).
01058                         substr('0'.dechex($nG),-2).
01059                         substr('0'.dechex($nB),-2);
01060         }
01061 
01071         function modifyHTMLColorAll($color,$all)        {
01072                 return t3lib_div::modifyHTMLColor($color,$all,$all,$all);
01073         }
01074 
01082         function rm_endcomma($string)   {
01083                 return ereg_replace(',$','',$string);
01084         }
01085 
01095         function danish_strtoupper($string)     {
01096                 $value = strtoupper($string);
01097                 return strtr($value, 'áéúíâêûôîæøåäöü', 'ÁÉÚÍÄËÜÖÏÆØÅÄÖÜ');
01098         }
01099 
01110         function convUmlauts($str)      {
01111                 $pat  = array ( '/ä/',  '/Ä/',  '/ö/',  '/Ö/',  '/ü/',  '/Ü/',  '/ß/',  '/å/',  '/Å/',  '/ø/',  '/Ø/',  '/æ/',  '/Æ/'   );
01112                 $repl = array ( 'ae',   'Ae',   'oe',   'Oe',   'ue',   'Ue',   'ss',   'aa',   'AA',   'oe',   'OE',   'ae',   'AE'    );
01113                 return preg_replace($pat,$repl,$str);
01114         }
01115 
01123         function testInt($var)  {
01124                 return !strcmp($var,intval($var));
01125         }
01126 
01135         function isFirstPartOfStr($str,$partStr)        {
01136                 // Returns true, if the first part of a $str equals $partStr and $partStr is not ''
01137                 $psLen = strlen($partStr);
01138                 if ($psLen)     {
01139                         return substr($str,0,$psLen)==(string)$partStr;
01140                 } else return false;
01141         }
01142 
01151         function formatSize($sizeInBytes,$labels='')    {
01152 
01153                         // Set labels:
01154                 if (strlen($labels) == 0) {
01155                     $labels = ' | K| M| G';
01156                 } else {
01157                     $labels = str_replace('"','',$labels);
01158                 }
01159                 $labelArr = explode('|',$labels);
01160 
01161                         // Find size:
01162                 if ($sizeInBytes>900)   {
01163                         if ($sizeInBytes>900000000)     {       // GB
01164                                 $val = $sizeInBytes/(1024*1024*1024);
01165                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[3];
01166                         }
01167                         elseif ($sizeInBytes>900000)    {       // MB
01168                                 $val = $sizeInBytes/(1024*1024);
01169                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[2];
01170                         } else {        // KB
01171                                 $val = $sizeInBytes/(1024);
01172                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[1];
01173                         }
01174                 } else {        // Bytes
01175                         return $sizeInBytes.$labelArr[0];
01176                 }
01177         }
01178 
01186         function convertMicrotime($microtime)   {
01187                 $parts = explode(' ',$microtime);
01188                 return round(($parts[0]+$parts[1])*1000);
01189         }
01190 
01200         function splitCalc($string,$operators)  {
01201                 $res = Array();
01202                 $sign='+';
01203                 while($string)  {
01204                         $valueLen=strcspn($string,$operators);
01205                         $value=substr($string,0,$valueLen);
01206                         $res[] = Array($sign,trim($value));
01207                         $sign=substr($string,$valueLen,1);
01208                         $string=substr($string,$valueLen+1);
01209                 }
01210                 reset($res);
01211                 return $res;
01212         }
01213 
01222         function calcPriority($string)  {
01223                 $string=ereg_replace('[[:space:]]*','',$string);        // removing all whitespace
01224                 $string='+'.$string;    // Ensuring an operator for the first entrance
01225                 $qm='\*\/\+-^%';
01226                 $regex = '(['.$qm.'])(['.$qm.']?[0-9\.]*)';
01227                         // split the expression here:
01228                 $reg = array();
01229                 preg_match_all('/'.$regex.'/',$string,$reg);
01230 
01231                 reset($reg[2]);
01232                 $number=0;
01233                 $Msign='+';
01234                 $err='';
01235                 $buffer=doubleval(current($reg[2]));
01236                 next($reg[2]);  // Advance pointer
01237                 while(list($k,$v)=each($reg[2]))        {
01238                         $v=doubleval($v);
01239                         $sign = $reg[1][$k];
01240                         if ($sign=='+' || $sign=='-')   {
01241                                 $number = $Msign=='-' ? $number-=$buffer : $number+=$buffer;
01242                                 $Msign = $sign;
01243                                 $buffer=$v;
01244                         } else {
01245                                 if ($sign=='/') {if ($v) $buffer/=$v; else $err='dividing by zero';}
01246                                 if ($sign=='%') {if ($v) $buffer%=$v; else $err='dividing by zero';}
01247                                 if ($sign=='*') {$buffer*=$v;}
01248                                 if ($sign=='^') {$buffer=pow($buffer,$v);}
01249                         }
01250                 }
01251                 $number = $Msign=='-' ? $number-=$buffer : $number+=$buffer;
01252                 return $err ? 'ERROR: '.$err : $number;
01253         }
01254 
01263         function calcParenthesis($string)       {
01264                 $securC=100;
01265                 do {
01266                         $valueLenO=strcspn($string,'(');
01267                         $valueLenC=strcspn($string,')');
01268                         if ($valueLenC==strlen($string) || $valueLenC < $valueLenO)     {
01269                                 $value = t3lib_div::calcPriority(substr($string,0,$valueLenC));
01270                                 $string = $value.substr($string,$valueLenC+1);
01271                                 return $string;
01272                         } else {
01273                                 $string = substr($string,0,$valueLenO).t3lib_div::calcParenthesis(substr($string,$valueLenO+1));
01274                         }
01275                                 // Security:
01276                         $securC--;
01277                         if ($securC<=0) break;
01278                 } while($valueLenO<strlen($string));
01279                 return $string;
01280         }
01281 
01289         function htmlspecialchars_decode($value)        {
01290                 $value = str_replace('&gt;','>',$value);
01291                 $value = str_replace('&lt;','<',$value);
01292                 $value = str_replace('&quot;','"',$value);
01293                 $value = str_replace('&amp;','&',$value);
01294                 return $value;
01295         }
01296 
01304         function deHSCentities($str)    {
01305                 return ereg_replace('&amp;([#[:alnum:]]*;)','&\1',$str);
01306         }
01307 
01317         function slashJS($string,$extended=0,$char="'") {
01318                 if ($extended)  {$string = str_replace ("\\", "\\\\", $string);}
01319                 return str_replace ($char, "\\".$char, $string);
01320         }
01321 
01330         function rawUrlEncodeJS($str)   {
01331                 return str_replace('%20',' ',rawurlencode($str));
01332         }
01333 
01342         function rawUrlEncodeFP($str)   {
01343                 return str_replace('%2F','/',rawurlencode($str));
01344         }
01345 
01353         function validEmail($email)     {
01354                 $email = trim ($email);
01355                 if (strstr($email,' '))  return FALSE;
01356                 return ereg('^[A-Za-z0-9\._-]+[@][A-Za-z0-9\._-]+[\.].[A-Za-z0-9]+$',$email) ? TRUE : FALSE;
01357         }
01358 
01368         function formatForTextarea($content)    {
01369                 return chr(10).htmlspecialchars($content);
01370         }
01371 
01372 
01373 
01374 
01375 
01376 
01377 
01378 
01379 
01380 
01381 
01382 
01383         /*************************
01384          *
01385          * ARRAY FUNCTIONS
01386          *
01387          *************************/
01388 
01399         function inArray($in_array,$item)       {
01400                 if (is_array($in_array))        {
01401                         while (list(,$val)=each($in_array))     {
01402                                 if (!is_array($val) && !strcmp($val,$item)) return true;
01403                         }
01404                 }
01405         }
01406 
01416         function intExplode($delim, $string)    {
01417                 $temp = explode($delim,$string);
01418                 while(list($key,$val)=each($temp))      {
01419                         $temp[$key]=intval($val);
01420                 }
01421                 reset($temp);
01422                 return $temp;
01423         }
01424 
01435         function revExplode($delim, $string, $count=0)  {
01436                 $temp = explode($delim,strrev($string),$count);
01437                 while(list($key,$val)=each($temp))      {
01438                         $temp[$key]=strrev($val);
01439                 }
01440                 $temp=array_reverse($temp);
01441                 reset($temp);
01442                 return $temp;
01443         }
01444 
01455         function trimExplode($delim, $string, $onlyNonEmptyValues=0)    {
01456                 $temp = explode($delim,$string);
01457                 $newtemp=array();
01458                 while(list($key,$val)=each($temp))      {
01459                         if (!$onlyNonEmptyValues || strcmp('',trim($val)))      {
01460                                 $newtemp[]=trim($val);
01461                         }
01462                 }
01463                 reset($newtemp);
01464                 return $newtemp;
01465         }
01466 
01477         function uniqueArray($valueArray)       {
01478                 return array_unique($valueArray);
01479         }
01480 
01489         function removeArrayEntryByValue($array,$cmpValue)      {
01490                 if (is_array($array))   {
01491                         reset($array);
01492                         while(list($k,$v)=each($array)) {
01493                                 if (is_array($v))       {
01494                                         $array[$k] = t3lib_div::removeArrayEntryByValue($v,$cmpValue);
01495                                 } else {
01496                                         if (!strcmp($v,$cmpValue))      {
01497                                                 unset($array[$k]);
01498                                         }
01499                                 }
01500                         }
01501                 }
01502                 reset($array);
01503                 return $array;
01504         }
01505 
01518         function implodeArrayForUrl($name,$theArray,$str='',$skipBlank=0,$rawurlencodeParamName=0)      {
01519                 if (is_array($theArray))        {
01520                         foreach($theArray as $Akey => $AVal)    {
01521                                 $thisKeyName = $name ? $name.'['.$Akey.']' : $Akey;
01522                                 if (is_array($AVal))    {
01523                                         $str = t3lib_div::implodeArrayForUrl($thisKeyName,$AVal,$str,$skipBlank,$rawurlencodeParamName);
01524                                 } else {
01525                                         if (!$skipBlank || strcmp($AVal,''))    {
01526                                                 $str.='&'.($rawurlencodeParamName ? rawurlencode($thisKeyName) : $thisKeyName).
01527                                                         '='.rawurlencode($AVal);
01528                                         }
01529                                 }
01530                         }
01531                 }
01532                 return $str;
01533         }
01534 
01543         function explodeUrl2Array($string,$multidim=FALSE)      {
01544                 $output = array();
01545                 if ($multidim)  {
01546                         parse_str($string,$output);
01547                 } else {
01548                         $p = explode('&',$string);
01549                         foreach($p as $v)       {
01550                                 if (strlen($v)) {
01551                                         list($pK,$pV) = explode('=',$v,2);
01552                                         $output[rawurldecode($pK)] = rawurldecode($pV);
01553                                 }
01554                         }
01555                 }
01556                 return $output;
01557         }
01558 
01569         function compileSelectedGetVarsFromArray($varList,$getArray,$GPvarAlt=1)        {
01570                 $keys = t3lib_div::trimExplode(',',$varList,1);
01571                 $outArr=array();
01572                 foreach($keys as $v)    {
01573                         if (isset($getArray[$v]))       {
01574                                 $outArr[$v]=$getArray[$v];
01575                         } elseif ($GPvarAlt) {
01576                                 $outArr[$v]=t3lib_div::_GP($v);
01577                         }
01578                 }
01579                 return $outArr;
01580         }
01581 
01592         function addSlashesOnArray(&$theArray)  {
01593                 if (is_array($theArray))        {
01594                         reset($theArray);
01595                         while(list($Akey,$AVal)=each($theArray))        {
01596                                 if (is_array($AVal))    {
01597                                         t3lib_div::addSlashesOnArray($theArray[$Akey]);
01598                                 } else {
01599                                         $theArray[$Akey] = addslashes($AVal);
01600                                 }
01601                         }
01602                         reset($theArray);
01603                 }
01604         }
01605 
01616         function stripSlashesOnArray(&$theArray)        {
01617                 if (is_array($theArray))        {
01618                         reset($theArray);
01619                         while(list($Akey,$AVal)=each($theArray))        {
01620                                 if (is_array($AVal))    {
01621                                         t3lib_div::stripSlashesOnArray($theArray[$Akey]);
01622                                 } else {
01623                                         $theArray[$Akey] = stripslashes($AVal);
01624                                 }
01625                         }
01626                         reset($theArray);
01627                 }
01628         }
01629 
01638         function slashArray($arr,$cmd)  {
01639                 if ($cmd=='strip')      t3lib_div::stripSlashesOnArray($arr);
01640                 if ($cmd=='add')        t3lib_div::addSlashesOnArray($arr);
01641                 return $arr;
01642         }
01643 
01655         function array_merge_recursive_overrule($arr0,$arr1,$notAddKeys=0,$includeEmtpyValues=true) {
01656                 reset($arr1);
01657                 while(list($key,$val) = each($arr1)) {
01658                         if(is_array($arr0[$key])) {
01659                                 if (is_array($arr1[$key]))      {
01660                                         $arr0[$key] = t3lib_div::array_merge_recursive_overrule($arr0[$key],$arr1[$key],$notAddKeys);
01661                                 }
01662                         } else {
01663                                 if ($notAddKeys) {
01664                                         if (isset($arr0[$key])) {
01665                                                 if ($includeEmtpyValues OR $val) {
01666                                                         $arr0[$key] = $val;
01667                                                 }
01668                                         }
01669                                 } else {
01670                                         if ($includeEmtpyValues OR $val) {
01671                                                 $arr0[$key] = $val;
01672                                         }
01673                                 }
01674                         }
01675                 }
01676                 reset($arr0);
01677                 return $arr0;
01678         }
01679 
01688         function array_merge($arr1,$arr2)       {
01689                 return $arr2+$arr1;
01690         }
01691 
01701         function csvValues($row,$delim=',',$quote='"')  {
01702                 reset($row);
01703                 $out=array();
01704                 while(list(,$value)=each($row)) {
01705                         list($valPart) = explode(chr(10),$value);
01706                         $valPart = trim($valPart);
01707                         $out[]=str_replace($quote,$quote.$quote,$valPart);
01708                 }
01709                 $str = $quote.implode($quote.$delim.$quote,$out).$quote;
01710                 return $str;
01711         }
01712 
01713 
01714 
01715 
01716 
01717 
01718 
01719 
01720 
01721 
01722 
01723 
01724 
01725 
01726 
01727 
01728         /*************************
01729          *
01730          * HTML/XML PROCESSING
01731          *
01732          *************************/
01733 
01743         function get_tag_attributes($tag)       {
01744                 $components = t3lib_div::split_tag_attributes($tag);
01745                 $name = '';      // attribute name is stored here
01746                 $valuemode = '';
01747                 if (is_array($components))      {
01748                         while (list($key,$val) = each ($components))    {
01749                                 if ($val != '=')        {       // Only if $name is set (if there is an attribute, that waits for a value), that valuemode is enabled. This ensures that the attribute is assigned it's value
01750                                         if ($valuemode) {
01751                                                 if ($name)      {
01752                                                         $attributes[$name] = $val;
01753                                                         $name = '';
01754                                                 }
01755                                         } else {
01756                                                 if ($key = strtolower(ereg_replace('[^a-zA-Z0-9]','',$val)))    {
01757                                                         $attributes[$key] = '';
01758                                                         $name = $key;
01759                                                 }
01760                                         }
01761                                         $valuemode = '';
01762                                 } else {
01763                                         $valuemode = 'on';
01764                                 }
01765                         }
01766                         if (is_array($attributes))      reset($attributes);
01767                         return $attributes;
01768                 }
01769         }
01770 
01780         function split_tag_attributes($tag)     {
01781                 $tag_tmp = trim(eregi_replace ('^<[^[:space:]]*','',trim($tag)));
01782                         // Removes any > in the end of the string
01783                 $tag_tmp = trim(eregi_replace ('>$','',$tag_tmp));
01784 
01785                 while (strcmp($tag_tmp,''))     {       // Compared with empty string instead , 030102
01786                         $firstChar=substr($tag_tmp,0,1);
01787                         if (!strcmp($firstChar,'"') || !strcmp($firstChar,"'")) {
01788                                 $reg=explode($firstChar,$tag_tmp,3);
01789                                 $value[]=$reg[1];
01790                                 $tag_tmp=trim($reg[2]);
01791                         } elseif (!strcmp($firstChar,'=')) {
01792                                 $value[] = '=';
01793                                 $tag_tmp = trim(substr($tag_tmp,1));            // Removes = chars.
01794                         } else {
01795                                         // There are '' around the value. We look for the next ' ' or '>'
01796                                 $reg = split('[[:space:]=]',$tag_tmp,2);
01797                                 $value[] = trim($reg[0]);
01798                                 $tag_tmp = trim(substr($tag_tmp,strlen($reg[0]),1).$reg[1]);
01799                         }
01800                 }
01801                 if (is_array($value))   reset($value);
01802                 return $value;
01803         }
01804 
01814         function implodeAttributes($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)   {
01815                 if (is_array($arr))     {
01816                         if ($xhtmlSafe) {
01817                                 $newArr=array();
01818                                 foreach($arr as $p => $v)       {
01819                                         if (!isset($newArr[strtolower($p)])) $newArr[strtolower($p)] = htmlspecialchars($v);
01820                                 }
01821                                 $arr = $newArr;
01822                         }
01823                         $list = array();
01824                         foreach($arr as $p => $v)       {
01825                                 if (strcmp($v,'') || $dontOmitBlankAttribs)     {$list[]=$p.'="'.$v.'"';}
01826                         }
01827                         return implode(' ',$list);
01828                 }
01829         }
01830 
01841         function implodeParams($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)       {
01842                 return t3lib_div::implodeAttributes($arr,$xhtmlSafe,$dontOmitBlankAttribs);
01843         }
01844 
01856         function wrapJS($string, $linebreak=TRUE) {
01857                 if(trim($string)) {
01858                                 // <script wrapped in nl?
01859                         $cr = $linebreak? "\n" : '';
01860 
01861                                 // remove nl from the beginning
01862                         $string = preg_replace ('/^\n+/', '', $string);
01863                                 // re-ident to one tab using the first line as reference
01864                         $match = array();
01865                         if(preg_match('/^(\t+)/',$string,$match)) {
01866                                 $string = str_replace($match[1],"\t", $string);
01867                         }
01868                         $string = $cr.'<script type="text/javascript">
01869 /*<![CDATA[*/
01870 '.$string.'
01871 /*]]>*/
01872 </script>'.$cr;
01873                 }
01874                 return trim($string);
01875         }
01876 
01877 
01887         function xml2tree($string,$depth=999) {
01888                 $parser = xml_parser_create();
01889                 $vals = array();
01890                 $index = array();
01891 
01892                 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
01893                 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
01894                 xml_parse_into_struct($parser, $string, $vals, $index);
01895 
01896                 if (xml_get_error_code($parser))        return 'Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
01897                 xml_parser_free($parser);
01898 
01899                 $stack = array( array() );
01900                 $stacktop = 0;
01901                 $startPoint=0;
01902 
01903 // FIXME don't use unset() - what does that mean? Use NULL or similar.
01904                 unset($tagi);
01905                 foreach($vals as $key => $val) {
01906                         $type = $val['type'];
01907 
01908                                 // open tag:
01909                         if ($type=='open' || $type=='complete') {
01910                                 $stack[$stacktop++] = $tagi;
01911 
01912                                 if ($depth==$stacktop)  {
01913                                         $startPoint=$key;
01914                                 }
01915 
01916                                 $tagi = array('tag' => $val['tag']);
01917 
01918                                 if(isset($val['attributes']))  $tagi['attrs'] = $val['attributes'];
01919                                 if(isset($val['value']))        $tagi['values'][] = $val['value'];
01920                         }
01921                                 // finish tag:
01922                         if ($type=='complete' || $type=='close')        {
01923                                 $oldtagi = $tagi;
01924                                 $tagi = $stack[--$stacktop];
01925                                 $oldtag = $oldtagi['tag'];
01926                                 unset($oldtagi['tag']);
01927 
01928                                 if ($depth==($stacktop+1))      {
01929                                         if ($key-$startPoint > 0)       {
01930                                                 $partArray = array_slice(
01931                                                         $vals,
01932                                                         $startPoint+1,
01933                                                         $key-$startPoint-1
01934                                                 );
01935                                                 #$oldtagi=array('XMLvalue'=>t3lib_div::xmlRecompileFromStructValArray($partArray));
01936                                                 $oldtagi['XMLvalue']=t3lib_div::xmlRecompileFromStructValArray($partArray);
01937                                         } else {
01938                                                 $oldtagi['XMLvalue']=$oldtagi['values'][0];
01939                                         }
01940                                 }
01941 
01942                                 $tagi['ch'][$oldtag][] = $oldtagi;
01943                                 unset($oldtagi);
01944                         }
01945                                 // cdata
01946                         if($type=='cdata') {
01947                                 $tagi['values'][] = $val['value'];
01948                         }
01949                 }
01950                 return $tagi['ch'];
01951         }
01952 
01963         function array2xml_cs($array,$docTag='phparray',$options=array(),$charset='')   {
01964 
01965                         // Figure out charset if not given explicitly:
01966                 if (!$charset)  {
01967                         if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'])  {       // First priority: forceCharset! If set, this will be authoritative!
01968                                 $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
01969                         } elseif (is_object($GLOBALS['LANG']))  {
01970                                 $charset = $GLOBALS['LANG']->charSet;   // If "LANG" is around, that will hold the current charset
01971                         } else {
01972                                 $charset = 'iso-8859-1';        // THIS is just a hopeful guess!
01973                         }
01974                 }
01975 
01976                         // Return XML:
01977                 return '<?xml version="1.0" encoding="'.htmlspecialchars($charset).'" standalone="yes" ?>'.chr(10).
01978                                 t3lib_div::array2xml($array,'',0,$docTag,0, $options);
01979         }
01980 
02004         function array2xml($array,$NSprefix='',$level=0,$docTag='phparray',$spaceInd=0, $options=array(),$stackData=array())    {
02005                         // The list of byte values which will trigger binary-safe storage. If any value has one of these char values in it, it will be encoded in base64
02006                 $binaryChars = chr(0).chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8).
02007                                                 chr(11).chr(12).chr(14).chr(15).chr(16).chr(17).chr(18).chr(19).
02008                                                 chr(20).chr(21).chr(22).chr(23).chr(24).chr(25).chr(26).chr(27).chr(28).chr(29).
02009                                                 chr(30).chr(31);
02010                         // Set indenting mode:
02011                 $indentChar = $spaceInd ? ' ' : chr(9);
02012                 $indentN = $spaceInd>0 ? $spaceInd : 1;
02013 
02014                         // Init output variable:
02015                 $output='';
02016 
02017                         // Traverse the input array
02018                 if (is_array($array))   {
02019                         foreach($array as $k=>$v)       {
02020                                 $attr = '';
02021                                 $tagName = $k;
02022 
02023                                         // Construct the tag name.
02024                                 if(isset($options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']])) {            // Use tag based on grand-parent + parent tag name
02025                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02026                                         $tagName = (string)$options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']];
02027                                 }elseif(isset($options['parentTagMap'][$stackData['parentTagName'].':_IS_NUM']) && t3lib_div::testInt($tagName)) {              // Use tag based on parent tag name + if current tag is numeric
02028                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02029                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName'].':_IS_NUM'];
02030                                 }elseif(isset($options['parentTagMap'][$stackData['parentTagName'].':'.$tagName])) {            // Use tag based on parent tag name + current tag
02031                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02032                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName'].':'.$tagName];
02033                                 } elseif(isset($options['parentTagMap'][$stackData['parentTagName']])) {                // Use tag based on parent tag name:
02034                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02035                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName']];
02036                                 } elseif (!strcmp(intval($tagName),$tagName))   {       // If integer...;
02037                                         if ($options['useNindex']) {    // If numeric key, prefix "n"
02038                                                 $tagName = 'n'.$tagName;
02039                                         } else {        // Use special tag for num. keys:
02040                                                 $attr.=' index="'.$tagName.'"';
02041                                                 $tagName = $options['useIndexTagForNum'] ? $options['useIndexTagForNum'] : 'numIndex';
02042                                         }
02043                                 } elseif($options['useIndexTagForAssoc']) {             // Use tag for all associative keys:
02044                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02045                                         $tagName = $options['useIndexTagForAssoc'];
02046                                 }
02047 
02048                                         // The tag name is cleaned up so only alphanumeric chars (plus - and _) are in there and not longer than 100 chars either.
02049                                 $tagName = substr(ereg_replace('[^[:alnum:]_-]','',$tagName),0,100);
02050 
02051                                         // If the value is an array then we will call this function recursively:
02052                                 if (is_array($v))       {
02053 
02054                                                 // Sub elements:
02055                                         if ($options['alt_options'][$stackData['path'].'/'.$tagName])   {
02056                                                 $subOptions = $options['alt_options'][$stackData['path'].'/'.$tagName];
02057                                                 $clearStackPath = $subOptions['clearStackPath'];
02058                                         } else {
02059                                                 $subOptions = $options;
02060                                                 $clearStackPath = FALSE;
02061                                         }
02062 
02063                                         $content = chr(10).
02064                                                                 t3lib_div::array2xml(
02065                                                                         $v,
02066                                                                         $NSprefix,
02067                                                                         $level+1,
02068                                                                         '',
02069                                                                         $spaceInd,
02070                                                                         $subOptions,
02071                                                                         array(
02072                                                                                 'parentTagName' => $tagName,
02073                                                                                 'grandParentTagName' => $stackData['parentTagName'],
02074                                                                                 'path' => $clearStackPath ? '' : $stackData['path'].'/'.$tagName,
02075                                                                         )
02076                                                                 ).
02077                                                                 str_pad('',($level+1)*$indentN,$indentChar);
02078                                         if ((int)$options['disableTypeAttrib']!=2)      {       // Do not set "type = array". Makes prettier XML but means that empty arrays are not restored with xml2array
02079                                                 $attr.=' type="array"';
02080                                         }
02081                                 } else {        // Just a value:
02082 
02083                                                 // Look for binary chars:
02084                                         $vLen = strlen($v);     // check for length, because PHP 5.2.0 may crash when first argument of strcspn is empty
02085                                         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!
02086                                                         // If the value contained binary chars then we base64-encode it an set an attribute to notify this situation:
02087                                                 $content = chr(10).chunk_split(base64_encode($v));
02088                                                 $attr.=' base64="1"';
02089                                         } else {
02090                                                         // Otherwise, just htmlspecialchar the stuff:
02091                                                 $content = htmlspecialchars($v);
02092                                                 $dType = gettype($v);
02093