First commit

This commit is contained in:
Theodotos Andreou 2018-01-14 13:10:16 +00:00
commit c6e2478c40
13918 changed files with 2303184 additions and 0 deletions

View file

@ -0,0 +1,231 @@
<?php
/**
* $Header$
* $Horde: horde/lib/Log/composite.php,v 1.2 2000/06/28 21:36:13 jon Exp $
*
* @version $Revision: 215528 $
* @package Log
*/
/**
* The Log_composite:: class implements a Composite pattern which
* allows multiple Log implementations to receive the same events.
*
* @author Chuck Hagenbuch <chuck@horde.org>
* @author Jon Parise <jon@php.net>
*
* @since Horde 1.3
* @since Log 1.0
* @package Log
*
* @example composite.php Using the composite handler.
*/
class Log_composite extends Log
{
/**
* Array holding all of the Log instances to which log events should be
* sent.
*
* @var array
* @access private
*/
var $_children = array();
/**
* Constructs a new composite Log object.
*
* @param boolean $name This parameter is ignored.
* @param boolean $ident This parameter is ignored.
* @param boolean $conf This parameter is ignored.
* @param boolean $level This parameter is ignored.
*
* @access public
*/
function __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_ident = $ident;
}
/**
* Opens all of the child instances.
*
* @return True if all of the child instances were successfully opened.
*
* @access public
*/
function open()
{
/* Attempt to open each of our children. */
$this->_opened = true;
foreach ($this->_children as $id => $child) {
$this->_opened &= $this->_children[$id]->open();
}
/* If all children were opened, return success. */
return $this->_opened;
}
/**
* Closes all of the child instances.
*
* @return True if all of the child instances were successfully closed.
*
* @access public
*/
function close()
{
/* Attempt to close each of our children. */
$closed = true;
foreach ($this->_children as $id => $child) {
$closed &= $this->_children[$id]->close();
}
/* Track the _opened state for consistency. */
$this->_opened = false;
/* If all children were closed, return success. */
return $closed;
}
/**
* Flushes all child instances. It is assumed that all of the children
* have been successfully opened.
*
* @return True if all of the child instances were successfully flushed.
*
* @access public
* @since Log 1.8.2
*/
function flush()
{
/* Attempt to flush each of our children. */
$flushed = true;
foreach ($this->_children as $id => $child) {
$flushed &= $this->_children[$id]->flush();
}
/* If all children were flushed, return success. */
return $flushed;
}
/**
* Sends $message and $priority to each child of this composite. If the
* children aren't already open, they will be opened here.
*
* @param mixed $message String or object containing the message
* to log.
* @param string $priority (optional) 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 entry is successfully logged.
*
* @access public
*/
function log($message, $priority = null)
{
/* If a priority hasn't been specified, use the default value. */
if ($priority === null) {
$priority = $this->_priority;
}
/*
* If the handlers haven't been opened, attempt to open them now.
* However, we don't treat failure to open all of the handlers as a
* fatal error. We defer that consideration to the success of calling
* each handler's log() method below.
*/
if (!$this->_opened) {
$this->open();
}
/* Attempt to log the event using each of the children. */
$success = true;
foreach ($this->_children as $id => $child) {
$success &= $this->_children[$id]->log($message, $priority);
}
$this->_announce(array('priority' => $priority, 'message' => $message));
/* Return success if all of the children logged the event. */
return $success;
}
/**
* Returns true if this is a composite.
*
* @return boolean True if this is a composite class.
*
* @access public
*/
function isComposite()
{
return true;
}
/**
* Sets this identification string for all of this composite's children.
*
* @param string $ident The new identification string.
*
* @access public
* @since Log 1.6.7
*/
function setIdent($ident)
{
/* Call our base class's setIdent() method. */
parent::setIdent($ident);
/* ... and then call setIdent() on all of our children. */
foreach ($this->_children as $id => $child) {
$this->_children[$id]->setIdent($ident);
}
}
/**
* Adds a Log instance to the list of children.
*
* @param object $child The Log instance to add.
*
* @return boolean True if the Log instance was successfully added.
*
* @access public
*/
function addChild(&$child)
{
/* Make sure this is a Log instance. */
if (!is_a($child, 'Log')) {
return false;
}
$this->_children[$child->_id] = &$child;
return true;
}
/**
* Removes a Log instance from the list of children.
*
* @param object $child The Log instance to remove.
*
* @return boolean True if the Log instance was successfully removed.
*
* @access public
*/
function removeChild($child)
{
if (!is_a($child, 'Log') || !isset($this->_children[$child->_id])) {
return false;
}
unset($this->_children[$child->_id]);
return true;
}
}

View file

@ -0,0 +1,208 @@
<?php
/**
* $Header$
*
* @version $Revision: 224513 $
* @package Log
*/
/**
* The Log_console class is a concrete implementation of the Log::
* abstract class which writes message to the text console.
*
* @author Jon Parise <jon@php.net>
* @since Log 1.1
* @package Log
*
* @example console.php Using the console handler.
*/
class Log_console extends Log
{
/**
* Handle to the current output stream.
* @var resource
* @access private
*/
var $_stream = STDOUT;
/**
* Should the output be buffered or displayed immediately?
* @var string
* @access private
*/
var $_buffering = false;
/**
* String holding the buffered output.
* @var string
* @access private
*/
var $_buffer = '';
/**
* 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.
* @var string
* @access private
*/
var $_timeFormat = '%b %d %H:%M:%S';
/**
* Constructs a new Log_console 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 __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (!empty($conf['stream'])) {
$this->_stream = $conf['stream'];
}
if (isset($conf['buffering'])) {
$this->_buffering = $conf['buffering'];
}
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'];
}
/*
* If output buffering has been requested, we need to register a
* shutdown function that will dump the buffer upon termination.
*/
if ($this->_buffering) {
register_shutdown_function(array(&$this, '_Log_console'));
}
}
/**
* Destructor
*/
function _Log_console()
{
$this->close();
}
/**
* Open the output stream.
*
* @access public
* @since Log 1.9.7
*/
function open()
{
$this->_opened = true;
return true;
}
/**
* Closes the output stream.
*
* This results in a call to flush().
*
* @access public
* @since Log 1.9.0
*/
function close()
{
$this->flush();
$this->_opened = false;
return true;
}
/**
* Flushes all pending ("buffered") data to the output stream.
*
* @access public
* @since Log 1.8.2
*/
function flush()
{
/*
* If output buffering is enabled, dump the contents of the buffer to
* the output stream.
*/
if ($this->_buffering && (strlen($this->_buffer) > 0)) {
fwrite($this->_stream, $this->_buffer);
$this->_buffer = '';
}
if (is_resource($this->_stream)) {
return fflush($this->_stream);
}
return false;
}
/**
* Writes $message to the text 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 the string representation of the message. */
$message = $this->_extractMessage($message);
/* Build the string containing the complete log line. */
$line = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$priority, $message) . "\n";
/*
* If buffering is enabled, append this line to the output buffer.
* Otherwise, print the line to the output stream immediately.
*/
if ($this->_buffering) {
$this->_buffer .= $line;
} else {
fwrite($this->_stream, $line);
}
/* Notify observers about this log message. */
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
}

View file

