00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00083 include_once( "lib/ezutils/classes/ezsys.php" );
00084
00085 define( "EZ_LEVEL_NOTICE", 1 );
00086 define( "EZ_LEVEL_WARNING", 2 );
00087 define( "EZ_LEVEL_ERROR", 3 );
00088 define( "EZ_LEVEL_TIMING_POINT", 4 );
00089 define( "EZ_LEVEL_DEBUG", 5 );
00090
00091 define( "EZ_SHOW_NOTICE", 1 << (EZ_LEVEL_NOTICE - 1) );
00092 define( "EZ_SHOW_WARNING", 1 << (EZ_LEVEL_WARNING - 1) );
00093 define( "EZ_SHOW_ERROR", 1 << (EZ_LEVEL_ERROR - 1) );
00094 define( "EZ_SHOW_TIMING_POINT", 1 << (EZ_LEVEL_TIMING_POINT - 1) );
00095 define( "EZ_SHOW_DEBUG", 1 << (EZ_LEVEL_DEBUG - 1) );
00096 define( "EZ_SHOW_ALL", EZ_SHOW_NOTICE | EZ_SHOW_WARNING | EZ_SHOW_ERROR | EZ_SHOW_TIMING_POINT | EZ_SHOW_DEBUG );
00097
00098 define( "EZ_HANDLE_NONE", 0 );
00099 define( "EZ_HANDLE_FROM_PHP", 1 );
00100 define( "EZ_HANDLE_TO_PHP", 2 );
00101
00102 define( "EZ_OUTPUT_MESSAGE_SCREEN", 1 );
00103 define( "EZ_OUTPUT_MESSAGE_STORE", 2 );
00104
00105 define( "EZ_DEBUG_MAX_LOGFILE_SIZE", 200*1024 );
00106 define( "EZ_DEBUG_MAX_LOGROTATE_FILES", 3 );
00107
eZDebug
00109 {
eZDebug( )
00114 {
00115 $this->TmpTimePoints = array( EZ_LEVEL_NOTICE => array(),
00116 EZ_LEVEL_WARNING => array(),
00117 EZ_LEVEL_ERROR => array(),
00118 EZ_LEVEL_DEBUG => array() );
00119
00120 $this->OutputFormat = array( EZ_LEVEL_NOTICE => array( "color" => "green",
00121 "name" => "Notice" ),
00122 EZ_LEVEL_WARNING => array( "color" => "orange",
00123 "name" => "Warning" ),
00124 EZ_LEVEL_ERROR => array( "color" => "red",
00125 "name" => "Error" ),
00126 EZ_LEVEL_DEBUG => array( "color" => "brown",
00127 "name" => "Debug" ),
00128 EZ_LEVEL_TIMING_POINT => array( "color" => "blue",
00129 "name" => "Timing" ) );
00130 $this->LogFiles = array( EZ_LEVEL_NOTICE => array( "var/log/",
00131 "notice.log" ),
00132 EZ_LEVEL_WARNING => array( "var/log/",
00133 "warning.log" ),
00134 EZ_LEVEL_ERROR => array( "var/log/",
00135 "error.log" ),
00136 EZ_LEVEL_DEBUG => array( "var/log/",
00137 "debug.log" ) );
00138 $this->MessageTypes = array( EZ_LEVEL_NOTICE,
00139 EZ_LEVEL_WARNING,
00140 EZ_LEVEL_ERROR,
00141 EZ_LEVEL_TIMING_POINT,
00142 EZ_LEVEL_DEBUG );
00143 $this->MessageNames = array( EZ_LEVEL_NOTICE => 'Notice',
00144 EZ_LEVEL_WARNING => 'Warning',
00145 EZ_LEVEL_ERROR => 'Error',
00146 EZ_LEVEL_TIMING_POINT => 'TimingPoint',
00147 EZ_LEVEL_DEBUG => 'Debug' );
00148 $this->LogFileEnabled = array( EZ_LEVEL_NOTICE => true,
00149 EZ_LEVEL_WARNING => true,
00150 EZ_LEVEL_ERROR => true,
00151 EZ_LEVEL_TIMING_POINT => true,
00152 EZ_LEVEL_DEBUG => true );
00153 $this->ShowTypes = EZ_SHOW_ALL;
00154 $this->HandleType = EZ_HANDLE_NONE;
00155 $this->OldHandler = false;
00156 $this->UseCSS = false;
00157 $this->MessageOutput = EZ_OUTPUT_MESSAGE_STORE;
00158 $this->eZDebug::timeToFloat( microtime() );
00159 $this->TimeAccumulatorList = array();
00160 $this->TimeAccumulatorGroupList = array();
00161 $this->OverrideList = array();
00162 }
00163
00164 function reset()
00165 {
00166 $this->DebugStrings = array();
00167 $this->TmpTimePoints = array( EZ_LEVEL_NOTICE => array(),
00168 EZ_LEVEL_WARNING => array(),
00169 EZ_LEVEL_ERROR => array(),
00170 EZ_LEVEL_DEBUG => array() );
00171 $this->TimeAccumulatorList = array();
00172 $this->TimeAccumulatorGroupList = array();
00173 }
00174
messageName( $messageType )
00179 {
00180 if ( !isset( $this ) or
00181 get_class( $this ) != "ezdebug" )
00182 $this =& eZDebug::instance();
00183 return $this->MessageNames[$messageType];
00184 }
00185
instance( )
00191 {
00192 $impl =& $GLOBALS["eZDebugGlobalInstance"];
00193
00194 $class =& get_class( $impl );
00195 if ( $class != "ezdebug" )
00196 {
00197 $impl = new eZDebug();
00198 }
00199 return $impl;
00200 }
00201
showMessage( $type )
00207 {
00208 $debug =& eZDebug::instance();
00209 return $debug->ShowTypes & $type;
00210 }
00211
setHandleType( $type )
00219 {
00220 if ( !isset( $this ) or
00221 get_class( $this ) != "ezdebug" )
00222 $this =& eZDebug::instance();
00223 if ( $type != EZ_HANDLE_TO_PHP and
00224 $type != EZ_HANDLE_FROM_PHP )
00225 $type = EZ_HANDLE_NONE;
00226 if ( $type == $this->HandleType )
00227 return $this->HandleType;
00228
00229 if ( $this->HandleType == EZ_HANDLE_FROM_PHP )
00230 restore_error_handler();
00231 switch ( $type )
00232 {
00233 case EZ_HANDLE_FROM_PHP:
00234 {
00235 set_error_handler( "eZDebugErrorHandler" );
00236 } break;
00237
00238 case EZ_HANDLE_TO_PHP:
00239 {
00240 restore_error_handler();
00241 } break;
00242
00243 case EZ_HANDLE_NONE:
00244 {
00245 }
00246 }
00247 $oldHandleType = $this->HandleType;
00248 $this->HandleType = $type;
00249 return $oldHandleType;
00250 }
00251
showTypes( $types = false )
00260 {
00261 if ( !isset( $this ) or
00262 get_class( $this ) != "ezdebug" )
00263 $this =& eZDebug::instance();
00264 if ( $types === false )
00265 return $this->ShowTypes;
00266 $old_types = $this->ShowTypes;
00267 $this->ShowTypes = $types;
00268 return $old_types;
00269 }
00270
errorHandler( $errno, $errstr, $errfile, $errline )
00276 {
00277 if ( error_reporting() == 0 )
00278 return;
00279 if ( !eZDebug::isDebugEnabled() )
00280 return;
00281 $str = "$errstr in $errfile on line $errline";
00282 $errnames =& $GLOBALS["eZDebugPHPErrorNames"];
00283 if ( !is_array( $errnames ) )
00284 {
00285 $errnames = array( E_ERROR => "E_ERROR",
00286 E_PARSE => "E_PARSE",
00287 E_CORE_ERROR => "E_CORE_ERROR",
00288 E_COMPILE_ERROR => "E_COMPILE_ERROR",
00289 E_USER_ERROR => "E_USER_ERROR",
00290 E_WARNING => "E_WARNING",
00291 E_CORE_WARNING => "E_CORE_WARNING",
00292 E_COMPILE_WARNING => "E_COMPILE_WARNING",
00293 E_USER_WARNING => "E_USER_WARNING",
00294 E_NOTICE => "E_NOTICE",
00295 E_USER_NOTICE => "E_USER_NOTICE" );
00296 }
00297 $errname = "unknown";
00298 if ( isset( $errnames[$errno] ) )
00299 $errname = $errnames[$errno];
00300 switch ( $errno )
00301 {
00302 case E_ERROR:
00303 case E_PARSE:
00304 case E_CORE_ERROR:
00305 case E_COMPILE_ERROR:
00306 case E_USER_ERROR:
00307 {
00308 eZDebug::writeError( $str, "PHP" );
00309 } break;
00310
00311 case E_WARNING:
00312 case E_CORE_WARNING:
00313 case E_COMPILE_WARNING:
00314 case E_USER_WARNING:
00315 case E_NOTICE:
00316 {
00317 eZDebug::writeWarning( $str, "PHP" );
00318 } break;
00319
00320 case E_USER_NOTICE:
00321 {
00322 eZDebug::writeNotice( $str, "PHP" );
00323 } break;
00324 }
00325 }
00326
writeNotice( $string, $label="" )
00332 {
00333 if ( !eZDebug::isDebugEnabled() )
00334 return;
00335 if ( !eZDebug::showMessage( EZ_SHOW_NOTICE ) )
00336 return;
00337 if ( is_object( $string ) || is_array( $string ) )
00338 $string =& eZDebug::dumpVariable( $string );
00339
00340 $debug =& eZDebug::instance();
00341 if ( $debug->HandleType == EZ_HANDLE_TO_PHP )
00342 trigger_error( $string, E_USER_NOTICE );
00343 else
00344 $debug->write( $string, EZ_LEVEL_NOTICE, $label );
00345 }
00346
writeWarning( $string, $label="" )
00352 {
00353 if ( !eZDebug::isDebugEnabled() )
00354 return;
00355 if ( !eZDebug::showMessage( EZ_SHOW_WARNING ) )
00356 return;
00357 if ( is_object( $string ) || is_array( $string ) )
00358 $string =& eZDebug::dumpVariable( $string );
00359
00360 $debug =& eZDebug::instance();
00361 if ( $debug->HandleType == EZ_HANDLE_TO_PHP )
00362 trigger_error( $string, E_USER_WARNING );
00363 else
00364 $debug->write( $string, EZ_LEVEL_WARNING, $label );
00365 }
00366
writeError( $string, $label="" )
00372 {
00373 if ( !eZDebug::isDebugEnabled() )
00374 return;
00375 if ( !eZDebug::showMessage( EZ_SHOW_ERROR ) )
00376 return;
00377 if ( is_object( $string ) || is_array( $string ) )
00378 $string =& eZDebug::dumpVariable( $string );
00379
00380 $debug =& eZDebug::instance();
00381 if ( $debug->HandleType == EZ_HANDLE_TO_PHP )
00382 trigger_error( $string, E_USER_ERROR );
00383 else
00384 $debug->write( $string, EZ_LEVEL_ERROR, $label );
00385 }
00386
writeDebug( $string, $label="" )
00392 {
00393 if ( !eZDebug::isDebugEnabled() )
00394 return;
00395 if ( !eZDebug::showMessage( EZ_SHOW_ERROR ) )
00396 return;
00397 if ( is_object( $string ) || is_array( $string ) )
00398 $string =& eZDebug::dumpVariable( $string );
00399
00400 $debug =& eZDebug::instance();
00401 if ( $debug->HandleType == EZ_HANDLE_TO_PHP )
00402 trigger_error( $string, E_USER_NOTICE );
00403 else
00404 $debug->write( $string, EZ_LEVEL_DEBUG, $label );
00405 }
00406
dumpVariable( $var )
00413 {
00414
00415 $variableContents = "";
00416 $buffer =& ob_get_contents();
00417 if ( strlen( $buffer ) > 0 )
00418 ob_end_clean();
00419
00420 ob_start();
00421 var_dump( $var );
00422 $variableContents .= ob_get_contents();
00423 ob_end_clean();
00424
00425
00426 ob_start();
00427 print( $buffer );
00428
00429 return $variableContents;
00430 }
00431
setUseExternalCSS( $use )
00437 {
00438 if ( !isset( $this ) or
00439 get_class( $this ) != "ezdebug" )
00440 $this =& eZDebug::instance();
00441 $this->UseCSS = $use;
00442 }
00443
setMessageOutput( $output )
00449 {
00450 if ( !isset( $this ) or
00451 get_class( $this ) != "ezdebug" )
00452 $this =& eZDebug::instance();
00453 $this->MessageOutput = $output;
00454 }
00455
00458 function setStoreLog( $store )
00459 {
00460 if ( !isset( $this ) or
00461 get_class( $this ) != "ezdebug" )
00462 $this =& eZDebug::instance();
00463 $this->StoreLog = $store;
00464 }
00465
addTimingPoint( $description = "" )
00470 {
00471 if ( !eZDebug::isDebugEnabled() )
00472 return;
00473 if ( !eZDebug::showMessage( EZ_SHOW_TIMING_POINT ) )
00474 return;
00475 $debug =& eZDebug::instance();
00476
00477 $time = microtime();
00478 $tp = array( "Time" => $time,
00479 "Description" => $description );
00480 $debug->TimePoints[] = $tp;
00481 $desc = "Timing Point: $description";
00482 foreach ( array( EZ_LEVEL_NOTICE, EZ_LEVEL_WARNING, EZ_LEVEL_ERROR, EZ_LEVEL_DEBUG ) as $lvl )
00483 {
00484 if ( isset( $debug->TmpTimePoints[$lvl] ) )
00485 $debug->TmpTimePoints[$lvl] = array();
00486 if ( $debug->TmpTimePoints[$lvl] === false and
00487 $debug->isLogFileEnabled( $lvl ) )
00488 {
00489 $files =& $debug->logFiles();
00490 $file = $files[$lvl];
00491 $debug->writeFile( $file, $desc, $lvl );
00492 }
00493 else
00494 array_push( $debug->TmpTimePoints[$lvl], $tp );
00495 }
00496 $debug->write( $description, EZ_LEVEL_TIMING_POINT );
00497 }
00498
write( $string, $verbosityLevel = EZ_LEVEL_NOTICE, $label="" )
00503 {
00504 if ( !eZDebug::isDebugEnabled() )
00505 return;
00506 switch ( $verbosityLevel )
00507 {
00508 case EZ_LEVEL_NOTICE:
00509 case EZ_LEVEL_WARNING:
00510 case EZ_LEVEL_ERROR:
00511 case EZ_LEVEL_DEBUG:
00512 case EZ_LEVEL_TIMING_POINT:
00513 break;
00514
00515 default:
00516 $verbosityLevel = EZ_LEVEL_ERROR;
00517 break;
00518 }
00519 if ( $this->MessageOutput & EZ_OUTPUT_MESSAGE_SCREEN )
00520 {
00521 print( "$verbosityLevel: $string ($label)\n" );
00522 }
00523 $files =& $this->logFiles();
00524 $fileName = false;
00525 if ( isset( $files[$verbosityLevel] ) )
00526 $fileName = $files[$verbosityLevel];
00527 if ( $this->MessageOutput & EZ_OUTPUT_MESSAGE_STORE )
00528 {
00529 $this->DebugStrings[] = array( "Level" => $verbosityLevel,
00530 "IP" => eZSys::serverVariable( 'REMOTE_ADDR', true ),
00531 "Time" => time(),
00532 "Label" => $label,
00533 "String" => $string );
00534
00535 if ( $fileName !== false )
00536 {
00537 $timePoints = $this->TmpTimePoints[$verbosityLevel];
00538 if ( is_array( $timePoints ) )
00539 {
00540 if ( $this->isLogFileEnabled( $verbosityLevel ) )
00541 {
00542 foreach ( $timePoints as $tp )
00543 {
00544 $desc = "Timing Point: " . $tp["Description"];
00545 if ( $this->isLogFileEnabled( $verbosityLevel ) )
00546 {
00547 $this->writeFile( $fileName, $desc, $verbosityLevel );
00548 }
00549 }
00550 }
00551 $this->TmpTimePoints[$verbosityLevel] = false;
00552 }
00553 if ( $this->isLogFileEnabled( $verbosityLevel ) )
00554 {
00555 $this->writeFile( $fileName, $string, $verbosityLevel );
00556 }
00557 }
00558 }
00559 }
00560
maxLogSize()
00566 {
00567 $maxLogSize =& $GLOBALS['eZDebugMaxLogSize'];
00568 if ( isset( $maxLogSize ) )
00569 return $maxLogSize;
00570 return EZ_DEBUG_MAX_LOGFILE_SIZE;
00571 }
00572
setMaxLogSize( $size )
00578 {
00579 $GLOBALS['eZDebugMaxLogSize'] = $size;
00580 }
00581
maxLogrotateFiles()
00587 {
00588 $maxLogrotateFiles =& $GLOBALS['eZDebugMaxLogrotateFiles'];
00589 if ( isset( $maxLogrotateFiles ) )
00590 return $maxLogrotateFiles;
00591 return EZ_DEBUG_MAX_LOGROTATE_FILES;
00592 }
00593
setLogrotateFiles( $files )
00599 {
00600 $GLOBALS['eZDebugMaxLogrotateFiles'] = $filse;
00601 }
00602
rotateLog( $fileName )
00611 {
00612 $eZDebug::maxLogrotateFiles();
00613 for ( $i = $maxLogrotateFiles; $i > 0; --$i )
00614 {
00615 $logRotateName = $fileName . '.' . $i;
00616 if ( @file_exists( $logRotateName ) )
00617 {
00618 if ( $i == $maxLogrotateFiles )
00619 {
00620 @unlink( $logRotateName );
00621
00622 }
00623 else
00624 {
00625 $newLogRotateName = $fileName . '.' . ($i + 1);
00626 @rename( $logRotateName, $newLogRotateName );
00627
00628 }
00629 }
00630 }
00631 if ( @file_exists( $fileName ) )
00632 {
00633 $newLogRotateName = $fileName . '.' . 1;
00634 @rename( $fileName, $newLogRotateName );
00635
00636 return true;
00637 }
00638 return false;
00639 }
00640
writeFile( &$logFileData, &$string, $verbosityLevel )
00646 {
00647 if ( !eZDebug::isDebugEnabled() )
00648 return;
00649 if ( !$this->isLogFileEnabled( $verbosityLevel ) )
00650 return;
00651 $oldHandleType = eZDebug::setHandleType( EZ_HANDLE_TO_PHP );
00652 $logDir = $logFileData[0];
00653 $logName = $logFileData[1];
00654 $fileName = $logDir . $logName;
00655 if ( !file_exists( $logDir ) )
00656 {
00657 include_once( 'lib/ezutils/classes/ezdir.php' );
00658 eZDir::mkdir( $logDir, 0775, true );
00659 }
00660 $oldumask = @umask( 0 );
00661 $fileExisted = @file_exists( $fileName );
00662 if ( $fileExisted and
00663 filesize( $fileName ) > eZDebug::maxLogSize() )
00664 {
00665 if ( eZDebug::rotateLog( $fileName ) )
00666 $fileExisted = false;
00667 }
00668 $logFile = @fopen( $fileName, "a" );
00669 if ( $logFile )
00670 {
00671 $time = strftime( "%b %d %Y %H:%M:%S", strtotime( "now" ) );
00672 $notice = "[ " . $time . " ] [" . eZSys::serverVariable( 'REMOTE_ADDR', true ) . "] " . $string . "\n";
00673 @fwrite( $logFile, $notice );
00674 @fclose( $logFile );
00675 if ( !$fileExisted )
00676 @chmod( $fileName, 0664 );
00677 @umask( $oldumask );
00678 }
00679 else
00680 {
00681 @umask( $oldumask );
00682 $logEnabled = $this->isLogFileEnabled( $verbosityLevel );
00683 $this->setLogFileEnabled( false, $verbosityLevel );
00684 if ( $verbosityLevel != EZ_LEVEL_ERROR or
00685 $logEnabled )
00686 {
00687 eZDebug::setHandleType( $oldHandleType );
00688 $this->writeError( "Cannot open log file '$fileName' for writing\n" .
00689 "The web server must be allowed to modify the file.\n" .
00690 "File logging for '$fileName' is disabled." , 'eZDebug::writeFile' );
00691 }
00692 }
00693 eZDebug::setHandleType( $oldHandleType );
00694 }
00695
setLogFileEnabled( $enabled, $types = false )
00702 {
00703 if ( !isset( $this ) or
00704 get_class( $this ) != "ezdebug" )
00705 $this =& eZDebug::instance();
00706 if ( $types === false )
00707 $types =& $this->messageTypes();
00708 if ( !is_array( $types ) )
00709 $types = array( $types );
00710 foreach ( $types as $type )
00711 {
00712 $this->LogFileEnabled[$type] = $enabled;
00713 }
00714 }
00715
isLogFileEnabled( $type )
00720 {
00721 return $this->LogFileEnabled[$type];
00722 }
00723
messageTypes()
00728 {
00729 return $this->MessageTypes;
00730 }
00731
logFiles()
00737 {
00738 return $this->LogFiles;
00739 }
00740
isDebugEnabled()
00747 {
00748 $debugEnabled =& $GLOBALS['eZDebugEnabled'];
00749 if ( isset( $debugEnabled ) )
00750 return $debugEnabled;
00751
00752 return false;
00753 }
00754
updateSettings( $settings )
00764 {
00765
00766 $oldHandleType = eZDebug::setHandleType( EZ_HANDLE_TO_PHP );
00767
00768 $debugEnabled =& $GLOBALS['eZDebugEnabled'];
00769
00770 $debugEnabled = $settings['debug-enabled'];
00771 if ( $settings['debug-enabled'] and
00772 $settings['debug-by-ip'] )
00773 {
00774 $ipAddress = eZSys::serverVariable( 'REMOTE_ADDR' );
00775 $debugEnabled = in_array( $ipAddress, $settings['debug-ip-list'] );
00776 }
00777 eZDebug::setHandleType( $oldHandleType );
00778 }
00779
printReport( $newWindow = false, $as_html = true, $returnReport = false )
00785 {
00786 if ( !eZDebug::isDebugEnabled() )
00787 return null;
00788
00789 $debug =& eZDebug::instance();
00790 $report =& $debug->printReportInternal( $as_html );
00791
00792
00793 if ( $newWindow == true )
00794 {
00795 $wwwDir = eZSys::wwwDir();
00796 print( "
00797 <SCRIPT LANGUAGE='JavaScript'>
00798 <!-- hide this script from old browsers
00799
00800 function showDebug( fileName, title )
00801 {
00802 debugWindow = window.open( '$wwwDir/var/cache/debug.html', 'ezdebug', 'width=500,height=550,status,scrollbars,resizable,screenX=0,screenY=20,left=20,top=40');
00803 debugWindow.document.close();
00804 debugWindow.location.reload();
00805 }
00806
00807 showDebug();
00808
00809 ezdebug.reload();
00810
00811
00812 // done hiding from old browsers -->
00813 </SCRIPT>
00814 " );
00815 $header = "<html><head><title>eZ debug</title></head><body>";
00816 $footer = "</body></html>";
00817 $varDirectory = eZSys::varDirectory();
00818 $fp = fopen( eZDir::path( array( $varDirectory, 'cache', 'debug.html' ) ), "w+" );
00819
00820 fwrite( $fp, $header );
00821 fwrite( $fp, $report );
00822 fwrite( $fp, $footer );
00823 fclose( $fp );
00824 }
00825 else
00826 {
00827 if ( !$returnReport )
00828 print( $report );
00829 else
00830 return $report;
00831 }
00832 return null;
00833 }
00834
timeToFloat( $mtime )
00840 {
00841 $tTime = explode( " ", $mtime );
00842 ereg( "0\.([0-9]+)", "" . $tTime[0], $t1 );
00843 $time = $tTime[1] . "." . $t1[1];
00844 return $time;
00845 }
00846
setScriptStart( $mtime = false )
00853 {
00854 if ( $mtime == false )
00855 $mtime = microtime();
00856 $time = eZDebug::timeToFloat( microtime() );
00857 $debug =& eZDebug::instance();
00858 $debug->ScriptStart = $time;
00859 }
00860
createAccumulatorGroup( $key, $name = false )
00866 {
00867 if ( !eZDebug::isDebugEnabled() )
00868 return;
00869 if ( $name == '' or
00870 $name === false )
00871 $name = $key;
00872 $debug =& eZDebug::instance();
00873 if ( !array_key_exists( $key, $debug->TimeAccumulatorList ) )
00874 $debug->TimeAccumulatorList[$key] = array( 'name' => $name, 'time' => 0, 'count' => 0, 'is_group' => true, 'in_group' => false );
00875 if ( !array_key_exists( $key, $debug->TimeAccumulatorGroupList ) )
00876 $debug->TimeAccumulatorGroupList[$key] = array();
00877 }
00878
createAccumulator( $key, $inGroup = false, $name = false )
00885 {
00886 if ( !eZDebug::isDebugEnabled() )
00887 return;
00888 if ( $name == '' or
00889 $name === false )
00890 $name = $key;
00891 $debug =& eZDebug::instance();
00892 $isGroup = false;
00893 if ( array_key_exists( $key, $debug->TimeAccumulatorList ) and
00894 array_key_exists( $key, $debug->TimeAccumulatorGroupList ) )
00895 $isGroup = true;
00896 $debug->TimeAccumulatorList[$key] = array( 'name' => $name, 'time' => 0, 'count' => 0, 'is_group' => $isGroup, 'in_group' => $inGroup );
00897 if ( $inGroup !== false )
00898 {
00899 $groupKeys = array();
00900 if ( array_key_exists( $inGroup, $debug->TimeAccumulatorGroupList ) )
00901 $groupKeys = $debug->TimeAccumulatorGroupList[$inGroup];
00902 $debug->TimeAccumulatorGroupList[$inGroup] = array_unique( array_merge( $groupKeys, array( $key ) ) );
00903 if ( array_key_exists( $inGroup, $debug->TimeAccumulatorList ) )
00904 $debug->TimeAccumulatorList[$inGroup]['is_group'] = true;
00905 }
00906 }
00907
accumulatorStart( $key, $inGroup = false, $name = false )
00913 {
00914 if ( !eZDebug::isDebugEnabled() )
00915 return;
00916 $debug =& eZDebug::instance();
00917 if ( ! array_key_exists( $key, $debug->TimeAccumulatorList ) )
00918 {
00919 $debug->createAccumulator( $key, $inGroup, $name );
00920 }
00921
00922 $accumulator =& $debug->TimeAccumulatorList[$key];
00923 $accumulator['temp_time'] = $debug->timeToFloat( microtime() );
00924 }
00925
accumulatorStop( $key )
00930 {
00931 if ( !eZDebug::isDebugEnabled() )
00932 return;
00933 $debug =& eZDebug::instance();
00934 $stopTime = $debug->timeToFloat( microtime() );
00935 if ( ! array_key_exists( $key, $debug->TimeAccumulatorList ) )
00936 {
00937 eZDebug::accumulatorStop' );
00938 return;
00939 }
00940 $accumulator =& $debug->TimeAccumulatorList[$key];
00941 $diffTime = $stopTime - $accumulator['temp_time'];
00942 $accumulator['time'] = $accumulator['time'] + $diffTime;
00943 ++$accumulator['count'];
00944 }
00945
00946
printReportInternal( $as_html = true )
00952 {
00953 $endTime = microtime();
00954 $returnText = "";
00955 if ( $as_html )
00956 {
00957 $returnText .= "<table style='border: 1px dashed black;' bgcolor=\"#fefefe\">";
00958 $returnText .= "<tr><th><h1>eZ debug</h1></th></tr>";
00959 $returnText .= "<tr><td>";
00960
00961 if ( !$this->UseCSS )
00962 {
00963 $returnText .= "<STYLE TYPE='text/css'>
00964 <!--
00965 td.debugheader
00966 \{
00967 background-color : #eeeeee;
00968 border-top : 1px solid #444488;
00969 border-bottom : 1px solid #444488;
00970 font-size : 65%;
00971 font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
00972 \}
00973
00974 td.timingpoint1
00975 \{
00976 background-color : #ffffff;
00977 border-top : 1px solid #444488;
00978 font-size : 65%;
00979 font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
00980 \}
00981
00982 td.timingpoint2
00983 \{
00984 background-color : #eeeeee;
00985 border-top : 1px solid #444488;
00986 font-size : 65%;
00987 font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
00988 \}
00989
00990 -->
00991 </STYLE>";
00992 }
00993 $returnText .= "<table style='border: 1px light gray;' cellspacing='0'>";
00994 }
00995
00996 foreach ( $this->DebugStrings as $debug )
00997 {
00998 $time = strftime ("%b %d %Y %H:%M:%S", strtotime( "now" ) );
00999
01000 $outputData = $this->OutputFormat[$debug["Level"]];
01001 if ( is_array( $outputData ) )
01002 {
01003 $color = $outputData["color"];
01004 $name = $outputData["name"];
01005 $label = $debug["Label"];
01006 if ( $as_html )
01007 {
01008 $label = htmlspecialchars( $label );
01009 $returnText .= "<tr><td class='debugheader' valign='top'><b><font color=\"$color\">$name:</font> $label</b></td>
01010 <td class='debugheader' valign='top'>$time</td></tr>
01011 <tr><td colspan='2'><pre>" . htmlspecialchars( $debug["String"] ) . "</pre></td></tr>";
01012 }
01013 else
01014 {
01015 $returnText .= "$name: ($label)\n" . $debug["String"] . "\n\n";
01016 }
01017 }
01018 }
01019 if ( $as_html )
01020 {
01021 $returnText .= "</table>";
01022
01023 $returnText .= "<h2>Timing points:</h2>";
01024 $returnText .= "<table style='border: 1px dashed black;' cellspacing='0'><tr><th>Checkpoint</th><th>Elapsed</th><th>Rel. Elapsed</th></tr>";
01025 }
01026 $startTime = false;
01027 $elapsed = 0.00;
01028 $relElapsed = 0.00;
01029 for ( $i = 0; $i < count( $this->TimePoints ); ++$i )
01030 {
01031 $point = $this->TimePoints[$i];
01032 $nextPoint = false;
01033 if ( isset( $this->TimePoints[$i + 1] ) )
01034 $nextPoint = $this->TimePoints[$i + 1];
01035 $time = $this->timeToFloat( $point["Time"] );
01036 $nextTime = false;
01037 if ( $nextPoint !== false )
01038 $nextTime = $this->timeToFloat( $nextPoint["Time"] );
01039 if ( $startTime === false )
01040 $startTime = $time;
01041 $elapsed = $time - $startTime;
01042 $relElapsed = $nextTime - $time;
01043
01044 if ( $i % 2 == 0 )
01045 $class = "timingpoint1";
01046 else
01047 $class = "timingpoint2";
01048
01049 if ( $as_html )
01050 {
01051 $returnText .= "<tr><td class='$class'>" . $point["Description"] . "</td><td class='$class'>" .
01052 number_format( ( $elapsed ), $this->TimingAccuracy ) . " sec</td><td class='$class'>".
01053 ( empty( $nextPoint ) ? " " : number_format( ( $relElapsed ), $this->TimingAccuracy ) . " sec" ) . "</td>"
01054 . "</tr>";
01055 }
01056 else
01057 {
01058 $returnText .= $point["Description"] .
01059 number_format( ( $elapsed ), $this->TimingAccuracy ) . " sec".
01060 ( empty( $nextPoint ) ? "" : number_format( ( $relElapsed ), $this->TimingAccuracy ) . " sec" ) . "\n";
01061 }
01062 }
01063
01064 if ( count( $this->TimePoints ) > 0 )
01065 {
01066 $tTime = explode( " ", $endTime );
01067 ereg( "0\.([0-9]+)", "" . $tTime[0], $t1 );
01068 $endTime = $tTime[1] . "." . $t1[1];
01069
01070 $totalElapsed = $endTime - $startTime;
01071
01072 if ( $as_html )
01073 {
01074 $returnText .= "<tr><td><b>Total runtime:</b></td><td><b>" .
01075 number_format( ( $totalElapsed ), $this->TimingAccuracy ) . " sec</b></td><td></td></tr>";
01076 }
01077 else
01078 {
01079 $returnText .= "Total runtime: " .
01080 number_format( ( $totalElapsed ), $this->TimingAccuracy ) . " sec\n";
01081 }
01082 }
01083 else
01084 {
01085 if ( $as_html )
01086 $returnText .= "<tr><td> No timing points defined</td><td>";
01087 else
01088 $returnText .= "No timing points defined\n";
01089 }
01090 if ( $as_html )
01091 {
01092 $returnText .= "</table>";
01093
01094
01095 }
01096
01097 if ( $as_html )
01098 {
01099 $returnText .= "<h2>Time accumulators:</h2>";
01100 $returnText .= "<table style='border: 1px dashed black;' cellspacing='0'><tr><th> Accumulator</th><th> Elapsed</th><th> Percent</th><th> Count</th><th> Average</th></tr>";
01101 $i = 0;
01102 }
01103
01104 $scriptEndTime = eZDebug::timeToFloat( microtime() );
01105 $totalElapsed = $scriptEndTime - $this->ScriptStart;
01106 $timeList = $this->TimeAccumulatorList;
01107 $groups = $this->TimeAccumulatorGroupList;
01108 $groupList = array();
01109 foreach ( $groups as $groupKey => $keyList )
01110 {
01111 if ( count( $keyList ) == 0 and
01112 !array_key_exists( $groupKey, $timeList ) )
01113 continue;
01114 $groupList[$groupKey] = array( 'name' => $groupKey );
01115 if ( array_key_exists( $groupKey, $timeList ) )
01116 {
01117 if ( $timeList[$groupKey]['time'] != 0 )
01118 $groupList[$groupKey]['time_data'] = $timeList[$groupKey];
01119 $groupList[$groupKey]['name'] = $timeList[$groupKey]['name'];
01120 unset( $timeList[$groupKey] );
01121 }
01122 $groupChildren = array();
01123 foreach ( $keyList as $timeKey )
01124 {
01125 if ( array_key_exists( $timeKey, $timeList ) )
01126 {
01127 $groupChildren[] = $timeList[$timeKey];
01128 unset( $timeList[$timeKey] );
01129 }
01130 }
01131 $groupList[$groupKey]['children'] = $groupChildren;
01132 }
01133 if ( count( $timeList ) > 0 )
01134 {
01135 $groupList['general'] = array( 'name' => 'General',
01136 'children' => $timeList );
01137 }
01138
01139 $j = 0;
01140 foreach ( $groupList as $group )
01141 {
01142 if ( $j % 2 == 0 )
01143 $class = "timingpoint1";
01144 else
01145 $class = "timingpoint2";
01146 ++$j;
01147 $groupName = $group['name'];
01148 $groupChildren = $group['children'];
01149 if ( count( $groupChildren ) == 0 and
01150 !array_key_exists( 'time_data', $group ) )
01151 continue;
01152 if ( $as_html )
01153 $returnText .= "<tr><td class='$class'><b>$groupName</b></td>";
01154 else
01155 $returnText .= "Group $groupName: ";
01156 if ( array_key_exists( 'time_data', $group ) )
01157 {
01158 $groupData = $group['time_data'];
01159 $groupElapsed = number_format( ( $groupData['time'] ), $this->TimingAccuracy );
01160 $groupPercent = number_format( ( $groupData['time'] * 100.0 ) / $totalElapsed, 1 );
01161 $groupCount = $groupData['count'];
01162 $groupAverage = number_format( ( $groupData['time'] / $groupData['count'] ), $this->TimingAccuracy );
01163 if ( $as_html )
01164 {
01165 $returnText .= ( "<td class=\"$class\">$groupElapsed sec</td>".
01166 "<td class=\"$class\" align=\"right\"> $groupPercent%</td>".
01167 "<td class=\"$class\" align=\"right\"> $groupCount</td>".
01168 "<td class=\"$class\" align=\"right\"> $groupAverage sec</td>" );
01169 }
01170 else
01171 {
01172 $returnText .= "$groupElapsed sec ($groupPercent%), $groupAverage avg sec ($groupCount)";
01173 }
01174 }
01175 else if ( $as_html )
01176 {
01177 $returnText .= ( "<td class=\"$class\"></td>".
01178 "<td class=\"$class\"></td>".
01179 "<td class=\"$class\"></td>".
01180 "<td class=\"$class\"></td>" );
01181 }
01182 if ( $as_html )
01183 $returnText .= "</tr>";
01184 else
01185 $returnText .= "\n";
01186
01187 $i = 0;
01188 foreach ( $groupChildren as $child )
01189 {
01190 $childName = $child['name'];
01191 $childElapsed = number_format( ( $child['time'] ), $this->TimingAccuracy );
01192 $childPercent = number_format( ( $child['time'] * 100.0 ) / $totalElapsed, $this->PercentAccuracy );
01193 $childCount = $child['count'];
01194 $childAverage = 0.0;
01195 if ( $childCount > 0 )
01196 {
01197 $childAverage = $child['time'] / $childCount;
01198 }
01199 $childAverage = number_format( $childAverage, $this->PercentAccuracy );
01200
01201 if ( $as_html )
01202 {
01203 if ( $i % 2 == 0 )
01204 $class = "timingpoint1";
01205 else
01206 $class = "timingpoint2";
01207 ++$i;
01208
01209 $returnText .= ( "<tr>" .
01210 "<td class=\"$class\">$childName</td>" .
01211 "<td class=\"$class\">$childElapsed sec</td>" .
01212 "<td class=\"$class\" align=\"right\">$childPercent%</td>" .
01213 "<td class=\"$class\" align=\"right\">$childCount</td>" .
01214 "<td class=\"$class\" align=\"right\">$childAverage sec</td>" .
01215 "</tr>" );
01216 }
01217 else
01218 {
01219 $returnText .= "$childName: $childElapsed sec ($childPercent%), $childAverage avg sec ($childCount)";
01220 }
01221 }
01222 }
01223 if ( $as_html )
01224 {
01225 $returnText .= "<tr><td><b>Total script time:</b></td><td><b>" . number_format( ( $totalElapsed ), $this->TimingAccuracy ) . " sec</b></td><td></td></tr>";
01226 }
01227 else
01228 {
01229 $returnText .= "Total script time: " . number_format( ( $totalElapsed ), $this->TimingAccuracy ) . " sec\n";
01230 }
01231 if ( $as_html )
01232 {
01233 $returnText .= "</table>";
01234 $returnText .= "</td></tr></table>";
01235 }
01236
01237 return $returnText;
01238 }
01239
01240
01241
DebugStrings = array();
01245
TimePoints = array();
01248
TmpTimePoints;
01251
TimeAccumulatorList = array();
01254
ShowTypes;
01257
HandleType;
01260
OutputFormat;
01263
LogFiles;
01266
TimingAccuracy = 4;
01269
PercentAccuracy = 4;
01272
UseCSS;
01275
MessageOutput;
01278
MessageTypes;
01281
LogFileEnabled;
01284
ScriptStart;
01287
OverrideList;
01290 }
01291
01297 function eZDebugErrorHandler( $errno, $errstr, $errfile, $errline )
01298 {
01299 if ( $GLOBALS['eZDebugRecursionFlag'] )
01300 {
01301 print( "Fatal debug error: A recursion in debug error handler was detected, aborting debug message.<br/>" );
01302 $GLOBALS['eZDebugRecursionFlag'] = false;
01303 return;
01304 }
01305 $GLOBALS['eZDebugRecursionFlag'] = true;
01306 $debug =& eZDebug::instance();
01307 $debug->errorHandler( $errno, $errstr, $errfile, $errline );
01308 $GLOBALS['eZDebugRecursionFlag'] = false;
01309 }
01310 $GLOBALS['eZDebugRecursionFlag'] = false;
01311
01312 ?>