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