/src/typo3_src-4.2.0alpha1/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 
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                 $array = explode($delim, $string);
01455                 if ($onlyNonEmptyValues) {
01456                         foreach($array as $index => &$value) {
01457                                 $value = trim($value);
01458                                 if ($value == '') {
01459                                         unset($array[$index]);
01460                                 }
01461                         }
01462                         $array = array_merge($array);
01463                 } else {
01464                         foreach($array as $key => &$value) {
01465                                 $value = trim($value);
01466                         }
01467                 }
01468                 return $array;
01469         }
01470 
01480         function uniqueArray($valueArray)       {
01481                 return array_unique($valueArray);
01482         }
01483 
01492         function removeArrayEntryByValue($array,$cmpValue)      {
01493                 if (is_array($array))   {
01494                         reset($array);
01495                         while(list($k,$v)=each($array)) {
01496                                 if (is_array($v))       {
01497                                         $array[$k] = t3lib_div::removeArrayEntryByValue($v,$cmpValue);
01498                                 } else {
01499                                         if (!strcmp($v,$cmpValue))      {
01500                                                 unset($array[$k]);
01501                                         }
01502                                 }
01503                         }
01504                 }
01505                 reset($array);
01506                 return $array;
01507         }
01508 
01521         function implodeArrayForUrl($name,$theArray,$str='',$skipBlank=0,$rawurlencodeParamName=0)      {
01522                 if (is_array($theArray))        {
01523                         foreach($theArray as $Akey => $AVal)    {
01524                                 $thisKeyName = $name ? $name.'['.$Akey.']' : $Akey;
01525                                 if (is_array($AVal))    {
01526                                         $str = t3lib_div::implodeArrayForUrl($thisKeyName,$AVal,$str,$skipBlank,$rawurlencodeParamName);
01527                                 } else {
01528                                         if (!$skipBlank || strcmp($AVal,''))    {
01529                                                 $str.='&'.($rawurlencodeParamName ? rawurlencode($thisKeyName) : $thisKeyName).
01530                                                         '='.rawurlencode($AVal);
01531                                         }
01532                                 }
01533                         }
01534                 }
01535                 return $str;
01536         }
01537 
01546         function explodeUrl2Array($string,$multidim=FALSE)      {
01547                 $output = array();
01548                 if ($multidim)  {
01549                         parse_str($string,$output);
01550                 } else {
01551                         $p = explode('&',$string);
01552                         foreach($p as $v)       {
01553                                 if (strlen($v)) {
01554                                         list($pK,$pV) = explode('=',$v,2);
01555                                         $output[rawurldecode($pK)] = rawurldecode($pV);
01556                                 }
01557                         }
01558                 }
01559                 return $output;
01560         }
01561 
01572         function compileSelectedGetVarsFromArray($varList,$getArray,$GPvarAlt=1)        {
01573                 $keys = t3lib_div::trimExplode(',',$varList,1);
01574                 $outArr=array();
01575                 foreach($keys as $v)    {
01576                         if (isset($getArray[$v]))       {
01577                                 $outArr[$v]=$getArray[$v];
01578                         } elseif ($GPvarAlt) {
01579                                 $outArr[$v]=t3lib_div::_GP($v);
01580                         }
01581                 }
01582                 return $outArr;
01583         }
01584 
01595         function addSlashesOnArray(&$theArray)  {
01596                 if (is_array($theArray))        {
01597                         reset($theArray);
01598                         while(list($Akey,$AVal)=each($theArray))        {
01599                                 if (is_array($AVal))    {
01600                                         t3lib_div::addSlashesOnArray($theArray[$Akey]);
01601                                 } else {
01602                                         $theArray[$Akey] = addslashes($AVal);
01603                                 }
01604                         }
01605                         reset($theArray);
01606                 }
01607         }
01608 
01619         function stripSlashesOnArray(&$theArray)        {
01620                 if (is_array($theArray))        {
01621                         reset($theArray);
01622                         while(list($Akey,$AVal)=each($theArray))        {
01623                                 if (is_array($AVal))    {
01624                                         t3lib_div::stripSlashesOnArray($theArray[$Akey]);
01625                                 } else {
01626                                         $theArray[$Akey] = stripslashes($AVal);
01627                                 }
01628                         }
01629                         reset($theArray);
01630                 }
01631         }
01632 
01641         function slashArray($arr,$cmd)  {
01642                 if ($cmd=='strip')      t3lib_div::stripSlashesOnArray($arr);
01643                 if ($cmd=='add')        t3lib_div::addSlashesOnArray($arr);
01644                 return $arr;
01645         }
01646 
01658         function array_merge_recursive_overrule($arr0,$arr1,$notAddKeys=0,$includeEmtpyValues=true) {
01659                 reset($arr1);
01660                 while(list($key,$val) = each($arr1)) {
01661                         if(is_array($arr0[$key])) {
01662                                 if (is_array($arr1[$key]))      {
01663                                         $arr0[$key] = t3lib_div::array_merge_recursive_overrule($arr0[$key],$arr1[$key],$notAddKeys,$includeEmtpyValues);
01664                                 }
01665                         } else {
01666                                 if ($notAddKeys) {
01667                                         if (isset($arr0[$key])) {
01668                                                 if ($includeEmtpyValues || $val) {
01669                                                         $arr0[$key] = $val;
01670                                                 }
01671                                         }
01672                                 } else {
01673                                         if ($includeEmtpyValues || $val) {
01674                                                 $arr0[$key] = $val;
01675                                         }
01676                                 }
01677                         }
01678                 }
01679                 reset($arr0);
01680                 return $arr0;
01681         }
01682 
01691         function array_merge($arr1,$arr2)       {
01692                 return $arr2+$arr1;
01693         }
01694 
01704         function csvValues($row,$delim=',',$quote='"')  {
01705                 reset($row);
01706                 $out=array();
01707                 foreach ($row as $value) {
01708                         $out[] = str_replace($quote, $quote.$quote, $value);
01709                 }
01710                 $str = $quote.implode($quote.$delim.$quote,$out).$quote;
01711                 return $str;
01712         }
01713 
01721         function array2json($jsonArray) {
01722                 if (!$GLOBALS['JSON']) {
01723                         require_once(PATH_typo3.'contrib/json.php');
01724                         $GLOBALS['JSON'] = t3lib_div::makeInstance('Services_JSON');
01725                 }
01726                 return $GLOBALS['JSON']->encode($jsonArray);
01727         }
01728 
01736         function removeDotsFromTS($ts) {
01737                 $out = array();
01738                 if (is_array($ts)) {
01739                         foreach ($ts as $key => $value) {
01740                                 if (is_array($value)) {
01741                                         $key = rtrim($key, '.');
01742                                         $out[$key] = t3lib_div::removeDotsFromTS($value);
01743                                 } else {
01744                                         $out[$key] = $value;
01745                                 }
01746                         }
01747                 }
01748                 return $out;
01749         }
01750 
01751 
01752 
01753 
01754 
01755 
01756 
01757 
01758 
01759 
01760 
01761 
01762 
01763 
01764 
01765 
01766         /*************************
01767          *
01768          * HTML/XML PROCESSING
01769          *
01770          *************************/
01771 
01781         function get_tag_attributes($tag)       {
01782                 $components = t3lib_div::split_tag_attributes($tag);
01783                 $name = '';      // attribute name is stored here
01784                 $valuemode = '';
01785                 if (is_array($components))      {
01786                         while (list($key,$val) = each ($components))    {
01787                                 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
01788                                         if ($valuemode) {
01789                                                 if ($name)      {
01790                                                         $attributes[$name] = $val;
01791                                                         $name = '';
01792                                                 }
01793                                         } else {
01794                                                 if ($key = strtolower(ereg_replace('[^a-zA-Z0-9]','',$val)))    {
01795                                                         $attributes[$key] = '';
01796                                                         $name = $key;
01797                                                 }
01798                                         }
01799                                         $valuemode = '';
01800                                 } else {
01801                                         $valuemode = 'on';
01802                                 }
01803                         }
01804                         if (is_array($attributes))      reset($attributes);
01805                         return $attributes;
01806                 }
01807         }
01808 
01818         function split_tag_attributes($tag)     {
01819                 $tag_tmp = trim(eregi_replace ('^<[^[:space:]]*','',trim($tag)));
01820                         // Removes any > in the end of the string
01821                 $tag_tmp = trim(eregi_replace ('>$','',$tag_tmp));
01822 
01823                 while (strcmp($tag_tmp,''))     {       // Compared with empty string instead , 030102
01824                         $firstChar=substr($tag_tmp,0,1);
01825                         if (!strcmp($firstChar,'"') || !strcmp($firstChar,"'")) {
01826                                 $reg=explode($firstChar,$tag_tmp,3);
01827                                 $value[]=$reg[1];
01828                                 $tag_tmp=trim($reg[2]);
01829                         } elseif (!strcmp($firstChar,'=')) {
01830                                 $value[] = '=';
01831                                 $tag_tmp = trim(substr($tag_tmp,1));            // Removes = chars.
01832                         } else {
01833                                         // There are '' around the value. We look for the next ' ' or '>'
01834                                 $reg = split('[[:space:]=]',$tag_tmp,2);
01835                                 $value[] = trim($reg[0]);
01836                                 $tag_tmp = trim(substr($tag_tmp,strlen($reg[0]),1).$reg[1]);
01837                         }
01838                 }
01839                 if (is_array($value))   reset($value);
01840                 return $value;
01841         }
01842 
01852         function implodeAttributes($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)   {
01853                 if (is_array($arr))     {
01854                         if ($xhtmlSafe) {
01855                                 $newArr=array();
01856                                 foreach($arr as $p => $v)       {
01857                                         if (!isset($newArr[strtolower($p)])) $newArr[strtolower($p)] = htmlspecialchars($v);
01858                                 }
01859                                 $arr = $newArr;
01860                         }
01861                         $list = array();
01862                         foreach($arr as $p => $v)       {
01863                                 if (strcmp($v,'') || $dontOmitBlankAttribs)     {$list[]=$p.'="'.$v.'"';}
01864                         }
01865                         return implode(' ',$list);
01866                 }
01867         }
01868 
01879         function implodeParams($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)       {
01880                 return t3lib_div::implodeAttributes($arr,$xhtmlSafe,$dontOmitBlankAttribs);
01881         }
01882 
01894         function wrapJS($string, $linebreak=TRUE) {
01895                 if(trim($string)) {
01896                                 // <script wrapped in nl?
01897                         $cr = $linebreak? "\n" : '';
01898 
01899                                 // remove nl from the beginning
01900                         $string = preg_replace ('/^\n+/', '', $string);
01901                                 // re-ident to one tab using the first line as reference
01902                         $match = array();
01903                         if(preg_match('/^(\t+)/',$string,$match)) {
01904                                 $string = str_replace($match[1],"\t", $string);
01905                         }
01906                         $string = $cr.'<script type="text/javascript">
01907 /*<![CDATA[*/
01908 '.$string.'
01909 /*]]>*/
01910 </script>'.$cr;
01911                 }
01912                 return trim($string);
01913         }
01914 
01915 
01925         function xml2tree($string,$depth=999) {
01926                 $parser = xml_parser_create();
01927                 $vals = array();
01928                 $index = array();
01929 
01930                 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
01931                 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
01932                 xml_parse_into_struct($parser, $string, $vals, $index);
01933 
01934                 if (xml_get_error_code($parser))        return 'Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
01935                 xml_parser_free($parser);
01936 
01937                 $stack = array( array() );
01938                 $stacktop = 0;
01939                 $startPoint=0;
01940 
01941 // FIXME don't use unset() - what does that mean? Use NULL or similar.
01942                 unset($tagi);
01943                 foreach($vals as $key => $val) {
01944                         $type = $val['type'];
01945 
01946                                 // open tag:
01947                         if ($type=='open' || $type=='complete') {
01948                                 $stack[$stacktop++] = $tagi;
01949 
01950                                 if ($depth==$stacktop)  {
01951                                         $startPoint=$key;
01952                                 }
01953 
01954                                 $tagi = array('tag' => $val['tag']);
01955 
01956                                 if(isset($val['attributes']))  $tagi['attrs'] = $val['attributes'];
01957                                 if(isset($val['value']))        $tagi['values'][] = $val['value'];
01958                         }
01959                                 // finish tag:
01960                         if ($type=='complete' || $type=='close')        {
01961                                 $oldtagi = $tagi;
01962                                 $tagi = $stack[--$stacktop];
01963                                 $oldtag = $oldtagi['tag'];
01964                                 unset($oldtagi['tag']);
01965 
01966                                 if ($depth==($stacktop+1))      {
01967                                         if ($key-$startPoint > 0)       {
01968                                                 $partArray = array_slice(
01969                                                         $vals,
01970                                                         $startPoint+1,
01971                                                         $key-$startPoint-1
01972                                                 );
01973                                                 #$oldtagi=array('XMLvalue'=>t3lib_div::xmlRecompileFromStructValArray($partArray));
01974                                                 $oldtagi['XMLvalue']=t3lib_div::xmlRecompileFromStructValArray($partArray);
01975                                         } else {
01976                                                 $oldtagi['XMLvalue']=$oldtagi['values'][0];
01977                                         }
01978                                 }
01979 
01980                                 $tagi['ch'][$oldtag][] = $oldtagi;
01981                                 unset($oldtagi);
01982                         }
01983                                 // cdata
01984                         if($type=='cdata') {
01985                                 $tagi['values'][] = $val['value'];
01986                         }
01987                 }
01988                 return $tagi['ch'];
01989         }
01990 
02001         function array2xml_cs($array,$docTag='phparray',$options=array(),$charset='')   {
02002 
02003                         // Figure out charset if not given explicitly:
02004                 if (!$charset)  {
02005                         if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'])  {       // First priority: forceCharset! If set, this will be authoritative!
02006                                 $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
02007                         } elseif (is_object($GLOBALS['LANG']))  {
02008                                 $charset = $GLOBALS['LANG']->charSet;   // If "LANG" is around, that will hold the current charset
02009                         } else {
02010                                 $charset = 'iso-8859-1';        // THIS is just a hopeful guess!
02011                         }
02012                 }
02013 
02014                         // Return XML:
02015                 return '<?xml version="1.0" encoding="'.htmlspecialchars($charset).'" standalone="yes" ?>'.chr(10).
02016                                 t3lib_div::array2xml($array,'',0,$docTag,0, $options);
02017         }
02018 
02042         function array2xml($array,$NSprefix='',$level=0,$docTag='phparray',$spaceInd=0, $options=array(),$stackData=array())    {
02043                         // 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
02044                 $binaryChars = chr(0).chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8).
02045                                                 chr(11).chr(12).chr(14).chr(15).chr(16).chr(17).chr(18).chr(19).
02046                                                 chr(20).chr(21).chr(22).chr(23).chr(24).chr(25).chr(26).chr(27).chr(28).chr(29).
02047                                                 chr(30).chr(31);
02048                         // Set indenting mode:
02049                 $indentChar = $spaceInd ? ' ' : chr(9);
02050                 $indentN = $spaceInd>0 ? $spaceInd : 1;
02051                 $nl = ($spaceInd >= 0 ? chr(10) : '');
02052 
02053                         // Init output variable:
02054                 $output='';
02055 
02056                         // Traverse the input array
02057                 if (is_array($array))   {
02058                         foreach($array as $k=>$v)       {
02059                                 $attr = '';
02060                                 $tagName = $k;
02061 
02062                                         // Construct the tag name.
02063                                 if(isset($options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']])) {            // Use tag based on grand-parent + parent tag name
02064                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02065                                         $tagName = (string)$options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']];
02066                                 }elseif(isset($options['parentTagMap'][$stackData['parentTagName'].':_IS_NUM']) && t3lib_div::testInt($tagName)) {              // Use tag based on parent tag name + if current tag is numeric
02067                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02068                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName'].':_IS_NUM'];
02069                                 }elseif(isset($options['parentTagMap'][$stackData['parentTagName'].':'.$tagName])) {            // Use tag based on parent tag name + current tag
02070                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02071                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName'].':'.$tagName];
02072                                 } elseif(isset($options['parentTagMap'][$stackData['parentTagName']])) {                // Use tag based on parent tag name:
02073                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02074                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName']];
02075                                 } elseif (!strcmp(intval($tagName),$tagName))   {       // If integer...;
02076                                         if ($options['useNindex']) {    // If numeric key, prefix "n"
02077                                                 $tagName = 'n'.$tagName;
02078                                         } else {        // Use special tag for num. keys:
02079                                                 $attr.=' index="'.$tagName.'"';
02080                                                 $tagName = $options['useIndexTagForNum'] ? $options['useIndexTagForNum'] : 'numIndex';
02081                                         }
02082                                 } elseif($options['useIndexTagForAssoc']) {             // Use tag for all associative keys:
02083                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
02084                                         $tagName = $options['useIndexTagForAssoc'];
02085                                 }
02086 
02087                                         // The tag name is cleaned up so only alphanumeric chars (plus - and _) are in there and not longer than 100 chars either.
02088                                 $tagName = substr(ereg_replace('[^[:alnum:]_-]','',$tagName),0,100);
02089 
02090                                         // If the value is an array then we will call this function recursively:
02091                                 if (is_array($v))       {
02092 
02093                                                 // Sub elements:
02094                                         if ($options['alt_options'][$stackData['path'].'/'.$tagName])   {
02095                                                 $subOptions = $options['alt_options'][$stackData['path'].'/'.$tagName];
02096                                                 $clearStackPath = $subOptions['clearStackPath'];
02097                                         } else {
02098                                                 $subOptions = $options;
02099                                                 $clearStackPath = FALSE;
02100                                         }
02101 
02102                                         $content = $nl .
02103                                                                 t3lib_div::array2xml(
02104                                                                         $v,
02105                                                                         $NSprefix,
02106                                                                         $level+1,
02107                                                                         '',
02108                                                                         $spaceInd,
02109                                                                         $subOptions,
02110                                                                         array(
02111                                                                                 'parentTagName' => $tagName,
02112