Documentation TYPO3 par Ameos

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 
00499         function fixed_lgd($string,$origChars,$preStr='...')    {
00500                 $chars = abs($origChars);
00501                 if ($chars >= 4)        {
00502                         if(strlen($string)>$chars)  {
00503                                 return $origChars < 0 ?
00504                                         $preStr.trim(substr($string, -($chars-3))) :
00505                                         trim(substr($string, 0, $chars-3)).$preStr;
00506                         }
00507                 }
00508                 return $string;
00509         }
00510 
00524         function fixed_lgd_pre($string,$chars)  {
00525                 return strrev(t3lib_div::fixed_lgd(strrev($string),$chars));
00526         }
00527 
00538         function fixed_lgd_cs($string,$chars)   {
00539                 if (is_object($GLOBALS['LANG']))        {
00540                         return $GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet,$string,$chars,'...');
00541                 } else {
00542                         return t3lib_div::fixed_lgd($string, $chars);
00543                 }
00544         }
00545 
00556         function breakTextForEmail($str,$implChar="\n",$charWidth=76)   {
00557                 $lines = explode(chr(10),$str);
00558                 $outArr=array();
00559                 while(list(,$lStr)=each($lines))        {
00560                         $outArr[] = t3lib_div::breakLinesForEmail($lStr,$implChar,$charWidth);
00561                 }
00562                 return implode(chr(10),$outArr);
00563         }
00564 
00575         function breakLinesForEmail($str,$implChar="\n",$charWidth=76)  {
00576                 $lines=array();
00577                 $l=$charWidth;
00578                 $p=0;
00579                 while(strlen($str)>$p)  {
00580                         $substr=substr($str,$p,$l);
00581                         if (strlen($substr)==$l)        {
00582                                 $count = count(explode(' ',trim(strrev($substr))));
00583                                 if ($count>1)   {       // OK...
00584                                         $parts = explode(' ',strrev($substr),2);
00585                                         $theLine = strrev($parts[1]);
00586                                 } else {
00587                                         $afterParts = explode(' ',substr($str,$l+$p),2);
00588                                         $theLine = $substr.$afterParts[0];
00589                                 }
00590                                 if (!strlen($theLine))  {break; }       // Error, because this would keep us in an endless loop.
00591                         } else {
00592                                 $theLine=$substr;
00593                         }
00594 
00595                         $lines[]=trim($theLine);
00596                         $p+=strlen($theLine);
00597                         if (!trim(substr($str,$p,$l)))  break;  // added...
00598                 }
00599                 return implode($implChar,$lines);
00600         }
00601 
00611         function cmpIP($baseIP, $list)  {
00612                 if ($list==='*')        return TRUE;
00613                 if (strstr($baseIP, ':') && t3lib_div::validIPv6($baseIP))      {
00614                         return t3lib_div::cmpIPv6($baseIP, $list);
00615                 } else {
00616                         return t3lib_div::cmpIPv4($baseIP, $list);
00617                 }
00618         }
00619 
00627         function cmpIPv4($baseIP, $list)        {
00628                 $IPpartsReq = explode('.',$baseIP);
00629                 if (count($IPpartsReq)==4)      {
00630                         $values = t3lib_div::trimExplode(',',$list,1);
00631 
00632                         foreach($values as $test)       {
00633                                 list($test,$mask) = explode('/',$test);
00634 
00635                                 if(intval($mask)) {
00636                                                 // "192.168.3.0/24"
00637                                         $lnet = ip2long($test);
00638                                         $lip = ip2long($baseIP);
00639                                         $binnet = str_pad( decbin($lnet),32,'0','STR_PAD_LEFT');
00640                                         $firstpart = substr($binnet,0,$mask);
00641                                         $binip = str_pad( decbin($lip),32,'0','STR_PAD_LEFT');
00642                                         $firstip = substr($binip,0,$mask);
00643                                         $yes = (strcmp($firstpart,$firstip)==0);
00644                                 } else {
00645                                                 // "192.168.*.*"
00646                                         $IPparts = explode('.',$test);
00647                                         $yes = 1;
00648                                         reset($IPparts);
00649                                         while(list($index,$val)=each($IPparts)) {
00650                                                 $val = trim($val);
00651                                                 if (strcmp($val,'*') && strcmp($IPpartsReq[$index],$val))       {
00652                                                         $yes=0;
00653                                                 }
00654                                         }
00655                                 }
00656                                 if ($yes) return true;
00657                         }
00658                 }
00659                 return false;
00660         }
00661 
00669         function cmpIPv6($baseIP, $list)        {
00670                 $success = false;       // Policy default: Deny connection
00671                 $baseIP = t3lib_div::normalizeIPv6($baseIP);
00672 
00673                 $values = t3lib_div::trimExplode(',',$list,1);
00674                 foreach ($values as $test)      {
00675                         list($test,$mask) = explode('/',$test);
00676                         if (t3lib_div::validIPv6($test))        {
00677                                 $test = t3lib_div::normalizeIPv6($test);
00678                                 if (intval($mask))      {
00679                                         switch ($mask) {        // test on /48 /64
00680                                                 case '48':
00681                                                         $testBin = substr(t3lib_div::IPv6Hex2Bin($test), 0, 48);
00682                                                         $baseIPBin = substr(t3lib_div::IPv6Hex2Bin($baseIP), 0, 48);
00683                                                         $success = strcmp($testBin, $baseIPBin)==0 ? true : false;
00684                                                 break;
00685                                                 case '64':
00686                                                         $testBin = substr(t3lib_div::IPv6Hex2Bin($test), 0, 64);
00687                                                         $baseIPBin = substr(t3lib_div::IPv6Hex2Bin($baseIP), 0, 64);
00688                                                         $success = strcmp($testBin, $baseIPBin)==0 ? true : false;
00689                                                 break;
00690                                                 default:
00691                                                         $success = false;
00692                                         }
00693                                 } else {
00694                                         if (t3lib_div::validIPv6($test))        {       // test on full ip address 128 bits
00695                                                 $testBin = t3lib_div::IPv6Hex2Bin($test);
00696                                                 $baseIPBin = t3lib_div::IPv6Hex2Bin($baseIP);
00697                                                 $success = strcmp($testBin, $baseIPBin)==0 ? true : false;
00698                                         }
00699                                 }
00700                         }
00701                         if ($success) return true;
00702                 }
00703                 return false;
00704         }
00705 
00712         function IPv6Hex2Bin ($hex)     {
00713                 $bin = '';
00714                 $hex = str_replace(':', '', $hex);      // Replace colon to nothing
00715                 for ($i=0; $i<strlen($hex); $i=$i+2)    {
00716                         $bin.= chr(hexdec(substr($hex, $i, 2)));
00717                 }
00718                 return $bin;
00719         }
00720 
00727         function normalizeIPv6($address)        {
00728                 $normalizedAddress = '';
00729                 $stageOneAddress = '';
00730 
00731                 $chunks = explode('::', $address);      // Count 2 if if address has hidden zero blocks
00732                 if (count($chunks)==2)  {
00733                         $chunksLeft = explode(':', $chunks[0]);
00734                         $chunksRight = explode(':', $chunks[1]);
00735                         $left = count($chunksLeft);
00736                         $right = count($chunksRight);
00737 
00738                                 // Special case: leading zero-only blocks count to 1, should be 0
00739                         if ($left==1 && strlen($chunksLeft[0])==0)      $left=0;
00740 
00741                         $hiddenBlocks = 8 - ($left + $right);
00742                         $hiddenPart = '';
00743                         while ($h<$hiddenBlocks)        {
00744                                 $hiddenPart .= '0000:';
00745                                 $h++;
00746                         }
00747 
00748                         if ($left == 0) {
00749                                 $stageOneAddress = $hiddenPart . $chunks[1];
00750                         } else {
00751                                 $stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1];
00752                         }
00753                 } else $stageOneAddress = $address;
00754 
00755                         // normalize the blocks:
00756                 $blocks = explode(':', $stageOneAddress);
00757                 $divCounter = 0;
00758                 foreach ($blocks as $block)     {
00759                         $tmpBlock = '';
00760                         $i = 0;
00761                         $hiddenZeros = 4 - strlen($block);
00762                         while ($i < $hiddenZeros)       {
00763                                 $tmpBlock .= '0';
00764                                 $i++;
00765                         }
00766                         $normalizedAddress .= $tmpBlock . $block;
00767                         if ($divCounter < 7)    {
00768                                 $normalizedAddress .= ':';
00769                                 $divCounter++;
00770                         }
00771                 }
00772                 return $normalizedAddress;
00773         }
00774 
00783         function validIPv6($ip) {
00784                 $uppercaseIP = strtoupper($ip);
00785 
00786                 $regex = '/^(';
00787                 $regex.= '(([\dA-F]{1,4}:){7}[\dA-F]{1,4})|';
00788                 $regex.= '(([\dA-F]{1,4}){1}::([\dA-F]{1,4}:){1,5}[\dA-F]{1,4})|';
00789                 $regex.= '(([\dA-F]{1,4}:){2}:([\dA-F]{1,4}:){1,4}[\dA-F]{1,4})|';
00790                 $regex.= '(([\dA-F]{1,4}:){3}:([\dA-F]{1,4}:){1,3}[\dA-F]{1,4})|';
00791                 $regex.= '(([\dA-F]{1,4}:){4}:([\dA-F]{1,4}:){1,2}[\dA-F]{1,4})|';
00792                 $regex.= '(([\dA-F]{1,4}:){5}:([\dA-F]{1,4}:){0,1}[\dA-F]{1,4})|';
00793                 $regex.= '(::([\dA-F]{1,4}:){0,6}[\dA-F]{1,4})';
00794                 $regex.= ')$/';
00795 
00796                 return preg_match($regex, $uppercaseIP) ? true : false;
00797         }
00798 
00806         function cmpFQDN($baseIP, $list)        {
00807                 if (count(explode('.',$baseIP))==4)     {
00808                         $resolvedHostName = explode('.', gethostbyaddr($baseIP));
00809                         $values = t3lib_div::trimExplode(',',$list,1);
00810 
00811                         foreach($values as $test)       {
00812                                 $hostNameParts = explode('.',$test);
00813                                 $yes = 1;
00814 
00815                                 foreach($hostNameParts as $index => $val)       {
00816                                         $val = trim($val);
00817                                         if (strcmp($val,'*') && strcmp($resolvedHostName[$index],$val)) {
00818                                                 $yes=0;
00819                                         }
00820                                 }
00821                                 if ($yes) return true;
00822                         }
00823                 }
00824                 return false;
00825         }
00826 
00836         function inList($list,$item)    {
00837                 return strstr(','.$list.',', ','.$item.',') ? true : false;
00838         }
00839 
00848         function rmFromList($element,$list)     {
00849                 $items = explode(',',$list);
00850                 while(list($k,$v)=each($items)) {
00851                         if ($v==$element)       {unset($items[$k]);}
00852                 }
00853                 return implode(',',$items);
00854         }
00855 
00864         function expandList($list)      {
00865                 $items = explode(',',$list);
00866                 $list = array();
00867                 while(list(,$item)=each($items))        {
00868                         $range = explode('-',$item);
00869                         if (isset($range[1]))   {
00870                                 $runAwayBrake = 1000;
00871                                 for ($n=$range[0]; $n<=$range[1]; $n++) {
00872                                         $list[] = $n;
00873 
00874                                         $runAwayBrake--;
00875                                         if ($runAwayBrake<=0)   break;
00876                                 }
00877                         } else {
00878                                 $list[] = $item;
00879                         }
00880                 }
00881 
00882                 return implode(',',$list);
00883         }
00884 
00895         function intInRange($theInt,$min,$max=2000000000,$zeroValue=0)  {
00896                 // Returns $theInt as an integer in the integerspace from $min to $max
00897                 $theInt = intval($theInt);
00898                 if ($zeroValue && !$theInt)     {$theInt=$zeroValue;}   // If the input value is zero after being converted to integer, zeroValue may set another default value for it.
00899                 if ($theInt<$min){$theInt=$min;}
00900                 if ($theInt>$max){$theInt=$max;}
00901                 return $theInt;
00902         }
00903 
00911         function intval_positive($theInt)       {
00912                 $theInt = intval($theInt);
00913                 if ($theInt<0){$theInt=0;}
00914                 return $theInt;
00915         }
00916 
00924         function int_from_ver($verNumberStr)    {
00925                 $verParts = explode('.',$verNumberStr);
00926                 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));
00927         }
00928 
00937         function compat_version($verNumberStr)  {
00938                 global $TYPO3_CONF_VARS;
00939                 $currVersionStr = $TYPO3_CONF_VARS['SYS']['compat_version'] ? $TYPO3_CONF_VARS['SYS']['compat_version'] : TYPO3_branch;
00940 
00941                 if (t3lib_div::int_from_ver($currVersionStr) < t3lib_div::int_from_ver($verNumberStr))  {
00942                         return FALSE;
00943                 } else {
00944                         return TRUE;
00945                 }
00946         }
00947 
00955         function md5int($str)   {
00956                 return hexdec(substr(md5($str),0,7));
00957         }
00958 
00968         function shortMD5($input, $len=10)      {
00969                 return substr(md5($input),0,$len);
00970         }
00971 
00981         function uniqueList($in_list, $secondParameter=NULL)    {
00982                 if (is_array($in_list)) die('t3lib_div::uniqueList() does NOT support array arguments anymore! Only string comma lists!');
00983                 if (isset($secondParameter))    die('t3lib_div::uniqueList() does NOT support more than a single argument value anymore. You have specified more than one.');
00984 
00985                 return implode(',',array_unique(t3lib_div::trimExplode(',',$in_list,1)));
00986         }
00987 
00995         function split_fileref($fileref)        {
00996                 $reg = array();
00997                 if (    ereg('(.*/)(.*)$',$fileref,$reg)        )       {
00998                         $info['path'] = $reg[1];
00999                         $info['file'] = $reg[2];
01000                 } else {
01001                         $info['path'] = '';
01002                         $info['file'] = $fileref;
01003                 }
01004                 $reg='';
01005                 if (    ereg('(.*)\.([^\.]*$)',$info['file'],$reg)      )       {
01006                         $info['filebody'] = $reg[1];
01007                         $info['fileext'] = strtolower($reg[2]);
01008                         $info['realFileext'] = $reg[2];
01009                 } else {
01010                         $info['filebody'] = $info['file'];
01011                         $info['fileext'] = '';
01012                 }
01013                 reset($info);
01014                 return $info;
01015         }
01016 
01033         function dirname($path) {
01034                 $p=t3lib_div::revExplode('/',$path,2);
01035                 return count($p)==2?$p[0]:'';
01036         }
01037 
01049         function modifyHTMLColor($color,$R,$G,$B)       {
01050                 // This takes a hex-color (# included!) and adds $R, $G and $B to the HTML-color (format: #xxxxxx) and returns the new color
01051                 $nR = t3lib_div::intInRange(hexdec(substr($color,1,2))+$R,0,255);
01052                 $nG = t3lib_div::intInRange(hexdec(substr($color,3,2))+$G,0,255);
01053                 $nB = t3lib_div::intInRange(hexdec(substr($color,5,2))+$B,0,255);
01054                 return '#'.
01055                         substr('0'.dechex($nR),-2).
01056                         substr('0'.dechex($nG),-2).
01057                         substr('0'.dechex($nB),-2);
01058         }
01059 
01069         function modifyHTMLColorAll($color,$all)        {
01070                 return t3lib_div::modifyHTMLColor($color,$all,$all,$all);
01071         }
01072 
01080         function rm_endcomma($string)   {
01081                 return ereg_replace(',$','',$string);
01082         }
01083 
01093         function danish_strtoupper($string)     {
01094                 $value = strtoupper($string);
01095                 return strtr($value, 'áéúíâêûôîæøåäöü', 'ÁÉÚÍÄËÜÖÏÆØÅÄÖÜ');
01096         }
01097 
01108         function convUmlauts($str)      {
01109                 $pat  = array ( '/ä/',  '/Ä/',  '/ö/',  '/Ö/',  '/ü/',  '/Ü/',  '/ß/',  '/å/',  '/Å/',  '/ø/',  '/Ø/',  '/æ/',  '/Æ/'   );
01110                 $repl = array ( 'ae',   'Ae',   'oe',   'Oe',   'ue',   'Ue',   'ss',   'aa',   'AA',   'oe',   'OE',   'ae',   'AE'    );
01111                 return preg_replace($pat,$repl,$str);
01112         }
01113 
01121         function testInt($var)  {
01122                 return !strcmp($var,intval($var));
01123         }
01124 
01133         function isFirstPartOfStr($str,$partStr)        {
01134                 // Returns true, if the first part of a $str equals $partStr and $partStr is not ''
01135                 $psLen = strlen($partStr);
01136                 if ($psLen)     {
01137                         return substr($str,0,$psLen)==(string)$partStr;
01138                 } else return false;
01139         }
01140 
01149         function formatSize($sizeInBytes,$labels='')    {
01150 
01151                         // Set labels:
01152                 if (strlen($labels) == 0) {
01153                     $labels = ' | K| M| G';
01154                 } else {
01155                     $labels = str_replace('"','',$labels);
01156                 }
01157                 $labelArr = explode('|',$labels);
01158 
01159                         // Find size:
01160                 if ($sizeInBytes>900)   {
01161                         if ($sizeInBytes>900000000)     {       // GB
01162                                 $val = $sizeInBytes/(1024*1024*1024);
01163                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[3];
01164                         }
01165                         elseif ($sizeInBytes>900000)    {       // MB
01166                                 $val = $sizeInBytes/(1024*1024);
01167                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[2];
01168                         } else {        // KB
01169                                 $val = $sizeInBytes/(1024);
01170                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[1];
01171                         }
01172                 } else {        // Bytes
01173                         return $sizeInBytes.$labelArr[0];
01174                 }
01175         }
01176 
01184         function convertMicrotime($microtime)   {
01185                 $parts = explode(' ',$microtime);
01186                 return round(($parts[0]+$parts[1])*1000);
01187         }
01188 
01198         function splitCalc($string,$operators)  {
01199                 $res = Array();
01200                 $sign='+';
01201                 while($string)  {
01202                         $valueLen=strcspn($string,$operators);
01203                         $value=substr($string,0,$valueLen);
01204                         $res[] = Array($sign,trim($value));
01205                         $sign=substr($string,$valueLen,1);
01206                         $string=substr($string,$valueLen+1);
01207                 }
01208                 reset($res);
01209                 return $res;
01210         }
01211 
01220         function calcPriority($string)  {
01221                 $string=ereg_replace('[[:space:]]*','',$string);        // removing all whitespace
01222                 $string='+'.$string;    // Ensuring an operator for the first entrance
01223                 $qm='\*\/\+-^%';
01224                 $regex = '(['.$qm.'])(['.$qm.']?[0-9\.]*)';
01225                         // split the expression here:
01226                 $reg = array();
01227                 preg_match_all('/'.$regex.'/',$string,$reg);
01228 
01229                 reset($reg[2]);
01230                 $number=0;
01231                 $Msign='+';
01232                 $err='';
01233                 $buffer=doubleval(current($reg[2]));
01234                 next($reg[2]);  // Advance pointer
01235                 while(list($k,$v)=each($reg[2]))        {
01236                         $v=doubleval($v);
01237                         $sign = $reg[1][$k];
01238                         if ($sign=='+' || $sign=='-')   {
01239                                 $number = $Msign=='-' ? $number-=$buffer : $number+=$buffer;
01240                                 $Msign = $sign;
01241                                 $buffer=$v;
01242                         } else {
01243                                 if ($sign=='/') {if ($v) $buffer/=$v; else $err='dividing by zero';}
01244                                 if ($sign=='%') {if ($v) $buffer%=$v; else $err='dividing by zero';}
01245                                 if ($sign=='*') {$buffer*=$v;}
01246                                 if ($sign=='^') {$buffer=pow($buffer,$v);}
01247                         }
01248                 }
01249                 $number = $Msign=='-' ? $number-=$buffer : $number+=$buffer;
01250                 return $err ? 'ERROR: '.$err : $number;
01251         }
01252 
01261         function calcParenthesis($string)       {
01262                 $securC=100;
01263                 do {
01264                         $valueLenO=strcspn($string,'(');
01265                         $valueLenC=strcspn($string,')');
01266                         if ($valueLenC==strlen($string) || $valueLenC < $valueLenO)     {
01267                                 $value = t3lib_div::calcPriority(substr($string,0,$valueLenC));
01268                                 $string = $value.substr($string,$valueLenC+1);
01269                                 return $string;
01270                         } else {
01271                                 $string = substr($string,0,$valueLenO).t3lib_div::calcParenthesis(substr($string,$valueLenO+1));
01272                         }
01273                                 // Security:
01274                         $securC--;
01275                         if ($securC<=0) break;
01276                 } while($valueLenO<strlen($string));
01277                 return $string;
01278         }
01279 
01287         function htmlspecialchars_decode($value)        {
01288                 $value = str_replace('&gt;','>',$value);
01289                 $value = str_replace('&lt;','<',$value);
01290                 $value = str_replace('&quot;','"',$value);
01291                 $value = str_replace('&amp;','&',$value);
01292                 return $value;
01293         }
01294 
01302         function deHSCentities($str)    {
01303                 return ereg_replace('&amp;([#[:alnum:]]*;)','&\1',$str);
01304         }
01305 
01315         function slashJS($string,$extended=0,$char="'") {
01316                 if ($extended)  {$string = str_replace ("\\", "\\\\", $string);}
01317                 return str_replace ($char, "\\".$char, $string);
01318         }
01319 
01328         function rawUrlEncodeJS($str)   {
01329                 return str_replace('%20',' ',rawurlencode($str));
01330         }
01331 
01340         function rawUrlEncodeFP($str)   {
01341                 return str_replace('%2F','/',rawurlencode($str));
01342         }
01343 
01351         function validEmail($email)     {
01352                 $email = trim ($email);
01353                 if (strstr($email,' '))  return FALSE;
01354                 return ereg('^[A-Za-z0-9\._-]+[@][A-Za-z0-9\._-]+[\.].[A-Za-z0-9]+$',$email) ? TRUE : FALSE;
01355         }
01356 
01366         function formatForTextarea($content)    {
01367                 return chr(10).htmlspecialchars($content);
01368         }
01369 
01370 
01371 
01372 
01373 
01374 
01375 
01376 
01377 
01378 
01379 
01380 
01381         /*************************
01382          *
01383          * ARRAY FUNCTIONS
01384          *
01385          *************************/
01386 
01397         function inArray($in_array,$item)       {
01398                 if (is_array($in_array))        {
01399                         while (list(,$val)=each($in_array))     {
01400                                 if (!is_array($val) && !strcmp($val,$item)) return true;
01401                         }
01402                 }
01403         }
01404 
01414         function intExplode($delim, $string)    {
01415                 $temp = explode($delim,$string);
01416                 while(list($key,$val)=each($temp))      {
01417                         $temp[$key]=intval($val);
01418                 }
01419                 reset($temp);
01420                 return $temp;
01421         }
01422 
01433         function revExplode($delim, $string, $count=0)  {
01434                 $temp = explode($delim,strrev($string),$count);
01435                 while(list($key,$val)=each($temp))      {
01436                         $temp[$key]=strrev($val);
01437                 }
01438                 $temp=array_reverse($temp);
01439                 reset($temp);
01440                 return $temp;
01441         }
01442 
01453         function trimExplode($delim, $string, $onlyNonEmptyValues=0)    {
01454                 $temp = explode($delim,$string);
01455                 $newtemp=array();
01456                 while(list($key,$val)=each($temp))      {
01457                         if (!$onlyNonEmptyValues || strcmp('',trim($val)))      {
01458                                 $newtemp[]=trim($val);
01459                         }
01460                 }
01461                 reset($newtemp);
01462                 return $newtemp;
01463         }
01464 
01474         function uniqueArray($valueArray)       {
01475                 return array_unique($valueArray);
01476         }
01477 
01486         function removeArrayEntryByValue($array,$cmpValue)      {
01487                 if (is_array($array))   {
01488                         reset($array);
01489                         while(list($k,$v)=each($array)) {
01490                                 if (is_array($v))       {
01491                                         $array[$k] = t3lib_div::removeArrayEntryByValue($v,$cmpValue);
01492                                 } else {
01493                                         if (!strcmp($v,$cmpValue))      {
01494                                                 unset($array[$k]);
01495                                         }
01496                                 }
01497                         }
01498                 }
01499                 reset($array);
01500                 return $array;
01501         }
01502 
01515         function implodeArrayForUrl($name,$theArray,$str='',$skipBlank=0,$rawurlencodeParamName=0)      {
01516                 if (is_array($theArray))        {
01517                         foreach($theArray as $Akey => $AVal)    {
01518                                 $thisKeyName = $name ? $name.'['.$Akey.']' : $Akey;
01519                                 if (is_array($AVal))    {
01520                                         $str = t3lib_div::implodeArrayForUrl($thisKeyName,$AVal,$str,$skipBlank,$rawurlencodeParamName);
01521                                 } else {
01522                                         if (!$skipBlank || strcmp($AVal,''))    {
01523                                                 $str.='&'.($rawurlencodeParamName ? rawurlencode($thisKeyName) : $thisKeyName).
01524                                                         '='.rawurlencode($AVal);
01525                                         }
01526                                 }
01527                         }
01528                 }
01529                 return $str;
01530         }
01531 
01540         function explodeUrl2Array($string,$multidim=FALSE)      {
01541                 $output = array();
01542                 if ($multidim)  {
01543                         parse_str($string,$output);
01544                 } else {
01545                         $p = explode('&',$string);
01546                         foreach($p as $v)       {
01547                                 if (strlen($v)) {
01548                                         list($pK,$pV) = explode('=',$v,2);
01549                                         $output[rawurldecode($pK)] = rawurldecode($pV);
01550                                 }
01551                         }
01552                 }
01553                 return $output;
01554         }
01555 
01566         function compileSelectedGetVarsFromArray($varList,$getArray,$GPvarAlt=1)        {
01567                 $keys = t3lib_div::trimExplode(',',$varList,1);
01568                 $outArr=array();
01569                 foreach($keys as $v)    {
01570                         if (isset($getArray[$v]))       {
01571                                 $outArr[$v]=$getArray[$v];
01572                         } elseif ($GPvarAlt) {
01573                                 $outArr[$v]=t3lib_div::_GP($v);
01574                         }
01575                 }
01576                 return $outArr;
01577         }
01578 
01589         function addSlashesOnArray(&$theArray)  {
01590                 if (is_array($theArray))        {
01591                         reset($theArray);
01592                         while(list($Akey,$AVal)=each($theArray))        {
01593                                 if (is_array($AVal))    {
01594                                         t3lib_div::addSlashesOnArray($theArray[$Akey]);
01595                                 } else {
01596                                         $theArray[$Akey] = addslashes($AVal);
01597                                 }
01598                         }
01599                         reset($theArray);
01600                 }
01601         }
01602 
01613         function stripSlashesOnArray(&$theArray)        {
01614                 if (is_array($theArray))        {
01615                         reset($theArray);
01616                         while(list($Akey,$AVal)=each($theArray))        {
01617                                 if (is_array($AVal))    {
01618                                         t3lib_div::stripSlashesOnArray($theArray[$Akey]);
01619                                 } else {
01620                                         $theArray[$Akey] = stripslashes($AVal);
01621                                 }
01622                         }
01623                         reset($theArray);
01624                 }
01625         }
01626 
01635         function slashArray($arr,$cmd)  {
01636                 if ($cmd=='strip')      t3lib_div::stripSlashesOnArray($arr);
01637                 if ($cmd=='add')        t3lib_div::addSlashesOnArray($arr);
01638                 return $arr;
01639         }
01640 
01652         function array_merge_recursive_overrule($arr0,$arr1,$notAddKeys=0,$includeEmtpyValues=true) {
01653                 reset($arr1);
01654                 while(list($key,$val) = each($arr1)) {
01655                         if(is_array($arr0[$key])) {
01656                                 if (is_array($arr1[$key]))      {
01657                                         $arr0[$key] = t3lib_div::array_merge_recursive_overrule($arr0[$key],$arr1[$key],$notAddKeys);
01658                                 }
01659                         } else {
01660                                 if ($notAddKeys) {
01661                                         if (isset($arr0[$key])) {
01662                                                 if ($includeEmtpyValues OR $val) {
01663                                                         $arr0[$key] = $val;
01664                                                 }
01665                                         }
01666                                 } else {
01667                                         if ($includeEmtpyValues OR $val) {
01668                                                 $arr0[$key] = $val;
01669                                         }
01670                                 }
01671                         }
01672                 }
01673                 reset($arr0);
01674                 return $arr0;
01675         }
01676 
01685         function array_merge($arr1,$arr2)       {
01686                 return $arr2+$arr1;
01687         }
01688 
01698         function csvValues($row,$delim=',',$quote='"')  {
01699                 reset($row);
01700                 $out=array();
01701                 while(list(,$value)=each($row)) {
01702                         list($valPart) = explode(chr(10),$value);
01703                         $valPart = trim($valPart);
01704                         $out[]=str_replace($quote,$quote.$quote,$valPart);
01705                 }
01706                 $str = $quote.implode($quote.$delim.$quote,$out).$quote;
01707                 return $str;
01708         }
01709 
01717         function removeDotsFromTS($ts) {
01718                 $out = array();
01719                 if (is_array($ts)) {
01720                         foreach ($ts as $key => $value) {
01721                                 if (is_array($value)) {
01722                                         $key = rtrim($key, '.');
01723                                         $out[$key] = t3lib_div::removeDotsFromTS($value);
01724                                 } else {
01725                                         $out[$key] = $value;
01726                                 }
01727                         }
01728                 }
01729                 return $out;
01730         }
01731 
01732 
01733 
01734 
01735 
01736 
01737 
01738 
01739 
01740 
01741 
01742 
01743 
01744 
01745 
01746 
01747         /*************************
01748          *
01749          * HTML/XML PROCESSING
01750          *
01751          *************************/
01752 
01762         function get_tag_attributes($tag)       {
01763                 $components = t3lib_div::split_tag_attributes($tag);
01764                 $name = '';      // attribute name is stored here
01765                 $valuemode = '';
01766                 if (is_array($components))      {
01767                         while (list($key,$val) = each ($components))    {
01768                                 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
01769                                         if ($valuemode) {
01770                                                 if ($name)      {
01771                                                         $attributes[$name] = $val;
01772                                                         $name = '';
01773                                                 }
01774                                         } else {
01775                                                 if ($key = strtolower(ereg_replace('[^a-zA-Z0-9]','',$val)))    {
01776                                                         $attributes[$key] = '';
01777                                                         $name = $key;
01778                                                 }
01779                                         }
01780                                         $valuemode = '';
01781                                 } else {
01782                                         $valuemode = 'on';
01783                                 }
01784                         }
01785                         if (is_array($attributes))      reset($attributes);
01786                         return $attributes;
01787                 }
01788         }
01789 
01799         function split_tag_attributes($tag)     {
01800                 $tag_tmp = trim(eregi_replace ('^<[^[:space:]]*','',trim($tag)));
01801                         // Removes any > in the end of the string
01802                 $tag_tmp = trim(eregi_replace ('>$','',$tag_tmp));
01803 
01804                 while (strcmp($tag_tmp,''))     {       // Compared with empty string instead , 030102
01805                         $firstChar=substr($tag_tmp,0,1);
01806                         if (!strcmp($firstChar,'"') || !strcmp($firstChar,"'")) {
01807                                 $reg=explode($firstChar,$tag_tmp,3);
01808                                 $value[]=$reg[1];
01809                                 $tag_tmp=trim($reg[2]);
01810                         } elseif (!strcmp($firstChar,'=')) {
01811                                 $value[] = '=';
01812                                 $tag_tmp = trim(substr($tag_tmp,1));            // Removes = chars.
01813                         } else {
01814                                         // There are '' around the value. We look for the next ' ' or '>'
01815                                 $reg = split('[[:space:]=]',$tag_tmp,2);
01816                                 $value[] = trim($reg[0]);
01817                                 $tag_tmp = trim(substr($tag_tmp,strlen($reg[0]),1).$reg[1]);
01818                         }
01819                 }
01820                 if (is_array($value))   reset($value);
01821                 return $value;
01822         }
01823 
01833         function implodeAttributes($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)   {
01834                 if (is_array($arr))     {
01835                         if ($xhtmlSafe) {
01836                                 $newArr=array();
01837                                 foreach($arr as $p => $v)       {
01838                                         if (!isset($newArr[strtolower($p)])) $newArr[strtolower($p)] = htmlspecialchars($v);
01839                                 }
01840                                 $arr = $newArr;
01841                         }
01842                         $list = array();
01843                         foreach($arr as $p => $v)       {
01844                                 if (strcmp($v,'') || $dontOmitBlankAttribs)     {$list[]=$p.'="'.$v.'"';}
01845                         }
01846                         return implode(' ',$list);
01847                 }
01848         }
01849 
01860         function implodeParams($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)       {
01861                 return t3lib_div::implodeAttributes($arr,$xhtmlSafe,$dontOmitBlankAttribs);
01862         }
01863 
01875         function wrapJS($string, $linebreak=TRUE) {
01876                 if(trim($string)) {
01877                                 // <script wrapped in nl?
01878                         $cr = $linebreak? "\n" : '';
01879 
01880                                 // remove nl from the beginning
01881                         $string = preg_replace ('/^\n+/', '', $string);
01882                                 // re-ident to one tab using the first line as reference
01883                         $match = array();
01884                         if(preg_match('/^(\t+)/',$string,$match)) {
01885                                 $string = str_replace($match[1],"\t", $string);
01886                         }
01887                         $string = $cr.'<script type="text/javascript">
01888 /*<![CDATA[*/
01889 '.$string.'
01890 /*]]>*/
01891 </script>'.$cr;
01892                 }
01893                 return trim($string);
01894         }
01895 
01896 
01906         function xml2tree($string,$depth=999) {
01907                 $parser = xml_parser_create();
01908                 $vals = array();
01909                 $index = array();
01910 
01911                 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
01912                 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
01913                 xml_parse_into_struct($parser, $string, $vals, $index);
01914 
01915                 if (xml_get_error_code($parser))        return 'Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
01916                 xml_parser_free($parser);
01917 
01918                 $stack = array( array() );
01919                 $stacktop = 0;
01920                 $startPoint=0;
01921 
01922 // FIXME don't use unset() - what does that mean? Use NULL or similar.
01923                 unset($tagi);
01924                 foreach($vals as $key => $val) {
01925                         $type = $val['type'];
01926 
01927                                 // open tag:
01928                         if ($type=='open' || $type=='complete') {
01929                                 $stack[$stacktop++] = $tagi;
01930 
01931                                 if ($depth==$stacktop)  {
01932                                         $startPoint=$key;
01933                                 }
01934 
01935                                 $tagi = array('tag' => $val['tag']);
01936 
01937                                 if(isset($val['attributes']))  $tagi['attrs'] = $val['attributes'];
01938                                 if(isset($val['value']))        $tagi['values'][] = $val['value'];
01939                         }
01940                                 // finish tag:
01941                         if ($type=='complete' || $type=='close')        {
01942                                 $oldtagi = $tagi;
01943                                 $tagi = $stack[--$stacktop];
01944                                 $oldtag = $oldtagi['tag'];
01945                                 unset($oldtagi['tag']);
01946 
01947                                 if ($depth==($stacktop+1))      {
01948                                         if ($key-$startPoint > 0)       {
01949                                                 $partArray = array_slice(
01950                                                         $vals,
01951                                                         $startPoint+1,
01952                                                         $key-$startPoint-1
01953                                                 );
01954                                                 #$oldtagi=array('XMLvalue'=>t3lib_div::xmlRecompileFromStructValArray($partArray));
01955                                                 $oldtagi['XMLvalue']=t3lib_div::xmlRecompileFromStructValArray($partArray);
01956                                         } else {
01957                                                 $oldtagi['XMLvalue']=$oldtagi['values'][0];
01958                                         }
01959                                 }
01960 
01961                                 $tagi['ch'][$oldtag][] = $oldtagi;
01962                                 unset($oldtagi);
01963                         }
01964                                 // cdata
01965                         if($type=='cdata') {
01966                                 $tagi['values'][] = $val['value'];
01967                         }
01968                 }
01969                 return $tagi['ch'];
01970         }
01971 
01982         function array2xml_cs($array,$docTag='phparray',$options=array(),$charset='')   {
01983 
01984                         // Figure out charset if not given explicitly:
01985                 if (!$charset)  {
01986                         if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'])  {       // First priority: forceCharset! If set, this will be authoritative!
01987                                 $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
01988                         } elseif (is_object($GLOBALS['LANG']))  {
01989                                 $charset = $GLOBALS['LANG']->charSet;   // If "LANG" is around, that will hold the current charset
01990                         } else {
01991                                 $charset = 'iso-8859-1';        // THIS is just a hopeful guess!
01992                         }
01993                 }
01994 
01995                         // Return XML:
01996                 return '<?xml version="1.0" encoding="'.htmlspecialchars($charset).'" standalone="yes" ?>'.chr(10).
01997                                 t3lib_div::array2xml($array,'',0,$docTag,0, $options);
01998         }
01999 
02023         function array2xml($array,$NSprefix='',$level=0,$docTag='phparray',$spaceInd=0, $options=array(),$stackData=array())    {
02024                         // 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
02025                 $binaryChars = chr(0).chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8).
02026                                                 chr(11).chr(12).chr(14).chr(15).chr(16).chr(17).chr(18).chr(19).
02027                                                 chr(20).chr(21).chr(22).chr(23).chr(24).chr(25).chr(26).chr(27).chr(28).chr(29).
02028                                                 chr(30).chr(31);
02029                         // Set indenting mode:
02030                 $indentChar = $spaceInd ? ' ' : chr(9);
02031                 $indentN = $spaceInd>0 ? $spaceInd : 1;
02032                 $nl = ($spaceInd >= 0 ? chr(10) : '');
02033 
02034                         // Init output variable:
02035                 $output='';
02036 
02037                         // Traverse the input array
02038                 if (is_array($array))   {
02039                         foreach($array as $k=>$v)       {
02040                                 $attr = '';
02041                                 $tagName = $k;
02042 
02043                                         // Construct the tag name.
02044                                 if(isset($options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']])) {            // Use tag based on grand-parent + parent tag name
02045                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02046                                         $tagName = (string)$options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']];
02047                                 }elseif(isset($options['parentTagMap'][$stackData['parentTagName'].':_IS_NUM']) && t3lib_div::testInt($tagName)) {              // Use tag based on parent tag name + if current tag is numeric
02048                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02049                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName'].':_IS_NUM'];
02050                                 }elseif(isset($options['parentTagMap'][$stackData['parentTagName'].':'.$tagName])) {            // Use tag based on parent tag name + current tag
02051                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02052                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName'].':'.$tagName];
02053                                 } elseif(isset($options['parentTagMap'][$stackData['parentTagName']])) {                // Use tag based on parent tag name:
02054                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02055                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName']];
02056                                 } elseif (!strcmp(intval($tagName),$tagName))   {       // If integer...;
02057                                         if ($options['useNindex']) {    // If numeric key, prefix "n"
02058                                                 $tagName = 'n'.$tagName;
02059                                         } else {        // Use special tag for num. keys:
02060                                                 $attr.=' index="'.$tagName.'"';
02061                                                 $tagName = $options['useIndexTagForNum'] ? $options['useIndexTagForNum'] : 'numIndex';
02062                                         }
02063                                 } elseif($options['useIndexTagForAssoc']) {             // Use tag for all associative keys:
02064                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02065                                         $tagName = $options['useIndexTagForAssoc'];
02066                                 }
02067 
02068                                         // The tag name is cleaned up so only alphanumeric chars (plus - and _) are in there and not longer than 100 chars either.
02069                                 $tagName = substr(ereg_replace('[^[:alnum:]_-]','',$tagName),0,100);
02070 
02071                                         // If the value is an array then we will call this function recursively:
02072                                 if (is_array($v))       {
02073 
02074                                                 // Sub elements:
02075                                         if ($options['alt_options'][$stackData['path'].'/'.$tagName])   {
02076                                                 $subOptions = $options['alt_options'][$stackData['path'].'/'.$tagName];
02077                                                 $clearStackPath = $subOptions['clearStackPath'];
02078                                         } else {
02079                                                 $subOptions = $options;
02080                                                 $clearStackPath = FALSE;
02081                                         }
02082 
02083                                         $content = $nl .
02084                                                                 t3lib_div::array2xml(
02085                                                                         $v,
02086                                                                         $NSprefix,
02087                                                                         $level+1,
02088                                                                         '',
02089                                                                         $spaceInd,
02090                                                                         $subOptions,
02091                                                                         array(
02092                                                                                 'parentTagName' => $tagName,
02093                                                                                 'grandParentTagName' => $stackData['parentTagName'],
02094                                                                                 'path' => $clearStackPath ? '' : $stackData['path'].'/'.$tagName,
02095                                                                         )
02096                                                                 ).
02097                                                                 ($spaceInd >= 0 ? str_pad('',($level+1)*$indentN,$indentChar) : '');
02098                                         if ((int)$options['disableTypeAttrib']!=2)      {       // Do not set "type = array". Makes prettier XML but means that empty arrays are not restored with xml2array
02099                                                 $attr.=' type="array"';
02100                                         }
02101                                 } else {        // Just a value: