b2evolution PHP Cross Reference Blogging Systems

Source: /inc/_core/model/_log.class.php - 645 lines - 16083 bytes - Summary - Text - Print

Description: This file implements the Log class FOR DEBUGGING It additionally provides the class Log_noop that implements the same (used) methods, but as no-operation functions. This is useful to create a more resource friendly object when you don't need it (think Debuglog).

   1  <?php
   2  /**
   3   * This file implements the Log class FOR DEBUGGING
   4   *
   5   * It additionally provides the class Log_noop that implements the same (used) methods, but as
   6   * no-operation functions. This is useful to create a more resource friendly object when
   7   * you don't need it (think Debuglog).
   8   *
   9   * This file is part of the evoCore framework - {@link http://evocore.net/}
  10   * See also {@link http://sourceforge.net/projects/evocms/}.
  11   *
  12   * @copyright (c)2003-2014 by Francois Planque - {@link http://fplanque.com/}
  13   * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
  14   *
  15   * {@internal License choice
  16   * - If you have received this file as part of a package, please find the license.txt file in
  17   *   the same folder or the closest folder above for complete license terms.
  18   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
  19   *   then you must choose one of the following licenses before using the file:
  20   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
  21   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
  22   * }}
  23   *
  24   * {@internal Open Source relicensing agreement:
  25   * Daniel HAHLER grants Francois PLANQUE the right to license
  26   * Daniel HAHLER's contributions to this file and the b2evolution project
  27   * under any OSI approved OSS license (http://www.opensource.org/licenses/).
  28   * }}
  29   *
  30   * @package evocore
  31   *
  32   * @author blueyed: Daniel HAHLER
  33   * @author fplanque: Francois PLANQUE
  34   *
  35   * @version $Id: _log.class.php 6136 2014-03-08 07:59:48Z manuel $ }}}
  36   *
  37   */
  38  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  39  
  40  
  41  /**
  42   * Log class. Logs notes and errors.
  43   *
  44   * Messages can be logged into different categories (aka levels)
  45   * Examples: 'note', 'error'. Note: 'all' is reserved to display all categories together.
  46   * Messages can later be displayed grouped by category/level.
  47   *
  48   * @package evocore
  49   */
  50  class Log
  51  {
  52      /**
  53       * The stored messages (by category).
  54       * array of arrays
  55       *
  56       * @var array
  57       */
  58      var $messages = array();
  59  
  60      /**
  61       * Default category for messages.
  62       * @var string
  63       */
  64      var $defaultcategory = 'note';
  65  
  66      /**
  67       * string or array to display before messages
  68       * @var mixed
  69       */
  70      var $head = '';
  71  
  72      /**
  73       * to display after messages
  74       * @var string
  75       */
  76      var $foot = '';
  77  
  78      /**
  79       * Cache for {@link Log::count()}
  80       * @var array
  81       */
  82      var $_count = array();
  83  
  84  
  85      /**
  86       * Constructor.
  87       *
  88       * @param string sets default category
  89       */
  90  	function Log( $category = 'note' )
  91      {
  92          $this->defaultcategory = $category;
  93  
  94          // create the array for this category
  95          $this->messages[$category] = array();
  96      }
  97  
  98  
  99      /**
 100       * Clears the Log (all or specified category).
 101       *
 102       * @param string category, use 'all' to unset all categories
 103       */
 104  	function clear( $category = NULL )
 105      {
 106          if( $category == 'all' )
 107          {
 108              $this->messages = array();
 109              $this->_count = array();
 110          }
 111          else
 112          {
 113              if( $category === NULL )
 114              {
 115                  $category = $this->defaultcategory;
 116              }
 117              unset( $this->messages[ $category ] );
 118              unset( $this->_count[$category] );
 119              unset( $this->_count['all'] );
 120          }
 121      }
 122  
 123  
 124      /**
 125       * Add a message to the Log.
 126       *
 127       * @param string the message
 128       * @param string|array the category, default is to use the object's default category.
 129       *        Can also be an array of categories to add the same message to.
 130       * @param boolean Dump (output) this directly?
 131       */
 132  	function add( $message, $category = NULL )
 133      {
 134          if( $category === NULL )
 135          { // By default, we use the default category:
 136              $category = $this->defaultcategory;
 137          }
 138  
 139          if( is_string($category) && isset($GLOBALS['debug_'.$category]) && $GLOBALS['debug_'.$category] == false )
 140          {    // We don't want to debug this category
 141              return;
 142          }
 143  
 144          if( is_array($category) )
 145          {
 146              foreach( $category as $l_cat )
 147              {
 148                  $this->add( $message, $l_cat, false );
 149              }
 150          }
 151          else
 152          {
 153              $this->messages[$category][] = $message;
 154  
 155              if( empty($this->_count[$category]) )
 156              {
 157                  $this->_count[$category] = 0;
 158              }
 159              $this->_count[$category]++;
 160          }
 161      }
 162  
 163  
 164      /**
 165       * Add an array of messages.
 166       *
 167       * @param array Array of messages where the keys are the categories and hold an array of messages.
 168       */
 169  	function add_messages( $messages )
 170      {
 171          foreach( $messages as $l_cat => $l_messages  )
 172          {
 173              foreach( $l_messages as $l_message )
 174              {
 175                  $this->add( $l_message, $l_cat );
 176              }
 177          }
 178      }
 179  
 180  
 181      /**
 182       * Get head/foot for a specific category, designed for internal use of {@link display()}
 183       *
 184       * @static
 185       * @access private
 186       *
 187       * @param mixed head or foot (array [ category => head/foot, category => 'string', 'template',
 188       *              or string [for container only])
 189       * @param string the category (or container)
 190       * @param string template, where the head/foot gets used (%s)
 191       */
 192  	function get_head_foot( $headfoot, $category, $template = NULL )
 193      {
 194          if( is_string($headfoot) && $category == 'container' )
 195          { // container head or foot
 196              $r = $headfoot;
 197          }
 198          elseif( is_array($headfoot) )
 199          { // head or foot for categories
 200              if( isset($headfoot[$category]) )
 201              {
 202                  $r = $headfoot[$category];
 203              }
 204              elseif( isset($headfoot['all']) && $category != 'container' )
 205              { // use 'all' info, except if for container
 206                  $r = $headfoot['all'];
 207              }
 208              else
 209              {
 210                  return false;
 211              }
 212  
 213              if( is_array($r) )
 214              {
 215                  if( isset($r['template']) )
 216                  {
 217                      $template = $r['template'];
 218                  }
 219                  $r = $r['string'];
 220              }
 221  
 222              // Replace '%s' with category:
 223              $r = str_replace( '%s', $category, $r );
 224          }
 225  
 226          if( empty($r) )
 227          {
 228              return false;
 229          }
 230  
 231          if( !empty($template) )
 232          {
 233              $r = sprintf( $template, $r );
 234          }
 235  
 236          return $r;
 237      }
 238  
 239  
 240      /**
 241       * Wrapper to display messages as simple paragraphs.
 242       *
 243       * @param mixed the category of messages, see {@link display()}. NULL for default category.
 244       * @param mixed the outer div, see {@link display()}
 245       * @param mixed the css class for inner paragraphs
 246       */
 247  	function display_paragraphs( $category = 'all', $outerdivclass = 'panelinfo', $cssclass = NULL )
 248      {
 249          if( is_null($cssclass) )
 250          {
 251              $cssclass = array( 'all' => array( 'divClass' => false ) );
 252          }
 253          return $this->display( '', '', true, $category, $cssclass, 'p', $outerdivclass );
 254      }
 255  
 256  
 257      /**
 258       * TEMPLATE TAG
 259       *
 260       * The purpose here is to have a tag which is simple yet flexible.
 261       * the display function is WAAAY too bloated.
 262       *
 263       * @todo optimize
 264       *
 265       * @param string HTML to display before the log when there is something to display
 266       * @param string HTML to display after the log when there is something to display
 267       * @param boolean Skip if previewing?
 268       *        TODO: dh> This appears to not display e.g. errors which got inserted?!!
 269       *                  I also don't see how this is a "simple" param (in the sense
 270       *                  of useful/required)
 271       */
 272  	function disp( $before = '<div class="action_messages">', $after = '</div>', $skip_if_preview = true )
 273      {
 274          if( count($this->messages) )
 275          {
 276              global $preview;
 277              if( $preview )
 278              {
 279                  return;
 280              }
 281  
 282              $disp = $this->display( NULL, NULL, false, 'all', NULL, NULL, NULL );
 283  
 284              if( !empty( $disp ) )
 285              {
 286                  echo $before.$disp.$after;
 287              }
 288          }
 289      }
 290  
 291  
 292      /**
 293       * Display messages of the Log object.
 294       *
 295       * - You can either output/get the messages of a category (string),
 296       *   all categories ('all') or category groups (array of strings) (defaults to 'all').
 297       * - Head/Foot will be displayed on top/bottom of the messages. You can pass
 298       *   an array as head/foot with the category as key and this will be displayed
 299       *   on top of the category's messages.
 300       * - You can choose from various styles for message groups ('ul', 'p', 'br')
 301       *   and set a css class for it (by default 'log_'.$category gets used).
 302       * - You can suppress the outer div or set a css class for it (defaults to
 303       *   'log_container').
 304       *
 305       * @todo Make this simple!
 306       * start by getting rid of the $category selection and the special cases for 'all'. If you don't want to display ALL messages,
 307       * then you should not log them in the same Log object and you should instantiate separate logs instead.
 308       *
 309       * @param string|NULL Header/title, might be array ( category => msg ),
 310       *                    'container' is then top. NULL for object's default ({@link Log::$head}.
 311       * @param string|NULL Footer, might be array ( category => msg ), 'container' is then bottom.
 312       *                    NULL for object's default ({@link Log::$foot}.
 313       * @param boolean to display or return (default: display)
 314       * @param mixed the category of messages to use (category, 'all', list of categories (array)
 315       *              or NULL for {@link $defaultcategory}).
 316       * @param string the CSS class of the messages div tag (default: 'log_'.$category)
 317       * @param string the style to use, 'ul', 'p', 'br', 'raw'
 318       *               (default: 'br' for single message, 'ul' for more)
 319       * @param mixed the outer div, may be false
 320       * @return boolean false, if no messages; else true (and outputs if $display)
 321       */
 322  	function display( $head = NULL, $foot = NULL, $display = true, $category = 'all', $cssclass = NULL, $style = NULL, $outerdivclass = 'log_container' )
 323      {
 324          if( is_null( $head ) )
 325          { // Use object default:
 326              $head = isset( $this->head ) ? $this->head : '';
 327          }
 328          if( is_null( $foot ) )
 329          { // Use object default:
 330              $foot = isset( $this->foot ) ? $this->foot : '';
 331          }
 332          if( is_null( $category ) )
 333          {
 334              $category = isset( $this, $this->defaultcategory ) ? $this->defaultcategory : 'error';
 335          }
 336  
 337          if( !$this->count( $category ) )
 338          { // no messages
 339              return false;
 340          }
 341          else
 342          {
 343              $messages = $this->get_messages( $category );
 344          }
 345  
 346          if( !is_array($cssclass) )
 347          {
 348              $cssclass = array( 'all' => array( 'class' => is_null($cssclass) ? NULL : $cssclass, 'divClass' => true ) );
 349          }
 350          elseif( !isset($cssclass['all']) )
 351          {
 352              $cssclass['all'] = array( 'class' => NULL, 'divClass' => true );
 353          }
 354  
 355  
 356          $disp = '';
 357  
 358          if( $outerdivclass )
 359          {
 360              $disp .= "\n<div class=\"$outerdivclass\">";
 361          }
 362  
 363          $disp .= Log::get_head_foot( $head, 'container', '<h2>%s</h2>' );
 364  
 365  
 366          foreach( $messages as $lcategory => $lmessages )
 367          {
 368              $lcssclass = isset($cssclass[$lcategory]) ? $cssclass[$lcategory] : $cssclass['all'];
 369              if( !isset($lcssclass['class']) || is_null($lcssclass['class']) )
 370              {
 371                  $lcssclass['class'] = 'log_'.$lcategory;
 372              }
 373              if( !isset($lcssclass['divClass']) || is_null($lcssclass['divClass']) || $lcssclass['divClass'] === true )
 374              {
 375                  $lcssclass['divClass'] = $lcssclass['class'];
 376              }
 377  
 378  
 379              $disp .= "\n";
 380              if( $lcssclass['divClass'] )
 381              {
 382                  $disp .= "\t<div class=\"{$lcssclass['divClass']}\">";
 383              }
 384  
 385              $disp .= Log::get_head_foot( $head, $lcategory, '<h3>%s</h3>' );
 386  
 387              if( $style == NULL )
 388              { // 'br' for a single message, 'ul' for more
 389                  $style = count($lmessages) == 1 ? 'br' : 'ul';
 390              }
 391  
 392              // implode messages
 393              if( $style == 'ul' )
 394              {
 395                  $disp .= "\t<ul".( $lcssclass['class'] ? " class=\"{$lcssclass['class']}\"" : '' ).'>'
 396                      .'<li>'.implode( "</li>\n<li>", $lmessages )."</li></ul>\n";
 397              }
 398              elseif( $style == 'p' )
 399              {
 400                  $disp .= "\t<p".( $lcssclass['class'] ? " class=\"{$lcssclass['class']}\"" : '' ).'>'
 401                              .implode( "</p>\n<p class=\"{$lcssclass['class']}\">", $lmessages )."</p>\n";
 402              }
 403              elseif( $style == 'raw' )
 404              {
 405                  $disp .= implode( "\n", $lmessages )."\n";
 406              }
 407              else
 408              {
 409                  $disp .= "\t".implode( "\n<br />\t", $lmessages );
 410              }
 411              $disp .= Log::get_head_foot( $foot, $lcategory, "\n<p>%s</p>" );
 412              if( $lcssclass['divClass'] )
 413              {
 414                  $disp .= "\t</div>\n";
 415              }
 416          }
 417  
 418          $disp .= Log::get_head_foot( $foot, 'container', "\n<p>%s</p>" );
 419  
 420          if( $outerdivclass )
 421          {
 422              $disp .= "</div>\n";
 423          }
 424  
 425          if( $display )
 426          {
 427              echo $disp;
 428              return true;
 429          }
 430  
 431          return $disp;
 432      }
 433  
 434  
 435      /**
 436       * Concatenates messages of a given category to a string
 437       *
 438       * @param string prefix of the string
 439       * @param string suffic of the string
 440       * @param string the category
 441       * @return string the messages, imploded. Tags stripped.
 442       */
 443  	function get_string( $head = '', $foot = '', $category = NULL, $implodeBy = ', ', $format = 'striptags' )
 444      {
 445          if( !$this->count( $category ) )
 446          {
 447              return false;
 448          }
 449  
 450          $r = '';
 451          if( '' != $head )
 452          {
 453              $r .= $head.' ';
 454          }
 455          $r .= implode( $implodeBy, $this->get_messages( $category, true ) );
 456          if( '' != $foot )
 457          {
 458              $r .= ' '.$foot;
 459          }
 460  
 461          switch( $format )
 462          {
 463              case 'xmlrpc':
 464                  $r = strip_tags( $r );    // get rid of <code>
 465                  $r = str_replace( '&lt;', '<', $r );
 466                  $r = str_replace( '&gt;', '>', $r );
 467                  $r = str_replace( '&quot;', '"', $r );
 468                  break;
 469  
 470              case 'striptags':
 471                  $r = strip_tags( $r );
 472                  break;
 473          }
 474  
 475          return $r;
 476      }
 477  
 478  
 479      /**
 480       * Counts messages of a given category
 481       *
 482       * @todo this seems a bit weird (not really relying on the cache ($_count) and unsetting 'all') -> write testcases to safely be able to change it.
 483       * @param string|array the category, NULL=default, 'all' = all
 484       * @return number of messages
 485       */
 486  	function count( $category = NULL )
 487      {
 488          if( is_null($category) )
 489          {    // use default category:
 490              $category = $this->defaultcategory;
 491          }
 492  
 493          if( is_string($category) )
 494          {
 495              if( empty( $this->_count[$category] ) )
 496              {
 497                  $this->_count[$category] = count( $this->get_messages( $category, true ) );
 498              }
 499              if( $category != 'all' )
 500              {
 501                  unset($this->_count['all']);
 502              }
 503              return $this->_count[$category];
 504          }
 505  
 506          return count( $this->get_messages( $category, true ) );
 507      }
 508  
 509  
 510      /**
 511       * Returns array of messages of a single category or group of categories.
 512       *
 513       * If the category is an array, those categories will be used (where 'all' will
 514       * be translated with the not already processed categories).
 515       * <code>get_messages( array('error', 'note', 'all') )</code> would return
 516       * 'errors', 'notes' and the remaining messages, in that order.
 517       *
 518       * @param string|array the category, NULL=default, 'all' = all
 519       * @param boolean if true will use subarrays for each category
 520       * @return array the messages, one or two dimensions (depends on second param)
 521       */
 522  	function get_messages( $category = NULL, $singleDimension = false )
 523      {
 524          $messages = array();
 525  
 526          if( is_null($category) )
 527          {
 528              $category = $this->defaultcategory;
 529          }
 530  
 531          if( $category == 'all' )
 532          {
 533              $category = array_keys( $this->messages );
 534              sort($category);
 535          }
 536          elseif( !is_array($category) )
 537          {
 538              $category = array( $category );
 539          }
 540  
 541          $categoriesDone = array();
 542  
 543          while( $lcategory = array_shift( $category ) )
 544          {
 545              if( $lcategory == 'all' )
 546              { // Put those categories in queue, which have not been processed already
 547                  $category = array_merge( array_diff( array_keys( $this->messages ), $categoriesDone ), $category );
 548                  sort($category);
 549                  continue;
 550              }
 551              if( in_array( $lcategory, $categoriesDone ) )
 552              {
 553                  continue;
 554              }
 555              $categoriesDone[] = $lcategory;
 556  
 557  
 558              if( !isset($this->messages[$lcategory][0]) )
 559              { // no messages
 560                  continue;
 561              }
 562  
 563              if( $singleDimension )
 564              {
 565                  $messages = array_merge( $messages, $this->messages[$lcategory] );
 566              }
 567              else
 568              {
 569                  $messages[$lcategory] = $this->messages[$lcategory];
 570              }
 571          }
 572          return $messages;
 573      }
 574  
 575  }
 576  
 577  
 578  /**
 579   * This is a no-operation implementation of {@link Log}.
 580   *
 581   * It just implements the used methods {@link get()} and {@link display()}.
 582   *
 583   * This is used for $Debuglog, when $debug is not enabled.
 584   *
 585   * @package evocore
 586   */
 587  class Log_noop {
 588      /**
 589       * This is a no-operation method.
 590       */
 591  	function Log_noop() {}
 592  
 593      /**
 594       * This is a no-operation method.
 595       */
 596  	function add() {}
 597  
 598      /**
 599       * This is a no-operation method.
 600       */
 601  	function add_messages() {}
 602  
 603      /**
 604       * This is a no-operation method.
 605       */
 606  	function clear() {}
 607  
 608      /**
 609       * This is a no-operation method.
 610       */
 611  	function count() {}
 612  
 613      /**
 614       * This is a no-operation method.
 615       */
 616  	function disp() {}
 617  
 618      /**
 619       * This is a no-operation method.
 620       */
 621  	function display() {}
 622  
 623      /**
 624       * This is a no-operation method.
 625       */
 626  	function display_paragraphs() {}
 627  
 628      /**
 629       * This is a no-operation method.
 630       */
 631  	function get_messages()
 632      {
 633          return array();
 634      }
 635  
 636      /**
 637       * This is a no-operation method.
 638       */
 639  	function get_string()
 640      {
 641          return '';
 642      }
 643  }
 644  
 645  ?>

title

Description

title

Description

title

Description

title

title

Body