/src/typo3_src-4.2.0alpha1/t3lib/class.t3lib_timetrack.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2007 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                 'highlight_col' => '#FF9933'
00105         );
00106 
00107         var $wrapError = array();
00108         var $wrapIcon = array();
00109         var $uniqueCounter = 0;
00110         var $tsStack = array(array());
00111         var $tsStackLevel = 0;
00112         var $tsStackLevelMax = array();
00113         var $tsStackLog = array();
00114         var $tsStackPointer = 0;
00115         var $currentHashPointer = array();
00116 
00117         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.
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125         /*******************************************
00126         *
00127         * Logging parsing times in the scripts
00128         *
00129         *******************************************/
00130 
00137         function start()    {
00138                 $this->wrapError = array(
00139                         0 => array('',''),
00140                         1 => array('<strong>','</strong>'),
00141                         2 => array('<strong style="color:#ff6600;">','</strong>'),
00142                         3 => array('<strong style="color:#ff0000;">','</strong>')
00143                 );
00144 
00145                 $this->wrapIcon = array(
00146                         0 => '',
00147                         1 => '<img src="'.TYPO3_mainDir.'gfx/icon_note.gif" width="18" height="16" align="absmiddle" alt="" />',
00148                         2 => '<img src="'.TYPO3_mainDir.'gfx/icon_warning.gif" width="18" height="16" align="absmiddle" alt="" />',
00149                         3 => '<img src="'.TYPO3_mainDir.'gfx/icon_fatalerror.gif" width="18" height="16" align="absmiddle" alt="" />'
00150                 );
00151 
00152                 $this->starttime = 0;
00153                 $this->starttime = $this->mtime();
00154         }
00155 
00164         function push($tslabel, $value='')  {
00165                 array_push($this->tsStack[$this->tsStackPointer], $tslabel);
00166                 array_push($this->currentHashPointer, 'timetracker_'.$this->uniqueCounter++);
00167 
00168                 $this->tsStackLevel++;
00169                 $this->tsStackLevelMax[] = $this->tsStackLevel;
00170 
00171                         // setTSlog
00172                 $k = end($this->currentHashPointer);
00173                 $this->tsStackLog[$k] = array(
00174                         'level' => $this->tsStackLevel,
00175                         'tsStack' => $this->tsStack,
00176                         'value' => $value,
00177                         'starttime' => microtime(),
00178                         'stackPointer' => $this->tsStackPointer
00179                 );
00180         }
00181 
00189         function pull($content='')  {
00190                 $k = end($this->currentHashPointer);
00191                 $this->tsStackLog[$k]['endtime'] =  microtime();
00192                 $this->tsStackLog[$k]['content'] = $content;
00193 
00194                 $this->tsStackLevel--;
00195                 array_pop($this->tsStack[$this->tsStackPointer]);
00196                 array_pop($this->currentHashPointer);
00197         }
00198 
00207         function setTSlogMessage($content,$num=0)   {
00208                 end($this->currentHashPointer);
00209                 $k = current($this->currentHashPointer);
00210 
00211                 if (strlen($content)>30) {      // Enlarge the "details" column by adding a wide clear.gif
00212                         $placeholder = '<br /><img src="'.TYPO3_mainDir.'clear.gif" width="300" height="1" alt="" />';
00213                 }
00214                 $this->tsStackLog[$k]['message'][] = $this->wrapIcon[$num].$this->wrapError[$num][0].htmlspecialchars($content).$this->wrapError[$num][1].$placeholder;
00215         }
00216 
00224         function setTSselectQuery($query,$msg)  {
00225                 end($this->currentHashPointer);
00226                 $k = current($this->currentHashPointer);
00227 
00228                 $this->tsStackLog[$k]['selectQuery'][] = array('query'=>$query,'msg'=>$msg);
00229         }
00230 
00237         function incStackPointer()  {
00238                 $this->tsStackPointer++;
00239                 $this->tsStack[$this->tsStackPointer]=array();
00240         }
00241 
00248         function decStackPointer()  {
00249                 unset($this->tsStack[$this->tsStackPointer]);
00250                 $this->tsStackPointer--;
00251         }
00252 
00258         function mtime()    {
00259                 return $this->convertMicrotime(microtime())-$this->starttime;
00260         }
00261 
00268         function convertMicrotime($microtime)   {
00269                 $parts = explode(' ',$microtime);
00270                 return round(($parts[0]+$parts[1])*1000);
00271         }
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289         /*******************************************
00290         *
00291         * Printing the parsing time information (for Admin Panel)
00292         *
00293         *******************************************/
00294 
00301         function printTSlog() {
00302                         // Calculate times and keys for the tsStackLog
00303                 $preEndtime = 0;
00304                 foreach($this->tsStackLog as $uniqueId=>$data) {
00305                         $this->tsStackLog[$uniqueId]['endtime'] = $this->convertMicrotime($this->tsStackLog[$uniqueId]['endtime'])-$this->starttime;
00306                         $this->tsStackLog[$uniqueId]['starttime'] = $this->convertMicrotime($this->tsStackLog[$uniqueId]['starttime'])-$this->starttime;
00307                         $this->tsStackLog[$uniqueId]['deltatime'] = $this->tsStackLog[$uniqueId]['endtime']-$this->tsStackLog[$uniqueId]['starttime'];
00308                         $this->tsStackLog[$uniqueId]['key'] = implode($this->tsStackLog[$uniqueId]['stackPointer']?'.':'/', end($data['tsStack']));
00309                         $preEndtime = $this->tsStackLog[$uniqueId]['endtime'];
00310                 }
00311 
00312                         // Create hierarchical array of keys pointing to the stack
00313                 $arr = array();
00314                 reset($this->tsStackLog);
00315                 while(list($uniqueId,$data)=each($this->tsStackLog)) {
00316                         $this->createHierarchyArray($arr,$data['level'], $uniqueId);
00317                 }
00318                         // Parsing the registeret content and create icon-html for the tree
00319                 $this->tsStackLog[$arr['0.'][0]]['content'] = $this->fixContent($arr['0.']['0.'], $this->tsStackLog[$arr['0.'][0]]['content'], '', 0, $arr['0.'][0]);
00320 
00321                         // Displaying the tree:
00322                 reset($this->tsStackLog);
00323 
00324                 $outputArr = array();
00325                 $outputArr[] = $this->fw('TypoScript Key');
00326                 $outputArr[] = $this->fw('Value');
00327 
00328                 if ($this->printConf['allTime']) {
00329                         $outputArr[] = $this->fw('Time');
00330                         $outputArr[] = $this->fw('Own');
00331                         $outputArr[] = $this->fw('Sub');
00332                         $outputArr[] = $this->fw('Total');
00333                 } else {
00334                         $outputArr[] = $this->fw('Own');
00335                 }
00336 
00337                 $outputArr[] = $this->fw('Details');
00338 
00339                 $out = '';
00340                 foreach ($outputArr as $row) {
00341                         $out.= '
00342                                 <th style="text-align:center; background:#ABBBB4;"><strong>'.$row.'</strong></th>';
00343                 }
00344                 $out = '<tr>'.$out.'</tr>';
00345 
00346                 $flag_tree = $this->printConf['flag_tree'];
00347                 $flag_messages = $this->printConf['flag_messages'];
00348                 $flag_content = $this->printConf['flag_content'];
00349                 $flag_queries = $this->printConf['flag_queries'];
00350                 $keyLgd = $this->printConf['keyLgd'];
00351                 $factor = $this->printConf['factor'];
00352                 $col = $this->printConf['col'];
00353                 $highlight_col = $this->printConf['highlight_col'];
00354 
00355                 $c=0;
00356                 while(list($uniqueId,$data)=each($this->tsStackLog)) {
00357                         $bgColor = ' background-color:'.($c%2 ? t3lib_div::modifyHTMLColor($col,$factor,$factor,$factor) : $col).';';
00358                         if ($this->highlightLongerThan && intval($data['owntime']) > intval($this->highlightLongerThan)) {
00359                                 $bgColor = ' background-color:'.$highlight_col.';';
00360                         }
00361 
00362                         $item = '';
00363                         if (!$c) {      // If first...
00364                                 $data['icons'] = '';
00365                                 $data['key'] = 'Script Start';
00366                                 $data['value'] = '';
00367                         }
00368 
00369 
00370                                 // key label:
00371                         $keyLabel = '';
00372                         if (!$flag_tree && $data['stackPointer']) {
00373                                 $temp = array();
00374                                 reset($data['tsStack']);
00375                                 while(list($k,$v)=each($data['tsStack'])) {
00376                                         $temp[] = t3lib_div::fixed_lgd_pre(implode($v,$k?'.':'/'),$keyLgd);
00377                                 }
00378                                 array_pop($temp);
00379                                 $temp = array_reverse($temp);
00380                                 array_pop($temp);
00381                                 if (count($temp)) {
00382                                         $keyLabel = '<br /><span style="color:#999999;">'.implode($temp,'<br />').'</span>';
00383                                 }
00384                         }
00385                         if ($flag_tree) {
00386                                 $tmp = t3lib_div::trimExplode('.',$data['key'],1);
00387                                 $theLabel = end($tmp);
00388                         } else {
00389                                 $theLabel = $data['key'];
00390                         }
00391                         $theLabel = t3lib_div::fixed_lgd_pre($theLabel, $keyLgd);
00392                         $theLabel = $data['stackPointer'] ? '<span style="color:maroon;">'.$theLabel.'</span>' : $theLabel;
00393                         $keyLabel = $theLabel.$keyLabel;
00394                         $item.= '<td valign="top" style="text-align:left; white-space:nowrap; padding-left:2px;'.$bgColor.'">'.($flag_tree?$data['icons']:'').$this->fw($keyLabel).'</td>';
00395 
00396                                 // key value:
00397                         $keyValue = $data['value'];
00398                         $item.= '<td valign="top" style="text-align:left; white-space:nowrap;'.$bgColor.'">'.$this->fw(htmlspecialchars($keyValue)).'</td>';
00399 
00400                         if ($this->printConf['allTime']) {
00401                                 $item.= '<td valign="top" style="text-align:right; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['starttime']).'</td>';
00402                                 $item.= '<td valign="top" style="text-align:right; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['owntime']).'</td>';
00403                                 $item.= '<td valign="top" style="text-align:left; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['subtime'] ? '+'.$data['subtime'] : '').'</td>';
00404                                 $item.= '<td valign="top" style="text-align:left; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['subtime'] ? '='.$data['deltatime'] : '').'</td>';
00405                         } else {
00406                                 $item.= '<td valign="top" style="text-align:right; white-space:nowrap;'.$bgColor.'"> '.$this->fw($data['owntime']).'</td>';
00407                         }
00408 
00409 
00410                                 // messages:
00411                         $msgArr = array();
00412                         $msg = '';
00413                         if ($flag_messages && is_array($data['message'])) {
00414                                 reset($data['message']);
00415                                 while(list(,$v)=each($data['message'])) {
00416                                         $msgArr[] = nl2br($v);
00417                                 }
00418                         }
00419                         if ($flag_queries && is_array($data['selectQuery'])) {
00420                                 reset($data['selectQuery']);
00421                                 while(list(,$v)=each($data['selectQuery'])) {
00422                                         $res = $GLOBALS['TYPO3_DB']->sql_query('EXPLAIN '.$v['query']);
00423                                         $v['mysql_error'] = $GLOBALS['TYPO3_DB']->sql_error();
00424                                         if (!$GLOBALS['TYPO3_DB']->sql_error()) {
00425                                                 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00426                                                         $v['explain'][]=$row;
00427                                                 }
00428                                         }
00429                                         $msgArr[] = t3lib_div::view_array($v);
00430                                 }
00431                         }
00432                         if ($flag_content && strcmp($data['content'],'')) {
00433                                 $maxlen = 120;
00434                                 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...)
00435                                         foreach ($reg[1] as $key=>$match) {
00436                                                 $match = preg_replace('/(.{'.$maxlen.'})/', '$1 ', $match);
00437                                                 $data['content'] = str_replace($reg[0][$key], $match, $data['content']);
00438                                         }
00439                                 }
00440                                 $msgArr[] = '<span style="color:#000066;">'.nl2br($data['content']).'</span>';
00441                         }
00442                         if (count($msgArr)) {
00443                                 $msg = implode($msgArr,'<hr />');
00444                         }
00445                         $item.= '<td valign="top" style="text-align:left;'.$bgColor.'">'.$this->fw($msg).'</td>';
00446                         $out.= '<tr>'.$item.'</tr>';
00447                         $c++;
00448                 }
00449                 $out = '<table border="0" cellpadding="0" cellspacing="0" summary="">'.$out.'</table>';
00450                 return $out;
00451         }
00452 
00463         function fixContent(&$arr, $content, $depthData='', $first=0, $vKey='') {
00464                 $ac=0;
00465                 $c=0;
00466                         // First, find number of entries
00467                 reset($arr);
00468                 while(list($k,$v)=each($arr)) {
00469                         if (t3lib_div::testInt($k)) {
00470                                 $ac++;
00471                         }
00472                 }
00473                         // Traverse through entries
00474                 $subtime=0;
00475                 reset($arr);
00476                 while(list($k,$v)=each($arr)) {
00477                         if (t3lib_div::testInt($k)) {
00478                                 $c++;
00479 
00480                                 $deeper = is_array($arr[$k.'.']) ? 1 : 0;
00481                                 $PM = 'join';
00482                                 $LN = ($ac==$c)?'blank':'line';
00483                                 $BTM = ($ac==$c)?'bottom':'';
00484                                 $PM = is_array($arr[$k.'.']) ? ($deeper ? 'minus':'plus') : 'join';
00485                                 $this->tsStackLog[$v]['icons'] = $depthData.($first?'':'<img src="'.TYPO3_mainDir.'gfx/ol/'.$PM.$BTM.'.gif" width="18" height="16" align="top" border="0" alt="" />');
00486 
00487                                 if (strlen($this->tsStackLog[$v]['content'])) {
00488                                         $content = str_replace($this->tsStackLog[$v]['content'],$v, $content);
00489                                 }
00490                                 if (is_array($arr[$k.'.'])) {
00491                                         $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);
00492                                 } else {
00493                                         $this->tsStackLog[$v]['content'] = $this->fixCLen($this->tsStackLog[$v]['content'], $this->tsStackLog[$v]['value']);
00494                                         $this->tsStackLog[$v]['subtime'] = '';
00495                                         $this->tsStackLog[$v]['owntime'] = $this->tsStackLog[$v]['deltatime'];
00496                                 }
00497                                 $subtime+= $this->tsStackLog[$v]['deltatime'];
00498                         }
00499                 }
00500                         // Set content with special chars
00501                 if (isset($this->tsStackLog[$vKey])) {
00502                         $this->tsStackLog[$vKey]['subtime'] = $subtime;
00503                         $this->tsStackLog[$vKey]['owntime'] = $this->tsStackLog[$vKey]['deltatime']-$subtime;
00504                 }
00505                 $content=$this->fixCLen($content, $this->tsStackLog[$vKey]['value']);
00506 
00507                         // Traverse array again, this time substitute the unique hash with the red key
00508                 reset($arr);
00509                 while(list($k,$v)=each($arr)) {
00510                         if (t3lib_div::testInt($k)) {
00511                                 if (strlen($this->tsStackLog[$v]['content'])) {
00512                                         $content = str_replace($v, '<strong style="color:red;">['.$this->tsStackLog[$v]['key'].']</strong>', $content);
00513                                 }
00514                         }
00515                 }
00516                         // return the content
00517                 return $content;
00518         }
00519 
00527         function fixCLen($c,$v) {
00528                 $len = $v=='FILE'?$this->printConf['contentLength_FILE']:$this->printConf['contentLength'];
00529                 if (strlen($c)>$len) {
00530                         $c = '<span style="color:green;">'.htmlspecialchars(t3lib_div::fixed_lgd($c,$len)).'</span>';
00531                 } else {
00532                         $c = htmlspecialchars($c);
00533                 }
00534                 return $c;
00535         }
00536 
00543         function fw($str) {
00544                 return '<span style="font-family:Verdana,Arial,Helvetica,sans-serif; font-size:0.6em; color:black; vertical-align:top;">'.$str.'&nbsp;</span>';
00545         }
00546 
00557         function createHierarchyArray(&$arr,$pointer,$uniqueId) {
00558                 if (!is_array($arr)) {
00559                         $arr = array();
00560                 }
00561                 if ($pointer>0) {
00562                         end($arr);
00563                         $k = key($arr);
00564                         $this->createHierarchyArray($arr[intval($k).'.'],$pointer-1,$uniqueId);
00565                 } else {
00566                         $arr[] = $uniqueId;
00567                 }
00568         }
00569 
00579         function debug_typo3PrintError($header,$text,$js,$baseUrl='') {
00580                 if ($js) {
00581                         echo "alert('".t3lib_div::slashJS($header."\n".$text)."');";
00582                 } else {
00583                         echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
00584                                         "http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
00585                                 <?xml version="1.0" encoding="utf-8"?>
00586                                 <html>
00587                                         <head>
00588                                                 '.($baseUrl ? '<base href="'.htmlspecialchars($baseUrl).'" />' : '').'
00589                                                 <title>Error!</title>
00590                                                 <style type="text/css"><!--/*--><![CDATA[/*><!--*/
00591                                                         body { font-family:Verdana,Arial,Helvetica,sans-serif; font-size: 90%; text-align: center; background-color: #ffffff; }
00592                                                         h1 { font-size: 1.2em; margin: 0 0 1em 0; }
00593                                                         p { margin: 0; text-align: left; }
00594                                                         img { border: 0; margin: 10px 0; }
00595                                                         div.center div { margin: 0 auto; }
00596                                                         .errorBox { width: 400px; padding: 0.5em; border: 1px solid black; background-color: #F4F0E8; }
00597                                                 /*]]>*/--></style>
00598                                         </head>
00599                                         <body>
00600                                                 <div class="center">
00601                                                         <img src="'.TYPO3_mainDir.'gfx/typo3logo.gif" width="123" height="34" alt="" />
00602                                                         <div class="errorBox">
00603                                                                 <h1>'.$header.'</h1>
00604                                                                 <p>'.$text.'</p>
00605                                                         </div>
00606                                                 </div>
00607                                         </body>
00608                                 </html>';
00609                 }
00610         }
00611 }
00612 
00613 // XCLASSing is not possible for this class
00614 
00615 ?>

This documentation has been generated automatically from TYPO3 source code using Doxygen and is provided as is by Cast Iron Coding as a courtesy to other TYPO3 developers and users. Please consider Cast Iron Coding — a full-service web development agency in Portland, Oregon specializing in TYPO3 extension development — for all of your TYPO3 development and consulting needs!