@ -0,0 +1,235 @@
<?php
/**
* $Header$
*
* @version $Revision: 250926 $
* @package Log
*/
/**
* The Log_daemon class is a concrete implementation of the Log::
* abstract class which sends messages to syslog daemon on UNIX-like machines.
* This class uses the syslog protocol: http://www.ietf.org/rfc/rfc3164.txt
*
* @author Bart van der Schans <schans@dds.nl>
* @version $Revision: 250926 $
* @package Log
*/
class Log_daemon extends Log
{
/**
* Integer holding the log facility to use.
* @var string
*/
var $_name = LOG_DAEMON;
/**
* Var holding the resource pointer to the socket
* @var resource
*/
var $_socket;
/**
* The ip address or servername
* @see http://www.php.net/manual/en/transports.php
* @var string
*/
var $_ip = '127.0.0.1';
/**
* Protocol to use (tcp, udp, etc.)
* @see http://www.php.net/manual/en/transports.php
* @var string
*/
var $_proto = 'udp';
/**
* Port to connect to
* @var int
*/
var $_port = 514;
/**
* Maximum message length in bytes
* @var int
*/
var $_maxsize = 4096;
/**
* Socket timeout in seconds
* @var int
*/
var $_timeout = 1;
/**
* Constructs a new syslog object.
*
* @param string $name The syslog facility.
* @param string $ident The identity string.
* @param array $conf The configuration array.
* @param int $maxLevel Maximum level at which to log.
* @access public
*/
function __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
/* Ensure we have a valid integer value for $name. */
if (empty($name) || !is_int($name)) {
$name = LOG_SYSLOG;
}
$this->_id = md5(microtime());
$this->_name = $name;
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (isset($conf['ip'])) {
$this->_ip = $conf['ip'];
}
if (isset($conf['proto'])) {
$this->_proto = $conf['proto'];
}
if (isset($conf['port'])) {
$this->_port = $conf['port'];
}
if (isset($conf['maxsize'])) {
$this->_maxsize = $conf['maxsize'];
}
if (isset($conf['timeout'])) {
$this->_timeout = $conf['timeout'];
}
$this->_proto = $this->_proto . '://';
register_shutdown_function(array(&$this, '_Log_daemon'));
}
/**
* Destructor.
*
* @access private
*/
function _Log_daemon()
{
$this->close();
}
/**
* Opens a connection to the system logger, if it has not already
* been opened. This is implicitly called by log(), if necessary.
* @access public
*/
function open()
{
if (!$this->_opened) {
$this->_opened = (bool)($this->_socket = @fsockopen(
$this->_proto . $this->_ip,
$this->_port,
$errno,
$errstr,
$this->_timeout));
}
return $this->_opened;
}
/**
* Closes the connection to the system logger, if it is open.
* @access public
*/
function close()
{
if ($this->_opened) {
$this->_opened = false;
return fclose($this->_socket);
}
return true;
}
/**
* Sends $message to the currently open syslog connection. Calls
* open() if necessary. Also passes the message along to any Log_observer
* instances that are observing this Log.
*
* @param string $message The textual message to be logged.
* @param int $priority (optional) The priority of the message. Valid
* values are: LOG_EMERG, LOG_ALERT, LOG_CRIT,
* LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO,
* and LOG_DEBUG. The default is LOG_INFO.
* @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;
}
/* If the connection isn't open and can't be opened, return failure. */
if (!$this->_opened && !$this->open()) {
return false;
}
/* Extract the string representation of the message. */
$message = $this->_extractMessage($message);
/* Set the facility level. */
$facility_level = intval($this->_name) +
intval($this->_toSyslog($priority));
/* Prepend ident info. */
if (!empty($this->_ident)) {
$message = $this->_ident . ' ' . $message;
}
/* Check for message length. */
if (strlen($message) > $this->_maxsize) {
$message = substr($message, 0, ($this->_maxsize) - 10) . ' [...]';
}
/* Write to socket. */
fwrite($this->_socket, '<' . $facility_level . '>' . $message . "\n");
$this->_announce(array('priority' => $priority, 'message' => $message));
}
/**
* Converts a PEAR_LOG_* constant into a syslog LOG_* constant.
*
* This function exists because, under Windows, not all of the LOG_*
* constants have unique values. Instead, the PEAR_LOG_* were introduced
* for global use, with the conversion to the LOG_* constants kept local to
* to the syslog driver.
*
* @param int $priority PEAR_LOG_* value to convert to LOG_* value.
*
* @return The LOG_* representation of $priority.
*
* @access private
*/
function _toSyslog($priority)
{
static $priorities = array(
PEAR_LOG_EMERG => LOG_EMERG,
PEAR_LOG_ALERT => LOG_ALERT,
PEAR_LOG_CRIT => LOG_CRIT,
PEAR_LOG_ERR => LOG_ERR,
PEAR_LOG_WARNING => LOG_WARNING,
PEAR_LOG_NOTICE => LOG_NOTICE,
PEAR_LOG_INFO => LOG_INFO,
PEAR_LOG_DEBUG => LOG_DEBUG
);
/* If we're passed an unknown priority, default to LOG_INFO. */
if (!is_int($priority) || !in_array($priority, $priorities)) {
return LOG_INFO;
}
return $priorities[$priority];
}
}

View file

@ -0,0 +1,161 @@
<?php
/**
* $Header$
*
* @version $Revision: 255603 $
* @package Log
*/
/**
* The Log_display class is a concrete implementation of the Log::
* abstract class which writes message into browser in usual PHP maner.
* This may be useful because when you use PEAR::setErrorHandling in
* PEAR_ERROR_CALLBACK mode error messages are not displayed by
* PHP error handler.
*
* @author Paul Yanchenko <pusher@inaco.ru>
* @since Log 1.8.0
* @package Log
*
* @example display.php Using the display handler.
*/
class Log_display extends Log
{
/**
* String containing the format of a log line.
* @var string
* @access private
*/
var $_lineFormat = '<b>%3$s</b>: %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.
* @var string
* @access private
*/
var $_timeFormat = '%b %d %H:%M:%S';
/**
* Constructs a new Log_display 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 __construct($name = '', $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
/* Start by configuring the line format. */
if (!empty($conf['lineFormat'])) {
$this->_lineFormat = str_replace(array_keys($this->_formatMap),
array_values($this->_formatMap),
$conf['lineFormat']);
}
/* We may need to prepend a string to our line format. */
$prepend = null;
if (isset($conf['error_prepend'])) {
$prepend = $conf['error_prepend'];
} else {
$prepend = ini_get('error_prepend_string');
}
if (!empty($prepend)) {
$this->_lineFormat = $prepend . $this->_lineFormat;
}
/* We may also need to append a string to our line format. */
$append = null;
if (isset($conf['error_append'])) {
$append = $conf['error_append'];
} else {
$append = ini_get('error_append_string');
}
if (!empty($append)) {
$this->_lineFormat .= $append;
}
/* Lastly, the line ending sequence is also configurable. */
if (isset($conf['linebreak'])) {
$this->_lineFormat .= $conf['linebreak'];
} else {
$this->_lineFormat .= "<br />\n";
}
/* The user can also change the time format. */
if (!empty($conf['timeFormat'])) {
$this->_timeFormat = $conf['timeFormat'];
}
}
/**
* Opens the display handler.
*
* @access public
* @since Log 1.9.6
*/
function open()
{
$this->_opened = true;
return true;
}
/**
* Closes the display handler.
*
* @access public
* @since Log 1.9.6
*/
function close()
{
$this->_opened = false;
return true;
}
/**
* Writes $message to the text browser. 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 the string representation of the message. */
$message = $this->_extractMessage($message);
/* Build and output the complete log line. */
echo $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$priority,
nl2br(htmlspecialchars($message)));
/* Notify observers about this log message. */
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
}

View file

@ -0,0 +1,160 @@
<?php
/**
* $Header$
*
* @version $Revision: 266582 $
* @package Log
*/
/**
* The Log_error_log class is a concrete implementation of the Log abstract
* class that logs messages using PHP's error_log() function.
*
* @author Jon Parise <jon@php.net>
* @since Log 1.7.0
* @package Log
*
* @example error_log.php Using the error_log handler.
*/
class Log_error_log extends Log
{
/**
* The error_log() log type.
* @var integer
* @access private
*/
var $_type = PEAR_LOG_TYPE_SYSTEM;
/**
* The type-specific destination value.
* @var string
* @access private
*/
var $_destination = '';
/**
* Additional headers to pass to the mail() function when the
* PEAR_LOG_TYPE_MAIL type is used.
* @var string
* @access private
*/
var $_extra_headers = '';
/**
* String containing the format of a log line.
* @var string
* @access private
*/
var $_lineFormat = '%2$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.
* @var string
* @access private
*/
var $_timeFormat = '%b %d %H:%M:%S';
/**
* Constructs a new Log_error_log 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 __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_type = $name;
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (!empty($conf['destination'])) {
$this->_destination = $conf['destination'];
}
if (!empty($conf['extra_headers'])) {
$this->_extra_headers = $conf['extra_headers'];
}
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'];
}
}
/**
* Opens the handler.
*
* @access public
* @since Log 1.9.6
*/
function open()
{
$this->_opened = true;
return true;
}
/**
* Closes the handler.
*
* @access public
* @since Log 1.9.6
*/
function close()
{
$this->_opened = false;
return true;
}
/**
* Logs $message using PHP's error_log() function. The message is also
* passed 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 the string representation of the message. */
$message = $this->_extractMessage($message);
/* Build the string containing the complete log line. */
$line = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$priority, $message);
/* Pass the log line and parameters to the error_log() function. */
$success = error_log($line, $this->_type, $this->_destination,
$this->_extra_headers);
$this->_announce(array('priority' => $priority, 'message' => $message));
return $success;
}
}

