ezdebug.php

00001 <?php
00002 //
00003 // Definition of eZDebug class
00004 //
00005 // Created on: <12-Feb-2002 11:00:54 bf>
00006 //
00007 // Copyright (C) 1999-2003 Exponential. All rights reserved.
00008 //
00009 // This source file is part of the Exponential (tm) Open Source Content
00010 // Management System.
00011 //
00012 // This file may be distributed and/or modified under the terms of the
00013 // "GNU General Public License" version 2 as published by the Free
00014 // Software Foundation and appearing in the file LICENSE.GPL included in
00015 // the packaging of this file.
00016 //
00017 // Licencees holding valid "Exponential professional licences" may use this
00018 // file in accordance with the "Exponential professional licence" Agreement
00019 // provided with the Software.
00020 //
00021 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
00022 // THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00023 // PURPOSE.
00024 //
00025 // The "Exponential professional licence" is available at
00026 // http://ez.no/products/licences/professional/. For pricing of this licence
00027 // please contact us via e-mail to licence@ez.no. Further contact
00028 // information is available at http://ez.no/home/contact/.
00029 //
00030 // The "GNU General Public License" (GPL) is available at
00031 // http://www.gnu.org/copyleft/gpl.html.
00032 //
00033 // Contact licence@ez.no if any conditions of this licencing isn't clear to
00034 // you.
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 ) // @ error-control operator is used
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         // save the buffer contents
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         // fill the buffer with the old values
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 //                     print( "@unlink( $logRotateName )<br/>" );
00622                 }
00623                 else
00624                 {
00625                     $newLogRotateName = $fileName . '.' . ($i + 1);
00626                     @rename( $logRotateName, $newLogRotateName );
00627 //                     print( "@rename( $logRotateName, $newLogRotateName )<br/>" );
00628                 }
00629             }
00630         }
00631         if ( @file_exists( $fileName ) )
00632         {
00633             $newLogRotateName = $fileName . '.' . 1;
00634             @rename( $fileName, $newLogRotateName );
00635 //             print( "@rename( $fileName, $newLogRotateName )<br/>" );
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         // Make sure errors are handled by PHP when we read, including our own debug output.
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 ) ? "&nbsp;" : 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>&nbsp;Accumulator</th><th>&nbsp;Elapsed</th><th>&nbsp;Percent</th><th>&nbsp;Count</th><th>&nbsp;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 ?>
 

Exponential