[ Index ]
 

Code source de Typo3 4.1.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/t3lib/ -> class.t3lib_parsehtml_proc.php (source)

   1  <?php
   2  /***************************************************************
   3  *  Copyright notice
   4  *
   5  *  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
   6  *  All rights reserved
   7  *
   8  *  This script is part of the TYPO3 project. The TYPO3 project is
   9  *  free software; you can redistribute it and/or modify
  10  *  it under the terms of the GNU General Public License as published by
  11  *  the Free Software Foundation; either version 2 of the License, or
  12  *  (at your option) any later version.
  13  *
  14  *  The GNU General Public License can be found at
  15  *  http://www.gnu.org/copyleft/gpl.html.
  16  *  A copy is found in the textfile GPL.txt and important notices to the license
  17  *  from the author is found in LICENSE.txt distributed with these scripts.
  18  *
  19  *
  20  *  This script is distributed in the hope that it will be useful,
  21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23  *  GNU General Public License for more details.
  24  *
  25  *  This copyright notice MUST APPEAR in all copies of the script!
  26  ***************************************************************/
  27  /**
  28   * Functions for parsing HTML, specially for TYPO3 processing in relation to TCEmain and Rich Text Editor (RTE)
  29   *
  30   * $Id: class.t3lib_parsehtml_proc.php 1984 2007-02-04 21:13:28Z mundaun $
  31   * Revised for TYPO3 3.6 December/2003 by Kasper Skaarhoj
  32   * XHTML compatible.
  33   *
  34   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
  35   * @internal
  36   */
  37  /**
  38   * [CLASS/FUNCTION INDEX of SCRIPT]
  39   *
  40   *
  41   *
  42   *  103: class t3lib_parsehtml_proc extends t3lib_parsehtml
  43   *  138:     function init($elRef='',$recPid=0)
  44   *  150:     function setRelPath($path)
  45   *  174:     function evalWriteFile($pArr,$currentRecord)
  46   *
  47   *              SECTION: Main function
  48   *  232:     function RTE_transform($value,$specConf,$direction='rte',$thisConfig=array())
  49   *
  50   *              SECTION: Specific RTE TRANSFORMATION functions
  51   *  398:     function TS_images_db($value)
  52   *  550:     function TS_images_rte($value)
  53   *  589:     function TS_reglinks($value,$direction)
  54   *  626:     function TS_links_db($value)
  55   *  675:     function TS_links_rte($value)
  56   *  760:     function TS_preserve_db($value)
  57   *  784:     function TS_preserve_rte($value)
  58   *  805:     function TS_transform_db($value,$css=FALSE)
  59   *  922:     function transformStyledATags($value)
  60   *  948:     function TS_transform_rte($value,$css=0)
  61   * 1019:     function TS_strip_db($value)
  62   *
  63   *              SECTION: Generic RTE transformation, analysis and helper functions
  64   * 1050:     function getURL($url)
  65   * 1064:     function HTMLcleaner_db($content,$tagList='')
  66   * 1091:     function getKeepTags($direction='rte',$tagList='')
  67   * 1200:     function divideIntoLines($value,$count=5,$returnArray=FALSE)
  68   * 1304:     function setDivTags($value,$dT='p')
  69   * 1349:     function internalizeFontTags($value)
  70   * 1385:     function siteUrl()
  71   * 1395:     function rteImageStorageDir()
  72   * 1407:     function removeTables($value,$breakChar='<br />')
  73   * 1439:     function defaultTStagMapping($code,$direction='rte')
  74   * 1462:     function getWHFromAttribs($attribArray)
  75   * 1489:     function urlInfoForLinkTags($url)
  76   * 1548:     function TS_AtagToAbs($value,$dontSetRTEKEEP=FALSE)
  77   *
  78   * TOTAL FUNCTIONS: 28
  79   * (This index is automatically created/updated by the extension "extdeveval")
  80   *
  81   */
  82  
  83  require_once (PATH_t3lib.'class.t3lib_parsehtml.php');
  84  
  85  
  86  
  87  
  88  
  89  
  90  
  91  
  92  
  93  
  94  
  95  
  96  /**
  97   * Class for parsing HTML for the Rich Text Editor. (also called transformations)
  98   *
  99   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
 100   * @package TYPO3
 101   * @subpackage t3lib
 102   */
 103  class t3lib_parsehtml_proc extends t3lib_parsehtml {
 104  
 105          // Static:
 106      var $headListTags = 'PRE,UL,OL,H1,H2,H3,H4,H5,H6,HR,ADDRESS,DL';    // List of tags for these elements
 107  
 108          // Internal, static:
 109      var $recPid = 0;                // Set this to the pid of the record manipulated by the class.
 110      var $elRef = '';                // Element reference [table]:[field], eg. "tt_content:bodytext"
 111      var $relPath='';                // Relative path
 112      var $relBackPath='';            // Relative back-path
 113      var $procOptions = '';            // Set to the TSconfig options coming from Page TSconfig
 114  
 115          // Internal, dynamic
 116      var $TS_transform_db_safecounter=100;        // Run-away brake for recursive calls.
 117      var $rte_p='';                                // Parameters from TCA types configuration related to the RTE
 118      var $getKeepTags_cache=array();                // Data caching for processing function
 119      var $allowedClasses=array();                // Storage of the allowed CSS class names in the RTE
 120      var $preserveTags = '';                        // Set to tags to preserve from Page TSconfig configuration
 121  
 122  
 123  
 124  
 125  
 126  
 127  
 128  
 129  
 130  
 131      /**
 132       * Initialize, setting element reference and record PID
 133       *
 134       * @param    string        Element reference, eg "tt_content:bodytext"
 135       * @param    integer        PID of the record (page id)
 136       * @return    void
 137       */
 138  	function init($elRef='',$recPid=0)    {
 139          $this->recPid = $recPid;
 140          $this->elRef = $elRef;
 141      }
 142  
 143      /**
 144       * Setting the ->relPath and ->relBackPath to proper values so absolute references to links and images can be converted to relative dittos.
 145       * This is used when editing files with the RTE
 146       *
 147       * @param    string        The relative path from PATH_site to the place where the file being edited is. Eg. "fileadmin/static".
 148       * @return    void        There is no output, it is set in internal variables. With the above example of "fileadmin/static" as input this will yield ->relPath to be "fileadmin/static/" and ->relBackPath to be "../../"
 149       */
 150  	function setRelPath($path)    {
 151          $path = trim($path);
 152          $path = ereg_replace('^/','',$path);
 153          $path = ereg_replace('/$','',$path);
 154          if ($path)    {
 155              $this->relPath = $path;
 156              $this->relBackPath = '';
 157              $partsC=count(explode('/',$this->relPath));
 158              for ($a=0;$a<$partsC;$a++)    {
 159                  $this->relBackPath.='../';
 160              }
 161              $this->relPath.='/';
 162          }
 163      }
 164  
 165      /**
 166       * Evaluate the environment for editing a staticFileEdit file.
 167       * Called for almost all fields being saved in the database. Is called without an instance of the object: t3lib_parsehtml_proc::evalWriteFile()
 168       *
 169       * @param    array        Parameters for the current field as found in types-config
 170       * @param    array        Current record we are editing.
 171       * @return    mixed        On success an array with various information is returned, otherwise a string with an error message
 172       * @see t3lib_TCEmain, t3lib_transferData
 173       */
 174  	function evalWriteFile($pArr,$currentRecord)    {
 175  
 176              // Write file configuration:
 177          if (is_array($pArr))    {
 178              if ($GLOBALS['TYPO3_CONF_VARS']['BE']['staticFileEditPath']
 179                  && substr($GLOBALS['TYPO3_CONF_VARS']['BE']['staticFileEditPath'],-1)=='/'
 180                  && @is_dir(PATH_site.$GLOBALS['TYPO3_CONF_VARS']['BE']['staticFileEditPath']))    {
 181  
 182                  $SW_p = $pArr['parameters'];
 183                  $SW_editFileField = trim($SW_p[0]);
 184                  $SW_editFile = $currentRecord[$SW_editFileField];
 185                  if ($SW_editFileField && $SW_editFile && t3lib_div::validPathStr($SW_editFile))    {
 186                      $SW_relpath = $GLOBALS['TYPO3_CONF_VARS']['BE']['staticFileEditPath'].$SW_editFile;
 187                      $SW_editFile = PATH_site.$SW_relpath;
 188                      if (@is_file($SW_editFile))    {
 189                          return array(
 190                              'editFile' => $SW_editFile,
 191                              'relEditFile' => $SW_relpath,
 192                              'contentField' => trim($SW_p[1]),
 193                              'markerField' => trim($SW_p[2]),
 194                              'loadFromFileField' => trim($SW_p[3]),
 195                              'statusField' => trim($SW_p[4])
 196                          );
 197                      } else return "ERROR: Editfile '".$SW_relpath."' did not exist";
 198                  } else return "ERROR: Edit file name could not be found or was bad.";
 199              } else return "ERROR: staticFileEditPath was not set, not set correctly or did not exist!";
 200          }
 201      }
 202  
 203  
 204  
 205  
 206  
 207  
 208  
 209  
 210  
 211  
 212  
 213  
 214  
 215      /**********************************************
 216       *
 217       * Main function
 218       *
 219       **********************************************/
 220  
 221      /**
 222       * Transform value for RTE based on specConf in the direction specified by $direction (rte/db)
 223       * This is the main function called from tcemain and transfer data classes
 224       *
 225       * @param    string        Input value
 226       * @param    array        Special configuration for a field; This is coming from the types-configuration of the field in the TCA. In the types-configuration you can setup features for the field rendering and in particular the RTE takes al its major configuration options from there!
 227       * @param    string        Direction of the transformation. Two keywords are allowed; "db" or "rte". If "db" it means the transformation will clean up content coming from the Rich Text Editor and goes into the database. The other direction, "rte", is of course when content is coming from database and must be transformed to fit the RTE.
 228       * @param    array        Parsed TypoScript content configuring the RTE, probably coming from Page TSconfig.
 229       * @return    string        Output value
 230       * @see t3lib_TCEmain::fillInFieldArray(), t3lib_transferData::renderRecord_typesProc()
 231       */
 232  	function RTE_transform($value,$specConf,$direction='rte',$thisConfig=array())    {
 233  
 234              // Init:
 235          $this->procOptions = $thisConfig['proc.'];
 236          $this->preserveTags = strtoupper(implode(',',t3lib_div::trimExplode(',',$this->procOptions['preserveTags'])));
 237  
 238              // Get parameters for rte_transformation:
 239          $p = $this->rte_p = t3lib_BEfunc::getSpecConfParametersFromArray($specConf['rte_transform']['parameters']);
 240  
 241              // Setting modes:
 242          if (strcmp($this->procOptions['overruleMode'],''))    {
 243              $modes = array_unique(t3lib_div::trimExplode(',',$this->procOptions['overruleMode']));
 244          } else {
 245              $modes = array_unique(t3lib_div::trimExplode('-',$p['mode']));
 246          }
 247          $revmodes = array_flip($modes);
 248  
 249              // Find special modes and extract them:
 250          if (isset($revmodes['ts']))    {
 251              $modes[$revmodes['ts']] = 'ts_transform,ts_preserve,ts_images,ts_links';
 252          }
 253              // Find special modes and extract them:
 254          if (isset($revmodes['ts_css']))    {
 255              $modes[$revmodes['ts_css']] = 'css_transform,ts_images,ts_links';
 256          }
 257  
 258              // Make list unique
 259          $modes = array_unique(t3lib_div::trimExplode(',',implode(',',$modes),1));
 260  
 261              // Reverse order if direction is "rte"
 262          if ($direction=='rte')    {
 263              $modes = array_reverse($modes);
 264          }
 265  
 266              // Getting additional HTML cleaner configuration. These are applied either before or after the main transformation is done and is thus totally independant processing options you can set up:
 267          $entry_HTMLparser = $this->procOptions['entryHTMLparser_'.$direction] ? $this->HTMLparserConfig($this->procOptions['entryHTMLparser_'.$direction.'.']) : '';
 268          $exit_HTMLparser = $this->procOptions['exitHTMLparser_'.$direction] ? $this->HTMLparserConfig($this->procOptions['exitHTMLparser_'.$direction.'.']) : '';
 269  
 270              // Line breaks of content is unified into char-10 only (removing char 13)
 271          if (!$this->procOptions['disableUnifyLineBreaks'])    {
 272              $value = str_replace(chr(13).chr(10),chr(10),$value);
 273          }
 274  
 275              // In an entry-cleaner was configured, pass value through the HTMLcleaner with that:
 276          if (is_array($entry_HTMLparser))    {
 277              $value = $this->HTMLcleaner($value,$entry_HTMLparser[0],$entry_HTMLparser[1],$entry_HTMLparser[2],$entry_HTMLparser[3]);
 278          }
 279  
 280              // Traverse modes:
 281          foreach($modes as $cmd)    {
 282                  // ->DB
 283              if ($direction=='db')    {
 284                      // Checking for user defined transformation:
 285                  if ($_classRef = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_parsehtml_proc.php']['transformation'][$cmd])    {
 286                      $_procObj = &t3lib_div::getUserObj($_classRef);
 287                      $_procObj->pObj = &$this;
 288                      $_procObj->transformationKey = $cmd;
 289                      $value = $_procObj->transform_db($value,$this);
 290                  } else {    // ... else use defaults:
 291                      switch($cmd)    {
 292                          case 'ts_images':
 293                              $value = $this->TS_images_db($value);
 294                          break;
 295                          case 'ts_reglinks':
 296                              $value = $this->TS_reglinks($value,'db');
 297                          break;
 298                          case 'ts_links':
 299                              $value = $this->TS_links_db($value);
 300                          break;
 301                          case 'ts_preserve':
 302                              $value = $this->TS_preserve_db($value);
 303                          break;
 304                          case 'ts_transform':
 305                          case 'css_transform':
 306                              $value = str_replace(chr(13),'',$value);    // Has a very disturbing effect, so just remove all '13' - depend on '10'
 307                              $this->allowedClasses = t3lib_div::trimExplode(',',strtoupper($this->procOptions['allowedClasses']),1);
 308                              $value = $this->TS_transform_db($value,$cmd=='css_transform');
 309                          break;
 310                          case 'ts_strip':
 311                              $value = $this->TS_strip_db($value);
 312                          break;
 313                          default:
 314                          break;
 315                      }
 316                  }
 317              }
 318                  // ->RTE
 319              if ($direction=='rte')    {
 320                      // Checking for user defined transformation:
 321                  if ($_classRef = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_parsehtml_proc.php']['transformation'][$cmd])    {
 322                      $_procObj = &t3lib_div::getUserObj($_classRef);
 323                      $_procObj->pObj = &$this;
 324                      $value = $_procObj->transform_rte($value,$this);
 325                  } else {    // ... else use defaults:
 326                      switch($cmd)    {
 327                          case 'ts_images':
 328                              $value = $this->TS_images_rte($value);
 329                          break;
 330                          case 'ts_reglinks':
 331                              $value = $this->TS_reglinks($value,'rte');
 332                          break;
 333                          case 'ts_links':
 334                              $value = $this->TS_links_rte($value);
 335                          break;
 336                          case 'ts_preserve':
 337                              $value = $this->TS_preserve_rte($value);
 338                          break;
 339                          case 'ts_transform':
 340                          case 'css_transform':
 341                              $value = str_replace(chr(13),'',$value);    // Has a very disturbing effect, so just remove all '13' - depend on '10'
 342                              $value = $this->TS_transform_rte($value,$cmd=='css_transform');
 343                          break;
 344                          default:
 345                          break;
 346                      }
 347                  }
 348              }
 349          }
 350  
 351              // In an exit-cleaner was configured, pass value through the HTMLcleaner with that:
 352          if (is_array($exit_HTMLparser))    {
 353              $value = $this->HTMLcleaner($value,$exit_HTMLparser[0],$exit_HTMLparser[1],$exit_HTMLparser[2],$exit_HTMLparser[3]);
 354          }
 355  
 356              // Final clean up of linebreaks:
 357          if (!$this->procOptions['disableUnifyLineBreaks'])    {
 358              $value = str_replace(chr(13).chr(10),chr(10),$value);    // Make sure no \r\n sequences has entered in the meantime...
 359              $value = str_replace(chr(10),chr(13).chr(10),$value);    // ... and then change all \n into \r\n
 360          }
 361  
 362              // Return value:
 363          return $value;
 364      }
 365  
 366  
 367  
 368  
 369  
 370  
 371  
 372  
 373  
 374  
 375  
 376  
 377  
 378  
 379  
 380  
 381      /************************************
 382       *
 383       * Specific RTE TRANSFORMATION functions
 384       *
 385       *************************************/
 386  
 387      /**
 388       * Transformation handler: 'ts_images' / direction: "db"
 389       * Processing images inserted in the RTE.
 390       * This is used when content goes from the RTE to the database.
 391       * Images inserted in the RTE has an absolute URL applied to the src attribute. This URL is converted to a relative URL
 392       * If it turns out that the URL is from another website than the current the image is read from that external URL and moved to the local server.
 393       * Also "magic" images are processed here.
 394       *
 395       * @param    string        The content from RTE going to Database
 396       * @return    string        Processed content
 397       */
 398  	function TS_images_db($value)    {
 399  
 400              // Split content by <img> tags and traverse the resulting array for processing:
 401          $imgSplit = $this->splitTags('img',$value);
 402          foreach($imgSplit as $k => $v)    {
 403              if ($k%2)    {    // image found, do processing:
 404  
 405                      // Init
 406                  $attribArray = $this->get_tag_attributes_classic($v,1);
 407                  $siteUrl = $this->siteUrl();
 408                  $sitePath = str_replace (t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST'), '', $siteUrl);
 409  
 410                  $absRef = trim($attribArray['src']);        // It's always a absolute URL coming from the RTE into the Database.
 411  
 412                      // make path absolute if it is relative and we have a site path wich is not '/'
 413                  $pI=pathinfo($absRef);
 414                  if($sitePath AND !$pI['scheme'] && t3lib_div::isFirstPartOfStr($absRef,$sitePath)) {
 415                          // if site is in a subpath (eg. /~user_jim/) this path needs to be removed because it will be added with $siteUrl
 416                      $absRef = substr($absRef,strlen($sitePath));
 417                      $absRef = $siteUrl.$absRef;
 418                  }
 419  
 420                      // External image from another URL? In that case, fetch image (unless disabled feature).
 421                  if (!t3lib_div::isFirstPartOfStr($absRef,$siteUrl) && !$this->procOptions['dontFetchExtPictures'])    {
 422                      $externalFile = $this->getUrl($absRef);    // Get it
 423                      if ($externalFile)    {
 424                          $pU = parse_url($absRef);
 425                          $pI=pathinfo($pU['path']);
 426  
 427                          if (t3lib_div::inList('gif,png,jpeg,jpg',strtolower($pI['extension'])))    {
 428                              $filename = t3lib_div::shortMD5($absRef).'.'.$pI['extension'];
 429                              $origFilePath = PATH_site.$this->rteImageStorageDir().'RTEmagicP_'.$filename;
 430                              $C_origFilePath = PATH_site.$this->rteImageStorageDir().'RTEmagicC_'.$filename.'.'.$pI['extension'];
 431                              if (!@is_file($origFilePath))    {
 432                                  t3lib_div::writeFile($origFilePath,$externalFile);
 433                                  t3lib_div::writeFile($C_origFilePath,$externalFile);
 434                              }
 435                              $absRef = $siteUrl.$this->rteImageStorageDir().'RTEmagicC_'.$filename.'.'.$pI['extension'];
 436  
 437                              $attribArray['src']=$absRef;
 438                              $params = t3lib_div::implodeAttributes($attribArray,1);
 439                              $imgSplit[$k] = '<img '.$params.' />';
 440                          }
 441                      }
 442                  }
 443  
 444                      // Check image as local file (siteURL equals the one of the image)
 445                  if (t3lib_div::isFirstPartOfStr($absRef,$siteUrl))    {
 446                      $path = rawurldecode(substr($absRef,strlen($siteUrl)));    // Rel-path, rawurldecoded for special characters.
 447                      $filepath = t3lib_div::getFileAbsFileName($path);        // Abs filepath, locked to relative path of this project.
 448  
 449                          // Check file existence (in relative dir to this installation!)
 450                      if ($filepath && @is_file($filepath))    {
 451  
 452                              // If "magic image":
 453                          $pathPre=$this->rteImageStorageDir().'RTEmagicC_';
 454                          if (t3lib_div::isFirstPartOfStr($path,$pathPre))    {
 455                              // Find original file:
 456                              $pI=pathinfo(substr($path,strlen($pathPre)));
 457                              $filename = substr($pI['basename'],0,-strlen('.'.$pI['extension']));
 458                              $origFilePath = PATH_site.$this->rteImageStorageDir().'RTEmagicP_'.$filename;
 459                              if (@is_file($origFilePath))    {
 460                                  $imgObj = t3lib_div::makeInstance('t3lib_stdGraphic');
 461                                  $imgObj->init();
 462                                  $imgObj->mayScaleUp=0;
 463                                  $imgObj->tempPath=PATH_site.$imgObj->tempPath;
 464  
 465                                  $curInfo = $imgObj->getImageDimensions($filepath);    // Image dimensions of the current image
 466                                  $curWH = $this->getWHFromAttribs($attribArray);    // Image dimensions as set in the image tag
 467                                      // Compare dimensions:
 468                                  if ($curWH[0]!=$curInfo[0] || $curWH[1]!=$curInfo[1])    {
 469                                      $origImgInfo = $imgObj->getImageDimensions($origFilePath);    // Image dimensions of the current image
 470                                      $cW = $curWH[0];
 471                                      $cH = $curWH[1];
 472                                          $cH = 1000;    // Make the image based on the width solely...
 473                                      $imgI = $imgObj->imageMagickConvert($origFilePath,$pI['extension'],$cW.'m',$cH.'m');
 474                                      if ($imgI[3])    {
 475                                          $fI=pathinfo($imgI[3]);
 476                                          @copy($imgI[3],$filepath);    // Override the child file
 477                                          unset($attribArray['style']);
 478                                          $attribArray['width']=$imgI[0];
 479                                          $attribArray['height']=$imgI[1];
 480                                          if (!$attribArray['border'])    $attribArray['border']=0;
 481                                          $params = t3lib_div::implodeAttributes($attribArray,1);
 482                                          $imgSplit[$k]='<img '.$params.' />';
 483                                      }
 484                                  }
 485                              }
 486  
 487                          } elseif ($this->procOptions['plainImageMode']) {    // If "plain image" has been configured:
 488  
 489                                  // Image dimensions as set in the image tag
 490                              $curWH = $this->getWHFromAttribs($attribArray);
 491                              $attribArray['width'] = $curWH[0];
 492                              $attribArray['height'] = $curWH[1];
 493  
 494                                  // Forcing values for style and border:
 495                              unset($attribArray['style']);
 496                              if (!$attribArray['border'])    $attribArray['border'] = 0;
 497  
 498                                  // Finding dimensions of image file:
 499                              $fI = @getimagesize($filepath);
 500  
 501                                  // Perform corrections to aspect ratio based on configuration:
 502                              switch((string)$this->procOptions['plainImageMode'])    {
 503                                  case 'lockDimensions':
 504                                      $attribArray['width']=$fI[0];
 505                                      $attribArray['height']=$fI[1];
 506                                  break;
 507                                  case 'lockRatioWhenSmaller':    // If the ratio has to be smaller, then first set the width...:
 508                                      if ($attribArray['width']>$fI[0])    $attribArray['width'] = $fI[0];
 509                                  case 'lockRatio':
 510                                      if ($fI[0]>0)    {
 511                                          $attribArray['height']=round($attribArray['width']*($fI[1]/$fI[0]));
 512                                      }
 513                                  break;
 514                              }
 515  
 516                                  // Compile the image tag again:
 517                              $params = t3lib_div::implodeAttributes($attribArray,1);
 518                              $imgSplit[$k]='<img '.$params.' />';
 519                          }
 520                      } else {    // Remove image if it was not found in a proper position on the server!
 521  
 522                              // Commented out; removing the image tag might not be that logical...
 523                          #$imgSplit[$k]='';
 524                      }
 525                  }
 526  
 527                      // Convert abs to rel url
 528                  if ($imgSplit[$k])    {
 529                      $attribArray=$this->get_tag_attributes_classic($imgSplit[$k],1);
 530                      $absRef = trim($attribArray['src']);
 531                      if (t3lib_div::isFirstPartOfStr($absRef,$siteUrl))    {
 532                          $attribArray['src'] = $this->relBackPath.substr($absRef,strlen($siteUrl));
 533                          if (!isset($attribArray['alt']))    $attribArray['alt']='';        // Must have alt-attribute for XHTML compliance.
 534                          $imgSplit[$k]='<img '.t3lib_div::implodeAttributes($attribArray,1,1).' />';
 535                      }
 536                  }
 537              }
 538          }
 539          return implode('',$imgSplit);
 540      }
 541  
 542      /**
 543       * Transformation handler: 'ts_images' / direction: "rte"
 544       * Processing images from database content going into the RTE.
 545       * Processing includes converting the src attribute to an absolute URL.
 546       *
 547       * @param    string        Content input
 548       * @return    string        Content output
 549       */
 550  	function TS_images_rte($value)    {
 551  
 552          $siteUrl = $this->siteUrl();
 553          $sitePath = str_replace (t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST'), '', $siteUrl);
 554  
 555              // Split content by <img> tags and traverse the resulting array for processing:
 556          $imgSplit = $this->splitTags('img',$value);
 557          foreach($imgSplit as $k => $v)    {
 558              if ($k%2)    {    // image found:
 559  
 560                      // Init
 561                  $attribArray=$this->get_tag_attributes_classic($v,1);
 562                  $absRef = trim($attribArray['src']);
 563  
 564                      // Unless the src attribute is already pointing to an external URL:
 565                  if (strtolower(substr($absRef,0,4))!='http')    {
 566                      $attribArray['src'] = substr($attribArray['src'],strlen($this->relBackPath));
 567                          // if site is in a subpath (eg. /~user_jim/) this path needs to be removed because it will be added with $siteUrl
 568                      $attribArray['src'] = preg_replace('#^'.preg_quote($sitePath,'#').'#','',$attribArray['src']);
 569                      $attribArray['src'] = $siteUrl.$attribArray['src'];
 570                      if (!isset($attribArray['alt']))    $attribArray['alt']='';
 571                      $params = t3lib_div::implodeAttributes($attribArray);
 572                      $imgSplit[$k]='<img '.$params.' />';
 573                  }
 574              }
 575          }
 576  
 577              // return processed content:
 578          return implode('',$imgSplit);
 579      }
 580  
 581      /**
 582       * Transformation handler: 'ts_reglinks' / direction: "db"+"rte" depending on $direction variable.
 583       * Converting <A>-tags to/from abs/rel
 584       *
 585       * @param    string        Content input
 586       * @param    string        Direction of conversion; "rte" (from database to RTE) or "db" (from RTE to database)
 587       * @return    string        Content output
 588       */
 589  	function TS_reglinks($value,$direction)        {
 590          $retVal = '';
 591  
 592          switch($direction)    {
 593              case 'rte':
 594                  $retVal = $this->TS_AtagToAbs($value,1);
 595              break;
 596              case 'db':
 597                  $siteURL = $this->siteUrl();
 598                  $blockSplit = $this->splitIntoBlock('A',$value);
 599                  reset($blockSplit);
 600                  while(list($k,$v)=each($blockSplit))    {
 601                      if ($k%2)    {    // block:
 602                          $attribArray=$this->get_tag_attributes_classic($this->getFirstTag($v),1);
 603                              // If the url is local, remove url-prefix
 604                          if ($siteURL && substr($attribArray['href'],0,strlen($siteURL))==$siteURL)    {
 605                              $attribArray['href']=$this->relBackPath.substr($attribArray['href'],strlen($siteURL));
 606                          }
 607                          $bTag='<a '.t3lib_div::implodeAttributes($attribArray,1).'>';
 608                          $eTag='</a>';
 609                          $blockSplit[$k] = $bTag.$this->TS_reglinks($this->removeFirstAndLastTag($blockSplit[$k]),$direction).$eTag;
 610                      }
 611                  }
 612                  $retVal = implode('',$blockSplit);
 613              break;
 614          }
 615          return $retVal;
 616      }
 617  
 618      /**
 619       * Transformation handler: 'ts_links' / direction: "db"
 620       * Converting <A>-tags to <link tags>
 621       *
 622       * @param    string        Content input
 623       * @return    string        Content output
 624       * @see TS_links_rte()
 625       */
 626  	function TS_links_db($value)    {
 627  
 628              // Split content into <a> tag blocks and process:
 629          $blockSplit = $this->splitIntoBlock('A',$value);
 630          foreach($blockSplit as $k => $v)    {
 631              if ($k%2)    {    // If an A-tag was found:
 632                  $attribArray = $this->get_tag_attributes_classic($this->getFirstTag($v),1);
 633                  $info = $this->urlInfoForLinkTags($attribArray['href']);
 634  
 635                      // Check options:
 636                  $attribArray_copy = $attribArray;
 637                  unset($attribArray_copy['href']);
 638                  unset($attribArray_copy['target']);
 639                  unset($attribArray_copy['class']);
 640                  unset($attribArray_copy['title']);
 641                  if ($attribArray_copy['rteerror'])    {    // Unset "rteerror" and "style" attributes if "rteerror" is set!
 642                      unset($attribArray_copy['style']);
 643                      unset($attribArray_copy['rteerror']);
 644                  }
 645                  if (!count($attribArray_copy))    {    // Only if href, target and class are the only attributes, we can alter the link!
 646                          // Creating the TYPO3 pseudo-tag "<LINK>" for the link (includes href/url, target and class attributes):
 647                      $bTag='<link '.$info['url'].($attribArray['target']?' '.$attribArray['target']:(($attribArray['class'] || $attribArray['title'])?' -':'')).($attribArray['class']?' '.$attribArray['class']:($attribArray['title']?' -':'')).($attribArray['title']?' "'.$attribArray['title'].'"':'').'>';
 648                      $eTag='</link>';
 649                      $blockSplit[$k] = $bTag.$this->TS_links_db($this->removeFirstAndLastTag($blockSplit[$k])).$eTag;
 650                  } else {    // ... otherwise store the link as a-tag.
 651                          // Unsetting 'rtekeep' attribute if that had been set.
 652                      unset($attribArray['rtekeep']);
 653                          // If the url is local, remove url-prefix
 654                      $siteURL = $this->siteUrl();
 655                      if ($siteURL && substr($attribArray['href'],0,strlen($siteURL))==$siteURL)    {
 656                          $attribArray['href']=$this->relBackPath.substr($attribArray['href'],strlen($siteURL));
 657                      }
 658                      $bTag='<a '.t3lib_div::implodeAttributes($attribArray,1).'>';
 659                      $eTag='</a>';
 660                      $blockSplit[$k] = $bTag.$this->TS_links_db($this->removeFirstAndLastTag($blockSplit[$k])).$eTag;
 661                  }
 662              }
 663          }
 664          return implode('',$blockSplit);
 665      }
 666  
 667      /**
 668       * Transformation handler: 'ts_links' / direction: "rte"
 669       * Converting <link tags> to <A>-tags
 670       *
 671       * @param    string        Content input
 672       * @return    string        Content output
 673       * @see TS_links_rte()
 674       */
 675  	function TS_links_rte($value)    {
 676          $value = $this->TS_AtagToAbs($value);
 677  
 678              // Split content by the TYPO3 pseudo tag "<link>":
 679          $blockSplit = $this->splitIntoBlock('link',$value,1);
 680          foreach($blockSplit as $k => $v)    {
 681              $error = '';
 682              if ($k%2)    {    // block:
 683                  $tagCode = t3lib_div::unQuoteFilenames(trim(substr($this->getFirstTag($v),0,-1)),true);
 684                  $link_param = $tagCode[1];
 685                  $href = '';
 686                  $siteUrl = $this->siteUrl();
 687                      // Parsing the typolink data. This parsing is roughly done like in tslib_content->typolink()
 688                  if(strstr($link_param,'@'))    {        // mailadr
 689                      $href = 'mailto:'.eregi_replace('^mailto:','',$link_param);
 690                  } elseif (substr($link_param,0,1)=='#') {    // check if anchor
 691                      $href = $siteUrl.$link_param;
 692                  } else {
 693                      $fileChar=intval(strpos($link_param, '/'));
 694                      $urlChar=intval(strpos($link_param, '.'));
 695  
 696                          // Detects if a file is found in site-root OR is a simulateStaticDocument.
 697                      list($rootFileDat) = explode('?',$link_param);
 698                      $rFD_fI = pathinfo($rootFileDat);
 699                      if (trim($rootFileDat) && !strstr($link_param,'/') && (@is_file(PATH_site.$rootFileDat) || t3lib_div::inList('php,html,htm',strtolower($rFD_fI['extension']))))    {
 700                          $href = $siteUrl.$link_param;
 701                      } elseif($urlChar && (strstr($link_param,'//') || !$fileChar || $urlChar<$fileChar))    {    // url (external): If doubleSlash or if a '.' comes before a '/'.
 702                          if (!ereg('^[a-z]*://',trim(strtolower($link_param))))    {$scheme='http://';} else {$scheme='';}
 703                          $href = $scheme.$link_param;
 704                      } elseif($fileChar)    {    // file (internal)
 705                          $href = $siteUrl.$link_param;
 706                      } else {    // integer or alias (alias is without slashes or periods or commas, that is 'nospace,alphanum_x,lower,unique' according to tables.php!!)
 707                          $link_params_parts = explode('#',$link_param);
 708                          $idPart = trim($link_params_parts[0]);        // Link-data del
 709                          if (!strcmp($idPart,''))    { $idPart=$this->recPid; }    // If no id or alias is given, set it to class record pid
 710  
 711  // FIXME commented because useless - what is it for?
 712  //                        if ($link_params_parts[1] && !$sectionMark)    {
 713  //                            $sectionMark = '#'.trim($link_params_parts[1]);
 714  //                        }
 715  
 716                              // Splitting the parameter by ',' and if the array counts more than 1 element it's a id/type/? pair
 717                          $pairParts = t3lib_div::trimExplode(',',$idPart);
 718                          if (count($pairParts)>1)    {
 719                              $idPart = $pairParts[0];
 720                              // Type ? future support for?
 721                          }
 722                              // Checking if the id-parameter is an alias.
 723                          if (!t3lib_div::testInt($idPart))    {
 724                              list($idPartR) = t3lib_BEfunc::getRecordsByField('pages','alias',$idPart);
 725                              $idPart = intval($idPartR['uid']);
 726                          }
 727                          $page = t3lib_BEfunc::getRecord('pages', $idPart);
 728                          if (is_array($page))    {    // Page must exist...
 729                              $href = $siteUrl.'?id='.$link_param;
 730                          } else {
 731                              #$href = '';
 732                              $href = $siteUrl.'?id='.$link_param;
 733                              $error = 'No page found: '.$idPart;
 734                          }
 735                      }
 736                  }
 737  
 738                  // Setting the A-tag:
 739                  $bTag = '<a href="'.htmlspecialchars($href).'"'.
 740                              ($tagCode[2]&&$tagCode[2]!='-' ? ' target="'.htmlspecialchars($tagCode[2]).'"' : '').
 741                              ($tagCode[3]&&$tagCode[3]!='-' ? ' class="'.htmlspecialchars($tagCode[3]).'"' : '').
 742                              ($tagCode[4] ? ' title="'.htmlspecialchars($tagCode[4]).'"' : '').
 743                              ($error ? ' rteerror="'.htmlspecialchars($error).'" style="background-color: yellow; border:2px red solid; color: black;"' : '').    // Should be OK to add the style; the transformation back to databsae will remove it...
 744                              '>';
 745                  $eTag = '</a>';
 746                  $blockSplit[$k] = $bTag.$this->TS_links_rte($this->removeFirstAndLastTag($blockSplit[$k])).$eTag;
 747              }
 748          }
 749  
 750              // Return content:
 751          return implode('',$blockSplit);
 752      }
 753  
 754      /**
 755       * Preserve special tags
 756       *
 757       * @param    string        Content input
 758       * @return    string        Content output
 759       */
 760  	function TS_preserve_db($value)    {
 761          if (!$this->preserveTags)    return $value;
 762  
 763              // Splitting into blocks for processing (span-tags are used for special tags)
 764          $blockSplit = $this->splitIntoBlock('span',$value);
 765          foreach($blockSplit as $k => $v)    {
 766              if ($k%2)    {    // block:
 767                  $attribArray=$this->get_tag_attributes_classic($this->getFirstTag($v));
 768                  if ($attribArray['specialtag'])    {
 769                      $theTag = rawurldecode($attribArray['specialtag']);
 770                      $theTagName = $this->getFirstTagName($theTag);
 771                      $blockSplit[$k] = $theTag.$this->removeFirstAndLastTag($blockSplit[$k]).'</'.$theTagName.'>';
 772                  }
 773              }
 774          }
 775          return implode('',$blockSplit);
 776      }
 777  
 778      /**
 779       * Preserve special tags
 780       *
 781       * @param    string        Content input
 782       * @return    string        Content output
 783       */
 784  	function TS_preserve_rte($value)    {
 785          if (!$this->preserveTags)    return $value;
 786  
 787          $blockSplit = $this->splitIntoBlock($this->preserveTags,$value);
 788          foreach($blockSplit as $k => $v)    {
 789              if ($k%2)    {    // block:
 790                  $blockSplit[$k] = '<span specialtag="'.rawurlencode($this->getFirstTag($v)).'">'.$this->removeFirstAndLastTag($blockSplit[$k]).'</span>';
 791              }
 792          }
 793          return implode('',$blockSplit);
 794      }
 795  
 796      /**
 797       * Transformation handler: 'ts_transform' + 'css_transform' / direction: "db"
 798       * Cleaning (->db) for standard content elements (ts)
 799       *
 800       * @param    string        Content input
 801       * @param    boolean        If true, the transformation was "css_transform", otherwise "ts_transform"
 802       * @return    string        Content output
 803       * @see TS_transform_rte()
 804       */
 805  	function TS_transform_db($value,$css=FALSE)    {
 806  
 807              // safety... so forever loops are avoided (they should not occur, but an error would potentially do this...)
 808          $this->TS_transform_db_safecounter--;
 809          if ($this->TS_transform_db_safecounter<0)    return $value;
 810  
 811              // Split the content from RTE by the occurence of these blocks:
 812          $blockSplit = $this->splitIntoBlock('TABLE,BLOCKQUOTE,'.$this->headListTags,$value);
 813  
 814          $cc=0;
 815          $aC = count($blockSplit);
 816  
 817              // Avoid superfluous linebreaks by transform_db after ending headListTag
 818          while($aC && !strcmp(trim($blockSplit[$aC-1]),''))    {
 819              unset($blockSplit[$aC-1]);
 820              $aC = count($blockSplit);
 821          }
 822  
 823              // Traverse the blocks
 824          foreach($blockSplit as $k => $v)    {
 825              $cc++;
 826              $lastBR = $cc==$aC ? '' : chr(10);
 827  
 828              if ($k%2)    {    // Inside block:
 829  
 830                      // Init:
 831                  $tag=$this->getFirstTag($v);
 832                  $tagName=strtolower($this->getFirstTagName($v));
 833  
 834                      // Process based on the tag:
 835                  switch($tagName)    {
 836                      case 'blockquote':    // Keep blockquotes, but clean the inside recursively in the same manner as the main code
 837                          $blockSplit[$k]='<'.$tagName.'>'.$this->TS_transform_db($this->removeFirstAndLastTag($blockSplit[$k]),$css).'</'.$tagName.'>'.$lastBR;
 838                      break;
 839                      case 'ol':
 840                      case 'ul':    // Transform lists into <typolist>-tags:
 841                          if (!$css)    {
 842                              if (!isset($this->procOptions['typolist']) || $this->procOptions['typolist'])    {
 843                                  $parts = $this->getAllParts($this->splitIntoBlock('LI',$this->removeFirstAndLastTag($blockSplit[$k])),1,0);
 844                                  while(list($k2)=each($parts))    {
 845                                      $parts[$k2]=preg_replace('/['.preg_quote(chr(10).chr(13)).']+/','',$parts[$k2]);    // remove all linesbreaks!
 846                                      $parts[$k2]=$this->defaultTStagMapping($parts[$k2],'db');
 847                                      $parts[$k2]=$this->cleanFontTags($parts[$k2],0,0,0);
 848                                      $parts[$k2] = $this->HTMLcleaner_db($parts[$k2],strtolower($this->procOptions['allowTagsInTypolists']?$this->procOptions['allowTagsInTypolists']:'br,font,b,i,u,a,img,span,strong,em'));
 849                                  }
 850                                  if ($tagName=='ol')    { $params=' type="1"'; } else { $params=''; }
 851                                  $blockSplit[$k]='<typolist'.$params.'>'.chr(10).implode(chr(10),$parts).chr(10).'</typolist>'.$lastBR;
 852                              }
 853                          } else {
 854                              $blockSplit[$k]=preg_replace('/['.preg_quote(chr(10).chr(13)).']+/',' ',$this->transformStyledATags($blockSplit[$k])).$lastBR;
 855                          }
 856                      break;
 857                      case 'table':    // Tables are NOT allowed in any form (unless preserveTables is set or CSS is the mode)
 858                          if (!$this->procOptions['preserveTables'] && !$css)    {
 859                              $blockSplit[$k]=$this->TS_transform_db($this->removeTables($blockSplit[$k]));
 860                          } else {
 861                              $blockSplit[$k]=preg_replace('/['.preg_quote(chr(10).chr(13)).']+/',' ',$this->transformStyledATags($blockSplit[$k])).$lastBR;
 862                          }
 863                      break;
 864                      case 'h1':
 865                      case 'h2':
 866                      case 'h3':
 867                      case 'h4':
 868                      case 'h5':
 869                      case 'h6':
 870                          if (!$css)    {
 871                              $attribArray=$this->get_tag_attributes_classic($tag);
 872                                  // Processing inner content here:
 873                              $innerContent = $this->HTMLcleaner_db($this->removeFirstAndLastTag($blockSplit[$k]));
 874  
 875                              if (!isset($this->procOptions['typohead']) || $this->procOptions['typohead'])    {
 876                                  $type = intval(substr($tagName,1));
 877                                  $blockSplit[$k]='<typohead'.
 878                                                  ($type!=6?' type="'.$type.'"':'').
 879                                                  ($attribArray['align']?' align="'.$attribArray['align'].'"':'').
 880                                                  ($attribArray['class']?' class="'.$attribArray['class'].'"':'').
 881                                                  '>'.
 882                                                  $innerContent.
 883                                                  '</typohead>'.
 884                                                  $lastBR;
 885                              } else {
 886                                  $blockSplit[$k]='<'.$tagName.
 887                                                  ($attribArray['align']?' align="'.htmlspecialchars($attribArray['align']).'"':'').
 888                                                  ($attribArray['class']?' class="'.htmlspecialchars($attribArray['class']).'"':'').
 889                                                  '>'.
 890                                                  $innerContent.
 891                                                  '</'.$tagName.'>'.
 892                                                  $lastBR;
 893                              }
 894                          } else {
 895                                  // Eliminate true linebreaks inside Hx tags
 896                              $blockSplit[$k]=preg_replace('/['.preg_quote(chr(10).chr(13)).']+/',' ',$this->transformStyledATags($blockSplit[$k])).$lastBR;
 897                          }
 898                      break;
 899                      default:
 900                              // Eliminate true linebreaks inside other headlist tags and after hr tag
 901                          $blockSplit[$k]=preg_replace('/['.preg_quote(chr(10).chr(13)).']+/',' ',$this->transformStyledATags($blockSplit[$k])).$lastBR;
 902                      break;
 903                  }
 904              } else {    // NON-block:
 905                  if (strcmp(trim($blockSplit[$k]),''))    {
 906                      $blockSplit[$k]=$this->divideIntoLines(preg_replace('/['.preg_quote(chr(10).chr(13)).']+/',' ',$blockSplit[$k])).$lastBR;
 907                      $blockSplit[$k]=$this->transformStyledATags($blockSplit[$k]);
 908                  } else unset($blockSplit[$k]);
 909              }
 910          }
 911          $this->TS_transform_db_safecounter++;
 912  
 913          return implode('',$blockSplit);
 914      }
 915  
 916      /**
 917       * Wraps a-tags that contain a style attribute with a span-tag
 918       *
 919       * @param    string        Content input
 920       * @return    string        Content output
 921       */
 922  	function transformStyledATags($value)    {
 923          $blockSplit = $this->splitIntoBlock('A',$value);
 924          foreach($blockSplit as $k => $v)    {
 925              if ($k%2)    {    // If an A-tag was found:
 926                  $attribArray = $this->get_tag_attributes_classic($this->getFirstTag($v),1);
 927                  if ($attribArray['style'])    {    // If "style" attribute is set!
 928                      $attribArray_copy['style'] = $attribArray['style'];
 929                      unset($attribArray['style']);
 930                      $bTag='<span '.t3lib_div::implodeAttributes($attribArray_copy,1).'><a '.t3lib_div::implodeAttributes($attribArray,1).'>';
 931                      $eTag='</a></span>';
 932                      $blockSplit[$k] = $bTag.$this->removeFirstAndLastTag($blockSplit[$k]).$eTag;
 933                  }
 934              }
 935          }
 936          return implode('',$blockSplit);
 937      }
 938  
 939      /**
 940       * Transformation handler: 'ts_transform' + 'css_transform' / direction: "rte"
 941       * Set (->rte) for standard content elements (ts)
 942       *
 943       * @param    string        Content input
 944       * @param    boolean        If true, the transformation was "css_transform", otherwise "ts_transform"
 945       * @return    string        Content output
 946       * @see TS_transform_db()
 947       */
 948  	function TS_transform_rte($value,$css=0)    {
 949  
 950              // Split the content from Database by the occurence of these blocks:
 951          $blockSplit = $this->splitIntoBlock('TABLE,BLOCKQUOTE,TYPOLIST,TYPOHEAD,'.$this->headListTags,$value);
 952  
 953              // Traverse the blocks
 954          foreach($blockSplit as $k => $v)    {
 955              if ($k%2)    {    // Inside one of the blocks:
 956  
 957                      // Init:
 958                  $tag = $this->getFirstTag($v);
 959                  $tagName = strtolower($this->getFirstTagName($v));
 960                  $attribArray = $this->get_tag_attributes_classic($tag);
 961  
 962                      // Based on tagname, we do transformations:
 963                  switch($tagName)    {
 964                      case 'blockquote':    // Keep blockquotes:
 965                          $blockSplit[$k] = $tag.
 966                                              $this->TS_transform_rte($this->removeFirstAndLastTag($blockSplit[$k]),$css).
 967                                              '</'.$tagName.'>';
 968                      break;
 969                      case 'typolist':    // Transform typolist blocks into OL/UL lists. Type 1 is expected to be numerical block
 970                          if (!isset($this->procOptions['typolist']) || $this->procOptions['typolist'])    {
 971                              $tListContent = $this->removeFirstAndLastTag($blockSplit[$k]);
 972                              $tListContent = ereg_replace('^[ ]*'.chr(10),'',$tListContent);
 973                              $tListContent = ereg_replace(chr(10).'[ ]*$','',$tListContent);
 974                              $lines = explode(chr(10),$tListContent);
 975                              $typ = $attribArray['type']==1 ? 'ol' : 'ul';
 976                              $blockSplit[$k] = '<'.$typ.'>'.chr(10).
 977                                                  '<li>'.implode('</li>'.chr(10).'<li>',$lines).'</li>'.
 978                                                  '</'.$typ.'>';
 979                          }
 980                      break;
 981                      case 'typohead':    // Transform typohead into Hx tags.
 982                          if (!isset($this->procOptions['typohead']) || $this->procOptions['typohead'])    {
 983                              $tC = $this->removeFirstAndLastTag($blockSplit[$k]);
 984                              $typ = t3lib_div::intInRange($attribArray['type'],0,6);
 985                              if (!$typ)    $typ=6;
 986                              $align = $attribArray['align']?' align="'.$attribArray['align'].'"': '';
 987                              $class = $attribArray['class']?' class="'.$attribArray['class'].'"': '';
 988                              $blockSplit[$k] = '<h'.$typ.$align.$class.'>'.
 989                                                  $tC.
 990                                                  '</h'.$typ.'>';
 991                          }
 992                      break;
 993                  }
 994                  $blockSplit[$k+1] = ereg_replace('^[ ]*'.chr(10),'',$blockSplit[$k+1]);    // Removing linebreak if typohead
 995              } else {    // NON-block:
 996                  $nextFTN = $this->getFirstTagName($blockSplit[$k+1]);
 997                  $singleLineBreak = $blockSplit[$k]==chr(10);
 998                  if (t3lib_div::inList('TABLE,BLOCKQUOTE,TYPOLIST,TYPOHEAD,'.$this->headListTags,$nextFTN))    {    // Removing linebreak if typolist/typohead
 999                      $blockSplit[$k] = ereg_replace(chr(10).'[ ]*$','',$blockSplit[$k]);
1000                  }
1001                      // If $blockSplit[$k] is blank then unset the line. UNLESS the line happend to be a single line break.
1002                  if (!strcmp($blockSplit[$k],'') && !$singleLineBreak)    {
1003                      unset($blockSplit[$k]);
1004                  } else {
1005                      $blockSplit[$k] = $this->setDivTags($blockSplit[$k],($this->procOptions['useDIVasParagraphTagForRTE']?'div':'p'));
1006                  }
1007              }
1008          }
1009          return implode(chr(10),$blockSplit);
1010      }
1011  
1012      /**
1013       * Transformation handler: 'ts_strip' / direction: "db"
1014       * Removing all non-allowed tags
1015       *
1016       * @param    string        Content input
1017       * @return    string        Content output
1018       */
1019  	function TS_strip_db($value)    {
1020          $value = strip_tags($value,'<'.implode('><',explode(',','b,i,u,a,img,br,div,center,pre,font,hr,sub,sup,p,strong,em,li,ul,ol,blockquote')).'>');
1021          return $value;
1022      }
1023  
1024  
1025  
1026  
1027  
1028  
1029  
1030  
1031  
1032  
1033  
1034  
1035  
1036  
1037      /***************************************************************
1038       *
1039       * Generic RTE transformation, analysis and helper functions
1040       *
1041       **************************************************************/
1042  
1043      /**
1044       * Reads the file or url $url and returns the content
1045       *
1046       * @param    string        Filepath/URL to read
1047       * @return    string        The content from the resource given as input.
1048       * @see t3lib_div::getURL()
1049       */
1050  	function getURL($url)    {
1051          return t3lib_div::getURL($url);
1052      }
1053  
1054      /**
1055       * Function for cleaning content going into the database.
1056       * Content is cleaned eg. by removing unallowed HTML and ds-HSC content
1057       * It is basically calling HTMLcleaner from the parent class with some preset configuration specifically set up for cleaning content going from the RTE into the db
1058       *
1059       * @param    string        Content to clean up
1060       * @param    string        Comma list of tags to specifically allow. Default comes from getKeepTags and is ""
1061       * @return    string        Clean content
1062       * @see getKeepTags()
1063       */
1064  	 function HTMLcleaner_db($content,$tagList='')    {
1065           if (!$tagList)    {
1066              $keepTags = $this->getKeepTags('db');
1067          } else {
1068              $keepTags = $this->getKeepTags('db',$tagList);
1069          }
1070          $kUknown = $this->procOptions['dontRemoveUnknownTags_db'] ? 1 : 0;        // Default: remove unknown tags.
1071          $hSC = $this->procOptions['dontUndoHSC_db'] ? 0 : -1;                    // Default: re-convert literals to characters (that is &lt; to <)
1072  
1073              // Create additional configuration in order to honor the setting RTE.default.proc.HTMLparser_db.xhtml_cleaning=1
1074          $addConfig=array();
1075          if ((is_array($this->procOptions['HTMLparser_db.']) && $this->procOptions['HTMLparser_db.']['xhtml_cleaning']) || (is_array($this->procOptions['entryHTMLparser_db.']) && $this->procOptions['entryHTMLparser_db.']['xhtml_cleaning']) || (is_array($this->procOptions['exitHTMLparser_db.']) && $this->procOptions['exitHTMLparser_db.']['xhtml_cleaning']))    {
1076              $addConfig['xhtml']=1;
1077          }
1078  
1079           return $this->HTMLcleaner($content,$keepTags,$kUknown,$hSC,$addConfig);
1080       }
1081  
1082      /**
1083       * Creates an array of configuration for the HTMLcleaner function based on whether content go TO or FROM the Rich Text Editor ($direction)
1084       * Unless "tagList" is given, the function will cache the configuration for next time processing goes on. (In this class that is the case only if we are processing a bulletlist)
1085       *
1086       * @param    string        The direction of the content being processed by the output configuration; "db" (content going into the database FROM the rte) or "rte" (content going into the form)
1087       * @param    string        Comma list of tags to keep (overriding default which is to keep all + take notice of internal configuration)
1088       * @return    array        Configuration array
1089       * @see HTMLcleaner_db()
1090       */
1091  	function getKeepTags($direction='rte',$tagList='')    {
1092          if (!is_array($this->getKeepTags_cache[$direction]) || $tagList)    {
1093  
1094                  // Setting up allowed tags:
1095              if (strcmp($tagList,''))    {    // If the $tagList input var is set, this will take precedence
1096                  $keepTags = array_flip(t3lib_div::trimExplode(',',$tagList,1));
1097              } else {    // Default is to get allowed/denied tags from internal array of processing options:
1098                      // Construct default list of tags to keep:
1099                  $typoScript_list = 'b,i,u,a,img,br,div,center,pre,font,hr,sub,sup,p,strong,em,li,ul,ol,blockquote,strike,span';
1100                  $keepTags = array_flip(t3lib_div::trimExplode(',',$typoScript_list.','.strtolower($this->procOptions['allowTags']),1));
1101  
1102                      // For tags to deny, remove them from $keepTags array:
1103                  $denyTags = t3lib_div::trimExplode(',',$this->procOptions['denyTags'],1);
1104                  foreach($denyTags as $dKe)    {
1105                      unset($keepTags[$dKe]);
1106                  }
1107              }
1108  
1109                  // Based on the direction of content, set further options:
1110              switch ($direction)    {
1111  
1112                      // GOING from database to Rich Text Editor:
1113                  case 'rte':
1114                          // Transform bold/italics tags to strong/em
1115                      if (isset($keepTags['b']))    {$keepTags['b']=array('remap'=>'STRONG');}
1116                      if (isset($keepTags['i']))    {$keepTags['i']=array('remap'=>'EM');}
1117  
1118                          // Transforming keepTags array so it can be understood by the HTMLcleaner function. This basically converts the format of the array from TypoScript (having .'s) to plain multi-dimensional array.
1119                      list($keepTags) = $this->HTMLparserConfig($this->procOptions['HTMLparser_rte.'],$keepTags);
1120                  break;
1121  
1122                      // GOING from RTE to database:
1123                  case 'db':
1124                          // Transform strong/em back to bold/italics:
1125                      if (isset($keepTags['strong']))    { $keepTags['strong']=array('remap'=>'b'); }
1126                      if (isset($keepTags['em']))        { $keepTags['em']=array('remap'=>'i'); }
1127  
1128                          // Setting up span tags if they are allowed:
1129                      if (isset($keepTags['span']))        {
1130                          $classes=array_merge(array(''),$this->allowedClasses);
1131                          $keepTags['span']=array(
1132                               'allowedAttribs' => 'class,style,xml:lang',
1133                              'fixAttrib' => Array(
1134                                  'class' => Array (
1135                                      'list' => $classes,
1136                                      'removeIfFalse' => 1
1137                                  )
1138                              ),
1139                              'rmTagIfNoAttrib' => 1
1140                          );
1141                          if (!$this->procOptions['allowedClasses'])    unset($keepTags['span']['fixAttrib']['class']['list']);
1142                      }
1143  
1144                          // Setting up font tags if they are allowed:
1145                      if (isset($keepTags['font']))        {
1146                          $colors=array_merge(array(''),t3lib_div::trimExplode(',',$this->procOptions['allowedFontColors'],1));
1147                          $keepTags['font']=array(
1148                              'allowedAttribs'=>'face,color,size',
1149                              'fixAttrib' => Array(
1150                                  'face' => Array (
1151                                      'removeIfFalse' => 1
1152                                  ),
1153                                  'color' => Array (
1154                                      'removeIfFalse' => 1,
1155                                      'list'=>$colors
1156                                  ),
1157                                  'size' => Array (
1158                                      'removeIfFalse' => 1,
1159                                  )
1160                              ),
1161                              'rmTagIfNoAttrib' => 1
1162                          );
1163                          if (!$this->procOptions['allowedFontColors'])    unset($keepTags['font']['fixAttrib']['color']['list']);
1164                      }
1165  
1166                          // Setting further options, getting them from the processiong options:
1167                      $TSc = $this->procOptions['HTMLparser_db.'];
1168                      if (!$TSc['globalNesting'])    $TSc['globalNesting']='b,i,u,a,center,font,sub,sup,strong,em,strike,span';
1169                      if (!$TSc['noAttrib'])    $TSc['noAttrib']='b,i,u,br,center,hr,sub,sup,strong,em,li,ul,ol,blockquote,strike';
1170  
1171                          // Transforming the array from TypoScript to regular array:
1172                      list($keepTags) = $this->HTMLparserConfig($TSc,$keepTags);
1173                  break;
1174              }
1175  
1176                  // Caching (internally, in object memory) the result unless tagList is set:
1177              if (!$tagList)    {
1178                  $this->getKeepTags_cache[$direction] = $keepTags;
1179              } else {
1180                  return $keepTags;
1181              }
1182          }
1183  
1184              // Return result:
1185          return $this->getKeepTags_cache[$direction];
1186      }
1187  
1188      /**
1189       * This resolves the $value into parts based on <div></div>-sections and <p>-sections and <br />-tags. These are returned as lines separated by chr(10).
1190       * This point is to resolve the HTML-code returned from RTE into ordinary lines so it's 'human-readable'
1191       * The function ->setDivTags does the opposite.
1192       * This function processes content to go into the database.
1193       *
1194       * @param    string        Value to process.
1195       * @param    integer        Recursion brake. Decremented on each recursion down to zero. Default is 5 (which equals the allowed nesting levels of p/div tags).
1196       * @param    boolean        If true, an array with the lines is returned, otherwise a string of the processed input value.
1197       * @return    string        Processed input value.
1198       * @see setDivTags()
1199       */
1200  	function divideIntoLines($value,$count=5,$returnArray=FALSE)    {
1201  
1202              // Internalize font tags (move them from OUTSIDE p/div to inside it that is the case):
1203          if ($this->procOptions['internalizeFontTags'])    {$value = $this->internalizeFontTags($value);}
1204  
1205              // Setting configuration for processing:
1206          $allowTagsOutside = t3lib_div::trimExplode(',',strtolower($this->procOptions['allowTagsOutside']?$this->procOptions['allowTagsOutside']:'img'),1);
1207          $remapParagraphTag = strtoupper($this->procOptions['remapParagraphTag']);
1208          $divSplit = $this->splitIntoBlock('div,p',$value,1);    // Setting the third param to 1 will eliminate false end-tags. Maybe this is a good thing to do...?
1209  
1210          if ($this->procOptions['keepPDIVattribs'])    {
1211              $keepAttribListArr = t3lib_div::trimExplode(',',strtolower($this->procOptions['keepPDIVattribs']),1);
1212          } else {
1213              $keepAttribListArr = array();
1214          }
1215  
1216              // Returns plainly the value if there was no div/p sections in it
1217          if (count($divSplit)<=1 || $count<=0)    {
1218              return $value;
1219          }
1220  
1221              // Traverse the splitted sections:
1222          foreach($divSplit as $k => $v)    {
1223              if ($k%2)    {    // Inside
1224                  $v=$this->removeFirstAndLastTag($v);
1225  
1226                      // Fetching 'sub-lines' - which will explode any further p/div nesting...
1227                  $subLines = $this->divideIntoLines($v,$count-1,1);
1228                  if (is_array($subLines))    {    // So, if there happend to be sub-nesting of p/div, this is written directly as the new content of THIS section. (This would be considered 'an error')
1229                      // No noting.
1230                  } else {    //... but if NO subsection was found, we process it as a TRUE line without erronous content:
1231                      $subLines = array($subLines);
1232                      if (!$this->procOptions['dontConvBRtoParagraph'])    {    // process break-tags, if configured for. Simply, the breaktags will here be treated like if each was a line of content...
1233                          $subLines = spliti('<br[[:space:]]*[\/]?>',$v);
1234                      }
1235  
1236                          // Traverse sublines (there is typically one, except if <br/> has been converted to lines as well!)
1237                      reset($subLines);
1238                      while(list($sk)=each($subLines))    {
1239  
1240                              // Clear up the subline for DB.
1241                          $subLines[$sk]=$this->HTMLcleaner_db($subLines[$sk]);
1242  
1243                              // Get first tag, attributes etc:
1244                          $fTag = $this->getFirstTag($divSplit[$k]);
1245                          $tagName=strtolower($this->getFirstTagName($divSplit[$k]));
1246                          $attribs=$this->get_tag_attributes($fTag);
1247  
1248                              // Keep attributes (lowercase)
1249                          $newAttribs=array();
1250                          if (count($keepAttribListArr))    {
1251                              foreach($keepAttribListArr as $keepA)    {
1252                                  if (isset($attribs[0][$keepA]))    { $newAttribs[$keepA] = $attribs[0][$keepA]; }
1253                              }
1254                          }
1255  
1256                              // ALIGN attribute:
1257                          if (!$this->procOptions['skipAlign'] && strcmp(trim($attribs[0]['align']),'') && strtolower($attribs[0]['align'])!='left')    {    // Set to value, but not 'left'
1258                              $newAttribs['align']=strtolower($attribs[0]['align']);
1259                          }
1260  
1261                              // CLASS attribute:
1262                          if (!$this->procOptions['skipClass'] && strcmp(trim($attribs[0]['class']),''))    {    // Set to whatever value
1263                              if (!count($this->allowedClasses) || in_array(strtoupper($attribs[0]['class']),$this->allowedClasses))    {
1264                                  $newAttribs['class']=$attribs[0]['class'];
1265                              }
1266                          }
1267  
1268                              // Remove any line break char (10 or 13)
1269                          $subLines[$sk]=ereg_replace(chr(10).'|'.chr(13),'',$subLines[$sk]);
1270  
1271                              // If there are any attributes or if we are supposed to remap the tag, then do so:
1272                          if (count($newAttribs) && strcmp($remapParagraphTag,'1'))        {
1273                              if ($remapParagraphTag=='P')    $tagName='p';
1274                              if ($remapParagraphTag=='DIV')    $tagName='div';
1275                              $subLines[$sk]='<'.trim($tagName.' '.$this->compileTagAttribs($newAttribs)).'>'.$subLines[$sk].'</'.$tagName.'>';
1276                          }
1277                      }
1278                  }
1279                      // Add the processed line(s)
1280                  $divSplit[$k] = implode(chr(10),$subLines);
1281  
1282                      // If it turns out the line is just blank (containing a &nbsp; possibly) then just make it pure blank:
1283                  if (trim(strip_tags($divSplit[$k]))=='&nbsp;' && !preg_match('/\<(img)(\s[^>]*)?\/?>/si', $divSplit[$k])) {
1284                      $divSplit[$k]='';
1285                  }
1286              } else {    // outside div:
1287                      // Remove positions which are outside div/p tags and without content
1288                  $divSplit[$k]=trim(strip_tags($divSplit[$k],'<'.implode('><',$allowTagsOutside).'>'));
1289                  if (!strcmp($divSplit[$k],''))    unset($divSplit[$k]);    // Remove part if it's empty
1290              }
1291          }
1292  
1293              // Return value:
1294          return $returnArray ? $divSplit : implode(chr(10),$divSplit);
1295      }
1296  
1297      /**
1298       * Converts all lines into <div></div>/<p></p>-sections (unless the line is a div-section already)
1299       * For processing of content going FROM database TO RTE.
1300       *
1301       * @param    string        Value to convert
1302       * @param    string        Tag to wrap with. Either "p" or "div" should it be. Lowercase preferably.
1303       * @return    string        Processed value.
1304       * @see divideIntoLines()
1305       */
1306  	function setDivTags($value,$dT='p')    {
1307  
1308              // First, setting configuration for the HTMLcleaner function. This will process each line between the <div>/<p> section on their way to the RTE
1309          $keepTags = $this->getKeepTags('rte');
1310          $kUknown = $this->procOptions['dontProtectUnknownTags_rte'] ? 0 : 'protect';    // Default: remove unknown tags.
1311          $hSC = $this->procOptions['dontHSC_rte'] ? 0 : 1;    // Default: re-convert literals to characters (that is &lt; to <)
1312          $convNBSP = !$this->procOptions['dontConvAmpInNBSP_rte']?1:0;
1313  
1314              // Divide the content into lines, based on chr(10):
1315          $parts = explode(chr(10),$value);
1316          foreach($parts as $k => $v)    {
1317  
1318                  // Processing of line content:
1319              if (!strcmp(trim($parts[$k]),''))    {    // If the line is blank, set it to &nbsp;
1320                  $parts[$k]='&nbsp;';
1321              } else {    // Clean the line content:
1322                  $parts[$k]=$this->HTMLcleaner($parts[$k],$keepTags,$kUknown,$hSC);
1323                  if ($convNBSP)    $parts[$k]=str_replace('&amp;nbsp;','&nbsp;',$parts[$k]);
1324              }
1325  
1326                  // Wrapping the line in <$dT> is not already wrapped:
1327              $testStr = strtolower(trim($parts[$k]));
1328              if (substr($testStr,0,4)!='<div' || substr($testStr,-6)!='</div>')    {
1329                  if (substr($testStr,0,2)!='<p' || substr($testStr,-4)!='</p>')    {
1330                          // Only set p-tags if there is not already div or p tags:
1331                      $parts[$k]='<'.$dT.'>'.$parts[$k].'</'.$dT.'>';
1332                  }
1333              }
1334          }
1335  
1336              // Implode result:
1337          return implode(chr(10),$parts);
1338      }
1339  
1340      /**
1341       * This splits the $value in font-tag chunks.
1342       * If there are any <P>/<DIV> sections inside of them, the font-tag is wrapped AROUND the content INSIDE of the P/DIV sections and the outer font-tag is removed.
1343       * This functions seems to be a good choice for pre-processing content if it has been pasted into the RTE from eg. star-office.
1344       * In that case the font-tags are normally on the OUTSIDE of the sections.
1345       * This function is used by eg. divideIntoLines() if the procesing option 'internalizeFontTags' is set.
1346       *
1347       * @param    string        Input content
1348       * @return    string        Output content
1349       * @see divideIntoLines()
1350       */
1351  	function internalizeFontTags($value)    {
1352  
1353              // Splitting into font tag blocks:
1354          $fontSplit = $this->splitIntoBlock('font',$value);
1355  
1356          foreach($fontSplit as $k => $v)    {
1357              if ($k%2)    {    // Inside
1358                  $fTag = $this->getFirstTag($v);    // Fint font-tag
1359  
1360                  $divSplit_sub = $this->splitIntoBlock('div,p',$this->removeFirstAndLastTag($v),1);
1361                  if (count($divSplit_sub)>1)    {    // If there were div/p sections inside the font-tag, do something about it...
1362                          // traverse those sections:
1363                      foreach($divSplit_sub as $k2 => $v2)    {
1364                          if ($k2%2)    {    // Inside
1365                              $div_p = $this->getFirstTag($v2);    // Fint font-tag
1366                              $div_p_tagname = $this->getFirstTagName($v2);    // Fint font-tag
1367                              $v2=$this->removeFirstAndLastTag($v2); // ... and remove it from original.
1368                              $divSplit_sub[$k2]=$div_p.$fTag.$v2.'</font>'.'</'.$div_p_tagname.'>';
1369                          } elseif (trim(strip_tags($v2))) {
1370                              $divSplit_sub[$k2]=$fTag.$v2.'</font>';
1371                          }
1372                      }
1373                      $fontSplit[$k]=implode('',$divSplit_sub);
1374                  }
1375              }
1376          }
1377  
1378          return implode('',$fontSplit);
1379      }
1380  
1381      /**
1382       * Returns SiteURL based on thisScript.
1383       *
1384       * @return    string        Value of t3lib_div::getIndpEnv('TYPO3_SITE_URL');
1385       * @see t3lib_div::getIndpEnv()
1386       */
1387  	function siteUrl()    {
1388          return t3lib_div::getIndpEnv('TYPO3_SITE_URL');
1389      }
1390  
1391      /**
1392       * Return the storage folder of RTE image files.
1393       * Default is $GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_imageStorageDir'] unless something else is configured in the types configuration for the RTE.
1394       *
1395       * @return    string
1396       */
1397  	function rteImageStorageDir()    {
1398          return $this->rte_p['imgpath'] ? $this->rte_p['imgpath'] : $GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_imageStorageDir'];
1399      }
1400  
1401      /**
1402       * Remove all tables from incoming code
1403       * The function is trying to to this is some more or less respectfull way. The approach is to resolve each table cells content and implode it all by <br /> chars. Thus at least the content is preserved in some way.
1404       *
1405       * @param    string        Input value
1406       * @param    string        Break character to use for linebreaks.
1407       * @return    string        Output value
1408       */
1409  	function removeTables($value,$breakChar='<br />')    {
1410  
1411              // Splitting value into table blocks:
1412          $tableSplit = $this->splitIntoBlock('table',$value);
1413  
1414              // Traverse blocks of tables:
1415          foreach($tableSplit as $k => $v)    {
1416              if ($k%2)    {
1417                  $tableSplit[$k]='';
1418                  $rowSplit = $this->splitIntoBlock('tr',$v);
1419                  foreach($rowSplit as $k2 => $v2)    {
1420                      if ($k2%2)    {
1421                          $cellSplit = $this->getAllParts($this->splitIntoBlock('td',$v2),1,0);
1422                          foreach($cellSplit as $k3 => $v3)    {
1423                              $tableSplit[$k].=$v3.$breakChar;
1424                          }
1425                      }
1426                  }
1427              }
1428          }
1429  
1430              // Implode it all again:
1431          return implode($breakChar,$tableSplit);
1432      }
1433  
1434      /**
1435       * Default tag mapping for TS
1436       *
1437       * @param    string        Input code to process
1438       * @param    string        Direction To databsae (db) or from database to RTE (rte)
1439       * @return    string        Processed value
1440       */
1441  	function defaultTStagMapping($code,$direction='rte')    {
1442          if ($direction=='db')    {
1443              $code=$this->mapTags($code,array(    // Map tags
1444                  'strong' => 'b',
1445                  'em' => 'i'
1446              ));
1447          }
1448          if ($direction=='rte')    {
1449              $code=$this->mapTags($code,array(    // Map tags
1450                  'b' => 'strong',
1451                  'i' => 'em'
1452              ));
1453          }
1454          return $code;
1455      }
1456  
1457      /**
1458       * Finds width and height from attrib-array
1459       * If the width and height is found in the style-attribute, use that!
1460       *
1461       * @param    array        Array of attributes from tag in which to search. More specifically the content of the key "style" is used to extract "width:xxx / height:xxx" information
1462       * @return    array        Integer w/h in key 0/1. Zero is returned if not found.
1463       */
1464  	function getWHFromAttribs($attribArray)    {
1465          $style =trim($attribArray['style']);
1466          if ($style)    {
1467              $regex='[[:space:]]*:[[:space:]]*([0-9]*)[[:space:]]*px';
1468                  // Width
1469              $reg = array();
1470              eregi('width'.$regex,$style,$reg);
1471              $w = intval($reg[1]);
1472                  // Height
1473              eregi('height'.$regex,$style,$reg);
1474              $h = intval($reg[1]);
1475          }
1476          if (!$w)    {
1477              $w = $attribArray['width'];
1478          }
1479          if (!$h)    {
1480              $h = $attribArray['height'];
1481          }
1482          return array(intval($w),intval($h));
1483      }
1484  
1485      /**
1486       * Parse <A>-tag href and return status of email,external,file or page
1487       *
1488       * @param    string        URL to analyse.
1489       * @return    array        Information in an array about the URL
1490       */
1491  	function urlInfoForLinkTags($url)    {
1492          $info = array();
1493          $url = trim($url);
1494          if (substr(strtolower($url),0,7)=='mailto:')    {
1495              $info['url']=trim(substr($url,7));
1496              $info['type']='email';
1497          } else {
1498              $curURL = $this->siteUrl();     // 100502, removed this: 'http://'.t3lib_div::getThisUrl(); Reason: The url returned had typo3/ in the end - should be only the site's url as far as I see...
1499              for($a=0;$a<strlen($url);$a++)    {
1500                  if ($url{$a}!=$curURL{$a})    {
1501                      break;
1502                  }
1503              }
1504  
1505              $info['relScriptPath']=substr($curURL,$a);
1506              $info['relUrl']=substr($url,$a);
1507              $info['url']=$url;
1508              $info['type']='ext';
1509  
1510              $siteUrl_parts = parse_url($url);
1511              $curUrl_parts = parse_url($curURL);
1512  
1513              if ($siteUrl_parts['host']==$curUrl_parts['host']     // Hosts should match
1514                  && (!$info['relScriptPath']    || (defined('TYPO3_mainDir') && substr($info['relScriptPath'],0,strlen(TYPO3_mainDir))==TYPO3_mainDir)))    {    // If the script path seems to match or is empty (FE-EDIT)
1515  
1516                      // New processing order 100502
1517                  $uP=parse_url($info['relUrl']);
1518  
1519                  if (!strcmp('#'.$siteUrl_parts['fragment'],$info['relUrl'])) {
1520                      $info['url']=$info['relUrl'];
1521                      $info['type']='anchor';
1522                  } elseif (!trim($uP['path']) || !strcmp($uP['path'],'index.php'))    {
1523                      $pp = explode('id=',$uP['query']);
1524                      $id = trim($pp[1]);
1525                      if ($id)    {
1526                          $info['pageid']=$id;
1527                          $info['cElement']=$uP['fragment'];
1528                          $info['url']=$id.($info['cElement']?'#'.$info['cElement']:'');
1529                          $info['type']='page';
1530                      }
1531                  } else {
1532                      $info['url']=$info['relUrl'];
1533                      $info['type']='file';
1534                  }
1535              } else {
1536                  unset($info['relScriptPath']);
1537                  unset($info['relUrl']);
1538              }
1539          }
1540          return $info;
1541      }
1542  
1543      /**
1544       * Converting <A>-tags to absolute URLs (+ setting rtekeep attribute)
1545       *
1546       * @param    string        Content input
1547       * @param    boolean        If true, then the "rtekeep" attribute will not be set.
1548       * @return    string        Content output
1549       */
1550  	function TS_AtagToAbs($value,$dontSetRTEKEEP=FALSE)    {
1551          $blockSplit = $this->splitIntoBlock('A',$value);
1552          reset($blockSplit);
1553          while(list($k,$v)=each($blockSplit))    {
1554              if ($k%2)    {    // block:
1555                  $attribArray = $this->get_tag_attributes_classic($this->getFirstTag($v),1);
1556  
1557                      // Checking if there is a scheme, and if not, prepend the current url.
1558                  if (strlen($attribArray['href']))    {    // ONLY do this if href has content - the <a> tag COULD be an anchor and if so, it should be preserved...
1559                      $uP = parse_url(strtolower($attribArray['href']));
1560                      if (!$uP['scheme'])    {
1561                          $attribArray['href'] = $this->siteUrl().substr($attribArray['href'],strlen($this->relBackPath));
1562                      }
1563                  } else {
1564                      $attribArray['rtekeep'] = 1;
1565                  }
1566                  if (!$dontSetRTEKEEP)    $attribArray['rtekeep'] = 1;
1567  
1568                  $bTag='<a '.t3lib_div::implodeAttributes($attribArray,1).'>';
1569                  $eTag='</a>';
1570                  $blockSplit[$k] = $bTag.$this->TS_AtagToAbs($this->removeFirstAndLastTag($blockSplit[$k])).$eTag;
1571              }
1572          }
1573          return implode('',$blockSplit);
1574      }
1575  }
1576  
1577  
1578  if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_parsehtml_proc.php'])    {
1579      include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_parsehtml_proc.php']);
1580  }
1581  ?>


Généré le : Sun Nov 25 17:13:16 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics