TYPO3 API  SVNRelease
class.t3lib_softrefproc.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 2003-2011 Kasper Skårhøj (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  *
00017  *  This script is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *  GNU General Public License for more details.
00021  *
00022  *  This copyright notice MUST APPEAR in all copies of the script!
00023  ***************************************************************/
00024 /**
00025  * Soft Reference processing class
00026  * "Soft References" are references to database elements, files, email addresses, URls etc.
00027  * which are found in-text in content. The <link [page_id]> tag from typical bodytext fields
00028  * are an example of this.
00029  * This class contains generic parsers for the most well-known types
00030  * which are default for most TYPO3 installations. Soft References can also be userdefined.
00031  * The Soft Reference parsers are used by the system to find these references and process them accordingly in import/export actions and copy operations.
00032  *
00033  * $Id: class.t3lib_softrefproc.php 10121 2011-01-18 20:15:30Z ohader $
00034  *
00035  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00036  */
00037 /**
00038  * [CLASS/FUNCTION INDEX of SCRIPT]
00039  *
00040  *
00041  *
00042  *  116: class t3lib_softrefproc
00043  *  137:     function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath='')
00044  *  213:     function findRef_images($content, $spParams)
00045  *  280:     function findRef_typolink($content, $spParams)
00046  *  317:     function findRef_typolink_tag($content, $spParams)
00047  *  352:     function findRef_TStemplate($content, $spParams)
00048  *  434:     function findRef_TSconfig($content, $spParams)
00049  *  457:     function findRef_email($content, $spParams)
00050  *  497:     function findRef_url($content, $spParams)
00051  *  539:     function findRef_extension_fileref($content, $spParams)
00052  *
00053  *            SECTION: Helper functions
00054  *  591:     function fileadminReferences($content, &$elements)
00055  *  634:     function getTypoLinkParts($typolinkValue)
00056  *  718:     function setTypoLinkPartsElement($tLP, &$elements, $content, $idx)
00057  *  833:     function getPageIdFromAlias($link_param)
00058  *  845:     function makeTokenID($index='')
00059  *
00060  * TOTAL FUNCTIONS: 14
00061  * (This index is automatically created/updated by the extension "extdeveval")
00062  *
00063  */
00064 
00065 
00066 /**
00067  * Example of usage
00068  *              // Soft References:
00069  *          if ($conf['softref'] && strlen($value)) {   // Check if a TCA configured field has softreferences defined (see TYPO3 Core API document)
00070  *              $softRefs = t3lib_BEfunc::explodeSoftRefParserList($conf['softref']);       // Explode the list of softreferences/parameters
00071  *              foreach($softRefs as $spKey => $spParams)   {   // Traverse soft references
00072  *                  $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey);  // create / get object
00073  *                  if (is_object($softRefObj)) {   // If there was an object returned...:
00074  *                      $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams);    // Do processing
00075  *
00076  * Result Array:
00077  * The Result array should contain two keys: "content" and "elements".
00078  * "content" is a string containing the input content but possibly with tokens inside.
00079  *      Tokens are strings like {softref:[tokenID]} which is a placeholder for a value extracted by a softref parser
00080  *      For each token there MUST be an entry in the "elements" key which has a "subst" key defining the tokenID and the tokenValue. See below.
00081  * "elements" is an array where the keys are insignificant, but the values are arrays with these keys:
00082  *      "matchString" => The value of the match. This is only for informational purposes to show what was found.
00083  *       "error"    => An error message can be set here, like "file not found" etc.
00084  *       "subst" => array(  // If this array is found there MUST be a token in the output content as well!
00085  *          "tokenID" => The tokenID string corresponding to the token in output content, {softref:[tokenID]}. This is typically an md5 hash of a string defining uniquely the position of the element.
00086  *          "tokenValue" => The value that the token substitutes in the text. Basically, if this value is inserted instead of the token the content should match what was inputted originally.
00087  *          "type" => file / db / string    = the type of substitution. "file" means it is a relative file [automatically mapped], "db" means a database record reference [automatically mapped], "string" means it is manually modified string content (eg. an email address)
00088  *          "relFileName" => (for "file" type): Relative filename. May not necessarily exist. This could be noticed in the error key.
00089  *          "recordRef" => (for "db" type) : Reference to DB record on the form [table]:[uid]. May not necessarily exist.
00090  *          "title" => Title of element (for backend information)
00091  *          "description" => Description of element (for backend information)
00092  *      )
00093  *
00094  */
00095 
00096 
00097 /**
00098  * Class for processing of the default soft reference types for CMS:
00099  *
00100  * - 'substitute' : A full field value targeted for manual substitution (for import /export features)
00101  * - 'notify' : Just report if a value is found, nothing more.
00102  * - 'images' : HTML <img> tags for RTE images / images from fileadmin/
00103  * - 'typolink' : references to page id or file, possibly with anchor/target, possibly commaseparated list.
00104  * - 'typolink_tag' : As typolink, but searching for <link> tag to encapsulate it.
00105  * - 'TSconfig' processing (filerefs? Domains? what do we know...)
00106  * - 'TStemplate' : freetext references to "fileadmin/" files.
00107  * - 'email' : Email highlight
00108  * - 'url' : URL highlights (with a scheme)
00109  *
00110  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00111  * @package TYPO3
00112  * @subpackage t3lib
00113  */
00114 class t3lib_softrefproc {
00115 
00116         // external configuration
00117     var $fileAdminDir = 'fileadmin';
00118 
00119 
00120         // Internal:
00121     var $tokenID_basePrefix = '';
00122 
00123     /**
00124      * Main function through which all processing happens
00125      *
00126      * @param   string      Database table name
00127      * @param   string      Field name for which processing occurs
00128      * @param   integer     UID of the record
00129      * @param   string      The content/value of the field
00130      * @param   string      The softlink parser key. This is only interesting if more than one parser is grouped in the same class. That is the case with this parser.
00131      * @param   array       Parameters of the softlink parser. Basically this is the content inside optional []-brackets after the softref keys. Parameters are exploded by ";"
00132      * @param   string      If running from inside a FlexForm structure, this is the path of the tag.
00133      * @return  array       Result array on positive matches, see description above. Otherwise false
00134      */
00135     function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath = '') {
00136 
00137         $retVal = FALSE;
00138 
00139         $this->tokenID_basePrefix = $table . ':' . $uid . ':' . $field . ':' . $structurePath . ':' . $spKey;
00140 
00141         switch ($spKey) {
00142             case 'notify': // Simple notification
00143                 $resultArray = array(
00144                     'elements' => array(
00145                         array(
00146                             'matchString' => $content
00147                         )
00148                     )
00149                 );
00150                 $retVal = $resultArray;
00151             break;
00152             case 'substitute':
00153                 $tokenID = $this->makeTokenID();
00154                 $resultArray = array(
00155                     'content' => '{softref:' . $tokenID . '}',
00156                     'elements' => array(
00157                         array(
00158                             'matchString' => $content,
00159                             'subst' => array(
00160                                 'type' => 'string',
00161                                 'tokenID' => $tokenID,
00162                                 'tokenValue' => $content
00163                             )
00164                         )
00165                     )
00166                 );
00167                 $retVal = $resultArray;
00168             break;
00169             case 'images':
00170                 $retVal = $this->findRef_images($content, $spParams);
00171             break;
00172             case 'typolink':
00173                 $retVal = $this->findRef_typolink($content, $spParams);
00174             break;
00175             case 'typolink_tag':
00176                 $retVal = $this->findRef_typolink_tag($content, $spParams);
00177             break;
00178             case 'ext_fileref':
00179                 $retVal = $this->findRef_extension_fileref($content, $spParams);
00180             break;
00181             case 'TStemplate':
00182                 $retVal = $this->findRef_TStemplate($content, $spParams);
00183             break;
00184             case 'TSconfig':
00185                 $retVal = $this->findRef_TSconfig($content, $spParams);
00186             break;
00187             case 'email':
00188                 $retVal = $this->findRef_email($content, $spParams);
00189             break;
00190             case 'url':
00191                 $retVal = $this->findRef_url($content, $spParams);
00192             break;
00193             default:
00194                 $retVal = FALSE;
00195             break;
00196         }
00197 
00198         return $retVal;
00199     }
00200 
00201     /**
00202      * Finding image tags in the content.
00203      * All images that are not from external URLs will be returned with an info text
00204      * Will only return files in fileadmin/ and files in uploads/ folders which are prefixed with "RTEmagic[C|P]_" for substitution
00205      * Any "clear.gif" images are ignored.
00206      *
00207      * @param   string      The input content to analyse
00208      * @param   array       Parameters set for the softref parser key in TCA/columns
00209      * @return  array       Result array on positive matches, see description above. Otherwise false
00210      */
00211     function findRef_images($content, $spParams) {
00212 
00213             // Start HTML parser and split content by image tag:
00214         $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
00215         $splitContent = $htmlParser->splitTags('img', $content);
00216         $elements = array();
00217 
00218             // Traverse splitted parts:
00219         foreach ($splitContent as $k => $v) {
00220             if ($k % 2) {
00221 
00222                     // Get file reference:
00223                 $attribs = $htmlParser->get_tag_attributes($v);
00224                 $srcRef = t3lib_div::htmlspecialchars_decode($attribs[0]['src']);
00225                 $pI = pathinfo($srcRef);
00226 
00227                     // If it looks like a local image, continue. Otherwise ignore it.
00228                 $absPath = t3lib_div::getFileAbsFileName(PATH_site . $srcRef);
00229                 if (!$pI['scheme'] && !$pI['query'] && $absPath && $srcRef !== 'clear.gif') {
00230 
00231                         // Initialize the element entry with info text here:
00232                     $tokenID = $this->makeTokenID($k);
00233                     $elements[$k] = array();
00234                     $elements[$k]['matchString'] = $v;
00235 
00236                         // If the image seems to be from fileadmin/ folder or an RTE image, then proceed to set up substitution token:
00237                     if (t3lib_div::isFirstPartOfStr($srcRef, $this->fileAdminDir . '/') || (t3lib_div::isFirstPartOfStr($srcRef, 'uploads/') && preg_match('/^RTEmagicC_/', basename($srcRef)))) {
00238                             // Token and substitute value:
00239                         if (strstr($splitContent[$k], $attribs[0]['src'])) { // Make sure the value we work on is found and will get substituted in the content (Very important that the src-value is not DeHSC'ed)
00240                             $splitContent[$k] = str_replace($attribs[0]['src'], '{softref:' . $tokenID . '}', $splitContent[$k]); // Substitute value with token (this is not be an exact method if the value is in there twice, but we assume it will not)
00241                             $elements[$k]['subst'] = array(
00242                                 'type' => 'file',
00243                                 'relFileName' => $srcRef,
00244                                 'tokenID' => $tokenID,
00245                                 'tokenValue' => $attribs[0]['src'],
00246                             );
00247                             if (!@is_file($absPath)) { // Finally, notice if the file does not exist.
00248                                 $elements[$k]['error'] = 'File does not exist!';
00249                             }
00250                         } else {
00251                             $elements[$k]['error'] = 'Could not substitute image source with token!';
00252                         }
00253                     }
00254                 }
00255             }
00256         }
00257 
00258             // Return result:
00259         if (count($elements)) {
00260             $resultArray = array(
00261                 'content' => implode('', $splitContent),
00262                 'elements' => $elements
00263             );
00264 
00265             return $resultArray;
00266         }
00267     }
00268 
00269     /**
00270      * TypoLink value processing.
00271      * Will process input value as a TypoLink value.
00272      *
00273      * @param   string      The input content to analyse
00274      * @param   array       Parameters set for the softref parser key in TCA/columns. value "linkList" will split the string by comma before processing.
00275      * @return  array       Result array on positive matches, see description above. Otherwise false
00276      * @see tslib_content::typolink(), getTypoLinkParts()
00277      */
00278     function findRef_typolink($content, $spParams) {
00279 
00280             // First, split the input string by a comma if the "linkList" parameter is set.
00281             // An example: the link field for images in content elements of type "textpic" or "image". This field CAN be configured to define a link per image, separated by comma.
00282         if (is_array($spParams) && in_array('linkList', $spParams)) {
00283             $linkElement = explode(',', $content); // Preserving whitespace on purpose.
00284         } else {
00285             $linkElement = array($content); // If only one element, just set in this array to make it easy below.
00286         }
00287 
00288             // Traverse the links now:
00289         $elements = array();
00290         foreach ($linkElement as $k => $typolinkValue) {
00291             $tLP = $this->getTypoLinkParts($typolinkValue);
00292             $linkElement[$k] = $this->setTypoLinkPartsElement($tLP, $elements, $typolinkValue, $k);
00293         }
00294 
00295             // Return output:
00296         if (count($elements)) {
00297             $resultArray = array(
00298                 'content' => implode(',', $linkElement),
00299                 'elements' => $elements
00300             );
00301 
00302             return $resultArray;
00303         }
00304     }
00305 
00306     /**
00307      * TypoLink tag processing.
00308      * Will search for <link ...> tags in the content string and process any found.
00309      *
00310      * @param   string      The input content to analyse
00311      * @param   array       Parameters set for the softref parser key in TCA/columns
00312      * @return  array       Result array on positive matches, see description above. Otherwise false
00313      * @see tslib_content::typolink(), getTypoLinkParts()
00314      */
00315     function findRef_typolink_tag($content, $spParams) {
00316 
00317             // Parse string for special TYPO3 <link> tag:
00318         $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
00319         $linkTags = $htmlParser->splitTags('link', $content);
00320 
00321             // Traverse result:
00322         $elements = array();
00323         foreach ($linkTags as $k => $foundValue) {
00324             if ($k % 2) {
00325                 $typolinkValue = preg_replace('/<LINK[[:space:]]+/i', '', substr($foundValue, 0, -1));
00326                 $tLP = $this->getTypoLinkParts($typolinkValue);
00327                 $linkTags[$k] = '<LINK ' . $this->setTypoLinkPartsElement($tLP, $elements, $typolinkValue, $k) . '>';
00328             }
00329         }
00330 
00331             // Return output:
00332         if (count($elements)) {
00333             $resultArray = array(
00334                 'content' => implode('', $linkTags),
00335                 'elements' => $elements
00336             );
00337 
00338             return $resultArray;
00339         }
00340     }
00341 
00342     /**
00343      * Processing the content expected from a TypoScript template
00344      * This content includes references to files in fileadmin/ folders and file references in HTML tags like <img src="">, <a href=""> and <form action="">
00345      *
00346      * @param   string      The input content to analyse
00347      * @param   array       Parameters set for the softref parser key in TCA/columns
00348      * @return  array       Result array on positive matches, see description above. Otherwise false
00349      */
00350     function findRef_TStemplate($content, $spParams) {
00351         $elements = array();
00352 
00353             // First, try to find images and links:
00354         $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
00355         $splitContent = $htmlParser->splitTags('img,a,form', $content);
00356 
00357             // Traverse splitted parts:
00358         foreach ($splitContent as $k => $v) {
00359             if ($k % 2) {
00360 
00361                 $attribs = $htmlParser->get_tag_attributes($v);
00362 
00363                 $attributeName = '';
00364                 switch ($htmlParser->getFirstTagName($v)) {
00365                     case 'img':
00366                         $attributeName = 'src';
00367                     break;
00368                     case 'a':
00369                         $attributeName = 'href';
00370                     break;
00371                     case 'form':
00372                         $attributeName = 'action';
00373                     break;
00374                 }
00375 
00376                     // Get file reference:
00377                 if (isset($attribs[0][$attributeName])) {
00378                     $srcRef = t3lib_div::htmlspecialchars_decode($attribs[0][$attributeName]);
00379 
00380                         // Set entry:
00381                     $tokenID = $this->makeTokenID($k);
00382                     $elements[$k] = array();
00383                     $elements[$k]['matchString'] = $v;
00384 
00385                         // OK, if it looks like a local file from fileadmin/, include it:
00386                     $pI = pathinfo($srcRef);
00387                     $absPath = t3lib_div::getFileAbsFileName(PATH_site . $srcRef);
00388                     if (t3lib_div::isFirstPartOfStr($srcRef, $this->fileAdminDir . '/') && !$pI['query'] && $absPath) {
00389 
00390                             // Token and substitute value:
00391                         if (strstr($splitContent[$k], $attribs[0][$attributeName])) { // Very important that the src-value is not DeHSC'ed
00392                             $splitContent[$k] = str_replace($attribs[0][$attributeName], '{softref:' . $tokenID . '}', $splitContent[$k]);
00393                             $elements[$k]['subst'] = array(
00394                                 'type' => 'file',
00395                                 'relFileName' => $srcRef,
00396                                 'tokenID' => $tokenID,
00397                                 'tokenValue' => $attribs[0][$attributeName],
00398                             );
00399                             if (!@is_file($absPath)) {
00400                                 $elements[$k]['error'] = 'File does not exist!';
00401                             }
00402                         } else {
00403                             $elements[$k]['error'] = 'Could not substitute attribute (' . $attributeName . ') value with token!';
00404                         }
00405                     }
00406                 }
00407             }
00408         }
00409         $content = implode('', $splitContent);
00410 
00411             // Process free fileadmin/ references as well:
00412         $content = $this->fileadminReferences($content, $elements);
00413 
00414             // Return output:
00415         if (count($elements)) {
00416             $resultArray = array(
00417                 'content' => $content,
00418                 'elements' => $elements
00419             );
00420             return $resultArray;
00421         }
00422     }
00423 
00424     /**
00425      * Processes possible references inside of Page and User TSconfig fields.
00426      * Currently this only includes file references to fileadmin/ but in fact there are currently no properties that supports such references.
00427      *
00428      * @param   string      The input content to analyse
00429      * @param   array       Parameters set for the softref parser key in TCA/columns
00430      * @return  array       Result array on positive matches, see description above. Otherwise false
00431      */
00432     function findRef_TSconfig($content, $spParams) {
00433         $elements = array();
00434 
00435             // Process free fileadmin/ references from TSconfig
00436         $content = $this->fileadminReferences($content, $elements);
00437 
00438             // Return output:
00439         if (count($elements)) {
00440             $resultArray = array(
00441                 'content' => $content,
00442                 'elements' => $elements
00443             );
00444             return $resultArray;
00445         }
00446     }
00447 
00448     /**
00449      * Finding email addresses in content and making them substitutable.
00450      *
00451      * @param   string      The input content to analyse
00452      * @param   array       Parameters set for the softref parser key in TCA/columns
00453      * @return  array       Result array on positive matches, see description above. Otherwise false
00454      */
00455     function findRef_email($content, $spParams) {
00456         $resultArray = array();
00457 
00458             // email:
00459         $parts = preg_split("/([^[:alnum:]]+)([A-Za-z0-9\._-]+[@][A-Za-z0-9\._-]+[\.].[A-Za-z0-9]+)/", ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
00460         foreach ($parts as $idx => $value) {
00461             if ($idx % 3 == 2) {
00462 
00463                 $tokenID = $this->makeTokenID($idx);
00464                 $elements[$idx] = array();
00465                 $elements[$idx]['matchString'] = $value;
00466 
00467                 if (is_array($spParams) && in_array('subst', $spParams)) {
00468                     $parts[$idx] = '{softref:' . $tokenID . '}';
00469                     $elements[$idx]['subst'] = array(
00470                         'type' => 'string',
00471                         'tokenID' => $tokenID,
00472                         'tokenValue' => $value,
00473                     );
00474                 }
00475             }
00476         }
00477 
00478             // Return output:
00479         if (count($elements)) {
00480             $resultArray = array(
00481                 'content' => substr(implode('', $parts), 1, -1),
00482                 'elements' => $elements
00483             );
00484             return $resultArray;
00485         }
00486     }
00487 
00488     /**
00489      * Finding URLs in content
00490      *
00491      * @param   string      The input content to analyse
00492      * @param   array       Parameters set for the softref parser key in TCA/columns
00493      * @return  array       Result array on positive matches, see description above. Otherwise false
00494      */
00495     function findRef_url($content, $spParams) {
00496         $resultArray = array();
00497 
00498             // Fileadmin files:
00499         $parts = preg_split("/([^[:alnum:]\"']+)((http|ftp):\/\/[^[:space:]\"'<>]*)([[:space:]])/", ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
00500 
00501         foreach ($parts as $idx => $value) {
00502             if ($idx % 5 == 3) {
00503                 unset($parts[$idx]);
00504             }
00505             if ($idx % 5 == 2) {
00506 
00507                 $tokenID = $this->makeTokenID($idx);
00508                 $elements[$idx] = array();
00509                 $elements[$idx]['matchString'] = $value;
00510 
00511                 if (is_array($spParams) && in_array('subst', $spParams)) {
00512                     $parts[$idx] = '{softref:' . $tokenID . '}';
00513                     $elements[$idx]['subst'] = array(
00514                         'type' => 'string',
00515                         'tokenID' => $tokenID,
00516                         'tokenValue' => $value,
00517                     );
00518                 }
00519             }
00520         }
00521 
00522             // Return output:
00523         if (count($elements)) {
00524             $resultArray = array(
00525                 'content' => substr(implode('', $parts), 1, -1),
00526                 'elements' => $elements
00527             );
00528             return $resultArray;
00529         }
00530     }
00531 
00532     /**
00533      * Finding reference to files from extensions in content, but only to notify about their existence. No substitution
00534      *
00535      * @param   string      The input content to analyse
00536      * @param   array       Parameters set for the softref parser key in TCA/columns
00537      * @return  array       Result array on positive matches, see description above. Otherwise false
00538      */
00539     function findRef_extension_fileref($content, $spParams) {
00540         $resultArray = array();
00541 
00542             // Fileadmin files:
00543         $parts = preg_split("/([^[:alnum:]\"']+)(EXT:[[:alnum:]_]+\/[^[:space:]\"',]*)/", ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
00544 
00545         foreach ($parts as $idx => $value) {
00546             if ($idx % 3 == 2) {
00547 
00548                 $tokenID = $this->makeTokenID($idx);
00549                 $elements[$idx] = array();
00550                 $elements[$idx]['matchString'] = $value;
00551             }
00552         }
00553 
00554             // Return output:
00555         if (count($elements)) {
00556             $resultArray = array(
00557                 'content' => substr(implode('', $parts), 1, -1),
00558                 'elements' => $elements
00559             );
00560             return $resultArray;
00561         }
00562     }
00563 
00564 
00565     /*************************
00566      *
00567      * Helper functions
00568      *
00569      *************************/
00570 
00571     /**
00572      * Searches the content for a reference to a file in "fileadmin/".
00573      * When a match is found it will get substituted with a token.
00574      *
00575      * @param   string      Input content to analyse
00576      * @param   array       Element array to be modified with new entries. Passed by reference.
00577      * @return  string      Output content, possibly with tokens inserted.
00578      */
00579     function fileadminReferences($content, &$elements) {
00580 
00581             // Fileadmin files are found
00582         $parts = preg_split("/([^[:alnum:]]+)(" . $this->fileAdminDir . "\/[^[:space:]\"'<>]*)/", ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
00583 
00584             // Traverse files:
00585         foreach ($parts as $idx => $value) {
00586             if ($idx % 3 == 2) {
00587 
00588                     // when file is found, set up an entry for the element:
00589                 $tokenID = $this->makeTokenID('fileadminReferences:' . $idx);
00590                 $elements['fileadminReferences.' . $idx] = array();
00591                 $elements['fileadminReferences.' . $idx]['matchString'] = $value;
00592                 $elements['fileadminReferences.' . $idx]['subst'] = array(
00593                     'type' => 'file',
00594                     'relFileName' => $value,
00595                     'tokenID' => $tokenID,
00596                     'tokenValue' => $value,
00597                 );
00598                 $parts[$idx] = '{softref:' . $tokenID . '}';
00599 
00600                     // Check if the file actually exists:
00601                 $absPath = t3lib_div::getFileAbsFileName(PATH_site . $value);
00602                 if (!@is_file($absPath)) {
00603                     $elements['fileadminReferences.' . $idx]['error'] = 'File does not exist!';
00604                 }
00605             }
00606         }
00607 
00608             // Implode the content again, removing prefixed and trailing white space:
00609         return substr(implode('', $parts), 1, -1);
00610     }
00611 
00612     /**
00613      * Analyse content as a TypoLink value and return an array with properties.
00614      * TypoLinks format is: <link [typolink] [browser target] [css class]>. See tslib_content::typolink()
00615      * The syntax of the [typolink] part is: [typolink] = [page id or alias][,[type value]][#[anchor, if integer = tt_content uid]]
00616      * The extraction is based on how tslib_content::typolink() behaves.
00617      *
00618      * @param   string      TypoLink value.
00619      * @return  array       Array with the properties of the input link specified. The key "LINK_TYPE" will reveal the type. If that is blank it could not be determined.
00620      * @see tslib_content::typolink(), setTypoLinkPartsElement()
00621      */
00622     function getTypoLinkParts($typolinkValue) {
00623         $finalTagParts = array();
00624 
00625             // Split by space into link / target / class
00626         list($link_param, $browserTarget, $cssClass) = t3lib_div::trimExplode(' ', $typolinkValue, 1);
00627         if (strlen($browserTarget)) {
00628             $finalTagParts['target'] = $browserTarget;
00629         }
00630         if (strlen($cssClass)) {
00631             $finalTagParts['class'] = $cssClass;
00632         }
00633 
00634             // Parse URL:
00635         $pU = @parse_url($link_param);
00636 
00637             // Detecting the kind of reference:
00638         if (strstr($link_param, '@') && !$pU['scheme']) { // If it's a mail address:
00639             $link_param = preg_replace('/^mailto:/i', '', $link_param);
00640 
00641             $finalTagParts['LINK_TYPE'] = 'mailto';
00642             $finalTagParts['url'] = trim($link_param);
00643         } else {
00644             $isLocalFile = 0;
00645             $fileChar = intval(strpos($link_param, '/'));
00646             $urlChar = intval(strpos($link_param, '.'));
00647 
00648                 // Detects if a file is found in site-root (or is a 'virtual' simulateStaticDocument file!) and if so it will be treated like a normal file.
00649             list($rootFileDat) = explode('?', rawurldecode($link_param));
00650             $containsSlash = strstr($rootFileDat, '/');
00651             $rFD_fI = pathinfo($rootFileDat);
00652             if (trim($rootFileDat) && !$containsSlash && (@is_file(PATH_site . $rootFileDat) || t3lib_div::inList('php,html,htm', strtolower($rFD_fI['extension'])))) {
00653                 $isLocalFile = 1;
00654             } elseif ($containsSlash) {
00655                 $isLocalFile = 2; // Adding this so realurl directories are linked right (non-existing).
00656             }
00657 
00658             if ($pU['scheme'] || ($isLocalFile != 1 && $urlChar && (!$containsSlash || $urlChar < $fileChar))) { // url (external): If doubleSlash or if a '.' comes before a '/'.
00659                 $finalTagParts['LINK_TYPE'] = 'url';
00660                 $finalTagParts['url'] = $link_param;
00661             } elseif ($containsSlash || $isLocalFile) { // file (internal)
00662                 $splitLinkParam = explode('?', $link_param);
00663                 if (file_exists(rawurldecode($splitLinkParam[0])) || $isLocalFile) {
00664                     $finalTagParts['LINK_TYPE'] = 'file';
00665                     $finalTagParts['filepath'] = rawurldecode($splitLinkParam[0]);
00666                     $finalTagParts['query'] = $splitLinkParam[1];
00667                 }
00668             } else { // integer or alias (alias is without slashes or periods or commas, that is 'nospace,alphanum_x,lower,unique' according to definition in $TCA!)
00669                 $finalTagParts['LINK_TYPE'] = 'page';
00670 
00671                 $link_params_parts = explode('#', $link_param);
00672                 $link_param = trim($link_params_parts[0]); // Link-data del
00673 
00674                 if (strlen($link_params_parts[1])) {
00675                     $finalTagParts['anchor'] = trim($link_params_parts[1]);
00676                 }
00677 
00678                     // Splitting the parameter by ',' and if the array counts more than 1 element it's a id/type/? pair
00679                 $pairParts = t3lib_div::trimExplode(',', $link_param);
00680                 if (count($pairParts) > 1) {
00681                     $link_param = $pairParts[0];
00682                     $finalTagParts['type'] = $pairParts[1]; // Overruling 'type'
00683                 }
00684 
00685                     // Checking if the id-parameter is an alias.
00686                 if (strlen($link_param)) {
00687                     if (!t3lib_div::testInt($link_param)) {
00688                         $finalTagParts['alias'] = $link_param;
00689                         $link_param = $this->getPageIdFromAlias($link_param);
00690                     }
00691 
00692                     $finalTagParts['page_id'] = intval($link_param);
00693                 }
00694             }
00695         }
00696 
00697         return $finalTagParts;
00698     }
00699 
00700     /**
00701      * Recompile a TypoLink value from the array of properties made with getTypoLinkParts() into an elements array
00702      *
00703      * @param   array       TypoLink properties
00704      * @param   array       Array of elements to be modified with substitution / information entries.
00705      * @param   string      The content to process.
00706      * @param   integer     Index value of the found element - user to make unique but stable tokenID
00707      * @return  string      The input content, possibly containing tokens now according to the added substitution entries in $elements
00708      * @see getTypoLinkParts()
00709      */
00710     function setTypoLinkPartsElement($tLP, &$elements, $content, $idx) {
00711 
00712             // Initialize, set basic values. In any case a link will be shown
00713         $tokenID = $this->makeTokenID('setTypoLinkPartsElement:' . $idx);
00714         $elements[$tokenID . ':' . $idx] = array();
00715         $elements[$tokenID . ':' . $idx]['matchString'] = $content;
00716 
00717             // Based on link type, maybe do more:
00718         switch ((string) $tLP['LINK_TYPE']) {
00719             case 'mailto':
00720             case 'url':
00721                     // Mail addresses and URLs can be substituted manually:
00722                 $elements[$tokenID . ':' . $idx]['subst'] = array(
00723                     'type' => 'string',
00724                     'tokenID' => $tokenID,
00725                     'tokenValue' => $tLP['url'],
00726                 );
00727                     // Output content will be the token instead:
00728                 $content = '{softref:' . $tokenID . '}';
00729             break;
00730             case 'file':
00731                     // Process files found in fileadmin directory:
00732                 if (!$tLP['query']) { // We will not process files which has a query added to it. That will look like a script we don't want to move.
00733                     if (t3lib_div::isFirstPartOfStr($tLP['filepath'], $this->fileAdminDir . '/')) { // File must be inside fileadmin/
00734 
00735                             // Set up the basic token and token value for the relative file:
00736                         $elements[$tokenID . ':' . $idx]['subst'] = array(
00737                             'type' => 'file',
00738                             'relFileName' => $tLP['filepath'],
00739                             'tokenID' => $tokenID,
00740                             'tokenValue' => $tLP['filepath'],
00741                         );
00742 
00743                             // Depending on whether the file exists or not we will set the
00744                         $absPath = t3lib_div::getFileAbsFileName(PATH_site . $tLP['filepath']);
00745                         if (!@is_file($absPath)) {
00746                             $elements[$tokenID . ':' . $idx]['error'] = 'File does not exist!';
00747                         }
00748 
00749                             // Output content will be the token instead
00750                         $content = '{softref:' . $tokenID . '}';
00751                     } else {
00752                         return $content;
00753                     }
00754                 } else {
00755                     return $content;
00756                 }
00757             break;
00758             case 'page':
00759                     // Rebuild page reference typolink part:
00760                 $content = '';
00761 
00762                     // Set page id:
00763                 if ($tLP['page_id']) {
00764                     $content .= '{softref:' . $tokenID . '}';
00765                     $elements[$tokenID . ':' . $idx]['subst'] = array(
00766                         'type' => 'db',
00767                         'recordRef' => 'pages:' . $tLP['page_id'],
00768                         'tokenID' => $tokenID,
00769                         'tokenValue' => $tLP['alias'] ? $tLP['alias'] : $tLP['page_id'], // Set page alias if that was used.
00770                     );
00771                 }
00772 
00773                     // Add type if applicable
00774                 if (strlen($tLP['type'])) {
00775                     $content .= ',' . $tLP['type'];
00776                 }
00777 
00778                     // Add anchor if applicable
00779                 if (strlen($tLP['anchor'])) {
00780                     if (t3lib_div::testInt($tLP['anchor'])) { // Anchor is assumed to point to a content elements:
00781                             // Initialize a new entry because we have a new relation:
00782                         $newTokenID = $this->makeTokenID('setTypoLinkPartsElement:anchor:' . $idx);
00783                         $elements[$newTokenID . ':' . $idx] = array();
00784                         $elements[$newTokenID . ':' . $idx]['matchString'] = 'Anchor Content Element: ' . $tLP['anchor'];
00785 
00786                         $content .= '#{softref:' . $newTokenID . '}';
00787                         $elements[$newTokenID . ':' . $idx]['subst'] = array(
00788                             'type' => 'db',
00789                             'recordRef' => 'tt_content:' . $tLP['anchor'],
00790                             'tokenID' => $newTokenID,
00791                             'tokenValue' => $tLP['anchor'],
00792                         );
00793                     } else { // Anchor is a hardcoded string
00794                         $content .= '#' . $tLP['type'];
00795                     }
00796                 }
00797             break;
00798             default:
00799                 {
00800                 $elements[$tokenID . ':' . $idx]['error'] = 'Couldn\t decide typolink mode.';
00801                 return $content;
00802                 }
00803             break;
00804         }
00805 
00806             // Finally, for all entries that was rebuild with tokens, add target and class in the end:
00807         if (strlen($content) && strlen($tLP['target'])) {
00808             $content .= ' ' . $tLP['target'];
00809             if (strlen($tLP['class'])) {
00810                 $content .= ' ' . $tLP['class'];
00811             }
00812         }
00813 
00814             // Return rebuilt typolink value:
00815         return $content;
00816     }
00817 
00818     /**
00819      * Look up and return page uid for alias
00820      *
00821      * @param   integer     Page alias string value
00822      * @return  integer     Page uid corresponding to alias value.
00823      */
00824     function getPageIdFromAlias($link_param) {
00825         $pRec = t3lib_BEfunc::getRecordsByField('pages', 'alias', $link_param);
00826 
00827         return $pRec[0]['uid'];
00828     }
00829 
00830     /**
00831      * Make Token ID for input index.
00832      *
00833      * @param   string      suffix value.
00834      * @return  string      Token ID
00835      */
00836     function makeTokenID($index = '') {
00837         return md5($this->tokenID_basePrefix . ':' . $index);
00838     }
00839 }
00840 
00841 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_softrefproc.php'])) {
00842     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_softrefproc.php']);
00843 }
00844 
00845 ?>