Main Page | Directories | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages | Examples

class.t3lib_parsehtml_proc.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2004 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 ***************************************************************/
00082 require_once (PATH_t3lib.'class.t3lib_parsehtml.php');
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00102 class t3lib_parsehtml_proc extends t3lib_parsehtml {
00103 
00104       // Static:
00105    var $headListTags = 'PRE,UL,OL,H1,H2,H3,H4,H5,H6';    // List of tags for header, pre and list containers
00106 
00107       // Internal, static:
00108    var $recPid = 0;           // Set this to the pid of the record manipulated by the class.
00109    var $elRef = '';           // Element reference [table]:[field], eg. "tt_content:bodytext"
00110    var $relPath='';           // Relative path
00111    var $relBackPath='';       // Relative back-path
00112    var $procOptions = '';        // Set to the TSconfig options coming from Page TSconfig
00113 
00114       // Internal, dynamic
00115    var $TS_transform_db_safecounter=100;     // Run-away brake for recursive calls.
00116    var $rte_p='';                      // Parameters from TCA types configuration related to the RTE
00117    var $getKeepTags_cache=array();           // Data caching for processing function
00118    var $allowedClasses=array();           // Storage of the allowed CSS class names in the RTE
00119    var $preserveTags = '';                // Set to tags to preserve from Page TSconfig configuration
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00137    function init($elRef='',$recPid=0)  {
00138       $this->recPid = $recPid;
00139       $this->elRef = $elRef;
00140    }
00141 
00149    function setRelPath($path) {
00150       $path = trim($path);
00151       $path = ereg_replace('^/','',$path);
00152       $path = ereg_replace('/$','',$path);
00153       if ($path)  {
00154          $this->relPath = $path;
00155          $this->relBackPath = '';
00156          $partsC=count(explode('/',$this->relPath));
00157          for ($a=0;$a<$partsC;$a++) {
00158             $this->relBackPath.='../';
00159          }
00160          $this->relPath.='/';
00161       }
00162    }
00163 
00173    function evalWriteFile($pArr,$currentRecord) {
00174 
00175          // Write file configuration:
00176       if (is_array($pArr)) {
00177          if ($GLOBALS['TYPO3_CONF_VARS']['BE']['staticFileEditPath']
00178             && substr($GLOBALS['TYPO3_CONF_VARS']['BE']['staticFileEditPath'],-1)=='/'
00179             && @is_dir(PATH_site.$GLOBALS['TYPO3_CONF_VARS']['BE']['staticFileEditPath']))   {
00180 
00181             $SW_p = $pArr['parameters'];
00182             $SW_editFileField = trim($SW_p[0]);
00183             $SW_editFile = $currentRecord[$SW_editFileField];
00184             if ($SW_editFileField && $SW_editFile && t3lib_div::validPathStr($SW_editFile))  {
00185                $SW_relpath = $GLOBALS['TYPO3_CONF_VARS']['BE']['staticFileEditPath'].$SW_editFile;
00186                $SW_editFile = PATH_site.$SW_relpath;
00187                if (@is_file($SW_editFile))   {
00188                   return array(
00189                      'editFile' => $SW_editFile,
00190                      'relEditFile' => $SW_relpath,
00191                      'contentField' => trim($SW_p[1]),
00192                      'markerField' => trim($SW_p[2]),
00193                      'loadFromFileField' => trim($SW_p[3]),
00194                      'statusField' => trim($SW_p[4])
00195                   );
00196                } else return "ERROR: Editfile '".$SW_relpath."' did not exist";
00197             } else return "ERROR: Edit file name could not be found or was bad.";
00198          } else return "ERROR: staticFileEditPath was not set, not set correctly or did not exist!";
00199       }
00200    }
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214    /**********************************************
00215     *
00216     * Main function
00217     *
00218     **********************************************/
00219 
00231    function RTE_transform($value,$specConf,$direction='rte',$thisConfig=array()) {
00232 
00233          // Init:
00234       $this->procOptions = $thisConfig['proc.'];
00235       $this->preserveTags = strtoupper(implode(',',t3lib_div::trimExplode(',',$this->procOptions['preserveTags'])));
00236 
00237          // Get parameters for rte_transformation:
00238       $p = $this->rte_p = t3lib_BEfunc::getSpecConfParametersFromArray($specConf['rte_transform']['parameters']);
00239 
00240          // Setting modes:
00241       if (strcmp($this->procOptions['overruleMode'],'')) {
00242          $modes = array_unique(t3lib_div::trimExplode(',',$this->procOptions['overruleMode']));
00243       } else {
00244          $modes = array_unique(t3lib_div::trimExplode('-',$p['mode']));
00245       }
00246       $revmodes = array_flip($modes);
00247 
00248          // Find special modes and extract them:
00249       if (isset($revmodes['ts']))   {
00250          $modes[$revmodes['ts']] = 'ts_transform,ts_preserve,ts_images,ts_links';
00251       }
00252          // Find special modes and extract them:
00253       if (isset($revmodes['ts_css']))  {
00254          $modes[$revmodes['ts_css']] = 'css_transform,ts_images,ts_links';
00255       }
00256 
00257          // Make list unique
00258       $modes = array_unique(t3lib_div::trimExplode(',',implode(',',$modes),1));
00259 
00260          // Reverse order if direction is "rte"
00261       if ($direction=='rte')  {
00262          $modes = array_reverse($modes);
00263       }
00264 
00265          // 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:
00266       $entry_HTMLparser = $this->procOptions['entryHTMLparser_'.$direction] ? $this->HTMLparserConfig($this->procOptions['entryHTMLparser_'.$direction.'.']) : '';
00267       $exit_HTMLparser = $this->procOptions['exitHTMLparser_'.$direction] ? $this->HTMLparserConfig($this->procOptions['exitHTMLparser_'.$direction.'.']) : '';
00268 
00269          // Line breaks of content is unified into char-10 only (removing char 13)
00270       if (!$this->procOptions['disableUnifyLineBreaks']) {
00271          $value = str_replace(chr(13).chr(10),chr(10),$value);
00272       }
00273 
00274          // In an entry-cleaner was configured, pass value through the HTMLcleaner with that:
00275       if (is_array($entry_HTMLparser)) {
00276          $value = $this->HTMLcleaner($value,$entry_HTMLparser[0],$entry_HTMLparser[1],$entry_HTMLparser[2],$entry_HTMLparser[3]);
00277       }
00278 
00279          // Traverse modes:
00280       foreach($modes as $cmd) {
00281             // ->DB
00282          if ($direction=='db')   {
00283                // Checking for user defined transformation:
00284             if ($_classRef = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_parsehtml_proc.php']['transformation'][$cmd])   {
00285                $_procObj = &t3lib_div::getUserObj($_classRef);
00286                $_procObj->pObj = &$this;
00287                $_procObj->transformationKey = $cmd;
00288                $value = $_procObj->transform_db($value,$this);
00289             } else { // ... else use defaults:
00290                switch($cmd)   {
00291                   case 'ts_images':
00292                      $value = $this->TS_images_db($value);
00293                   break;
00294                   case 'ts_reglinks':
00295                      $value = $this->TS_reglinks($value,'db');
00296                   break;
00297                   case 'ts_links':
00298                      $value = $this->TS_links_db($value);
00299                   break;
00300                   case 'ts_preserve':
00301                      $value = $this->TS_preserve_db($value);
00302                   break;
00303                   case 'ts_transform':
00304                   case 'css_transform':
00305                      $value = str_replace(chr(13),'',$value);  // Has a very disturbing effect, so just remove all '13' - depend on '10'
00306                      $this->allowedClasses = t3lib_div::trimExplode(',',strtoupper($this->procOptions['allowedClasses']),1);
00307                      $value = $this->TS_transform_db($value,$cmd=='css_transform');
00308                   break;
00309                   case 'ts_strip':
00310                      $value = $this->TS_strip_db($value);
00311                   break;
00312                   default:
00313                   break;
00314                }
00315             }
00316          }
00317             // ->RTE
00318          if ($direction=='rte')  {
00319                // Checking for user defined transformation:
00320             if ($_classRef = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_parsehtml_proc.php']['transformation'][$cmd])   {
00321                $_procObj = &t3lib_div::getUserObj($_classRef);
00322                $_procObj->pObj = &$this;
00323                $value = $_procObj->transform_rte($value,$this);
00324             } else { // ... else use defaults:
00325                switch($cmd)   {
00326                   case 'ts_images':
00327                      $value = $this->TS_images_rte($value);
00328                   break;
00329                   case 'ts_reglinks':
00330                      $value = $this->TS_reglinks($value,'rte');
00331                   break;
00332                   case 'ts_links':
00333                      $value = $this->TS_links_rte($value);
00334                   break;
00335                   case 'ts_preserve':
00336                      $value = $this->TS_preserve_rte($value);
00337                   break;
00338                   case 'ts_transform':
00339                   case 'css_transform':
00340                      $value = str_replace(chr(13),'',$value);  // Has a very disturbing effect, so just remove all '13' - depend on '10'
00341                      $value = $this->TS_transform_rte($value,$cmd=='css_transform');
00342                   break;
00343                   default:
00344                   break;
00345                }
00346             }
00347          }
00348       }
00349 
00350          // In an exit-cleaner was configured, pass value through the HTMLcleaner with that:
00351       if (is_array($exit_HTMLparser))  {
00352          $value = $this->HTMLcleaner($value,$exit_HTMLparser[0],$exit_HTMLparser[1],$exit_HTMLparser[2],$exit_HTMLparser[3]);
00353       }
00354 
00355          // Final clean up of linebreaks:
00356       if (!$this->procOptions['disableUnifyLineBreaks']) {
00357          $value = str_replace(chr(13).chr(10),chr(10),$value); // Make sure no \r\n sequences has entered in the meantime...
00358          $value = str_replace(chr(10),chr(13).chr(10),$value); // ... and then change all \n into \r\n
00359       }
00360 
00361          // Return value:
00362       return $value;
00363    }
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380    /************************************
00381     *
00382     * Specific RTE TRANSFORMATION functions
00383     *
00384     *************************************/
00385 
00397    function TS_images_db($value) {
00398 
00399          // Split content by <img> tags and traverse the resulting array for processing:
00400       $imgSplit = $this->splitTags('img',$value);
00401       foreach($imgSplit as $k => $v)   {
00402          if ($k%2)   {  // image found, do processing:
00403 
00404                // Init
00405             $attribArray = $this->get_tag_attributes_classic($v,1);
00406             $siteUrl = $this->siteUrl();
00407             $absRef = trim($attribArray['src']);      // It's always a absolute URL coming from the RTE into the Database.
00408 
00409                // External image from another URL? In that case, fetch image (unless disabled feature).
00410             if (!t3lib_div::isFirstPartOfStr($absRef,$siteUrl) && !$this->procOptions['dontFetchExtPictures']) {
00411                $externalFile = $this->getUrl($absRef);   // Get it
00412                if ($externalFile)   {
00413                   $pU = parse_url($absRef);
00414                   $pI=pathinfo($pU['path']);
00415 
00416                   if (t3lib_div::inList('gif,png,jpeg,jpg',strtolower($pI['extension']))) {
00417                      $filename = t3lib_div::shortMD5($absRef).'.'.$pI['extension'];
00418                      $origFilePath = PATH_site.$this->rteImageStorageDir().'RTEmagicP_'.$filename;
00419                      $C_origFilePath = PATH_site.$this->rteImageStorageDir().'RTEmagicC_'.$filename.'.'.$pI['extension'];
00420                      if (!@is_file($origFilePath)) {
00421                         t3lib_div::writeFile($origFilePath,$externalFile);
00422                         t3lib_div::writeFile($C_origFilePath,$externalFile);
00423                      }
00424                      $absRef = $siteUrl.$this->rteImageStorageDir().'RTEmagicC_'.$filename.'.'.$pI['extension'];
00425 
00426                      $attribArray['src']=$absRef;
00427                      $params = t3lib_div::implodeAttributes($attribArray,1);
00428                      $imgSplit[$k] = '<img '.$params.' />';
00429                   }
00430                }
00431             }
00432                // Check image as local file (siteURL equals the one of the image)
00433             if (t3lib_div::isFirstPartOfStr($absRef,$siteUrl)) {
00434                $path = rawurldecode(substr($absRef,strlen($siteUrl)));  // Rel-path, rawurldecoded for special characters.
00435                $filepath = t3lib_div::getFileAbsFileName($path);     // Abs filepath, locked to relative path of this project.
00436 
00437                   // Check file existence (in relative dir to this installation!)
00438                if ($filepath && @is_file($filepath))  {
00439 
00440                      // If "magic image":
00441                   $pathPre=$this->rteImageStorageDir().'RTEmagicC_';
00442                   if (t3lib_div::isFirstPartOfStr($path,$pathPre))   {
00443                      // Find original file:
00444                      $pI=pathinfo(substr($path,strlen($pathPre)));
00445                      $filename = substr($pI['basename'],0,-strlen('.'.$pI['extension']));
00446                      $origFilePath = PATH_site.$this->rteImageStorageDir().'RTEmagicP_'.$filename;
00447                      if (@is_file($origFilePath))  {
00448                         $imgObj = t3lib_div::makeInstance('t3lib_stdGraphic');
00449                         $imgObj->init();
00450                         $imgObj->mayScaleUp=0;
00451                         $imgObj->tempPath=PATH_site.$imgObj->tempPath;
00452 
00453                         $curInfo = $imgObj->getImageDimensions($filepath); // Image dimensions of the current image
00454                         $curWH = $this->getWHFromAttribs($attribArray); // Image dimensions as set in the image tag
00455                            // Compare dimensions:
00456                         if ($curWH[0]!=$curInfo[0] || $curWH[1]!=$curInfo[1]) {
00457                            $origImgInfo = $imgObj->getImageDimensions($origFilePath);  // Image dimensions of the current image
00458                            $cW = $curWH[0];
00459                            $cH = $curWH[1];
00460                               $cH = 1000; // Make the image based on the width solely...
00461                            $imgI = $imgObj->imageMagickConvert($origFilePath,$pI['extension'],$cW.'m',$cH.'m');
00462                            if ($imgI[3])  {
00463                               $fI=pathinfo($imgI[3]);
00464                               @copy($imgI[3],$filepath); // Override the child file
00465                               unset($attribArray['style']);
00466                               $attribArray['width']=$imgI[0];
00467                               $attribArray['height']=$imgI[1];
00468                               if (!$attribArray['border'])  $attribArray['border']=0;
00469                               $params = t3lib_div::implodeAttributes($attribArray,1);
00470                               $imgSplit[$k]='<img '.$params.' />';
00471                            }
00472                         }
00473                      }
00474 
00475                   } elseif ($this->procOptions['plainImageMode']) {  // If "plain image" has been configured:
00476 
00477                         // Image dimensions as set in the image tag
00478                      $curWH = $this->getWHFromAttribs($attribArray);
00479                      $attribArray['width'] = $curWH[0];
00480                      $attribArray['height'] = $curWH[1];
00481 
00482                         // Forcing values for style and border:
00483                      unset($attribArray['style']);
00484                      if (!$attribArray['border'])  $attribArray['border'] = 0;
00485 
00486                         // Finding dimensions of image file:
00487                      $fI = @getimagesize($filepath);
00488 
00489                         // Perform corrections to aspect ratio based on configuration:
00490                      switch((string)$this->procOptions['plainImageMode'])  {
00491                         case 'lockDimensions':
00492                            $attribArray['width']=$fI[0];
00493                            $attribArray['height']=$fI[1];
00494                         break;
00495                         case 'lockRatioWhenSmaller':  // If the ratio has to be smaller, then first set the width...:
00496                            if ($attribArray['width']>$fI[0])   $attribArray['width'] = $fI[0];
00497                         case 'lockRatio':
00498                            if ($fI[0]>0)  {
00499                               $attribArray['height']=round($attribArray['width']*($fI[1]/$fI[0]));
00500                            }
00501                         break;
00502                      }
00503 
00504                         // Compile the image tag again:
00505                      $params = t3lib_div::implodeAttributes($attribArray,1);
00506                      $imgSplit[$k]='<img '.$params.' />';
00507                   }
00508                } else { // Remove image if it was not found in a proper position on the server!
00509 
00510                      // Commented out; removing the image tag might not be that logical...
00511                   #$imgSplit[$k]='';
00512                }
00513             }
00514 
00515                // Convert abs to rel url
00516             if ($imgSplit[$k])   {
00517                $attribArray=$this->get_tag_attributes_classic($imgSplit[$k],1);
00518                $absRef = trim($attribArray['src']);
00519                if (t3lib_div::isFirstPartOfStr($absRef,$siteUrl)) {
00520                   $attribArray['src'] = $this->relBackPath.substr($absRef,strlen($siteUrl));
00521                   if (!isset($attribArray['alt'])) $attribArray['alt']='';    // Must have alt-attribute for XHTML compliance.
00522                   $imgSplit[$k]='<img '.t3lib_div::implodeAttributes($attribArray,1,1).' />';
00523                }
00524             }
00525          }
00526       }
00527       return implode('',$imgSplit);
00528    }
00529 
00538    function TS_images_rte($value)   {
00539 
00540          // Split content by <img> tags and traverse the resulting array for processing:
00541       $imgSplit = $this->splitTags('img',$value);
00542       foreach($imgSplit as $k => $v)   {
00543          if ($k%2)   {  // image found:
00544 
00545                // Init
00546             $attribArray=$this->get_tag_attributes_classic($v,1);
00547             $siteUrl = $this->siteUrl();
00548             $absRef = trim($attribArray['src']);
00549 
00550                // Unless the src attribute is already pointing to an external URL:
00551             if (strtolower(substr($absRef,0,4))!='http') {
00552                $attribArray['src'] = $siteUrl.substr($attribArray['src'],strlen($this->relBackPath));
00553                if (!isset($attribArray['alt'])) $attribArray['alt']='';
00554                $params = t3lib_div::implodeAttributes($attribArray);
00555                $imgSplit[$k]='<img '.$params.' />';
00556             }
00557          }
00558       }
00559 
00560          // return processed content:
00561       return implode('',$imgSplit);
00562    }
00563 
00572    function TS_reglinks($value,$direction)      {
00573       switch($direction)   {
00574          case 'rte':
00575             return $this->TS_AtagToAbs($value,1);
00576          break;
00577          case 'db':
00578             $siteURL = $this->siteUrl();
00579             $blockSplit = $this->splitIntoBlock('A',$value);
00580             reset($blockSplit);
00581             while(list($k,$v)=each($blockSplit))   {
00582                if ($k%2)   {  // block:
00583                   $attribArray=$this->get_tag_attributes_classic($this->getFirstTag($v),1);
00584                      // If the url is local, remove url-prefix
00585                   if ($siteURL && substr($attribArray['href'],0,strlen($siteURL))==$siteURL) {
00586                      $attribArray['href']=$this->relBackPath.substr($attribArray['href'],strlen($siteURL));
00587                   }
00588                   $bTag='<a '.t3lib_div::implodeAttributes($attribArray,1).'>';
00589                   $eTag='</a>';
00590                   $blockSplit[$k] = $bTag.$this->TS_reglinks($this->removeFirstAndLastTag($blockSplit[$k]),$direction).$eTag;
00591                }
00592             }
00593             return implode('',$blockSplit);
00594          break;
00595       }
00596    }
00597 
00606    function TS_links_db($value)  {
00607 
00608          // Split content into <a> tag blocks and process:
00609       $blockSplit = $this->splitIntoBlock('A',$value);
00610       foreach($blockSplit as $k => $v) {
00611          if ($k%2)   {  // If an A-tag was found:
00612             $attribArray = $this->get_tag_attributes_classic($this->getFirstTag($v),1);
00613             $info = $this->urlInfoForLinkTags($attribArray['href']);
00614 
00615                // Check options:
00616             $attribArray_copy = $attribArray;
00617             unset($attribArray_copy['href']);
00618             unset($attribArray_copy['target']);
00619             unset($attribArray_copy['class']);
00620             if ($attribArray_copy['rteerror'])  {  // Unset "rteerror" and "style" attributes if "rteerror" is set!
00621                unset($attribArray_copy['style']);
00622                unset($attribArray_copy['rteerror']);
00623             }
00624             if (!count($attribArray_copy))   {  // Only if href, target and class are the only attributes, we can alter the link!
00625                   // Creating the TYPO3 pseudo-tag "<LINK>" for the link (includes href/url, target and class attributes):
00626                $bTag='<LINK '.$info['url'].($attribArray['target']?' '.$attribArray['target']:($attribArray['class']?' -':'')).($attribArray['class']?' '.$attribArray['class']:'').'>';
00627                $eTag='</LINK>';
00628                $blockSplit[$k] = $bTag.$this->TS_links_db($this->removeFirstAndLastTag($blockSplit[$k])).$eTag;
00629             } else { // ... otherwise store the link as a-tag.
00630                   // Unsetting 'rtekeep' attribute if that had been set.
00631                unset($attribArray['rtekeep']);
00632                   // If the url is local, remove url-prefix
00633                $siteURL = $this->siteUrl();
00634                if ($siteURL && substr($attribArray['href'],0,strlen($siteURL))==$siteURL) {
00635                   $attribArray['href']=$this->relBackPath.substr($attribArray['href'],strlen($siteURL));
00636                }
00637                $bTag='<a '.t3lib_div::implodeAttributes($attribArray,1).'>';
00638                $eTag='</a>';
00639                $blockSplit[$k] = $bTag.$this->TS_links_db($this->removeFirstAndLastTag($blockSplit[$k])).$eTag;
00640             }
00641          }
00642       }
00643       return implode('',$blockSplit);
00644    }
00645 
00654    function TS_links_rte($value) {
00655       $value = $this->TS_AtagToAbs($value);
00656 
00657          // Split content by the TYPO3 pseudo tag "<LINK>":
00658       $blockSplit = $this->splitIntoBlock('link',$value,1);
00659       foreach($blockSplit as $k => $v) {
00660          $error = '';
00661          if ($k%2)   {  // block:
00662             $tagCode = t3lib_div::trimExplode(' ',trim(substr($this->getFirstTag($v),0,-1)),1);
00663             $link_param = $tagCode[1];
00664             $href = '';
00665             $siteUrl = $this->siteUrl();
00666                // Parsing the typolink data. This parsing is roughly done like in tslib_content->typolink()
00667             if(strstr($link_param,'@'))   {     // mailadr
00668                $href = 'mailto:'.eregi_replace('^mailto:','',$link_param);
00669             } elseif (substr($link_param,0,1)=='#') { // check if anchor
00670                $href = $siteUrl.$link_param;
00671             } else {
00672                $fileChar=intval(strpos($link_param, '/'));
00673                $urlChar=intval(strpos($link_param, '.'));
00674 
00675                   // Detects if a file is found in site-root OR is a simulateStaticDocument.
00676                list($rootFileDat) = explode('?',$link_param);
00677                $rFD_fI = pathinfo($rootFileDat);
00678                if (trim($rootFileDat) && !strstr($link_param,'/') && (@is_file(PATH_site.$rootFileDat) || t3lib_div::inList('php,html,htm',strtolower($rFD_fI['extension']))))   {
00679                   $href = $siteUrl.$link_param;
00680                } elseif($urlChar && (strstr($link_param,'//') || !$fileChar || $urlChar<$fileChar))   {  // url (external): If doubleSlash or if a '.' comes before a '/'.
00681                   if (!ereg('^[a-z]*://',trim(strtolower($link_param))))   {$scheme='http://';} else {$scheme='';}
00682                   $href = $scheme.$link_param;
00683                } elseif($fileChar)  {  // file (internal)
00684                   $href = $siteUrl.$link_param;
00685                } else { // integer or alias (alias is without slashes or periods or commas, that is 'nospace,alphanum_x,lower,unique' according to tables.php!!)
00686                   $link_params_parts = explode('#',$link_param);
00687                   $idPart = trim($link_params_parts[0]);    // Link-data del
00688                   if (!strcmp($idPart,''))   { $idPart=$this->recPid; } // If no id or alias is given, set it to class record pid
00689                   if ($link_params_parts[1] && !$sectionMark)  {
00690                      $sectionMark = '#'.trim($link_params_parts[1]);
00691                   }
00692                      // Splitting the parameter by ',' and if the array counts more than 1 element it's a id/type/? pair
00693                   $pairParts = t3lib_div::trimExplode(',',$idPart);
00694                   if (count($pairParts)>1)   {
00695                      $idPart = $pairParts[0];
00696                      // Type ? future support for?
00697                   }
00698                      // Checking if the id-parameter is an alias.
00699                   if (!t3lib_div::testInt($idPart))   {
00700                      list($idPartR) = t3lib_BEfunc::getRecordsByField('pages','alias',$idPart);
00701                      $idPart = intval($idPartR['uid']);
00702                   }
00703                   $page = t3lib_BEfunc::getRecord('pages', $idPart);
00704                   if (is_array($page)) {  // Page must exist...
00705                      $href = $siteUrl.'?id='.$link_param;
00706                   } else {
00707                      #$href = '';
00708                      $href = $siteUrl.'?id='.$link_param;
00709                      $error = 'No page found: '.$idPart;
00710                   }
00711                }
00712             }
00713 
00714             // Setting the A-tag:
00715             $bTag = '<a href="'.htmlspecialchars($href).'"'.
00716                      ($tagCode[2]&&$tagCode[2]!='-' ? ' target="'.htmlspecialchars($tagCode[2]).'"' : '').
00717                      ($tagCode[3] ? ' class="'.htmlspecialchars($tagCode[3]).'"' : '').
00718                      ($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...
00719                      '>';
00720             $eTag = '</a>';
00721             $blockSplit[$k] = $bTag.$this->TS_links_rte($this->removeFirstAndLastTag($blockSplit[$k])).$eTag;
00722          }
00723       }
00724 
00725          // Return content:
00726       return implode('',$blockSplit);
00727    }
00728 
00735    function TS_preserve_db($value)  {
00736       if (!$this->preserveTags)  return $value;
00737 
00738          // Splitting into blocks for processing (span-tags are used for special tags)
00739       $blockSplit = $this->splitIntoBlock('span',$value);
00740       foreach($blockSplit as $k => $v) {
00741          if ($k%2)   {  // block:
00742             $attribArray=$this->get_tag_attributes_classic($this->getFirstTag($v));
00743             if ($attribArray['specialtag'])  {
00744                $theTag = rawurldecode($attribArray['specialtag']);
00745                $theTagName = $this->getFirstTagName($theTag);
00746                $blockSplit[$k] = $theTag.$this->removeFirstAndLastTag($blockSplit[$k]).'</'.$theTagName.'>';
00747             }
00748          }
00749       }
00750       return implode('',$blockSplit);
00751    }
00752 
00759    function TS_preserve_rte($value) {
00760       if (!$this->preserveTags)  return $value;
00761 
00762       $blockSplit = $this->splitIntoBlock($this->preserveTags,$value);
00763       foreach($blockSplit as $k => $v) {
00764          if ($k%2)   {  // block:
00765             $blockSplit[$k] = '<span specialtag="'.rawurlencode($this->getFirstTag($v)).'">'.$this->removeFirstAndLastTag($blockSplit[$k]).'</span>';
00766          }
00767       }
00768       return implode('',$blockSplit);
00769    }
00770 
00780    function TS_transform_db($value,$css=FALSE)  {
00781 
00782          // safety... so forever loops are avoided (they should not occur, but an error would potentially do this...)
00783       $this->TS_transform_db_safecounter--;
00784       if ($this->TS_transform_db_safecounter<0) return $value;
00785 
00786          // Split the content from RTE by the occurence of these blocks:
00787       $blockSplit = $this->splitIntoBlock('TABLE,BLOCKQUOTE,'.$this->headListTags,$value);
00788 
00789       $cc=0;
00790       $aC = count($blockSplit);
00791 
00792          // Traverse the blocks
00793       foreach($blockSplit as $k => $v) {
00794          $cc++;
00795          $lastBR = $cc==$aC ? '' : chr(10);
00796 
00797          if ($k%2)   {  // Inside block:
00798 
00799                // Init:
00800             $tag=$this->getFirstTag($v);
00801             $tagName=strtolower($this->getFirstTagName($v));
00802 
00803                // Process based on the tag:
00804             switch($tagName)  {
00805                case 'blockquote':   // Keep blockquotes, but clean the inside recursively in the same manner as the main code
00806                   $blockSplit[$k]='<'.$tagName.'>'.$this->TS_transform_db($this->removeFirstAndLastTag($blockSplit[$k]),$css).'</'.$tagName.'>'.$lastBR;
00807                break;
00808                case 'ol':
00809                case 'ul':  // Transform lists into <typolist>-tags:
00810                   if (!$css)  {
00811                      if (!isset($this->procOptions['typolist']) || $this->procOptions['typolist']) {
00812                         $parts = $this->getAllParts($this->splitIntoBlock('LI',$this->removeFirstAndLastTag($blockSplit[$k])),1,0);
00813                         while(list($k2)=each($parts)) {
00814                            $parts[$k2]=ereg_replace(chr(10).'|'.chr(13),'',$parts[$k2]);  // remove all linesbreaks!
00815                            $parts[$k2]=$this->defaultTStagMapping($parts[$k2],'db');
00816                            $parts[$k2]=$this->cleanFontTags($parts[$k2],0,0,0);
00817                            $parts[$k2] = $this->HTMLcleaner_db($parts[$k2],strtolower($this->procOptions['allowTagsInTypolists']?$this->procOptions['allowTagsInTypolists']:'br,font,b,i,u,a,img,span,strong,em'));
00818                         }
00819                         if ($tagName=='ol')  { $params=' type="1"'; } else { $params=''; }
00820                         $blockSplit[$k]='<typolist'.$params.'>'.chr(10).implode(chr(10),$parts).chr(10).'</typolist>'.$lastBR;
00821                      }
00822                   } else {
00823                      $blockSplit[$k].=$lastBR;
00824                   }
00825                break;
00826                case 'table':  // Tables are NOT allowed in any form (unless preserveTables is set or CSS is the mode)
00827                   if (!$this->procOptions['preserveTables'] && !$css)   {
00828                      $blockSplit[$k]=$this->TS_transform_db($this->removeTables($blockSplit[$k]));
00829                   } else {
00830                      $blockSplit[$k]=str_replace(chr(10),'',$blockSplit[$k]).$lastBR;
00831                   }
00832                break;
00833                case 'h1':
00834                case 'h2':
00835                case 'h3':
00836                case 'h4':
00837                case 'h5':
00838                case 'h6':
00839                   if (!$css)  {
00840                      $attribArray=$this->get_tag_attributes_classic($tag);
00841                         // Processing inner content here:
00842                      $innerContent = $this->HTMLcleaner_db($this->removeFirstAndLastTag($blockSplit[$k]));
00843 
00844                      if (!isset($this->procOptions['typohead']) || $this->procOptions['typohead']) {
00845                         $type = intval(substr($tagName,1));
00846                         $blockSplit[$k]='<typohead'.
00847                                     ($type!=6?' type="'.$type.'"':'').
00848                                     ($attribArray['align']?' align="'.$attribArray['align'].'"':'').
00849                                     ($attribArray['class']?' class="'.$attribArray['class'].'"':'').
00850                                     '>'.
00851                                     $innerContent.
00852                                     '</typohead>'.
00853                                     $lastBR;
00854                      } else {
00855                         $blockSplit[$k]='<'.$tagName.
00856                                     ($attribArray['align']?' align="'.htmlspecialchars($attribArray['align']).'"':'').
00857                                     ($attribArray['class']?' class="'.htmlspecialchars($attribArray['class']).'"':'').
00858                                     '>'.
00859                                     $innerContent.
00860                                     '</'.$tagName.'>'.
00861                                     $lastBR;
00862                      }
00863                   } else {
00864                      $blockSplit[$k].=$lastBR;
00865                   }
00866                break;
00867                default:
00868                   $blockSplit[$k].=$lastBR;
00869                break;
00870             }
00871          } else { // NON-block:
00872             if (strcmp(trim($blockSplit[$k]),''))  {
00873                $blockSplit[$k]=$this->divideIntoLines($blockSplit[$k]).$lastBR;
00874             } else unset($blockSplit[$k]);
00875          }
00876       }
00877       $this->TS_transform_db_safecounter++;
00878 
00879       return implode('',$blockSplit);
00880    }
00881 
00891    function TS_transform_rte($value,$css=0)  {
00892 
00893          // Split the content from Database by the occurence of these blocks:
00894       $blockSplit = $this->splitIntoBlock('TABLE,BLOCKQUOTE,TYPOLIST,TYPOHEAD,'.$this->headListTags,$value);
00895 
00896          // Traverse the blocks
00897       foreach($blockSplit as $k => $v) {
00898          if ($k%2)   {  // Inside one of the blocks:
00899 
00900                // Init:
00901             $tag = $this->getFirstTag($v);
00902             $tagName = strtolower($this->getFirstTagName($v));
00903             $attribArray = $this->get_tag_attributes_classic($tag);
00904 
00905                // Based on tagname, we do transformations:
00906             switch($tagName)  {
00907                case 'blockquote':   // Keep blockquotes:
00908                   $blockSplit[$k] = $tag.
00909                                  $this->TS_transform_rte($this->removeFirstAndLastTag($blockSplit[$k]),$css).
00910                                  '</'.$tagName.'>';
00911                break;
00912                case 'typolist':  // Transform typolist blocks into OL/UL lists. Type 1 is expected to be numerical block
00913                   if (!isset($this->procOptions['typolist']) || $this->procOptions['typolist']) {
00914                      $tListContent = $this->removeFirstAndLastTag($blockSplit[$k]);
00915                      $tListContent = ereg_replace('^[ ]*'.chr(10),'',$tListContent);
00916                      $tListContent = ereg_replace(chr(10).'[ ]*$','',$tListContent);
00917                      $lines = explode(chr(10),$tListContent);
00918                      $typ = $attribArray['type']==1 ? 'ol' : 'ul';
00919                      $blockSplit[$k] = '<'.$typ.'>'.chr(10).
00920                                     '<li>'.implode('</li>'.chr(10).'<li>',$lines).'</li>'.
00921                                     '</'.$typ.'>';
00922                   }
00923                break;
00924                case 'typohead':  // Transform typohead into Hx tags.
00925                   if (!isset($this->procOptions['typohead']) || $this->procOptions['typohead']) {
00926                      $tC = $this->removeFirstAndLastTag($blockSplit[$k]);
00927                      $typ = t3lib_div::intInRange($attribArray['type'],0,6);
00928                      if (!$typ)  $typ=6;
00929                      $align = $attribArray['align']?' align="'.$attribArray['align'].'"': '';
00930                      $class = $attribArray['class']?' class="'.$attribArray['class'].'"': '';
00931                      $blockSplit[$k] = '<h'.$typ.$align.$class.'>'.
00932                                     $tC.
00933                                     '</h'.$typ.'>';
00934                   }
00935                break;
00936             }
00937             $blockSplit[$k+1] = ereg_replace('^[ ]*'.chr(10),'',$blockSplit[$k+1]); // Removing linebreak if typohead
00938          } else { // NON-block:
00939             $nextFTN = $this->getFirstTagName($blockSplit[$k+1]);
00940             $singleLineBreak = $blockSplit[$k]==chr(10);
00941             if (t3lib_div::inList('TABLE,BLOCKQUOTE,TYPOLIST,TYPOHEAD,'.$this->headListTags,$nextFTN))   {  // Removing linebreak if typolist/typohead
00942                $blockSplit[$k] = ereg_replace(chr(10).'[ ]*$','',$blockSplit[$k]);
00943             }
00944                // If $blockSplit[$k] is blank then unset the line. UNLESS the line happend to be a single line break.
00945             if (!strcmp($blockSplit[$k],'') && !$singleLineBreak) {
00946                unset($blockSplit[$k]);
00947             } else {
00948                $blockSplit[$k] = $this->setDivTags($blockSplit[$k],($this->procOptions['useDIVasParagraphTagForRTE']?'div':'p'));
00949             }
00950          }
00951       }
00952       return implode(chr(10),$blockSplit);
00953    }
00954 
00962    function TS_strip_db($value)  {
00963       $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')).'>');
00964       return $value;
00965    }
00966 
00967 
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 
00976 
00977 
00978 
00979 
00980    /***************************************************************
00981     *
00982     * Generic RTE transformation, analysis and helper functions
00983     *
00984     **************************************************************/
00985 
00993    function getURL($url)   {
00994       return t3lib_div::getURL($url);
00995    }
00996 
01007     function HTMLcleaner_db($content,$tagList='')  {
01008       if (!$tagList) {
01009          $keepTags = $this->getKeepTags('db');
01010       } else {
01011          $keepTags = $this->getKeepTags('db',$tagList);
01012       }
01013       $kUknown = $this->procOptions['dontRemoveUnknownTags_db'] ? 1 : 0;      // Default: remove unknown tags.
01014       $hSC = $this->procOptions['dontUndoHSC_db'] ? 0 : -1;             // Default: re-convert literals to characters (that is &lt; to <)
01015 
01016       return $this->HTMLcleaner($content,$keepTags,$kUknown,$hSC);
01017     }
01018 
01028    function getKeepTags($direction='rte',$tagList='') {
01029       if (!is_array($this->getKeepTags_cache[$direction]) || $tagList)  {
01030 
01031             // Setting up allowed tags:
01032          if (strcmp($tagList,''))   {  // If the $tagList input var is set, this will take precedence
01033             $keepTags = array_flip(t3lib_div::trimExplode(',',$tagList,1));
01034          } else { // Default is to get allowed/denied tags from internal array of processing options:
01035                // Construct default list of tags to keep:
01036             $typoScript_list = 'b,i,u,a,img,br,div,center,pre,font,hr,sub,sup,p,strong,em,li,ul,ol,blockquote,strike,span';
01037             $keepTags = array_flip(t3lib_div::trimExplode(',',$typoScript_list.','.strtolower($this->procOptions['allowTags']),1));
01038 
01039                // For tags to deny, remove them from $keepTags array:
01040             $denyTags = t3lib_div::trimExplode(',',$this->procOptions['denyTags'],1);
01041             foreach($denyTags as $dKe) {
01042                unset($keepTags[$dKe]);
01043             }
01044          }
01045 
01046             // Based on the direction of content, set further options:
01047          switch ($direction)  {
01048 
01049                // GOING from database to Rich Text Editor:
01050             case 'rte':
01051                   // Transform bold/italics tags to strong/em
01052                if (isset($keepTags['b'])) {$keepTags['b']=array('remap'=>'STRONG');}
01053                if (isset($keepTags['i'])) {$keepTags['i']=array('remap'=>'EM');}
01054 
01055                   // 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.
01056                list($keepTags) = $this->HTMLparserConfig($this->procOptions['HTMLparser_rte.'],$keepTags);
01057             break;
01058 
01059                // GOING from RTE to database:
01060             case 'db':
01061                   // Transform strong/em back to bold/italics:
01062                if (isset($keepTags['strong']))  { $keepTags['strong']=array('remap'=>'b'); }
01063                if (isset($keepTags['em']))      { $keepTags['em']=array('remap'=>'i'); }
01064 
01065                   // Setting up span tags if they are allowed:
01066                if (isset($keepTags['span']))    {
01067                   $classes=array_merge(array(''),$this->allowedClasses);
01068                   $keepTags['span']=array(
01069                      'allowedAttribs'=>'class',
01070                      'fixAttrib' => Array(
01071                         'class' => Array (
01072                            'list' => $classes,
01073                            'removeIfFalse' => 1
01074                         )
01075                      ),
01076                      'rmTagIfNoAttrib' => 1
01077                   );
01078                   if (!$this->procOptions['allowedClasses'])   unset($keepTags['span']['fixAttrib']['class']['list']);
01079                }
01080 
01081                   // Setting up font tags if they are allowed:
01082                if (isset($keepTags['font']))    {
01083                   $colors=array_merge(array(''),t3lib_div::trimExplode(',',$this->procOptions['allowedFontColors'],1));
01084                   $keepTags['font']=array(
01085                      'allowedAttribs'=>'face,color,size',
01086                      'fixAttrib' => Array(
01087                         'face' => Array (
01088                            'removeIfFalse' => 1
01089                         ),
01090                         'color' => Array (
01091                            'removeIfFalse' => 1,
01092                            'list'=>$colors
01093                         ),
01094                         'size' => Array (
01095                            'removeIfFalse' => 1,
01096                         )
01097                      ),
01098                      'rmTagIfNoAttrib' => 1
01099                   );
01100                   if (!$this->procOptions['allowedFontColors'])   unset($keepTags['font']['fixAttrib']['color']['list']);
01101                }
01102 
01103                   // Setting further options, getting them from the processiong options:
01104                $TSc = $this->procOptions['HTMLparser_db.'];
01105                if (!$TSc['globalNesting'])   $TSc['globalNesting']='b,i,u,a,center,font,sub,sup,strong,em,strike,span';
01106                if (!$TSc['noAttrib'])  $TSc['noAttrib']='b,i,u,br,center,hr,sub,sup,strong,em,li,ul,ol,blockquote,strike';
01107 
01108                   // Transforming the array from TypoScript to regular array:
01109                list($keepTags) = $this->HTMLparserConfig($TSc,$keepTags);
01110             break;
01111          }
01112 
01113             // Caching (internally, in object memory) the result unless tagList is set:
01114          if (!$tagList) {
01115             $this->getKeepTags_cache[$direction] = $keepTags;
01116          } else {
01117             return $keepTags;
01118          }
01119       }
01120 
01121          // Return result:
01122       return $this->getKeepTags_cache[$direction];
01123    }
01124 
01137    function divideIntoLines($value,$count=5,$returnArray=FALSE)   {
01138 
01139          // Internalize font tags (move them from OUTSIDE p/div to inside it that is the case):
01140       if ($this->procOptions['internalizeFontTags'])  {$value = $this->internalizeFontTags($value);}
01141 
01142          // Setting configuration for processing:
01143       $allowTagsOutside = t3lib_div::trimExplode(',',strtolower($this->procOptions['allowTagsOutside']?$this->procOptions['allowTagsOutside']:'img'),1);
01144       $remapParagraphTag = strtoupper($this->procOptions['remapParagraphTag']);
01145       $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...?
01146 
01147       if ($this->procOptions['keepPDIVattribs'])   {
01148          $keepAttribListArr = t3lib_div::trimExplode(',',strtolower($this->procOptions['keepPDIVattribs']),1);
01149       } else {
01150          $keepAttribListArr = array();
01151       }
01152 
01153          // Returns plainly the value if there was no div/p sections in it
01154       if (count($divSplit)<=1 || $count<=0)  {
01155          return $value;
01156       }
01157 
01158          // Traverse the splitted sections:
01159       foreach($divSplit as $k => $v)   {
01160          if ($k%2)   {  // Inside
01161             $v=$this->removeFirstAndLastTag($v);
01162 
01163                // Fetching 'sub-lines' - which will explode any further p/div nesting...
01164             $subLines = $this->divideIntoLines($v,$count-1,1);
01165             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')
01166                // No noting.
01167             } else { //... but if NO subsection was found, we process it as a TRUE line without erronous content:
01168                $subLines = array($subLines);
01169                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...
01170                   $subLines = spliti('<br[[:space:]]*[\/]?>',$v);
01171                }
01172 
01173                   // Traverse sublines (there is typically one, except if <br/> has been converted to lines as well!)
01174                reset($subLines);
01175                while(list($sk)=each($subLines)) {
01176 
01177                      // Clear up the subline for DB.
01178                   $subLines[$sk]=$this->HTMLcleaner_db($subLines[$sk]);
01179 
01180                      // Get first tag, attributes etc:
01181                   $fTag = $this->getFirstTag($divSplit[$k]);
01182                   $tagName=strtolower($this->getFirstTagName($divSplit[$k]));
01183                   $attribs=$this->get_tag_attributes($fTag);
01184 
01185                      // Keep attributes (lowercase)
01186                   $newAttribs=array();
01187                   if (count($keepAttribListArr))   {
01188                      foreach($keepAttribListArr as $keepA)  {
01189                         if (isset($attribs[0][$keepA]))  { $newAttribs[$keepA] = $attribs[0][$keepA]; }
01190                      }
01191                   }
01192 
01193                      // ALIGN attribute:
01194                   if (!$this->procOptions['skipAlign'] && strcmp(trim($attribs[0]['align']),'') && strtolower($attribs[0]['align'])!='left') {  // Set to value, but not 'left'
01195                      $newAttribs['align']=strtolower($attribs[0]['align']);
01196                   }
01197 
01198                      // CLASS attribute:
01199                   if (!$this->procOptions['skipClass'] && strcmp(trim($attribs[0]['class']),''))   {  // Set to whatever value
01200                      if (!count($this->allowedClasses) || in_array(strtoupper($attribs[0]['class']),$this->allowedClasses))   {
01201                         $newAttribs['class']=$attribs[0]['class'];
01202                      }
01203                   }
01204 
01205                      // Remove any line break char (10 or 13)
01206                   $subLines[$sk]=ereg_replace(chr(10).'|'.chr(13),'',$subLines[$sk]);
01207 
01208                      // If there are any attributes or if we are supposed to remap the tag, then do so:
01209                   if (count($newAttribs) && strcmp($remapParagraphTag,'1'))      {
01210                      if ($remapParagraphTag=='P')  $tagName='p';
01211                      if ($remapParagraphTag=='DIV')   $tagName='div';
01212                      $subLines[$sk]='<'.trim($tagName.' '.$this->compileTagAttribs($newAttribs)).'>'.$subLines[$sk].'</'.$tagName.'>';
01213                   }
01214                }
01215             }
01216                // Add the processed line(s)
01217             $divSplit[$k] = implode(chr(10),$subLines);
01218 
01219                // If it turns out the line is just blank (containing a &nbsp; possibly) then just make it pure blank:
01220             if (trim(strip_tags($divSplit[$k]))=='&nbsp;')     $divSplit[$k]='';
01221          } else { // outside div:
01222                // Remove positions which are outside div/p tags and without content
01223             $divSplit[$k]=trim(strip_tags($divSplit[$k],'<'.implode('><',$allowTagsOutside).'>'));
01224             if (!strcmp($divSplit[$k],''))   unset($divSplit[$k]);   // Remove part if it's empty
01225          }
01226       }
01227 
01228          // Return value:
01229       return $returnArray ? $divSplit : implode(chr(10),$divSplit);
01230    }
01231 
01241    function setDivTags($value,$dT='p') {
01242 
01243          // First, setting configuration for the HTMLcleaner function. This will process each line between the <div>/<p> section on their way to the RTE
01244       $keepTags = $this->getKeepTags('rte');
01245       $kUknown = $this->procOptions['dontProtectUnknownTags_rte'] ? 0 : 'protect';  // Default: remove unknown tags.
01246       $hSC = $this->procOptions['dontHSC_rte'] ? 0 : 1;  // Default: re-convert literals to characters (that is &lt; to <)
01247       $convNBSP = !$this->procOptions['dontConvAmpInNBSP_rte']?1:0;
01248 
01249          // Divide the content into lines, based on chr(10):
01250       $parts = explode(chr(10),$value);
01251       foreach($parts as $k => $v)   {
01252 
01253             // Processing of line content:
01254          if (!strcmp(trim($parts[$k]),''))   {  // If the line is blank, set it to &nbsp;
01255             $parts[$k]='&nbsp;';
01256          } else { // Clean the line content:
01257             $parts[$k]=$this->HTMLcleaner($parts[$k],$keepTags,$kUknown,$hSC);
01258             if ($convNBSP) $parts[$k]=str_replace('&amp;nbsp;','&nbsp;',$parts[$k]);
01259          }
01260 
01261             // Wrapping the line in <$dT> is not already wrapped:
01262          $testStr = strtolower(trim($parts[$k]));
01263          if (substr($testStr,0,4)!='<div' || substr($testStr,-6)!='</div>')   {
01264             if (substr($testStr,0,2)!='<p' || substr($testStr,-4)!='</p>') {
01265                   // Only set p-tags if there is not already div or p tags:
01266                $parts[$k]='<'.$dT.'>'.$parts[$k].'</'.$dT.'>';
01267             }
01268          }
01269       }
01270 
01271          // Implode result:
01272       return implode(chr(10),$parts);
01273    }
01274 
01286    function internalizeFontTags($value)   {
01287 
01288          // Splitting into font tag blocks:
01289       $fontSplit = $this->splitIntoBlock('font',$value);
01290 
01291       foreach($fontSplit as $k => $v)  {
01292          if ($k%2)   {  // Inside
01293             $fTag = $this->getFirstTag($v);  // Fint font-tag
01294 
01295             $divSplit_sub = $this->splitIntoBlock('div,p',$this->removeFirstAndLastTag($v),1);
01296             if (count($divSplit_sub)>1)   {  // If there were div/p sections inside the font-tag, do something about it...
01297                   // traverse those sections:
01298                foreach($divSplit_sub as $k2 => $v2)   {
01299                   if ($k2%2)  {  // Inside
01300                      $div_p = $this->getFirstTag($v2);   // Fint font-tag
01301                      $div_p_tagname = $this->getFirstTagName($v2);   // Fint font-tag
01302                      $v2=$this->removeFirstAndLastTag($v2); // ... and remove it from original.
01303                      $divSplit_sub[$k2]=$div_p.$fTag.$v2.'</font>'.'</'.$div_p_tagname.'>';
01304                   } elseif (trim(strip_tags($v2))) {
01305                      $divSplit_sub[$k2]=$fTag.$v2.'</font>';
01306                   }
01307                }
01308                $fontSplit[$k]=implode('',$divSplit_sub);
01309             }
01310          }
01311       }
01312 
01313       return implode('',$fontSplit);
01314    }
01315 
01322    function siteUrl()   {
01323       return t3lib_div::getIndpEnv('TYPO3_SITE_URL');
01324    }
01325 
01332    function rteImageStorageDir() {
01333       return $this->rte_p['imgpath'] ? $this->rte_p['imgpath'] : $GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_imageStorageDir'];
01334    }
01335 
01344    function removeTables($value,$breakChar='<br />')  {
01345 
01346          // Splitting value into table blocks:
01347       $tableSplit = $this->splitIntoBlock('table',$value);
01348 
01349          // Traverse blocks of tables:
01350       foreach($tableSplit as $k => $v) {
01351          if ($k%2)   {
01352             $tableSplit[$k]='';
01353             $rowSplit = $this->splitIntoBlock('tr',$v);
01354             foreach($rowSplit as $k2 => $v2) {
01355                if ($k2%2)  {
01356                   $cellSplit = $this->getAllParts($this->splitIntoBlock('td',$v2),1,0);
01357                   foreach($cellSplit as $k3 => $v3)   {
01358                      $tableSplit[$k].=$v3.$breakChar;
01359                   }
01360                }
01361             }
01362          }
01363       }
01364 
01365          // Implode it all again:
01366       return implode($breakChar,$tableSplit);
01367    }
01368 
01376    function defaultTStagMapping($code,$direction='rte')  {
01377       if ($direction=='db')   {
01378          $code=$this->mapTags($code,array(   // Map tags
01379             'strong' => 'b',
01380             'em' => 'i'
01381          ));
01382       }
01383       if ($direction=='rte')  {
01384          $code=$this->mapTags($code,array(   // Map tags
01385             'b' => 'strong',
01386             'i' => 'em'
01387          ));
01388       }
01389       return $code;
01390    }
01391 
01399    function getWHFromAttribs($attribArray)   {
01400       $style =trim($attribArray['style']);
01401       if ($style) {
01402          $regex='[[:space:]]*:[[:space:]]*([0-9]*)[[:space:]]*px';
01403             // Width
01404          eregi('width'.$regex,$style,$reg);
01405          $w = intval($reg[1]);
01406             // Height
01407          eregi('height'.$regex,$style,$reg);
01408          $h = intval($reg[1]);
01409       }
01410       if (!$w) {
01411          $w = $attribArray['width'];
01412       }
01413       if (!$h) {
01414          $h = $attribArray['height'];
01415       }
01416       return array(intval($w),intval($h));
01417    }
01418 
01425    function urlInfoForLinkTags($url)   {
01426       $info = array();
01427       $url = trim($url);
01428       if (substr(strtolower($url),0,7)=='mailto:') {
01429          $info['url']=trim(substr($url,7));
01430          $info['type']='email';
01431       } else {
01432          $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...
01433          for($a=0;$a<strlen($url);$a++)   {
01434             if ($url[$a]!=$curURL[$a]) {
01435                break;
01436             }
01437          }
01438 
01439          $info['relScriptPath']=substr($curURL,$a);
01440          $info['relUrl']=substr($url,$a);
01441          $info['url']=$url;
01442          $info['type']='ext';
01443 
01444          $siteUrl_parts = parse_url($url);
01445          $curUrl_parts = parse_url($curURL);
01446 
01447          if ($siteUrl_parts['host']==$curUrl_parts['host']  // Hosts should match
01448             && (!$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)
01449 
01450                // New processing order 100502
01451             $uP=parse_url($info['relUrl']);
01452 
01453             if (!strcmp('#'.$siteUrl_parts['fragment'],$info['relUrl'])) {
01454                $info['url']=$info['relUrl'];
01455                $info['type']='anchor';
01456             } elseif (!trim($uP['path']) || !strcmp($uP['path'],'index.php')) {
01457                $pp = explode('id=',$uP['query']);
01458                $id = trim($pp[1]);
01459                if ($id) {
01460                   $info['pageid']=$id;
01461                   $info['cElement']=$uP['fragment'];
01462                   $info['url']=$id.($info['cElement']?'#'.$info['cElement']:'');
01463                   $info['type']='page';
01464                }
01465             } else {
01466                $info['url']=$info['relUrl'];
01467                $info['type']='file';
01468             }
01469          } else {
01470             unset($info['relScriptPath']);
01471             unset($info['relUrl']);
01472          }
01473       }
01474       return $info;
01475    }
01476 
01484    function TS_AtagToAbs($value,$dontSetRTEKEEP=FALSE)   {
01485       $blockSplit = $this->splitIntoBlock('A',$value);
01486       reset($blockSplit);
01487       while(list($k,$v)=each($blockSplit))   {
01488          if ($k%2)   {  // block:
01489             $attribArray = $this->get_tag_attributes_classic($this->getFirstTag($v),1);
01490 
01491                // Checking if there is a scheme, and if not, prepend the current url.
01492             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...
01493                $uP = parse_url(strtolower($attribArray['href']));
01494                if (!$uP['scheme'])  {
01495                   $attribArray['href'] = $this->siteUrl().substr($attribArray['href'],strlen($this->relBackPath));
01496                }
01497             } else {
01498                $attribArray['rtekeep'] = 1;
01499             }
01500             if (!$dontSetRTEKEEP)   $attribArray['rtekeep'] = 1;
01501 
01502             $bTag='<a '.t3lib_div::implodeAttributes($attribArray,1).'>';
01503             $eTag='</a>';
01504             $blockSplit[$k] = $bTag.$this->TS_AtagToAbs($this->removeFirstAndLastTag($blockSplit[$k])).$eTag;
01505          }
01506       }
01507       return implode('',$blockSplit);
01508    }
01509 }
01510 
01511 
01512 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_parsehtml_proc.php'])   {
01513    include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_parsehtml_proc.php']);
01514 }
01515 ?>

Generated on Sun Oct 3 01:05:49 2004 for TYPO3core 3.7.0 dev by  doxygen 1.3.8-20040913