View file

@ -0,0 +1,316 @@
<?php
/**
* $Header$
*
* @version $Revision: 224513 $
* @package Log
*/
/**
* The Log_file class is a concrete implementation of the Log abstract
* class that logs messages to a text file.
*
* @author Jon Parise <jon@php.net>
* @author Roman Neuhauser <neuhauser@bellavista.cz>
* @since Log 1.0
* @package Log
*
* @example file.php Using the file handler.
*/
class Log_file extends Log
{
/**
* String containing the name of the log file.
* @var string
* @access private
*/
var $_filename = 'php.log';
/**
* Handle to the log file.
* @var resource
* @access private
*/
var $_fp = false;
/**
* Should new log entries be append to an existing log file, or should the
* a new log file overwrite an existing one?
* @var boolean
* @access private
*/
var $_append = true;
/**
* Should advisory file locking (i.e., flock()) be used?
* @var boolean
* @access private
*/
var $_locking = false;
/**
* Integer (in octal) containing the log file's permissions mode.
* @var integer
* @access private
*/
var $_mode = 0644;
/**
* Integer (in octal) specifying the file permission mode that will be
* used when creating directories that do not already exist.
* @var integer
* @access private
*/
var $_dirmode = 0755;
/**
* 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.
* @var string
* @access private
*/
var $_timeFormat = '%b %d %H:%M:%S';
/**
* String containing the end-on-line character sequence.
* @var string
* @access private
*/
var $_eol = "\n";
/**
* Constructs a new Log_file 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 __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_filename = $name;
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (isset($conf['append'])) {
$this->_append = $conf['append'];
}
if (isset($conf['locking'])) {
$this->_locking = $conf['locking'];
}
if (!empty($conf['mode'])) {
if (is_string($conf['mode'])) {
$this->_mode = octdec($conf['mode']);
} else {
$this->_mode = $conf['mode'];
}
}
if (!empty($conf['dirmode'])) {
if (is_string($conf['dirmode'])) {
$this->_dirmode = octdec($conf['dirmode']);
} else {
$this->_dirmode = $conf['dirmode'];
}
}
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'];
}
if (!empty($conf['eol'])) {
$this->_eol = $conf['eol'];
} else {
$this->_eol = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n";
}
register_shutdown_function(array(&$this, '_Log_file'));
}
/**
* Destructor
*/
function _Log_file()
{
if ($this->_opened) {
$this->close();
}
}
/**
* Creates the given directory path. If the parent directories don't
* already exist, they will be created, too.
*
* This implementation is inspired by Python's os.makedirs function.
*
* @param string $path The full directory path to create.
* @param integer $mode The permissions mode with which the
* directories will be created.
*
* @return True if the full path is successfully created or already
* exists.
*
* @access private
*/
function _mkpath($path, $mode = 0700)
{
/* Separate the last pathname component from the rest of the path. */
$head = dirname($path);
$tail = basename($path);
/* Make sure we've split the path into two complete components. */
if (empty($tail)) {
$head = dirname($path);
$tail = basename($path);
}
/* Recurse up the path if our current segment does not exist. */
if (!empty($head) && !empty($tail) && !is_dir($head)) {
$this->_mkpath($head, $mode);
}
/* Create this segment of the path. */
return @mkdir($head, $mode);
}
/**
* Opens the log file for output. If the specified log file does not
* already exist, it will be created. By default, new log entries are
* appended to the end of the log file.
*
* This is implicitly called by log(), if necessary.
*
* @access public
*/
function open()
{
if (!$this->_opened) {
/* If the log file's directory doesn't exist, create it. */
if (!is_dir(dirname($this->_filename))) {
$this->_mkpath($this->_filename, $this->_dirmode);
}
/* Determine whether the log file needs to be created. */
$creating = !file_exists($this->_filename);
/* Obtain a handle to the log file. */
$this->_fp = fopen($this->_filename, ($this->_append) ? 'a' : 'w');
/* We consider the file "opened" if we have a valid file pointer. */
$this->_opened = ($this->_fp !== false);
/* Attempt to set the file's permissions if we just created it. */
if ($creating && $this->_opened) {
chmod($this->_filename, $this->_mode);
}
}
return $this->_opened;
}
/**
* Closes the log file if it is open.
*
* @access public
*/
function close()
{
/* If the log file is open, close it. */
if ($this->_opened && fclose($this->_fp)) {
$this->_opened = false;
}
return ($this->_opened === false);
}
/**
* Flushes all pending data to the file handle.
*
* @access public
* @since Log 1.8.2
*/
function flush()
{
if (is_resource($this->_fp)) {
return fflush($this->_fp);
}
return false;
}
/**
* Logs $message to the output window. The message is also passed 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;
}
/* If the log file isn't already open, open it now. */
if (!$this->_opened && !$this->open()) {
return false;
}
/* Extract the string representation of the message. */
$message = $this->_extractMessage($message);
/* Build the string containing the complete log line. */
$line = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$priority, $message) . $this->_eol;
/* If locking is enabled, acquire an exclusive lock on the file. */
if ($this->_locking) {
flock($this->_fp, LOCK_EX);
}
/* Write the log line to the log file. */
$success = (fwrite($this->_fp, $line) !== false);
/* Unlock the file now that we're finished writing to it. */
if ($this->_locking) {
flock($this->_fp, LOCK_UN);
}
/* Notify observers about this log message. */
$this->_announce(array('priority' => $priority, 'message' => $message));
return $success;
}
}

View file

@ -0,0 +1,214 @@
<?php
/**
* $Header$
*
* @version $Revision: 250923 $
* @package Log
*/
/**
* The Log_firebug class is a concrete implementation of the Log::
* abstract class which writes message into Firebug console.
*
* http://www.getfirebug.com/
*
* @author Mika Tuupola <tuupola@appelsiini.net>
* @since Log 1.9.11
* @package Log
*
* @example firebug.php Using the firebug handler.
*/
class Log_firebug extends Log
{
/**
* Should the output be buffered or displayed immediately?
* @var string
* @access private
*/
var $_buffering = false;
/**
* String holding the buffered output.
* @var string
* @access private
*/
var $_buffer = array();
/**
* String containing the format of a log line.
* @var string
* @access private
*/
var $_lineFormat = '%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';
/**
* Mapping of log priorities to Firebug methods.
* @var array
* @access private
*/
var $_methods = array(
PEAR_LOG_EMERG => 'error',
PEAR_LOG_ALERT => 'error',
PEAR_LOG_CRIT => 'error',
PEAR_LOG_ERR => 'error',
PEAR_LOG_WARNING => 'warn',
PEAR_LOG_NOTICE => 'info',
PEAR_LOG_INFO => 'info',
PEAR_LOG_DEBUG => 'debug'
);
/**
* Constructs a new Log_firebug 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 __construct($name = '', $ident = 'PHP', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (isset($conf['buffering'])) {
$this->_buffering = $conf['buffering'];
}
if ($this->_buffering) {
register_shutdown_function(array(&$this, '_Log_firebug'));
}
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'];
}
}
/**
* Opens the firebug handler.
*
* @access public
*/
function open()
{
$this->_opened = true;
return true;
}
/**
* Destructor
*/
function _Log_firebug()
{
$this->close();
}
/**
* Closes the firebug handler.
*
* @access public
*/
function close()
{
$this->flush();
$this->_opened = false;
return true;
}
/**
* Flushes all pending ("buffered") data.
*
* @access public
*/
function flush() {
if (count($this->_buffer)) {
print '<script type="text/javascript">';
print "\nif (('console' in window) && ('firebug' in console)) {\n";
foreach ($this->_buffer as $line) {
print " $line\n";
}
print "}\n";
print "</script>\n";
};
$this->_buffer = array();
}
/**
* Writes $message to Firebug 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 the string representation of the message. */
$message = $this->_extractMessage($message);
$method = $this->_methods[$priority];
/* normalize line breaks */
$message = str_replace("\r\n", "\n", $message);
/* escape line breaks */
$message = str_replace("\n", "\\n\\\n", $message);
/* escape quotes */
$message = str_replace('"', '\\"', $message);
/* Build the string containing the complete log line. */
$line = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$priority,
$message);
if ($this->_buffering) {
$this->_buffer[] = sprintf('console.%s("%s");', $method, $line);
} else {
print '<script type="text/javascript">';
print "\nif (('console' in window) && ('firebug' in console)) {\n";
/* Build and output the complete log line. */
printf(' console.%s("%s");', $method, $line);
print "\n}\n";
print "</script>\n";
}
/* Notify observers about this log message. */
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
}

