[ Index ]
 

Code source de eZ Publish 3.9.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/ezutils/classes/ -> ezdebug.php (source)

   1  <?php
   2  //
   3  // Definition of eZDebug class
   4  //
   5  // Created on: <12-Feb-2002 11:00:54 bf>
   6  //
   7  // SOFTWARE NAME: eZ publish
   8  // SOFTWARE RELEASE: 3.9.0
   9  // BUILD VERSION: 17785
  10  // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS
  11  // SOFTWARE LICENSE: GNU General Public License v2.0
  12  // NOTICE: >
  13  //   This program is free software; you can redistribute it and/or
  14  //   modify it under the terms of version 2.0  of the GNU General
  15  //   Public License as published by the Free Software Foundation.
  16  //
  17  //   This program is distributed in the hope that it will be useful,
  18  //   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19  //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20  //   GNU General Public License for more details.
  21  //
  22  //   You should have received a copy of version 2.0 of the GNU General
  23  //   Public License along with this program; if not, write to the Free
  24  //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25  //   MA 02110-1301, USA.
  26  //
  27  //
  28  
  29  /*! \defgroup eZUtils Utility classes */
  30  
  31  /*!
  32    \class eZDebug ezdebug.php
  33    \ingroup eZUtils
  34    \brief Advanced debug/log system
  35  
  36    The eZ debug library is used to handle debug information. It
  37    can display information on screen and/or write it to log files.
  38  
  39    You can enable on-screen debug information for specific IP addresses.
  40  
  41    Timing points can be placed in the code to time the different sections of code.
  42  
  43    Each debug message can be turned on/off by using the showTypes() function.
  44  
  45    PHP error messages can also be shown using setHandleType().
  46  
  47    \code
  48    include_once( "lib/ezutils/classes/ezdebug.php" );
  49  
  50    // write a temporary debug message
  51    eZDebug::writeDebug( "Test" );
  52  
  53    // write a notice
  54    eZDebug::writeNotice( "Image found" );
  55  
  56    // write a warning
  57    eZDebug::writeWarning( "Image not found, using default" );
  58  
  59    // write an error
  60    eZDebug::writeError( "Object not found, bailing.." );
  61  
  62    // add a timing points
  63    eZDebug::addTimingPoint( "Module Found" );
  64  
  65    //.... code
  66  
  67    eZDebug::addTimingPoint( "Module loading" );
  68  
  69    // print the results on screen.
  70    eZDebug::printReport();
  71  
  72    \endcode
  73  */
  74  
  75  include_once ( "lib/ezutils/classes/ezsys.php" );
  76  
  77  define( "EZ_LEVEL_NOTICE", 1 );
  78  define( "EZ_LEVEL_WARNING", 2 );
  79  define( "EZ_LEVEL_ERROR", 3 );
  80  define( "EZ_LEVEL_TIMING_POINT", 4 );
  81  define( "EZ_LEVEL_DEBUG", 5 );
  82  
  83  define( "EZ_SHOW_NOTICE", 1 << (EZ_LEVEL_NOTICE - 1) );
  84  define( "EZ_SHOW_WARNING", 1 << (EZ_LEVEL_WARNING - 1) );
  85  define( "EZ_SHOW_ERROR", 1 << (EZ_LEVEL_ERROR - 1) );
  86  define( "EZ_SHOW_TIMING_POINT", 1 << (EZ_LEVEL_TIMING_POINT - 1) );
  87  define( "EZ_SHOW_DEBUG", 1 << (EZ_LEVEL_DEBUG - 1) );
  88  define( "EZ_SHOW_ALL", EZ_SHOW_NOTICE | EZ_SHOW_WARNING | EZ_SHOW_ERROR | EZ_SHOW_TIMING_POINT | EZ_SHOW_DEBUG );
  89  
  90  define( "EZ_HANDLE_NONE", 0 );
  91  define( "EZ_HANDLE_FROM_PHP", 1 );
  92  define( "EZ_HANDLE_TO_PHP", 2 );
  93  
  94  define( "EZ_OUTPUT_MESSAGE_SCREEN", 1 );
  95  define( "EZ_OUTPUT_MESSAGE_STORE", 2 );
  96  
  97  define( "EZ_DEBUG_MAX_LOGFILE_SIZE", 200*1024 );
  98  define( "EZ_DEBUG_MAX_LOGROTATE_FILES", 3 );
  99  
 100  define( "EZ_DEBUG_XDEBUG_SIGNATURE", '--XDEBUG--' );
 101  
 102  class eZDebug
 103  {
 104      /*!
 105        Creates a new debug object.
 106      */
 107      function eZDebug( )
 108      {
 109          $this->TmpTimePoints = array( EZ_LEVEL_NOTICE => array(),
 110                                        EZ_LEVEL_WARNING => array(),
 111                                        EZ_LEVEL_ERROR => array(),
 112                                        EZ_LEVEL_DEBUG => array() );
 113  
 114          $this->OutputFormat = array( EZ_LEVEL_NOTICE => array( "color" => "green",
 115                                                                 'style' => 'notice',
 116                                                                 'xhtml-identifier' => 'ezdebug-first-notice',
 117                                                                 "name" => "Notice" ),
 118                                       EZ_LEVEL_WARNING => array( "color" => "orange",
 119                                                                  'style' => 'warning',
 120                                                                  'xhtml-identifier' => 'ezdebug-first-warning',
 121                                                                  "name" => "Warning" ),
 122                                       EZ_LEVEL_ERROR => array( "color" => "red",
 123                                                                'style' => 'error',
 124                                                                'xhtml-identifier' => 'ezdebug-first-error',
 125                                                                "name" => "Error" ),
 126                                       EZ_LEVEL_DEBUG => array( "color" => "brown",
 127                                                                'style' => 'debug',
 128                                                                'xhtml-identifier' => 'ezdebug-first-debug',
 129                                                                "name" => "Debug" ),
 130                                       EZ_LEVEL_TIMING_POINT => array( "color" => "blue",
 131                                                                       'style' => 'timing',
 132                                                                       'xhtml-identifier' => 'ezdebug-first-timing-point',
 133                                                                       "name" => "Timing" ) );
 134          $this->LogFiles = array( EZ_LEVEL_NOTICE => array( "var/log/",
 135                                                             "notice.log" ),
 136                                   EZ_LEVEL_WARNING => array( "var/log/",
 137                                                              "warning.log" ),
 138                                   EZ_LEVEL_ERROR => array( "var/log/",
 139                                                            "error.log" ),
 140                                   EZ_LEVEL_DEBUG => array( "var/log/",
 141                                                            "debug.log" ) );
 142          $this->MessageTypes = array( EZ_LEVEL_NOTICE,
 143                                       EZ_LEVEL_WARNING,
 144                                       EZ_LEVEL_ERROR,
 145                                       EZ_LEVEL_TIMING_POINT,
 146                                       EZ_LEVEL_DEBUG );
 147          $this->MessageNames = array( EZ_LEVEL_NOTICE => 'Notice',
 148                                       EZ_LEVEL_WARNING => 'Warning',
 149                                       EZ_LEVEL_ERROR => 'Error',
 150                                       EZ_LEVEL_TIMING_POINT => 'TimingPoint',
 151                                       EZ_LEVEL_DEBUG => 'Debug' );
 152          $this->LogFileEnabled = array( EZ_LEVEL_NOTICE => true,
 153                                         EZ_LEVEL_WARNING => true,
 154                                         EZ_LEVEL_ERROR => true,
 155                                         EZ_LEVEL_TIMING_POINT => true,
 156                                         EZ_LEVEL_DEBUG => true );
 157          $this->AlwaysLog = array( EZ_LEVEL_NOTICE => false,
 158                                    EZ_LEVEL_WARNING => false,
 159                                    EZ_LEVEL_ERROR => true, // Error is on by default, due to its importance
 160                                    EZ_LEVEL_TIMING_POINT => false,
 161                                    EZ_LEVEL_DEBUG => false );
 162          $this->GlobalLogFileEnabled = true;
 163          if ( isset( $GLOBALS['eZDebugLogFileEnabled'] ) )
 164          {
 165              $this->GlobalLogFileEnabled = $GLOBALS['eZDebugLogFileEnabled'];
 166          }
 167          $this->ShowTypes = EZ_SHOW_ALL;
 168          $this->HandleType = EZ_HANDLE_NONE;
 169          $this->OldHandler = false;
 170          $this->UseCSS = false;
 171          $this->MessageOutput = EZ_OUTPUT_MESSAGE_STORE;
 172          $this->ScriptStart = eZDebug::timeToFloat( microtime() );
 173          $this->TimeAccumulatorList = array();
 174          $this->TimeAccumulatorGroupList = array();
 175          $this->OverrideList = array();
 176          $this->topReportsList = array();
 177          $this->bottomReportsList = array();
 178      }
 179  
 180      function reset()
 181      {
 182          $this->DebugStrings = array();
 183          $this->TmpTimePoints = array( EZ_LEVEL_NOTICE => array(),
 184                                        EZ_LEVEL_WARNING => array(),
 185                                        EZ_LEVEL_ERROR => array(),
 186                                        EZ_LEVEL_DEBUG => array() );
 187          $this->TimeAccumulatorList = array();
 188          $this->TimeAccumulatorGroupList = array();
 189          $this->topReportsList = array();
 190          $this->bottomReportsList = array();
 191      }
 192  
 193      /*!
 194       \return the name of the message type.
 195      */
 196      function messageName( $messageType )
 197      {
 198          if ( isset( $this ) and
 199               get_class( $this ) == "ezdebug" )
 200              $instance =& $this;
 201          else
 202              $instance =& eZDebug::instance();
 203          return $instance->MessageNames[$messageType];
 204      }
 205  
 206      /*!
 207        Will return the current eZDebug object. If no object exists one will
 208        be created.
 209      */
 210      function &instance( )
 211      {
 212          $impl =& $GLOBALS["eZDebugGlobalInstance"];
 213  
 214          $class = get_class( $impl );
 215          if ( $class != "ezdebug" )
 216          {
 217              $impl = new eZDebug();
 218          }
 219          return $impl;
 220      }
 221  
 222      /*!
 223       \static
 224       Returns true if the message type $type can be shown.
 225      */
 226      function showMessage( $type )
 227      {
 228          $debug =& eZDebug::instance();
 229          return $debug->ShowTypes & $type;
 230      }
 231  
 232      /*!
 233       \return \c true if the debug level \a $level should always log to file.
 234      */
 235      function alwaysLogMessage( $level )
 236      {
 237          if ( isset( $this ) and
 238               get_class( $this ) == "ezdebug" )
 239              $instance =& $this;
 240          else
 241              $instance =& eZDebug::instance();
 242  
 243          // If there is a global setting for this get the value
 244          // and unset it globally
 245          if ( isset( $GLOBALS['eZDebugAlwaysLog'] ) )
 246          {
 247              $instance->AlwaysLog = $GLOBALS['eZDebugAlwaysLog'] + $instance->AlwaysLog;
 248              unset( $GLOBALS['eZDebugAlwaysLog'] );
 249          }
 250  
 251          if ( !isset( $instance->AlwaysLog[$level] ) )
 252              return false;
 253          return $instance->AlwaysLog[$level];
 254      }
 255  
 256      /*!
 257       Determines how PHP errors are handled. If $type is EZ_HANDLE_TO_PHP all error messages
 258       is sent to PHP using trigger_error(), if $type is EZ_HANDLE_FROM_PHP all error messages
 259       from PHP is fetched using a custom error handler and output as a usual eZDebug message.
 260       If $type is EZ_HANDLE_NONE there is no error exchange between PHP and eZDebug.
 261      */
 262      function setHandleType( $type )
 263      {
 264          if ( isset( $this ) and
 265               get_class( $this ) == "ezdebug" )
 266              $instance =& $this;
 267          else
 268              $instance =& eZDebug::instance();
 269          if ( $type != EZ_HANDLE_TO_PHP and
 270               $type != EZ_HANDLE_FROM_PHP )
 271              $type = EZ_HANDLE_NONE;
 272          if ( extension_loaded( 'xdebug' ) and
 273               $type == EZ_HANDLE_FROM_PHP )
 274              $type = EZ_HANDLE_NONE;
 275          if ( $type == $instance->HandleType )
 276              return $instance->HandleType;
 277  
 278          if ( $instance->HandleType == EZ_HANDLE_FROM_PHP )
 279              restore_error_handler();
 280          switch ( $type )
 281          {
 282              case EZ_HANDLE_FROM_PHP:
 283              {
 284                  set_error_handler( "eZDebugErrorHandler" );
 285              } break;
 286  
 287              case EZ_HANDLE_TO_PHP:
 288              {
 289                  restore_error_handler();
 290              } break;
 291  
 292              case EZ_HANDLE_NONE:
 293              {
 294              }
 295          }
 296          $oldHandleType = $instance->HandleType;
 297          $instance->HandleType = $type;
 298          return $oldHandleType;
 299      }
 300  
 301      /*!
 302       \static
 303       Sets types to be shown to $types and returns the old show types.
 304       If $types is not supplied the current value is returned and no change is done.
 305       $types is one or more of EZ_SHOW_NOTICE, EZ_SHOW_WARNING, EZ_SHOW_ERROR, EZ_SHOW_TIMING_POINT
 306       or'ed together.
 307      */
 308      function showTypes( $types = false )
 309      {
 310          if ( isset( $this ) and
 311               get_class( $this ) == "ezdebug" )
 312              $instance =& $this;
 313          else
 314              $instance =& eZDebug::instance();
 315          if ( $types === false )
 316              return $instance->ShowTypes;
 317          $old_types = $instance->ShowTypes;
 318          $instance->ShowTypes = $types;
 319          return $old_types;
 320      }
 321  
 322      /*!
 323       Handles PHP errors, creates notice, warning and error messages for
 324       the various PHP error types.
 325      */
 326      function errorHandler( $errno, $errstr, $errfile, $errline )
 327      {
 328          if ( error_reporting() == 0 ) // @ error-control operator is used
 329              return;
 330          if ( !eZDebug::isDebugEnabled() )
 331              return;
 332          $str = "$errstr in $errfile on line $errline";
 333          $errnames =& $GLOBALS["eZDebugPHPErrorNames"];
 334          if ( !is_array( $errnames ) )
 335          {
 336              $errnames = array( E_ERROR => "E_ERROR",
 337                                 E_PARSE => "E_PARSE",
 338                                 E_CORE_ERROR => "E_CORE_ERROR",
 339                                 E_COMPILE_ERROR => "E_COMPILE_ERROR",
 340                                 E_USER_ERROR => "E_USER_ERROR",
 341                                 E_WARNING => "E_WARNING",
 342                                 E_CORE_WARNING => "E_CORE_WARNING",
 343                                 E_COMPILE_WARNING => "E_COMPILE_WARNING",
 344                                 E_USER_WARNING => "E_USER_WARNING",
 345                                 E_NOTICE => "E_NOTICE",
 346                                 E_USER_NOTICE => "E_USER_NOTICE" );
 347          }
 348          $errname = "unknown";
 349          if ( isset( $errnames[$errno] ) )
 350              $errname = $errnames[$errno];
 351          switch ( $errno )
 352          {
 353              case E_ERROR:
 354              case E_PARSE:
 355              case E_CORE_ERROR:
 356              case E_COMPILE_ERROR:
 357              case E_USER_ERROR:
 358              {
 359                  eZDebug::writeError( $str, "PHP" );
 360              } break;
 361  
 362              case E_WARNING:
 363              case E_CORE_WARNING:
 364              case E_COMPILE_WARNING:
 365              case E_USER_WARNING:
 366              case E_NOTICE:
 367              {
 368                  eZDebug::writeWarning( $str, "PHP" );
 369              } break;
 370  
 371              case E_USER_NOTICE:
 372              {
 373                  eZDebug::writeNotice( $str, "PHP" );
 374              } break;
 375          }
 376      }
 377  
 378      /*!
 379        \static
 380        Writes a debug notice.
 381  
 382        The global variable \c 'eZDebugNotice' will be set to \c true if the notice is added.
 383        \param $label This label will be associated with the notice, e.g. to say where the notice came from.
 384        \param $backgroundClass A string defining the class to use in the HTML debug output.
 385      */
 386      function writeNotice( $string, $label = "", $backgroundClass = "" )
 387      {
 388          $alwaysLog = eZDebug::alwaysLogMessage( EZ_LEVEL_NOTICE );
 389          $enabled = eZDebug::isDebugEnabled();
 390          if ( !$alwaysLog and !$enabled )
 391              return;
 392  
 393          $show = eZDebug::showMessage( EZ_SHOW_NOTICE );
 394          if ( !$alwaysLog and !$show )
 395              return;
 396  
 397          if ( is_object( $string ) || is_array( $string ) )
 398               $string = eZDebug::dumpVariable( $string );
 399  
 400          $GLOBALS['eZDebugNotice'] = true;
 401          if ( !isset( $GLOBALS['eZDebugNoticeCount'] ) )
 402              $GLOBALS['eZDebugNoticeCount'] = 0;
 403          ++$GLOBALS['eZDebugNoticeCount'];
 404  
 405          $debug =& eZDebug::instance();
 406          if ( $debug->HandleType == EZ_HANDLE_TO_PHP )
 407          {
 408              // If we get here only because of $alwaysLog we should not trigger a PHP error
 409              if ( $enabled and $show )
 410              {
 411                  if ( $label )
 412                      $string = "$label: $string";
 413                  trigger_error( $string, E_USER_NOTICE );
 414              }
 415          }
 416          else
 417          {
 418              $debug->write( $string, EZ_LEVEL_NOTICE, $label, $backgroundClass, $alwaysLog );
 419          }
 420      }
 421  
 422      /*!
 423        \static
 424        Writes a debug warning.
 425  
 426        The global variable \c 'eZDebugWarning' will be set to \c true if the notice is added.
 427        \param $label This label will be associated with the notice, e.g. to say where the notice came from.
 428      */
 429      function writeWarning( $string, $label = "", $backgroundClass = "" )
 430      {
 431          $alwaysLog = eZDebug::alwaysLogMessage( EZ_LEVEL_WARNING );
 432          $enabled = eZDebug::isDebugEnabled();
 433          if ( !$alwaysLog and !$enabled )
 434              return;
 435  
 436          $show = eZDebug::showMessage( EZ_SHOW_WARNING );
 437          if ( !$alwaysLog and !$show )
 438              return;
 439  
 440          if ( is_object( $string ) || is_array( $string ) )
 441              $string = eZDebug::dumpVariable( $string );
 442  
 443          $GLOBALS['eZDebugWarning'] = true;
 444          if ( !isset( $GLOBALS['eZDebugWarningCount'] ) )
 445              $GLOBALS['eZDebugWarningCount'] = 0;
 446          ++$GLOBALS['eZDebugWarningCount'];
 447  
 448          $debug =& eZDebug::instance();
 449          if ( $debug->HandleType == EZ_HANDLE_TO_PHP )
 450          {
 451              // If we get here only because of $alwaysLog we should not trigger a PHP error
 452              if ( $enabled and $show )
 453              {
 454                  if ( $label )
 455                      $string = "$label: $string";
 456                  trigger_error( $string, E_USER_WARNING );
 457              }
 458          }
 459          else
 460          {
 461              $debug->write( $string, EZ_LEVEL_WARNING, $label, $backgroundClass, $alwaysLog );
 462          }
 463      }
 464  
 465      /*!
 466        \static
 467        Writes a debug error.
 468  
 469        The global variable \c 'eZDebugError' will be set to \c true if the notice is added.
 470        \param $label This label will be associated with the notice, e.g. to say where the notice came from.
 471      */
 472      function writeError( $string, $label = "", $backgroundClass = "" )
 473      {
 474          $alwaysLog = eZDebug::alwaysLogMessage( EZ_LEVEL_ERROR );
 475          $enabled = eZDebug::isDebugEnabled();
 476          if ( !$alwaysLog and !$enabled )
 477              return;
 478  
 479          $show = eZDebug::showMessage( EZ_SHOW_ERROR );
 480          if ( !$alwaysLog and !$show )
 481              return;
 482  
 483          if ( is_object( $string ) || is_array( $string ) )
 484              $string = eZDebug::dumpVariable( $string );
 485  
 486          $GLOBALS['eZDebugError'] = true;
 487          if ( !isset( $GLOBALS['eZDebugErrorCount'] ) )
 488              $GLOBALS['eZDebugErrorCount'] = 0;
 489          ++$GLOBALS['eZDebugErrorCount'];
 490  
 491          $debug =& eZDebug::instance();
 492          if ( $debug->HandleType == EZ_HANDLE_TO_PHP )
 493          {
 494              // If we get here only because of $alwaysLog we should not trigger a PHP error
 495              if ( $enabled and $show )
 496              {
 497                  if ( $label )
 498                      $string = "$label: $string";
 499                  trigger_error( $string, E_USER_ERROR );
 500              }
 501          }
 502          else
 503          {
 504              $debug->write( $string, EZ_LEVEL_ERROR, $label, $backgroundClass, $alwaysLog );
 505          }
 506      }
 507  
 508      /*!
 509        \static
 510        Writes a debug message.
 511  
 512        The global variable \c 'eZDebugDebug' will be set to \c true if the notice is added.
 513        \param $label This label will be associated with the notice, e.g. to say where the notice came from.
 514      */
 515      function writeDebug( $string, $label = "", $backgroundClass = "" )
 516      {
 517          $alwaysLog = eZDebug::alwaysLogMessage( EZ_LEVEL_DEBUG );
 518          $enabled = eZDebug::isDebugEnabled();
 519          if ( !$alwaysLog and !$enabled )
 520              return;
 521  
 522          $show = eZDebug::showMessage( EZ_SHOW_DEBUG );
 523          if ( !$alwaysLog and !$show )
 524              return;
 525  
 526          if ( is_object( $string ) || is_array( $string ) )
 527              $string = eZDebug::dumpVariable( $string );
 528  
 529          $GLOBALS['eZDebugDebug'] = true;
 530          if ( !isset( $GLOBALS['eZDebugDebugCount'] ) )
 531              $GLOBALS['eZDebugDebugCount'] = 0;
 532          ++$GLOBALS['eZDebugDebugCount'];
 533  
 534          $debug =& eZDebug::instance();
 535          if ( $debug->HandleType == EZ_HANDLE_TO_PHP )
 536          {
 537              // If we get here only because of $alwaysLog we should not trigger a PHP error
 538              if ( $enabled and $show )
 539              {
 540                  if ( $label )
 541                      $string = "$label: $string";
 542                  trigger_error( $string, E_USER_NOTICE );
 543              }
 544          }
 545          else
 546          {
 547              $debug->write( $string, EZ_LEVEL_DEBUG, $label, $backgroundClass, $alwaysLog );
 548          }
 549      }
 550  
 551      /*!
 552        \static
 553        \private
 554        Dumps the variables contents using the var_dump function
 555      */
 556      function dumpVariable( $var )
 557      {
 558          // If we have var_export (PHP >= 4.2.0) we use the instead
 559          // provides better output, doesn't require output buffering
 560          // and doesn't get mangled by Xdebug
 561  
 562          // dl: we should always use 'var_dump' since 'var_export' is
 563          // unable to handle recursion properly.
 564          //if ( function_exists( 'var_export' ) )
 565          //    return var_export( $var, true );
 566  
 567          ob_start();
 568          var_dump( $var );
 569          $variableContents = '';
 570          if ( extension_loaded( 'xdebug' ) )
 571             $variableContents = EZ_DEBUG_XDEBUG_SIGNATURE;
 572          $variableContents .= ob_get_contents();
 573          ob_end_clean();
 574          return $variableContents;
 575      }
 576  
 577      /*!
 578       Enables/disables the use of external CSS. If false a <style> tag is output
 579       before the debug list. Default is to use internal css.
 580      */
 581      function setUseExternalCSS( $use )
 582      {
 583          if ( isset( $this ) and
 584               get_class( $this ) == "ezdebug" )
 585              $instance =& $this;
 586          else
 587              $instance =& eZDebug::instance();
 588          $instance->UseCSS = $use;
 589      }
 590  
 591      /*!
 592       Determines the way messages are output, the \a $output parameter
 593       is EZ_OUTPUT_MESSAGE_SCREEN and EZ_OUTPUT_MESSAGE_STORE ored together.
 594      */
 595      function setMessageOutput( $output )
 596      {
 597          if ( isset( $this ) and
 598               get_class( $this ) == "ezdebug" )
 599              $instance =& $this;
 600          else
 601              $instance =& eZDebug::instance();
 602          $instance->MessageOutput = $output;
 603      }
 604  
 605      /*!
 606      */
 607      function setStoreLog( $store )
 608      {
 609          if ( isset( $this ) and
 610               get_class( $this ) == "ezdebug" )
 611              $instance =& $this;
 612          else
 613              $instance =& eZDebug::instance();
 614          $instance->StoreLog = $store;
 615      }
 616  
 617      /*!
 618        Adds a new timing point for the benchmark report.
 619      */
 620      function addTimingPoint( $description = "" )
 621      {
 622          if ( !eZDebug::isDebugEnabled() )
 623              return;
 624          if ( !eZDebug::showMessage( EZ_SHOW_TIMING_POINT ) )
 625              return;
 626          $debug =& eZDebug::instance();
 627  
 628          $time = microtime();
 629          $usedMemory = 0;
 630          if ( function_exists( "memory_get_usage" ) )
 631              $usedMemory = memory_get_usage();
 632          $tp = array( "Time" => $time,
 633                       "Description" => $description,
 634                       "MemoryUsage" => $usedMemory );
 635          $debug->TimePoints[] = $tp;
 636          $desc = "Timing Point: $description";
 637          foreach ( array( EZ_LEVEL_NOTICE, EZ_LEVEL_WARNING, EZ_LEVEL_ERROR, EZ_LEVEL_DEBUG ) as $lvl )
 638          {
 639              if ( isset( $debug->TmpTimePoints[$lvl] ) )
 640                  $debug->TmpTimePoints[$lvl] = array();
 641              if ( $debug->TmpTimePoints[$lvl] === false and
 642                   $debug->isLogFileEnabled( $lvl ) )
 643              {
 644                  $files =& $debug->logFiles();
 645                  $file = $files[$lvl];
 646                  $debug->writeFile( $file, $desc, $lvl );
 647              }
 648              else
 649                  array_push( $debug->TmpTimePoints[$lvl],  $tp );
 650          }
 651          $debug->write( $description, EZ_LEVEL_TIMING_POINT );
 652      }
 653  
 654      /*!
 655        \private
 656        Writes a debug log message.
 657      */
 658      function write( $string, $verbosityLevel = EZ_LEVEL_NOTICE, $label = "", $backgroundClass = "", $alwaysLog = false )
 659      {
 660          $enabled = eZDebug::isDebugEnabled();
 661          if ( !$alwaysLog and !$enabled )
 662              return;
 663          switch ( $verbosityLevel )
 664          {
 665              case EZ_LEVEL_NOTICE:
 666              case EZ_LEVEL_WARNING:
 667              case EZ_LEVEL_ERROR:
 668              case EZ_LEVEL_DEBUG:
 669              case EZ_LEVEL_TIMING_POINT:
 670                  break;
 671  
 672              default:
 673                  $verbosityLevel = EZ_LEVEL_ERROR;
 674              break;
 675          }
 676          if ( $this->MessageOutput & EZ_OUTPUT_MESSAGE_SCREEN and $enabled )
 677          {
 678              print( "$verbosityLevel: $string ($label)\n" );
 679          }
 680          $files =& $this->logFiles();
 681          $fileName = false;
 682          if ( isset( $files[$verbosityLevel] ) )
 683              $fileName = $files[$verbosityLevel];
 684          if ( $this->MessageOutput & EZ_OUTPUT_MESSAGE_STORE or $alwaysLog )
 685          {
 686              if ( ! eZDebug::isLogOnlyEnabled() and $enabled )
 687              {
 688                  $ip = eZSys::serverVariable( 'REMOTE_ADDR', true );
 689                  if ( !$ip )
 690                      $ip = eZSys::serverVariable( 'HOSTNAME', true );
 691                  $this->DebugStrings[] = array( "Level" => $verbosityLevel,
 692                                                 "IP" => $ip,
 693                                                 "Time" => time(),
 694                                                 "Label" => $label,
 695                                                 "String" => $string,
 696                                                 "BackgroundClass" => $backgroundClass );
 697              }
 698  
 699              if ( $fileName !== false )
 700              {
 701                  $timePoints = $this->TmpTimePoints[$verbosityLevel];
 702                  if ( is_array( $timePoints ) )
 703                  {
 704                      if ( $this->isLogFileEnabled( $verbosityLevel ) )
 705                      {
 706                          foreach ( $timePoints as $tp )
 707                          {
 708                              $desc = "Timing Point: " . $tp["Description"];
 709                              if ( $this->isLogFileEnabled( $verbosityLevel ) )
 710                              {
 711                                  $this->writeFile( $fileName, $desc, $verbosityLevel, $alwaysLog );
 712                              }
 713                          }
 714                      }
 715                      $this->TmpTimePoints[$verbosityLevel] = false;
 716                  }
 717                  if ( $this->isLogFileEnabled( $verbosityLevel ) )
 718                  {
 719                      $string = "$label:\n$string";
 720                      $this->writeFile( $fileName, $string, $verbosityLevel, $alwaysLog );
 721                  }
 722              }
 723          }
 724      }
 725  
 726      /*!
 727       \static
 728       \return the maxium size for a log file in bytes.
 729      */
 730      function maxLogSize()
 731      {
 732          $maxLogSize =& $GLOBALS['eZDebugMaxLogSize'];
 733          if ( isset( $maxLogSize ) )
 734              return $maxLogSize;
 735          return EZ_DEBUG_MAX_LOGFILE_SIZE;
 736      }
 737  
 738      /*!
 739       \static
 740       Sets the maxium size for a log file to \a $size.
 741      */
 742      function setMaxLogSize( $size )
 743      {
 744          $GLOBALS['eZDebugMaxLogSize'] = $size;
 745      }
 746  
 747      /*!
 748       \static
 749       \return the maxium number of logrotate files to keep.
 750      */
 751      function maxLogrotateFiles()
 752      {
 753          $maxLogrotateFiles =& $GLOBALS['eZDebugMaxLogrotateFiles'];
 754          if ( isset( $maxLogrotateFiles ) )
 755              return $maxLogrotateFiles;
 756          return EZ_DEBUG_MAX_LOGROTATE_FILES;
 757      }
 758  
 759      /*!
 760       \static
 761       Sets the maxium number of logrotate files to keep to \a $files.
 762      */
 763      function setLogrotateFiles( $files )
 764      {
 765          $GLOBALS['eZDebugMaxLogrotateFiles'] = $filse;
 766      }
 767  
 768      /*!
 769       \static
 770       Rotates logfiles so the current logfile is backed up,
 771       old rotate logfiles are rotated once more and those that
 772       exceed maxLogrotateFiles() will be removed.
 773       Rotated files will get the extension .1, .2 etc.
 774      */
 775      function rotateLog( $fileName )
 776      {
 777          $maxLogrotateFiles = eZDebug::maxLogrotateFiles();
 778          for ( $i = $maxLogrotateFiles; $i > 0; --$i )
 779          {
 780              $logRotateName = $fileName . '.' . $i;
 781              if ( @file_exists( $logRotateName ) )
 782              {
 783                  if ( $i == $maxLogrotateFiles )
 784                  {
 785                      @unlink( $logRotateName );
 786  //                     print( "@unlink( $logRotateName )<br/>" );
 787                  }
 788                  else
 789                  {
 790                      $newLogRotateName = $fileName . '.' . ($i + 1);
 791                      @rename( $logRotateName, $newLogRotateName );
 792  //                     print( "@rename( $logRotateName, $newLogRotateName )<br/>" );
 793                  }
 794              }
 795          }
 796          if ( @file_exists( $fileName ) )
 797          {
 798              $newLogRotateName = $fileName . '.' . 1;
 799              @rename( $fileName, $newLogRotateName );
 800  //             print( "@rename( $fileName, $newLogRotateName )<br/>" );
 801              return true;
 802          }
 803          return false;
 804      }
 805  
 806      /*!
 807       \private
 808       Writes the log message $string to the file $fileName.
 809      */
 810      function writeFile( &$logFileData, &$string, $verbosityLevel, $alwaysLog = false )
 811      {
 812          $enabled = eZDebug::isDebugEnabled();
 813          if ( !$alwaysLog and !$enabled )
 814              return;
 815          if ( !$alwaysLog and !$this->isLogFileEnabled( $verbosityLevel ) )
 816              return;
 817          $oldHandleType = eZDebug::setHandleType( EZ_HANDLE_TO_PHP );
 818          $logDir = $logFileData[0];
 819          $logName = $logFileData[1];
 820          $fileName = $logDir . $logName;
 821          if ( !file_exists( $logDir ) )
 822          {
 823              include_once ( 'lib/ezfile/classes/ezdir.php' );
 824              eZDir::mkdir( $logDir, 0775, true );
 825          }
 826          $oldumask = @umask( 0 );
 827          $fileExisted = @file_exists( $fileName );
 828          if ( $fileExisted and
 829               filesize( $fileName ) > eZDebug::maxLogSize() )
 830          {
 831              if ( eZDebug::rotateLog( $fileName ) )
 832                  $fileExisted = false;
 833          }
 834          $logFile = @fopen( $fileName, "a" );
 835          if ( $logFile )
 836          {
 837              $time = strftime( "%b %d %Y %H:%M:%S", strtotime( "now" ) );
 838              $ip = eZSys::serverVariable( 'REMOTE_ADDR', true );
 839              if ( !$ip )
 840                  $ip = eZSys::serverVariable( 'HOSTNAME', true );
 841              $notice = "[ " . $time . " ] [" . $ip . "] " . $string . "\n";
 842              @fwrite( $logFile, $notice );
 843              @fclose( $logFile );
 844              if ( !$fileExisted )
 845                  @chmod( $fileName, 0664 );
 846              @umask( $oldumask );
 847          }
 848          else
 849          {
 850              @umask( $oldumask );
 851              $logEnabled = $this->isLogFileEnabled( $verbosityLevel );
 852              $this->setLogFileEnabled( false, $verbosityLevel );
 853              if ( $verbosityLevel != EZ_LEVEL_ERROR or
 854                   $logEnabled )
 855              {
 856                  eZDebug::setHandleType( $oldHandleType );
 857                  $this->writeError( "Cannot open log file '$fileName' for writing\n" .
 858                                     "The web server must be allowed to modify the file.\n" .
 859                                     "File logging for '$fileName' is disabled." , 'eZDebug::writeFile' );
 860              }
 861          }
 862          eZDebug::setHandleType( $oldHandleType );
 863      }
 864  
 865      /*!
 866       \static
 867       Enables or disables logging to file for a given message type.
 868       If \a $types is not supplied it will do the operation for all types.
 869      */
 870      function setLogFileEnabled( $enabled, $types = false )
 871      {
 872          if ( isset( $this ) and
 873               get_class( $this ) == "ezdebug" )
 874              $instance =& $this;
 875          else
 876              $instance =& eZDebug::instance();
 877          if ( $types === false )
 878              $types = $instance->messageTypes();
 879          if ( !is_array( $types ) )
 880              $types = array( $types );
 881          foreach ( $types as $type )
 882          {
 883              $instance->LogFileEnabled[$type] = $enabled;
 884          }
 885      }
 886  
 887      /*!
 888       \return true if the message type \a $type has logging to file enabled.
 889       \sa isGlobalLogFileEnabled, setIsLogFileEnabled
 890      */
 891      function isLogFileEnabled( $type )
 892      {
 893          if ( !$this->isGlobalLogFileEnabled() )
 894              return false;
 895          return $this->LogFileEnabled[$type];
 896      }
 897  
 898      /*!
 899       \return true if the message type \a $type has logging to file enabled.
 900       \sa isLogFileEnabled, setIsGlobalLogFileEnabled
 901      */
 902      function isGlobalLogFileEnabled()
 903      {
 904          return $this->GlobalLogFileEnabled;
 905      }
 906  
 907      /*!
 908       Sets whether the logfile \a $type is enabled or disabled to \a $enabled.
 909       \sa isLogFileEnabled
 910      */
 911      function setIsLogFileEnabled( $type, $enabled )
 912      {
 913          $this->LogFileEnabled[$type] = $enabled;
 914      }
 915  
 916      /*!
 917       Sets whether logfiles are enabled or disabled globally. Sets the value to \a $enabled.
 918       \sa isLogFileEnabled, isGlobalLogFileEnabled
 919      */
 920      function setIsGlobalLogFileEnabled( $enabled )
 921      {
 922          $this->GlobalLogFileEnabled = $enabled;
 923      }
 924  
 925      /*!
 926       Sets whether debug output should be logged only
 927      */
 928      function setLogOnly( $enabled )
 929      {
 930          $GLOBALS['eZDebugLogOnly'] = $enabled;
 931      }
 932  
 933      /*!
 934       \return an array with the available message types.
 935      */
 936      function messageTypes()
 937      {
 938          return $this->MessageTypes;
 939      }
 940  
 941      /*!
 942       Returns an associative array of all the log files used by this class
 943       where each key is the debug level (EZ_LEVEL_NOTICE, EZ_LEVEL_WARNING or EZ_LEVEL_ERROR or EZ_LEVEL_DEBUG).
 944      */
 945      function &logFiles()
 946      {
 947          return $this->LogFiles;
 948      }
 949  
 950      /*!
 951       \static
 952       \return true if debug should be enabled.
 953       \note Will return false until the real settings has been updated with updateSettings()
 954      */
 955      function isDebugEnabled()
 956      {
 957          if ( isset( $GLOBALS['eZDebugEnabled'] ) )
 958          {
 959              return $GLOBALS['eZDebugEnabled'];
 960          }
 961  
 962          return false;
 963      }
 964  
 965      /*!
 966       \static
 967       \return true if there should only be logging of debug strings to file.
 968       \note Will return false until the real settings has been updated with updateSettings()
 969      */
 970      function isLogOnlyEnabled()
 971      {
 972          if ( isset( $GLOBALS['eZDebugLogOnly'] ) )
 973          {
 974              return $GLOBALS['eZDebugLogOnly'];
 975          }
 976  
 977          return false;
 978      }
 979  
 980      /*!
 981       \static
 982       Determine if an ipaddress is in a network. E.G. 120.120.120.120 in 120.120.0.0/24.
 983       \return true or false.
 984      */
 985      function isIPInNet( $ipaddress, $network, $mask = 24 )
 986      {
 987          $lnet = ip2long( $network );
 988          $lip = ip2long( $ipaddress );
 989          $binnet = str_pad( decbin( $lnet ), 32, "0", "STR_PAD_LEFT" );
 990          $firstpart = substr($binnet,0,$mask);
 991          $binip = str_pad( decbin( $lip ), 32, "0", "STR_PAD_LEFT" );
 992          $firstip = substr( $binip, 0, $mask );
 993          return( strcmp( $firstpart, $firstip ) == 0 );
 994      }
 995  
 996      /*!
 997       \static
 998       Updates the settings for debug handling with the settings array \a $settings.
 999       The array must contain the following keys.
1000       - debug-enabled - boolean which controls debug handling
1001       - debug-by-ip   - boolean which controls IP controlled debugging
1002       - debug-ip-list - array of IPs which gets debug
1003       - debug-by-user - boolean which controls userID controlled debugging
1004       - debug-user-list - array of UserIDs which gets debug
1005      */
1006      function updateSettings( $settings )
1007      {
1008          // Make sure errors are handled by PHP when we read, including our own debug output.
1009          $oldHandleType = eZDebug::setHandleType( EZ_HANDLE_TO_PHP );
1010  
1011          $debugEnabled =& $GLOBALS['eZDebugEnabled'];
1012          if ( isset( $settings['debug-log-files-enabled'] ) )
1013          {
1014              $GLOBALS['eZDebugLogFileEnabled'] = $settings['debug-log-files-enabled'];
1015              if ( isset( $GLOBALS["eZDebugGlobalInstance"] ) )
1016                  $GLOBALS["eZDebugGlobalInstance"]->GlobalLogFileEnabled = $settings['debug-log-files-enabled'];
1017          }
1018  
1019          if ( isset( $settings['debug-styles'] ) )
1020          {
1021              $GLOBALS['eZDebugStyles'] = $settings['debug-styles'];
1022          }
1023  
1024          if ( isset( $settings['always-log'] ) and
1025               is_array( $settings['always-log'] ) )
1026          {
1027              $GLOBALS['eZDebugAlwaysLog'] = $settings['always-log'];
1028          }
1029  
1030          if ( isset( $settings['log-only'] ) )
1031          {
1032              $GLOBALS['eZDebugLogOnly'] = ( $settings['log-only'] == 'enabled' );
1033          }
1034  
1035          $notDebugByIP = true;
1036          $debugEnabled = $settings['debug-enabled'];
1037          if ( $settings['debug-enabled'] and
1038               $settings['debug-by-ip'] )
1039          {
1040              $ipAddress = eZSys::serverVariable( 'REMOTE_ADDR', true );
1041              if ( $ipAddress )
1042              {
1043                  $debugEnabled = false;
1044                  foreach( $settings['debug-ip-list'] as $itemToMatch )
1045                  {
1046                      if ( preg_match("/^(([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+))(\/([0-9]+)$|$)/", $itemToMatch, $matches ) )
1047                      {
1048                          if ( $matches[6] )
1049                          {
1050                              if ( eZDebug::isIPInNet( $ipAddress, $matches[1], $matches[7]))
1051                              {
1052                                  $debugEnabled = true;
1053                                  $notDebugByIP = false;
1054                                  break;
1055                              }
1056                          }
1057                          else
1058                          {
1059                              if ( $matches[1] == $ipAddress )
1060                              {
1061                                  $debugEnabled = true;
1062                                  $notDebugByIP = false;
1063                                  break;
1064                              }
1065                          }
1066                      }
1067                  }
1068              }
1069              else
1070              {
1071                  $debugEnabled = (
1072                      in_array( 'commandline', $settings['debug-ip-list'] ) &&
1073                      ( php_sapi_name() == 'cli' )
1074                  );
1075              }
1076          }
1077          if ( $settings['debug-enabled'] and
1078               isset( $settings['debug-by-user'] ) and
1079               $settings['debug-by-user'] and
1080               $notDebugByIP )
1081          {
1082              $debugUserIDList = $settings['debug-user-list'] ? $settings['debug-user-list'] : array();
1083              $GLOBALS['eZDebugUserIDList'] = $debugUserIDList;
1084              // We enable the debug temporarily.
1085              // In checkDebugByUser() will be last(final) check for debug by user id.
1086              $debugEnabled = true;
1087          }
1088  
1089          eZDebug::setHandleType( $oldHandleType );
1090      }
1091  
1092      /*!
1093        \static
1094        Final checking for debug by user id.
1095        Checks if we should enable debug.
1096      */
1097      function checkDebugByUser()
1098      {
1099          $debugUserIDList = isset( $GLOBALS['eZDebugUserIDList'] ) ? $GLOBALS['eZDebugUserIDList'] : false;
1100  
1101          if ( $debugUserIDList === false )
1102              return false;
1103  
1104          $debugEnabled =& $GLOBALS['eZDebugEnabled'];
1105          if ( count( $debugUserIDList ) == 0 )
1106          {
1107              // We should set previous value.
1108              $debugEnabled = false;
1109              return false;
1110          }
1111  
1112          if ( include_once ( "kernel/classes/datatypes/ezuser/ezuser.php" ) )
1113              $currentUserID = eZUser::currentUserID();
1114  
1115          $debugEnabled = $currentUserID ? in_array( $currentUserID, $debugUserIDList ) : $debugEnabled;
1116  
1117          unset( $GLOBALS['eZDebugUserIDList'] );
1118      }
1119  
1120      /*!
1121        \static
1122        Prints the debug report
1123      */
1124      function printReport( $newWindow = false, $as_html = true, $returnReport = false,
1125                             $allowedDebugLevels = false, $useAccumulators = true, $useTiming = true, $useIncludedFiles = false )
1126      {
1127          if ( !eZDebug::isDebugEnabled() )
1128              return null;
1129  
1130          $debug =& eZDebug::instance();
1131          $report = $debug->printReportInternal( $as_html, $returnReport & $newWindow, $allowedDebugLevels, $useAccumulators, $useTiming, $useIncludedFiles );
1132  
1133          if ( $newWindow == true )
1134          {
1135              $debugFilePath = eZDir::path( array( eZSys::varDirectory(), 'cache', 'debug.html' ) );
1136              print( "
1137  <SCRIPT LANGUAGE='JavaScript'>
1138  <!-- hide this script from old browsers
1139  
1140  function showDebug()
1141  {
1142      var debugWindow;
1143  
1144      if  (navigator.appName == \"Microsoft Internet Explorer\")
1145      {
1146          //Microsoft Internet Explorer
1147          debugWindow = window.open( '/$debugFilePath', 'ezdebug', 'width=500,height=550,status,scrollbars,resizable,screenX=0,screenY=20,left=20,top=40');
1148          debugWindow.document.close();
1149          debugWindow.location.reload();
1150      }
1151      else if (navigator.appName == \"Opera\")
1152      {
1153          //Opera
1154          debugWindow = window.open( '', 'ezdebug', 'width=500,height=550,status,scrollbars,resizable,screenX=0,screenY=20,left=20,top=40');
1155          debugWindow.location.href=\"/$debugFilePath\";
1156          debugWindow.navigate(\"/$debugFilePath\");
1157      }
1158      else
1159      {
1160          //Mozilla, Firefox, etc.
1161          debugWindow = window.open( '', 'ezdebug', 'width=500,height=550,status,scrollbars,resizable,screenX=0,screenY=20,left=20,top=40');
1162      debugWindow.document.location.href=\"/$debugFilePath\";
1163      };
1164  }
1165  
1166  showDebug();
1167          
1168  // done hiding from old browsers -->
1169  </SCRIPT>
1170  " );
1171              $header = "<html><head><title>eZ debug</title></head><body>";
1172              $footer = "</body></html>";
1173              $fp = fopen( $debugFilePath, "w+" );
1174  
1175              fwrite( $fp, $header );
1176              fwrite( $fp, $report );
1177              fwrite( $fp, $footer );
1178              fclose( $fp );
1179          }
1180          else
1181          {
1182              if ( $returnReport )
1183                  return $report;
1184          }
1185          return null;
1186      }
1187  
1188      /*!
1189        \private
1190       Returns the microtime as a float value. $mtime must be in microtime() format.
1191      */
1192      function timeToFloat( $mtime )
1193      {
1194          $tTime = explode( " ", $mtime );
1195          ereg( "0\.([0-9]+)", "" . $tTime[0], $t1 );
1196          $time = $tTime[1] . "." . $t1[1];
1197          return $time;
1198      }
1199  
1200      /*!
1201       Sets the time of the start of the script ot \a $mtime.
1202       If \a $mtime is not supplied it gets the current \c microtime().
1203       This is used to calculate total execution time and percentages.
1204      */
1205      function setScriptStart( $mtime = false )
1206      {
1207          if ( $mtime == false )
1208              $mtime = microtime();
1209          $time = eZDebug::timeToFloat( microtime() );
1210          $debug =& eZDebug::instance();
1211          $debug->ScriptStart = $time;
1212      }
1213  
1214      /*!
1215        Creates an accumulator group with key \a $key and group name \a $name.
1216        If \a $name is not supplied name is taken from \a $key.
1217      */
1218      function createAccumulatorGroup( $key, $name = false )
1219      {
1220          if ( !eZDebug::isDebugEnabled() )
1221              return;
1222          if ( $name == '' or
1223               $name === false )
1224              $name = $key;
1225          $debug =& eZDebug::instance();
1226          if ( !array_key_exists( $key, $debug->TimeAccumulatorList ) )
1227              $debug->TimeAccumulatorList[$key] = array( 'name' => $name,  'time' => 0, 'count' => 0, 'is_group' => true, 'in_group' => false );
1228          if ( !array_key_exists( $key, $debug->TimeAccumulatorGroupList ) )
1229              $debug->TimeAccumulatorGroupList[$key] = array();
1230      }
1231  
1232      /*!
1233       Creates a new accumulator entry if one does not already exist and initializes with default data.
1234       If \a $name is not supplied name is taken from \a $key.
1235       If \a $inGroup is supplied it will place the accumulator under the specified group.
1236      */
1237      function createAccumulator( $key, $inGroup = false, $name = false )
1238      {
1239          if ( !eZDebug::isDebugEnabled() )
1240              return;
1241          if ( $name == '' or
1242               $name === false )
1243              $name = $key;
1244          $debug =& eZDebug::instance();
1245          $isGroup = false;
1246          if ( array_key_exists( $key, $debug->TimeAccumulatorList ) and
1247               array_key_exists( $key, $debug->TimeAccumulatorGroupList ) )
1248              $isGroup = true;
1249          $debug->TimeAccumulatorList[$key] = array( 'name' => $name,  'time' => 0, 'count' => 0, 'is_group' => $isGroup, 'in_group' => $inGroup );
1250          if ( $inGroup !== false )
1251          {
1252              $groupKeys = array();
1253              if ( array_key_exists( $inGroup, $debug->TimeAccumulatorGroupList ) )
1254                  $groupKeys = $debug->TimeAccumulatorGroupList[$inGroup];
1255              $debug->TimeAccumulatorGroupList[$inGroup] = array_unique( array_merge( $groupKeys, array( $key ) ) );
1256              if ( array_key_exists( $inGroup, $debug->TimeAccumulatorList ) )
1257                  $debug->TimeAccumulatorList[$inGroup]['is_group'] = true;
1258          }
1259      }
1260  
1261      /*!
1262       Starts an time count for the accumulator \a $key.
1263       You can also specify a name which will be displayed.
1264      */
1265      function accumulatorStart( $key, $inGroup = false, $name = false, $recursive = false )
1266      {
1267          if ( !eZDebug::isDebugEnabled() )
1268              return;
1269          $debug =& eZDebug::instance();
1270          $key = $key === false ? 'Default Debug-Accumulator' : $key;
1271          if ( ! array_key_exists( $key, $debug->TimeAccumulatorList ) )
1272          {
1273              $debug->createAccumulator( $key, $inGroup, $name );
1274          }
1275  
1276          $accumulator =& $debug->TimeAccumulatorList[$key];
1277          if ( $recursive )
1278          {
1279              if ( isset( $accumulator['recursive_counter'] ) )
1280              {
1281                  $accumulator['recursive_counter']++;
1282                  return;
1283              }
1284              $accumulator['recursive_counter'] = 0;
1285          }
1286          $accumulator['temp_time'] = $debug->timeToFloat( microtime() );
1287      }
1288  
1289      /*!
1290       Stops a previous time count and adds the total time to the accumulator \a $key.
1291      */
1292      function accumulatorStop( $key, $recursive = false )
1293      {
1294          if ( !eZDebug::isDebugEnabled() )
1295              return;
1296          $debug =& eZDebug::instance();
1297          $stopTime = $debug->timeToFloat( microtime() );
1298          $key = $key === false ? 'Default Debug-Accumulator' : $key;
1299          if ( ! array_key_exists( $key, $debug->TimeAccumulatorList ) )
1300          {
1301              eZDebug::writeWarning( 'Accumulator $key does not exists, run eZDebug::accumulatorStart first', 'eZDebug::accumulatorStop' );
1302              return;
1303          }
1304          $accumulator =& $debug->TimeAccumulatorList[$key];
1305          if ( $recursive )
1306          {
1307              if ( isset( $accumulator['recursive_counter'] ) )
1308              {
1309                  if ( $accumulator['recursive_counter'] > 0 )
1310                  {
1311                      $accumulator['recursive_counter']--;
1312                      return;
1313                  }
1314              }
1315          }
1316          $diffTime = $stopTime - $accumulator['temp_time'];
1317          $accumulator['time'] = $accumulator['time'] + $diffTime;
1318          ++$accumulator['count'];
1319      }
1320  
1321  
1322      /*!
1323        \private
1324        Prints a full debug report with notice, warnings, errors and a timing report.
1325      */
1326      function printReportInternal( $as_html = true, $returnReport = true, $allowedDebugLevels = false,
1327                                     $useAccumulators = true, $useTiming = true, $useIncludedFiles = false )
1328      {
1329          $styles = array( 'warning' => false,
1330                           'warning-end' => false,
1331                           'error' => false,
1332                           'error-end' => false,
1333                           'debug' => false,
1334                           'debug-end' => false,
1335                           'notice' => false,
1336                           'notice-end' => false,
1337                           'timing' => false,
1338                           'timing-end' => false,
1339                           'mark' => false,
1340                           'mark-end' => false,
1341                           'emphasize' => false,
1342                           'emphasize-end' => false,
1343                           'bold' => false,
1344                           'bold-end' => false );
1345          if ( isset( $GLOBALS['eZDebugStyles'] ) )
1346              $styles = $GLOBALS['eZDebugStyles'];
1347          if ( !$allowedDebugLevels )
1348              $allowedDebugLevels = array( EZ_LEVEL_NOTICE, EZ_LEVEL_WARNING, EZ_LEVEL_ERROR,
1349                                           EZ_LEVEL_DEBUG, EZ_LEVEL_TIMING_POINT );
1350          $endTime = microtime();
1351  
1352          if ( $returnReport )
1353          {
1354              ob_start();
1355          }
1356  
1357          if ( $as_html )
1358          {
1359              echo "<table style='border: 1px dashed black;' bgcolor=\"#fefefe\">";
1360              echo "<tr><th><h1>eZ debug</h1></th></tr>";
1361  
1362              echo "<tr><td>";
1363  
1364              if ( !$this->UseCSS )
1365              {
1366                  echo "<STYLE TYPE='text/css'>
1367                  <!--
1368  td.debugheader
1369  \{
1370      background-color : #eeeeee;
1371      border-top : 1px solid #444488;
1372      border-bottom : 1px solid #444488;
1373      font-size : 65%;
1374      font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
1375  \}
1376  
1377  pre.debugtransaction
1378  \{
1379      background-color : #f8f6d8;
1380  \}
1381  
1382  td.timingpoint1
1383  \{
1384      background-color : #ffffff;
1385      border-top : 1px solid #444488;
1386      font-size : 65%;
1387      font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
1388  \}
1389  
1390  td.timingpoint2
1391  \{
1392      background-color : #eeeeee;
1393      border-top : 1px solid #444488;
1394      font-size : 65%;
1395      font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
1396  \}
1397  
1398  -->
1399  </STYLE>";
1400              }
1401              echo "<table style='border: 1px lightgray;' cellspacing='0'>";
1402          }
1403  
1404          $this->printTopReportsList();
1405  
1406          $hasLevel = array( EZ_LEVEL_NOTICE => false,
1407                             EZ_LEVEL_WARNING => false,
1408                             EZ_LEVEL_ERROR => false,
1409                             EZ_LEVEL_TIMING_POINT => false,
1410                             EZ_LEVEL_DEBUG => false );
1411  
1412          foreach ( $this->DebugStrings as $debug )
1413          {
1414              if ( !in_array( $debug['Level'], $allowedDebugLevels ) )
1415                  continue;
1416              $time = strftime ("%b %d %Y %H:%M:%S", strtotime( "now" ) );
1417  
1418              $outputData = $this->OutputFormat[$debug["Level"]];
1419              if ( is_array( $outputData ) )
1420              {
1421                  $identifierText = '';
1422                  if ( !$hasLevel[$debug['Level']] )
1423                  {
1424                      $hasLevel[$debug['Level']] = true;
1425                      $identifierText = 'id="' . $outputData['xhtml-identifier'] . '"';
1426                  }
1427                  $color = $outputData["color"];
1428                  $name = $outputData["name"];
1429                  $label = $debug["Label"];
1430                  $bgclass = $debug["BackgroundClass"];
1431                  $pre = ($bgclass != '' ? " class='$bgclass'" : '');
1432                  if ( $as_html )
1433                  {
1434                      $label = htmlspecialchars( $label );
1435  
1436                      $contents = '';
1437                      if ( extension_loaded( 'xdebug' ) && ( strncmp( EZ_DEBUG_XDEBUG_SIGNATURE, $debug['String'], strlen( EZ_DEBUG_XDEBUG_SIGNATURE ) ) === 0 ) )
1438                          $contents = substr( $debug['String'], strlen( EZ_DEBUG_XDEBUG_SIGNATURE ) );
1439                      else
1440                          $contents = htmlspecialchars( $debug['String'] );
1441  
1442                      echo "<tr><td class='debugheader' valign='top'$identifierText><b><font color=\"$color\">$name:</font> $label</b></td>
1443                                      <td class='debugheader' valign='top'>$time</td></tr>
1444                                      <tr><td colspan='2'><pre$pre>" .  $contents . "</pre></td></tr>";
1445                  }
1446                  else
1447                  {
1448                      echo $styles[$outputData['style']] . "$name:" . $styles[$outputData['style'].'-end'] . " ";
1449                      echo $styles['bold'] . "($label)" . $styles['bold-end'] . "\n" . $debug["String"] . "\n\n";
1450                  }
1451              }
1452              flush();
1453          }
1454          if ( $as_html )
1455          {
1456              echo "</table>";
1457  
1458              echo "<h2>Timing points:</h2>";
1459              echo "<table style='border: 1px dashed black;' cellspacing='0'><tr><th>Checkpoint</th><th>Elapsed</th><th>Rel. Elapsed</th><th>Memory</th><th>Rel. Memory</th></tr>";
1460          }
1461          $startTime = false;
1462          $elapsed = 0.00;
1463          $relElapsed = 0.00;
1464          if ( $useTiming )
1465          {
1466              for ( $i = 0; $i < count( $this->TimePoints ); ++$i )
1467              {
1468                  $point = $this->TimePoints[$i];
1469                  $nextPoint = false;
1470                  if ( isset( $this->TimePoints[$i + 1] ) )
1471                      $nextPoint = $this->TimePoints[$i + 1];
1472                  $time = $this->timeToFloat( $point["Time"] );
1473                  $nextTime = false;
1474                  if ( $nextPoint !== false )
1475                      $nextTime = $this->timeToFloat( $nextPoint["Time"] );
1476                  if ( $startTime === false )
1477                      $startTime = $time;
1478                  $elapsed = $time - $startTime;
1479                  $relElapsed = $nextTime - $time;
1480  
1481                  $memory = $point["MemoryUsage"];
1482                  $nextMemory = 0;
1483                  // Calculate relative memory usage
1484                  if ( $nextPoint !== false )
1485                  {
1486                      $nextMemory = $nextPoint["MemoryUsage"];
1487                      $relMemory = $nextMemory - $memory;
1488                  }
1489  
1490                  // Convert memeory usage to human readable
1491                  $memory = number_format( $memory / 1024, $this->TimingAccuracy ) . "KB";
1492                  $relMemory = number_format( $relMemory / 1024, $this->TimingAccuracy ) . "KB";
1493  
1494                  if ( $i % 2 == 0 )
1495                      $class = "timingpoint1";
1496                  else
1497                      $class = "timingpoint2";
1498  
1499                  if ( $as_html )
1500                  {
1501                      echo "<tr><td class='$class'>" . $point["Description"] . "</td><td class='$class'>" .
1502      number_format( ( $elapsed ), $this->TimingAccuracy ) . " sec</td><td class='$class'>".
1503      ( empty( $nextPoint ) ? "&nbsp;" : number_format( ( $relElapsed ), $this->TimingAccuracy ) . " sec" ) . "</td>"
1504      . "<td class='$class'>" . $memory . "</td><td class='$class'>". $relMemory . "</td></tr>";
1505                  }
1506                  else
1507                  {
1508                      echo $point["Description"] . ' ' .
1509      number_format( ( $elapsed ), $this->TimingAccuracy ) . " sec".
1510      ( empty( $nextPoint ) ? "" : number_format( ( $relElapsed ), $this->TimingAccuracy ) . " sec" ) . "\n";
1511                  }
1512              }
1513  
1514              if ( count( $this->TimePoints ) > 0 )
1515              {
1516                  $tTime = explode( " ", $endTime );
1517                  ereg( "0\.([0-9]+)", "" . $tTime[0], $t1 );
1518                  $endTime = $tTime[1] . "." . $t1[1];
1519  
1520                  $totalElapsed = $endTime - $startTime;
1521  
1522                  if ( $as_html )
1523                  {
1524                      echo "<tr><td><b>Total runtime:</b></td><td><b>" .
1525      number_format( ( $totalElapsed ), $this->TimingAccuracy ) . " sec</b></td><td></td></tr>";
1526                  }
1527                  else
1528                  {
1529                      echo "Total runtime: " .
1530      number_format( ( $totalElapsed ), $this->TimingAccuracy ) . " sec\n";
1531                  }
1532              }
1533              else
1534              {
1535                  if ( $as_html )
1536                      echo "<tr><td> No timing points defined</td><td>";
1537                  else
1538                      echo "No timing points defined\n";
1539              }
1540              if ( function_exists('xdebug_peak_memory_usage') )
1541              {
1542                  $peakMemory = xdebug_peak_memory_usage();
1543                  if ( $as_html )
1544                      echo "<tr><td><b>Peak memory usage:</b></td><td><b>" .
1545                          number_format( $peakMemory / 1024, $this->TimingAccuracy ) . "KB</b></td></tr>";
1546                  else
1547                      echo "Peak memory usage: " .
1548                          number_format( $peakMemory / 1024, $this->TimingAccuracy ) . "KB\n";
1549              }
1550          }
1551          if ( $as_html )
1552          {
1553              echo "</table>";
1554          }
1555  
1556          if ( $useIncludedFiles )
1557          {
1558              if ( $as_html )
1559                  echo "<h2>Included files:</h2><table style='border: 1px dashed black;' cellspacing='0'><tr><th>File</th></tr>";
1560              else
1561                  echo $styles['emphasize'] . "Includes" . $styles['emphasize-end'] . "\n";
1562              $phpFiles = get_included_files();
1563              $j = 0;
1564              $currentPathReg = preg_quote( realpath( "." ) );
1565              foreach ( $phpFiles as $phpFile )
1566              {
1567                  if ( preg_match( "#^$currentPathReg/(.+)$#", $phpFile, $matches ) )
1568                      $phpFile = $matches[1];
1569                  if ( $as_html )
1570                  {
1571                      if ( $j % 2 == 0 )
1572                          $class = "timingpoint1";
1573                      else
1574                          $class = "timingpoint2";
1575                      ++$j;
1576                      echo "<tr><td class=\"$class\">$phpFile</td></tr>";
1577                  }
1578                  else
1579                  {
1580                      echo "$phpFile\n";
1581                  }
1582              }
1583              if ( $as_html )
1584                  echo "</table>";
1585          }
1586  
1587          if ( $as_html )
1588          {
1589              echo "<h2>Time accumulators:</h2>";
1590              echo "<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>";
1591              $i = 0;
1592          }
1593  
1594          $scriptEndTime = eZDebug::timeToFloat( microtime() );
1595          $totalElapsed = $scriptEndTime - $this->ScriptStart;
1596          $timeList = $this->TimeAccumulatorList;
1597          $groups = $this->TimeAccumulatorGroupList;
1598          $groupList = array();
1599          foreach ( $groups as $groupKey => $keyList )
1600          {
1601              if ( count( $keyList ) == 0 and
1602                   !array_key_exists( $groupKey, $timeList ) )
1603                  continue;
1604              $groupList[$groupKey] = array( 'name' => $groupKey );
1605              if ( array_key_exists( $groupKey, $timeList ) )
1606              {
1607                  if ( $timeList[$groupKey]['time'] != 0 )
1608                      $groupList[$groupKey]['time_data'] = $timeList[$groupKey];
1609                  $groupList[$groupKey]['name'] = $timeList[$groupKey]['name'];
1610                  unset( $timeList[$groupKey] );
1611              }
1612              $groupChildren = array();
1613              foreach ( $keyList as $timeKey )
1614              {
1615                  if ( array_key_exists( $timeKey, $timeList ) )
1616                  {
1617                      $groupChildren[] = $timeList[$timeKey];
1618                      unset( $timeList[$timeKey] );
1619                  }
1620              }
1621              $groupList[$groupKey]['children'] = $groupChildren;
1622          }
1623          if ( count( $timeList ) > 0 )
1624          {
1625              $groupList['general'] = array( 'name' => 'General',
1626                                             'children' => $timeList );
1627          }
1628  
1629          if ( $useAccumulators )
1630          {
1631              $j = 0;
1632              foreach ( $groupList as $group )
1633              {
1634                  if ( $j % 2 == 0 )
1635                      $class = "timingpoint1";
1636                  else
1637                      $class = "timingpoint2";
1638                  ++$j;
1639                  $groupName = $group['name'];
1640                  $groupChildren = $group['children'];
1641                  if ( count( $groupChildren ) == 0 and
1642                       !array_key_exists( 'time_data', $group ) )
1643                      continue;
1644                  if ( $as_html )
1645                      echo "<tr><td class='$class'><b>$groupName</b></td>";
1646                  else
1647                      echo "Group " . $styles['mark'] . "$groupName:" . $styles['mark-end'] . " ";
1648                  if ( array_key_exists( 'time_data', $group ) )
1649                  {
1650                      $groupData = $group['time_data'];
1651                      $groupElapsed = number_format( ( $groupData['time'] ), $this->TimingAccuracy );
1652                      $groupPercent = number_format( ( $groupData['time'] * 100.0 ) / $totalElapsed, 1 );
1653                      $groupCount = $groupData['count'];
1654                      $groupAverage = number_format( ( $groupData['time'] / $groupData['count'] ), $this->TimingAccuracy );
1655                      if ( $as_html )
1656                      {
1657                          echo ( "<td class=\"$class\">$groupElapsed sec</td>".
1658                                           "<td class=\"$class\" align=\"right\"> $groupPercent%</td>".
1659                                           "<td class=\"$class\" align=\"right\"> $groupCount</td>".
1660                                           "<td class=\"$class\" align=\"right\"> $groupAverage sec</td>" );
1661                      }
1662                      else
1663                      {
1664                          echo $styles['emphasize'] . "$groupElapsed" . $styles['emphasize-end'] . " sec ($groupPercent%), $groupAverage avg sec ($groupCount)";
1665                      }
1666                  }
1667                  else if ( $as_html )
1668                  {
1669                      echo ( "<td class=\"$class\"></td>".
1670                                       "<td class=\"$class\"></td>".
1671                                       "<td class=\"$class\"></td>".
1672                                       "<td class=\"$class\"></td>" );
1673                  }
1674                  if ( $as_html )
1675                      echo "</tr>";
1676                  else
1677                      echo "\n";
1678  
1679                  $i = 0;
1680                  foreach ( $groupChildren as $child )
1681                  {
1682                      $childName = $child['name'];
1683                      $childElapsed = number_format( ( $child['time'] ), $this->TimingAccuracy );
1684                      $childPercent = number_format( ( $child['time'] * 100.0 ) / $totalElapsed, $this->PercentAccuracy );
1685                      $childCount = $child['count'];
1686                      $childAverage = 0.0;
1687                      if ( $childCount > 0 )
1688                      {
1689                          $childAverage = $child['time'] / $childCount;
1690                      }
1691                      $childAverage = number_format( $childAverage, $this->PercentAccuracy );
1692  
1693                      if ( $as_html )
1694                      {
1695                          if ( $i % 2 == 0 )
1696                              $class = "timingpoint1";
1697                          else
1698                              $class = "timingpoint2";
1699                          ++$i;
1700  
1701                          echo ( "<tr>" .
1702                                           "<td class=\"$class\">$childName</td>" .
1703                                           "<td class=\"$class\">$childElapsed sec</td>" .
1704                                           "<td class=\"$class\" align=\"right\">$childPercent%</td>" .
1705                                           "<td class=\"$class\" align=\"right\">$childCount</td>" .
1706                                           "<td class=\"$class\" align=\"right\">$childAverage sec</td>" .
1707                                           "</tr>" );
1708                      }
1709                      else
1710                      {
1711                          echo "$childName: " . $styles['emphasize'] . $childElapsed . $styles['emphasize-end'] . " sec ($childPercent%), $childAverage avg sec ($childCount)\n";
1712                      }
1713                  }
1714              }
1715          }
1716          if ( $as_html )
1717          {
1718              echo "<tr><td><b>Total script time:</b></td><td><b>" . number_format( ( $totalElapsed ), $this->TimingAccuracy ) . " sec</b></td><td></td></tr>";
1719          }
1720          else
1721          {
1722              echo "\nTotal script time: " . $styles['emphasize'] . number_format( ( $totalElapsed ), $this->TimingAccuracy ) . $styles['emphasize-end'] . " sec\n";
1723          }
1724  
1725          if ( $as_html )
1726          {
1727              echo "</table>";
1728          }
1729  
1730          $this->printBottomReportsList();
1731  
1732          if ( $as_html )
1733          {
1734              echo "</td></tr></table>";
1735          }
1736  
1737          if ( $returnReport )
1738          {
1739              $returnText = ob_get_contents();
1740              ob_end_clean();
1741              return $returnText;
1742          }
1743          else
1744          {
1745              return NULL;
1746          }
1747      }
1748  
1749      /*!
1750       Appends report to 'top' reports list.
1751      */
1752      function appendTopReport( $reportName, &$reportContent )
1753      {
1754          $debug =& eZDebug::instance();
1755          $debug->topReportsList[$reportName] =& $reportContent;
1756      }
1757  
1758      /*!
1759       Prints all 'top' reports
1760      */
1761      function printTopReportsList()
1762      {
1763          $debug =& eZDebug::instance();
1764          $reportNames = array_keys( $debug->topReportsList );
1765          foreach ( $reportNames as $reportName )
1766          {
1767              $reportContent =& $debug->topReportsList[$reportName];
1768              echo $reportContent;
1769          }
1770      }
1771  
1772      /*!
1773       Appends report to 'bottom' reports list.
1774      */
1775      function appendBottomReport( $reportName, &$reportContent )
1776      {
1777          $debug =& eZDebug::instance();
1778          $debug->bottomReportsList[$reportName] =& $reportContent;
1779      }
1780  
1781      /*!
1782       Prints all 'bottom' reports
1783      */
1784      function printBottomReportsList()
1785      {
1786          $debug =& eZDebug::instance();
1787          $reportNames = array_keys( $debug->bottomReportsList );
1788          foreach ( $reportNames as $reportName )
1789          {
1790              $reportContent =& $debug->bottomReportsList[$reportName];
1791              echo $reportContent;
1792          }
1793      }
1794  
1795      /// \privatesection
1796      /// String array containing the debug information
1797      var $DebugStrings = array();
1798  
1799      /// Array which contains the time points
1800      var $TimePoints = array();
1801  
1802      /// Array which contains the temporary time points
1803      var $TmpTimePoints;
1804  
1805      /// Array wich contains time accumulators
1806      var $TimeAccumulatorList = array();
1807  
1808      /// Determines which debug messages should be shown
1809      var $ShowTypes;
1810  
1811      /// Determines what to do with php errors, ignore, fetch or output
1812      var $HandleType;
1813  
1814      /// An array of the outputformats for the different debug levels
1815      var $OutputFormat;
1816  
1817      /// An array of logfiles used by the debug class with each key being the debug level
1818      var $LogFiles;
1819  
1820      /// How many places behing . should be displayed when showing times
1821      var $TimingAccuracy = 4;
1822  
1823      /// How many places behing . should be displayed when showing percentages
1824      var $PercentAccuracy = 4;
1825  
1826      /// Whether to use external CSS or output own CSS. True if external is to be used.
1827      var $UseCSS;
1828  
1829      /// Determines how messages are output (screen/log)
1830      var $MessageOutput;
1831  
1832      /// A list of message types
1833      var $MessageTypes;
1834  
1835      /// A map with message types and whether they should do file logging.
1836      var $LogFileEnabled;
1837  
1838      /// Controls whether logfiles are used at all.
1839      var $GlobalLogFileEnabled;
1840  
1841      /// The time when the script was started
1842      var $ScriptStart;
1843  
1844      /// A list of override directories
1845      var $OverrideList;
1846  
1847      /// A list of debug reports that appears at the bottom of debug output
1848      var $bottomReportsList;
1849  
1850      /// A list of debug reports that appears at the top of debug output
1851      var $topReportsList;
1852  }
1853  
1854  /*!
1855    Helper function for eZDebug, called whenever a PHP error occurs.
1856    The error is then handled by the eZDebug class.
1857  */
1858  
1859  function eZDebugErrorHandler( $errno, $errstr, $errfile, $errline )
1860  {
1861      if ( $GLOBALS['eZDebugRecursionFlag'] )
1862      {
1863          print( "Fatal debug error: A recursion in debug error handler was detected, aborting debug message.<br/>" );
1864          $GLOBALS['eZDebugRecursionFlag'] = false;
1865          return;
1866      }
1867      if ( preg_match( "/variable(.*?)reference/", $errstr ) )
1868          return;
1869      $GLOBALS['eZDebugRecursionFlag'] = true;
1870      $debug =& eZDebug::instance();
1871      $debug->errorHandler( $errno, $errstr, $errfile, $errline );
1872      $GLOBALS['eZDebugRecursionFlag'] = false;
1873  }
1874  $GLOBALS['eZDebugRecursionFlag'] = false;
1875  
1876  ?>


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7