Tiny bug with date function in t3lib_befunc. Casted timestamp to integer.
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_timetrack.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2009 Kasper Skaarhoj (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 class with time tracking functions
29 *
30 * $Id$
31 * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
32 * XHTML compliant
33 *
34 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
35 */
36 /**
37 * [CLASS/FUNCTION INDEX of SCRIPT]
38 *
39 *
40 *
41 * 88: class t3lib_timeTrack
42 *
43 * SECTION: Logging parsing times in the scripts
44 * 144: function start()
45 * 164: function push($tslabel, $value='')
46 * 189: function pull($content='')
47 * 207: function setTSlogMessage($content,$num=0)
48 * 221: function setTSselectQuery($query,$msg)
49 * 234: function incStackPointer()
50 * 245: function decStackPointer()
51 * 255: function mtime()
52 * 265: function convertMicrotime($microtime)
53 *
54 * SECTION: Printing the parsing time information (for Admin Panel)
55 * 298: function printTSlog()
56 * 447: function fixContent(&$arr, $content, $depthData='', $first=0, $vKey='')
57 * 511: function fixCLen($c,$v)
58 * 527: function fw($str)
59 * 541: function createHierarchyArray(&$arr,$pointer,$uniqueId)
60 * 561: function debug_typo3PrintError($header,$text,$js,$baseUrl='')
61 *
62 * TOTAL FUNCTIONS: 15
63 * (This index is automatically created/updated by the extension "extdeveval")
64 *
65 */
66
67
68
69
70
71
72
73
74
75
76
77 /**
78 * Frontend Timetracking functions
79 *
80 * Is used to register how much time is used with operations in TypoScript
81 * Used by index_ts
82 *
83 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
84 * @package TYPO3
85 * @subpackage t3lib
86 * @see t3lib_tsfeBeUserAuth, tslib_fe, tslib_cObj, TSpagegen
87 */
88 class t3lib_timeTrack {
89 var $starttime = 0; // Is loaded with the millisecond time when this object is created
90
91 var $LR = 1; // Log Rendering flag. If set, ->push() and ->pull() is called from the cObj->cObjGetSingle(). This determines whether or not the TypoScript parsing activity is logged. But it also slows down the rendering
92 var $printConf=array(
93 'showParentKeys' => 1,
94 'contentLength' => 10000, // Determines max lenght of displayed content before it gets cropped.
95 'contentLength_FILE' => 400, // Determines max lenght of displayed content FROM FILE cObjects before it gets cropped. Reason is that most FILE cObjects are huge and often used as template-code.
96 'flag_tree' => 1,
97 'flag_messages' => 1,
98 'flag_queries' => 0,
99 'flag_content' => 0,
100 'allTime' => 0,
101 'keyLgd' => 40,
102 'factor' => 10,
103 'col' => '#D9D5C9',
104 'highlight_col' => '#FF9933'
105 );
106
107 var $wrapError = array();
108 var $wrapIcon = array();
109 var $uniqueCounter = 0;
110 var $tsStack = array(array());
111 var $tsStackLevel = 0;
112 var $tsStackLevelMax = array();
113 var $tsStackLog = array();
114 var $tsStackPointer = 0;
115 var $currentHashPointer = array();
116
117 var $highlightLongerThan = 0; // Log entries that take than this number of milliseconds (own time) will be highlighted during log display. Set 0 to disable highlighting.
118
119
120
121
122
123
124
125 /*******************************************
126 *
127 * Logging parsing times in the scripts
128 *
129 *******************************************/
130
131 /**
132 * Constructor
133 * Sets the starting time
134 *
135 * @return void
136 */
137 public function start() {
138 $this->wrapError = array(
139 0 => array('',''),
140 1 => array('<strong>','</strong>'),
141 2 => array('<strong style="color:#ff6600;">','</strong>'),
142 3 => array('<strong style="color:#ff0000;">','</strong>')
143 );
144
145 $this->wrapIcon = array(
146 0 => '',
147 1 => '<img src="'.TYPO3_mainDir.'gfx/icon_note.gif" width="18" height="16" align="absmiddle" alt="" />',
148 2 => '<img src="'.TYPO3_mainDir.'gfx/icon_warning.gif" width="18" height="16" align="absmiddle" alt="" />',
149 3 => '<img src="'.TYPO3_mainDir.'gfx/icon_fatalerror.gif" width="18" height="16" align="absmiddle" alt="" />'
150 );
151
152 $this->starttime = $this->getMilliseconds();
153 }
154
155 /**
156 * Pushes an element to the TypoScript tracking array
157 *
158 * @param string Label string for the entry, eg. TypoScript property name
159 * @param string Additional value(?)
160 * @return void
161 * @see tslib_cObj::cObjGetSingle(), pull()
162 */
163 public function push($tslabel, $value = '') {
164 array_push($this->tsStack[$this->tsStackPointer], $tslabel);
165 array_push($this->currentHashPointer, 'timetracker_'.$this->uniqueCounter++);
166
167 $this->tsStackLevel++;
168 $this->tsStackLevelMax[] = $this->tsStackLevel;
169
170 // setTSlog
171 $k = end($this->currentHashPointer);
172 $this->tsStackLog[$k] = array(
173 'level' => $this->tsStackLevel,
174 'tsStack' => $this->tsStack,
175 'value' => $value,
176 'starttime' => microtime(true),
177 'stackPointer' => $this->tsStackPointer
178 );
179 }
180
181 /**
182 * Pulls an element from the TypoScript tracking array
183 *
184 * @param string The content string generated within the push/pull part.
185 * @return void
186 * @see tslib_cObj::cObjGetSingle(), push()
187 */
188 public function pull($content = '') {
189 $k = end($this->currentHashPointer);
190 $this->tsStackLog[$k]['endtime'] = microtime(true);
191 $this->tsStackLog[$k]['content'] = $content;
192
193 $this->tsStackLevel--;
194 array_pop($this->tsStack[$this->tsStackPointer]);
195 array_pop($this->currentHashPointer);
196 }
197
198 /**
199 * Logs the TypoScript entry
200 *
201 * @param string The message string
202 * @param integer Message type: 0: information, 1: message, 2: warning, 3: error
203 * @return void
204 * @see tslib_cObj::CONTENT()
205 */
206 public function setTSlogMessage($content, $num = 0) {
207 end($this->currentHashPointer);
208 $k = current($this->currentHashPointer);
209
210 if (strlen($content)>30) { // Enlarge the "details" column by adding a wide clear.gif
211 $placeholder = '<br /><img src="'.TYPO3_mainDir.'clear.gif" width="300" height="1" alt="" />';
212 }
213 $this->tsStackLog[$k]['message'][] = $this->wrapIcon[$num].$this->wrapError[$num][0].htmlspecialchars($content).$this->wrapError[$num][1].$placeholder;
214 }
215
216 /**
217 * Set TSselectQuery - for messages in TypoScript debugger.
218 *
219 * @param array Query array
220 * @param string Message/Label to attach
221 * @return void
222 */
223 public function setTSselectQuery(array $data, $msg = '') {
224 end($this->currentHashPointer);
225 $k = current($this->currentHashPointer);
226
227 if (strlen($msg)) {
228 $data['msg'] = $msg;
229 }
230
231 $this->tsStackLog[$k]['selectQuery'][] = $data;
232 }
233
234 /**
235 * Increases the stack pointer
236 *
237 * @return void
238 * @see decStackPointer(), TSpagegen::renderContent(), tslib_cObj::cObjGetSingle()
239 */
240 public function incStackPointer() {
241 $this->tsStackPointer++;
242 $this->tsStack[$this->tsStackPointer]=array();
243 }
244
245 /**
246 * Decreases the stack pointer
247 *
248 * @return void
249 * @see incStackPointer(), TSpagegen::renderContent(), tslib_cObj::cObjGetSingle()
250 */
251 public function decStackPointer() {
252 unset($this->tsStack[$this->tsStackPointer]);
253 $this->tsStackPointer--;
254 }
255
256 /**
257 * Returns the current time in milliseconds
258 *
259 * @return integer
260 * @deprecated since TYPO3 4.3 - use getDifferenceToStarttime() instead
261 */
262 protected function mtime() {
263 return $this->getDifferenceToStarttime();
264 }
265
266 /**
267 * Returns microtime input to milliseconds
268 *
269 * @param string PHP microtime string
270 * @return integer
271 * @deprecated since TYPO3 4.3 - use getMilliseconds() instead that expects microtime as float instead of a string
272 */
273 public function convertMicrotime($microtime) {
274 t3lib_div::logDeprecatedFunction();
275
276 $parts = explode(' ',$microtime);
277 return round(($parts[0]+$parts[1])*1000);
278 }
279
280 /**
281 * Gets a microtime value as milliseconds value.
282 *
283 * @param float $microtime: The microtime value - if not set the current time is used
284 * @return integer The microtime value as milliseconds value
285 */
286 public function getMilliseconds($microtime = NULL) {
287 if (!isset($microtime)) {
288 $microtime = microtime(true);
289 }
290 return round($microtime * 1000);
291 }
292
293 /**
294 * Gets the difference between a given microtime value and the starting time as milliseconds.
295 *
296 * @param float $microtime: The microtime value - if not set the current time is used
297 * @return integer The difference between a given microtime value and starting time as milliseconds
298 */
299 public function getDifferenceToStarttime($microtime = NULL) {
300 return ($this->getMilliseconds($microtime) - $this->starttime);
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319 /*******************************************
320 *
321 * Printing the parsing time information (for Admin Panel)
322 *
323 *******************************************/
324
325 /**
326 * Print TypoScript parsing log
327 *
328 * @return string HTML table with the information about parsing times.
329 * @see t3lib_tsfeBeUserAuth::extGetCategory_tsdebug()
330 */
331 public function printTSlog() {
332 // Calculate times and keys for the tsStackLog
333 foreach ($this->tsStackLog as $uniqueId => &$data) {
334 $data['endtime'] = $this->getDifferenceToStarttime($data['endtime']);
335 $data['starttime'] = $this->getDifferenceToStarttime($data['starttime']);
336 $data['deltatime'] = $data['endtime'] - $data['starttime'];
337 $data['key'] = implode($data['stackPointer'] ? '.' : '/', end($data['tsStack']));
338 }
339
340 // Create hierarchical array of keys pointing to the stack
341 $arr = array();
342 foreach ($this->tsStackLog as $uniqueId => $data) {
343 $this->createHierarchyArray($arr, $data['level'], $uniqueId);
344 }
345 // Parsing the registeret content and create icon-html for the tree
346 $this->tsStackLog[$arr['0.'][0]]['content'] = $this->fixContent($arr['0.']['0.'], $this->tsStackLog[$arr['0.'][0]]['content'], '', 0, $arr['0.'][0]);
347
348 // Displaying the tree:
349 $outputArr = array();
350 $outputArr[] = $this->fw('TypoScript Key');
351 $outputArr[] = $this->fw('Value');
352
353 if ($this->printConf['allTime']) {
354 $outputArr[] = $this->fw('Time');
355 $outputArr[] = $this->fw('Own');
356 $outputArr[] = $this->fw('Sub');
357 $outputArr[] = $this->fw('Total');
358 } else {
359 $outputArr[] = $this->fw('Own');
360 }
361
362 $outputArr[] = $this->fw('Details');
363
364 $out = '';
365 foreach ($outputArr as $row) {
366 $out.= '
367 <th style="text-align:center; background:#ABBBB4;"><strong>'.$row.'</strong></th>';
368 }
369 $out = '<tr>'.$out.'</tr>';
370
371 $flag_tree = $this->printConf['flag_tree'];
372 $flag_messages = $this->printConf['flag_messages'];
373 $flag_content = $this->printConf['flag_content'];
374 $flag_queries = $this->printConf['flag_queries'];
375 $keyLgd = $this->printConf['keyLgd'];
376 $factor = $this->printConf['factor'];
377 $col = $this->printConf['col'];
378 $highlight_col = $this->printConf['highlight_col'];
379
380 $c=0;
381 foreach ($this->tsStackLog as $uniqueId => $data) {
382 $bgColor = ' background-color:'.($c%2 ? t3lib_div::modifyHTMLColor($col,$factor,$factor,$factor) : $col).';';
383 if ($this->highlightLongerThan && intval($data['owntime']) > intval($this->highlightLongerThan)) {
384 $bgColor = ' background-color:'.$highlight_col.';';
385 }
386
387 $item = '';
388 if (!$c) { // If first...
389 $data['icons'] = '';
390 $data['key'] = 'Script Start';
391 $data['value'] = '';
392 }
393
394
395 // key label:
396 $keyLabel = '';
397 if (!$flag_tree && $data['stackPointer']) {
398 $temp = array();
399 reset($data['tsStack']);
400 while(list($k,$v)=each($data['tsStack'])) {
401 $temp[] = t3lib_div::fixed_lgd_cs(implode($v,$k?'.':'/'),-$keyLgd);
402 }
403 array_pop($temp);
404 $temp = array_reverse($temp);
405 array_pop($temp);
406 if (count($temp)) {
407 $keyLabel = '<br /><span style="color:#999999;">'.implode($temp,'<br />').'</span>';
408 }
409 }
410 if ($flag_tree) {
411 $tmp = t3lib_div::trimExplode('.',$data['key'],1);
412 $theLabel = end($tmp);
413 } else {
414 $theLabel = $data['key'];
415 }
416 $theLabel = t3lib_div::fixed_lgd_cs($theLabel, -$keyLgd);
417 $theLabel = $data['stackPointer'] ? '<span style="color:maroon;">'.$theLabel.'</span>' : $theLabel;
418 $keyLabel = $theLabel.$keyLabel;
419 $item.= '<td valign="top" style="text-align:left; white-space:nowrap; padding-left:2px;'.$bgColor.'">'.($flag_tree?$data['icons']:'').$this->fw($keyLabel).'</td>';
420
421 // key value:
422 $keyValue = $data['value'];
423 $item.= '<td valign="top" style="text-align:left; white-space:nowrap;'.$bgColor.'">'.$this->fw(htmlspecialchars($keyValue)).'</td>';
424
425 if ($this->printConf['allTime']) {
426 $item.= '<td valign="top" style="text-align:right; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['starttime']).'</td>';
427 $item.= '<td valign="top" style="text-align:right; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['owntime']).'</td>';
428 $item.= '<td valign="top" style="text-align:left; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['subtime'] ? '+'.$data['subtime'] : '').'</td>';
429 $item.= '<td valign="top" style="text-align:left; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['subtime'] ? '='.$data['deltatime'] : '').'</td>';
430 } else {
431 $item.= '<td valign="top" style="text-align:right; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['owntime']).'</td>';
432 }
433
434
435 // messages:
436 $msgArr = array();
437 $msg = '';
438 if ($flag_messages && is_array($data['message'])) {
439 reset($data['message']);
440 while(list(,$v)=each($data['message'])) {
441 $msgArr[] = nl2br($v);
442 }
443 }
444 if ($flag_queries && is_array($data['selectQuery'])) {
445 $msgArr[] = t3lib_div::view_array($data['selectQuery']);
446 }
447 if ($flag_content && strcmp($data['content'],'')) {
448 $maxlen = 120;
449 if (preg_match_all('/(\S{'.$maxlen.',})/', $data['content'], $reg)) { // Break lines which are too longer than $maxlen chars (can happen if content contains long paths...)
450 foreach ($reg[1] as $key=>$match) {
451 $match = preg_replace('/(.{'.$maxlen.'})/', '$1 ', $match);
452 $data['content'] = str_replace($reg[0][$key], $match, $data['content']);
453 }
454 }
455 $msgArr[] = '<span style="color:#000066;">'.nl2br($data['content']).'</span>';
456 }
457 if (count($msgArr)) {
458 $msg = implode($msgArr,'<hr />');
459 }
460 $item.= '<td valign="top" style="text-align:left;'.$bgColor.'">'.$this->fw($msg).'</td>';
461 $out.= '<tr>'.$item.'</tr>';
462 $c++;
463 }
464 $out = '<table border="0" cellpadding="0" cellspacing="0" summary="">'.$out.'</table>';
465 return $out;
466 }
467
468 /**
469 * Recursively generates the content to display
470 *
471 * @param array Array which is modified with content. Reference
472 * @param string Current content string for the level
473 * @param string Prefixed icons for new PM icons
474 * @param boolean Set this for the first call from outside.
475 * @param string Seems to be the previous tsStackLog key
476 * @return string Returns the $content string generated/modified. Also the $arr array is modified!
477 */
478 protected function fixContent(&$arr, $content, $depthData = '', $first = 0, $vKey = '') {
479 $ac=0;
480 $c=0;
481 // First, find number of entries
482 reset($arr);
483 while(list($k,$v)=each($arr)) {
484 if (t3lib_div::testInt($k)) {
485 $ac++;
486 }
487 }
488 // Traverse through entries
489 $subtime=0;
490 reset($arr);
491 while(list($k,$v)=each($arr)) {
492 if (t3lib_div::testInt($k)) {
493 $c++;
494
495 $deeper = is_array($arr[$k.'.']) ? 1 : 0;
496 $PM = 'join';
497 $LN = ($ac==$c)?'blank':'line';
498 $BTM = ($ac==$c)?'bottom':'';
499 $PM = is_array($arr[$k.'.']) ? ($deeper ? 'minus':'plus') : 'join';
500 $this->tsStackLog[$v]['icons'] = $depthData.($first?'':'<img src="'.TYPO3_mainDir.'gfx/ol/'.$PM.$BTM.'.gif" width="18" height="16" align="top" border="0" alt="" />');
501
502 if (strlen($this->tsStackLog[$v]['content'])) {
503 $content = str_replace($this->tsStackLog[$v]['content'],$v, $content);
504 }
505 if (is_array($arr[$k.'.'])) {
506 $this->tsStackLog[$v]['content'] = $this->fixContent($arr[$k.'.'], $this->tsStackLog[$v]['content'], $depthData.($first?'':'<img src="'.TYPO3_mainDir.'gfx/ol/'.$LN.'.gif" width="18" height="16" align="top" border="0" alt="" />'), 0, $v);
507 } else {
508 $this->tsStackLog[$v]['content'] = $this->fixCLen($this->tsStackLog[$v]['content'], $this->tsStackLog[$v]['value']);
509 $this->tsStackLog[$v]['subtime'] = '';
510 $this->tsStackLog[$v]['owntime'] = $this->tsStackLog[$v]['deltatime'];
511 }
512 $subtime+= $this->tsStackLog[$v]['deltatime'];
513 }
514 }
515 // Set content with special chars
516 if (isset($this->tsStackLog[$vKey])) {
517 $this->tsStackLog[$vKey]['subtime'] = $subtime;
518 $this->tsStackLog[$vKey]['owntime'] = $this->tsStackLog[$vKey]['deltatime']-$subtime;
519 }
520 $content=$this->fixCLen($content, $this->tsStackLog[$vKey]['value']);
521
522 // Traverse array again, this time substitute the unique hash with the red key
523 reset($arr);
524 while(list($k,$v)=each($arr)) {
525 if (t3lib_div::testInt($k)) {
526 if (strlen($this->tsStackLog[$v]['content'])) {
527 $content = str_replace($v, '<strong style="color:red;">['.$this->tsStackLog[$v]['key'].']</strong>', $content);
528 }
529 }
530 }
531 // return the content
532 return $content;
533 }
534
535 /**
536 * Wraps the input content string in green colored span-tags IF the length o fthe input string exceeds $this->printConf['contentLength'] (or $this->printConf['contentLength_FILE'] if $v == "FILE"
537 *
538 * @param string The content string
539 * @param string Command: If "FILE" then $this->printConf['contentLength_FILE'] is used for content length comparison, otherwise $this->printConf['contentLength']
540 * @return string
541 */
542 protected function fixCLen($c, $v) {
543 $len = $v=='FILE'?$this->printConf['contentLength_FILE']:$this->printConf['contentLength'];
544 if (strlen($c)>$len) {
545 $c = '<span style="color:green;">'.htmlspecialchars(t3lib_div::fixed_lgd_cs($c,$len)).'</span>';
546 } else {
547 $c = htmlspecialchars($c);
548 }
549 return $c;
550 }
551
552 /**
553 * Wraps input string in a <span> tag with black verdana font
554 *
555 * @param string The string to be wrapped
556 * @return string
557 */
558 protected function fw($str) {
559 return '<span style="font-family:Verdana,Arial,Helvetica,sans-serif; font-size:10px; color:black; vertical-align:top;">'.$str.'&nbsp;</span>';
560 }
561
562 /**
563 * Helper function for internal data manipulation
564 *
565 * @param array Array (passed by reference) and modified
566 * @param integer Pointer value
567 * @param string Unique ID string
568 * @return void
569 * @access private
570 * @see printTSlog()
571 */
572 protected function createHierarchyArray(&$arr, $pointer, $uniqueId) {
573 if (!is_array($arr)) {
574 $arr = array();
575 }
576 if ($pointer>0) {
577 end($arr);
578 $k = key($arr);
579 $this->createHierarchyArray($arr[intval($k).'.'],$pointer-1,$uniqueId);
580 } else {
581 $arr[] = $uniqueId;
582 }
583 }
584
585 /**
586 * This prints out a TYPO3 error message.
587 *
588 * @param string Header string
589 * @param string Message string
590 * @param boolean If set, then this will produce a alert() line for inclusion in JavaScript.
591 * @param string URL for the <base> tag (if you want it)
592 * @return string
593 */
594 public function debug_typo3PrintError($header, $text, $js, $baseUrl = '') {
595 if ($js) {
596 $errorMessage = 'alert(\'' . t3lib_div::slashJS($header . '\n' . $text) . '\');';
597 } else {
598 $errorMessage = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
599 "http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
600 <?xml version="1.0" encoding="utf-8"?>
601 <html>
602 <head>
603 '.($baseUrl ? '<base href="'.htmlspecialchars($baseUrl).'" />' : '').'
604 <title>Error!</title>
605 <style type="text/css"><!--/*--><![CDATA[/*><!--*/
606 body { font-family:Verdana,Arial,Helvetica,sans-serif; font-size: 90%; text-align: center; background-color: #ffffff; }
607 h1 { font-size: 1.2em; margin: 0 0 1em 0; }
608 p { margin: 0; text-align: left; }
609 img { border: 0; margin: 10px 0; }
610 div.center div { margin: 0 auto; }
611 .errorBox { width: 400px; padding: 0.5em; border: 1px solid black; background-color: #F4F0E8; }
612 /*]]>*/--></style>
613 </head>
614 <body>
615 <div class="center">
616 <img src="'.TYPO3_mainDir.'gfx/typo3logo.gif" width="123" height="34" alt="" />
617 <div class="errorBox">
618 <h1>'.$header.'</h1>
619 <p>'.$text.'</p>
620 </div>
621 </div>
622 </body>
623 </html>';
624 }
625
626 // Hook to modify error message
627 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_timetrack.php']['debug_typo3PrintError'])) {
628 $params = array(
629 'header' => $header,
630 'text' => $text,
631 'js' => $js,
632 'baseUrl' => $baseUrl,
633 'errorMessage' => &$errorMessage
634 );
635 $null = null;
636 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_timetrack.php']['debug_typo3PrintError'] as $hookMethod) {
637 t3lib_div::callUserFunction($hookMethod, $params, $null);
638 }
639 }
640
641 echo $errorMessage;
642 }
643 }
644
645 // XCLASSing is not possible for this class
646
647 ?>