View file

@ -0,0 +1,294 @@
<?php
/**
* $Header$
*
* @version $Revision: 266658 $
* @package Log
*/
/**
* The Log_mail class is a concrete implementation of the Log:: abstract class
* which sends log messages to a mailbox.
* The mail is actually sent when you close() the logger, or when the destructor
* is called (when the script is terminated).
*
* PLEASE NOTE that you must create a Log_mail object using =&, like this :
* $logger =& Log::factory("mail", "recipient@example.com", ...)
*
* This is a PEAR requirement for destructors to work properly.
* See http://pear.php.net/manual/en/class.pear.php
*
* @author Ronnie Garcia <ronnie@mk2.net>
* @author Jon Parise <jon@php.net>
* @since Log 1.3
* @package Log
*
* @example mail.php Using the mail handler.
*/
class Log_mail extends Log
{
/**
* String holding the recipients' email addresses. Multiple addresses
* should be separated with commas.
* @var string
* @access private
*/
var $_recipients = '';
/**
* String holding the sender's email address.
* @var string
* @access private
*/
var $_from = '';
/**
* String holding the email's subject.
* @var string
* @access private
*/
var $_subject = '[Log_mail] Log message';
/**
* String holding an optional preamble for the log messages.
* @var string
* @access private
*/
var $_preamble = '';
/**
* 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.
* @var string
* @access private
*/
var $_timeFormat = '%b %d %H:%M:%S';
/**
* String holding the mail message body.
* @var string
* @access private
*/
var $_message = '';
/**
* Flag used to indicated that log lines have been written to the message
* body and the message should be sent on close().
* @var boolean
* @access private
*/
var $_shouldSend = false;
/**
* String holding the backend name of PEAR::Mail
* @var string
* @access private
*/
var $_mailBackend = '';
/**
* Array holding the params for PEAR::Mail
* @var array
* @access private
*/
var $_mailParams = array();
/**
* Constructs a new Log_mail object.
*
* Here is how you can customize the mail driver with the conf[] hash :
* $conf['from']: the mail's "From" header line,
* $conf['subject']: the mail's "Subject" line.
* $conf['mailBackend']: backend name of PEAR::Mail
* $conf['mailParams']: parameters for the PEAR::Mail backend
*
* @param string $name The message's recipients.
* @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 __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_recipients = $name;
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (!empty($conf['from'])) {
$this->_from = $conf['from'];
} else {
$this->_from = ini_get('sendmail_from');
}
if (!empty($conf['subject'])) {
$this->_subject = $conf['subject'];
}
if (!empty($conf['preamble'])) {
$this->_preamble = $conf['preamble'];
}
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'];
}
if (!empty($conf['mailBackend'])) {
$this->_mailBackend = $conf['mailBackend'];
}
if (!empty($conf['mailParams'])) {
$this->_mailParams = $conf['mailParams'];
}
/* register the destructor */
register_shutdown_function(array(&$this, '_Log_mail'));
}
/**
* Destructor. Calls close().
*
* @access private
*/
function _Log_mail()
{
$this->close();
}
/**
* Starts a new mail message.
* This is implicitly called by log(), if necessary.
*
* @access public
*/
function open()
{
if (!$this->_opened) {
if (!empty($this->_preamble)) {
$this->_message = $this->_preamble . "\r\n\r\n";
}
$this->_opened = true;
$_shouldSend = false;
}
return $this->_opened;
}
/**
* Closes the message, if it is open, and sends the mail.
* This is implicitly called by the destructor, if necessary.
*
* @access public
*/
function close()
{
if ($this->_opened) {
if ($this->_shouldSend && !empty($this->_message)) {
if ($this->_mailBackend === '') { // use mail()
$headers = "From: $this->_from\r\n";
$headers .= 'User-Agent: PEAR Log Package';
if (mail($this->_recipients, $this->_subject,
$this->_message, $headers) == false) {
return false;
}
} else { // use PEAR::Mail
include_once 'Mail.php';
$headers = array('From' => $this->_from,
'To' => $this->_recipients,
'User-Agent' => 'PEAR Log Package',
'Subject' => $this->_subject);
$mailer = &Mail::factory($this->_mailBackend,
$this->_mailParams);
$res = $mailer->send($this->_recipients, $headers,
$this->_message);
if (PEAR::isError($res)) {
return false;
}
}
/* Clear the message string now that the email has been sent. */
$this->_message = '';
$this->_shouldSend = false;
}
$this->_opened = false;
}
return ($this->_opened === false);
}
/**
* Flushes the log output by forcing the email message to be sent now.
* Events that are logged after flush() is called will be appended to a
* new email message.
*
* @access public
* @since Log 1.8.2
*/
function flush()
{
/*
* It's sufficient to simply call close() to flush the output.
* The next call to log() will cause the handler to be reopened.
*/
return $this->close();
}
/**
* Writes $message to the currently open mail message.
* Calls open(), if necessary.
*
* @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;
}
/* If the message isn't open and can't be opened, return failure. */
if (!$this->_opened && !$this->open()) {
return false;
}
/* Extract the string representation of the message. */
$message = $this->_extractMessage($message);
/* Append the string containing the complete log line. */
$this->_message .= $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$priority, $message) . "\r\n";
$this->_shouldSend = true;
/* Notify observers about this log message. */
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
}

View file

@ -0,0 +1,170 @@
<?php
/**
* $Header$
* $Horde: horde/lib/Log/mcal.php,v 1.2 2000/06/28 21:36:13 jon Exp $
*
* @version $Revision: 180836 $
* @package Log
*/
/**
* The Log_mcal class is a concrete implementation of the Log::
* abstract class which sends messages to a local or remote calendar
* store accessed through MCAL.
*
* @author Chuck Hagenbuch <chuck@horde.org>
* @since Horde 1.3
* @since Log 1.0
* @package Log
*/
class Log_mcal extends Log
{
/**
* holding the calendar specification to connect to.
* @var string
* @access private
*/
var $_calendar = '{localhost/mstore}';
/**
* holding the username to use.
* @var string
* @access private
*/
var $_username = '';
/**
* holding the password to use.
* @var string
* @access private
*/
var $_password = '';
/**
* holding the options to pass to the calendar stream.
* @var integer
* @access private
*/
var $_options = 0;
/**
* ResourceID of the MCAL stream.
* @var string
* @access private
*/
var $_stream = '';
/**
* Integer holding the log facility to use.
* @var string
* @access private
*/
var $_name = LOG_SYSLOG;
/**
* Constructs a new Log_mcal object.
*
* @param string $name The category to use for our events.
* @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 __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_name = $name;
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
$this->_calendar = $conf['calendar'];
$this->_username = $conf['username'];
$this->_password = $conf['password'];
$this->_options = $conf['options'];
}
/**
* Opens a calendar stream, if it has not already been
* opened. This is implicitly called by log(), if necessary.
* @access public
*/
function open()
{
if (!$this->_opened) {
$this->_stream = mcal_open($this->_calendar, $this->_username,
$this->_password, $this->_options);
$this->_opened = true;
}
return $this->_opened;
}
/**
* Closes the calendar stream, if it is open.
* @access public
*/
function close()
{
if ($this->_opened) {
mcal_close($this->_stream);
$this->_opened = false;
}
return ($this->_opened === false);
}
/**
* Logs $message and associated information to the currently open
* calendar stream. Calls open() if necessary. 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;
}
/* If the connection isn't open and can't be opened, return failure. */
if (!$this->_opened && !$this->open()) {
return false;
}
/* Extract the string representation of the message. */
$message = $this->_extractMessage($message);
$date_str = date('Y:n:j:G:i:s');
$dates = explode(':', $date_str);
mcal_event_init($this->_stream);
mcal_event_set_title($this->_stream, $this->_ident);
mcal_event_set_category($this->_stream, $this->_name);
mcal_event_set_description($this->_stream, $message);
mcal_event_add_attribute($this->_stream, 'priority', $priority);
mcal_event_set_start($this->_stream, $dates[0], $dates[1], $dates[2],
$dates[3], $dates[4], $dates[5]);
mcal_event_set_end($this->_stream, $dates[0], $dates[1], $dates[2],
$dates[3], $dates[4], $dates[5]);
mcal_append_event($this->_stream);
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
}

