Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00088 class t3lib_timeTrack { 00089 var $starttime = 0; // Is loaded with the millisecond time when this object is created 00090 00091 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 00092 var $printConf=array( 00093 'showParentKeys' => 1, 00094 'contentLength' => 10000, // Determines max lenght of displayed content before it gets cropped. 00095 '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. 00096 'flag_tree' => 1, 00097 'flag_messages' => 1, 00098 'flag_queries' => 0, 00099 'flag_content' => 0, 00100 'allTime' => 0, 00101 'keyLgd' => 40, 00102 'factor' => 10, 00103 'col' => '#D9D5C9' 00104 ); 00105 00106 var $wrapError =array( 00107 0 => array('',''), 00108 1 => array('<b>','</b>'), 00109 2 => array('<b><font color="#ff6600">','</font></b>'), 00110 3 => array('<b><font color="#ff0000">','</font></b>') 00111 ); 00112 var $wrapIcon =array( 00113 0 => '', 00114 1 => '<img src="t3lib/gfx/icon_note.gif" width="18" height="16" align="absmiddle" alt="" />', 00115 2 => '<img src="t3lib/gfx/icon_warning.gif" width="18" height="16" align="absmiddle" alt="" />', 00116 3 => '<img src="t3lib/gfx/icon_fatalerror.gif" width="18" height="16" align="absmiddle" alt="" />' 00117 ); 00118 00119 var $uniqueCounter=0; 00120 var $tsStack = array(array()); 00121 var $tsStackLevel = 0; 00122 var $tsStackLevelMax=array(); 00123 var $tsStackLog = array(); 00124 var $tsStackPointer=0; 00125 var $currentHashPointer=array(); 00126 00127 00128 00129 00130 00131 00132 /******************************************* 00133 * 00134 * Logging parsing times in the scripts 00135 * 00136 *******************************************/ 00137 00144 function start() { 00145 $this->starttime=0; 00146 $this->starttime=$this->mtime(); 00147 } 00148 00157 function push($tslabel, $value='') { 00158 array_push($this->tsStack[$this->tsStackPointer], $tslabel); 00159 array_push($this->currentHashPointer, 'timetracker_'.$this->uniqueCounter++); 00160 00161 $this->tsStackLevel++; 00162 $this->tsStackLevelMax[] = $this->tsStackLevel; 00163 00164 // setTSlog 00165 $k = end($this->currentHashPointer); 00166 $this->tsStackLog[$k] = array( 00167 'level' => $this->tsStackLevel, 00168 'tsStack' => $this->tsStack, 00169 'value' => $value, 00170 'starttime' => microtime(), 00171 'stackPointer' => $this->tsStackPointer 00172 ); 00173 } 00174 00182 function pull($content='') { 00183 $k = end($this->currentHashPointer); 00184 $this->tsStackLog[$k]['endtime'] = microtime(); 00185 $this->tsStackLog[$k]['content'] = $content; 00186 00187 $this->tsStackLevel--; 00188 array_pop($this->tsStack[$this->tsStackPointer]); 00189 array_pop($this->currentHashPointer); 00190 } 00191 00200 function setTSlogMessage($content,$num=0) { 00201 end($this->currentHashPointer); 00202 $k = current($this->currentHashPointer); 00203 00204 $this->tsStackLog[$k]['message'][] = $this->wrapIcon[$num].$this->wrapError[$num][0].htmlspecialchars($content).$this->wrapError[$num][1]; 00205 } 00206 00214 function setTSselectQuery($query,$msg) { 00215 end($this->currentHashPointer); 00216 $k = current($this->currentHashPointer); 00217 00218 $this->tsStackLog[$k]['selectQuery'][] = array('query'=>$query,'msg'=>$msg); 00219 } 00220 00227 function incStackPointer() { 00228 $this->tsStackPointer++; 00229 $this->tsStack[$this->tsStackPointer]=array(); 00230 } 00231 00238 function decStackPointer() { 00239 unset($this->tsStack[$this->tsStackPointer]); 00240 $this->tsStackPointer--; 00241 } 00242 00248 function mtime() { 00249 return $this->convertMicrotime(microtime())-$this->starttime; 00250 } 00251 00258 function convertMicrotime($microtime) { 00259 $parts = explode(' ',$microtime); 00260 return round(($parts[0]+$parts[1])*1000); 00261 } 00262 00263 00264 00265 00266 00267 00268 00269 00270 00271 00272 00273 00274 00275 00276 00277 00278 00279 /******************************************* 00280 * 00281 * Printing the parsing time information (for Admin Panel) 00282 * 00283 *******************************************/ 00284 00291 function printTSlog() { 00292 // Calculate times and keys for the tsStackLog 00293 reset($this->tsStackLog); 00294 $preEndtime=0; 00295 while(list($uniqueId,$data)=each($this->tsStackLog)) { 00296 $this->tsStackLog[$uniqueId]['endtime'] = $this->convertMicrotime($this->tsStackLog[$uniqueId]['endtime'])-$this->starttime; 00297 $this->tsStackLog[$uniqueId]['starttime'] = $this->convertMicrotime($this->tsStackLog[$uniqueId]['starttime'])-$this->starttime; 00298 $this->tsStackLog[$uniqueId]['deltatime'] = $this->tsStackLog[$uniqueId]['endtime']-$this->tsStackLog[$uniqueId]['starttime']; 00299 $this->tsStackLog[$uniqueId]['key'] = implode(end($data['tsStack']),$this->tsStackLog[$uniqueId]['stackPointer']?'.':'/'); 00300 $preEndtime = $this->tsStackLog[$uniqueId]['endtime']; 00301 } 00302 00303 // Create hierarchical array of keys pointing to the stack 00304 $arr = array(); 00305 reset($this->tsStackLog); 00306 while(list($uniqueId,$data)=each($this->tsStackLog)) { 00307 $this->createHierarchyArray($arr,$data['level'], $uniqueId); 00308 } 00309 // Parsing the registeret content and create icon-html for the tree 00310 $this->tsStackLog[$arr['0.'][0]]['content'] = $this->fixContent($arr['0.']['0.'], $this->tsStackLog[$arr['0.'][0]]['content'], '', 0, $arr['0.'][0]); 00311 00312 // Displaying the tree: 00313 reset($this->tsStackLog); 00314 $out='<tr> 00315 <td bgcolor="#ABBBB4" align="center"><b>'.$this->fw('TypoScript Key').'</b></td> 00316 <td bgcolor="#ABBBB4" align="center"><b>'.$this->fw('Value').'</b></td>'; 00317 if ($this->printConf['allTime']) { 00318 $out.=' 00319 <td bgcolor="#ABBBB4" align="center"><b>'.$this->fw('Time').'</b></td> 00320 <td bgcolor="#ABBBB4" align="center"><b>'.$this->fw('Own').'</b></td> 00321 <td bgcolor="#ABBBB4" align="center"><b>'.$this->fw('Sub').'</b></td> 00322 <td bgcolor="#ABBBB4" align="center"><b>'.$this->fw('Total').'</b></td>'; 00323 } else { 00324 $out.=' 00325 <td bgcolor="#ABBBB4" align="center"><b>'.$this->fw('Own').'</b></td>'; 00326 } 00327 00328 $out.=' 00329 <td bgcolor="#ABBBB4" align="center"><b>'.$this->fw('Details').'</b></td> 00330 </tr>'; 00331 00332 00333 00334 $flag_tree=$this->printConf['flag_tree']; 00335 $flag_messages=$this->printConf['flag_messages']; 00336 $flag_content=$this->printConf['flag_content']; 00337 $flag_queries=$this->printConf['flag_queries']; 00338 $keyLgd=$this->printConf['keyLgd']; 00339 $factor=$this->printConf['factor']; 00340 $col=$this->printConf['col']; 00341 00342 $c=0; 00343 while(list($uniqueId,$data)=each($this->tsStackLog)) { 00344 $bgColor = ' bgcolor="'.($c%2 ? t3lib_div::modifyHTMLColor($col,$factor,$factor,$factor) : $col).'"'; 00345 $item=''; 00346 if (!$c) { // If first... 00347 $data['icons']=''; 00348 $data['key']= 'Script Start'; 00349 $data['value'] = ''; 00350 } 00351 00352 00353 // key label: 00354 $keyLabel=''; 00355 if (!$flag_tree && $data['stackPointer']) { 00356 $temp=array(); 00357 reset($data['tsStack']); 00358 while(list($k,$v)=each($data['tsStack'])) { 00359 $temp[]=t3lib_div::fixed_lgd_pre(implode($v,$k?'.':'/'),$keyLgd); 00360 } 00361 array_pop($temp); 00362 $temp = array_reverse($temp); 00363 array_pop($temp); 00364 if (count($temp)) { 00365 $keyLabel='<br /><font color="#999999">'.implode($temp,'<br />').'</font>'; 00366 } 00367 } 00368 $theLabel = $flag_tree ? end(t3lib_div::trimExplode('.',$data['key'],1)) : $data['key']; 00369 $theLabel = t3lib_div::fixed_lgd_pre($theLabel, $keyLgd); 00370 $theLabel = $data['stackPointer'] ? '<font color="maroon">'.$theLabel.'</font>' : $theLabel; 00371 $keyLabel=$theLabel.$keyLabel; 00372 $item.='<td valign="top" nowrap="nowrap"'.$bgColor.'>'.($flag_tree?$data['icons']:'').$this->fw($keyLabel).'</td>'; 00373 00374 // key value: 00375 $keyValue=$data['value']; 00376 $item.='<td valign="top" nowrap="nowrap"'.$bgColor.'>'.$this->fw(htmlspecialchars($keyValue)).'</td>'; 00377 00378 if ($this->printConf['allTime']) { 00379 // deltatime: 00380 $item.='<td valign="top" align="right" nowrap="nowrap"'.$bgColor.'>'.$this->fw($data['starttime']).'</td>'; 00381 $item.='<td valign="top" align="right" nowrap="nowrap"'.$bgColor.'>'.$this->fw($data['owntime']).'</td>'; 00382 $item.='<td valign="top" align="right" nowrap="nowrap"'.$bgColor.'>'.$this->fw($data['subtime'] ? '+'.$data['subtime'] : '').'</td>'; 00383 $item.='<td valign="top" align="right" nowrap="nowrap"'.$bgColor.'>'.$this->fw($data['subtime'] ? '='.$data['deltatime'] : '').'</td>'; 00384 } else { 00385 // deltatime: 00386 $item.='<td valign="top" align="right" nowrap="nowrap"'.$bgColor.'>'.$this->fw($data['owntime']).'</td>'; 00387 } 00388 00389 00390 // messages: 00391 $msgArr=array(); 00392 $msg=''; 00393 if ($flag_messages && is_array($data['message'])) { 00394 reset($data['message']); 00395 while(list(,$v)=each($data['message'])) { 00396 $msgArr[]=nl2br($v); 00397 } 00398 } 00399 if ($flag_queries && is_array($data['selectQuery'])) { 00400 reset($data['selectQuery']); 00401 while(list(,$v)=each($data['selectQuery'])) { 00402 $res = $GLOBALS['TYPO3_DB']->sql_query('EXPLAIN '.$v['query']); 00403 $v['mysql_error'] = $GLOBALS['TYPO3_DB']->sql_error(); 00404 if (!$GLOBALS['TYPO3_DB']->sql_error()) { 00405 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00406 $v['explain'][]=$row; 00407 } 00408 } 00409 $msgArr[]=t3lib_div::view_array($v); 00410 } 00411 } 00412 if ($flag_content && strcmp($data['content'],'')) { 00413 $msgArr[]='<font color="#000066">'.nl2br($data['content']).'</font>'; 00414 } 00415 if (count($msgArr)) { 00416 $msg=implode($msgArr,'<hr />'); 00417 } 00418 $item.='<td valign="top"'.$bgColor.'>'.$this->fw($msg).'</td>'; 00419 $out.='<tr>'.$item.'</tr>'; 00420 $c++; 00421 } 00422 $out='<table border="0" cellpadding="0" cellspacing="0">'.$out.'</table>'; 00423 return $out; 00424 } 00425 00436 function fixContent(&$arr, $content, $depthData='', $first=0, $vKey='') { 00437 $ac=0; 00438 $c=0; 00439 // First, find number of entries 00440 reset($arr); 00441 while(list($k,$v)=each($arr)) { 00442 if (t3lib_div::testInt($k)) { 00443 $ac++; 00444 } 00445 } 00446 // Traverse through entries 00447 $subtime=0; 00448 reset($arr); 00449 while(list($k,$v)=each($arr)) { 00450 if (t3lib_div::testInt($k)) { 00451 $c++; 00452 00453 $deeper = is_array($arr[$k.'.']) ? 1 : 0; 00454 $PM = 'join'; 00455 $LN = ($ac==$c)?'blank':'line'; 00456 $BTM = ($ac==$c)?'bottom':''; 00457 $PM = is_array($arr[$k.'.']) ? ($deeper ? 'minus':'plus') : 'join'; 00458 $this->tsStackLog[$v]['icons']=$depthData.($first?'':'<img src="t3lib/gfx/ol/'.$PM.$BTM.'.gif" width="18" height="16" align="top" border="0" alt="" />'); 00459 00460 if (strlen($this->tsStackLog[$v]['content'])) { 00461 $content = str_replace($this->tsStackLog[$v]['content'],$v, $content); 00462 } 00463 if (is_array($arr[$k.'.'])) { 00464 $this->tsStackLog[$v]['content'] = $this->fixContent($arr[$k.'.'], $this->tsStackLog[$v]['content'], $depthData.($first?'':'<img src="t3lib/gfx/ol/'.$LN.'.gif" width="18" height="16" align="top" border="0" alt="" />'), 0, $v); 00465 } else { 00466 $this->tsStackLog[$v]['content'] = $this->fixCLen($this->tsStackLog[$v]['content'], $this->tsStackLog[$v]['value']); 00467 $this->tsStackLog[$v]['subtime']=''; 00468 $this->tsStackLog[$v]['owntime']=$this->tsStackLog[$v]['deltatime']; 00469 } 00470 $subtime+=$this->tsStackLog[$v]['deltatime']; 00471 } 00472 } 00473 // Set content with special chars 00474 if (isset($this->tsStackLog[$vKey])) { 00475 $this->tsStackLog[$vKey]['subtime']=$subtime; 00476 $this->tsStackLog[$vKey]['owntime']=$this->tsStackLog[$vKey]['deltatime']-$subtime; 00477 } 00478 $content=$this->fixCLen($content, $this->tsStackLog[$vKey]['value']); 00479 00480 // Traverse array again, this time substitute the unique hash with the red key 00481 reset($arr); 00482 while(list($k,$v)=each($arr)) { 00483 if (t3lib_div::testInt($k)) { 00484 if (strlen($this->tsStackLog[$v]['content'])) { 00485 $content = str_replace($v, '<font color="red"><b>['.$this->tsStackLog[$v]['key'].']</b></font>', $content); 00486 } 00487 } 00488 } 00489 // return the content 00490 return $content; 00491 } 00492 00500 function fixCLen($c,$v) { 00501 $len = $v=='FILE'?$this->printConf['contentLength_FILE']:$this->printConf['contentLength']; 00502 if (strlen($c)>$len) { 00503 $c='<font color="green">'.htmlspecialchars(t3lib_div::fixed_lgd($c,$len)).'</font>'; 00504 } else { 00505 $c=htmlspecialchars($c); 00506 } 00507 return $c; 00508 } 00509 00516 function fw($str) { 00517 return '<font face="verdana" color="black" size="1" style="color:black;">'.$str.' </font>'; 00518 } 00519 00530 function createHierarchyArray(&$arr,$pointer,$uniqueId) { 00531 if (!is_array($arr)) $arr=array(); 00532 if ($pointer>0) { 00533 end($arr); 00534 $k=key($arr); 00535 $this->createHierarchyArray($arr[intval($k).'.'],$pointer-1,$uniqueId); 00536 } else { 00537 $arr[] = $uniqueId; 00538 } 00539 } 00540 00550 function debug_typo3PrintError($header,$text,$js,$baseUrl='') { 00551 if ($js) { 00552 echo"alert('".t3lib_div::slashJS($header."\n".$text)."');"; 00553 } else { 00554 echo ' 00555 <html> 00556 <head> 00557 '.($baseUrl ? '<base href="'.htmlspecialchars($baseUrl).'" />' : '').' 00558 <title>Error!</title> 00559 </head> 00560 <body bgcolor="white"> 00561 <div align="center"> 00562 <table border="0" cellspacing="0" cellpadding="0" width="333" bgcolor="#ffffff"> 00563 <tr> 00564 <td><img src="t3lib/gfx/typo3logo.gif" width="333" height="43" vspace="10" border="0" alt="" /></td> 00565 </tr> 00566 <tr> 00567 <td bgcolor="black"> 00568 <table width="100%" border="0" cellspacing="1" cellpadding="10"> 00569 <tr> 00570 <td bgcolor="#F4F0E8"> 00571 <font face="verdana,arial,helvetica" size="2">'; 00572 echo '<b><center><font size="+1">'.$header.'</font></center></b><br />'.$text; 00573 echo ' </font> 00574 </td> 00575 </tr> 00576 </table> 00577 </td> 00578 </tr> 00579 </table> 00580 </div> 00581 </body> 00582 </html>'; 00583 } 00584 } 00585 } 00586 ?>