d9b9560d2d40bc09e2e0c1fd34083d304cced2f8
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / class.tslib_content.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-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 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * This class contains all main TypoScript features.
30 * This includes the rendering of TypoScript content objects (cObjects).
31 * Is the backbone of TypoScript Template rendering.
32 *
33 * There are lots of functions you can use from your include-scripts.
34 * The class "tslib_cObj" is normally instantiated and referred to as "cObj".
35 * When you call your own PHP-code typically through a USER or USER_INT cObject then it is this class that instantiates the object and calls the main method. Before it does so it will set (if you are using classes) a reference to itself in the internal variable "cObj" of the object. Thus you can access all functions and data from this class by $this->cObj->... from within you classes written to be USER or USER_INT content objects.
36 *
37 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
38 * @package TYPO3
39 * @subpackage tslib
40 */
41 class tslib_cObj {
42
43 var $align = array(
44 'center',
45 'right',
46 'left'
47 );
48
49 /**
50 * stdWrap functions in their correct order
51 *
52 * @see stdWrap()
53 */
54 var $stdWrapOrder = array(
55 'stdWrapPreProcess' => 'hook', // this is a placeholder for the first Hook
56 'cacheRead' => 'hook', // this is a placeholder for checking if the content is available in cache
57 'setContentToCurrent' => 'boolean',
58 'setContentToCurrent.' => 'array',
59 'setCurrent' => 'string',
60 'setCurrent.' => 'array',
61 'lang.' => 'array',
62 'data' => 'getText',
63 'data.' => 'array',
64 'field' => 'fieldName',
65 'field.' => 'array',
66 'current' => 'boolean',
67 'current.' => 'array',
68 'cObject' => 'cObject',
69 'cObject.' => 'array',
70 'numRows.' => 'array',
71 'filelist' => 'dir',
72 'filelist.' => 'array',
73 'preUserFunc' => 'functionName',
74 'stdWrapOverride' => 'hook', // this is a placeholder for the second Hook
75 'override' => 'string',
76 'override.' => 'array',
77 'preIfEmptyListNum' => 'listNum',
78 'preIfEmptyListNum.' => 'array',
79 'ifEmpty' => 'string',
80 'ifEmpty.' => 'array',
81 'ifBlank' => 'string',
82 'ifBlank.' => 'array',
83 'listNum' => 'listNum',
84 'listNum.' => 'array',
85 'trim' => 'boolean',
86 'trim.' => 'array',
87 'stdWrap' => 'stdWrap',
88 'stdWrap.' => 'array',
89 'stdWrapProcess' => 'hook', // this is a placeholder for the third Hook
90 'required' => 'boolean',
91 'required.' => 'array',
92 'if.' => 'array',
93 'fieldRequired' => 'fieldName',
94 'fieldRequired.' => 'array',
95 'csConv' => 'string',
96 'csConv.' => 'array',
97 'parseFunc' => 'objectpath',
98 'parseFunc.' => 'array',
99 'HTMLparser' => 'boolean',
100 'HTMLparser.' => 'array',
101 'split.' => 'array',
102 'replacement.' => 'array',
103 'prioriCalc' => 'boolean',
104 'prioriCalc.' => 'array',
105 'char' => 'integer',
106 'char.' => 'array',
107 'intval' => 'boolean',
108 'intval.' => 'array',
109 'hash' => 'string',
110 'hash.' => 'array',
111 'round' => 'boolean',
112 'round.' => 'array',
113 'numberFormat.' => 'array',
114 'expandList' => 'boolean',
115 'expandList.' => 'array',
116 'date' => 'dateconf',
117 'date.' => 'array',
118 'strftime' => 'strftimeconf',
119 'strftime.' => 'array',
120 'age' => 'boolean',
121 'age.' => 'array',
122 'case' => 'case',
123 'case.' => 'array',
124 'bytes' => 'boolean',
125 'bytes.' => 'array',
126 'substring' => 'parameters',
127 'substring.' => 'array',
128 'removeBadHTML' => 'boolean',
129 'removeBadHTML.' => 'array',
130 'cropHTML' => 'crop',
131 'cropHTML.' => 'array',
132 'stripHtml' => 'boolean',
133 'stripHtml.' => 'array',
134 'crop' => 'crop',
135 'crop.' => 'array',
136 'rawUrlEncode' => 'boolean',
137 'rawUrlEncode.' => 'array',
138 'htmlSpecialChars' => 'boolean',
139 'htmlSpecialChars.' => 'array',
140 'doubleBrTag' => 'string',
141 'doubleBrTag.' => 'array',
142 'br' => 'boolean',
143 'br.' => 'array',
144 'brTag' => 'string',
145 'brTag.' => 'array',
146 'encapsLines.' => 'array',
147 'keywords' => 'boolean',
148 'keywords.' => 'array',
149 'innerWrap' => 'wrap',
150 'innerWrap.' => 'array',
151 'innerWrap2' => 'wrap',
152 'innerWrap2.' => 'array',
153 'fontTag' => 'wrap',
154 'fontTag.' => 'array',
155 'addParams.' => 'array',
156 'textStyle.' => 'array',
157 'tableStyle.' => 'array',
158 'filelink.' => 'array',
159 'preCObject' => 'cObject',
160 'preCObject.' => 'array',
161 'postCObject' => 'cObject',
162 'postCObject.' => 'array',
163 'wrapAlign' => 'align',
164 'wrapAlign.' => 'array',
165 'typolink.' => 'array',
166 'TCAselectItem.' => 'array',
167 'space' => 'space',
168 'space.' => 'array',
169 'spaceBefore' => 'int',
170 'spaceBefore.' => 'array',
171 'spaceAfter' => 'int',
172 'spaceAfter.' => 'array',
173 'wrap' => 'wrap',
174 'wrap.' => 'array',
175 'noTrimWrap' => 'wrap',
176 'noTrimWrap.' => 'array',
177 'wrap2' => 'wrap',
178 'wrap2.' => 'array',
179 'dataWrap' => 'dataWrap',
180 'dataWrap.' => 'array',
181 'prepend' => 'cObject',
182 'prepend.' => 'array',
183 'append' => 'cObject',
184 'append.' => 'array',
185 'wrap3' => 'wrap',
186 'wrap3.' => 'array',
187 'orderedStdWrap' => 'stdWrap',
188 'orderedStdWrap.' => 'array',
189 'outerWrap' => 'wrap',
190 'outerWrap.' => 'array',
191 'insertData' => 'boolean',
192 'insertData.' => 'array',
193 'offsetWrap' => 'space',
194 'offsetWrap.' => 'array',
195 'postUserFunc' => 'functionName',
196 'postUserFuncInt' => 'functionName',
197 'prefixComment' => 'string',
198 'prefixComment.' => 'array',
199 'editIcons' => 'string',
200 'editIcons.' => 'array',
201 'editPanel' => 'boolean',
202 'editPanel.' => 'array',
203 'cacheStore' => 'hook', // this is a placeholder for storing the content in cache
204 'stdWrapPostProcess' => 'hook', // this is a placeholder for the last Hook
205 'debug' => 'boolean',
206 'debug.' => 'array',
207 'debugFunc' => 'boolean',
208 'debugFunc.' => 'array',
209 'debugData' => 'boolean',
210 'debugData.' => 'array'
211 );
212
213 /**
214 * Holds ImageMagick parameters and extensions used for compression
215 *
216 * @see IMGTEXT()
217 *
218 * 0= Default
219 * 1= Dont change! (removes all parameters for the image_object!!)
220 * 1x = GIFs
221 * 2x = JPGs
222 */
223 var $image_compression = array(
224 10 => array(
225 'params' => '', 'ext' => 'gif'
226 ),
227 11 => array(
228 'params' => '-colors 128', 'ext' => 'gif'
229 ),
230 12 => array(
231 'params' => '-colors 64', 'ext' => 'gif'
232 ),
233 13 => array(
234 'params' => '-colors 32', 'ext' => 'gif'
235 ),
236 14 => array(
237 'params' => '-colors 16', 'ext' => 'gif'
238 ),
239 15 => array(
240 'params' => '-colors 8', 'ext' => 'gif'
241 ),
242
243 20 => array(
244 'params' => '-quality 100', 'ext' => 'jpg'
245 ),
246 21 => array(
247 'params' => '-quality 90', 'ext' => 'jpg'
248 ),
249 22 => array(
250 'params' => '-quality 80', 'ext' => 'jpg'
251 ),
252 23 => array(
253 'params' => '-quality 70', 'ext' => 'jpg'
254 ),
255 24 => array(
256 'params' => '-quality 60', 'ext' => 'jpg'
257 ),
258 25 => array(
259 'params' => '-quality 50', 'ext' => 'jpg'
260 ),
261 26 => array(
262 'params' => '-quality 40', 'ext' => 'jpg'
263 ),
264 27 => array(
265 'params' => '-quality 30', 'ext' => 'jpg'
266 ),
267 28 => array(
268 'params' => '-quality 20', 'ext' => 'jpg'
269 ),
270
271 30 => array(
272 'params' => '-colors 256', 'ext' => 'png'
273 ),
274 31 => array(
275 'params' => '-colors 128', 'ext' => 'png'
276 ),
277 32 => array(
278 'params' => '-colors 64', 'ext' => 'png'
279 ),
280 33 => array(
281 'params' => '-colors 32', 'ext' => 'png'
282 ),
283 34 => array(
284 'params' => '-colors 16', 'ext' => 'png'
285 ),
286 35 => array(
287 'params' => '-colors 8', 'ext' => 'png'
288 ),
289 39 => array(
290 'params' => '', 'ext' => 'png'
291 ),
292 );
293
294 /**
295 * ImageMagick parameters for image effects
296 *
297 * @see IMGTEXT()
298 */
299 var $image_effects = array(
300 1 => '-rotate 90',
301 2 => '-rotate 270',
302 3 => '-rotate 180',
303 10 => '-colorspace GRAY',
304 11 => '-sharpen 70',
305 20 => '-normalize',
306 23 => '-contrast',
307 25 => '-gamma 1.3',
308 26 => '-gamma 0.8'
309 );
310
311 /**
312 * Loaded with the current data-record.
313 *
314 * If the instance of this class is used to render records from the database those records are found in this array.
315 * The function stdWrap has TypoScript properties that fetch field-data from this array.
316 * @see init()
317 */
318 var $data = array();
319 protected $table = '';
320 var $oldData = array(); // Used for backup...
321 var $alternativeData = ''; // If this is set with an array before stdWrap, it's used instead of $this->data in the data-property in stdWrap
322 var $parameters = array(); // Used by the parseFunc function and is loaded with tag-parameters when parsing tags.
323 var $currentValKey = 'currentValue_kidjls9dksoje';
324 var $currentRecord = ''; // This is set to the [table]:[uid] of the record delivered in the $data-array, if the cObjects CONTENT or RECORD is in operation. Note that $GLOBALS['TSFE']->currentRecord is set to an equal value but always indicating the latest record rendered.
325 var $currentRecordTotal = 0; // Set in cObj->RECORDS and cObj->CONTENT to the current number of records selected in a query.
326 var $currentRecordNumber = 0; // Incremented in cObj->RECORDS and cObj->CONTENT before each record rendering.
327 var $parentRecordNumber = 0; // Incremented in parent cObj->RECORDS and cObj->CONTENT before each record rendering.
328 var $parentRecord = array(); // If the tslib_cObj was started from CONTENT, RECORD or SEARCHRESULT cObject's this array has two keys, 'data' and 'currentRecord' which indicates the record and data for the parent cObj.
329 var $regObj; // This may be set as a reference to the calling object of eg. cObjGetSingle. Anyway, just use it as you like. It's used in productsLib.inc for example.
330
331
332 // internal
333 var $INT_include = 0; // Is set to 1 if the instance of this cObj is executed from a *_INT plugin (see pagegen, bottom of document)
334 var $checkPid_cache = array(); // This is used by checkPid, that checks if pages are accessible. The $checkPid_cache['page_uid'] is set TRUE or FALSE upon this check featuring a caching function for the next request.
335 var $checkPid_badDoktypeList = '255';
336 var $lastTypoLinkUrl = ''; // This will be set by typoLink() to the url of the most recent link created.
337 var $lastTypoLinkTarget = ''; // DO. link target.
338 var $lastTypoLinkLD = array();
339 var $substMarkerCache = array(); // Caching substituteMarkerArrayCached function
340 var $recordRegister = array(); // array that registers rendered content elements (or any table) to make sure they are not rendered recursively!
341 var $cObjHookObjectsArr = array(); // Containig hooks for userdefined cObjects
342 protected $stdWrapHookObjects = array(); // Containing hook objects for stdWrap
343 protected $getImgResourceHookObjects; // Containing hook objects for getImgResource
344
345 /**
346 * @var array with members of tslib_content_abstract
347 */
348 protected $contentObjects = array();
349
350 /**
351 * Set to TRUE by doConvertToUserIntObject() if USER object wants to become USER_INT
352 */
353 public $doConvertToUserIntObject = FALSE;
354
355 /**
356 * Indicates current object type. Can hold one of OBJECTTYPE_ constants or FALSE.
357 * The value is set and reset inside USER() function. Any time outside of
358 * USER() it is FALSE.
359 */
360 protected $userObjectType = FALSE;
361
362 /**
363 * Indicates that object type is USER.
364 *
365 * @see tslib_cObjh::$userObjectType
366 */
367 const OBJECTTYPE_USER_INT = 1;
368
369 /**
370 * Indicates that object type is USER.
371 *
372 * @see tslib_cObjh::$userObjectType
373 */
374 const OBJECTTYPE_USER = 2;
375
376 /**
377 * Class constructor.
378 * Well, it has to be called manually since it is not a real constructor function.
379 * So after making an instance of the class, call this function and pass to it a database record and the tablename from where the record is from. That will then become the "current" record loaded into memory and accessed by the .fields property found in eg. stdWrap.
380 *
381 * @param array $data the record data that is rendered.
382 * @param string $table the table that the data record is from.
383 * @return void
384 */
385 function start($data, $table = '') {
386 global $TYPO3_CONF_VARS;
387 $this->data = $data;
388 $this->table = $table;
389 $this->currentRecord = $table ? $table . ':' . $this->data['uid'] : '';
390 $this->parameters = array();
391 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_content.php']['cObjTypeAndClass'])) {
392 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_content.php']['cObjTypeAndClass'] as $classArr) {
393 $this->cObjHookObjectsArr[$classArr[0]] = t3lib_div::getUserObj($classArr[1]);
394 }
395 }
396
397 $this->stdWrapHookObjects = array();
398 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_content.php']['stdWrap'])) {
399 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_content.php']['stdWrap'] as $classData) {
400 $hookObject = t3lib_div::getUserObj($classData);
401
402 if (!($hookObject instanceof tslib_content_stdWrapHook)) {
403 throw new UnexpectedValueException(
404 $classData . ' must implement interface tslib_content_stdWrapHook',
405 1195043965
406 );
407 }
408
409 $this->stdWrapHookObjects[] = $hookObject;
410 }
411 }
412
413 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_content.php']['postInit'])) {
414 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_content.php']['postInit'] as $classData) {
415 $postInitializationProcessor = t3lib_div::getUserObj($classData);
416
417 if (!($postInitializationProcessor instanceof tslib_content_PostInitHook)) {
418 throw new UnexpectedValueException(
419 $classData . ' must implement interface tslib_content_PostInitHook',
420 1274563549
421 );
422 }
423
424 $postInitializationProcessor->postProcessContentObjectInitialization($this);
425 }
426 }
427 }
428
429 /**
430 * Clone helper.
431 *
432 * Resets the references to the TypoScript Content Object implementation
433 * objects of tslib_content_*. Otherwise they would still point to the
434 * original tslib_cObj instance's tslib_content_* instances, they in return
435 * would back-reference to the original tslib_cObj instance instead of the
436 * newly cloned tslib_cObj instance.
437 *
438 * @see http://bugs.typo3.org/view.php?id=16568
439 */
440 public function __clone() {
441 $this->contentObjects = array();
442 }
443
444 /**
445 * Gets the 'getImgResource' hook objects.
446 * The first call initializes the accordant objects.
447 *
448 * @return array The 'getImgResource' hook objects (if any)
449 */
450 protected function getGetImgResourceHookObjects() {
451 if (!isset($this->getImgResourceHookObjects)) {
452 $this->getImgResourceHookObjects = array();
453
454 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImgResource'])) {
455 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImgResource'] as $classData) {
456 $hookObject = t3lib_div::getUserObj($classData);
457
458 if (!($hookObject instanceof tslib_cObj_getImgResourceHook)) {
459 throw new UnexpectedValueException(
460 '$hookObject must implement interface tslib_cObj_getImgResourceHook',
461 1218636383
462 );
463 }
464
465 $this->getImgResourceHookObjects[] = $hookObject;
466 }
467 }
468 }
469
470 return $this->getImgResourceHookObjects;
471 }
472
473 /**
474 * Sets the internal variable parentRecord with information about current record.
475 * If the tslib_cObj was started from CONTENT, RECORD or SEARCHRESULT cObject's this array has two keys, 'data' and 'currentRecord' which indicates the record and data for the parent cObj.
476 *
477 * @param array $data: The record array
478 * @param string $currentRecord: This is set to the [table]:[uid] of the record delivered in the $data-array, if the cObjects CONTENT or RECORD is in operation. Note that $GLOBALS['TSFE']->currentRecord is set to an equal value but always indicating the latest record rendered.
479 * @return void
480 * @access private
481 */
482 function setParent($data, $currentRecord) {
483 $this->parentRecord = array(
484 'data' => $data,
485 'currentRecord' => $currentRecord
486 );
487 }
488
489
490
491 /***********************************************
492 *
493 * CONTENT_OBJ:
494 *
495 ***********************************************/
496
497 /**
498 * Returns the "current" value.
499 * The "current" value is just an internal variable that can be used by functions to pass a single value on to another function later in the TypoScript processing.
500 * It's like "load accumulator" in the good old C64 days... basically a "register" you can use as you like.
501 * The TSref will tell if functions are setting this value before calling some other object so that you know if it holds any special information.
502 *
503 * @return mixed The "current" value
504 */
505 function getCurrentVal() {
506 return $this->data[$this->currentValKey];
507 }
508
509 /**
510 * Sets the "current" value.
511 *
512 * @param mixed The variable that you want to set as "current"
513 * @return void
514 * @see getCurrentVal()
515 */
516 function setCurrentVal($value) {
517 $this->data[$this->currentValKey] = $value;
518 }
519
520 /**
521 * Rendering of a "numerical array" of cObjects from TypoScript
522 * Will call ->cObjGetSingle() for each cObject found and accumulate the output.
523 *
524 * @param array $setup: array with cObjects as values.
525 * @param string $addKey: A prefix for the debugging information
526 * @return string Rendered output from the cObjects in the array.
527 * @see cObjGetSingle()
528 */
529 function cObjGet($setup, $addKey = '') {
530 if (is_array($setup)) {
531 $sKeyArray = t3lib_TStemplate::sortedKeyList($setup);
532 $content = '';
533 foreach ($sKeyArray as $theKey) {
534 $theValue = $setup[$theKey];
535 if (intval($theKey) && !strstr($theKey, '.')) {
536 $conf = $setup[$theKey . '.'];
537 $content .= $this->cObjGetSingle($theValue, $conf, $addKey . $theKey); // Get the contentObject
538 }
539 }
540 return $content;
541 }
542 }
543
544 /**
545 * Renders a content object
546 *
547 * @param string The content object name, eg. "TEXT" or "USER" or "IMAGE"
548 * @param array The array with TypoScript properties for the content object
549 * @param string A string label used for the internal debugging tracking.
550 * @return string cObject output
551 */
552 function cObjGetSingle($name, $conf, $TSkey = '__') {
553 global $TYPO3_CONF_VARS;
554
555 $content = '';
556 // Checking that the function is not called eternally. This is done by interrupting at a depth of 100
557 $GLOBALS['TSFE']->cObjectDepthCounter--;
558 if ($GLOBALS['TSFE']->cObjectDepthCounter > 0) {
559 $name = trim($name);
560 if ($GLOBALS['TT']->LR)
561 $GLOBALS['TT']->push($TSkey, $name);
562
563 // Checking if the COBJ is a reference to another object. (eg. name of 'blabla.blabla = < styles.something')
564 if (substr($name, 0, 1) == '<') {
565 $key = trim(substr($name, 1));
566 $cF = t3lib_div::makeInstance('t3lib_TSparser');
567 // $name and $conf is loaded with the referenced values.
568 $old_conf = $conf;
569 list ($name, $conf) = $cF->getVal($key, $GLOBALS['TSFE']->tmpl->setup);
570 if (is_array($old_conf) && count($old_conf)) {
571 $conf = $this->joinTSarrays($conf, $old_conf);
572 }
573 // Getting the cObject
574 $GLOBALS['TT']->incStackPointer();
575 $content .= $this->cObjGetSingle($name, $conf, $key);
576 $GLOBALS['TT']->decStackPointer();
577 } else {
578
579 $hooked = FALSE;
580 // Application defined cObjects
581 foreach ($this->cObjHookObjectsArr as $cObjName => $hookObj) {
582 if (($name === $cObjName) && method_exists($hookObj, 'cObjGetSingleExt')) {
583 $content .= $hookObj->cObjGetSingleExt($name, $conf, $TSkey, $this);
584 $hooked = TRUE;
585 }
586 }
587 if (!$hooked) {
588 $contentObject = $this->getContentObject($name);
589 if ($contentObject) {
590 $content .= $contentObject->render($conf);
591 } else {
592 // call hook functions for extra processing
593 if ($name && is_array($TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_content.php']['cObjTypeAndClassDefault'])) {
594 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_content.php']['cObjTypeAndClassDefault'] as $classData) {
595 $hookObject = t3lib_div::getUserObj($classData);
596
597 if (!($hookObject instanceof tslib_content_cObjGetSingleHook)) {
598 throw new UnexpectedValueException(
599 '$hookObject must implement interface tslib_content_cObjGetSingleHook',
600 1195043731
601 );
602 }
603 /* @var $hookObject tslib_content_cObjGetSingleHook */
604 $content .= $hookObject->getSingleContentObject($name, (array) $conf, $TSkey, $this);
605 }
606 } else {
607 // log error in AdminPanel
608 $warning = sprintf('Content Object "%s" does not exist', $name);
609 $GLOBALS['TT']->setTSlogMessage($warning, 2);
610 }
611 }
612 }
613 }
614 if ($GLOBALS['TT']->LR)
615 $GLOBALS['TT']->pull($content);
616 }
617 // Increasing on exit...
618 $GLOBALS['TSFE']->cObjectDepthCounter++;
619 return $content;
620 }
621
622 /**
623 * Returns a new content object of type $name.
624 *
625 * @param string $name
626 * @return tslib_content_abstract
627 */
628 public function getContentObject($name) {
629 $classMapping = array(
630 'TEXT' => 'Text',
631 'CASE' => 'Case',
632 'CLEARGIF' => 'ClearGif',
633 'COBJ_ARRAY' => 'ContentObjectArray',
634 'COA' => 'ContentObjectArray',
635 'COA_INT' => 'ContentObjectArrayInternal',
636 'USER' => 'User',
637 'USER_INT' => 'UserInternal',
638 'FILE' => 'File',
639 'IMAGE' => 'Image',
640 'IMG_RESOURCE' => 'ImageResource',
641 'IMGTEXT' => 'ImageText',
642 'CONTENT' => 'Content',
643 'RECORDS' => 'Records',
644 'HMENU' => 'HierarchicalMenu',
645 'CTABLE' => 'ContentTable',
646 'OTABLE' => 'OffsetTable',
647 'COLUMNS' => 'Columns',
648 'HRULER' => 'HorizontalRuler',
649 'CASEFUNC' => 'Case',
650 'LOAD_REGISTER' => 'LoadRegister',
651 'RESTORE_REGISTER' => 'RestoreRegister',
652 'FORM' => 'Form',
653 'SEARCHRESULT' => 'SearchResult',
654 'TEMPLATE' => 'Template',
655 'FLUIDTEMPLATE' => 'FluidTemplate',
656 'MULTIMEDIA' => 'Multimedia',
657 'MEDIA' => 'Media',
658 'SWFOBJECT' => 'ShockwaveFlashObject',
659 'FLOWPLAYER' => 'FlowPlayer',
660 'QTOBJECT' => 'QuicktimeObject',
661 'SVG' => 'ScalableVectorGraphics',
662 'EDITPANEL' => 'EditPanel',
663 );
664 $name = $classMapping[$name];
665
666 if (!array_key_exists($name, $this->contentObjects)) {
667 try {
668 $this->contentObjects[$name] = t3lib_div::makeInstance('tslib_content_' . $name, $this);
669 } catch (ReflectionException $e) {
670 $this->contentObjects[$name] = NULL;
671 }
672 }
673 return $this->contentObjects[$name];
674 }
675
676
677 /********************************************
678 *
679 * Functions rendering content objects (cObjects)
680 *
681 ********************************************/
682
683 /**
684 * Rendering the cObject, HTML
685 *
686 * @param array array of TypoScript properties
687 * @return string Output
688 * @deprecated since 6.0, will be removed in two versions
689 */
690 function HTML($conf) {
691 t3lib_div::logDeprecatedFunction();
692 return '';
693 }
694
695 /**
696 * Rendering the cObject, FLOWPLAYER
697 *
698 * @param array $conf array of TypoScript properties
699 * @return string Output
700 */
701 function FLOWPLAYER($conf) {
702 return $this->getContentObject('FLOWPLAYER')->render($conf);
703 }
704
705
706 /**
707 * Rendering the cObject, TEXT
708 *
709 * @param array array of TypoScript properties
710 * @return string Output
711 */
712 function TEXT($conf) {
713 return $this->getContentObject('TEXT')->render($conf);
714 }
715
716 /**
717 * Rendering the cObject, CLEARGIF
718 *
719 * @param array array of TypoScript properties
720 * @return string Output
721 */
722 function CLEARGIF($conf) {
723 return $this->getContentObject('CLEARGIF')->render($conf);
724 }
725
726 /**
727 * Rendering the cObject, COBJ_ARRAY / COA and COBJ_ARRAY_INT
728 *
729 * @param array array of TypoScript properties
730 * @param string If "INT" then the cObject is a "COBJ_ARRAY_INT" (non-cached), otherwise just "COBJ_ARRAY" (cached)
731 * @return string Output
732 */
733 function COBJ_ARRAY($conf, $ext = '') {
734 if ($ext === 'INT') {
735 return $this->getContentObject('COA_INT')->render($conf);
736 } else {
737 return $this->getContentObject('COA')->render($conf);
738 }
739 }
740
741 /**
742 * Rendering the cObject, USER and USER_INT
743 *
744 * @param array array of TypoScript properties
745 * @param string If "INT" then the cObject is a "USER_INT" (non-cached), otherwise just "USER" (cached)
746 * @return string Output
747 */
748 function USER($conf, $ext = '') {
749 if ($ext === 'INT') {
750 return $this->getContentObject('USER_INT')->render($conf);
751 } else {
752 return $this->getContentObject('USER')->render($conf);
753 }
754 }
755
756 /**
757 * Retrieves a type of object called as USER or USER_INT. Object can detect their
758 * type by using this call. It returns OBJECTTYPE_USER_INT or OBJECTTYPE_USER depending on the
759 * current object execution. In all other cases it will return FALSE to indicate
760 * a call out of context.
761 *
762 * @return mixed One of OBJECTTYPE_ class constants or FALSE
763 */
764 public function getUserObjectType() {
765 return $this->userObjectType;
766 }
767
768 /**
769 * Sets the user object type
770 *
771 * @param mixed $userObjectType
772 * @return void
773 */
774 public function setUserObjectType($userObjectType) {
775 $this->userObjectType = $userObjectType;
776 }
777
778 /**
779 * Requests the current USER object to be converted to USER_INT.
780 *
781 * @return void
782 */
783 public function convertToUserIntObject() {
784 if ($this->userObjectType !== self::OBJECTTYPE_USER) {
785 $GLOBALS['TT']->setTSlogMessage('tslib_cObj::convertToUserIntObject() ' . 'is called in the wrong context or for the wrong object type', 2);
786 } else {
787 $this->doConvertToUserIntObject = TRUE;
788 }
789 }
790
791 /**
792 * Rendering the cObject, FILE
793 *
794 * @param array array of TypoScript properties
795 * @return string Output
796 */
797 function FILE($conf) {
798 return $this->getContentObject('FILE')->render($conf);
799 }
800
801 /**
802 * Rendering the cObject, IMAGE
803 *
804 * @param array array of TypoScript properties
805 * @return string Output
806 * @see cImage()
807 */
808 function IMAGE($conf) {
809 return $this->getContentObject('IMAGE')->render($conf);
810 }
811
812 /**
813 * Rendering the cObject, IMG_RESOURCE
814 *
815 * @param array array of TypoScript properties
816 * @return string Output
817 * @see getImgResource()
818 */
819 function IMG_RESOURCE($conf) {
820 return $this->getContentObject('IMG_RESOURCE')->render($conf);
821 }
822
823 /**
824 * Rendering the cObject, IMGTEXT
825 *
826 * @param array array of TypoScript properties
827 * @return string Output
828 */
829 function IMGTEXT($conf) {
830 return $this->getContentObject('IMGTEXT')->render($conf);
831 }
832
833 /**
834 * Rendering the cObject, CONTENT
835 *
836 * @param array array of TypoScript properties
837 * @return string Output
838 */
839 function CONTENT($conf) {
840 return $this->getContentObject('CONTENT')->render($conf);
841 }
842
843 /**
844 * Rendering the cObject, RECORDS
845 *
846 * @param array array of TypoScript properties
847 * @return string Output
848 */
849 function RECORDS($conf) {
850 return $this->getContentObject('RECORDS')->render($conf);
851 }
852
853 /**
854 * Rendering the cObject, HMENU
855 *
856 * @param array array of TypoScript properties
857 * @return string Output
858 */
859 function HMENU($conf) {
860 return $this->getContentObject('HMENU')->render($conf);
861 }
862
863 /**
864 * Rendering the cObject, CTABLE
865 *
866 * @param array array of TypoScript properties
867 * @return string Output
868 */
869 function CTABLE($conf) {
870 return $this->getContentObject('CTABLE')->render($conf);
871 }
872
873 /**
874 * Rendering the cObject, OTABLE
875 *
876 * @param array array of TypoScript properties
877 * @return string Output
878 */
879 function OTABLE($conf) {
880 return $this->getContentObject('OTABLE')->render($conf);
881 }
882
883 /**
884 * Rendering the cObject, COLUMNS
885 *
886 * @param array array of TypoScript properties
887 * @return string Output
888 */
889 function COLUMNS($conf) {
890 return $this->getContentObject('COLUMNS')->render($conf);
891 }
892
893 /**
894 * Rendering the cObject, HRULER
895 *
896 * @param array array of TypoScript properties
897 * @return string Output
898 */
899 function HRULER($conf) {
900 return $this->getContentObject('HRULER')->render($conf);
901 }
902
903 /**
904 * Rendering the cObject, CASE
905 *
906 * @param array array of TypoScript properties
907 * @return string Output
908 */
909 function CASEFUNC($conf) {
910 return $this->getContentObject('CASE')->render($conf);
911 }
912
913 /**
914 * Rendering the cObject, LOAD_REGISTER and RESTORE_REGISTER
915 * NOTICE: This cObject does NOT return any content since it just sets internal data based on the TypoScript properties.
916 *
917 * @param array array of TypoScript properties
918 * @param string If "RESTORE_REGISTER" then the cObject rendered is "RESTORE_REGISTER", otherwise "LOAD_REGISTER"
919 * @return string Empty string (the cObject only sets internal data!)
920 */
921 function LOAD_REGISTER($conf, $name) {
922 if ($name === 'RESTORE_REGISTER') {
923 return $this->getContentObject('RESTORE_REGISTER')->render($conf);
924 } else {
925 return $this->getContentObject('LOAD_REGISTER')->render($conf);
926 }
927 }
928
929 /**
930 * Rendering the cObject, FORM
931 *
932 * @param array array of TypoScript properties
933 * @param array Alternative formdata overriding whatever comes from TypoScript
934 * @return string Output
935 */
936 function FORM($conf, $formData = '') {
937 return $this->getContentObject('FORM')->render($conf, $formData);
938 }
939
940 /**
941 * Rendering the cObject, SEARCHRESULT
942 *
943 * @param array array of TypoScript properties
944 * @return string Output
945 */
946 function SEARCHRESULT($conf) {
947 return $this->getContentObject('SEARCHRESULT')->render($conf);
948 }
949
950 /**
951 * Rendering the cObject, PHP_SCRIPT, PHP_SCRIPT_INT and PHP_SCRIPT_EXT
952 *
953 * @param array array of TypoScript properties
954 * @param string If "INT", then rendering "PHP_SCRIPT_INT"; If "EXT", then rendering "PHP_SCRIPT_EXT"; Default is rendering "PHP_SCRIPT" (cached)
955 * @return string Output
956 * @deprecated and unused since 6.0, will be removed two versions later
957 */
958 function PHP_SCRIPT($conf, $ext = '') {
959 t3lib_div::logDeprecatedFunction();
960 return '';
961 }
962
963 /**
964 * Rendering the cObject, TEMPLATE
965 *
966 * @param array array of TypoScript properties
967 * @return string Output
968 * @see substituteMarkerArrayCached()
969 */
970 function TEMPLATE($conf) {
971 return $this->getContentObject('TEMPLATE')->render($conf);
972 }
973
974 /**
975 * Rendering the cObject, FLUIDTEMPLATE
976 *
977 * @param array array of TypoScript properties
978 * @return string the HTML output
979 * @author Steffen Ritter <info@steffen-ritter.net>
980 * @author Benjamin Mack <benni@typo3.org>
981 */
982 protected function FLUIDTEMPLATE(array $conf) {
983 return $this->getContentObject('FLUIDTEMPLATE')->render($conf);
984 }
985
986 /**
987 * Rendering the cObject, MULTIMEDIA
988 *
989 * @param array array of TypoScript properties
990 * @return string Output
991 */
992 function MULTIMEDIA($conf) {
993 return $this->getContentObject('MULTIMEDIA')->render($conf);
994 }
995
996 /**
997 * Rendering the cObject, MEDIA
998 *
999 * @param array array of TypoScript properties
1000 * @return string Output
1001 */
1002 public function MEDIA($conf) {
1003 return $this->getContentObject('MEDIA')->render($conf);
1004 }
1005
1006 /**
1007 * Rendering the cObject, SWFOBJECT
1008 *
1009 * @param array array of TypoScript properties
1010 * @return string Output
1011 */
1012 public function SWFOBJECT($conf) {
1013 return $this->getContentObject('SWFOBJECT')->render($conf);
1014 }
1015
1016 /**
1017 * Rendering the cObject, QTOBJECT
1018 *
1019 * @param array array of TypoScript properties
1020 * @return string Output
1021 */
1022 public function QTOBJECT($conf) {
1023 return $this->getContentObject('QTOBJECT')->render($conf);
1024 }
1025
1026 /**
1027 * Rendering the cObject, SVG
1028 *
1029 * @param array array of TypoScript properties
1030 * @return string Output
1031 */
1032 public function SVG($conf) {
1033 return $this->getContentObject('SVG')->render($conf);
1034 }
1035
1036 /************************************
1037 *
1038 * Various helper functions for content objects:
1039 *
1040 ************************************/
1041
1042
1043 /**
1044 * Converts a given config in Flexform to a conf-array
1045 * @param string Flexform data
1046 * @param array array to write the data into, by reference
1047 * @param boolean is set if called recursive. Don't call function with this parameter, it's used inside the function only
1048 * @access public
1049 *
1050 */
1051 public function readFlexformIntoConf($flexData, &$conf, $recursive = FALSE) {
1052 if ($recursive === FALSE) {
1053 $flexData = t3lib_div::xml2array($flexData, 'T3');
1054 }
1055
1056 if (is_array($flexData)) {
1057 if (isset($flexData['data']['sDEF']['lDEF'])) {
1058 $flexData = $flexData['data']['sDEF']['lDEF'];
1059 }
1060
1061 foreach ($flexData as $key => $value) {
1062 if (is_array($value['el']) && count($value['el']) > 0) {
1063 foreach ($value['el'] as $ekey => $element) {
1064 if (isset($element['vDEF'])) {
1065 $conf[$ekey] = $element['vDEF'];
1066 } else {
1067 if (is_array($element)) {
1068 $this->readFlexformIntoConf($element, $conf[$key][key($element)][$ekey], TRUE);
1069 } else {
1070 $this->readFlexformIntoConf($element, $conf[$key][$ekey], TRUE);
1071 }
1072 }
1073 }
1074 } else {
1075 $this->readFlexformIntoConf($value['el'], $conf[$key], TRUE);
1076 }
1077 if ($value['vDEF']) {
1078 $conf[$key] = $value['vDEF'];
1079 }
1080 }
1081 }
1082 }
1083
1084
1085 /**
1086 * Returns all parents of the given PID (Page UID) list
1087 *
1088 * @param string A list of page Content-Element PIDs (Page UIDs) / stdWrap
1089 * @param array stdWrap array for the list
1090 * @return string A list of PIDs
1091 * @access private
1092 */
1093 function getSlidePids($pidList, $pidConf) {
1094 $pidList = isset($pidConf)
1095 ? trim($this->stdWrap($pidList, $pidConf))
1096 : trim($pidList);
1097 if (!strcmp($pidList, '')) {
1098 $pidList = 'this';
1099 }
1100 if (trim($pidList)) {
1101 $listArr = t3lib_div::intExplode(',', str_replace('this', $GLOBALS['TSFE']->contentPid, $pidList));
1102 $listArr = $this->checkPidArray($listArr);
1103 }
1104 $pidList = array();
1105 if (is_array($listArr) && count($listArr)) {
1106 foreach ($listArr as $uid) {
1107 $page = $GLOBALS['TSFE']->sys_page->getPage($uid);
1108 if (!$page['is_siteroot']) {
1109 $pidList[] = $page['pid'];
1110 }
1111 }
1112 }
1113 return implode(',', $pidList);
1114 }
1115
1116 /**
1117 * Returns a default value for a form field in the FORM cObject.
1118 * Page CANNOT be cached because that would include the inserted value for the current user.
1119 *
1120 * @param boolean If noValueInsert OR if the no_cache flag for this page is NOT set, the original default value is returned.
1121 * @param string $fieldName: The POST var name to get default value for
1122 * @param string $defaultVal: The current default value
1123 * @return string The default value, either from INPUT var or the current default, based on whether caching is enabled or not.
1124 * @access private
1125 */
1126 function getFieldDefaultValue($noValueInsert, $fieldName, $defaultVal) {
1127 if (!$GLOBALS['TSFE']->no_cache || (!isset($_POST[$fieldName]) && !isset($_GET[$fieldName])) || $noValueInsert) {
1128 return $defaultVal;
1129 } else {
1130 return t3lib_div::_GP($fieldName);
1131 }
1132 }
1133
1134 /**
1135 * Returns a <img> tag with the image file defined by $file and processed according to the properties in the TypoScript array.
1136 * Mostly this function is a sub-function to the IMAGE function which renders the IMAGE cObject in TypoScript.
1137 * This function is called by "$this->cImage($conf['file'],$conf);" from IMAGE().
1138 *
1139 * @param string File TypoScript resource
1140 * @param array TypoScript configuration properties
1141 * @return string <img> tag, (possibly wrapped in links and other HTML) if any image found.
1142 * @access private
1143 * @see IMAGE()
1144 */
1145 function cImage($file, $conf) {
1146 $info = $this->getImgResource($file, $conf['file.']);
1147 $GLOBALS['TSFE']->lastImageInfo = $info;
1148 if (is_array($info)) {
1149 $info[3] = t3lib_div::png_to_gif_by_imagemagick($info[3]);
1150 $GLOBALS['TSFE']->imagesOnPage[] = $info[3]; // This array is used to collect the image-refs on the page...
1151
1152
1153 $altParam = $this->getAltParam($conf);
1154 if($conf['params'] && !isset($conf['params.'])) {
1155 $params = ' ' . $conf['params'];
1156 } else {
1157 $params = isset($conf['params.'])
1158 ? ' ' . $this->stdWrap($conf['params'], $conf['params.'])
1159 : '';
1160 }
1161 $theValue = '<img src="' . htmlspecialchars($GLOBALS['TSFE']->absRefPrefix .
1162 t3lib_div::rawUrlEncodeFP($info[3])) . '" width="' . $info[0] . '" height="' . $info[1] . '"' .
1163 $this->getBorderAttr(' border="' . intval($conf['border']) . '"') .
1164 $params .
1165 ($altParam) .
1166 (!empty($GLOBALS['TSFE']->xhtmlDoctype) ? ' /' : '') .
1167 '>';
1168 $linkWrap = isset($conf['linkWrap.'])
1169 ? $this->stdWrap($conf['linkWrap'], $conf['linkWrap.'])
1170 : $conf['linkWrap'];
1171 if ($linkWrap) {
1172 $theValue = $this->linkWrap($theValue, $linkWrap);
1173 } elseif ($conf['imageLinkWrap']) {
1174 $theValue = $this->imageLinkWrap($theValue, $info['origFile'], $conf['imageLinkWrap.']);
1175 }
1176 $wrap = isset($conf['wrap.'])
1177 ? $this->stdWrap($conf['wrap'], $conf['wrap.'])
1178 : $conf['wrap'];
1179 if($wrap) {
1180 $theValue = $this->wrap($theValue, $conf['wrap']);
1181 }
1182 return $theValue;
1183 }
1184 }
1185
1186 /**
1187 * Returns the 'border' attribute for an <img> tag only if the doctype is not xhtml_strict, xhtml_11, xhtml_2 or html5
1188 * or if the config parameter 'disableImgBorderAttr' is not set.
1189 *
1190 * @param string the border attribute
1191 * @return string the border attribute
1192 */
1193 function getBorderAttr($borderAttr) {
1194 if (! t3lib_div::inList('xhtml_strict,xhtml_11,xhtml_2', $GLOBALS['TSFE']->xhtmlDoctype) &&
1195 $GLOBALS['TSFE']->config['config']['doctype'] != 'html5' &&
1196 ! $GLOBALS['TSFE']->config['config']['disableImgBorderAttr']) {
1197 return $borderAttr;
1198 }
1199 }
1200
1201 /**
1202 * Wraps the input string in link-tags that opens the image in a new window.
1203 *
1204 * @param string String to wrap, probably an <img> tag
1205 * @param string The original image file
1206 * @param array TypoScript properties for the "imageLinkWrap" function
1207 * @return string The input string, $string, wrapped as configured.
1208 * @see cImage()
1209 */
1210 function imageLinkWrap($string, $imageFile, $conf) {
1211 $a1 = '';
1212 $a2 = '';
1213 $content = $string;
1214 $enable = isset($conf['enable.'])
1215 ? $this->stdWrap($conf['enable'], $conf['enable.'])
1216 : $conf['enable'];
1217 if ($enable) {
1218 $content = $this->typolink($string, $conf['typolink.']);
1219 if(isset($conf['file.'])) {
1220 $imageFile = $this->stdWrap($imageFile, $conf['file.']);
1221 }
1222
1223 // imageFileLink:
1224 if ($content == $string && @is_file($imageFile)) {
1225 $parameterNames = array('width', 'height', 'effects', 'alternativeTempPath', 'bodyTag', 'title', 'wrap');
1226 $parameters = array();
1227
1228 $sample = isset($conf['sample.'])
1229 ? $this->stdWrap($conf['sample'], $conf['sample.'])
1230 : $conf['sample'];
1231 if ($sample) {
1232 $parameters['sample'] = 1;
1233 }
1234
1235 foreach ($parameterNames as $parameterName) {
1236 if(isset($conf[$parameterName.'.'])) {
1237 $conf[$parameterName] = $this->stdWrap($conf[$parameterName], $conf[$parameterName.'.']);
1238 }
1239 if (isset($conf[$parameterName]) && $conf[$parameterName]) {
1240 $parameters[$parameterName] = $conf[$parameterName];
1241 }
1242 }
1243
1244 $parametersEncoded = base64_encode(serialize($parameters));
1245
1246 $md5_value = t3lib_div::hmac(
1247 implode(
1248 '|',
1249 array($imageFile, $parametersEncoded)
1250 )
1251 );
1252
1253 $params = '&md5=' . $md5_value;
1254 foreach (str_split($parametersEncoded, 64) as $index => $chunk) {
1255 $params .= '&parameters' . rawurlencode('[') . $index . rawurlencode(']') . '=' . rawurlencode($chunk);
1256 }
1257
1258 $url = $GLOBALS['TSFE']->absRefPrefix . 'index.php?eID=tx_cms_showpic&file=' . rawurlencode($imageFile) . $params;
1259
1260 $directImageLink = isset($conf['directImageLink.'])
1261 ? $this->stdWrap($conf['directImageLink'], $conf['directImageLink.'])
1262 : $conf['directImageLink'];
1263 if ($directImageLink) {
1264 $imgResourceConf = array(
1265 'file' => $imageFile,
1266 'file.' => $conf
1267 );
1268 $url = $this->IMG_RESOURCE($imgResourceConf);
1269 if (!$url) {
1270 // if no imagemagick / gm is available
1271 $url = $imageFile;
1272 }
1273 }
1274
1275 // Create TARGET-attribute only if the right doctype is used
1276 if (!t3lib_div::inList('xhtml_strict,xhtml_11,xhtml_2', $GLOBALS['TSFE']->xhtmlDoctype)) {
1277 $target = isset($conf['target.'])
1278 ? $this->stdWrap($conf['target'], $conf['target.'])
1279 : $conf['target'];
1280 if ($target) {
1281 $target = sprintf(' target="%s"', $target);
1282 } else {
1283 $target = ' target="thePicture"';
1284 }
1285 } else {
1286 $target = '';
1287 }
1288 $conf['JSwindow'] = isset($conf['JSwindow.'])
1289 ? $this->stdWrap($conf['JSwindow'], $conf['JSwindow.'])
1290 : $conf['JSwindow'];
1291 if ($conf['JSwindow']) {
1292 if ($conf['JSwindow.']['altUrl'] || $conf['JSwindow.']['altUrl.']) {
1293 $altUrl = isset($conf['JSwindow.']['altUrl.'])
1294 ? $this->stdWrap($conf['JSwindow.']['altUrl'], $conf['JSwindow.']['altUrl.'])
1295 : $conf['JSwindow.']['altUrl'];
1296 if ($altUrl) {
1297 $url = $altUrl .
1298 ($conf['JSwindow.']['altUrl_noDefaultParams'] ? '' : '?file=' .
1299 rawurlencode($imageFile) . $params);
1300 }
1301 }
1302 $gifCreator = t3lib_div::makeInstance('tslib_gifbuilder');
1303 $gifCreator->init();
1304 $gifCreator->mayScaleUp = 0;
1305
1306 $dims = $gifCreator->getImageScale($gifCreator->getImageDimensions($imageFile), $conf['width'], $conf['height'], '');
1307 $JSwindowExpand = isset($conf['JSwindow.']['expand.'])
1308 ? $this->stdWrap($conf['JSwindow.']['expand'], $conf['JSwindow.']['expand.'])
1309 : $conf['JSwindow.']['expand'];
1310 $offset = t3lib_div::intExplode(',', $JSwindowExpand . ',');
1311
1312 $newWindow = isset($conf['JSwindow.']['newWindow.'])
1313 ? $this->stdWrap($conf['JSwindow.']['newWindow'], $conf['JSwindow.']['newWindow.'])
1314 : $conf['JSwindow.']['newWindow'];
1315 $a1 = '<a href="' . htmlspecialchars($url) . '" onclick="' .
1316 htmlspecialchars('openPic(\'' . $GLOBALS['TSFE']->baseUrlWrap($url) . '\',\'' .
1317 ($newWindow ? md5($url) : 'thePicture') . '\',\'width=' .
1318 ($dims[0] + $offset[0]) . ',height=' . ($dims[1] + $offset[1]) .
1319 ',status=0,menubar=0\'); return false;') . '"' .
1320 $target . $GLOBALS['TSFE']->ATagParams . '>';
1321 $a2 = '</a>';
1322 $GLOBALS['TSFE']->setJS('openPic');
1323 } else {
1324 $conf['linkParams.']['parameter'] = $url;
1325 $string = $this->typoLink($string, $conf['linkParams.']);
1326 }
1327
1328 if(isset($conf['stdWrap.'])) {
1329 $string = $this->stdWrap($string, $conf['stdWrap.']);
1330 }
1331
1332 $content = $a1 . $string . $a2;
1333 }
1334 }
1335
1336 return $content;
1337 }
1338
1339 /**
1340 * Returns content of a file. If it's an image the content of the file is not returned but rather an image tag is.
1341 *
1342 * @param string The filename, being a TypoScript resource data type
1343 * @param string Additional parameters (attributes). Default is empty alt and title tags.
1344 * @return string If jpg,gif,jpeg,png: returns image_tag with picture in. If html,txt: returns content string
1345 * @see FILE()
1346 */
1347 function fileResource($fName, $addParams = 'alt="" title=""') {
1348 $incFile = $GLOBALS['TSFE']->tmpl->getFileName($fName);
1349 if ($incFile) {
1350 $fileinfo = t3lib_div::split_fileref($incFile);
1351 if (t3lib_div::inList('jpg,gif,jpeg,png', $fileinfo['fileext'])) {
1352 $imgFile = $incFile;
1353 $imgInfo = @getImageSize($imgFile);
1354 return '<img src="' . $GLOBALS['TSFE']->absRefPrefix . $imgFile .
1355 '" width="' . $imgInfo[0] . '" height="' . $imgInfo[1] . '"' .
1356 $this->getBorderAttr(' border="0"') . ' ' . $addParams . ' />';
1357 } elseif (filesize($incFile) < 1024 * 1024) {
1358 return $GLOBALS['TSFE']->tmpl->fileContent($incFile);
1359 }
1360 }
1361 }
1362
1363 /**
1364 * Sets the SYS_LASTCHANGED timestamp if input timestamp is larger than current value.
1365 * The SYS_LASTCHANGED timestamp can be used by various caching/indexing applications to determine if the page has new content.
1366 * Therefore you should call this function with the last-changed timestamp of any element you display.
1367 *
1368 * @param integer Unix timestamp (number of seconds since 1970)
1369 * @return void
1370 * @see tslib_fe::setSysLastChanged()
1371 */
1372 function lastChanged($tstamp) {
1373 $tstamp = intval($tstamp);
1374 if ($tstamp > intval($GLOBALS['TSFE']->register['SYS_LASTCHANGED'])) {
1375 $GLOBALS['TSFE']->register['SYS_LASTCHANGED'] = $tstamp;
1376 }
1377 }
1378
1379 /**
1380 * Wraps the input string by the $wrap value and implements the "linkWrap" data type as well.
1381 * The "linkWrap" data type means that this function will find any integer encapsulated in {} (curly braces) in the first wrap part and substitute it with the corresponding page uid from the rootline where the found integer is pointing to the key in the rootline. See link below.
1382 *
1383 * @param string Input string
1384 * @param string A string where the first two parts separated by "|" (vertical line) will be wrapped around the input string
1385 * @return string Wrapped output string
1386 * @see wrap(), cImage(), FILE()
1387 */
1388 function linkWrap($content, $wrap) {
1389 $wrapArr = explode('|', $wrap);
1390 if (preg_match('/\{([0-9]*)\}/', $wrapArr[0], $reg)) {
1391 if ($uid = $GLOBALS['TSFE']->tmpl->rootLine[$reg[1]]['uid']) {
1392 $wrapArr[0] = str_replace($reg[0], $uid, $wrapArr[0]);
1393 }
1394 }
1395 return trim($wrapArr[0]) . $content . trim($wrapArr[1]);
1396 }
1397
1398 /**
1399 * An abstraction method which creates an alt or title parameter for an HTML img, applet, area or input element and the FILE content element.
1400 * From the $conf array it implements the properties "altText", "titleText" and "longdescURL"
1401 *
1402 * @param array TypoScript configuration properties
1403 * @param boolean If set, the longdesc attribute will be generated - must only be used for img elements!
1404 * @return string Parameter string containing alt and title parameters (if any)
1405 * @see IMGTEXT(), FILE(), FORM(), cImage(), filelink()
1406 */
1407 function getAltParam($conf, $longDesc = TRUE) {
1408 $altText = isset($conf['altText.'])
1409 ? trim($this->stdWrap($conf['altText'], $conf['altText.']))
1410 : trim($conf['altText']);
1411 $titleText = isset($conf['titleText.'])
1412 ? trim($this->stdWrap($conf['titleText'], $conf['titleText.']))
1413 : trim($conf['titleText']);
1414 if (isset($conf['longdescURL.']) && $GLOBALS['TSFE']->config['config']['doctype'] != 'html5') {
1415 $longDesc = $this->typoLink_URL($conf['longdescURL.']);
1416 } else {
1417 $longDesc = trim($conf['longdescURL']);
1418 }
1419
1420 // "alt":
1421 $altParam = ' alt="' . htmlspecialchars($altText) . '"';
1422
1423 // "title":
1424 $emptyTitleHandling = 'useAlt';
1425 $emptyTitleHandling = isset($conf['emptyTitleHandling.'])
1426 ? $this->stdWrap($conf['emptyTitleHandling'], $conf['emptyTitleHandling.'])
1427 : $conf['emptyTitleHandling'];
1428 // choices: 'keepEmpty' | 'useAlt' | 'removeAttr'
1429 if ($titleText || $emptyTitleHandling == 'keepEmpty') {
1430 $altParam .= ' title="' . htmlspecialchars($titleText) . '"';
1431 } elseif (!$titleText && $emptyTitleHandling == 'useAlt') {
1432 $altParam .= ' title="' . htmlspecialchars($altText) . '"';
1433 }
1434
1435 // "longDesc" URL
1436 if ($longDesc) {
1437 $altParam .= ' longdesc="' . htmlspecialchars(strip_tags($longDesc)) . '"';
1438 }
1439
1440 return $altParam;
1441 }
1442
1443 /**
1444 * Removes forbidden characters and spaces from name/id attributes in the form tag and formfields
1445 *
1446 * @param string Input string
1447 * @return string the cleaned string
1448 * @see FORM()
1449 */
1450 function cleanFormName($name) {
1451 // turn data[x][y] into data:x:y:
1452 $name = preg_replace('/\[|\]\[?/', ':', trim($name));
1453 // remove illegal chars like _
1454 return preg_replace('#[^:a-zA-Z0-9]#', '', $name);
1455 }
1456
1457 /**
1458 * An abstraction method to add parameters to an A tag.
1459 * Uses the ATagParams property.
1460 *
1461 * @param array TypoScript configuration properties
1462 * @param boolean If set, will add the global config.ATagParams to the link
1463 * @return string String containing the parameters to the A tag (if non empty, with a leading space)
1464 * @see IMGTEXT(), filelink(), makelinks(), typolink()
1465 */
1466 function getATagParams($conf, $addGlobal = 1) {
1467 $aTagParams = '';
1468 if ($conf['ATagParams.']) {
1469 $aTagParams = ' ' . $this->stdWrap($conf['ATagParams'], $conf['ATagParams.']);
1470 } elseif ($conf['ATagParams']) {
1471 $aTagParams = ' ' . $conf['ATagParams'];
1472 }
1473 if ($addGlobal) {
1474 $aTagParams = ' ' . trim($GLOBALS['TSFE']->ATagParams . $aTagParams);
1475 }
1476
1477 // extend params
1478 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getATagParamsPostProc']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getATagParamsPostProc'])) {
1479 $_params = array(
1480 'conf' => &$conf,
1481 'aTagParams' => &$aTagParams
1482 );
1483 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getATagParamsPostProc'] as $objRef) {
1484 $processor = &t3lib_div::getUserObj($objRef);
1485 $aTagParams = $processor->process( $_params, $this);
1486 }
1487 }
1488
1489 return $aTagParams;
1490 }
1491
1492 /**
1493 * All extension links should ask this function for additional properties to their tags.
1494 * Designed to add for instance an "onclick" property for site tracking systems.
1495 *
1496 * @param string URL of the website
1497 * @return string the additional tag properties
1498 */
1499 function extLinkATagParams($URL, $TYPE) {
1500 $out = '';
1501
1502 if ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['extLinkATagParamsHandler']) {
1503 $extLinkATagParamsHandler = t3lib_div::getUserObj(
1504 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['extLinkATagParamsHandler']
1505 );
1506
1507 if (method_exists($extLinkATagParamsHandler, 'main')) {
1508 $out .= trim($extLinkATagParamsHandler->main($URL, $TYPE, $this));
1509 }
1510 }
1511
1512 return trim($out) ? ' ' . trim($out) : '';
1513 }
1514
1515
1516
1517 /***********************************************
1518 *
1519 * HTML template processing functions
1520 *
1521 ***********************************************/
1522
1523 /**
1524 * Returns a subpart from the input content stream.
1525 * A subpart is a part of the input stream which is encapsulated in a
1526 * string matching the input string, $marker. If this string is found
1527 * inside of HTML comment tags the start/end points of the content block
1528 * returned will be that right outside that comment block.
1529 * Example: The contennt string is
1530 * "Hello <!--###sub1### begin--> World. How are <!--###sub1### end--> you?"
1531 * If $marker is "###sub1###" then the content returned is
1532 * " World. How are ". The input content string could just as well have
1533 * been "Hello ###sub1### World. How are ###sub1### you?" and the result
1534 * would be the same
1535 * Wrapper for t3lib_parsehtml::getSubpart which behaves identical
1536 *
1537 * @param string The content stream, typically HTML template content.
1538 * @param string The marker string, typically on the form "###[the marker string]###"
1539 * @return string The subpart found, if found.
1540 * @see substituteSubpart(), t3lib_parsehtml::getSubpart()
1541 */
1542 public function getSubpart($content, $marker) {
1543 return t3lib_parsehtml::getSubpart($content, $marker);
1544 }
1545
1546 /**
1547 * Substitute subpart in input template stream.
1548 * This function substitutes a subpart in $content with the content of
1549 * $subpartContent.
1550 * Wrapper for t3lib_parsehtml::substituteSubpart which behaves identical
1551 *
1552 * @param string The content stream, typically HTML template content.
1553 * @param string The marker string, typically on the form "###[the marker string]###"
1554 * @param mixed The content to insert instead of the subpart found. If a string, then just plain substitution happens (includes removing the HTML comments of the subpart if found). If $subpartContent happens to be an array, it's [0] and [1] elements are wrapped around the EXISTING content of the subpart (fetched by getSubpart()) thereby not removing the original content.
1555 * @param boolean If $recursive is set, the function calls itself with the content set to the remaining part of the content after the second marker. This means that proceding subparts are ALSO substituted!
1556 * @return string The processed HTML content string.
1557 * @see getSubpart(), t3lib_parsehtml::substituteSubpart()
1558 */
1559 public function substituteSubpart($content, $marker, $subpartContent, $recursive = 1) {
1560 return t3lib_parsehtml::substituteSubpart($content, $marker, $subpartContent, $recursive);
1561 }
1562
1563 /**
1564 * Substitues multiple subparts at once
1565 *
1566 * @param string The content stream, typically HTML template content.
1567 * @param array The array of key/value pairs being subpart/content values used in the substitution. For each element in this array the function will substitute a subpart in the content stream with the content.
1568 * @return string The processed HTML content string.
1569 */
1570 public function substituteSubpartArray($content, array $subpartsContent) {
1571 return t3lib_parsehtml::substituteSubpartArray($content, $subpartsContent);
1572 }
1573
1574 /**
1575 * Substitutes a marker string in the input content
1576 * (by a simple str_replace())
1577 *
1578 * @param string The content stream, typically HTML template content.
1579 * @param string The marker string, typically on the form "###[the marker string]###"
1580 * @param mixed The content to insert instead of the marker string found.
1581 * @return string The processed HTML content string.
1582 * @see substituteSubpart()
1583 */
1584 public function substituteMarker($content, $marker, $markContent) {
1585 return t3lib_parsehtml::substituteMarker($content, $marker, $markContent);
1586 }
1587
1588 /**
1589 * Multi substitution function with caching.
1590 *
1591 * This function should be a one-stop substitution function for working
1592 * with HTML-template. It does not substitute by str_replace but by
1593 * splitting. This secures that the value inserted does not themselves
1594 * contain markers or subparts.
1595 *
1596 * Note that the "caching" won't cache the content of the substition,
1597 * but only the splitting of the template in various parts. So if you
1598 * want only one cache-entry per template, make sure you always pass the
1599 * exact same set of marker/subpart keys. Else you will be flooding the
1600 * users cache table.
1601 *
1602 * This function takes three kinds of substitutions in one:
1603 * $markContentArray is a regular marker-array where the 'keys' are
1604 * substituted in $content with their values
1605 *
1606 * $subpartContentArray works exactly like markContentArray only is whole
1607 * subparts substituted and not only a single marker.
1608 *
1609 * $wrappedSubpartContentArray is an array of arrays with 0/1 keys where
1610 * the subparts pointed to by the main key is wrapped with the 0/1 value
1611 * alternating.
1612 *
1613 * @param string The content stream, typically HTML template content.
1614 * @param array Regular marker-array where the 'keys' are substituted in $content with their values
1615 * @param array Exactly like markContentArray only is whole subparts substituted and not only a single marker.
1616 * @param array An array of arrays with 0/1 keys where the subparts pointed to by the main key is wrapped with the 0/1 value alternating.
1617 * @return string The output content stream
1618 * @see substituteSubpart(), substituteMarker(), substituteMarkerInObject(), TEMPLATE()
1619 */
1620 public function substituteMarkerArrayCached($content, array $markContentArray = NULL, array $subpartContentArray = NULL, array $wrappedSubpartContentArray = NULL) {
1621 $GLOBALS['TT']->push('substituteMarkerArrayCached');
1622
1623 // If not arrays then set them
1624 if (is_null($markContentArray))
1625 $markContentArray = array(); // Plain markers
1626 if (is_null($subpartContentArray))
1627 $subpartContentArray = array(); // Subparts being directly substituted
1628 if (is_null($wrappedSubpartContentArray))
1629 $wrappedSubpartContentArray = array(); // Subparts being wrapped
1630 // Finding keys and check hash:
1631 $sPkeys = array_keys($subpartContentArray);
1632 $wPkeys = array_keys($wrappedSubpartContentArray);
1633 $aKeys = array_merge(array_keys($markContentArray), $sPkeys, $wPkeys);
1634 if (!count($aKeys)) {
1635 $GLOBALS['TT']->pull();
1636 return $content;
1637 }
1638 asort($aKeys);
1639 $storeKey = md5('substituteMarkerArrayCached_storeKey:' . serialize(array(
1640 $content, $aKeys
1641 )));
1642 if ($this->substMarkerCache[$storeKey]) {
1643 $storeArr = $this->substMarkerCache[$storeKey];
1644 $GLOBALS['TT']->setTSlogMessage('Cached', 0);
1645 } else {
1646 $storeArrDat = $GLOBALS['TSFE']->sys_page->getHash($storeKey);
1647 if (!isset($storeArrDat)) {
1648 // Initialize storeArr
1649 $storeArr = array();
1650
1651 // Finding subparts and substituting them with the subpart as a marker
1652 foreach ($sPkeys as $sPK) {
1653 $content = $this->substituteSubpart($content, $sPK, $sPK);
1654 }
1655
1656 // Finding subparts and wrapping them with markers
1657 foreach ($wPkeys as $wPK) {
1658 $content = $this->substituteSubpart($content, $wPK, array(
1659 $wPK, $wPK
1660 ));
1661 }
1662
1663 // traverse keys and quote them for reg ex.
1664 foreach ($aKeys as $tK => $tV) {
1665 $aKeys[$tK] = preg_quote($tV, '/');
1666 }
1667 $regex = '/' . implode('|', $aKeys) . '/';
1668 // Doing regex's
1669 $storeArr['c'] = preg_split($regex, $content);
1670 preg_match_all($regex, $content, $keyList);
1671 $storeArr['k'] = $keyList[0];
1672 // Setting cache:
1673 $this->substMarkerCache[$storeKey] = $storeArr;
1674
1675 // Storing the cached data:
1676 $GLOBALS['TSFE']->sys_page->storeHash($storeKey, serialize($storeArr), 'substMarkArrayCached');
1677
1678 $GLOBALS['TT']->setTSlogMessage('Parsing', 0);
1679 } else {
1680 // Unserializing
1681 $storeArr = unserialize($storeArrDat);
1682 // Setting cache:
1683 $this->substMarkerCache[$storeKey] = $storeArr;
1684 $GLOBALS['TT']->setTSlogMessage('Cached from DB', 0);
1685 }
1686 }
1687
1688 // Substitution/Merging:
1689 // Merging content types together, resetting
1690 $valueArr = array_merge($markContentArray, $subpartContentArray, $wrappedSubpartContentArray);
1691
1692 $wSCA_reg = array();
1693 $content = '';
1694 // traversing the keyList array and merging the static and dynamic content
1695 foreach ($storeArr['k'] as $n => $keyN) {
1696 $content .= $storeArr['c'][$n];
1697 if (!is_array($valueArr[$keyN])) {
1698 $content .= $valueArr[$keyN];
1699 } else {
1700 $content .= $valueArr[$keyN][(intval($wSCA_reg[$keyN]) % 2)];
1701 $wSCA_reg[$keyN]++;
1702 }
1703 }
1704 $content .= $storeArr['c'][count($storeArr['k'])];
1705
1706 $GLOBALS['TT']->pull();
1707 return $content;
1708 }
1709
1710 /**
1711 * Traverses the input $markContentArray array and for each key the marker
1712 * by the same name (possibly wrapped and in upper case) will be
1713 * substituted with the keys value in the array.
1714 *
1715 * This is very useful if you have a data-record to substitute in some
1716 * content. In particular when you use the $wrap and $uppercase values to
1717 * pre-process the markers. Eg. a key name like "myfield" could effectively
1718 * be represented by the marker "###MYFIELD###" if the wrap value
1719 * was "###|###" and the $uppercase boolean TRUE.
1720 *
1721 * @param string The content stream, typically HTML template content.
1722 * @param array The array of key/value pairs being marker/content values used in the substitution. For each element in this array the function will substitute a marker in the content stream with the content.
1723 * @param string A wrap value - [part 1] | [part 2] - for the markers before substitution
1724 * @param boolean If set, all marker string substitution is done with upper-case markers.
1725 * @param boolean If set, all unused marker are deleted.
1726 * @return string The processed output stream
1727 * @see substituteMarker(), substituteMarkerInObject(), TEMPLATE()
1728 */
1729 public function substituteMarkerArray($content, array $markContentArray, $wrap = '', $uppercase = FALSE, $deleteUnused = FALSE) {
1730 return t3lib_parsehtml::substituteMarkerArray($content, $markContentArray, $wrap, $uppercase, $deleteUnused);
1731 }
1732
1733 /**
1734 * Substitute marker array in an array of values
1735 *
1736 * @param mixed If string, then it just calls substituteMarkerArray. If array(and even multi-dim) then for each key/value pair the marker array will be substituted (by calling this function recursively)
1737 * @param array The array of key/value pairs being marker/content values used in the substitution. For each element in this array the function will substitute a marker in the content string/array values.
1738 * @return mixed The processed input variable.
1739 * @see substituteMarker()
1740 */
1741 public function substituteMarkerInObject(&$tree, array $markContentArray) {
1742 if (is_array($tree)) {
1743 foreach ($tree as $key => $value) {
1744 $this->substituteMarkerInObject($tree[$key], $markContentArray);
1745 }
1746 } else {
1747 $tree = $this->substituteMarkerArray($tree, $markContentArray);
1748 }
1749
1750 return $tree;
1751 }
1752
1753 /**
1754 * Replaces all markers and subparts in a template with the content provided in the structured array.
1755 *
1756 * @param $content
1757 * @param array $markersAndSubparts
1758 * @param string $wrap
1759 * @param bool $uppercase
1760 * @param bool $deleteUnused
1761 * @return string
1762 * @see t3lib_parsehtml::substituteMarkerAndSubpartArrayRecursive()
1763 */
1764 public function substituteMarkerAndSubpartArrayRecursive($content, array $markersAndSubparts, $wrap = '', $uppercase = FALSE,
1765 $deleteUnused = FALSE) {
1766 return t3lib_parsehtml::substituteMarkerAndSubpartArrayRecursive(
1767 $content, $markersAndSubparts, $wrap, $uppercase, $deleteUnused
1768 );
1769 }
1770
1771 /**
1772 * Adds elements to the input $markContentArray based on the values from
1773 * the fields from $fieldList found in $row
1774 *
1775 * @param array array with key/values being marker-strings/substitution values.
1776 * @param array An array with keys found in the $fieldList (typically a record) which values should be moved to the $markContentArray
1777 * @param string A list of fields from the $row array to add to the $markContentArray array. If empty all fields from $row will be added (unless they are integers)
1778 * @param boolean If set, all values added to $markContentArray will be nl2br()'ed
1779 * @param string Prefix string to the fieldname before it is added as a key in the $markContentArray. Notice that the keys added to the $markContentArray always start and end with "###"
1780 * @param boolean If set, all values are passed through htmlspecialchars() - RECOMMENDED to avoid most obvious XSS and maintain XHTML compliance.
1781 * @return array The modified $markContentArray
1782 */
1783 public function fillInMarkerArray(array $markContentArray, array $row, $fieldList = '', $nl2br = TRUE, $prefix = 'FIELD_', $HSC = FALSE) {
1784 if ($fieldList) {
1785 $fArr = t3lib_div::trimExplode(',', $fieldList, 1);
1786 foreach ($fArr as $field) {
1787 $markContentArray['###' . $prefix . $field . '###'] =
1788 $nl2br ? nl2br($row[$field], !empty($GLOBALS['TSFE']->xhtmlDoctype)) : $row[$field];
1789 }
1790 } else {
1791 if (is_array($row)) {
1792 foreach ($row as $field => $value) {
1793 if (!t3lib_utility_Math::canBeInterpretedAsInteger($field)) {
1794 if ($HSC) {
1795 $value = htmlspecialchars($value);
1796 }
1797
1798 $markContentArray['###' . $prefix . $field . '###'] =
1799 $nl2br ? nl2br($value, !empty($GLOBALS['TSFE']->xhtmlDoctype)) : $value;
1800 }
1801 }
1802 }
1803 }
1804
1805 return $markContentArray;
1806 }
1807
1808 /***********************************************
1809 *
1810 * "stdWrap" + sub functions
1811 *
1812 ***********************************************/
1813
1814 /**
1815 * The "stdWrap" function. This is the implementation of what is known as "stdWrap properties" in TypoScript.
1816 * Basically "stdWrap" performs some processing of a value based on properties in the input $conf array(holding the TypoScript "stdWrap properties")
1817 * See the link below for a complete list of properties and what they do. The order of the table with properties found in TSref (the link) follows the actual order of implementation in this function.
1818 *
1819 * If $this->alternativeData is an array it's used instead of the $this->data array in ->getData
1820 *
1821 * @param string Input value undergoing processing in this function. Possibly substituted by other values fetched from another source.
1822 * @param array TypoScript "stdWrap properties".
1823 * @return string The processed input value
1824 */
1825 public function stdWrap($content = '', $conf = array()) {
1826 if (count($this->stdWrapHookObjects)) {
1827 foreach ($this->stdWrapHookObjects as $hookObject) {
1828 if (is_callable(array($hookObject, 'stdWrapPreProcess'))) {
1829 $conf['stdWrapPreProcess'] = 1;
1830 }
1831 ;
1832 if (is_callable(array($hookObject, 'stdWrapOverride'))) {
1833 $conf['stdWrapOverride'] = 1;
1834 }
1835 ;
1836 if (is_callable(array($hookObject, 'stdWrapProcess'))) {
1837 $conf['stdWrapProcess'] = 1;
1838 }
1839 ;
1840 if (is_callable(array($hookObject, 'stdWrapPostProcess'))) {
1841 $conf['stdWrapPostProcess'] = 1;
1842 }
1843 ;
1844 }
1845 }
1846
1847 if (is_array($conf) && count($conf)) {
1848
1849 // cache handling
1850 if (is_array($conf['cache.'])) {
1851 $conf['cache.']['key'] = $this->stdWrap($conf['cache.']['key'], $conf['cache.']['key.']);
1852 $conf['cache.']['tags'] = $this->stdWrap($conf['cache.']['tags'], $conf['cache.']['tags.']);
1853 $conf['cache.']['lifetime'] = $this->stdWrap($conf['cache.']['lifetime'], $conf['cache.']['lifetime.']);
1854
1855 $conf['cacheRead'] = 1;
1856 $conf['cacheStore'] = 1;
1857 }
1858
1859 // check, which of the available stdWrap functions is needed for the current conf Array
1860 // and keep only those but still in the same order
1861 $sortedConf = array_intersect_key($this->stdWrapOrder, $conf);
1862 // functions types that should not make use of nested stdWrap function calls to avoid conflicts with internal TypoScript used by these functions
1863 $stdWrapDisabledFunctionTypes = 'cObject,functionName,stdWrap';
1864 // additional Array to check whether a function has already been executed
1865 $isExecuted = array();
1866 // additional switch to make sure 'required', 'if' and 'fieldRequired'
1867 // will still stop rendering immediately in case they return FALSE
1868
1869 $this->stdWrapRecursionLevel++;
1870 $this->stopRendering[$this->stdWrapRecursionLevel] = FALSE;
1871
1872 // execute each function in the predefined order
1873 foreach ($sortedConf as $stdWrapName => $functionType) {
1874 // eliminate the second key of a pair 'key'|'key.' to make sure functions get called only once and check if rendering has been stopped
1875 if (!$isExecuted[$stdWrapName] &&
1876 !$this->stopRendering[$this->stdWrapRecursionLevel]) {
1877 $functionName = rtrim($stdWrapName, '.');
1878 $functionProperties = $functionName . '.';
1879 // if there is any code one the next level, check if it contains "official" stdWrap functions
1880 // if yes, execute them first - will make each function stdWrap aware
1881 // so additional stdWrap calls within the functions can be removed, since the result will be the same
1882 // exception: the recursive stdWrap function and cObject will still be using their own stdWrap call, since it modifies the content and not a property
1883 if (count($conf[$functionProperties]) &&
1884 !t3lib_div::inList($stdWrapDisabledFunctionTypes, $functionType)) {
1885 if (array_intersect_key($this->stdWrapOrder, $conf[$functionProperties])) {
1886 $conf[$functionName] = $this->stdWrap($conf[$functionName], $conf[$functionProperties]);
1887 }
1888 }
1889 // get just that part of $conf that is needed for the particular function
1890 $singleConf = array(
1891 $functionName => $conf[$functionName],
1892 $functionProperties => $conf[$functionProperties]
1893 );
1894
1895 // in this special case 'spaceBefore' and 'spaceAfter' need additional stuff from 'space.''
1896 if ($functionName == 'spaceBefore' || $functionName == 'spaceAfter') {
1897 $singleConf['space.'] = $conf['space.'];
1898 }
1899
1900 // hand over the whole $conf array to the stdWrapHookObjects
1901 if ($functionType === 'hook') {
1902 $singleConf = $conf;
1903 }
1904 // check if key is still containing something, since it might have been changed by next level stdWrap before
1905 if ((isset($conf[$functionName]) || $conf[$functionProperties]) &&
1906 !($functionType == 'boolean' && !$conf[$functionName])) {
1907 //add both keys - with and without the dot - to the set of executed functions
1908 $isExecuted[$functionName] = TRUE;
1909 $isExecuted[$functionProperties] = TRUE;
1910 // call the function with the prefix stdWrap_ to make sure nobody can execute functions just by adding their name to the TS Array
1911 $functionName = 'stdWrap_' . $functionName;
1912 $content = $this->$functionName(
1913 $content,
1914 $singleConf
1915 );
1916 // for booleans we have to mark the function as executed in any case, even if it has been 0, '' or false to avoid a second call based on the functionProperties, which would always be true
1917 } elseif($functionType == 'boolean' && !$conf[$functionName]) {
1918 $isExecuted[$functionName] = TRUE;
1919 $isExecuted[$functionProperties] = TRUE;
1920 }
1921 }
1922 }
1923
1924 unset($this->stopRendering[$this->stdWrapRecursionLevel]);
1925 $this->stdWrapRecursionLevel--;
1926
1927 }
1928 return $content;
1929 }
1930
1931 /**
1932 * stdWrap pre process hook
1933 * can be used by extensions authors to modify the behaviour of stdWrap functions to their needs
1934 * this hook will execute functions before any other stdWrap function can modify anything
1935 *
1936 * @param string Input value undergoing processing in these functions.
1937 * @param array All stdWrap properties, not just the ones for a particular function.
1938 * @return string The processed input value
1939 */
1940 public function stdWrap_stdWrapPreProcess($content = '', $conf = array()) {
1941 foreach ($this->stdWrapHookObjects as $hookObject) {
1942 $content = $hookObject->stdWrapPreProcess($content, $conf, $this);
1943 }
1944 return $content;
1945 }
1946
1947 /**
1948 * Check if content was cached before (depending on the given cache key)
1949 *
1950 * @param string Input value undergoing processing in these functions.
1951 * @param array All stdWrap properties, not just the ones for a particular function.
1952 * @return string The processed input value
1953 */
1954 public function stdWrap_cacheRead($content = '', $conf = array()) {
1955 if (!empty($conf['cache.']['key'])) {
1956 $cacheFrontend = $GLOBALS['typo3CacheManager']->getCache('cache_hash'); /* @var $cacheFrontend t3lib_cache_frontend_VariableFrontend */
1957 if ($cacheFrontend && $cacheFrontend->has($conf['cache.']['key'])) {
1958 $content = $cacheFrontend->get($conf['cache.']['key']);
1959 $this->stopRendering[$this->stdWrapRecursionLevel] = TRUE;
1960 }
1961 }
1962 return $content;
1963 }
1964
1965 /**
1966 * setContentToCurrent
1967 * actually it just does the contrary: Sets the value of 'current' based on current content
1968 *
1969 * @param string Input value undergoing processing in this function.
1970 * @param array stdWrap properties for setContentToCurrent.
1971 * @return string The processed input value
1972 */
1973 public function stdWrap_setContentToCurrent($content = '', $conf = array()) {
1974 $this->data[$this->currentValKey] = $content;
1975 return $content;
1976 }
1977
1978 /**
1979 * setCurrent
1980 * Sets the value of 'current' based on the outcome of stdWrap operations
1981 *
1982 * @param string Input value undergoing processing in this function.
1983 * @param array stdWrap properties for setCurrent.
1984 * @return string The processed input value
1985 */
1986 public function stdWrap_setCurrent($content = '', $conf = array()) {
1987 $this->data[$this->currentValKey] = $conf['setCurrent'];
1988 return $content;
1989 }
1990
1991 /**
1992 * lang
1993 * Translates content based on the language currently used by the FE
1994 *
1995 * @param string Input value undergoing processing in this function.
1996 * @param array stdWrap properties for lang.
1997 * @return string The processed input value
1998 */
1999 public function stdWrap_lang($content = '', $conf = array()) {
2000 if (isset($conf['lang.']) && $GLOBALS['TSFE']->config['config']['language'] && isset($conf['lang.'][$GLOBALS['TSFE']->config['config']['language']])) {
2001 $content = $conf['lang.'][$GLOBALS['TSFE']->config['config']['language']];
2002 }
2003 return $content;
2004 }
2005
2006 /**
2007 * data
2008 * Gets content from different sources based on getText functions, makes use of alternativeData, when set
2009 *
2010 * @param string Input value undergoing processing in this function.
2011 * @param array stdWrap properties for data.
2012 * @return string The processed input value
2013 */
2014 public function stdWrap_data($content = '', $conf = array()) {
2015 $content = $this->getData($conf['data'], is_array($this->alternativeData) ? $this->alternativeData : $this->data);
2016 $this->alternativeData = ''; // This must be unset directly after
2017 return $content;
2018 }
2019
2020 /**
2021 * field
2022 * Gets content from a DB field
2023 *
2024 * @param string Input value undergoing processing in this function.
2025 * @param array stdWrap properties for field.
2026 * @return string The processed input value
2027 */
2028 public function stdWrap_field($content = '', $conf = array()) {
2029 $content = $this->getFieldVal($conf['field']);
2030 return $content;
2031 }
2032
2033 /**
2034 * current
2035 * Gets content that has been perviously set as 'current'
2036 * Can be set via setContentToCurrent or setCurrent or will be set automatically i.e. inside the split function
2037 *
2038 * @param string Input value undergoing processing in this function.
2039 * @param array stdWrap properties for current.
2040 * @return string The processed input value
2041 */
2042 public function stdWrap_current($content = '', $conf = array()) {
2043 $content = $this->data[$this->currentValKey];
2044 return $content;
2045 }
2046
2047 /**
2048 * cObject
2049 * Will replace the content with the value of a any official TypoScript cObject
2050 * like TEXT, COA, HMENU
2051 *
2052 * @param string Input value undergoing processing in this function.
2053 * @param array stdWrap properties for cObject.
2054 * @return string The processed input value
2055 */
2056 public function stdWrap_cObject($content = '', $conf = array()) {
2057 $content = $this->cObjGetSingle($conf['cObject'], $conf['cObject.'], '/stdWrap/.cObject');
2058 return $content;
2059 }
2060
2061 /**
2062 * numRows
2063 * Counts the number of returned records of a DB operation
2064 * makes use of select internally
2065 *
2066 * @param string Input value undergoing processing in this function.
2067 * @param array stdWrap properties for numRows.
2068 * @return string The processed input value
2069 */
2070 public function stdWrap_numRows($content = '', $conf = array()) {
2071 $content = $this->numRows($conf['numRows.']);
2072 return $content;
2073 }
2074
2075 /**
2076 * filelist
2077 * Will create a list of files based on some additional parameters
2078 *
2079 * @param string Input value undergoing processing in this function.
2080 * @param array stdWrap properties for filelist.
2081 * @return string The processed input value
2082 */
2083 public function stdWrap_filelist($content = '', $conf = array()) {
2084 $content = $this->filelist($conf['filelist']);
2085 return $content;
2086 }
2087
2088 /**
2089 * preUserFunc
2090 * Will execute a user public function before the content will be modified by any other stdWrap function
2091 *
2092 * @param string Input value undergoing processing in this function.
2093 * @param array stdWrap properties for preUserFunc.
2094 * @return string The processed input value
2095 */
2096 public function stdWrap_preUserFunc($content = '', $conf = array()) {
2097 $content = $this->callUserFunction($conf['preUserFunc'], $conf['preUserFunc.'], $content);
2098 return $content;
2099 }
2100
2101 /**
2102 * stdWrap override hook
2103 * can be used by extensions authors to modify the behaviour of stdWrap functions to their needs
2104 * this hook will execute functions on existing content but still before the content gets modified or replaced
2105 *
2106 * @param string Input value undergoing processing in these functions.
2107 * @param array All stdWrap properties, not just the ones for a particular function.
2108 * @return string The processed input value
2109 */
2110 public function stdWrap_stdWrapOverride($content = '', $conf = array()) {
2111 foreach ($this->stdWrapHookObjects as $hookObject) {
2112 $content = $hookObject->stdWrapOverride($content, $conf, $this);
2113 }
2114 return $content;
2115 }
2116
2117 /**
2118 * override
2119 * Will override the current value of content with its own value'
2120 *
2121 * @param string Input value undergoing processing in this function.
2122 * @param array stdWrap properties for override.
2123 * @return string The processed input value
2124 */
2125 public function stdWrap_override($content = '', $conf = array()) {
2126 if (trim($conf['override'])) {
2127 $content = $conf['override'];
2128 }
2129 return $content;
2130 }
2131
2132 /**
2133 * preIfEmptyListNum
2134 * Gets a value off a CSV list before the following ifEmpty check
2135 * Makes sure that the result of ifEmpty will be TRUE in case the CSV does not contain a value at the position given by preIfEmptyListNum
2136 *
2137 * @param string Input value undergoing processing in this function.
2138 * @param array stdWrap properties for preIfEmptyListNum.
2139 * @return string The processed input value
2140 */
2141 public function stdWrap_preIfEmptyListNum($content = '', $conf = array()) {
2142 $content = $this->listNum($content, $conf['preIfEmptyListNum'], $conf['preIfEmptyListNum.']['splitChar']);
2143 return $content;
2144 }
2145
2146 /**
2147 * ifEmpty
2148 * Will set content to a replacement value in case the trimmed value of content returns FALSE
2149 * 0 (zero) will be replaced as well
2150 *
2151 * @param string Input value undergoing processing in this function.
2152 * @param array stdWrap properties for ifEmpty.
2153 * @return string The processed input value
2154 */
2155 public function stdWrap_ifEmpty($content = '', $conf = array()) {
2156 if (!trim($content)) {
2157 $content = $conf['ifEmpty'];
2158 }
2159 return $content;
2160 }
2161
2162 /**
2163 * ifBlank
2164 * Will set content to a replacement value in case the trimmed value of content has no length
2165 * 0 (zero) will not be replaced
2166 *
2167 * @param string Input value undergoing processing in this function.
2168 * @param array stdWrap properties for ifBlank.
2169 * @return string The processed input value
2170 */
2171 public function stdWrap_ifBlank($content = '', $conf = array()) {
2172 if (!strlen(trim($content))) {
2173 $content = $conf['ifBlank'];
2174 }
2175 return $content;
2176 }
2177
2178 /**
2179 * listNum
2180 * Gets a value off a CSV list after ifEmpty check
2181 * Might return an empty value in case the CSV does not contain a value at the position given by listNum
2182 * Use preIfEmptyListNum to avoid that behaviour
2183 *
2184 * @param string Input value undergoing processing in this function.
2185 * @param array stdWrap properties for listNum.
2186 * @return string The processed input value
2187 */
2188 public function stdWrap_listNum($content = '', $conf = array()) {
2189 $content = $this->listNum($content, $conf['listNum'], $conf['listNum.']['splitChar']);
2190 return $content;
2191 }
2192
2193 /**
2194 * trim
2195 * Cuts off any whitespace at the beginning and the end of the content
2196 *
2197 * @param string Input value undergoing processing in this function.
2198 * @param array stdWrap properties for trim.
2199 * @return string The processed input value
2200 */
2201 public function stdWrap_trim($content = '', $conf = array()) {
2202 $content = trim($content);
2203 return $content;
2204 }
2205
2206 /**
2207 * stdWrap
2208 * A recursive call of the stdWrap function set
2209 * This enables the user to execute stdWrap functions in another than the predefined order
2210 * It modifies the content, not the property
2211 * while the new feature of chained stdWrap functions modifies the property and not the content
2212 *
2213 * @param string Input value undergoing processing in this function.
2214 * @param array stdWrap properties for stdWrap.
2215 * @return string The processed input value
2216 */
2217 public function stdWrap_stdWrap($content = '', $conf = array()) {
2218 $content = $this->stdWrap($content, $conf['stdWrap.']);
2219 return $content;
2220 }
2221
2222 /**
2223 * stdWrap process hook
2224 * can be used by extensions authors to modify the behaviour of stdWrap functions to their needs
2225 * this hook executes functions directly after the recursive stdWrap function call but still before the content gets modified
2226 *
2227 * @param string Input value undergoing processing in these functions.
2228 * @param array All stdWrap properties, not just the ones for a particular function.
2229 * @return string The processed input value
2230 */
2231 public function stdWrap_stdWrapProcess($content = '', $conf = array()) {
2232 foreach ($this->stdWrapHookObjects as $hookObject) {
2233 $content = $hookObject->stdWrapProcess($content, $conf, $this);
2234 }
2235 return $content;
2236 }
2237
2238 /**
2239 * required
2240 * Will immediately stop rendering and return an empty value
2241 * when there is no content at this point
2242 *
2243 * @param string Input value undergoing processing in this function.
2244 * @param array stdWrap properties for required.
2245 * @return string The processed input value
2246 */
2247 public function stdWrap_required($content = '', $conf = array()) {
2248 if ((string) $content == '') {
2249 $content = '';
2250 $this->stopRendering[$this->stdWrapRecursionLevel] = TRUE;
2251 }
2252 return $content;
2253 }
2254
2255 /**
2256 * if
2257 * Will immediately stop rendering and return an empty value
2258 * when the result of the checks returns FALSE
2259 *
2260 * @param string Input value undergoing processing in this function.
2261 * @param array stdWrap properties for if.
2262 * @return string The processed input value
2263 */
2264 public function stdWrap_if($content = '', $conf = array()) {
2265 if (!$this->checkIf($conf['if.'])) {
2266 $content = '';
2267 $this->stopRendering[$this->stdWrapRecursionLevel] = TRUE;
2268 }
2269 return $content;
2270 }
2271
2272 /**
2273 * fieldRequired
2274 * Will immediately stop rendering and return an empty value
2275 * when there is no content in the field given by fieldRequired
2276 *
2277 * @param string Input value undergoing processing in this function.
2278 * @param array stdWrap properties for fieldRequired.
2279 * @return string The processed input value
2280 */
2281 public function stdWrap_fieldRequired($content = '', $conf = array()) {
2282 if (!trim($this->data[$conf['fieldRequired']])) {
2283 $content = '';
2284 $this->stopRendering[$this->stdWrapRecursionLevel] = TRUE;
2285 }
2286 return $content;
2287 }
2288
2289 /**
2290 * csConv
2291 * Will convert the current chracter set of the content to the one given in csConv
2292 *
2293 * @param string Input value undergoing processing in this function.
2294 * @param array stdWrap properties for csConv.
2295 * @return string The processed input value
2296 */
2297 public function stdWrap_csConv($content = '', $conf = array()) {
2298 $content = $GLOBALS['TSFE']->csConv($content, $conf['csConv']);
2299 return $content;
2300 }
2301
2302 /**
2303 * parseFunc
2304 * Will parse the content based on functions given as stdWrap properties
2305 * Heavily used together with RTE based content
2306 *
2307 * @param string Input value undergoing processing in this function.
2308 * @param array stdWrap properties for parseFunc.
2309 * @return string The processed input value
2310 */
2311 public function stdWrap_parseFunc($content = '', $conf = array()) {
2312 $content = $this->parseFunc($content, $conf['parseFunc.'], $conf['parseFunc']);
2313 return $content;
2314 }
2315
2316 /**
2317 * HTMLparser
2318 * Will parse HTML content based on functions given as stdWrap properties
2319 * Heavily used together with RTE based content
2320 *
2321 * @param string Input value undergoing processing in this function.
2322 * @param array stdWrap properties for HTMLparser.
2323 * @return string The processed input value
2324 */
2325 public function stdWrap_HTMLparser($content = '', $conf = array()) {
2326 if (is_array($conf['HTMLparser.'])) {
2327 $content = $this->HTMLparser_TSbridge($content, $conf['HTMLparser.']);
2328 }
2329 return $content;
2330 }
2331
2332 /**
2333 * split
2334 * Will split the content by a given token and treat the results separately
2335 * Automatically fills 'current' with a single result
2336 *
2337 * @param string Input value undergoing processing in this function.
2338 * @param array stdWrap properties for split.
2339 * @return string The processed input value
2340 */
2341 public function stdWrap_split($content = '', $conf = array()) {
2342 $content = $this->splitObj($content, $conf['split.']);
2343 return $content;
2344 }
2345
2346 /**
2347 * replacement
2348 * Will execute replacements on the content (optionally with preg-regex)
2349 *
2350 * @param string Input value undergoing processing in this function.
2351 * @param array stdWrap properties for replacement.
2352 * @return string The processed input value
2353 */
2354 public function stdWrap_replacement($content = '', $conf = array()) {
2355 $content = $this->replacement($content, $conf['replacement.']);
2356 return $content;
2357 }
2358
2359 /**
2360 * prioriCalc
2361 * Will use the content as a mathematical term and calculate the result
2362 * Can be set to 1 to just get a calculated value or 'intval' to get the integer of the result
2363 *
2364 * @param string Input value undergoing processing in this function.
2365 * @param array stdWrap properties for prioriCalc.
2366 * @return string The processed input value
2367 */
2368 public function stdWrap_prioriCalc($content = '', $conf = array()) {
2369 $content = t3lib_utility_Math::calculateWithParentheses($content);
2370 if ($conf['prioriCalc'] == 'intval')
2371 $content = intval($content);
2372 return $content;
2373 }
2374
2375 /**
2376 * char
2377 * Will return a character based on its position within the current character set
2378 *
2379 * @param string Input value undergoing processing in this function.
2380 * @param array stdWrap properties for char.
2381 * @return string The processed input value
2382 */
2383 public function stdWrap_char($content = '', $conf = array()) {
2384 $content = chr(intval($conf['char']));
2385 return $content;
2386 }
2387
2388 /**
2389 * intval
2390 * Will return an integer value of the current content
2391 *
2392 * @param string Input value undergoing processing in this function.
2393 * @param array stdWrap properties for intval.
2394 * @return string The processed input value
2395 */
2396 public function stdWrap_intval($content = '', $conf = array()) {
2397 $content = intval($content);
2398 return $content;
2399 }
2400
2401 /**
2402 * Will return a hashed value of the current content
2403 *
2404 * @param string Input value undergoing processing in this function.
2405 * @param array stdWrap properties for hash.
2406 * @return string The processed input value
2407 * @link http://php.net/manual/de/function.hash-algos.php for a list of supported hash algorithms
2408 */
2409 public function stdWrap_hash($content = '', array $conf = array()) {
2410 $algorithm = isset($conf['hash.'])
2411 ? $this->stdWrap($conf['hash'], $conf['hash.'])
2412 : $conf['hash'];
2413 if (function_exists('hash') && in_array($algorithm, hash_algos())) {
2414 $content = hash($algorithm, $content);
2415 } else {
2416 // non-existing hashing algorithm
2417 $content = '';
2418 }
2419 return $content;
2420 }
2421
2422 /**
2423 * stdWrap_round will return a rounded number with ceil(), floor() or round(), defaults to round()
2424 * Only the english number format is supported . (dot) as decimal point
2425 *
2426 * @param string Input value undergoing processing in this function.
2427 * @param array stdWrap properties for round.
2428 * @return string The processed input value
2429 */
2430 public function stdWrap_round($content = '', $conf = array()){
2431 $content = $this->round($content, $conf['round.']);
2432 return $content;
2433 }
2434
2435 /**
2436 * numberFormat
2437 * Will return a formatted number based on configuration given as stdWrap properties
2438 *
2439 * @param string Input value undergoing processing in this function.
2440 * @param array stdWrap properties for numberFormat.
2441 * @return string The processed input value
2442 */
2443 public function stdWrap_numberFormat($content = '', $conf = array()) {
2444 $content = $this->numberFormat($content, $conf['numberFormat.']);
2445 return $content;
2446 }
2447
2448 /**
2449 * expandList
2450 * Will return a formatted number based on configuration given as stdWrap properties
2451 *
2452 * @param string Input value undergoing processing in this function.
2453 * @param array stdWrap properties for expandList.
2454 * @return string The processed input value
2455 */
2456 public function stdWrap_expandList($content = '', $conf = array()) {
2457 $content = t3lib_div::expandList($content);
2458 return $content;
2459 }
2460
2461 /**
2462 * date
2463 * Will return a formatted date based on configuration given according to PHP date/gmdate properties
2464 * Will return gmdate when the property GMT returns TRUE
2465 *
2466 * @param string $content Input value undergoing processing in this function.
2467 * @param array $conf stdWrap properties for date.
2468 * @return string The processed input value
2469 */
2470 public function stdWrap_date($content = '', $conf = array()) {
2471 // check for zero length string to mimic default case of date/gmdate.
2472 $content = $content == '' ? $GLOBALS['EXEC_TIME'] : intval($content);
2473 $content = ($conf['date.']['GMT'] ? gmdate($conf['date'], $content) : date($conf['date'], $content));
2474 return $content;
2475 }
2476
2477 /**
2478 * strftime
2479 * Will return a formatted date based on configuration given according to PHP strftime/gmstrftime properties
2480 * Will return gmstrftime when the property GMT returns TRUE
2481 *
2482 * @param string Input value undergoing processing in this function.
2483 * @param array stdWrap properties for strftime.
2484 * @return string The processed input value
2485 */
2486 public function stdWrap_strftime($content = '', $conf = array()) {
2487 $content = ($conf['strftime.']['GMT'] ? gmstrftime($conf['strftime'], $content) : strftime($conf['strftime'], $content));
2488 $tmp_charset = $conf['strftime.']['charset'] ? $conf['strftime.']['charset'] : $GLOBALS['TSFE']->localeCharset;
2489 if ($tmp_charset) {
2490 $content = $GLOBALS['TSFE']->csConv($content, $tmp_charset);
2491 }
2492 return $content;
2493 }
2494
2495 /**
2496 * age
2497 * Will return the age of a given timestamp based on configuration given by stdWrap properties
2498 *
2499 * @param string Input value undergoing processing in this function.
2500 * @param array stdWrap properties for age.
2501 * @return string The processed input value
2502 */
2503 public function stdWrap_age($content = '', $conf = array()) {
2504 $content = $this->calcAge($GLOBALS['EXEC_TIME'] - $content, $conf['age']);
2505 return $content;
2506 }
2507
2508 /**
2509 * case
2510 * Will transform the content to be upper or lower case only
2511 * Leaves HTML tags untouched
2512 *
2513 * @param string Input value undergoing processing in this function.
2514 * @param array stdWrap properties for case.
2515 * @return string The processed input value
2516 */
2517 public function stdWrap_case($content = '', $conf = array()) {
2518 $content = $this->HTMLcaseshift($content, $conf['case']);
2519 return $content;
2520 }
2521
2522 /**
2523 * bytes
2524 * Will return the size of a given number in Bytes *
2525 *
2526 * @param string Input value undergoing processing in this function.
2527 * @param array stdWrap properties for bytes.
2528 * @return string The processed input value
2529 */
2530 public function stdWrap_bytes($content = '', $conf = array()) {
2531 $content = t3lib_div::formatSize($content, $conf['bytes.']['labels']);
2532 return $content;
2533 }
2534
2535 /**
2536 * substring
2537 * Will return a substring based on position information given by stdWrap properties
2538 *
2539 * @param string Input value undergoing processing in this function.
2540 * @param array stdWrap properties for substring.
2541 * @return string The processed input value
2542 */
2543 public function stdWrap_substring($content = '', $conf = array()) {
2544 $content = $this->substring($content, $conf['substring']);
2545 return $content;
2546 }
2547
2548 /**
2549 * removeBadHTML
2550 * Removes HTML tags based on stdWrap properties
2551 *
2552 * @param string Input value undergoing processing in this function.
2553 * @param array stdWrap properties for removeBadHTML.
2554 * @return string The processed input value
2555 */
2556 public function stdWrap_removeBadHTML($content = '', $conf = array()) {
2557 $content = $this->removeBadHTML($content, $conf['removeBadHTML.']);
2558 return $content;
2559 }
2560
2561 /**
2562 * cropHTML
2563 * Crops content to a given size while leaving HTML tags untouched
2564 *
2565 * @param string Input value undergoing processing in this function.
2566 * @param array stdWrap properties for cropHTML.
2567 * @return string The processed input value
2568 */
2569 public function stdWrap_cropHTML($content = '', $conf = array()) {
2570 $content = $this->cropHTML($content, $conf['cropHTML']);
2571 return $content;
2572 }
2573
2574 /**
2575 * stripHtml
2576 * Copmletely removes HTML tags from content
2577 *
2578 * @param string Input value undergoing processing in this function.
2579 * @param array stdWrap properties for stripHtml.
2580 * @return string The processed input value
2581 */
2582 public function stdWrap_stripHtml($content = '', $conf = array()) {
2583 $content = strip_tags($content);
2584 return $content;
2585 }
2586
2587 /**
2588 * cropHTML
2589 * Crops content to a given size without caring abhout HTML tags
2590 *
2591 * @param string Input value undergoing processing in this function.
2592 * @param array stdWrap properties for crop.
2593 * @return string The processed input value
2594 */
2595 public function stdWrap_crop($content = '', $conf = array()) {
2596 $content = $this->crop($content, $conf['crop']);
2597 return $content;
2598 }
2599
2600 /**
2601 * rawUrlEncode
2602 * Encodes content to be used within URLs
2603 *
2604 * @param string Input value undergoing processing in this function.
2605 * @param array stdWrap properties for rawUrlEncode.
2606 * @return string The processed input value
2607 */
2608 public function stdWrap_rawUrlEncode($content = '', $conf = array()) {
2609 $content = rawurlencode($content);
2610 return $content;
2611 }
2612
2613 /**
2614 * htmlSpecialChars
2615 * Transforms HTML tags to readable text by replacing special characters with their HTML entity
2616 * When preserveEntities returns TRUE, existing entities will be left untouched
2617 *
2618 * @param string Input value undergoing processing in this function.
2619 * @param array stdWrap properties for htmlSpecalChars.
2620 * @return string The processed input value
2621 */
2622 public function stdWrap_htmlSpecialChars($content = '', $conf = array()) {
2623 $content = htmlSpecialChars($content);
2624 if ($conf['htmlSpecialChars.']['preserveEntities'])
2625 $content = t3lib_div::deHSCentities($content);
2626 return $content;
2627 }
2628
2629 /**
2630 * doubleBrTag
2631 * Searches for double line breaks and replaces them with the given value
2632 *
2633 * @param string Input value undergoing processing in this function.
2634 * @param array stdWrap properties for doubleBrTag.
2635 * @return string The processed input value
2636 */
2637 public function stdWrap_doubleBrTag($content = '', $conf = array()) {
2638 $content = preg_replace("/\r?\n[\t ]*\r?\n/", $conf['doubleBrTag'], $content);
2639 return $content;
2640 }
2641
2642 /**
2643 * br
2644 * Searches for single line breaks and replaces them with a <br />/<br> tag
2645 * according to the doctype
2646 *
2647 * @param string Input value undergoing processing in this function.
2648 * @param array stdWrap properties for br.
2649 * @return string The processed input value
2650 */
2651 public function stdWrap_br($content = '', $conf = array()) {
2652 $content = nl2br($content, !empty($GLOBALS['TSFE']->xhtmlDoctype));
2653 return $content;
2654 }
2655
2656 /**
2657 * brTag
2658 * Searches for single line feeds and replaces them with the given value
2659 *
2660 * @param string Input value undergoing processing in this function.
2661 * @param array stdWrap properties for brTag.
2662 * @return string The processed input value
2663 */
2664 public function stdWrap_brTag($content = '', $conf = array()) {
2665 $content = str_replace(LF, $conf['brTag'], $content);
2666 return $content;
2667 }
2668
2669 /**
2670 * encapsLines
2671 * Modifies text blocks by searching for lines which are not surrounded by HTML tags yet
2672 * and wrapping them with values given by stdWrap properties
2673 *
2674 * @param string Input value undergoing processing in this function.
2675 * @param array stdWrap properties for erncapsLines.
2676 * @return string The processed input value
2677 */
2678 public function stdWrap_encapsLines($content = '', $conf = array()) {
2679 $content = $this->encaps_lineSplit($content, $conf['encapsLines.']);
2680 return $content;
2681 }
2682
2683 /**
2684 * keywords
2685 * Transforms content into a CSV list to be used i.e. as keywords within a meta tag
2686 *
2687 * @param string Input value undergoing processing in this function.
2688 * @param array stdWrap properties for keywords.
2689 * @return string The processed input value
2690 */
2691 public function stdWrap_keywords($content = '', $conf = array()) {
2692 $content = $this->keywords($content);
2693 return $content;
2694 }
2695
2696 /**
2697 * innerWrap
2698 * First of a set of different wraps which will be applied in a certain order before or after other functions that modify the content
2699 * See wrap
2700 *
2701 * @param string Input value undergoing processing in this function.
2702 * @param array stdWrap properties for innerWrap.
2703 * @return string The processed input value
2704 */
2705 public function stdWrap_innerWrap($content = '', $conf = array()) {
2706 $content = $this->wrap($content, $conf['innerWrap']);
2707 return $content;
2708 }
2709
2710 /**
2711 * innerWrap2
2712 * Second of a set of different wraps which will be applied in a certain order before or after other functions that modify the content
2713 * See wrap
2714 *
2715 * @param string Input value undergoing processing in this function.
2716 * @param array stdWrap properties for innerWrap2.
2717 * @return string The processed input value
2718 */
2719 public function stdWrap_innerWrap2($content = '', $conf = array()) {
2720 $content = $this->wrap($content, $conf['innerWrap2']);
2721 return $content;
2722 }
2723
2724 /**
2725 * fontTag
2726 * A wrap formerly used to apply font tags to format the content
2727 * Still used by lib.stdheader although real font tags are not state of the art anymore
2728 * See wrap
2729 *
2730 * @param string Input value undergoing processing in this function.
2731 * @param array stdWrap properties for fontTag.
2732 * @return string The processed input value
2733 */
2734 public function stdWrap_fontTag($content = '', $conf = array()) {
2735 $content = $this->wrap($content, $conf['fontTag']);
2736 return $content;
2737 }
2738
2739 /**
2740 * addParams
2741 * Adds tag attributes to any content that is a tag
2742 *
2743 * @param string Input value undergoing processing in this function.
2744 * @param array stdWrap properties for addParams.
2745 * @return string The processed input value
2746 */
2747 public function stdWrap_addParams($content = '', $conf = array()) {
2748 $content = $this->addParams($content, $conf['addParams.']);
2749 return $content;
2750 }
2751
2752 /**
2753 * textStyle
2754 * Wraps content in font tags
2755 * See wrap
2756 *
2757 * @param string Input value undergoing processing in this function.
2758 * @param array stdWrap properties for textStyle.
2759 * @return string The processed input value
2760 */
2761 public function stdWrap_textStyle($content = '', $conf = array()) {
2762 $content = $this->textStyle($content, $conf['textStyle.']);
2763 return $content;
2764 }
2765
2766 /**
2767 * tableStyle
2768 * Wraps content with table tags
2769 * See wrap
2770 *
2771 * @param string Input value undergoing processing in this function.
2772 * @param array stdWrap properties for tableStyle.
2773 * @return string The processed input value
2774 */
2775 public function stdWrap_tableStyle($content = '', $conf = array()) {
2776 $content = $this->tableStyle($content, $conf['tableStyle.']);
2777 return $content;
2778 }
2779
2780 /**
2781 * filelink
2782 * Used to make lists of links to files
2783 * See wrap
2784 *
2785 * @param string Input value undergoing processing in this function.
2786 * @param array stdWrap properties for filelink.
2787 * @return string The processed input value
2788 */
2789 public function stdWrap_filelink($content = '', $conf = array()) {
2790 $content = $this->filelink($content, $conf['filelink.']);
2791 return $content;
2792 }
2793
2794 /**
2795 * preCObject
2796 * A content object that is prepended to the current content but between the innerWraps and the rest of the wraps
2797 *
2798 * @param string Input value undergoing processing in this function.
2799 * @param array stdWrap properties for preCObject.
2800 * @return string The processed input value
2801 */
2802 public function stdWrap_preCObject($content = '', $conf = array()) {
2803 $content = $this->cObjGetSingle($conf['preCObject'], $conf['preCObject.'], '/stdWrap/.preCObject') . $content;
2804 return $content;
2805 }
2806
2807 /**
2808 * postCObject
2809 * A content object that is appended to the current content but between the innerWraps and the rest of the wraps
2810 *
2811 * @param string Input value undergoing processing in this function.
2812 * @param array stdWrap properties for postCObject.
2813 * @return string The processed input value
2814 */
2815 public function stdWrap_postCObject($content = '', $conf = array()) {
2816 $content .= $this->cObjGetSingle($conf['postCObject'], $conf['postCObject.'], '/stdWrap/.postCObject');
2817 return $content;
2818 }
2819
2820 /**
2821 * wrapAlign
2822 * Wraps content with a div container having the style attribute text-align set to the given value
2823 * See wrap
2824 *
2825 * @param string Input value undergoing processing in this function.
2826 * @param array stdWrap properties for wrapAlign.
2827 * @return string The processed input value
2828 */
2829 public function stdWrap_wrapAlign($content = '', $conf = array()) {
2830 $wrapAlign = trim($conf['wrapAlign']);
2831 if ($wrapAlign) {
2832 $content = $this->wrap($content, '<div style="text-align:' . $wrapAlign . ';">|</div>');
2833 }
2834 return $content;
2835 }
2836
2837 /**
2838 * typolink
2839 * Wraps the content with a link tag
2840 * URLs and other attributes are created automatically by the values given in the stdWrap properties
2841 * See wrap
2842 *
2843 * @param string Input value undergoing processing in this function.
2844 * @param array stdWrap properties for typolink.
2845 * @return string The processed input value
2846 */
2847 public function stdWrap_typolink($content = '', $conf = array()) {
2848 $content = $this->typolink($content, $conf['typolink.']);
2849 return $content;
2850 }
2851
2852 /**
2853 * TCAselectItem
2854 * Returns a list of options available for a given field in the DB which has to be of the type select
2855 *
2856 * @param string Input value undergoing processing in this function.
2857 * @param array stdWrap properties for TCAselectItem.
2858 * @return string The processed input value
2859 */
2860 public function stdWrap_TCAselectItem($content = '', $conf = array()) {
2861 if (is_array($conf['TCAselectItem.'])) {
2862 $content = $this->TCAlookup($content, $conf['TCAselectItem.']);
2863 }
2864 return $content;
2865 }
2866
2867 /**
2868 * spaceBefore
2869 * Will add space before the current content
2870 * By default this is done with a clear.gif but it can be done with CSS margins by setting the property space.useDiv to TRUE
2871 *
2872 * @param string Input value undergoing processing in this function.
2873 * @param array stdWrap properties for spaceBefore and space.
2874 * @return string The processed input value
2875 */
2876 public function stdWrap_spaceBefore($content = '', $conf = array()) {
2877 $content = $this->wrapSpace($content, trim($conf['spaceBefore']) . '|', $conf['space.']);
2878 return $content;
2879 }
2880
2881 /**
2882 * spaceAfter
2883 * Will add space after the current content
2884 * By default this is done with a clear.gif but it can be done with CSS margins by setting the property space.useDiv to TRUE
2885 *
2886 * @param string Input value undergoing processing in this function.
2887 * @param array stdWrap properties for spaceAfter and space.
2888 * @return string The processed input value
2889 */
2890 public function stdWrap_spaceAfter($content = '', $conf = array()) {
2891 $content = $this->wrapSpace($content, '|' . trim($conf['spaceAfter']), $conf['space.']);
2892 return $content;
2893 }
2894
2895 /**
2896 * space
2897 * Will add space before or after the current content
2898 * By default this is done with a clear.gif but it can be done with CSS margins by setting the property space.useDiv to TRUE
2899 * See wrap
2900 *
2901 * @param string Input value undergoing processing in this function.
2902 * @param array stdWrap properties for space.
2903 * @return string The processed input value
2904 */
2905 public function stdWrap_space($content = '', $conf = array()) {
2906 $content = $this->wrapSpace($content, trim($conf['space']), $conf['space.']);
2907 return $content;
2908 }
2909
2910 /**
2911 * wrap
2912 * This is the "mother" of all wraps
2913 * Third of a set of different wraps which will be applied in a certain order before or after other functions that modify the content
2914 * Basically it will put additional content before and after the current content using a split character as a placeholder for the current content
2915 * The default split character is | but it can be replaced with other characters by the property splitChar
2916 * Any other wrap that does not have own splitChar settings will be using the default split char though
2917 *
2918 * @param string Input value undergoing processing in this function.
2919 * @param array stdWrap properties for wrap.
2920 * @return string The processed input value
2921 */
2922 public function stdWrap_wrap($content = '', $conf = array()) {
2923 $content = $this->wrap($content, $conf['wrap'], ($conf['wrap.']['splitChar'] ? $conf['wrap.']['splitChar'] : '|'));
2924 return $content;
2925 }
2926
2927 /**
2928 * noTrimWrap
2929 * Fourth of a set of different wraps which will be applied in a certain order before or after other functions that modify the content
2930 * The major difference to any other wrap is, that this one can make use of whitespace without trimming *
2931 *
2932 * @param string Input value undergoing processing in this function.
2933 * @param array stdWrap properties for noTrimWrap.
2934 * @return string The processed input value
2935 */
2936 public function stdWrap_noTrimWrap($content = '', $conf = array()) {
2937 $content = $this->noTrimWrap($content, $conf['noTrimWrap']);
2938 return $content;
2939 }
2940
2941 /**
2942 * wrap2
2943 * Fifth of a set of different wraps which will be applied in a certain order before or after other functions that modify the content
2944 * The default split character is | but it can be replaced with other characters by the property splitChar
2945 *
2946 * @param string Input value undergoing processing in this function.
2947 * @param array stdWrap properties for wrap2.
2948 * @return string The processed input value
2949 */
2950 public function stdWrap_wrap2($content = '', $conf = array()) {
2951 $content = $this->wrap($content, $conf['wrap2'], ($conf['wrap2.']['splitChar'] ? $conf['wrap2.']['splitChar'] : '|'));
2952 return $content;
2953 }
2954
2955 /**
2956 * dataWrap
2957 * Sixth of a set of different wraps which will be applied in a certain order before or after other functions that modify the content
2958 * Can fetch additional content the same way data does (i.e. {field:whatever}) and apply it to the wrap before that is applied to the content
2959 *
2960 * @param string Input value undergoing processing in this function.
2961 * @param array stdWrap properties for dataWrap.
2962 * @return string The processed input value
2963 */
2964 public function stdWrap_dataWrap($content = '', $conf = array()) {
2965 $content = $this->dataWrap($content, $conf['dataWrap']);
2966 return $content;
2967 }
2968
2969 /**
2970 * prepend
2971 * A content object that will be prepended to the current content after most of the wraps have already been applied
2972 *
2973 * @param string Input value undergoing processing in this function.
2974 * @param array stdWrap properties for prepend.
2975 * @return string The processed input value
2976 */
2977 public function stdWrap_prepend($content = '', $conf = array()) {
2978 $content = $this->cObjGetSingle($conf['prepend'], $conf['prepend.'], '/stdWrap/.prepend') . $content;
2979 return $content;
2980 }
2981
2982 /**
2983 * append
2984 * A content object that will be appended to the current content after most of the wraps have already been applied
2985 *
2986 * @param string Input value undergoing processing in this function.
2987 * @param array stdWrap properties for append.
2988 * @return string The processed input value
2989 */
2990 public function stdWrap_append($content = '', $conf = array()) {
2991 $content .= $this->cObjGetSingle($conf['append'], $conf['append.'], '/stdWrap/.append');
2992 return $content;
2993 }
2994
2995 /**
2996 * wrap3
2997 * Seventh of a set of different wraps which will be applied in a certain order before or after other functions that modify the content
2998 * The default split character is | but it can be replaced with other characters by the property splitChar
2999 *
3000 * @param string Input value undergoing processing in this function.
3001 * @param array stdWrap properties for wrap3.
3002 * @return string The processed input value
3003 */
3004 public function stdWrap_wrap3($content = '', $conf = array()) {
3005 $content = $this->wrap($content, $conf['wrap3'], ($conf['wrap3.']['splitChar'] ? $conf['wrap3.']['splitChar'] : '|'));
3006 return $content;
3007 }
3008
3009 /**
3010 * orderedStdWrap
3011 * Calls stdWrap for each entry in the provided array
3012 *
3013 * @param string Input value undergoing processing in this function.
3014 * @param array stdWrap properties for orderedStdWrap.
3015 * @return string The processed input value
3016 */
3017 public function stdWrap_orderedStdWrap($content = '', $conf = array()) {
3018 $sortedKeysArray = t3lib_TStemplate::sortedKeyList($conf['orderedStdWrap.'], TRUE);
3019 foreach ($sortedKeysArray as $key) {
3020 $content = $this->stdWrap($content, $conf['orderedStdWrap.'][$key . '.']);
3021 }
3022 return $content;
3023 }
3024 /**
3025 * outerWrap
3026 * Eighth of a set of different wraps which will be applied in a certain order before or after other functions that modify the content
3027 *
3028 * @param string Input value undergoing processing in this function.
3029 * @param array stdWrap properties for outerWrap.
3030 * @return string The processed input value
3031 */
3032 public function stdWrap_outerWrap($content = '', $conf = array()) {
3033 $content = $this->wrap($content, $conf['outerWrap']);
3034 return $content;
3035 }
3036
3037 /**
3038 * insertData
3039 * Can fetch additional content the same way data does and replaces any occurence of {field:whatever} with this content
3040 *
3041 * @param string Input value undergoing processing in this function.
3042 * @param array stdWrap properties for insertData.
3043 * @return string The processed input value
3044 */
3045 public function stdWrap_insertData($content = '', $conf = array()) {
3046 $content = $this->insertData($content);
3047 return $content;
3048 }
3049
3050 /**
3051 * offsetWrap
3052 * Creates a so called offset table around the content
3053 * Still here for historical reasons even not used too much nowadays
3054 *
3055 * @param string Input value undergoing processing in this function.
3056 * @param array stdWrap properties for offsetWrap.
3057 * @return string The processed input value
3058 */
3059 public function stdWrap_offsetWrap($content = '', $conf = array()) {
3060 $controlTable = t3lib_div::makeInstance('tslib_tableOffset');
3061 if ($conf['offsetWrap.']['tableParams'] || $conf['offsetWrap.']['tableParams.']) {
3062 $controlTable->tableParams = isset($conf['offsetWrap.']['tableParams.'])
3063 ? $this->stdWrap($conf['offsetWrap.']['tableParams'], $conf['offsetWrap.']['tableParams.'])
3064 : $conf['offsetWrap.']['tableParams'];
3065 }
3066 if ($conf['offsetWrap.']['tdParams'] || $conf['offsetWrap.']['tdParams.']) {
3067 $controlTable->tdParams = ' ' . (isset($conf['offsetWrap.']['tdParams.'])
3068 ? $this->stdWrap($conf['offsetWrap.']['tdParams'], $conf['offsetWrap.']['tdParams.'])
3069 : $conf['offsetWrap.']['tdParams']);
3070 }
3071 $content = $controlTable->start($content, $conf['offsetWrap']);
3072 if ($conf['offsetWrap.']['stdWrap.']) {
3073 $content = $this->stdWrap($content, $conf['offsetWrap.']['stdWrap.']);
3074 }
3075 return $content;
3076 }
3077
3078 /**
3079 * postUserFunc
3080 * Will execute a user function after the content has been modified by any other stdWrap function
3081 *
3082 * @param string Input value undergoing processing in this function.
3083 * @param array stdWrap properties for postUserFunc.
3084 * @return string The processed input value
3085 */
3086 public function stdWrap_postUserFunc($content = '', $conf = array()) {
3087 $content = $this->callUserFunction($conf['postUserFunc'], $conf['postUserFunc.'], $content);
3088 return $content;
3089 }
3090
3091 /**
3092 * postUserFuncInt
3093 * Will execute a user function after the content has been created and each time it is fetched from Cache
3094 * The result of this function itself will not be cached
3095 *
3096 * @param string Input value undergoing processing in this function.
3097 * @param array stdWrap properties for postUserFuncInt.
3098 * @return string The processed input value
3099 */
3100 public function stdWrap_postUserFuncInt($content = '', $conf = array()) {
3101 $substKey = 'INT_SCRIPT.' . $GLOBALS['TSFE']->uniqueHash();
3102 $GLOBALS['TSFE']->config['INTincScript'][$substKey] = array(
3103 'content' => $content, 'postUserFunc' => $conf['postUserFuncInt'], 'conf' => $conf['postUserFuncInt.'], 'type' => 'POSTUSERFUNC', 'cObj' => serialize($this)
3104 );
3105 $content = '<!--' . $substKey . '-->';
3106 return $content;
3107 }
3108
3109 /**
3110 * prefixComment
3111 * Will add HTML comments to the content to make it easier to identify certain content elements within the HTML output later on
3112 *
3113 * @param string Input value undergoing processing in this function.
3114 * @param array stdWrap properties for prefixComment.
3115 * @return string The processed input value
3116 */
3117 public function stdWrap_prefixComment($content = '', $conf = array()) {
3118<