View file

@ -0,0 +1,358 @@
<?php
/**
* $Header$
*
* @version $Revision: 204814 $
* @package Log
*/
/** PEAR's MDB2 package */
require_once 'MDB2.php';
MDB2::loadFile('Date');
/**
* The Log_mdb2 class is a concrete implementation of the Log:: abstract class
* which sends messages to an SQL server. Each entry occupies a separate row
* in the database.
*
* This implementation uses PEAR's MDB2 database abstraction layer.
*
* CREATE TABLE log_table (
* id INT NOT NULL,
* logtime TIMESTAMP NOT NULL,
* ident CHAR(16) NOT NULL,
* priority INT NOT NULL,
* message VARCHAR(200),
* PRIMARY KEY (id)
* );
*
* @author Lukas Smith <smith@backendmedia.com>
* @author Jon Parise <jon@php.net>
* @since Log 1.9.0
* @package Log
*/
class Log_mdb2 extends Log
{
/**
* Variable containing the DSN information.
* @var mixed
* @access private
*/
var $_dsn = '';
/**
* Array containing our set of DB configuration options.
* @var array
* @access private
*/
var $_options = array('persistent' => true);
/**
* Object holding the database handle.
* @var object
* @access private
*/
var $_db = null;
/**
* Resource holding the prepared statement handle.
* @var resource
* @access private
*/
var $_statement = null;
/**
* Flag indicating that we're using an existing database connection.
* @var boolean
* @access private
*/
var $_existingConnection = false;
/**
* String holding the database table to use.
* @var string
* @access private
*/
var $_table = 'log_table';
/**
* String holding the name of the ID sequence.
* @var string
* @access private
*/
var $_sequence = 'log_id';
/**
* Maximum length of the $ident string. This corresponds to the size of
* the 'ident' column in the SQL table.
* @var integer
* @access private
*/
var $_identLimit = 16;
/**
* Set of field types used in the database table.
* @var array
* @access private
*/
var $_types = array(
'id' => 'integer',
'logtime' => 'timestamp',
'ident' => 'text',
'priority' => 'text',
'message' => 'clob'
);
/**
* Constructs a new sql logging object.
*
* @param string $name The target SQL table.
* @param string $ident The identification field.
* @param array $conf The connection configuration array.
* @param int $level Log messages up to and including this level.
* @access public
*/
function __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_table = $name;
$this->_mask = Log::UPTO($level);
/* If an options array was provided, use it. */
if (isset($conf['options']) && is_array($conf['options'])) {
$this->_options = $conf['options'];
}
/* If a specific sequence name was provided, use it. */
if (!empty($conf['sequence'])) {
$this->_sequence = $conf['sequence'];
}
/* If a specific sequence name was provided, use it. */
if (isset($conf['identLimit'])) {
$this->_identLimit = $conf['identLimit'];
}
/* Now that the ident limit is confirmed, set the ident string. */
$this->setIdent($ident);
/* If an existing database connection was provided, use it. */
if (isset($conf['db'])) {
$this->_db = &$conf['db'];
$this->_existingConnection = true;
$this->_opened = true;
} elseif (isset($conf['singleton'])) {
$this->_db = MDB2::singleton($conf['singleton'], $this->_options);
$this->_existingConnection = true;
$this->_opened = true;
} else {
$this->_dsn = $conf['dsn'];
}
}
/**
* Opens a connection to the database, if it has not already
* been opened. This is implicitly called by log(), if necessary.
*
* @return boolean True on success, false on failure.
* @access public
*/
function open()
{
if (!$this->_opened) {
/* Use the DSN and options to create a database connection. */
$this->_db = MDB2::connect($this->_dsn, $this->_options);
if (PEAR::isError($this->_db)) {
return false;
}
/* Create a prepared statement for repeated use in log(). */
if (!$this->_prepareStatement()) {
return false;
}
/* We now consider out connection open. */
$this->_opened = true;
}
return $this->_opened;
}
/**
* Closes the connection to the database if it is still open and we were
* the ones that opened it. It is the caller's responsible to close an
* existing connection that was passed to us via $conf['db'].
*
* @return boolean True on success, false on failure.
* @access public
*/
function close()
{
/* If we have a statement object, free it. */
if (is_object($this->_statement)) {
$this->_statement->free();
$this->_statement = null;
}
/* If we opened the database connection, disconnect it. */
if ($this->_opened && !$this->_existingConnection) {
$this->_opened = false;
return $this->_db->disconnect();
}
return ($this->_opened === false);
}
/**
* Sets this Log instance's identification string. Note that this
* SQL-specific implementation will limit the length of the $ident string
* to sixteen (16) characters.
*
* @param string $ident The new identification string.
*
* @access public
* @since Log 1.8.5
*/
function setIdent($ident)
{
$this->_ident = substr($ident, 0, $this->_identLimit);
}
/**
* Inserts $message to the currently open database. Calls open(),
* if necessary. 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;
}
/* If the connection isn't open and can't be opened, return failure. */
if (!$this->_opened && !$this->open()) {
return false;
}
/* If we don't already have a statement object, create one. */
if (!is_object($this->_statement) && !$this->_prepareStatement()) {
return false;
}
/* Extract the string representation of the message. */
$message = $this->_extractMessage($message);
/* Build our set of values for this log entry. */
$values = array(
'id' => $this->_db->nextId($this->_sequence),
'logtime' => MDB2_Date::mdbNow(),
'ident' => $this->_ident,
'priority' => $priority,
'message' => $message
);
/* Execute the SQL query for this log entry insertion. */
$this->_db->expectError(MDB2_ERROR_NOSUCHTABLE);
$result = &$this->_statement->execute($values);
$this->_db->popExpect();
/* Attempt to handle any errors. */
if (PEAR::isError($result)) {
/* We can only handle MDB2_ERROR_NOSUCHTABLE errors. */
if ($result->getCode() != MDB2_ERROR_NOSUCHTABLE) {
return false;
}
/* Attempt to create the target table. */
if (!$this->_createTable()) {
return false;
}
/* Recreate our prepared statement resource. */
$this->_statement->free();
if (!$this->_prepareStatement()) {
return false;
}
/* Attempt to re-execute the insertion query. */
$result = $this->_statement->execute($values);
if (PEAR::isError($result)) {
return false;
}
}
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
/**
* Create the log table in the database.
*
* @return boolean True on success or false on failure.
* @access private
*/
function _createTable()
{
$this->_db->loadModule('Manager', null, true);
$result = $this->_db->manager->createTable(
$this->_table,
array(
'id' => array('type' => $this->_types['id']),
'logtime' => array('type' => $this->_types['logtime']),
'ident' => array('type' => $this->_types['ident']),
'priority' => array('type' => $this->_types['priority']),
'message' => array('type' => $this->_types['message'])
)
);
if (PEAR::isError($result)) {
return false;
}
$result = $this->_db->manager->createIndex(
$this->_table,
'unique_id',
array('fields' => array('id' => true), 'unique' => true)
);
if (PEAR::isError($result)) {
return false;
}
return true;
}
/**
* Prepare the SQL insertion statement.
*
* @return boolean True if the statement was successfully created.
*
* @access private
* @since Log 1.9.0
*/
function _prepareStatement()
{
$this->_statement = &$this->_db->prepare(
'INSERT INTO ' . $this->_table .
' (id, logtime, ident, priority, message)' .
' VALUES(:id, :logtime, :ident, :priority, :message)',
$this->_types, MDB2_PREPARE_MANIP);
/* Return success if we didn't generate an error. */
return (PEAR::isError($this->_statement) === false);
}
}

View file

