[ Index ]

PHP Cross Reference of BackPress

title

Body

[close]

/includes/ -> class.bp-log.php (source)

   1  <?php
   2  
   3  
   4  /**
   5   * BackPress logging level constants
   6   */
   7  define('BP_LOG_NONE',    0);
   8  define('BP_LOG_FAIL',    1);
   9  define('BP_LOG_ERROR',   2);
  10  define('BP_LOG_WARNING', 4);
  11  define('BP_LOG_NOTICE',  8);
  12  define('BP_LOG_DEBUG',   16);
  13  
  14  /**
  15   * Combination of all errors (excluding none and debug)
  16   */
  17  define('BP_LOG_ALL', BP_LOG_FAIL + BP_LOG_ERROR + BP_LOG_WARNING + BP_LOG_NOTICE);
  18  
  19  
  20  
  21  /**
  22   * Provides easy and abstracted logging facilities
  23   *
  24   * @package BackPress
  25   */
  26  class BP_Log
  27  {
  28      /**
  29       * The logging level
  30       *
  31       * @var integer
  32       */
  33      var $level = BP_LOG_NONE;
  34  
  35      /**
  36       * The type of logging
  37       *
  38       * @var string
  39       */
  40      var $type = 'php';
  41      
  42      /**
  43       * The types of logging available
  44       *
  45       * @var array
  46       */
  47      var $types = array('php', 'file', 'display', 'console');
  48  
  49      /**
  50       * The filename of the file to log messages to when type is "file"
  51       *
  52       * @var string
  53       */
  54      var $filename = '';
  55  
  56      /**
  57       * Whether or not the javascript functions are available
  58       *
  59       * @var boolean
  60       **/
  61      var $console_javascript_loaded = false;
  62  
  63      /**
  64       * Console log messages which are queued up to be displayed on page load
  65       *
  66       * @var array
  67       **/
  68      var $console_javascript_onloads = array();
  69  
  70      /**
  71       * Initialises the logging
  72       *
  73       * @return void
  74       */
  75  	function __construct($level = false, $type = false, $filename = false)
  76      {
  77          $this->set_level($level);
  78          $this->set_type($type);
  79          $this->set_filename($filename);
  80      }
  81  
  82  	function BP_log($level = false, $type = false, $filename = false) {
  83          self::__construct($level, $type, $filename);
  84      }
  85      /**
  86       * Sets the logging level
  87       *
  88       * @return integer|boolean The old level on success or false
  89       * @uses BP_LOG_LEVEL
  90       */
  91  	function set_level($level)
  92      {
  93          $old_level = $this->level;
  94  
  95          if (is_integer($level)) {
  96              $this->level = $level;
  97          } elseif (defined('BP_LOG_LEVEL') && is_integer(BP_LOG_LEVEL)) {
  98              $this->level = BP_LOG_LEVEL;
  99          } else {
 100              return false;
 101          }
 102  
 103          return $old_level;
 104      }
 105  
 106      /**
 107       * Sets the logging type
 108       *
 109       * @return string|false The old type on success or false
 110       * @uses BP_LOG_TYPE
 111       */
 112  	function set_type($type)
 113      {
 114          $old_type = $this->type;
 115          $type = strtolower($type);
 116  
 117          if (in_array($type, $this->types)) {
 118              $this->type = $type;
 119          } elseif (defined('BP_LOG_TYPE') && in_array(BP_LOG_TYPE, $this->types)) {
 120              $this->type = BP_LOG_TYPE;
 121          } else {
 122              return false;
 123          }
 124  
 125          return $old_type;
 126      }
 127  
 128      /**
 129       * Sets the logging filename
 130       *
 131       * @return string|boolean The old filename on success or false
 132       * @uses BP_LOG_FILENAME
 133       */
 134  	function set_filename($filename)
 135      {
 136          $old_filename = $this->filename;
 137  
 138          if (is_string($filename)) {
 139              $_filename = $filename;
 140          } elseif (defined('BP_LOG_FILENAME') && is_string(BP_LOG_FILENAME)) {
 141              $_filename = BP_LOG_FILENAME;
 142          } else {
 143              return false;
 144          }
 145  
 146          if (isset($_filename) && file_exists($_filename) && is_file($_filename) && is_writable($_filename)) {
 147              $this->filename = $_filename;
 148          } else {
 149              return false;
 150          }
 151  
 152          return $old_filename;
 153      }
 154  
 155      /**
 156       * Sends a message to the log
 157       *
 158       * @return boolean True on success, false on failure
 159       */
 160  	function send($message = '', $level = BP_LOG_DEBUG, $type = false, $prefix = false)
 161      {
 162          // Make sure the level of this message is set to be logged
 163          if (($level & $this->level) === 0) {
 164              return;
 165          }
 166  
 167          // Format the message into an array of lines to be logged
 168          $lines = $this->format_message($message, $level, $prefix);
 169  
 170          // Do some validation on the type
 171          if ($type && in_array($type, $this->types)) {
 172              $_type = $type;
 173          } else {
 174              $_type = $this->type;
 175          }
 176  
 177          // Get a name for the level
 178          if ($level) {
 179              $_level = $this->get_level_from_integer($level);
 180          }
 181  
 182          // Setup strings to prepend to some of the types
 183          $prepend = $_level . ': ';
 184          if ($prefix) {
 185              $prepend .= $prefix . ': ';
 186          }
 187          $pad = str_repeat(' ', strlen($prepend) - 2) . '| ';
 188  
 189          // Switch over the four types
 190          switch ($_type) {
 191              case 'php':
 192                  $php_fail = false;
 193  
 194                  // Check that the error_log() function is available
 195                  if (function_exists('error_log') && is_callable('error_log')) {
 196                      foreach ($lines as $key => $line) {
 197                          if ($key === 0) {
 198                              $_prepend = $prepend;
 199                          } else {
 200                              $_prepend = $pad;
 201                          }
 202                          if (!error_log($_prepend . $line, 0)) {
 203                              $php_fail = true;
 204                              break;
 205                          }
 206                      }
 207                  } else {
 208                      $php_fail = true;
 209                  }
 210  
 211                  if ($php_fail) {
 212                      // The PHP error log process failed, path of least resistance is to write to display
 213                      $this->send($message, $level, 'display', $prefix);
 214                      return;
 215                  }
 216                  break;
 217  
 218              case 'file':
 219                  $file_fail = false;
 220  
 221                  // We've already done the prerequisite checks on the file by now so just write to it
 222                  if (!$file_handle = fopen($this->filename, 'a')) {
 223                      $file_fail = true;
 224                  } else {
 225                      // Prepare a string to write
 226                      $_lines = array(
 227                          '[' . date('c') . ']',
 228                          '[client ' . $_SERVER['REMOTE_ADDR'] . ']',
 229                          $prepend,
 230                          join("\n", $lines)
 231                      );
 232                  }
 233                  if (fwrite($file_handle, join(' ', $_lines) . "\n") === false) {
 234                      $file_fail = true;
 235                  }
 236                  if ($file_handle) {
 237                      fclose($file_handle);
 238                  }
 239                  if ($file_fail) {
 240                      // Writing to file failed, output to display
 241                      $this->send($message, $level, 'display', $prefix);
 242                      return;
 243                  }
 244                  break;
 245  
 246              case 'display':
 247                  $_lines = array();
 248                  foreach ($lines as $key => $line) {
 249                      if ($key === 0) {
 250                          $_lines[] = $prepend . $line;
 251                      } else {
 252                          $_lines[] = $pad . $line;
 253                      }
 254                  }
 255                  echo '<div class="bplog_message bplog_level_' . strtolower($_level) . '"><pre>' . join("\n", $_lines) . '</pre></div>' . "\n";
 256                  break;
 257  
 258              case 'console':
 259                  $_lines = array();
 260                  foreach ($lines as $key => $line) {
 261                      if ($key === 0 && $prefix) {
 262                          $_lines[] = $prefix . ': ' . $line;
 263                      } else {
 264                          $_lines[] = $line;
 265                      }
 266                  }
 267                  
 268                  $_lines = $ident . $_level . ' ~\n' . str_replace('\'', '\\\'', join('\n', $_lines));
 269                  
 270                  if (!$this->console_javascript_loaded) {
 271                      // Queue it for logging onload
 272                      $this->console_javascript_onloads[] = array('message' => $_lines, 'level' => $level, 'time' => date('c'));
 273                  } else {
 274                      // Log it now
 275                      echo '<script type="text/javascript" charset="utf-8">bp_log_add(\'' . $this->_esc_js_log( $_lines ) . '\', ' . $this->_esc_js_log( $level ) . ', \'' . $this->_esc_js_log( date('c') ) . '\');</script>' . "\n";
 276                  }
 277                  break;
 278          }
 279  
 280          return true;
 281      }
 282  
 283      /**
 284       * Gets the name of the log level from an integer
 285       *
 286       * @return string The logging level
 287       */
 288  	function get_level_from_integer($integer)
 289      {
 290          switch ($integer) {
 291              case BP_LOG_NONE:
 292                  return 'BP_LOG_NONE';
 293                  break;
 294              case BP_LOG_FAIL:
 295                  return 'BP_LOG_FAIL';
 296                  break;
 297              case BP_LOG_ERROR:
 298                  return 'BP_LOG_ERROR';
 299                  break;
 300              case BP_LOG_WARNING:
 301                  return 'BP_LOG_WARNING';
 302                  break;
 303              case BP_LOG_NOTICE:
 304                  return 'BP_LOG_NOTICE';
 305                  break;
 306              case BP_LOG_DEBUG:
 307                  return 'BP_LOG_DEBUG';
 308                  break;
 309              default:
 310                  return 'BP_LOG_UNDEFINED';
 311                  break;
 312          }
 313      }
 314  
 315      /**
 316       * Formats a message for output to a log file
 317       *
 318       * @return boolean True on success, false on failure
 319       */
 320  	function format_message($message, $level = BP_LOG_DEBUG, $prefix = false, $tabs = 0)
 321      {
 322          $lines = array();
 323          
 324          if (is_null($message)) {
 325              $lines[] = 'null (' . var_export($message, true) . ')';
 326              return $lines;
 327          }
 328          
 329          if (is_bool($message)) {
 330              $lines[] = 'bool (' . var_export($message, true) . ')';
 331              return $lines;
 332          }
 333  
 334          if (is_string($message)) {
 335              if ($level === BP_LOG_DEBUG || $message === '') {
 336                  $lines[] = 'string(' . strlen($message) . ') ("' . $message . '")';
 337              } else {
 338                  $lines[] = $message;
 339              }
 340              return $lines;
 341          }
 342  
 343          if (is_array($message) || is_object($message)) {
 344              if (is_array($message)) {
 345                  $lines[] = 'array(' . count($message) . ') (';
 346              } else {
 347                  $lines[] = 'object(' . get_class($message) . ') (';
 348              }
 349              $tabs++;
 350              foreach ($message as $key => $value) {
 351                  $array = $this->format_message($value, $level, false, $tabs);
 352                  if (is_array($array)) {
 353                      $array[0] = str_repeat('    ', $tabs) . $key . ' => ' . $array[0];
 354                      $lines = array_merge($lines, $array);
 355                  } else {
 356                      $lines[] = str_repeat('    ', $tabs) . $key . ' => ' . $array;
 357                  }
 358              }
 359              $tabs--;
 360              $lines[] = str_repeat('    ', $tabs) . ')';
 361              return $lines;
 362          }
 363  
 364          if (is_int($message)) {
 365              $lines[] = 'int (' . $message . ')';
 366              return $lines;
 367          }
 368  
 369          if (is_float($message)) {
 370              $lines[] = 'float (' . $message . ')';
 371              return $lines;
 372          }
 373  
 374          if (is_resource($message)) {
 375              $lines[] = 'resource (' . get_resource_type($message) . ')';
 376              return $lines;
 377          }
 378  
 379          $lines[] = 'unknown (' . $message . ')';
 380          return $lines;
 381      }
 382  
 383      /**
 384       * Send a debug message
 385       *
 386       * @return boolean True on success, false on failure
 387       */
 388  	function debug($message, $prefix = false)
 389      {
 390          $this->send($message, BP_LOG_DEBUG, false, $prefix);
 391      }
 392  
 393      /**
 394       * Send a notice message
 395       *
 396       * If the message is an array, then it sends each index as a separate message
 397       *
 398       * @return boolean True on success, false on failure
 399       */
 400  	function notice($message)
 401      {
 402          if (is_array($message)) {
 403              foreach ($message as $value) {
 404                  $this->send($value, BP_LOG_NOTICE);
 405              }
 406          } else {
 407              $this->send($message, BP_LOG_NOTICE);
 408          }
 409      }
 410  
 411      /**
 412       * Send a warning message
 413       *
 414       * If the message is an array, then it sends each index as a separate message
 415       *
 416       * @return boolean True on success, false on failure
 417       */
 418  	function warning($message)
 419      {
 420          if (is_array($message)) {
 421              foreach ($message as $value) {
 422                  $this->send($value, BP_LOG_WARNING);
 423              }
 424          } else {
 425              $this->send($message, BP_LOG_WARNING);
 426          }
 427      }
 428  
 429      /**
 430       * Send an error message
 431       *
 432       * If the message is an array, then it sends each index as a separate message
 433       *
 434       * @return boolean True on success, false on failure
 435       */
 436  	function error($message)
 437      {
 438          if (is_array($message)) {
 439              foreach ($message as $value) {
 440                  $this->send($value, BP_LOG_ERROR);
 441              }
 442          } else {
 443              $this->send($message, BP_LOG_ERROR);
 444          }
 445      }
 446  
 447      /**
 448       * Send an error message and die
 449       *
 450       * If the message is an array, then it sends each index as a separate message
 451       *
 452       * @return boolean True on success, false on failure
 453       */
 454  	function fail($message)
 455      {
 456          if (is_array($message)) {
 457              foreach ($message as $value) {
 458                  $this->send($value, BP_LOG_FAIL);
 459              }
 460          } else {
 461              $this->send($message, BP_LOG_FAIL);
 462          }
 463  
 464          die();
 465      }
 466  
 467      /**
 468       * Outputs javascript functions for the head of the html document
 469       *
 470       * Must be included in the head of the debug document somehow when using 'console' type.
 471       *
 472       * @return void
 473       **/
 474  	function console_javascript()
 475      {
 476          if ($this->type !== 'console') {
 477              return;
 478          }
 479  
 480          $this->console_javascript_loaded = true;
 481  ?>
 482  
 483      <script type="text/javascript" charset="utf-8">
 484          var BP_LOG_NONE    = 0;
 485          var BP_LOG_FAIL    = 1;
 486          var BP_LOG_ERROR   = 2;
 487          var BP_LOG_WARNING = 4;
 488          var BP_LOG_NOTICE  = 8;
 489          var BP_LOG_DEBUG   = 16;
 490          
 491  		function bp_log_send(message, level, time) {
 492              if (window.console) {
 493                  // Works in later Safari and Firefox with Firebug
 494                  switch (level) {
 495                      case BP_LOG_NONE:
 496                          // This shouldn't happen really
 497                          break;
 498                      case BP_LOG_FAIL:
 499                      case BP_LOG_ERROR:
 500                          window.console.error("[" + time + "] " + message);
 501                          break;
 502                      case BP_LOG_WARNING:
 503                          window.console.warn("[" + time + "] " + message);
 504                          break;
 505                      case BP_LOG_NOTICE:
 506                          window.console.info("[" + time + "] " + message);
 507                          break;
 508                      case BP_LOG_DEBUG:
 509                          window.console.log("[" + time + "] " + message);
 510                          break;
 511                      default:
 512                          break;
 513                  }
 514              }
 515          }
 516  
 517          var bp_log_queue = new Array();
 518  
 519  		function bp_log_add(message, level, time) {
 520              bp_log_queue.push(new Array(message, level, time));
 521          }
 522  
 523  		function bp_log_process() {
 524              while (item = bp_log_queue.shift()) {
 525                  bp_log_send(item[0], item[1], item[2]);
 526              }
 527          }
 528  
 529  		function bp_log_onload() {
 530  <?php
 531          foreach ($this->console_javascript_onloads as $onload) {
 532              echo "\t\t\t" . 'bp_log_send(\'' . $this->_esc_js_log( $onload['message'] ) . '\', ' . $this->_esc_js_log( $onload['level'] ) . ', \'' . $this->_esc_js_log( $onload['time'] ) . '\');' . "\n";
 533          }
 534  ?>
 535              bp_log_process();
 536          }
 537  
 538          window.onload = bp_log_onload;
 539      </script>
 540  
 541  <?php
 542      }
 543  
 544  	function _esc_js_log( $message )
 545      {
 546          return str_replace(
 547              array( '\'', "\n" ),
 548              array( '\\\'', '\n' ),
 549              $message
 550          );
 551      }
 552      
 553  } // END class BP_Log


Generated: Wed Dec 19 01:01:51 2018 Cross-referenced by PHPXref 0.7.1