t3lib/class.t3lib_div.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2005 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 ***************************************************************/
00211 class t3lib_div {
00212 
00213 
00214 
00215 
00216 
00217         /*************************
00218          *
00219          * GET/POST Variables
00220          *
00221          * Background:
00222          * Input GET/POST variables in PHP may have their quotes escaped with "\" or not depending on configuration.
00223          * TYPO3 has always converted quotes to BE escaped if the configuration told that they would not be so.
00224          * But the clean solution is that quotes are never escaped and that is what the functions below offers.
00225          * Eventually TYPO3 should provide this in the global space as well.
00226          * In the transitional phase (or forever..?) we need to encourage EVERY to read and write GET/POST vars through the API functions below.
00227          *
00228          *************************/
00229 
00241         function _GP($var)      {
00242                 if(empty($var)) return;
00243                 $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var];
00244                 if (isset($value))      {
00245                         if (is_array($value))   { t3lib_div::stripSlashesOnArray($value); } else { $value = stripslashes($value); }
00246                 }
00247                 return $value;
00248         }
00249 
00259         function _GET($var=NULL)        {
00260                 $value = ($var === NULL) ? $_GET : (empty($var) ? NULL : $_GET[$var]);
00261                 if (isset($value))      {       // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
00262                         if (is_array($value))   { t3lib_div::stripSlashesOnArray($value); } else { $value = stripslashes($value); }
00263                 }
00264                 return $value;
00265         }
00266 
00276         function _POST($var=NULL)       {
00277                 $value = ($var === NULL) ? $_POST : (empty($var) ? NULL : $_POST[$var]);
00278                 if (isset($value))      {       // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
00279                         if (is_array($value))   { t3lib_div::stripSlashesOnArray($value); } else { $value = stripslashes($value); }
00280                 }
00281                 return $value;
00282         }
00283 
00292         function _GETset($inputGet,$key='')     {
00293                         // ADDS slashes since TYPO3 standard currently is that slashes MUST be applied (regardless of magic_quotes setting).
00294                 if (strcmp($key,''))    {
00295                         if (is_array($inputGet))        { t3lib_div::addSlashesOnArray($inputGet); } else { $inputGet = addslashes($inputGet); }
00296                         $GLOBALS['HTTP_GET_VARS'][$key] = $_GET[$key] = $inputGet;
00297                 } elseif (is_array($inputGet)){
00298                         t3lib_div::addSlashesOnArray($inputGet);
00299                         $GLOBALS['HTTP_GET_VARS'] = $_GET = $inputGet;
00300                 }
00301         }
00302 
00315         function GPvar($var,$strip=0)   {
00316                 if(empty($var)) return;
00317                 $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var];
00318                 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.
00319                 if ($strip && isset($value) && is_array($value)) { t3lib_div::stripSlashesOnArray($value); }
00320                 return $value;
00321         }
00322 
00332         function GParrayMerged($var)    {
00333                 $postA = is_array($_POST[$var]) ? $_POST[$var] : array();
00334                 $getA = is_array($_GET[$var]) ? $_GET[$var] : array();
00335                 $mergedA = t3lib_div::array_merge_recursive_overrule($getA,$postA);
00336                 t3lib_div::stripSlashesOnArray($mergedA);
00337                 return $mergedA;
00338         }
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349         /*************************
00350          *
00351          * IMAGE FUNCTIONS
00352          *
00353          *************************/
00354 
00355 
00376         function gif_compress($theFile, $type)  {
00377                 $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
00378                 $returnCode='';
00379                 if ($gfxConf['gif_compress'] && strtolower(substr($theFile,-4,4))=='.gif')      {       // GIF...
00380                         if (($type=='IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw'])       {       // IM
00381                                 $cmd = t3lib_div::imageMagickCommand('convert', '"'.$theFile.'" "'.$theFile.'"', $gfxConf['im_path_lzw']);
00382                                 exec($cmd);
00383 
00384                                 $returnCode='IM';
00385                         } elseif (($type=='GD' || !$type) && $gfxConf['gdlib'] && !$gfxConf['gdlib_png'])       {       // GD
00386                                 $tempImage = imageCreateFromGif($theFile);
00387                                 imageGif($tempImage, $theFile);
00388                                 imageDestroy($tempImage);
00389                                 $returnCode='GD';
00390                         }
00391                 }
00392                 return $returnCode;
00393         }
00394 
00404         function png_to_gif_by_imagemagick($theFile)    {
00405                 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif']
00406                         && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im']
00407                         && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']
00408                         && strtolower(substr($theFile,-4,4))=='.png'
00409                         && @is_file($theFile))  {       // IM
00410                                 $newFile = substr($theFile,0,-4).'.gif';
00411                                 $cmd = t3lib_div::imageMagickCommand('convert', '"'.$theFile.'" "'.$newFile.'"', $gfxConf['im_path_lzw']);
00412                                 exec($cmd);
00413                                 $theFile = $newFile;
00414                                         // 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!!
00415                 }
00416                 return $theFile;
00417         }
00418 
00429         function read_png_gif($theFile,$output_png=0)   {
00430                 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] && @is_file($theFile))     {
00431                         $ext = strtolower(substr($theFile,-4,4));
00432                         if (
00433                                         ((string)$ext=='.png' && $output_png)   ||
00434                                         ((string)$ext=='.gif' && !$output_png)
00435                                 )       {
00436                                 return $theFile;
00437                         } else {
00438                                 $newFile = PATH_site.'typo3temp/readPG_'.md5($theFile.'|'.filemtime($theFile)).($output_png?'.png':'.gif');
00439                                 exec($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path'].'convert "'.$theFile.'" "'.$newFile.'"');
00440                                 if (@is_file($newFile)) return $newFile;
00441                         }
00442                 }
00443         }
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459         /*************************
00460          *
00461          * STRING FUNCTIONS
00462          *
00463          *************************/
00464 
00478         function fixed_lgd($string,$origChars,$preStr='...')    {
00479                 $chars = abs($origChars);
00480                 if ($chars >= 4)        {
00481                         if(strlen($string)>$chars)  {
00482                                 return $origChars < 0 ?
00483                                         $preStr.trim(substr($string, -($chars-3))) :
00484                                         trim(substr($string, 0, $chars-3)).$preStr;
00485                         }
00486                 }
00487                 return $string;
00488         }
00489 
00503         function fixed_lgd_pre($string,$chars)  {
00504                 return strrev(t3lib_div::fixed_lgd(strrev($string),$chars));
00505         }
00506 
00517         function fixed_lgd_cs($string,$chars)   {
00518                 if (is_object($GLOBALS['LANG']))        {
00519                         return $GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet,$string,$chars,'...');
00520                 } else {
00521                         return t3lib_div::fixed_lgd($string, $chars);
00522                 }
00523         }
00524 
00534         function breakTextForEmail($str,$implChar="\n",$charWidth=76)   {
00535                 $lines = explode(chr(10),$str);
00536                 $outArr=array();
00537                 while(list(,$lStr)=each($lines))        {
00538                         $outArr = array_merge($outArr,t3lib_div::breakLinesForEmail($lStr,$implChar,$charWidth));
00539                 }
00540                 return implode(chr(10),$outArr);
00541         }
00542 
00553         function breakLinesForEmail($str,$implChar="\n",$charWidth=76)  {
00554                 $lines=array();
00555                 $l=$charWidth;
00556                 $p=0;
00557                 while(strlen($str)>$p)  {
00558                         $substr=substr($str,$p,$l);
00559                         if (strlen($substr)==$l)        {
00560                                 $count = count(explode(' ',trim(strrev($substr))));
00561                                 if ($count>1)   {       // OK...
00562                                         $parts = explode(' ',strrev($substr),2);
00563                                         $theLine = strrev($parts[1]);
00564                                 } else {
00565                                         $afterParts = explode(' ',substr($str,$l+$p),2);
00566                                         $theLine = $substr.$afterParts[0];
00567                                 }
00568                                 if (!strlen($theLine))  {break; }       // Error, because this would keep us in an endless loop.
00569                         } else {
00570                                 $theLine=$substr;
00571                         }
00572 
00573                         $lines[]=trim($theLine);
00574                         $p+=strlen($theLine);
00575                         if (!trim(substr($str,$p,$l)))  break;  // added...
00576                 }
00577                 return implode($implChar,$lines);
00578         }
00579 
00588         function cmpIP($baseIP, $list)  {
00589                 $IPpartsReq = explode('.',$baseIP);
00590                 if (count($IPpartsReq)==4)      {
00591                         $values = t3lib_div::trimExplode(',',$list,1);
00592 
00593                         foreach($values as $test)       {
00594                                 list($test,$mask) = explode('/',$test);
00595 
00596                                 if(intval($mask)) {
00597                                                 // "192.168.3.0/24"
00598                                         $lnet = ip2long($test);
00599                                         $lip = ip2long($baseIP);
00600                                         $binnet = str_pad( decbin($lnet),32,'0','STR_PAD_LEFT');
00601                                         $firstpart = substr($binnet,0,$mask);
00602                                         $binip = str_pad( decbin($lip),32,'0','STR_PAD_LEFT');
00603                                         $firstip = substr($binip,0,$mask);
00604                                         $yes = (strcmp($firstpart,$firstip)==0);
00605                                 } else {
00606                                                 // "192.168.*.*"
00607                                         $IPparts = explode('.',$test);
00608                                         $yes = 1;
00609                                         reset($IPparts);
00610                                         while(list($index,$val)=each($IPparts)) {
00611                                                 $val = trim($val);
00612                                                 if (strcmp($val,'*') && strcmp($IPpartsReq[$index],$val))       {
00613                                                         $yes=0;
00614                                                 }
00615                                         }
00616                                 }
00617                                 if ($yes) return true;
00618                         }
00619                 }
00620                 return false;
00621         }
00622 
00630         function cmpFQDN($baseIP, $list)        {
00631                 if (count(explode('.',$baseIP))==4)     {
00632                         $resolvedHostName = explode('.', gethostbyaddr($baseIP));
00633                         $values = t3lib_div::trimExplode(',',$list,1);
00634 
00635                         foreach($values as $test)       {
00636                                 $hostNameParts = explode('.',$test);
00637                                 $yes = 1;
00638 
00639                                 foreach($hostNameParts as $index => $val)       {
00640                                         $val = trim($val);
00641                                         if (strcmp($val,'*') && strcmp($resolvedHostName[$index],$val)) {
00642                                                 $yes=0;
00643                                         }
00644                                 }
00645                                 if ($yes) return true;
00646                         }
00647                 }
00648                 return false;
00649         }
00650 
00660         function inList($list,$item)    {
00661                 return strstr(','.$list.',', ','.$item.',') ? true : false;
00662         }
00663 
00672         function rmFromList($element,$list)     {
00673                 $items = explode(',',$list);
00674                 while(list($k,$v)=each($items)) {
00675                         if ($v==$element)       {unset($items[$k]);}
00676                 }
00677                 return implode(',',$items);
00678         }
00679 
00688         function expandList($list)      {
00689                 $items = explode(',',$list);
00690                 $list = array();
00691                 while(list(,$item)=each($items))        {
00692                         $range = explode('-',$item);
00693                         if (isset($range[1]))   {
00694                                 $runAwayBrake = 1000;
00695                                 for ($n=$range[0]; $n<=$range[1]; $n++) {
00696                                         $list[] = $n;
00697 
00698                                         $runAwayBrake--;
00699                                         if ($runAwayBrake<=0)   break;
00700                                 }
00701                         } else {
00702                                 $list[] = $item;
00703                         }
00704                 }
00705 
00706                 return implode(',',$list);
00707         }
00708 
00719         function intInRange($theInt,$min,$max=2000000000,$zeroValue=0)  {
00720                 // Returns $theInt as an integer in the integerspace from $min to $max
00721                 $theInt = intval($theInt);
00722                 if ($zeroValue && !$theInt)     {$theInt=$zeroValue;}   // If the input value is zero after being converted to integer, zeroValue may set another default value for it.
00723                 if ($theInt<$min){$theInt=$min;}
00724                 if ($theInt>$max){$theInt=$max;}
00725                 return $theInt;
00726         }
00727 
00735         function intval_positive($theInt)       {
00736                 $theInt = intval($theInt);
00737                 if ($theInt<0){$theInt=0;}
00738                 return $theInt;
00739         }
00740 
00748         function int_from_ver($verNumberStr)    {
00749                 $verParts = explode('.',$verNumberStr);
00750                 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));
00751         }
00752 
00760         function md5int($str)   {
00761                 return hexdec(substr(md5($str),0,7));
00762         }
00763 
00773         function shortMD5($input, $len=10)      {
00774                 return substr(md5($input),0,$len);
00775         }
00776 
00786         function uniqueList($in_list, $secondParameter=NULL)    {
00787                 if (is_array($in_list)) die('t3lib_div::uniqueList() does NOT support array arguments anymore! Only string comma lists!');
00788                 if (isset($secondParameter))    die('t3lib_div::uniqueList() does NOT support more than a single argument value anymore. You have specified more than one.');
00789 
00790                 return implode(',',array_unique(t3lib_div::trimExplode(',',$in_list,1)));
00791         }
00792 
00800         function split_fileref($fileref)        {
00801                 if (    ereg('(.*/)(.*)$',$fileref,$reg)        )       {
00802                         $info['path'] = $reg[1];
00803                         $info['file'] = $reg[2];
00804                 } else {
00805                         $info['path'] = '';
00806                         $info['file'] = $fileref;
00807                 }
00808                 $reg='';
00809                 if (    ereg('(.*)\.([^\.]*$)',$info['file'],$reg)      )       {
00810                         $info['filebody'] = $reg[1];
00811                         $info['fileext'] = strtolower($reg[2]);
00812                         $info['realFileext'] = $reg[2];
00813                 } else {
00814                         $info['filebody'] = $info['file'];
00815                         $info['fileext'] = '';
00816                 }
00817                 reset($info);
00818                 return $info;
00819         }
00820 
00837         function dirname($path) {
00838                 $p=t3lib_div::revExplode('/',$path,2);
00839                 return count($p)==2?$p[0]:'';
00840         }
00841 
00853         function modifyHTMLColor($color,$R,$G,$B)       {
00854                 // This takes a hex-color (# included!) and adds $R, $G and $B to the HTML-color (format: #xxxxxx) and returns the new color
00855                 $nR = t3lib_div::intInRange(hexdec(substr($color,1,2))+$R,0,255);
00856                 $nG = t3lib_div::intInRange(hexdec(substr($color,3,2))+$G,0,255);
00857                 $nB = t3lib_div::intInRange(hexdec(substr($color,5,2))+$B,0,255);
00858                 return '#'.
00859                         substr('0'.dechex($nR),-2).
00860                         substr('0'.dechex($nG),-2).
00861                         substr('0'.dechex($nB),-2);
00862         }
00863 
00873         function modifyHTMLColorAll($color,$all)        {
00874                 return t3lib_div::modifyHTMLColor($color,$all,$all,$all);
00875         }
00876 
00884         function rm_endcomma($string)   {
00885                 return ereg_replace(',$','',$string);
00886         }
00887 
00897         function danish_strtoupper($string)     {
00898                 $value = strtoupper($string);
00899                 return strtr($value, 'áéúíâêûôîæøåäöü', 'ÁÉÚÍÄËÜÖÏÆØÅÄÖÜ');
00900         }
00901 
00912         function convUmlauts($str)      {
00913                 $pat  = array ( '/ä/',  '/Ä/',  '/ö/',  '/Ö/',  '/ü/',  '/Ü/',  '/ß/',  '/å/',  '/Å/',  '/ø/',  '/Ø/',  '/æ/',  '/Æ/'   );
00914                 $repl = array ( 'ae',   'Ae',   'oe',   'Oe',   'ue',   'Ue',   'ss',   'aa',   'AA',   'oe',   'OE',   'ae',   'AE'    );
00915                 return preg_replace($pat,$repl,$str);
00916         }
00917 
00925         function testInt($var)  {
00926                 return !strcmp($var,intval($var));
00927         }
00928 
00937         function isFirstPartOfStr($str,$partStr)        {
00938                 // Returns true, if the first part of a $str equals $partStr and $partStr is not ''
00939                 $psLen = strlen($partStr);
00940                 if ($psLen)     {
00941                         return substr($str,0,$psLen)==(string)$partStr;
00942                 } else return false;
00943         }
00944 
00953         function formatSize($sizeInBytes,$labels='')    {
00954 
00955                         // Set labels:
00956                 if (strlen($labels) == 0) {
00957                     $labels = ' | K| M| G';
00958                 } else {
00959                     $labels = str_replace('"','',$labels);
00960                 }
00961                 $labelArr = explode('|',$labels);
00962 
00963                         // Find size:
00964                 if ($sizeInBytes>900)   {
00965                         if ($sizeInBytes>900000000)     {       // GB
00966                                 $val = $sizeInBytes/(1024*1024*1024);
00967                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[3];
00968                         }
00969                         elseif ($sizeInBytes>900000)    {       // MB
00970                                 $val = $sizeInBytes/(1024*1024);
00971                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[2];
00972                         } else {        // KB
00973                                 $val = $sizeInBytes/(1024);
00974                                 return number_format($val, (($val<20)?1:0), '.', '').$labelArr[1];
00975                         }
00976                 } else {        // Bytes
00977                         return $sizeInBytes.$labelArr[0];
00978                 }
00979         }
00980 
00988         function convertMicrotime($microtime)   {
00989                 $parts = explode(' ',$microtime);
00990                 return round(($parts[0]+$parts[1])*1000);
00991         }
00992 
01002         function splitCalc($string,$operators)  {
01003                 $res = Array();
01004                 $sign='+';
01005                 while($string)  {
01006                         $valueLen=strcspn($string,$operators);
01007                         $value=substr($string,0,$valueLen);
01008                         $res[] = Array($sign,trim($value));
01009                         $sign=substr($string,$valueLen,1);
01010                         $string=substr($string,$valueLen+1);
01011                 }
01012                 reset($res);
01013                 return $res;
01014         }
01015 
01024         function calcPriority($string)  {
01025                 $string=ereg_replace('[[:space:]]*','',$string);        // removing all whitespace
01026                 $string='+'.$string;    // Ensuring an operator for the first entrance
01027                 $qm='\*\/\+-^%';
01028                 $regex = '(['.$qm.'])(['.$qm.']?[0-9\.]*)';
01029                         // split the expression here:
01030                 preg_match_all('/'.$regex.'/',$string,$reg);
01031 
01032                 reset($reg[2]);
01033                 $number=0;
01034                 $Msign='+';
01035                 $err='';
01036                 $buffer=doubleval(current($reg[2]));
01037                 next($reg[2]);  // Advance pointer
01038                 while(list($k,$v)=each($reg[2]))        {
01039                         $v=doubleval($v);
01040                         $sign = $reg[1][$k];
01041                         if ($sign=='+' || $sign=='-')   {
01042                                 $number = $Msign=='-' ? $number-=$buffer : $number+=$buffer;
01043                                 $Msign = $sign;
01044                                 $buffer=$v;
01045                         } else {
01046                                 if ($sign=='/') {if ($v) $buffer/=$v; else $err='dividing by zero';}
01047                                 if ($sign=='%') {if ($v) $buffer%=$v; else $err='dividing by zero';}
01048                                 if ($sign=='*') {$buffer*=$v;}
01049                                 if ($sign=='^') {$buffer=pow($buffer,$v);}
01050                         }
01051                 }
01052                 $number = $Msign=='-' ? $number-=$buffer : $number+=$buffer;
01053                 return $err ? 'ERROR: '.$err : $number;
01054         }
01055 
01064         function calcParenthesis($string)       {
01065                 $securC=100;
01066                 do {
01067                         $valueLenO=strcspn($string,'(');
01068                         $valueLenC=strcspn($string,')');
01069                         if ($valueLenC==strlen($string) || $valueLenC < $valueLenO)     {
01070                                 $value = t3lib_div::calcPriority(substr($string,0,$valueLenC));
01071                                 $string = $value.substr($string,$valueLenC+1);
01072                                 return $string;
01073                         } else {
01074                                 $string = substr($string,0,$valueLenO).t3lib_div::calcParenthesis(substr($string,$valueLenO+1));
01075                         }
01076                                 // Security:
01077                         $securC--;
01078                         if ($securC<=0) break;
01079                 } while($valueLenO<strlen($string));
01080                 return $string;
01081         }
01082 
01090         function htmlspecialchars_decode($value)        {
01091                 $value = str_replace('&gt;','>',$value);
01092                 $value = str_replace('&lt;','<',$value);
01093                 $value = str_replace('&quot;','"',$value);
01094                 $value = str_replace('&amp;','&',$value);
01095                 return $value;
01096         }
01097 
01105         function deHSCentities($str)    {
01106                 return ereg_replace('&amp;([#[:alnum:]]*;)','&\1',$str);
01107         }
01108 
01118         function slashJS($string,$extended=0,$char="'") {
01119                 if ($extended)  {$string = str_replace ("\\", "\\\\", $string);}
01120                 return str_replace ($char, "\\".$char, $string);
01121         }
01122 
01131         function rawUrlEncodeJS($str)   {
01132                 return str_replace('%20',' ',rawurlencode($str));
01133         }
01134 
01143         function rawUrlEncodeFP($str)   {
01144                 return str_replace('%2F','/',rawurlencode($str));
01145         }
01146 
01154         function validEmail($email)     {
01155                 $email = trim ($email);
01156                 if (strstr($email,' '))  return FALSE;
01157                 return ereg('^[A-Za-z0-9\._-]+[@][A-Za-z0-9\._-]+[\.].[A-Za-z0-9]+$',$email) ? TRUE : FALSE;
01158         }
01159 
01169         function formatForTextarea($content)    {
01170                 return chr(10).htmlspecialchars($content);
01171         }
01172 
01173 
01174 
01175 
01176 
01177 
01178 
01179 
01180 
01181 
01182 
01183 
01184         /*************************
01185          *
01186          * ARRAY FUNCTIONS
01187          *
01188          *************************/
01189 
01200         function inArray($in_array,$item)       {
01201                 if (is_array($in_array))        {
01202                         while (list(,$val)=each($in_array))     {
01203                                 if (!is_array($val) && !strcmp($val,$item)) return true;
01204                         }
01205                 }
01206         }
01207 
01217         function intExplode($delim, $string)    {
01218                 $temp = explode($delim,$string);
01219                 while(list($key,$val)=each($temp))      {
01220                         $temp[$key]=intval($val);
01221                 }
01222                 reset($temp);
01223                 return $temp;
01224         }
01225 
01236         function revExplode($delim, $string, $count=0)  {
01237                 $temp = explode($delim,strrev($string),$count);
01238                 while(list($key,$val)=each($temp))      {
01239                         $temp[$key]=strrev($val);
01240                 }
01241                 $temp=array_reverse($temp);
01242                 reset($temp);
01243                 return $temp;
01244         }
01245 
01256         function trimExplode($delim, $string, $onlyNonEmptyValues=0)    {
01257                 $temp = explode($delim,$string);
01258                 $newtemp=array();
01259                 while(list($key,$val)=each($temp))      {
01260                         if (!$onlyNonEmptyValues || strcmp('',trim($val)))      {
01261                                 $newtemp[]=trim($val);
01262                         }
01263                 }
01264                 reset($newtemp);
01265                 return $newtemp;
01266         }
01267 
01278         function uniqueArray($valueArray)       {
01279                 return array_unique($valueArray);
01280         }
01281 
01290         function removeArrayEntryByValue($array,$cmpValue)      {
01291                 if (is_array($array))   {
01292                         reset($array);
01293                         while(list($k,$v)=each($array)) {
01294                                 if (is_array($v))       {
01295                                         $array[$k] = t3lib_div::removeArrayEntryByValue($v,$cmpValue);
01296                                 } else {
01297                                         if (!strcmp($v,$cmpValue))      {
01298                                                 unset($array[$k]);
01299                                         }
01300                                 }
01301                         }
01302                 }
01303                 reset($array);
01304                 return $array;
01305         }
01306 
01319         function implodeArrayForUrl($name,$theArray,$str='',$skipBlank=0,$rawurlencodeParamName=0)      {
01320                 if (is_array($theArray))        {
01321                         foreach($theArray as $Akey => $AVal)    {
01322                                 $thisKeyName = $name ? $name.'['.$Akey.']' : $Akey;
01323                                 if (is_array($AVal))    {
01324                                         $str = t3lib_div::implodeArrayForUrl($thisKeyName,$AVal,$str,$skipBlank,$rawurlencodeParamName);
01325                                 } else {
01326                                         if (!$skipBlank || strcmp($AVal,''))    {
01327                                                 $str.='&'.($rawurlencodeParamName ? rawurlencode($thisKeyName) : $thisKeyName).
01328                                                         '='.rawurlencode($AVal);
01329                                         }
01330                                 }
01331                         }
01332                 }
01333                 return $str;
01334         }
01335 
01344         function explodeUrl2Array($string,$multidim=FALSE)      {
01345                 if ($multidim)  {
01346                         parse_str($string,$tempGetVars);
01347                         return $tempGetVars;
01348                 } else {
01349                         $output = array();
01350                         $p = explode('&',$string);
01351                         foreach($p as $v)       {
01352                                 if (strlen($v)) {
01353                                         list($pK,$pV) = explode('=',$v,2);
01354                                         $output[rawurldecode($pK)] = rawurldecode($pV);
01355                                 }
01356                         }
01357                         return $output;
01358                 }
01359         }
01360 
01371         function compileSelectedGetVarsFromArray($varList,$getArray,$GPvarAlt=1)        {
01372                 $keys = t3lib_div::trimExplode(',',$varList,1);
01373                 $outArr=array();
01374                 foreach($keys as $v)    {
01375                         if (isset($getArray[$v]))       {
01376                                 $outArr[$v]=$getArray[$v];
01377                         } elseif ($GPvarAlt) {
01378                                 $outArr[$v]=t3lib_div::_GP($v);
01379                         }
01380                 }
01381                 return $outArr;
01382         }
01383 
01394         function addSlashesOnArray(&$theArray)  {
01395                 if (is_array($theArray))        {
01396                         reset($theArray);
01397                         while(list($Akey,$AVal)=each($theArray))        {
01398                                 if (is_array($AVal))    {
01399                                         t3lib_div::addSlashesOnArray($theArray[$Akey]);
01400                                 } else {
01401                                         $theArray[$Akey] = addslashes($AVal);
01402                                 }
01403                         }
01404                         reset($theArray);
01405                 }
01406         }
01407 
01418         function stripSlashesOnArray(&$theArray)        {
01419                 if (is_array($theArray))        {
01420                         reset($theArray);
01421                         while(list($Akey,$AVal)=each($theArray))        {
01422                                 if (is_array($AVal))    {
01423                                         t3lib_div::stripSlashesOnArray($theArray[$Akey]);
01424                                 } else {
01425                                         $theArray[$Akey] = stripslashes($AVal);
01426                                 }
01427                         }
01428                         reset($theArray);
01429                 }
01430         }
01431 
01440         function slashArray($arr,$cmd)  {
01441                 if ($cmd=='strip')      t3lib_div::stripSlashesOnArray($arr);
01442                 if ($cmd=='add')        t3lib_div::addSlashesOnArray($arr);
01443                 return $arr;
01444         }
01445 
01457         function array_merge_recursive_overrule($arr0,$arr1,$notAddKeys=0,$includeEmtpyValues=true) {
01458                 reset($arr1);
01459                 while(list($key,$val) = each($arr1)) {
01460                         if(is_array($arr0[$key])) {
01461                                 if (is_array($arr1[$key]))      {
01462                                         $arr0[$key] = t3lib_div::array_merge_recursive_overrule($arr0[$key],$arr1[$key],$notAddKeys);
01463                                 }
01464                         } else {
01465                                 if ($notAddKeys) {
01466                                         if (isset($arr0[$key])) {
01467                                                 if ($includeEmtpyValues OR $val) {
01468                                                         $arr0[$key] = $val;
01469                                                 }
01470                                         }
01471                                 } else {
01472                                         if ($includeEmtpyValues OR $val) {
01473                                                 $arr0[$key] = $val;
01474                                         }
01475                                 }
01476                         }
01477                 }
01478                 reset($arr0);
01479                 return $arr0;
01480         }
01481 
01490         function array_merge($arr1,$arr2)       {
01491                 return $arr2+$arr1;
01492         }
01493 
01503         function csvValues($row,$delim=',',$quote='"')  {
01504                 reset($row);
01505                 $out=array();
01506                 while(list(,$value)=each($row)) {
01507                         list($valPart) = explode(chr(10),$value);
01508                         $valPart = trim($valPart);
01509                         $out[]=str_replace($quote,$quote.$quote,$valPart);
01510                 }
01511                 $str = $quote.implode($quote.$delim.$quote,$out).$quote;
01512                 return $str;
01513         }
01514 
01515 
01516 
01517 
01518 
01519 
01520 
01521 
01522 
01523 
01524 
01525 
01526 
01527 
01528 
01529 
01530         /*************************
01531          *
01532          * HTML/XML PROCESSING
01533          *
01534          *************************/
01535 
01545         function get_tag_attributes($tag)       {
01546                 $components = t3lib_div::split_tag_attributes($tag);
01547                 $name = '';      // attribute name is stored here
01548                 $valuemode = '';
01549                 if (is_array($components))      {
01550                         while (list($key,$val) = each ($components))    {
01551                                 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
01552                                         if ($valuemode) {
01553                                                 if ($name)      {
01554                                                         $attributes[$name] = $val;
01555                                                         $name = '';
01556                                                 }
01557                                         } else {
01558                                                 if ($key = strtolower(ereg_replace('[^a-zA-Z0-9]','',$val)))    {
01559                                                         $attributes[$key] = '';
01560                                                         $name = $key;
01561                                                 }
01562                                         }
01563                                         $valuemode = '';
01564                                 } else {
01565                                         $valuemode = 'on';
01566                                 }
01567                         }
01568                         if (is_array($attributes))      reset($attributes);
01569                         return $attributes;
01570                 }
01571         }
01572 
01582         function split_tag_attributes($tag)     {
01583                 $tag_tmp = trim(eregi_replace ('^<[^[:space:]]*','',trim($tag)));
01584                         // Removes any > in the end of the string
01585                 $tag_tmp = trim(eregi_replace ('>$','',$tag_tmp));
01586 
01587                 while (strcmp($tag_tmp,''))     {       // Compared with empty string instead , 030102
01588                         $firstChar=substr($tag_tmp,0,1);
01589                         if (!strcmp($firstChar,'"') || !strcmp($firstChar,"'")) {
01590                                 $reg=explode($firstChar,$tag_tmp,3);
01591                                 $value[]=$reg[1];
01592                                 $tag_tmp=trim($reg[2]);
01593                         } elseif (!strcmp($firstChar,'=')) {
01594                                 $value[] = '=';
01595                                 $tag_tmp = trim(substr($tag_tmp,1));            // Removes = chars.
01596                         } else {
01597                                         // There are '' around the value. We look for the next ' ' or '>'
01598                                 $reg = split('[[:space:]=]',$tag_tmp,2);
01599                                 $value[] = trim($reg[0]);
01600                                 $tag_tmp = trim(substr($tag_tmp,strlen($reg[0]),1).$reg[1]);
01601                         }
01602                 }
01603                 if (is_array($value))   reset($value);
01604                 return $value;
01605         }
01606 
01616         function implodeAttributes($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)   {
01617                 if (is_array($arr))     {
01618                         if ($xhtmlSafe) {
01619                                 $newArr=array();
01620                                 foreach($arr as $p => $v)       {
01621                                         if (!isset($newArr[strtolower($p)])) $newArr[strtolower($p)] = htmlspecialchars($v);
01622                                 }
01623                                 $arr = $newArr;
01624                         }
01625                         $list = array();
01626                         foreach($arr as $p => $v)       {
01627                                 if (strcmp($v,'') || $dontOmitBlankAttribs)     {$list[]=$p.'="'.$v.'"';}
01628                         }
01629                         return implode(' ',$list);
01630                 }
01631         }
01632 
01643         function implodeParams($arr,$xhtmlSafe=FALSE,$dontOmitBlankAttribs=FALSE)       {
01644                 return t3lib_div::implodeAttributes($arr,$xhtmlSafe,$dontOmitBlankAttribs);
01645         }
01646 
01658         function wrapJS($string, $linebreak=TRUE) {
01659                 if(trim($string)) {
01660                                 // <script wrapped in nl?
01661                         $cr = $linebreak? "\n" : '';
01662 
01663                                 // remove nl from the beginning
01664                         $string = preg_replace ('/^\n+/', '', $string);
01665                                 // re-ident to one tab using the first line as reference
01666                         if(preg_match('/^(\t+)/',$string,$match)) {
01667                                 $string = str_replace($match[1],"\t", $string);
01668                         }
01669                         $string = $cr.'<script type="text/javascript">
01670 /*<![CDATA[*/
01671 '.$string.'
01672 /*]]>*/
01673 </script>'.$cr;
01674                 }
01675                 return trim($string);
01676         }
01677 
01678 
01688         function xml2tree($string,$depth=999) {
01689                 $parser = xml_parser_create();
01690                 $vals = array();
01691                 $index = array();
01692 
01693                 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
01694                 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
01695                 xml_parse_into_struct($parser, $string, $vals, $index);
01696 
01697                 if (xml_get_error_code($parser))        return 'Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
01698                 xml_parser_free($parser);
01699 
01700                 $stack = array( array() );
01701                 $stacktop = 0;
01702                 $startPoint=0;
01703 
01704                 unset($tagi);
01705                 foreach($vals as $key => $val) {
01706                         $type = $val['type'];
01707 
01708                                 // open tag:
01709                         if ($type=='open' || $type=='complete') {
01710                                 $stack[$stacktop++] = $tagi;
01711 
01712                                 if ($depth==$stacktop)  {
01713                                         $startPoint=$key;
01714                                 }
01715 
01716                                 $tagi = array('tag' => $val['tag']);
01717 
01718                                 if(isset($val['attributes']))  $tagi['attrs'] = $val['attributes'];
01719                                 if(isset($val['value']))        $tagi['values'][] = $val['value'];
01720                         }
01721                                 // finish tag:
01722                         if ($type=='complete' || $type=='close')        {
01723                                 $oldtagi = $tagi;
01724                                 $tagi = $stack[--$stacktop];
01725                                 $oldtag = $oldtagi['tag'];
01726                                 unset($oldtagi['tag']);
01727 
01728                                 if ($depth==($stacktop+1))      {
01729                                         if ($key-$startPoint > 0)       {
01730                                                 $partArray = array_slice(
01731                                                         $vals,
01732                                                         $startPoint+1,
01733                                                         $key-$startPoint-1
01734                                                 );
01735                                                 #$oldtagi=array('XMLvalue'=>t3lib_div::xmlRecompileFromStructValArray($partArray));
01736                                                 $oldtagi['XMLvalue']=t3lib_div::xmlRecompileFromStructValArray($partArray);
01737                                         } else {
01738                                                 $oldtagi['XMLvalue']=$oldtagi['values'][0];
01739                                         }
01740                                 }
01741 
01742                                 $tagi['ch'][$oldtag][] = $oldtagi;
01743                                 unset($oldtagi);
01744                         }
01745                                 // cdata
01746                         if($type=='cdata') {
01747                                 $tagi['values'][] = $val['value'];
01748                         }
01749                 }
01750                 return $tagi['ch'];
01751         }
01752 
01774         function array2xml($array,$NSprefix='',$level=0,$docTag='phparray',$spaceInd=0, $options=array(),$stackData=array())    {
01775                         // 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
01776                 $binaryChars = chr(0).chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8).
01777                                                 chr(11).chr(12).chr(14).chr(15).chr(16).chr(17).chr(18).chr(19).
01778                                                 chr(20).chr(21).chr(22).chr(23).chr(24).chr(25).chr(26).chr(27).chr(28).chr(29).
01779                                                 chr(30).chr(31);
01780                         // Set indenting mode:
01781                 $indentChar = $spaceInd ? ' ' : chr(9);
01782                 $indentN = $spaceInd>0 ? $spaceInd : 1;
01783 
01784                         // Init output variable:
01785                 $output='';
01786 
01787                         // Traverse the input array
01788                 if (is_array($array))   {
01789                         foreach($array as $k=>$v)       {
01790                                 $attr = '';
01791                                 $tagName = $k;
01792 
01793                                         // Construct the tag name.
01794                                 if(isset($options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']])) {            // Use tag based on grand-parent + parent tag name
01795                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
01796                                         $tagName = (string)$options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']];
01797                                 }elseif(isset($options['parentTagMap'][$stackData['parentTagName'].':'.$tagName])) {            // Use tag based on parent tag name + current tag
01798                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
01799                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName'].':'.$tagName];
01800                                 } elseif(isset($options['parentTagMap'][$stackData['parentTagName']])) {                // Use tag based on parent tag name:
01801                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
01802                                         $tagName = (string)$options['parentTagMap'][$stackData['parentTagName']];
01803                                 } elseif (!strcmp(intval($tagName),$tagName))   {       // If integer...;
01804                                         if ($options['useNindex']) {    // If numeric key, prefix "n"
01805                                                 $tagName = 'n'.$tagName;
01806                                         } else {        // Use special tag for num. keys:
01807                                                 $attr.=' index="'.$tagName.'"';
01808                                                 $tagName = $options['useIndexTagForNum'] ? $options['useIndexTagForNum'] : 'numIndex';
01809                                         }
01810                                 } elseif($options['useIndexTagForAssoc']) {             // Use tag for all associative keys:
01811                                         $attr.=' index="'.htmlspecialchars($tagName).'"';
01812                                         $tagName = $options['useIndexTagForAssoc'];
01813                                 }
01814 
01815                                         // The tag name is cleaned up so only alphanumeric chars (plus - and _) are in there and not longer than 100 chars either.
01816                                 $tagName = substr(ereg_replace('[^[:alnum:]_-]','',$tagName),0,100);
01817 
01818                                         // If the value is an array then we will call this function recursively:
01819                                 if (is_array($v))       {
01820 
01821                                                 // Sub elements:
01822                                         if ($options['alt_options'][$stackData['path'].'/'.$tagName])   {
01823                                                 $subOptions = $options['alt_options'][$stackData['path'].'/'.$tagName];
01824                                                 $clearStackPath = $subOptions['clearStackPath'];
01825                                         } else {
01826                                                 $subOptions = $options;
01827                                                 $clearStackPath = FALSE;
01828                                         }
01829 
01830                                         $content = chr(10).
01831                                                                 t3lib_div::array2xml(
01832                                                                         $v,
01833                                                                         $NSprefix,
01834                                                                         $level+1,
01835                                                                         '',
01836                                                                         $spaceInd,
01837                                                                         $subOptions,
01838                                                                         array(
01839                                                                                 'parentTagName' => $tagName,
01840                                                                                 'grandParentTagName' => $stackData['parentTagName'],
01841                                                                                 'path' => $clearStackPath ? '' : $stackData['path'].'/'.$tagName,
01842                                                                         )
01843                                                                 ).
01844                                                                 str_pad('',($level+1)*$indentN,$indentChar);
01845                                         $attr.=' type="array"';
01846                                 } else {        // Just a value:
01847 
01848                                                 // Look for binary chars:
01849                                         if (strcspn($v,$binaryChars) != strlen($v))     {       // Go for base64 encoding if the initial segment NOT matching any binary char has the same length as the whole string!
01850                                                         // If the value contained binary chars then we base64-encode it an set an attribute to notify this situation:
01851                                                 $content = chr(10).chunk_split(base64_encode($v));
01852                                                 $attr.=' base64="1"';
01853                                         } else {
01854                                                         // Otherwise, just htmlspecialchar the stuff:
01855                                                 $content = htmlspecialchars($v);
01856                                                 $dType = gettype($v);
01857                                                 if ($dType!='string' && !$options['disableTypeAttrib']) { $attr.=' type="'.$dType.'"'; }
01858                                         }
01859                                 }
01860 
01861                                         // Add the element to the output string:
01862                                 $output.=str_pad('',($level+1)*$indentN,$indentChar).'<'.$NSprefix.$tagName.$attr.'>'.$content.'</'.$NSprefix.$tagName.'>'.chr(10);
01863                         }
01864                 }
01865 
01866                         // If we are at the outer-most level, then we finally wrap it all in the document tags and return that as the value:
01867                 if (!$level)    {
01868                         $output =
01869                                 '<'.$docTag.'>'.chr(10).
01870                                 $output.
01871                                 '</'.$docTag.'>';
01872                 }
01873 
01874                 return $output;
01875         }
01876 
01888         function xml2array($string,$NSprefix='',$reportDocTag=FALSE) {
01889                 global $TYPO3_CONF_VARS;
01890 
01891                         // Create parser:
01892                 $parser = xml_parser_create();
01893                 $vals = array();
01894                 $index = array();
01895 
01896                 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
01897                 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
01898 
01899                         // PHP5 fix of charset awareness:
01900                         // Problem is: PHP5 apparently detects the charset of the XML file (or defaults to utf-8) and will AUTOMATICALLY convert the content to either utf-8, iso-8859-1 or us-ascii. PHP4 just passed the content through without taking action regarding the charset.
01901                         // In TYPO3 we expect that the charset of XML content is NOT handled in the parser but internally in TYPO3 instead. Therefore it would be very nice if PHP5 could be configured to NOT process the charset of the files. But this is not possible for now.
01902                         // What we do here fixes the problem but ONLY if the charset is utf-8, iso-8859-1 or us-ascii. That should work for most TYPO3 installations, in particular if people use utf-8 which we highly recommend.
01903                 if ((double)phpversion()>=5)    {
01904                         unset($ereg_result);
01905                         ereg('^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"',substr($string,0,200),$ereg_result);
01906                         $theCharset = $ereg_result[1] ? $ereg_result[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1');
01907                         xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset);  // us-ascii / utf-8 / iso-8859-1
01908                 }
01909 
01910                         // Parse content:
01911                 xml_parse_into_struct($parser, $string, $vals, $index);
01912 
01913                         // If error, return error message:
01914                 if (xml_get_error_code($parser))        {
01915                         return 'Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
01916                 }
01917                 xml_parser_free($parser);
01918 
01919                         // Init vars:
01920                 $stack = array(array());
01921                 $stacktop = 0;
01922                 $current=array();
01923                 $tagName = '';
01924                 $documentTag = '';
01925 
01926                         // Traverse the parsed XML structure:
01927                 foreach($vals as $key => $val) {
01928 
01929                                 // First, process the tag-name (which is used in both cases, whether "complete" or "close")
01930                         $tagName = $val['tag'];
01931                         if (!$documentTag)      $documentTag = $tagName;
01932 
01933                                 // Test for name space:
01934                         $tagName = ($NSprefix && substr($tagName,0,strlen($NSprefix))==$NSprefix) ? substr($tagName,strlen($NSprefix)) : $tagName;
01935 
01936                                 // Test for numeric tag, encoded on the form "nXXX":
01937                         $testNtag = substr($tagName,1); // Closing tag.
01938                         $tagName = (substr($tagName,0,1)=='n' && !strcmp(intval($testNtag),$testNtag)) ? intval($testNtag) : $tagName;
01939 
01940                                 // Test for alternative index value:
01941                         if (strlen($val['attributes']['index']))        { $tagName = $val['attributes']['index']; }
01942 
01943                                 // Setting tag-values, manage stack:
01944                         switch($val['type'])    {
01945                                 case 'open':            // If open tag it means there is an array stored in sub-elements. Therefore increase the stackpointer and reset the accumulation array:
01946                                         $current[$tagName] = array();   // Setting blank place holder
01947                                         $stack[$stacktop++] = $current;
01948                                         $current = array();
01949                                 break;
01950                                 case 'close':   // If the tag is "close" then it is an array which is closing and we decrease the stack pointer.
01951                                         $oldCurrent = $current;
01952                                         $current = $stack[--$stacktop];
01953                                         end($current);  // Going to the end of array to get placeholder key, key($current), and fill in array next:
01954                                         $current[key($current)] = $oldCurrent;
01955                                         unset($oldCurrent);
01956                                 break;
01957                                 case 'complete':        // If "complete", then it's a value. If the attribute "base64" is set, then decode the value, otherwise just set it.
01958                                         if ($val['attributes']['base64'])       {
01959                                                 $current[$tagName] = base64_decode($val['value']);
01960                                         } else {
01961                                                 $current[$tagName] = (string)$val['value']; // Had to cast it as a string - otherwise it would be evaluate false if tested with isset()!!
01962 
01963                                                         // Cast type:
01964                                                 switch((string)$val['attributes']['type'])      {
01965                                                         case 'integer':
01966