@ -0,0 +1,91 @@
<?php
/**
* $Header$
*
* @version $Revision: 215527 $
* @package Log
*/
/**
* The Log_null class is a concrete implementation of the Log:: abstract
* class. It simply consumes log events.
*
* @author Jon Parise <jon@php.net>
* @since Log 1.8.2
* @package Log
*
* @example null.php Using the null handler.
*/
class Log_null extends Log
{
/**
* Constructs a new Log_null 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 __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
}
/**
* Opens the handler.
*
* @access public
* @since Log 1.9.6
*/
function open()
{
$this->_opened = true;
return true;
}
/**
* Closes the handler.
*
* @access public
* @since Log 1.9.6
*/
function close()
{
$this->_opened = false;
return true;
}
/**
* Simply consumes the log event. The message will still be passed
* 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;
}
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
}

View file

@ -0,0 +1,129 @@
<?php
/**
* $Header$
* $Horde: horde/lib/Log/observer.php,v 1.5 2000/06/28 21:36:13 jon Exp $
*
* @version $Revision: 211953 $
* @package Log
*/
/**
* The Log_observer:: class implements the Observer end of a Subject-Observer
* pattern for watching log activity and taking actions on exceptional events.
*
* @author Chuck Hagenbuch <chuck@horde.org>
* @since Horde 1.3
* @since Log 1.0
* @package Log
*
* @example observer_mail.php An example Log_observer implementation.
*/
class Log_observer
{
/**
* Instance-specific unique identification number.
*
* @var integer
* @access private
*/
var $_id = 0;
/**
* The minimum priority level of message that we want to hear about.
* PEAR_LOG_EMERG is the highest priority, so we will only hear messages
* with an integer priority value less than or equal to ours. It defaults
* to PEAR_LOG_INFO, which listens to everything except PEAR_LOG_DEBUG.
*
* @var string
* @access private
*/
var $_priority = PEAR_LOG_INFO;
/**
* Creates a new basic Log_observer instance.
*
* @param integer $priority The highest priority at which to receive
* log event notifications.
*
* @access public
*/
function __construct($priority = PEAR_LOG_INFO)
{
$this->_id = md5(microtime());
$this->_priority = $priority;
}
/**
* Attempts to return a new concrete Log_observer instance of the requested
* type.
*
* @param string $type The type of concreate Log_observer subclass
* to return.
* @param integer $priority The highest priority at which to receive
* log event notifications.
* @param array $conf Optional associative array of additional
* configuration values.
*
* @return object The newly created concrete Log_observer
* instance, or null on an error.
*/
function &factory($type, $priority = PEAR_LOG_INFO, $conf = array())
{
$type = strtolower($type);
$class = 'Log_observer_' . $type;
/*
* If the desired class already exists (because the caller has supplied
* it from some custom location), simply instantiate and return a new
* instance.
*/
if (class_exists($class)) {
$object = new $class($priority, $conf);
return $object;
}
/* Support both the new-style and old-style file naming conventions. */
$newstyle = true;
$classfile = dirname(__FILE__) . '/observer_' . $type . '.php';
if (!file_exists($classfile)) {
$classfile = 'Log/' . $type . '.php';
$newstyle = false;
}
/*
* Attempt to include our version of the named class, but don't treat
* a failure as fatal. The caller may have already included their own
* version of the named class.
*/
@include_once $classfile;
/* If the class exists, return a new instance of it. */
if (class_exists($class)) {
/* Support both new-style and old-style construction. */
if ($newstyle) {
$object = new $class($priority, $conf);
} else {
$object = &new $class($priority);
}
return $object;
}
$null = null;
return $null;
}
/**
* This is a stub method to make sure that Log_Observer classes do
* something when they are notified of a message. The default behavior
* is to just print the message, which is obviously not desireable in
* practically any situation - which is why you need to override this
* method. :)
*
* @param array $event A hash describing the log event.
*/
function notify($event)
{
print_r($event);
}
}

View file

@ -0,0 +1,294 @@
<?php
/**
* $Header$
* $Horde: horde/lib/Log/sql.php,v 1.12 2000/08/16 20:27:34 chuck Exp $
*
* @version $Revision: 250926 $
* @package Log
*/
/**
* We require the PEAR DB class. This is generally defined in the DB.php file,
* but it's possible that the caller may have provided the DB class, or a
* compatible wrapper (such as the one shipped with MDB2), so we first check
* for an existing 'DB' class before including 'DB.php'.
*/
if (!class_exists('DB')) {
require_once 'DB.php';
}
/**
* The Log_sql class is a concrete implementation of the Log::
* abstract class which sends messages to an SQL server. Each entry
* occupies a separate row in the database.
*
* This implementation uses PHP's PEAR database abstraction layer.
*
* CREATE TABLE log_table (
* id INT NOT NULL,
* logtime TIMESTAMP NOT NULL,
* ident CHAR(16) NOT NULL,
* priority INT NOT NULL,
* message VARCHAR(200),
* PRIMARY KEY (id)
* );
*
* @author Jon Parise <jon@php.net>
* @since Horde 1.3
* @since Log 1.0
* @package Log
*
* @example sql.php Using the SQL handler.
*/
class Log_sql extends Log
{
/**
* Variable containing the DSN information.
* @var mixed
* @access private
*/
var $_dsn = '';
/**
* String containing the SQL insertion statement.
*
* @var string
* @access private
*/
var $_sql = '';
/**
* Array containing our set of DB configuration options.
* @var array
* @access private
*/
var $_options = array('persistent' => true);
/**
* Object holding the database handle.
* @var object
* @access private
*/
var $_db = null;
/**
* Resource holding the prepared statement handle.
* @var resource
* @access private
*/
var $_statement = null;
/**
* Flag indicating that we're using an existing database connection.
* @var boolean
* @access private
*/
var $_existingConnection = false;
/**
* String holding the database table to use.
* @var string
* @access private
*/
var $_table = 'log_table';
/**
* String holding the name of the ID sequence.
* @var string
* @access private
*/
var $_sequence = 'log_id';
/**
* Maximum length of the $ident string. This corresponds to the size of
* the 'ident' column in the SQL table.
* @var integer
* @access private
*/
var $_identLimit = 16;
/**
* Constructs a new sql logging object.
*
* @param string $name The target SQL table.
* @param string $ident The identification field.
* @param array $conf The connection configuration array.
* @param int $level Log messages up to and including this level.
* @access public
*/
function __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_table = $name;
$this->_mask = Log::UPTO($level);
/* Now that we have a table name, assign our SQL statement. */
if (!empty($conf['sql'])) {
$this->_sql = $conf['sql'];
} else {
$this->_sql = 'INSERT INTO ' . $this->_table .
' (id, logtime, ident, priority, message)' .
' VALUES(?, CURRENT_TIMESTAMP, ?, ?, ?)';
}
/* If an options array was provided, use it. */
if (isset($conf['options']) && is_array($conf['options'])) {
$this->_options = $conf['options'];
}
/* If a specific sequence name was provided, use it. */
if (!empty($conf['sequence'])) {
$this->_sequence = $conf['sequence'];
}
/* If a specific sequence name was provided, use it. */
if (isset($conf['identLimit'])) {
$this->_identLimit = $conf['identLimit'];
}
/* Now that the ident limit is confirmed, set the ident string. */
$this->setIdent($ident);
/* If an existing database connection was provided, use it. */
if (isset($conf['db'])) {
$this->_db = &$conf['db'];
$this->_existingConnection = true;
$this->_opened = true;
} else {
$this->_dsn = $conf['dsn'];
}
}
/**
* Opens a connection to the database, if it has not already
* been opened. This is implicitly called by log(), if necessary.
*
* @return boolean True on success, false on failure.
* @access public
*/
function open()
{
if (!$this->_opened) {
/* Use the DSN and options to create a database connection. */
$this->_db = DB::connect($this->_dsn, $this->_options);
if (DB::isError($this->_db)) {
return false;
}
/* Create a prepared statement for repeated use in log(). */
if (!$this->_prepareStatement()) {
return false;
}
/* We now consider out connection open. */
$this->_opened = true;
}
return $this->_opened;
}
/**
* Closes the connection to the database if it is still open and we were
* the ones that opened it. It is the caller's responsible to close an
* existing connection that was passed to us via $conf['db'].
*
* @return boolean True on success, false on failure.
* @access public
*/
function close()
{
if ($this->_opened && !$this->_existingConnection) {
$this->_opened = false;
$this->_db->freePrepared($this->_statement);
return $this->_db->disconnect();
}
return ($this->_opened === false);
}
/**
* Sets this Log instance's identification string. Note that this
* SQL-specific implementation will limit the length of the $ident string
* to sixteen (16) characters.
*
* @param string $ident The new identification string.
*
* @access public
* @since Log 1.8.5
*/
function setIdent($ident)
{
$this->_ident = substr($ident, 0, $this->_identLimit);
}
/**
* Inserts $message to the currently open database. Calls open(),
* if necessary. 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;
}
/* If the connection isn't open and can't be opened, return failure. */
if (!$this->_opened && !$this->open()) {
return false;
}
/* If we don't already have our statement object yet, create it. */
if (!is_object($this->_statement) && !$this->_prepareStatement()) {
return false;
}
/* Extract the string representation of the message. */
$message = $this->_extractMessage($message);
/* Build our set of values for this log entry. */
$id = $this->_db->nextId($this->_sequence);
$values = array($id, $this->_ident, $priority, $message);
/* Execute the SQL query for this log entry insertion. */
$result =& $this->_db->execute($this->_statement, $values);
if (DB::isError($result)) {
return false;
}
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
/**
* Prepare the SQL insertion statement.
*
* @return boolean True if the statement was successfully created.
*
* @access private
* @since Log 1.9.1
*/
function _prepareStatement()
{
$this->_statement = $this->_db->prepare($this->_sql);
/* Return success if we didn't generate an error. */
return (DB::isError($this->_statement) === false);
}
}

