Documentation TYPO3 par Ameos |
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 < 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 possibly) then just make it pure blank: 01220 if (trim(strip_tags($divSplit[$k]))==' ') $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 < 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 01255 $parts[$k]=' '; 01256 } else { // Clean the line content: 01257 $parts[$k]=$this->HTMLcleaner($parts[$k],$keepTags,$kUknown,$hSC); 01258 if ($convNBSP) $parts[$k]=str_replace('&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 ?>