<?php
/**
* Log:: driver to write messages into FirePHP console
*
* PHP versions 4 and 5
*
* @category Logging
* @package Log
* @author Laurent Laville <pear@laurent-laville.org>
* @copyright 2008 Laurent Laville
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id:$
* @link http://pear.php.net/package/Log
* @since File available since Release 1.12.0
*/
require_once 'FirePHPCore/FirePHP.class.php';
define('PEAR_LOG_FIREPHP_LOG', FirePHP::LOG);
define('PEAR_LOG_FIREPHP_INFO', FirePHP::INFO);
define('PEAR_LOG_FIREPHP_WARN', FirePHP::WARN);
define('PEAR_LOG_FIREPHP_ERROR', FirePHP::ERROR);
define('PEAR_LOG_FIREPHP_DUMP', FirePHP::DUMP);
define('PEAR_LOG_FIREPHP_TRACE', FirePHP::TRACE);
define('PEAR_LOG_FIREPHP_TABLE', FirePHP::TABLE);
define('PEAR_LOG_FIREPHP_EXCEPTION', FirePHP::EXCEPTION);
define('PEAR_LOG_FIREPHP_GROUP_START', FirePHP::GROUP_START);
define('PEAR_LOG_FIREPHP_GROUP_END', FirePHP::GROUP_END);
/**
* The Log_firephp class is a concrete implementation of the Log::
* abstract class which writes message into FirePHP console.
*
* http://www.firephp.org/
*
* @category Logging
* @package Log
* @author Laurent Laville <pear@laurent-laville.org>
* @copyright 2008 Laurent Laville
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.12.0
* @link http://pear.php.net/package/Log
* @since File available since Release 1.12.0
*/
class Log_firephp extends Log
{
/**
* String containing the format of a log line.
* @var string
* @access private
*/
var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
/**
* String containing the timestamp format. It will be passed directly to
* strftime(). Note that the timestamp string will generated using the
* current locale.
*
* Note! Default lineFormat of this driver does not display time.
*
* @var string
* @access private
*/
var $_timeFormat = '%b %d %H:%M:%S';
/**
* Options for the FireCorePHP library
*
* @var array
*/
var $_options = array();
/**
* Constructs a new Log_firephp object.
*
* @param string $name Ignored.
* @param string $ident The identity string.
* @param array $conf The configuration array.
* @param int $level Log messages up to and including this level.
*
* @access public
*/
function Log_firephp($name = '', $ident = 'PHP', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (!empty($conf['lineFormat'])) {
$this->_lineFormat = str_replace(array_keys($this->_formatMap),
array_values($this->_formatMap),
$conf['lineFormat']);
}
if (!empty($conf['timeFormat'])) {
$this->_timeFormat = $conf['timeFormat'];
}
$options = array();
if (isset($conf['maxObjectDepth'])) {
$options['maxObjectDepth'] = $conf['maxObjectDepth'];
}
if (isset($conf['maxArrayDepth'])) {
$options['maxArrayDepth'] = $conf['maxArrayDepth'];
}
if (isset($conf['useNativeJsonEncode'])) {
$options['useNativeJsonEncode'] = $conf['useNativeJsonEncode'];
}
if (isset($conf['includeLineNumbers'])) {
$options['includeLineNumbers'] = $conf['includeLineNumbers'];
}
// default FireCorePHP options
// @todo replace when a public getOptions() method will be available
$this->_options = array('maxObjectDepth' => 10,
'maxArrayDepth' => 20,
'useNativeJsonEncode' => true,
'includeLineNumbers' => true);
$this->_options = array_merge($this->_options, $options);
}
/**
* Writes $message to firephp console. Also, passes the message
* along to any Log_observer instances that are observing this Log.
*
* @param mixed $message String or object containing the message to log.
* @param string $priority The priority of the message. Valid values are:
* PEAR_LOG_EMERG, PEAR_LOG_ALERT,
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
*
* @return boolean True on success or false on failure.
* @access public
*/
function log($message, $priority = null)
{
/* If a priority hasn't been specified, use the default value. */
if ($priority === null) {
$priority = $this->_priority;
}
/* Abort early if the priority is above the maximum logging level. */
if (!$this->_isMasked($priority)) {
return false;
}
/* Extract valid FirePHP components from $message parameter */
if (is_array($message)) {
if (isset($message['type'])) {
$type = $message['type'];
} else {
$type = null;
}
if (isset($message['message'])) {
$object = $message['message'];
} else {
if ($type == PEAR_LOG_FIREPHP_LOG
|| $type == PEAR_LOG_FIREPHP_INFO
|| $type == PEAR_LOG_FIREPHP_WARN
|| $type == PEAR_LOG_FIREPHP_ERROR
|| $type == PEAR_LOG_FIREPHP_DUMP
|| $type == PEAR_LOG_FIREPHP_TABLE
) {
/* "object" is mandatory for these FirePHP levels :
log, info, warn, error, dump, table */
return false;
}
$object = null;
}
if (isset($message['label'])) {
$label = $message['label'];
} else {
if ($type == PEAR_LOG_FIREPHP_TRACE) {
/* "label" is mandatory for FirePHP trace level */
return false;
}
$label = null;
}
} elseif (is_scalar($message)) {
$object = $message;
$label = null;
$type = PEAR_LOG_FIREPHP_LOG;
} elseif ($message instanceof Exception) {
$object = $message;
$label = null;
$type = PEAR_LOG_FIREPHP_EXCEPTION;
} else {
// $message parameter should be either :
// an array with key-values (object, label, type) or a PHP Exception
return false;
}
if (!is_null($label)) {
/* Build the string containing the complete log line. */
$label = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$priority,
$label);
} elseif (!is_null($object) && is_string($object)) {
/* Extract the string representation of the message. */
$msg = $this->_extractMessage($object);
/* normalize line breaks */
$msg = str_replace("\r\n", "\n", $msg);
/* escape line breaks */
$msg = str_replace("\n", "\\n\\\n", $msg);
/* escape quotes */
$msg = str_replace('"', '\\"', $msg);
/* Build the string containing the complete log line. */
$object = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$priority,
$msg);
}
$firephp = FirePHP::getInstance(true);
$firephp->setOptions($this->_options);
switch ($type) {
case PEAR_LOG_FIREPHP_LOG :
case PEAR_LOG_FIREPHP_INFO :
case PEAR_LOG_FIREPHP_WARN :
case PEAR_LOG_FIREPHP_ERROR :
case PEAR_LOG_FIREPHP_DUMP :
case PEAR_LOG_FIREPHP_TABLE :
$firephp->fb($object, $label, $type);
break;
case PEAR_LOG_FIREPHP_TRACE :
$firephp->fb($label, $type);
break;
case PEAR_LOG_FIREPHP_EXCEPTION :
$firephp->fb($object);
break;
case PEAR_LOG_FIREPHP_GROUP_START :
$firephp->group($label);
break;
case PEAR_LOG_FIREPHP_GROUP_END :
$firephp->groupEnd();
break;
default :
$firephp->fb($object, $label, PEAR_LOG_FIREPHP_LOG);
}
if ($type == PEAR_LOG_FIREPHP_GROUP_START
|| $type == PEAR_LOG_FIREPHP_GROUP_END) {
// do not inform other observers about a group open/close message
} else {
/* Notify observers about this log message. */
$this->_announce(array('priority' => $priority, 'message' => $message));
}
return true;
}
/**
* A convenience function for logging an info FirePHP event. It will log a
* message at the PEAR_LOG_INFO log level.
*
* @param mixed $message String or object containing the message to log.
*
* @return boolean True if the message was successfully logged.
*
* @access public
*/
function info($message)
{
if (is_array($message) && !isset($message['type'])) {
$message['type'] = PEAR_LOG_FIREPHP_INFO;
}
return $this->log($message, PEAR_LOG_INFO);
}
/**
* A convenience function for logging a warning FirePHP event. It will log a
* message at the PEAR_LOG_WARNING log level.
*
* @param mixed $message String or object containing the message to log.
*
* @return boolean True if the message was successfully logged.
*
* @access public
*/
function warning($message)
{
if (is_array($message) && !isset($message['type'])) {
$message['type'] = PEAR_LOG_FIREPHP_WARN;
}
return $this->log($message, PEAR_LOG_WARNING);
}
/**
* A convenience function for logging an error FirePHP event. It will log a
* message at the PEAR_LOG_ERR log level.
*
* @param mixed $message String or object containing the message to log.
*
* @return boolean True if the message was successfully logged.
*
* @access public
*/
function err($message)
{
if (is_array($message) && !isset($message['type'])) {
$message['type'] = PEAR_LOG_FIREPHP_ERROR;
}
return $this->log($message, PEAR_LOG_ERR);
}
/**
* A convenience function for logging a dump FirePHP event. It will log a
* message at the PEAR_LOG_DEBUG log level.
*
* @param mixed $message String or object containing the message to log.
*
* @return boolean True if the message was successfully logged.
*
* @access public
*/
function dump($message)
{
if (is_array($message) && !isset($message['type'])) {
$message['type'] = PEAR_LOG_FIREPHP_DUMP;
}
return $this->log($message, PEAR_LOG_DEBUG);
}
/**
* A convenience function for logging a trace FirePHP event. It will log a
* message at the PEAR_LOG_DEBUG log level.
*
* @param mixed $message String or object containing the message to log.
*
* @return boolean True if the message was successfully logged.
*
* @access public
*/
function trace($message)
{
if (is_array($message) && !isset($message['type'])) {
$message['type'] = PEAR_LOG_FIREPHP_TRACE;
}
return $this->log($message, PEAR_LOG_DEBUG);
}
/**
* A convenience function for logging a table FirePHP event. It will log a
* message at the PEAR_LOG_DEBUG log level (by default).
*
* @param mixed $message String or object containing the message to log.
* @param string $priority The priority of the message. Valid values are:
* PEAR_LOG_EMERG, PEAR_LOG_ALERT,
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
*
* @return boolean True if the message was successfully logged.
*
* @access public
*/
function table($message, $priority = PEAR_LOG_DEBUG)
{
if (is_array($message) && !isset($message['type'])) {
$message['type'] = PEAR_LOG_FIREPHP_TABLE;
}
return $this->log($message, $priority);
}
/**
* Register FirePHP driver as your error handler
*
* @return mixed Returns a string containing the previously defined error handler
* (if any), or NULL on error. If the previous handler was
* a class method, this function will return an indexed array
* with the class and the method name.
* @access public
*/
function registerErrorHandler()
{
return set_error_handler(array($this, 'errorHandler'));
}
/**
* FirePHP's error handler
*
* Throws exception for each php error that will occur.
*
* @param int $errno contains the level of the error raised
* @param string $errstr contains the error message
* @param string $errfile contains the filename that the error was raised in
* @param int $errline contains the line number the error was raised at
* @param array $errcontext contain an array of every variable that existed
* in the scope the error was triggered in
*
* @return void
* @access public
*/
function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
{
// Don't throw exception if error reporting is switched off
if (error_reporting() == 0) {
return;
}
// Only catch for errors we are asking for
if (error_reporting() & $errno) {
/* Map the PHP error to a Log priority. */
switch ($errno) {
case E_WARNING:
case E_USER_WARNING:
$priority = PEAR_LOG_WARNING;
$type = PEAR_LOG_FIREPHP_WARN;
break;
case E_NOTICE:
case E_USER_NOTICE:
$priority = PEAR_LOG_NOTICE;
$type = PEAR_LOG_FIREPHP_WARN;
break;
case E_ERROR:
case E_USER_ERROR:
$priority = PEAR_LOG_ERR;
$type = PEAR_LOG_FIREPHP_ERROR;
break;
default:
$priority = PEAR_LOG_INFO;
$type = PEAR_LOG_FIREPHP_INFO;
}
$this->log(array('message' => $errstr
. ' in ' . $errfile
. ' at line ' . $errline,
'type' => $type), $priority);
}
}
/**
* Register FirePHP as your exception handler
*
* @return string|null Returns the name of the previously defined
* exception handler, or NULL on error. If no previous
* handler was defined, NULL is also returned.
* @access public
*/
function registerExceptionHandler()
{
return set_exception_handler(array($this, 'exceptionHandler'));
}
/**
* FirePHP's exception handler
*
* Logs all exceptions to your firebug console.
*
* @param exception $exception contains the exception raised
*
* @return void
* @access public
*/
function exceptionHandler($exception)
{
$this->log($exception, PEAR_LOG_ALERT);
}
/**
* Register FirePHP driver as your assert callback
*
* @return mixed Returns the original setting or FALSE on errors
* @access public
*/
function registerAssertionHandler()
{
return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler'));
}
/**
* FirePHP's assertion handler
*
* Logs all assertions to your firebug console and then stops the script.
*
* @param string $file File source of assertion
* @param int $line Line source of assertion
* @param mixed $code Assertion code
*
* @return void
* @access public
*/
function assertionHandler($file, $line, $code)
{
$this->log(array('message' => 'Assertion Failed: '. $code
. ' in ' . $file
. ' at line ' . $line,
'type' => PEAR_LOG_FIREPHP_ERROR), PEAR_LOG_ERR);
}
}
?>