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