View file

@ -0,0 +1,225 @@
<?php
/**
* $Header$
*
* @version $Revision: 202069 $
* @package Log
*/
/**
* The Log_sqlite class is a concrete implementation of the Log::
* abstract class which sends messages to an Sqlite database.
* Each entry occupies a separate row in the database.
*
* This implementation uses PHP native Sqlite functions.
*
* CREATE TABLE log_table (
* id INTEGER PRIMARY KEY NOT NULL,
* logtime NOT NULL,
* ident CHAR(16) NOT NULL,
* priority INT NOT NULL,
* message
* );
*
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Jon Parise <jon@php.net>
* @since Log 1.8.3
* @package Log
*
* @example sqlite.php Using the Sqlite handler.
*/
class Log_sqlite extends Log
{
/**
* Array containing the connection defaults
* @var array
* @access private
*/
var $_options = array('mode' => 0666,
'persistent' => false);
/**
* Object holding the database handle.
* @var object
* @access private
*/
var $_db = null;
/**
* Flag indicating that we're using an existing database connection.
* @var boolean
* @access private
*/
var $_existingConnection = false;
/**
* String holding the database table to use.
* @var string
* @access private
*/
var $_table = 'log_table';
/**
* Constructs a new sql logging object.
*
* @param string $name The target SQL table.
* @param string $ident The identification field.
* @param mixed $conf Can be an array of configuration options used
* to open a new database connection
* or an already opened sqlite connection.
* @param int $level Log messages up to and including this level.
* @access public
*/
function __construct($name, $ident = '', &$conf, $level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_table = $name;
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (is_array($conf)) {
foreach ($conf as $k => $opt) {
$this->_options[$k] = $opt;
}
} else {
// If an existing database connection was provided, use it.
$this->_db =& $conf;
$this->_existingConnection = true;
}
}
/**
* Opens a connection to the database, if it has not already
* been opened. This is implicitly called by log(), if necessary.
*
* @return boolean True on success, false on failure.
* @access public
*/
function open()
{
if (is_resource($this->_db)) {
$this->_opened = true;
return $this->_createTable();
} else {
/* Set the connection function based on the 'persistent' option. */
if (empty($this->_options['persistent'])) {
$connectFunction = 'sqlite_open';
} else {
$connectFunction = 'sqlite_popen';
}
/* Attempt to connect to the database. */
if ($this->_db = $connectFunction($this->_options['filename'],
(int)$this->_options['mode'],
$error)) {
$this->_opened = true;
return $this->_createTable();
}
}
return $this->_opened;
}
/**
* Closes the connection to the database if it is still open and we were
* the ones that opened it. It is the caller's responsible to close an
* existing connection that was passed to us via $conf['db'].
*
* @return boolean True on success, false on failure.
* @access public
*/
function close()
{
/* We never close existing connections. */
if ($this->_existingConnection) {
return false;
}
if ($this->_opened) {
$this->_opened = false;
sqlite_close($this->_db);
}
return ($this->_opened === false);
}
/**
* Inserts $message to the currently open database. Calls open(),
* if necessary. 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;
}
/* If the connection isn't open and can't be opened, return failure. */
if (!$this->_opened && !$this->open()) {
return false;
}
// Extract the string representation of the message.
$message = $this->_extractMessage($message);
// Build the SQL query for this log entry insertion.
$q = sprintf('INSERT INTO [%s] (logtime, ident, priority, message) ' .
"VALUES ('%s', '%s', %d, '%s')",
$this->_table,
strftime('%Y-%m-%d %H:%M:%S', time()),
sqlite_escape_string($this->_ident),
$priority,
sqlite_escape_string($message));
if (!($res = @sqlite_unbuffered_query($this->_db, $q))) {
return false;
}
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
/**
* Checks whether the log table exists and creates it if necessary.
*
* @return boolean True on success or false on failure.
* @access private
*/
function _createTable()
{
$q = "SELECT name FROM sqlite_master WHERE name='" . $this->_table .
"' AND type='table'";
$res = sqlite_query($this->_db, $q);
if (sqlite_num_rows($res) == 0) {
$q = 'CREATE TABLE [' . $this->_table . '] (' .
'id INTEGER PRIMARY KEY NOT NULL, ' .
'logtime NOT NULL, ' .
'ident CHAR(16) NOT NULL, ' .
'priority INT NOT NULL, ' .
'message)';
if (!($res = sqlite_unbuffered_query($this->_db, $q))) {
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,179 @@
<?php
/**
* $Header$
* $Horde: horde/lib/Log/syslog.php,v 1.6 2000/06/28 21:36:13 jon Exp $
*
* @version $Revision: 228384 $
* @package Log
*/
/**
* The Log_syslog class is a concrete implementation of the Log::
* abstract class which sends messages to syslog on UNIX-like machines
* (PHP emulates this with the Event Log on Windows machines).
*
* @author Chuck Hagenbuch <chuck@horde.org>
* @author Jon Parise <jon@php.net>
* @since Horde 1.3
* @since Log 1.0
* @package Log
*
* @example syslog.php Using the syslog handler.
*/
class Log_syslog extends Log
{
/**
* Integer holding the log facility to use.
* @var integer
* @access private
*/
var $_name = LOG_SYSLOG;
/**
* Should we inherit the current syslog connection for this process, or
* should we call openlog() to start a new syslog connection?
* @var boolean
* @access private
*/
var $_inherit = false;
/**
* Constructs a new syslog object.
*
* @param string $name The syslog facility.
* @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 __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
/* Ensure we have a valid integer value for $name. */
if (empty($name) || !is_int($name)) {
$name = LOG_SYSLOG;
}
if (isset($conf['inherit'])) {
$this->_inherit = $conf['inherit'];
$this->_opened = $this->_inherit;
}
$this->_id = md5(microtime());
$this->_name = $name;
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
}
/**
* Opens a connection to the system logger, if it has not already
* been opened. This is implicitly called by log(), if necessary.
* @access public
*/
function open()
{
if (!$this->_opened) {
$this->_opened = openlog($this->_ident, LOG_PID, $this->_name);
}
return $this->_opened;
}
/**
* Closes the connection to the system logger, if it is open.
* @access public
*/
function close()
{
if ($this->_opened && !$this->_inherit) {
closelog();
$this->_opened = false;
}
return true;
}
/**
* Sends $message to the currently open syslog connection. Calls
* open() if necessary. 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 int $priority (optional) 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;
}
/* If the connection isn't open and can't be opened, return failure. */
if (!$this->_opened && !$this->open()) {
return false;
}
/* Extract the string representation of the message. */
$message = $this->_extractMessage($message);
/* Build a syslog priority value based on our current configuration. */
$priority = $this->_toSyslog($priority);
if ($this->_inherit) {
$priority |= $this->_name;
}
if (!syslog($priority, $message)) {
return false;
}
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
/**
* Converts a PEAR_LOG_* constant into a syslog LOG_* constant.
*
* This function exists because, under Windows, not all of the LOG_*
* constants have unique values. Instead, the PEAR_LOG_* were introduced
* for global use, with the conversion to the LOG_* constants kept local to
* to the syslog driver.
*
* @param int $priority PEAR_LOG_* value to convert to LOG_* value.
*
* @return The LOG_* representation of $priority.
*
* @access private
*/
function _toSyslog($priority)
{
static $priorities = array(
PEAR_LOG_EMERG => LOG_EMERG,
PEAR_LOG_ALERT => LOG_ALERT,
PEAR_LOG_CRIT => LOG_CRIT,
PEAR_LOG_ERR => LOG_ERR,
PEAR_LOG_WARNING => LOG_WARNING,
PEAR_LOG_NOTICE => LOG_NOTICE,
PEAR_LOG_INFO => LOG_INFO,
PEAR_LOG_DEBUG => LOG_DEBUG
);
/* If we're passed an unknown priority, default to LOG_INFO. */
if (!is_int($priority) || !in_array($priority, $priorities)) {
return LOG_INFO;
}
return $priorities[$priority];
}
}

View file

@ -0,0 +1,286 @@
<?php
/**
* $Header$
*
* @version $Revision: 278003 $
* @package Log
*/
/**
* The Log_win class is a concrete implementation of the Log abstract
* class that logs messages to a separate browser window.
*
* The concept for this log handler is based on part by Craig Davis' article
* entitled "JavaScript Power PHP Debugging:
*
* http://www.zend.com/zend/tut/tutorial-DebugLib.php
*
* @author Jon Parise <jon@php.net>
* @since Log 1.7.0
* @package Log
*
* @example win.php Using the window handler.
*/
class Log_win extends Log
{
/**
* The name of the output window.
* @var string
* @access private
*/
var $_name = 'LogWindow';
/**
* The title of the output window.
* @var string
* @access private
*/
var $_title = 'Log Output Window';
/**
* Mapping of log priorities to styles.
* @var array
* @access private
*/
var $_styles = array(
PEAR_LOG_EMERG => 'color: red;',
PEAR_LOG_ALERT => 'color: orange;',
PEAR_LOG_CRIT => 'color: yellow;',
PEAR_LOG_ERR => 'color: green;',
PEAR_LOG_WARNING => 'color: blue;',
PEAR_LOG_NOTICE => 'color: indigo;',
PEAR_LOG_INFO => 'color: violet;',
PEAR_LOG_DEBUG => 'color: black;'
);
/**
* String buffer that holds line that are pending output.
* @var array
* @access private
*/
var $_buffer = array();
/**
* Constructs a new Log_win 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 __construct($name, $ident = '', $conf = array(),
$level = PEAR_LOG_DEBUG)
{
$this->_id = md5(microtime());
$this->_name = str_replace(' ', '_', $name);
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (isset($conf['title'])) {
$this->_title = $conf['title'];
}
if (isset($conf['styles']) && is_array($conf['styles'])) {
$this->_styles = $conf['styles'];
}
if (isset($conf['colors']) && is_array($conf['colors'])) {
foreach ($conf['colors'] as $level => $color) {
$this->_styles[$level] .= "color: $color;";
}
}
register_shutdown_function(array(&$this, '_Log_win'));
}
/**
* Destructor
*/
function _Log_win()
{
if ($this->_opened || (count($this->_buffer) > 0)) {
$this->close();
}
}
/**
* The first time open() is called, it will open a new browser window and
* prepare it for output.
*
* This is implicitly called by log(), if necessary.
*
* @access public
*/
function open()
{
if (!$this->_opened) {
$win = $this->_name;
$styles = $this->_styles;
if (!empty($this->_ident)) {
$identHeader = "$win.document.writeln('<th>Ident</th>')";
} else {
$identHeader = '';
}
echo <<< EOT
<script language="JavaScript">
$win = window.open('', '{$this->_name}', 'toolbar=no,scrollbars,width=600,height=400');
$win.document.writeln('<html>');
$win.document.writeln('<head>');
$win.document.writeln('<title>{$this->_title}</title>');
$win.document.writeln('<style type="text/css">');
$win.document.writeln('body { font-family: monospace; font-size: 8pt; }');
$win.document.writeln('td,th { font-size: 8pt; }');
$win.document.writeln('td,th { border-bottom: #999999 solid 1px; }');
$win.document.writeln('td,th { border-right: #999999 solid 1px; }');
$win.document.writeln('tr { text-align: left; vertical-align: top; }');
$win.document.writeln('td.l0 { $styles[0] }');
$win.document.writeln('td.l1 { $styles[1] }');
$win.document.writeln('td.l2 { $styles[2] }');
$win.document.writeln('td.l3 { $styles[3] }');
$win.document.writeln('td.l4 { $styles[4] }');
$win.document.writeln('td.l5 { $styles[5] }');
$win.document.writeln('td.l6 { $styles[6] }');
$win.document.writeln('td.l7 { $styles[7] }');
$win.document.writeln('</style>');
$win.document.writeln('<script type="text/javascript">');
$win.document.writeln('function scroll() {');
$win.document.writeln(' body = document.getElementById("{$this->_name}");');
$win.document.writeln(' body.scrollTop = body.scrollHeight;');
$win.document.writeln('}');
$win.document.writeln('<\/script>');
$win.document.writeln('</head>');
$win.document.writeln('<body id="{$this->_name}" onclick="scroll()">');
$win.document.writeln('<table border="0" cellpadding="2" cellspacing="0">');
$win.document.writeln('<tr><th>Time</th>');
$identHeader
$win.document.writeln('<th>Priority</th><th width="100%">Message</th></tr>');
</script>
EOT;
$this->_opened = true;
}
return $this->_opened;
}
/**
* Closes the output stream if it is open. If there are still pending
* lines in the output buffer, the output window will be opened so that
* the buffer can be drained.
*
* @access public
*/
function close()
{
/*
* If there are still lines waiting to be written, open the output
* window so that we can drain the buffer.
*/
if (!$this->_opened && (count($this->_buffer) > 0)) {
$this->open();
}
if ($this->_opened) {
$this->_writeln('</table>');
$this->_writeln('</body></html>');
$this->_drainBuffer();
$this->_opened = false;
}
return ($this->_opened === false);
}
/**
* Writes the contents of the output buffer to the output window.
*
* @access private
*/
function _drainBuffer()
{
$win = $this->_name;
foreach ($this->_buffer as $line) {
echo "<script language='JavaScript'>\n";
echo "$win.document.writeln('" . addslashes($line) . "');\n";
echo "self.focus();\n";
echo "</script>\n";
}
/* Now that the buffer has been drained, clear it. */
$this->_buffer = array();
}
/**
* Writes a single line of text to the output buffer.
*
* @param string $line The line of text to write.
*
* @access private
*/
function _writeln($line)
{
/* Add this line to our output buffer. */
$this->_buffer[] = $line;
/* Buffer the output until this page's headers have been sent. */
if (!headers_sent()) {
return;
}
/* If we haven't already opened the output window, do so now. */
if (!$this->_opened && !$this->open()) {
return;
}
/* Drain the buffer to the output window. */
$this->_drainBuffer();
}
/**
* Logs $message to the output window. The message is also passed 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 the string representation of the message. */
$message = $this->_extractMessage($message);
$message = preg_replace('/\r\n|\n|\r/', '<br />', $message);
list($usec, $sec) = explode(' ', microtime());
/* Build the output line that contains the log entry row. */
$line = '<tr>';
$line .= sprintf('<td>%s.%s</td>',
strftime('%H:%M:%S', $sec), substr($usec, 2, 2));
if (!empty($this->_ident)) {
$line .= '<td>' . $this->_ident . '</td>';
}
$line .= '<td>' . ucfirst($this->priorityToString($priority)) . '</td>';
$line .= sprintf('<td class="l%d">%s</td>', $priority, $message);
$line .= '</tr>';
$this->_writeln($line);
$this->_announce(array('priority' => $priority, 'message' => $message));
return true;
}
}