diff options
Diffstat (limited to 'inc/Log')
-rwxr-xr-x | inc/Log/composite.php | 196 | ||||
-rwxr-xr-x | inc/Log/console.php | 190 | ||||
-rwxr-xr-x | inc/Log/daemon.php | 229 | ||||
-rwxr-xr-x | inc/Log/display.php | 108 | ||||
-rwxr-xr-x | inc/Log/error_log.php | 104 | ||||
-rwxr-xr-x | inc/Log/file.php | 286 | ||||
-rwxr-xr-x | inc/Log/mail.php | 222 | ||||
-rwxr-xr-x | inc/Log/mcal.php | 171 | ||||
-rwxr-xr-x | inc/Log/null.php | 68 | ||||
-rwxr-xr-x | inc/Log/observer.php | 126 | ||||
-rwxr-xr-x | inc/Log/sql.php | 225 | ||||
-rwxr-xr-x | inc/Log/sqlite.php | 238 | ||||
-rwxr-xr-x | inc/Log/syslog.php | 160 | ||||
-rwxr-xr-x | inc/Log/win.php | 256 |
14 files changed, 2579 insertions, 0 deletions
diff --git a/inc/Log/composite.php b/inc/Log/composite.php new file mode 100755 index 00000000000..104c8966c42 --- /dev/null +++ b/inc/Log/composite.php @@ -0,0 +1,196 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/composite.php,v 1.23 2004/08/09 06:04:11 jon Exp $ + * $Horde: horde/lib/Log/composite.php,v 1.2 2000/06/28 21:36:13 jon Exp $ + * + * @version $Revision: 1.23 $ + * @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 Log_composite($name = false, $ident = false, $conf = false, + $level = PEAR_LOG_DEBUG) + { + } + + /** + * Opens the child connections. + * + * @access public + */ + function open() + { + if (!$this->_opened) { + foreach ($this->_children as $id => $child) { + $this->_children[$id]->open(); + } + $this->_opened = true; + } + } + + /** + * Closes any child instances. + * + * @access public + */ + function close() + { + if ($this->_opened) { + foreach ($this->_children as $id => $child) { + $this->_children[$id]->close(); + } + $this->_opened = false; + } + } + + /** + * Flushes all open child instances. + * + * @access public + * @since Log 1.8.2 + */ + function flush() + { + if ($this->_opened) { + foreach ($this->_children as $id => $child) { + $this->_children[$id]->flush(); + } + } + } + + /** + * Sends $message and $priority to each child of this composite. + * + * @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; + } + + foreach ($this->_children as $id => $child) { + $this->_children[$id]->log($message, $priority); + } + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + + /** + * 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) + { + 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; + } +} + +?> diff --git a/inc/Log/console.php b/inc/Log/console.php new file mode 100755 index 00000000000..62032e79644 --- /dev/null +++ b/inc/Log/console.php @@ -0,0 +1,190 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/console.php,v 1.19 2004/01/19 08:02:40 jon Exp $ + * + * @version $Revision: 1.19 $ + * @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'; + + /** + * Hash that maps canonical format keys to position arguments for the + * "line format" string. + * @var array + * @access private + */ + var $_formatMap = array('%{timestamp}' => '%1$s', + '%{ident}' => '%2$s', + '%{priority}' => '%3$s', + '%{message}' => '%4$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 Log_console($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->flush(); + } + + /** + * 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 = ''; + } + + return fflush($this->_stream); + } + + /** + * 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 = sprintf($this->_lineFormat, strftime($this->_timeFormat), + $this->_ident, $this->priorityToString($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; + } +} + +?> diff --git a/inc/Log/daemon.php b/inc/Log/daemon.php new file mode 100755 index 00000000000..739270c9a32 --- /dev/null +++ b/inc/Log/daemon.php @@ -0,0 +1,229 @@ +<?php +// $Id: daemon.php,v 1.1 2004/12/21 06:55:38 jon Exp $ + +/** + * 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: 1.1 $ + * @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 Log_daemon($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]; + } +} diff --git a/inc/Log/display.php b/inc/Log/display.php new file mode 100755 index 00000000000..0d5a93d79da --- /dev/null +++ b/inc/Log/display.php @@ -0,0 +1,108 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/display.php,v 1.6 2004/11/27 21:46:50 jon Exp $ + * + * @version $Revision: 1.6 $ + * @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 to output before an error message + * @var string + * @access private + */ + var $_error_prepend = ''; + + /** + * String to output after an error message + * @var string + * @access private + */ + var $_error_append = ''; + + + /** + * 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 Log_display($name = '', $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (!empty($conf['error_prepend'])) { + $this->_error_prepend = $conf['error_prepend']; + } else { + $this->_error_prepend = ini_get('error_prepend_string'); + } + + if (!empty($conf['error_append'])) { + $this->_error_append = $conf['error_append']; + } else { + $this->_error_append = ini_get('error_append_string'); + } + } + + /** + * 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->_error_prepend . + '<b>' . ucfirst($this->priorityToString($priority)) . '</b>: '. + nl2br(htmlspecialchars($message)) . + $this->_error_append . "<br />\n"; + + /* Notify observers about this log message. */ + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } +} + +?> diff --git a/inc/Log/error_log.php b/inc/Log/error_log.php new file mode 100755 index 00000000000..04c0952cd7a --- /dev/null +++ b/inc/Log/error_log.php @@ -0,0 +1,104 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/error_log.php,v 1.6 2004/01/19 08:02:40 jon Exp $ + * + * @version $Revision: 1.6 $ + * @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 = ''; + + /** + * 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 Log_error_log($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']; + } + } + + /** + * 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); + + $success = error_log($this->_ident . ': ' . $message, $this->_type, + $this->_destination, $this->_extra_headers); + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return $success; + } +} + +?> diff --git a/inc/Log/file.php b/inc/Log/file.php new file mode 100755 index 00000000000..36f30b42978 --- /dev/null +++ b/inc/Log/file.php @@ -0,0 +1,286 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/file.php,v 1.37 2004/01/19 08:02:40 jon Exp $ + * + * @version $Revision: 1.37 $ + * @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; + + /** + * Integer (in octal) containing the log file's permissions mode. + * @var integer + * @access private + */ + var $_mode = 0644; + + /** + * 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'; + + /** + * Hash that maps canonical format keys to position arguments for the + * "line format" string. + * @var array + * @access private + */ + var $_formatMap = array('%{timestamp}' => '%1$s', + '%{ident}' => '%2$s', + '%{priority}' => '%3$s', + '%{message}' => '%4$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 Log_file($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 (!empty($conf['mode'])) { + $this->_mode = $conf['mode']; + } + + 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. + * + * @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) + { + static $depth = 0; + + /* Guard against potentially infinite recursion. */ + if ($depth++ > 25) { + trigger_error("_mkpath(): Maximum recursion depth (25) exceeded", + E_USER_WARNING); + return false; + } + + /* We're only interested in the directory component of the path. */ + $path = dirname($path); + + /* If the directory already exists, return success immediately. */ + if (is_dir($path)) { + $depth = 0; + return true; + } + + /* + * In order to understand recursion, you must first understand + * recursion ... + */ + if ($this->_mkpath($path, $mode) === false) { + return false; + } + + return @mkdir($path, $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); + } + + /* Obtain a handle to the log file. */ + $this->_fp = fopen($this->_filename, ($this->_append) ? 'a' : 'w'); + + $this->_opened = ($this->_fp !== false); + + /* Attempt to set the log file's mode. */ + @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() + { + return fflush($this->_fp); + } + + /** + * 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 = sprintf($this->_lineFormat, strftime($this->_timeFormat), + $this->_ident, $this->priorityToString($priority), + $message) . $this->_eol; + + /* Write the log line to the log file. */ + $success = (fwrite($this->_fp, $line) !== false); + + /* Notify observers about this log message. */ + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return $success; + } +} + +?> diff --git a/inc/Log/mail.php b/inc/Log/mail.php new file mode 100755 index 00000000000..064f13c0ed5 --- /dev/null +++ b/inc/Log/mail.php @@ -0,0 +1,222 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/mail.php,v 1.21 2004/01/19 08:02:40 jon Exp $ + * + * @version $Revision: 1.21 $ + * @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 recipient's email address. + * @var string + * @access private + */ + var $_recipient = ''; + + /** + * 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 holding the mail message body. + * @var string + * @access private + */ + var $_message = ''; + + + /** + * 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. + * + * @param string $name The filename of the logfile. + * @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_mail($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_recipient = $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']; + } + + /* 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 . "\n\n"; + } + $this->_opened = true; + } + + 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 (!empty($this->_message)) { + $headers = "From: $this->_from\n"; + $headers .= "User-Agent: Log_mail"; + + if (mail($this->_recipient, $this->_subject, $this->_message, + $headers) == false) { + error_log("Log_mail: Failure executing mail()", 0); + return false; + } + + /* Clear the message string now that the email has been sent. */ + $this->_message = ''; + } + $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); + + $entry = sprintf("%s %s [%s] %s\n", strftime('%b %d %H:%M:%S'), + $this->_ident, Log::priorityToString($priority), + $message); + + $this->_message .= $entry; + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } +} + +?> diff --git a/inc/Log/mcal.php b/inc/Log/mcal.php new file mode 100755 index 00000000000..a5c46f3dfc6 --- /dev/null +++ b/inc/Log/mcal.php @@ -0,0 +1,171 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/mcal.php,v 1.17 2004/01/19 08:02:40 jon Exp $ + * $Horde: horde/lib/Log/mcal.php,v 1.2 2000/06/28 21:36:13 jon Exp $ + * + * @version $Revision: 1.17 $ + * @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 Log_mcal($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; + } +} + +?> diff --git a/inc/Log/null.php b/inc/Log/null.php new file mode 100755 index 00000000000..23de3f1a9e5 --- /dev/null +++ b/inc/Log/null.php @@ -0,0 +1,68 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/null.php,v 1.3 2004/01/19 08:02:40 jon Exp $ + * + * @version $Revision: 1.3 $ + * @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 Log_null($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + } + + /** + * 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; + } +} + +?> diff --git a/inc/Log/observer.php b/inc/Log/observer.php new file mode 100755 index 00000000000..187d5070f74 --- /dev/null +++ b/inc/Log/observer.php @@ -0,0 +1,126 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/observer.php,v 1.12 2004/01/11 20:49:49 jon Exp $ + * $Horde: horde/lib/Log/observer.php,v 1.5 2000/06/28 21:36:13 jon Exp $ + * + * @version $Revision: 1.12 $ + * @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 Log_observer($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 an false on an error. + */ + function &factory($type, $priority = PEAR_LOG_INFO, $conf = array()) + { + $type = strtolower($type); + $class = 'Log_observer_' . $type; + + /* Support both the new-style and old-style file naming conventions. */ + if (file_exists(dirname(__FILE__) . '/observer_' . $type . '.php')) { + $classfile = 'Log/observer_' . $type . '.php'; + $newstyle = true; + } else { + $classfile = 'Log/' . $type . '.php'; + $newstyle = false; + } + + /* Issue a warning if the old-style conventions are being used. */ + if (!$newstyle) + { + trigger_error('Using old-style Log_observer conventions', + E_USER_WARNING); + } + + /* + * 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) { + return new $class($priority, $conf); + } else { + return new $class($priority); + } + } + + return false; + } + + /** + * 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); + } +} + +?> diff --git a/inc/Log/sql.php b/inc/Log/sql.php new file mode 100755 index 00000000000..3a20a0e2faf --- /dev/null +++ b/inc/Log/sql.php @@ -0,0 +1,225 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/sql.php,v 1.34 2004/08/19 06:35:57 jon Exp $ + * $Horde: horde/lib/Log/sql.php,v 1.12 2000/08/16 20:27:34 chuck Exp $ + * + * @version $Revision: 1.34 $ + * @package Log + */ + +/** PEAR's DB package */ +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 { + + /** + * Array containing the dsn information. + * @var string + * @access private + */ + var $_dsn = ''; + + /** + * 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'; + + /** + * 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 Log_sql($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_table = $name; + $this->_mask = Log::UPTO($level); + + /* 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) { + $this->_db = &DB::connect($this->_dsn, true); + if (DB::isError($this->_db)) { + return false; + } + $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; + 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; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /* Build the SQL query for this log entry insertion. */ + $id = $this->_db->nextId($this->_sequence); + $q = sprintf('insert into %s (id, logtime, ident, priority, message)' . + 'values(%d, CURRENT_TIMESTAMP, %s, %d, %s)', + $this->_table, $id, $this->_db->quote($this->_ident), + $priority, $this->_db->quote($message)); + + $result = $this->_db->query($q); + if (DB::isError($result)) { + return false; + } + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } +} + +?> diff --git a/inc/Log/sqlite.php b/inc/Log/sqlite.php new file mode 100755 index 00000000000..83b908a9396 --- /dev/null +++ b/inc/Log/sqlite.php @@ -0,0 +1,238 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP version 4.0 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Authors: Bertrand Mansion <bmansion@mamasam.com> | +// +----------------------------------------------------------------------+ +// +// $Id: sqlite.php,v 1.3 2004/01/19 08:02:40 jon Exp $ + +/** + * 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 Log_sqlite($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; + } +} + +?> diff --git a/inc/Log/syslog.php b/inc/Log/syslog.php new file mode 100755 index 00000000000..4bafbaa2d9a --- /dev/null +++ b/inc/Log/syslog.php @@ -0,0 +1,160 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/syslog.php,v 1.22 2004/01/19 08:02:40 jon Exp $ + * $Horde: horde/lib/Log/syslog.php,v 1.6 2000/06/28 21:36:13 jon Exp $ + * + * @version $Revision: 1.22 $ + * @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> + * @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 string + * @access private + */ + var $_name = LOG_SYSLOG; + + /** + * 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 Log_syslog($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); + } + + /** + * 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) { + openlog($this->_ident, LOG_PID, $this->_name); + $this->_opened = true; + } + + return $this->_opened; + } + + /** + * Closes the connection to the system logger, if it is open. + * @access public + */ + function close() + { + if ($this->_opened) { + closelog(); + $this->_opened = false; + } + + return ($this->_opened === false); + } + + /** + * 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); + + if (!syslog($this->_toSyslog($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]; + } +} +?> diff --git a/inc/Log/win.php b/inc/Log/win.php new file mode 100755 index 00000000000..e8a09d16e81 --- /dev/null +++ b/inc/Log/win.php @@ -0,0 +1,256 @@ +<?php +/** + * $Header: /repository/pear/Log/Log/win.php,v 1.16 2004/09/08 23:35:53 jon Exp $ + * + * @version $Revision: 1.16 $ + * @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 colors. + * @var array + * @access private + */ + var $_colors = array( + PEAR_LOG_EMERG => 'red', + PEAR_LOG_ALERT => 'orange', + PEAR_LOG_CRIT => 'yellow', + PEAR_LOG_ERR => 'green', + PEAR_LOG_WARNING => 'blue', + PEAR_LOG_NOTICE => 'indigo', + PEAR_LOG_INFO => 'violet', + PEAR_LOG_DEBUG => '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 Log_win($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_name = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (isset($conf['title'])) { + $this->_title = $conf['title']; + } + if (isset($conf['colors']) && is_array($conf['colors'])) { + $this->_colors = $conf['colors']; + } + + 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; + + if (!empty($this->_ident)) { + $identHeader = "$win.document.writeln('<th>Ident</th>')"; + } else { + $identHeader = ''; + } + + echo <<< END_OF_SCRIPT +<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('</style>'); +$win.document.writeln('</head>'); +$win.document.writeln('<body>'); +$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> +END_OF_SCRIPT; + $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->_opened = false; + } + + return ($this->_opened === false); + } + + /** + * Writes a single line of text to the output window. + * + * @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 false; + } + + /* Drain the buffer to the output window. */ + $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(); + } + + /** + * 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); + + list($usec, $sec) = explode(' ', microtime()); + + /* Build the output line that contains the log entry row. */ + $line = '<tr align="left" valign="top">'; + $line .= sprintf('<td>%s.%s</td>', + strftime('%T', $sec), substr($usec, 2, 2)); + if (!empty($this->_ident)) { + $line .= '<td>' . $this->_ident . '</td>'; + } + $line .= '<td>' . ucfirst($this->priorityToString($priority)) . '</td>'; + $line .= sprintf('<td style="color: %s">%s</td>', + $this->_colors[$priority], + preg_replace('/\r\n|\n|\r/', '<br />', $message)); + $line .= '</tr>'; + + $this->_writeln($line); + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } +} + +?> |