Fixed bug #17184: Disable the CSRF protection in ExtDirect calls coming from the...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_softrefproc.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2003-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the Typo3 project. The Typo3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24 /**
25 * Soft Reference processing class
26 * "Soft References" are references to database elements, files, email addresses, URls etc.
27 * which are found in-text in content. The <link [page_id]> tag from typical bodytext fields
28 * are an example of this.
29 * This class contains generic parsers for the most well-known types
30 * which are default for most TYPO3 installations. Soft References can also be userdefined.
31 * The Soft Reference parsers are used by the system to find these references and process them accordingly in import/export actions and copy operations.
32 *
33 * $Id$
34 *
35 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
36 */
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 *
41 *
42 * 116: class t3lib_softrefproc
43 * 137: function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath='')
44 * 213: function findRef_images($content, $spParams)
45 * 280: function findRef_typolink($content, $spParams)
46 * 317: function findRef_typolink_tag($content, $spParams)
47 * 352: function findRef_TStemplate($content, $spParams)
48 * 434: function findRef_TSconfig($content, $spParams)
49 * 457: function findRef_email($content, $spParams)
50 * 497: function findRef_url($content, $spParams)
51 * 539: function findRef_extension_fileref($content, $spParams)
52 *
53 * SECTION: Helper functions
54 * 591: function fileadminReferences($content, &$elements)
55 * 634: function getTypoLinkParts($typolinkValue)
56 * 718: function setTypoLinkPartsElement($tLP, &$elements, $content, $idx)
57 * 833: function getPageIdFromAlias($link_param)
58 * 845: function makeTokenID($index='')
59 *
60 * TOTAL FUNCTIONS: 14
61 * (This index is automatically created/updated by the extension "extdeveval")
62 *
63 */
64
65
66 /**
67 * Example of usage
68 * // Soft References:
69 * if ($conf['softref'] && strlen($value)) { // Check if a TCA configured field has softreferences defined (see TYPO3 Core API document)
70 * $softRefs = t3lib_BEfunc::explodeSoftRefParserList($conf['softref']); // Explode the list of softreferences/parameters
71 * foreach($softRefs as $spKey => $spParams) { // Traverse soft references
72 * $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey); // create / get object
73 * if (is_object($softRefObj)) { // If there was an object returned...:
74 * $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams); // Do processing
75 *
76 * Result Array:
77 * The Result array should contain two keys: "content" and "elements".
78 * "content" is a string containing the input content but possibly with tokens inside.
79 * Tokens are strings like {softref:[tokenID]} which is a placeholder for a value extracted by a softref parser
80 * 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.
81 * "elements" is an array where the keys are insignificant, but the values are arrays with these keys:
82 * "matchString" => The value of the match. This is only for informational purposes to show what was found.
83 * "error" => An error message can be set here, like "file not found" etc.
84 * "subst" => array( // If this array is found there MUST be a token in the output content as well!
85 * "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.
86 * "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.
87 * "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)
88 * "relFileName" => (for "file" type): Relative filename. May not necessarily exist. This could be noticed in the error key.
89 * "recordRef" => (for "db" type) : Reference to DB record on the form [table]:[uid]. May not necessarily exist.
90 * "title" => Title of element (for backend information)
91 * "description" => Description of element (for backend information)
92 * )
93 *
94 */
95
96
97 /**
98 * Class for processing of the default soft reference types for CMS:
99 *
100 * - 'substitute' : A full field value targeted for manual substitution (for import /export features)
101 * - 'notify' : Just report if a value is found, nothing more.
102 * - 'images' : HTML <img> tags for RTE images / images from fileadmin/
103 * - 'typolink' : references to page id or file, possibly with anchor/target, possibly commaseparated list.
104 * - 'typolink_tag' : As typolink, but searching for <link> tag to encapsulate it.
105 * - 'TSconfig' processing (filerefs? Domains? what do we know...)
106 * - 'TStemplate' : freetext references to "fileadmin/" files.
107 * - 'email' : Email highlight
108 * - 'url' : URL highlights (with a scheme)
109 *
110 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
111 * @package TYPO3
112 * @subpackage t3lib
113 */
114 class t3lib_softrefproc {
115
116 // external configuration
117 var $fileAdminDir = 'fileadmin';
118
119
120 // Internal:
121 var $tokenID_basePrefix = '';
122
123 /**
124 * Main function through which all processing happens
125 *
126 * @param string Database table name
127 * @param string Field name for which processing occurs
128 * @param integer UID of the record
129 * @param string The content/value of the field
130 * @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.
131 * @param array Parameters of the softlink parser. Basically this is the content inside optional []-brackets after the softref keys. Parameters are exploded by ";"
132 * @param string If running from inside a FlexForm structure, this is the path of the tag.
133 * @return array Result array on positive matches, see description above. Otherwise false
134 */
135 function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath = '') {
136
137 $retVal = FALSE;
138
139 $this->tokenID_basePrefix = $table . ':' . $uid . ':' . $field . ':' . $structurePath . ':' . $spKey;
140
141 switch ($spKey) {
142 case 'notify': // Simple notification
143 $resultArray = array(
144 'elements' => array(
145 array(
146 'matchString' => $content
147 )
148 )
149 );
150 $retVal = $resultArray;
151 break;
152 case 'substitute':
153 $tokenID = $this->makeTokenID();
154 $resultArray = array(
155 'content' => '{softref:' . $tokenID . '}',
156 'elements' => array(
157 array(
158 'matchString' => $content,
159 'subst' => array(
160 'type' => 'string',
161 'tokenID' => $tokenID,
162 'tokenValue' => $content
163 )
164 )
165 )
166 );
167 $retVal = $resultArray;
168 break;
169 case 'images':
170 $retVal = $this->findRef_images($content, $spParams);
171 break;
172 case 'typolink':
173 $retVal = $this->findRef_typolink($content, $spParams);
174 break;
175 case 'typolink_tag':
176 $retVal = $this->findRef_typolink_tag($content, $spParams);
177 break;
178 case 'ext_fileref':
179 $retVal = $this->findRef_extension_fileref($content, $spParams);
180 break;
181 case 'TStemplate':
182 $retVal = $this->findRef_TStemplate($content, $spParams);
183 break;
184 case 'TSconfig':
185 $retVal = $this->findRef_TSconfig($content, $spParams);
186 break;
187 case 'email':
188 $retVal = $this->findRef_email($content, $spParams);
189 break;
190 case 'url':
191 $retVal = $this->findRef_url($content, $spParams);
192 break;
193 default:
194 $retVal = FALSE;
195 break;
196 }
197
198 return $retVal;
199 }
200
201 /**
202 * Finding image tags in the content.
203 * All images that are not from external URLs will be returned with an info text
204 * Will only return files in fileadmin/ and files in uploads/ folders which are prefixed with "RTEmagic[C|P]_" for substitution
205 * Any "clear.gif" images are ignored.
206 *
207 * @param string The input content to analyse
208 * @param array Parameters set for the softref parser key in TCA/columns
209 * @return array Result array on positive matches, see description above. Otherwise false
210 */
211 function findRef_images($content, $spParams) {
212
213 // Start HTML parser and split content by image tag:
214 $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
215 $splitContent = $htmlParser->splitTags('img', $content);
216 $elements = array();
217
218 // Traverse splitted parts:
219 foreach ($splitContent as $k => $v) {
220 if ($k % 2) {
221
222 // Get file reference:
223 $attribs = $htmlParser->get_tag_attributes($v);
224 $srcRef = t3lib_div::htmlspecialchars_decode($attribs[0]['src']);
225 $pI = pathinfo($srcRef);
226
227 // If it looks like a local image, continue. Otherwise ignore it.
228 $absPath = t3lib_div::getFileAbsFileName(PATH_site . $srcRef);
229 if (!$pI['scheme'] && !$pI['query'] && $absPath && $srcRef !== 'clear.gif') {
230
231 // Initialize the element entry with info text here:
232 $tokenID = $this->makeTokenID($k);
233 $elements[$k] = array();
234 $elements[$k]['matchString'] = $v;
235
236 // If the image seems to be from fileadmin/ folder or an RTE image, then proceed to set up substitution token:
237 if (t3lib_div::isFirstPartOfStr($srcRef, $this->fileAdminDir . '/') || (t3lib_div::isFirstPartOfStr($srcRef, 'uploads/') && preg_match('/^RTEmagicC_/', basename($srcRef)))) {
238 // Token and substitute value:
239 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)
240 $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)
241 $elements[$k]['subst'] = array(
242 'type' => 'file',
243 'relFileName' => $srcRef,
244 'tokenID' => $tokenID,
245 'tokenValue' => $attribs[0]['src'],
246 );
247 if (!@is_file($absPath)) { // Finally, notice if the file does not exist.
248 $elements[$k]['error'] = 'File does not exist!';
249 }
250 } else {
251 $elements[$k]['error'] = 'Could not substitute image source with token!';
252 }
253 }
254 }
255 }
256 }
257
258 // Return result:
259 if (count($elements)) {
260 $resultArray = array(
261 'content' => implode('', $splitContent),
262 'elements' => $elements
263 );
264
265 return $resultArray;
266 }
267 }
268
269 /**
270 * TypoLink value processing.
271 * Will process input value as a TypoLink value.
272 *
273 * @param string The input content to analyse
274 * @param array Parameters set for the softref parser key in TCA/columns. value "linkList" will split the string by comma before processing.
275 * @return array Result array on positive matches, see description above. Otherwise false
276 * @see tslib_content::typolink(), getTypoLinkParts()
277 */
278 function findRef_typolink($content, $spParams) {
279
280 // First, split the input string by a comma if the "linkList" parameter is set.
281 // 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.
282 if (is_array($spParams) && in_array('linkList', $spParams)) {
283 $linkElement = explode(',', $content); // Preserving whitespace on purpose.
284 } else {
285 $linkElement = array($content); // If only one element, just set in this array to make it easy below.
286 }
287
288 // Traverse the links now:
289 $elements = array();
290 foreach ($linkElement as $k => $typolinkValue) {
291 $tLP = $this->getTypoLinkParts($typolinkValue);
292 $linkElement[$k] = $this->setTypoLinkPartsElement($tLP, $elements, $typolinkValue, $k);
293 }
294
295 // Return output:
296 if (count($elements)) {
297 $resultArray = array(
298 'content' => implode(',', $linkElement),
299 'elements' => $elements
300 );
301
302 return $resultArray;
303 }
304 }
305
306 /**
307 * TypoLink tag processing.
308 * Will search for <link ...> tags in the content string and process any found.
309 *
310 * @param string The input content to analyse
311 * @param array Parameters set for the softref parser key in TCA/columns
312 * @return array Result array on positive matches, see description above. Otherwise false
313 * @see tslib_content::typolink(), getTypoLinkParts()
314 */
315 function findRef_typolink_tag($content, $spParams) {
316
317 // Parse string for special TYPO3 <link> tag:
318 $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
319 $linkTags = $htmlParser->splitTags('link', $content);
320
321 // Traverse result:
322 $elements = array();
323 foreach ($linkTags as $k => $foundValue) {
324 if ($k % 2) {
325 $typolinkValue = preg_replace('/<LINK[[:space:]]+/i', '', substr($foundValue, 0, -1));
326 $tLP = $this->getTypoLinkParts($typolinkValue);
327 $linkTags[$k] = '<LINK ' . $this->setTypoLinkPartsElement($tLP, $elements, $typolinkValue, $k) . '>';
328 }
329 }
330
331 // Return output:
332 if (count($elements)) {
333 $resultArray = array(
334 'content' => implode('', $linkTags),
335 'elements' => $elements
336 );
337
338 return $resultArray;
339 }
340 }
341
342 /**
343 * Processing the content expected from a TypoScript template
344 * This content includes references to files in fileadmin/ folders and file references in HTML tags like <img src="">, <a href=""> and <form action="">
345 *
346 * @param string The input content to analyse
347 * @param array Parameters set for the softref parser key in TCA/columns
348 * @return array Result array on positive matches, see description above. Otherwise false
349 */
350 function findRef_TStemplate($content, $spParams) {
351 $elements = array();
352
353 // First, try to find images and links:
354 $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
355 $splitContent = $htmlParser->splitTags('img,a,form', $content);
356
357 // Traverse splitted parts:
358 foreach ($splitContent as $k => $v) {
359 if ($k % 2) {
360
361 $attribs = $htmlParser->get_tag_attributes($v);
362
363 $attributeName = '';
364 switch ($htmlParser->getFirstTagName($v)) {
365 case 'img':
366 $attributeName = 'src';
367 break;
368 case 'a':
369 $attributeName = 'href';
370 break;
371 case 'form':
372 $attributeName = 'action';
373 break;
374 }
375
376 // Get file reference:
377 if (isset($attribs[0][$attributeName])) {
378 $srcRef = t3lib_div::htmlspecialchars_decode($attribs[0][$attributeName]);
379
380 // Set entry:
381 $tokenID = $this->makeTokenID($k);
382 $elements[$k] = array();
383 $elements[$k]['matchString'] = $v;
384
385 // OK, if it looks like a local file from fileadmin/, include it:
386 $pI = pathinfo($srcRef);
387 $absPath = t3lib_div::getFileAbsFileName(PATH_site . $srcRef);
388 if (t3lib_div::isFirstPartOfStr($srcRef, $this->fileAdminDir . '/') && !$pI['query'] && $absPath) {
389
390 // Token and substitute value:
391 if (strstr($splitContent[$k], $attribs[0][$attributeName])) { // Very important that the src-value is not DeHSC'ed
392 $splitContent[$k] = str_replace($attribs[0][$attributeName], '{softref:' . $tokenID . '}', $splitContent[$k]);
393 $elements[$k]['subst'] = array(
394 'type' => 'file',
395 'relFileName' => $srcRef,
396 'tokenID' => $tokenID,
397 'tokenValue' => $attribs[0][$attributeName],
398 );
399 if (!@is_file($absPath)) {
400 $elements[$k]['error'] = 'File does not exist!';
401 }
402 } else {
403 $elements[$k]['error'] = 'Could not substitute attribute (' . $attributeName . ') value with token!';
404 }
405 }
406 }
407 }
408 }
409 $content = implode('', $splitContent);
410
411 // Process free fileadmin/ references as well:
412 $content = $this->fileadminReferences($content, $elements);
413
414 // Return output:
415 if (count($elements)) {
416 $resultArray = array(
417 'content' => $content,
418 'elements' => $elements
419 );
420 return $resultArray;
421 }
422 }
423
424 /**
425 * Processes possible references inside of Page and User TSconfig fields.
426 * Currently this only includes file references to fileadmin/ but in fact there are currently no properties that supports such references.
427 *
428 * @param string The input content to analyse
429 * @param array Parameters set for the softref parser key in TCA/columns
430 * @return array Result array on positive matches, see description above. Otherwise false
431 */
432 function findRef_TSconfig($content, $spParams) {
433 $elements = array();
434
435 // Process free fileadmin/ references from TSconfig
436 $content = $this->fileadminReferences($content, $elements);
437
438 // Return output:
439 if (count($elements)) {
440 $resultArray = array(
441 'content' => $content,
442 'elements' => $elements
443 );
444 return $resultArray;
445 }
446 }
447
448 /**
449 * Finding email addresses in content and making them substitutable.
450 *
451 * @param string The input content to analyse
452 * @param array Parameters set for the softref parser key in TCA/columns
453 * @return array Result array on positive matches, see description above. Otherwise false
454 */
455 function findRef_email($content, $spParams) {
456 $resultArray = array();
457
458 // email:
459 $parts = preg_split("/([^[:alnum:]]+)([A-Za-z0-9\._-]+[@][A-Za-z0-9\._-]+[\.].[A-Za-z0-9]+)/", ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
460 foreach ($parts as $idx => $value) {
461 if ($idx % 3 == 2) {
462
463 $tokenID = $this->makeTokenID($idx);
464 $elements[$idx] = array();
465 $elements[$idx]['matchString'] = $value;
466
467 if (is_array($spParams) && in_array('subst', $spParams)) {
468 $parts[$idx] = '{softref:' . $tokenID . '}';
469 $elements[$idx]['subst'] = array(
470 'type' => 'string',
471 'tokenID' => $tokenID,
472 'tokenValue' => $value,
473 );
474 }
475 }
476 }
477
478 // Return output:
479 if (count($elements)) {
480 $resultArray = array(
481 'content' => substr(implode('', $parts), 1, -1),
482 'elements' => $elements
483 );
484 return $resultArray;
485 }
486 }
487
488 /**
489 * Finding URLs in content
490 *
491 * @param string The input content to analyse
492 * @param array Parameters set for the softref parser key in TCA/columns
493 * @return array Result array on positive matches, see description above. Otherwise false
494 */
495 function findRef_url($content, $spParams) {
496 $resultArray = array();
497
498 // Fileadmin files:
499 $parts = preg_split("/([^[:alnum:]\"']+)((http|ftp):\/\/[^[:space:]\"'<>]*)([[:space:]])/", ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
500
501 foreach ($parts as $idx => $value) {
502 if ($idx % 5 == 3) {
503 unset($parts[$idx]);
504 }
505 if ($idx % 5 == 2) {
506
507 $tokenID = $this->makeTokenID($idx);
508 $elements[$idx] = array();
509 $elements[$idx]['matchString'] = $value;
510
511 if (is_array($spParams) && in_array('subst', $spParams)) {
512 $parts[$idx] = '{softref:' . $tokenID . '}';
513 $elements[$idx]['subst'] = array(
514 'type' => 'string',
515 'tokenID' => $tokenID,
516 'tokenValue' => $value,
517 );
518 }
519 }
520 }
521
522 // Return output:
523 if (count($elements)) {
524 $resultArray = array(
525 'content' => substr(implode('', $parts), 1, -1),
526 'elements' => $elements
527 );
528 return $resultArray;
529 }
530 }
531
532 /**
533 * Finding reference to files from extensions in content, but only to notify about their existence. No substitution
534 *
535 * @param string The input content to analyse
536 * @param array Parameters set for the softref parser key in TCA/columns
537 * @return array Result array on positive matches, see description above. Otherwise false
538 */
539 function findRef_extension_fileref($content, $spParams) {
540 $resultArray = array();
541
542 // Fileadmin files:
543 $parts = preg_split("/([^[:alnum:]\"']+)(EXT:[[:alnum:]_]+\/[^[:space:]\"',]*)/", ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
544
545 foreach ($parts as $idx => $value) {
546 if ($idx % 3 == 2) {
547
548 $tokenID = $this->makeTokenID($idx);
549 $elements[$idx] = array();
550 $elements[$idx]['matchString'] = $value;
551 }
552 }
553
554 // Return output:
555 if (count($elements)) {
556 $resultArray = array(
557 'content' => substr(implode('', $parts), 1, -1),
558 'elements' => $elements
559 );
560 return $resultArray;
561 }
562 }
563
564
565 /*************************
566 *
567 * Helper functions
568 *
569 *************************/
570
571 /**
572 * Searches the content for a reference to a file in "fileadmin/".
573 * When a match is found it will get substituted with a token.
574 *
575 * @param string Input content to analyse
576 * @param array Element array to be modified with new entries. Passed by reference.
577 * @return string Output content, possibly with tokens inserted.
578 */
579 function fileadminReferences($content, &$elements) {
580
581 // Fileadmin files are found
582 $parts = preg_split("/([^[:alnum:]]+)(" . $this->fileAdminDir . "\/[^[:space:]\"'<>]*)/", ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
583
584 // Traverse files:
585 foreach ($parts as $idx => $value) {
586 if ($idx % 3 == 2) {
587
588 // when file is found, set up an entry for the element:
589 $tokenID = $this->makeTokenID('fileadminReferences:' . $idx);
590 $elements['fileadminReferences.' . $idx] = array();
591 $elements['fileadminReferences.' . $idx]['matchString'] = $value;
592 $elements['fileadminReferences.' . $idx]['subst'] = array(
593 'type' => 'file',
594 'relFileName' => $value,
595 'tokenID' => $tokenID,
596 'tokenValue' => $value,
597 );
598 $parts[$idx] = '{softref:' . $tokenID . '}';
599
600 // Check if the file actually exists:
601 $absPath = t3lib_div::getFileAbsFileName(PATH_site . $value);
602 if (!@is_file($absPath)) {
603 $elements['fileadminReferences.' . $idx]['error'] = 'File does not exist!';
604 }
605 }
606 }
607
608 // Implode the content again, removing prefixed and trailing white space:
609 return substr(implode('', $parts), 1, -1);
610 }
611
612 /**
613 * Analyse content as a TypoLink value and return an array with properties.
614 * TypoLinks format is: <link [typolink] [browser target] [css class]>. See tslib_content::typolink()
615 * The syntax of the [typolink] part is: [typolink] = [page id or alias][,[type value]][#[anchor, if integer = tt_content uid]]
616 * The extraction is based on how tslib_content::typolink() behaves.
617 *
618 * @param string TypoLink value.
619 * @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.
620 * @see tslib_content::typolink(), setTypoLinkPartsElement()
621 */
622 function getTypoLinkParts($typolinkValue) {
623 $finalTagParts = array();
624
625 // Split by space into link / target / class
626 list($link_param, $browserTarget, $cssClass) = t3lib_div::trimExplode(' ', $typolinkValue, 1);
627 if (strlen($browserTarget)) {
628 $finalTagParts['target'] = $browserTarget;
629 }
630 if (strlen($cssClass)) {
631 $finalTagParts['class'] = $cssClass;
632 }
633
634 // Parse URL:
635 $pU = @parse_url($link_param);
636
637 // Detecting the kind of reference:
638 if (strstr($link_param, '@') && !$pU['scheme']) { // If it's a mail address:
639 $link_param = preg_replace('/^mailto:/i', '', $link_param);
640
641 $finalTagParts['LINK_TYPE'] = 'mailto';
642 $finalTagParts['url'] = trim($link_param);
643 } else {
644 $isLocalFile = 0;
645 $fileChar = intval(strpos($link_param, '/'));
646 $urlChar = intval(strpos($link_param, '.'));
647
648 // 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.
649 list($rootFileDat) = explode('?', rawurldecode($link_param));
650 $containsSlash = strstr($rootFileDat, '/');
651 $rFD_fI = pathinfo($rootFileDat);
652 if (trim($rootFileDat) && !$containsSlash && (@is_file(PATH_site . $rootFileDat) || t3lib_div::inList('php,html,htm', strtolower($rFD_fI['extension'])))) {
653 $isLocalFile = 1;
654 } elseif ($containsSlash) {
655 $isLocalFile = 2; // Adding this so realurl directories are linked right (non-existing).
656 }
657
658 if ($pU['scheme'] || ($isLocalFile != 1 && $urlChar && (!$containsSlash || $urlChar < $fileChar))) { // url (external): If doubleSlash or if a '.' comes before a '/'.
659 $finalTagParts['LINK_TYPE'] = 'url';
660 $finalTagParts['url'] = $link_param;
661 } elseif ($containsSlash || $isLocalFile) { // file (internal)
662 $splitLinkParam = explode('?', $link_param);
663 if (file_exists(rawurldecode($splitLinkParam[0])) || $isLocalFile) {
664 $finalTagParts['LINK_TYPE'] = 'file';
665 $finalTagParts['filepath'] = rawurldecode($splitLinkParam[0]);
666 $finalTagParts['query'] = $splitLinkParam[1];
667 }
668 } else { // integer or alias (alias is without slashes or periods or commas, that is 'nospace,alphanum_x,lower,unique' according to definition in $TCA!)
669 $finalTagParts['LINK_TYPE'] = 'page';
670
671 $link_params_parts = explode('#', $link_param);
672 $link_param = trim($link_params_parts[0]); // Link-data del
673
674 if (strlen($link_params_parts[1])) {
675 $finalTagParts['anchor'] = trim($link_params_parts[1]);
676 }
677
678 // Splitting the parameter by ',' and if the array counts more than 1 element it's a id/type/? pair
679 $pairParts = t3lib_div::trimExplode(',', $link_param);
680 if (count($pairParts) > 1) {
681 $link_param = $pairParts[0];
682 $finalTagParts['type'] = $pairParts[1]; // Overruling 'type'
683 }
684
685 // Checking if the id-parameter is an alias.
686 if (strlen($link_param)) {
687 if (!t3lib_div::testInt($link_param)) {
688 $finalTagParts['alias'] = $link_param;
689 $link_param = $this->getPageIdFromAlias($link_param);
690 }
691
692 $finalTagParts['page_id'] = intval($link_param);
693 }
694 }
695 }
696
697 return $finalTagParts;
698 }
699
700 /**
701 * Recompile a TypoLink value from the array of properties made with getTypoLinkParts() into an elements array
702 *
703 * @param array TypoLink properties
704 * @param array Array of elements to be modified with substitution / information entries.
705 * @param string The content to process.
706 * @param integer Index value of the found element - user to make unique but stable tokenID
707 * @return string The input content, possibly containing tokens now according to the added substitution entries in $elements
708 * @see getTypoLinkParts()
709 */
710 function setTypoLinkPartsElement($tLP, &$elements, $content, $idx) {
711
712 // Initialize, set basic values. In any case a link will be shown
713 $tokenID = $this->makeTokenID('setTypoLinkPartsElement:' . $idx);
714 $elements[$tokenID . ':' . $idx] = array();
715 $elements[$tokenID . ':' . $idx]['matchString'] = $content;
716
717 // Based on link type, maybe do more:
718 switch ((string) $tLP['LINK_TYPE']) {
719 case 'mailto':
720 case 'url':
721 // Mail addresses and URLs can be substituted manually:
722 $elements[$tokenID . ':' . $idx]['subst'] = array(
723 'type' => 'string',
724 'tokenID' => $tokenID,
725 'tokenValue' => $tLP['url'],
726 );
727 // Output content will be the token instead:
728 $content = '{softref:' . $tokenID . '}';
729 break;
730 case 'file':
731 // Process files found in fileadmin directory:
732 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.
733 if (t3lib_div::isFirstPartOfStr($tLP['filepath'], $this->fileAdminDir . '/')) { // File must be inside fileadmin/
734
735 // Set up the basic token and token value for the relative file:
736 $elements[$tokenID . ':' . $idx]['subst'] = array(
737 'type' => 'file',
738 'relFileName' => $tLP['filepath'],
739 'tokenID' => $tokenID,
740 'tokenValue' => $tLP['filepath'],
741 );
742
743 // Depending on whether the file exists or not we will set the
744 $absPath = t3lib_div::getFileAbsFileName(PATH_site . $tLP['filepath']);
745 if (!@is_file($absPath)) {
746 $elements[$tokenID . ':' . $idx]['error'] = 'File does not exist!';
747 }
748
749 // Output content will be the token instead
750 $content = '{softref:' . $tokenID . '}';
751 } else {
752 return $content;
753 }
754 } else {
755 return $content;
756 }
757 break;
758 case 'page':
759 // Rebuild page reference typolink part:
760 $content = '';
761
762 // Set page id:
763 if ($tLP['page_id']) {
764 $content .= '{softref:' . $tokenID . '}';
765 $elements[$tokenID . ':' . $idx]['subst'] = array(
766 'type' => 'db',
767 'recordRef' => 'pages:' . $tLP['page_id'],
768 'tokenID' => $tokenID,
769 'tokenValue' => $tLP['alias'] ? $tLP['alias'] : $tLP['page_id'], // Set page alias if that was used.
770 );
771 }
772
773 // Add type if applicable
774 if (strlen($tLP['type'])) {
775 $content .= ',' . $tLP['type'];
776 }
777
778 // Add anchor if applicable
779 if (strlen($tLP['anchor'])) {
780 if (t3lib_div::testInt($tLP['anchor'])) { // Anchor is assumed to point to a content elements:
781 // Initialize a new entry because we have a new relation:
782 $newTokenID = $this->makeTokenID('setTypoLinkPartsElement:anchor:' . $idx);
783 $elements[$newTokenID . ':' . $idx] = array();
784 $elements[$newTokenID . ':' . $idx]['matchString'] = 'Anchor Content Element: ' . $tLP['anchor'];
785
786 $content .= '#{softref:' . $newTokenID . '}';
787 $elements[$newTokenID . ':' . $idx]['subst'] = array(
788 'type' => 'db',
789 'recordRef' => 'tt_content:' . $tLP['anchor'],
790 'tokenID' => $newTokenID,
791 'tokenValue' => $tLP['anchor'],
792 );
793 } else { // Anchor is a hardcoded string
794 $content .= '#' . $tLP['type'];
795 }
796 }
797 break;
798 default:
799 {
800 $elements[$tokenID . ':' . $idx]['error'] = 'Couldn\t decide typolink mode.';
801 return $content;
802 }
803 break;
804 }
805
806 // Finally, for all entries that was rebuild with tokens, add target and class in the end:
807 if (strlen($content) && strlen($tLP['target'])) {
808 $content .= ' ' . $tLP['target'];
809 if (strlen($tLP['class'])) {
810 $content .= ' ' . $tLP['class'];
811 }
812 }
813
814 // Return rebuilt typolink value:
815 return $content;
816 }
817
818 /**
819 * Look up and return page uid for alias
820 *
821 * @param integer Page alias string value
822 * @return integer Page uid corresponding to alias value.
823 */
824 function getPageIdFromAlias($link_param) {
825 $pRec = t3lib_BEfunc::getRecordsByField('pages', 'alias', $link_param);
826
827 return $pRec[0]['uid'];
828 }
829
830 /**
831 * Make Token ID for input index.
832 *
833 * @param string suffix value.
834 * @return string Token ID
835 */
836 function makeTokenID($index = '') {
837 return md5($this->tokenID_basePrefix . ':' . $index);
838 }
839 }
840
841 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_softrefproc.php'])) {
842 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_softrefproc.php']);
843 }
844
845 ?>