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