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