--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ */
+class Horde_Log {
+
+ /** Emergency: system is unusable */
+ const EMERG = 0;
+
+ /** Alert: action must be taken immediately */
+ const ALERT = 1;
+
+ /** Critical: critical conditions */
+ const CRIT = 2;
+
+ /** Error: error conditions */
+ const ERR = 3;
+
+ /** Warning: warning conditions */
+ const WARN = 4;
+
+ /** Notice: normal but significant condition */
+ const NOTICE = 5;
+
+ /** Informational: informational messages */
+ const INFO = 6;
+
+ /** Debug: debug-level messages */
+ const DEBUG = 7;
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Exception extends Exception
+{
+ /**
+ */
+ public function __construct($msg, $code = 0)
+ {
+ parent::__construct($msg, $code);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Filters
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Filters
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+interface Horde_Log_Filter_Interface
+{
+ /**
+ * Returns TRUE to accept the message, FALSE to block it.
+ *
+ * @param array $event Log event
+ * @return boolean accepted?
+ */
+ public function accept($event);
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Filter_Level implements Horde_Log_Filter_Interface
+{
+ /**
+ * @var integer
+ */
+ protected $_level;
+
+ /**
+ * Filter out any log messages greater than $level.
+ *
+ * @param integer $level Maximum log level to pass through the filter
+ */
+ public function __construct($level)
+ {
+ if (! is_integer($level)) {
+ throw new Horde_Log_Exception('Level must be an integer');
+ }
+
+ $this->_level = $level;
+ }
+
+ /**
+ * Returns TRUE to accept the message, FALSE to block it.
+ *
+ * @param array $event Log event
+ * @return boolean accepted?
+ */
+ public function accept($event)
+ {
+ return $event['level'] <= $this->_level;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Filters
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Filters
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Filter_Message implements Horde_Log_Filter_Interface
+{
+ /**
+ * @var string
+ */
+ protected $_regexp;
+
+ /**
+ * Filter out any log messages not matching $regexp.
+ *
+ * @param string $regexp Regular expression to test the log message
+ * @throws Horde_Log_Exception Invalid regular expression
+ */
+ public function __construct($regexp)
+ {
+ if (@preg_match($regexp, '') === false) {
+ throw new Horde_Log_Exception("Invalid regular expression '$regexp'");
+ }
+ $this->_regexp = $regexp;
+ }
+
+ /**
+ * Returns TRUE to accept the message, FALSE to block it.
+ *
+ * @param array $event Log event
+ * @return boolean accepted?
+ */
+ public function accept($event)
+ {
+ return preg_match($this->_regexp, $event['message']) > 0;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+interface Horde_Log_Formatter_Interface
+{
+ /**
+ * Formats an event to be written by the handler.
+ *
+ * @param array $event Log event
+ * @return string formatted line
+ */
+ public function format($event);
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Formatters
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Formatters
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Formatter_Simple
+{
+ /**
+ * Format string
+ *
+ * @var string
+ */
+ protected $_format;
+
+ /**
+ * Constructor
+ */
+ public function __construct($options = null)
+ {
+ if (is_array($options) && isset($options['format'])) {
+ $format = $options['format'];
+ } else {
+ $format = $options;
+ }
+
+ if (is_null($format)) {
+ $format = '%timestamp% %levelName%: %message%' . PHP_EOL;
+ }
+
+ if (!is_string($format)) {
+ throw new Horde_Log_Exception('Format must be a string');
+ }
+
+ $this->_format = $format;
+ }
+
+ /**
+ * Formats an event to be written by the handler.
+ *
+ * @param array $event Log event
+ * @return string formatted line
+ */
+ public function format($event)
+ {
+ $output = $this->_format;
+ foreach ($event as $name => $value) {
+ $output = str_replace("%$name%", $value, $output);
+ }
+ return $output;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Formatters
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Formatters
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Formatter_Xml
+{
+ protected $_options = array('elementEntry' => 'log',
+ 'elementTimestamp' => 'timestamp',
+ 'elementMessage' => 'message',
+ 'elementLevel' => 'level',
+ 'lineEnding' => PHP_EOL);
+
+ public function __construct($options = array())
+ {
+ $this->_options = array_merge($this->_options, $options);
+ }
+
+ /**
+ * Formats an event to be written by the handler.
+ *
+ * @param array $event Log event
+ * @return string XML string
+ */
+ public function format($event)
+ {
+ $dom = new DOMDocument();
+
+ $elt = $dom->appendChild(new DOMElement($this->_options['elementEntry']));
+ $elt->appendChild(new DOMElement($this->_options['elementTimestamp'], date('c')));
+ $elt->appendChild(new DOMElement($this->_options['elementMessage'], $event['message']));
+ $elt->appendChild(new DOMElement($this->_options['elementLevel'], $event['level']));
+
+ $xml = $dom->saveXML();
+ $xml = preg_replace('/<\?xml version="1.0"( encoding="[^\"]*")?\?>\n/u', '', $xml);
+
+ return $xml . $this->_options['lineEnding'];
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+abstract class Horde_Log_Handler_Base
+{
+ /**
+ * @var array of key/value pair options
+ */
+ protected $_options = array();
+
+ /**
+ * @var array of Horde_Log_Filter_Interface
+ */
+ protected $_filters = array();
+
+ /**
+ * Add a filter specific to this handler.
+ *
+ * @param Horde_Log_Filter_Interface $filter
+ * @return void
+ */
+ public function addFilter($filter)
+ {
+ if (is_integer($filter)) {
+ $filter = new Horde_Log_Filter_Level($filter);
+ }
+
+ $this->_filters[] = $filter;
+ }
+
+ /**
+ * Log a message to this handler.
+ *
+ * @param array $event Log event
+ * @return void
+ */
+ public function log($event)
+ {
+ // if any local filter rejects the message, don't log it.
+ foreach ($this->_filters as $filter) {
+ if (!$filter->accept($event)) {
+ return;
+ }
+ }
+
+ $this->write($event);
+ }
+
+ /**
+ * Sets an option specific to the implementation of the log handler.
+ *
+ * @param $optionKey Key name for the option to be changed. Keys are handler-specific
+ * @param $optionValue New value to assign to the option
+ * @return bool True
+ */
+ public function setOption($optionKey, $optionValue)
+ {
+ if (!isset($this->_options[$optionKey])) {
+ throw new Horde_Log_Exception("Unknown option \"$optionKey\".");
+ }
+ $this->_options[$optionKey] = $optionValue;
+
+ return true;
+ }
+
+ /**
+ * Buffer a message to be stored in the storage
+ * implemented by this handler.
+ *
+ * @param array $event Log event
+ */
+ abstract public function write($event);
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Handler_Db extends Horde_Log_Handler_Base
+{
+ /**
+ * Database adapter instance
+ * @var Horde_Db_Adapter
+ */
+ private $_db;
+
+ /**
+ * Name of the log table in the database
+ * @var string
+ */
+ private $_table;
+
+ /**
+ * Options to be set by setOption(). Sets the field names in the database table.
+ *
+ * @var array
+ */
+ protected $_options = array('fieldMessage' => 'message',
+ 'fieldLevel' => 'level');
+
+ /**
+ * Class constructor
+ *
+ * @param Horde_Db_Adapter $db Database adapter instance
+ * @param string $table Log table in database
+ */
+ public function __construct($db, $table)
+ {
+ $this->_db = $db;
+ $this->_table = $table;
+ }
+
+ /**
+ * Write a message to the log.
+ *
+ * @param array $event Log event
+ * @return bool Always True
+ */
+ public function write($event)
+ {
+ $fields = array(
+ $this->_options['fieldMessage'] => $event['message'],
+ $this->_options['fieldLevel'] => $event['level'],
+ );
+
+ $this->_db->insert($this->_table, $fields);
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Handler_Firebug extends Horde_Log_Handler_Base
+{
+ /**
+ * Formats the log message before writing.
+ * @var Horde_Log_Formatter_Interface
+ */
+ protected $_formatter;
+
+ /**
+ * Options to be set by setOption(). Sets the field names in the database table.
+ *
+ * @var array
+ */
+ protected $_options = array('buffering' => false);
+
+ /**
+ * Array of buffered output.
+ * @var string
+ */
+ protected $_buffer = array();
+
+ /**
+ * Mapping of log priorities to Firebug methods.
+ * @var array
+ * @access private
+ */
+ protected static $_methods = array(
+ Horde_Log::EMERG => 'error',
+ Horde_Log::ALERT => 'error',
+ Horde_Log::CRIT => 'error',
+ Horde_Log::ERR => 'error',
+ Horde_Log::WARN => 'warn',
+ Horde_Log::NOTICE => 'info',
+ Horde_Log::INFO => 'info',
+ Horde_Log::DEBUG => 'debug',
+ );
+
+ /**
+ * Class Constructor
+ */
+ public function __construct()
+ {
+ $this->_formatter = new Horde_Log_Formatter_Simple();
+ }
+
+ /**
+ * Write a message to the firebug console. This function really just writes
+ * the message to the buffer. If buffering is enabled, the
+ * message won't be output until the buffer is flushed. If
+ * buffering is not enabled, the buffer will be flushed
+ * immediately.
+ *
+ * @param array $event Log event
+ * @return bool Always True
+ */
+ public function write($event)
+ {
+ $this->_buffer[] = $event;
+
+ if (empty($this->_options['buffering'])) {
+ $this->flush();
+ }
+
+ return true;
+ }
+
+ /**
+ */
+ public function flush()
+ {
+ if (!count($this->_buffer)) {
+ return true;
+ }
+
+ $output = array();
+ foreach ($this->_buffer as $event) {
+ $line = trim($this->_formatter->format($event));
+
+ // normalize line breaks
+ $line = str_replace("\r\n", "\n", $line);
+
+ // escape line breaks
+ $line = str_replace("\n", "\\n\\\n", $line);
+
+ // escape quotes
+ $line = str_replace('"', '\\"', $line);
+
+ // firebug call
+ $method = isset(self::$_methods[$event['level']]) ? self::$_methods[$event['level']] : 'log';
+ $output[] = 'console.' . $method . '("' . $line . '");';
+ }
+
+ echo '<script type="text/javascript">'
+ . "\nif (('console' in window) || ('firebug' in console)) {\n"
+ . implode("\n", $output) . "\n"
+ . "}\n"
+ . "</script>\n";
+
+ $this->_buffer = array();
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Handler_Null extends Horde_Log_Handler_Base
+{
+ /**
+ * Write a message to the log buffer
+ */
+ public function write($event)
+ {
+ return true;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Handlers
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Handler_Stream extends Horde_Log_Handler_Base
+{
+ /**
+ * Formats the log message before writing.
+ * @var Horde_Log_Formatter_Interface
+ */
+ protected $_formatter;
+
+ /**
+ * Holds the PHP stream to log to.
+ * @var null|stream
+ */
+ protected $_stream = null;
+
+ /**
+ * Class Constructor
+ *
+ * @param mixed $streamOrUrl Stream or URL to open as a stream
+ * @param string $mode Mode, only applicable if a URL is given
+ */
+ public function __construct($streamOrUrl, $mode = 'a+')
+ {
+ $this->_formatter = new Horde_Log_Formatter_Simple();
+
+ if (is_resource($streamOrUrl)) {
+ if (get_resource_type($streamOrUrl) != 'stream') {
+ throw new Horde_Log_Exception('Resource is not a stream');
+ }
+
+ if ($mode != 'a+') {
+ throw new Horde_Log_Exception('Mode cannot be changed on existing streams');
+ }
+
+ $this->_stream = $streamOrUrl;
+ } else {
+ if (! $this->_stream = @fopen($streamOrUrl, $mode, false)) {
+ $msg = "\"$streamOrUrl\" cannot be opened with mode \"$mode\"";
+ throw new Horde_Log_Exception($msg);
+ }
+ }
+ }
+
+ /**
+ * Write a message to the log.
+ *
+ * @param array $event Log event
+ * @return bool Always True
+ */
+ public function write($event)
+ {
+ $line = $this->_formatter->format($event);
+
+ if (! @fwrite($this->_stream, $line)) {
+ throw new Horde_Log_Exception("Unable to write to stream");
+ }
+
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ * @method void LOGLEVEL() LOGLEVEL($event) Log an event at LOGLEVEL, where LOGLEVEL has been added with addLevel() or already exists
+ * @method void emerg() emerg($event) Log an event at the EMERG log level
+ * @method void alert() alert($event) Log an event at the ALERT log level
+ * @method void crit() crit($event) Log an event at the CRIT log level
+ * @method void err() err($event) Log an event at the ERR log level
+ * @method void warn() warn($event) Log an event at the WARN log level
+ * @method void notice() notice($event) Log an event at the NOTICE log level
+ * @method void info() info($event) Log an event at the INFO log level
+ * @method void debug() debug($event) Log an event at the DEBUG log level
+ */
+class Horde_Log_Logger
+{
+ /**
+ * @var array of log levels where the keys are the
+ * level priorities and the values are the level names
+ */
+ private $_levels = array();
+
+ /**
+ * @var array of Horde_Log_Handler_Abstract objects
+ */
+ private $_handlers = array();
+
+ /**
+ * @var array of Horde_Log_Filter_Interface objects
+ */
+ private $_filters = array();
+
+ /**
+ * Class constructor. Create a new logger
+ *
+ * @param Horde_Log_Handler_Abstract|null $handler default handler
+ */
+ public function __construct($handler = null)
+ {
+ $r = new ReflectionClass('Horde_Log');
+ $this->_levels = array_flip($r->getConstants());
+
+ if ($handler !== null) {
+ $this->addHandler($handler);
+ }
+ }
+
+ /**
+ * Undefined method handler allows a shortcut:
+ * $log->levelName('message')
+ * instead of
+ * $log->log('message', Horde_Log_LEVELNAME)
+ *
+ * @param string $method log level name
+ * @param string $params message to log
+ * @return void
+ */
+ public function __call($method, $params)
+ {
+ $level = strtoupper($method);
+ if (($level = array_search($level, $this->_levels)) !== false) {
+ $this->log(array_shift($params), $level);
+ } else {
+ throw new Horde_Log_Exception('Bad log level');
+ }
+ }
+
+ /**
+ * Log a message at a level
+ *
+ * @param mixed $event Message to log, either an array or a string
+ * @param integer $level Log level of message, required if $message is a string
+ * @return void
+ */
+ public function log($event, $level = null)
+ {
+ if (empty($this->_handlers)) {
+ throw new Horde_Log_Exception('No handlers were added');
+ }
+
+ // Create an event array from the given arguments.
+ if (is_array($event)) {
+ // If we are passed an array, it must contain 'message'
+ // and 'level' indices.
+ if (!isset($event['message'])) {
+ throw new Horde_Log_Exception('Event array did not contain a message');
+ }
+ if (!isset($event['level'])) {
+ if ($level === null) {
+ throw new Horde_Log_Exception('Event array did not contain a log level');
+ } else {
+ $event['level'] = $level;
+ }
+ }
+ } else {
+ // Create an event array from the message and level
+ // arguments.
+ $event = array('message' => $event, 'level' => $level);
+ }
+
+ if (!isset($this->_levels[$event['level']])) {
+ throw new Horde_Log_Exception('Bad log level');
+ }
+
+ // Fill in the level name and timestamp for filters, formatters, handlers
+ $event['levelName'] = $this->_levels[$event['level']];
+
+ if (!isset($event['timestamp'])) {
+ $event['timestamp'] = date('c');
+ }
+
+ // If any global filter rejects the event, don't log it.
+ foreach ($this->_filters as $filter) {
+ if (!$filter->accept($event)) {
+ return;
+ }
+ }
+
+ foreach ($this->_handlers as $handler) {
+ $handler->log($event);
+ }
+ }
+
+ /**
+ * Add a custom log level
+ *
+ * @param string $name Name of level
+ * @param integer $level Numeric level
+ * @return void
+ */
+ public function addLevel($name, $level)
+ {
+ // Log level names must be uppercase for predictability.
+ $name = strtoupper($name);
+
+ if (isset($this->_levels[$level])
+ || array_search($name, $this->_levels)) {
+ throw new Horde_Log_Exception('Existing log levels cannot be overwritten');
+ }
+
+ $this->_levels[$level] = $name;
+ }
+
+ /**
+ * Add a filter that will be applied before all log handlers.
+ * Before a message will be received by any of the handlers, it
+ * must be accepted by all filters added with this method.
+ *
+ * @param Horde_Log_Filter_Interface $filter
+ * @return void
+ */
+ public function addFilter($filter)
+ {
+ if (is_integer($filter)) {
+ $filter = new Horde_Log_Filter_Level($filter);
+ }
+
+ $this->_filters[] = $filter;
+ }
+
+ /**
+ * Add a handler. A handler is responsible for taking a log
+ * message and writing it out to storage.
+ *
+ * @param Horde_Log_Handler_Abstract $handler
+ * @return void
+ */
+ public function addHandler($handler)
+ {
+ $this->_handlers[] = $handler;
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Log</name>
+ <channel>pear.horde.org</channel>
+ <summary>Horde Logging library</summary>
+ <description>Horde Logging package with configurable handlers, filters, and formatting.
+ </description>
+ <lead>
+ <name>Chuck Hagenbuch</name>
+ <user>chuck</user>
+ <email>chuck@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <lead>
+ <name>Mike Naberezny</name>
+ <user>mnaberez</user>
+ <email>mike@maintainable.com</email>
+ <active>yes</active>
+ </lead>
+ <date>2007-10-21</date>
+ <time>23:26:00</time>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://opensource.org/licenses/bsd-license.php">BSD</license>
+ <notes>Initial Horde_Log release
+ </notes>
+ <contents>
+ <dir name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Log">
+ <dir name="Filter">
+ <file name="Interface.php" role="php" />
+ <file name="Level.php" role="php" />
+ <file name="Message.php" role="php" />
+ </dir> <!-- /lib/Horde/Log/Filter -->
+ <dir name="Formatter">
+ <file name="Interface.php" role="php" />
+ <file name="Simple.php" role="php" />
+ <file name="Xml.php" role="php" />
+ </dir> <!-- /lib/Horde/Log/Formatter -->
+ <dir name="Handler">
+ <file name="Base.php" role="php" />
+ <file name="Db.php" role="php" />
+ <file name="Firebug.php" role="php" />
+ <file name="Null.php" role="php" />
+ <file name="Stream.php" role="php" />
+ </dir> <!-- /lib/Horde/Log/Handler -->
+ <file name="Exception.php" role="php" />
+ <file name="Logger.php" role="php" />
+ </dir> <!-- /lib/Horde/Log -->
+ <file name="Log.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ </dir>
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2</min>
+ </php>
+ <pearinstaller>
+ <min>1.5.0</min>
+ </pearinstaller>
+ </required>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Log/Exception.php" as="Horde/Log/Exception.php" />
+ <install name="lib/Horde/Log/Filter/Interface.php" as="Horde/Log/Filter/Interface.php" />
+ <install name="lib/Horde/Log/Filter/Level.php" as="Horde/Log/Filter/Level.php" />
+ <install name="lib/Horde/Log/Filter/Message.php" as="Horde/Log/Filter/Message.php" />
+ <install name="lib/Horde/Log/Formatter/Interface.php" as="Horde/Log/Formatter/Interface.php" />
+ <install name="lib/Horde/Log/Formatter/Simple.php" as="Horde/Log/Formatter/Simple.php" />
+ <install name="lib/Horde/Log/Formatter/Xml.php" as="Horde/Log/Formatter/Xml.php" />
+ <install name="lib/Horde/Log/Handler/Base.php" as="Horde/Log/Handler/Base.php" />
+ <install name="lib/Horde/Log/Handler/Db.php" as="Horde/Log/Handler/Db.php" />
+ <install name="lib/Horde/Log/Handler/Firebug.php" as="Horde/Log/Handler/Firebug.php" />
+ <install name="lib/Horde/Log/Handler/Null.php" as="Horde/Log/Handler/Null.php" />
+ <install name="lib/Horde/Log/Handler/Stream.php" as="Horde/Log/Handler/Stream.php" />
+ <install name="lib/Horde/Log/Logger.php" as="Horde/Log/Logger.php" />
+ <install name="lib/Horde/Log.php" as="Horde/Log.php" />
+ </filelist>
+ </phprelease>
+</package>
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+ define('PHPUnit_MAIN_METHOD', 'Horde_Log_AllTests::main');
+}
+
+require_once 'PHPUnit/Framework/TestSuite.php';
+require_once 'PHPUnit/TextUI/TestRunner.php';
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_AllTests
+{
+
+ public static function main()
+ {
+ PHPUnit_TextUI_TestRunner::run(self::suite());
+ }
+
+ public static function suite()
+ {
+ set_include_path(dirname(__FILE__) . '/../../../lib' . PATH_SEPARATOR . get_include_path());
+ if (!spl_autoload_functions()) {
+ spl_autoload_register(create_function('$class', '$filename = str_replace(array(\'::\', \'_\'), \'/\', $class); include "$filename.php";'));
+ }
+
+ $suite = new PHPUnit_Framework_TestSuite('Horde_Log');
+
+ $basedir = dirname(__FILE__);
+ $baseregexp = preg_quote($basedir . DIRECTORY_SEPARATOR, '/');
+
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basedir)) as $file) {
+ if ($file->isFile() && preg_match('/Test.php$/', $file->getFilename())) {
+ $pathname = $file->getPathname();
+ require $pathname;
+
+ $class = 'Horde_Log_' . str_replace(DIRECTORY_SEPARATOR, '_',
+ preg_replace("/^$baseregexp(.*)\.php/", '\\1', $pathname));
+ $suite->addTestSuite($class);
+ }
+ }
+
+ return $suite;
+ }
+
+}
+
+if (PHPUnit_MAIN_METHOD == 'Horde_Log_AllTests::main') {
+ Horde_Log_AllTests::main();
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Filter_ChainingTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ date_default_timezone_set('America/New_York');
+
+ $this->log = fopen('php://memory', 'w');
+ $this->logger = new Horde_Log_Logger();
+ $this->logger->addHandler(new Horde_Log_Handler_Stream($this->log));
+ }
+
+ public function tearDown()
+ {
+ fclose($this->log);
+ }
+
+ public function testFilterAllHandlers()
+ {
+ // filter out anything above a WARNing for all handlers
+ $this->logger->addFilter(Horde_Log::WARN);
+
+ $this->logger->info($ignored = 'info-message-ignored');
+ $this->logger->warn($logged = 'warn-message-logged');
+
+ rewind($this->log);
+ $logdata = stream_get_contents($this->log);
+
+ $this->assertNotContains($ignored, $logdata);
+ $this->assertContains($logged, $logdata);
+ }
+
+
+ public function testFilterOnSpecificHandler()
+ {
+ $log2 = fopen('php://memory', 'w');
+ $handler2 = new Horde_Log_Handler_Stream($log2);
+ $handler2->addFilter(Horde_Log::ERR);
+
+ $this->logger->addHandler($handler2);
+
+ $this->logger->warn($warn = 'warn-message');
+ $this->logger->err($err = 'err-message');
+
+ rewind($this->log);
+ $logdata = stream_get_contents($this->log);
+ $this->assertContains($warn, $logdata);
+ $this->assertContains($err, $logdata);
+
+ rewind($log2);
+ $logdata = stream_get_contents($log2);
+ $this->assertContains($err, $logdata);
+ $this->assertNotContains($warn, $logdata);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Filter_LevelTest extends PHPUnit_Framework_TestCase
+{
+
+ public function setUp()
+ {
+ // accept at or below level 2
+ $this->filter = new Horde_Log_Filter_Level(2);
+ }
+
+ public function testLevelFilterAccept()
+ {
+ $this->assertTrue($this->filter->accept(array('message' => '', 'level' => 2)));
+ $this->assertTrue($this->filter->accept(array('message' => '', 'level' => 1)));
+ }
+
+ public function testLevelFilterReject()
+ {
+ $this->assertFalse($this->filter->accept(array('message' => '', 'level' => 3)));
+ }
+
+ public function testConstructorThrowsOnInvalidLevel()
+ {
+ try {
+ new Horde_Log_Filter_Level('foo');
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/must be an integer/i', $e->getMessage());
+ }
+ }
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Filter_MessageTest extends PHPUnit_Framework_TestCase
+{
+
+ public function testMessageFilterRecognizesInvalidRegularExpression()
+ {
+ try {
+ $filter = new Horde_Log_Filter_Message('invalid regexp');
+ $this->fail();
+ } catch (Horde_Log_Exception $e) {
+ $this->assertRegexp('/invalid reg/i', $e->getMessage());
+ }
+ }
+
+ public function testMessageFilter()
+ {
+ $filter = new Horde_Log_Filter_Message('/accept/');
+ $this->assertTrue($filter->accept(array('message' => 'foo accept bar', 'level' => 0)));
+ $this->assertFalse($filter->accept(array('message' => 'foo reject bar', 'level' => 0)));
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Formatter_SimpleTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstructorThrowsOnBadFormatString()
+ {
+ try {
+ new Horde_Log_Formatter_Simple(1);
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/must be a string/i', $e->getMessage());
+ }
+ }
+
+ public function testDefaultFormat()
+ {
+ $f = new Horde_Log_Formatter_Simple();
+ $line = $f->format(array('message' => $message = 'message',
+ 'level' => $level = Horde_Log::ALERT,
+ 'levelName' => $levelName = 'ALERT'));
+
+ $this->assertContains($message, $line);
+ $this->assertContains($levelName, $line);
+ }
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Formatter_XmlTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ date_default_timezone_set('America/New_York');
+ }
+
+ public function testDefaultFormat()
+ {
+ $f = new Horde_Log_Formatter_Xml();
+ $line = $f->format(array('message' => $message = 'message', 'level' => $level = 1));
+
+ $this->assertContains($message, $line);
+ $this->assertContains((string)$level, $line);
+ }
+
+ public function testXmlDeclarationIsStripped()
+ {
+ $f = new Horde_Log_Formatter_Xml();
+ $line = $f->format(array('message' => $message = 'message', 'level' => $level = 1));
+
+ $this->assertNotContains('<\?xml version=', $line);
+ }
+
+ public function testXmlValidates()
+ {
+ $f = new Horde_Log_Formatter_Xml();
+ $line = $f->format(array('message' => $message = 'message', 'level' => $level = 1));
+
+ $sxml = @simplexml_load_string($line);
+ $this->assertType('SimpleXMLElement', $sxml, 'Formatted XML is invalid');
+ }
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Handler_DbTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ $this->tableName = 'db-table-name';
+
+ $this->db = new Horde_Log_Handler_DbTest_MockDbAdapter();
+ $this->handler = new Horde_Log_Handler_Db($this->db, $this->tableName);
+ }
+
+ public function testWriteWithDefaults()
+ {
+ // log to the mock db adapter
+ $message = 'message-to-log';
+ $level = 2;
+ $this->handler->write(array('message' => $message, 'level' => $level));
+
+ // insert should be called once...
+ $this->assertContains('insert', array_keys($this->db->calls));
+ $this->assertEquals(1, count($this->db->calls['insert']));
+
+ // ...with the correct table and binds for the database
+ $binds = array('message' => $message,
+ 'level' => $level);
+ $this->assertEquals(array($this->tableName, $binds),
+ $this->db->calls['insert'][0]);
+ }
+
+ public function testWriteUsesOptionalCustomColumns()
+ {
+ $this->handler->setOption('fieldMessage', $messageField = 'new-message-field');
+ $this->handler->setOption('fieldLevel', $levelField = 'new-level-field');
+
+ // log to the mock db adapter
+ $message = 'message-to-log';
+ $level = 2;
+ $this->handler->write(array('message' => $message, 'level' => $level));
+
+ // insert should be called once...
+ $this->assertContains('insert', array_keys($this->db->calls));
+ $this->assertEquals(1, count($this->db->calls['insert']));
+
+ // ...with the correct table and binds for the database
+ $binds = array($messageField => $message,
+ $levelField => $level);
+ $this->assertEquals(array($this->tableName, $binds),
+ $this->db->calls['insert'][0]);
+ }
+}
+
+
+class Horde_Log_Handler_DbTest_MockDbAdapter
+{
+ public $calls = array();
+
+ public function __call($method, $params)
+ {
+ $this->calls[$method][] = $params;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Handler_FirebugTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ date_default_timezone_set('America/New_York');
+ }
+
+ public function testSettingBadOptionThrows()
+ {
+ try {
+ $handler = new Horde_Log_Handler_Stream('php://memory');
+ $handler->setOption('foo', 42);
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/unknown option/i', $e->getMessage());
+ }
+ }
+
+ public function testWrite()
+ {
+ ob_start();
+
+ $handler = new Horde_Log_Handler_Firebug();
+ $handler->write(array('message' => $message = 'message-to-log',
+ 'level' => $level = Horde_Log::ALERT,
+ 'levelName' => $levelName = 'ALERT',
+ 'timestamp' => date('c')));
+
+ $contents = ob_get_clean();
+
+ $date = '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}-\d{2}:\d{2}';
+
+ $this->assertRegExp("/console.error\(\"$date $levelName: $message\"\);/", $contents);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Handler_NullTest extends PHPUnit_Framework_TestCase
+{
+ public function testWrite()
+ {
+ $handler = new Horde_Log_Handler_Null();
+ $this->assertTrue($handler->write(array('message' => 'foo', 'level' => 42)));
+ }
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Handler_StreamTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ date_default_timezone_set('America/New_York');
+ }
+
+ public function testConstructorThrowsWhenResourceIsNotStream()
+ {
+ $resource = xml_parser_create();
+ try {
+ new Horde_Log_Handler_Stream($resource);
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/not a stream/i', $e->getMessage());
+ }
+ xml_parser_free($resource);
+ }
+
+ public function testConstructorWithValidStream()
+ {
+ $stream = fopen('php://memory', 'a');
+ new Horde_Log_Handler_Stream($stream);
+ }
+
+ public function testConstructorWithValidUrl()
+ {
+ new Horde_Log_Handler_Stream('php://memory');
+ }
+
+ public function testConstructorThrowsWhenModeSpecifiedForExistingStream()
+ {
+ $stream = fopen('php://memory', 'a');
+ try {
+ new Horde_Log_Handler_Stream($stream, 'w');
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/existing stream/i', $e->getMessage());
+ }
+ }
+
+ public function testConstructorThrowsWhenStreamCannotBeOpened()
+ {
+ try {
+ new Horde_Log_Handler_Stream('');
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/cannot be opened/i', $e->getMessage());
+ }
+ }
+
+ public function testSettingBadOptionThrows()
+ {
+ try {
+ $handler = new Horde_Log_Handler_Stream('php://memory');
+ $handler->setOption('foo', 42);
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/unknown option/i', $e->getMessage());
+ }
+ }
+
+ public function testWrite()
+ {
+ $stream = fopen('php://memory', 'a');
+
+ $handler = new Horde_Log_Handler_Stream($stream);
+ $handler->write(array('message' => $message = 'message-to-log',
+ 'level' => $level = Horde_Log::ALERT,
+ 'levelName' => $levelName = 'ALERT',
+ 'timestamp' => date('c')));
+
+ rewind($stream);
+ $contents = stream_get_contents($stream);
+ fclose($stream);
+
+ $date = '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}-\d{2}:\d{2}';
+
+ $this->assertRegExp("/$date $levelName: $message/", $contents);
+ }
+
+ public function testWriteThrowsWhenStreamWriteFails()
+ {
+ $stream = fopen('php://memory', 'a');
+ $handler = new Horde_Log_Handler_Stream($stream);
+ fclose($stream);
+
+ try {
+ $handler->write(array('message' => 'foo', 'level' => 1));
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/unable to write/i', $e->getMessage());
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * This package is based on Zend_Log from the Zend Framework
+ * (http://framework.zend.com). Both that package and this
+ * one were written by Mike Naberezny and Chuck Hagenbuch.
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author Mike Naberezny <mike@maintainable.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_LogTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ date_default_timezone_set('America/New_York');
+
+ $this->log = fopen('php://memory', 'a');
+ $this->handler = new Horde_Log_Handler_Stream($this->log);
+ }
+
+ // Handlers
+
+ public function testHandlerCanBeAddedWithConstructor()
+ {
+ $logger = new Horde_Log_Logger($this->handler);
+ $logger->log($message = 'message-to-long', Horde_Log::INFO);
+
+ rewind($this->log);
+ $this->assertContains($message, stream_get_contents($this->log));
+ }
+
+ public function testaddHandler()
+ {
+ $logger = new Horde_Log_Logger();
+ $logger->addHandler($this->handler);
+ $logger->log($message = 'message-to-log', Horde_Log::INFO);
+
+ rewind($this->log);
+ $this->assertContains($message, stream_get_contents($this->log));
+ }
+
+ public function testaddHandlerAddsMultipleHandlers()
+ {
+ $logger = new Horde_Log_Logger();
+
+ // create handlers for two separate streams of temporary memory
+ $log1 = fopen('php://memory', 'a');
+ $handler1 = new Horde_Log_Handler_Stream($log1);
+ $log2 = fopen('php://memory', 'a');
+ $handler2 = new Horde_Log_Handler_Stream($log2);
+
+ // add the handlers
+ $logger->addHandler($handler1);
+ $logger->addHandler($handler2);
+
+ // log to both handlers
+ $logger->log($message = 'message-sent-to-both-logs', Horde_Log::INFO);
+
+ // verify both handlers were called by the logger
+ rewind($log1);
+ $this->assertContains($message, stream_get_contents($log1));
+ rewind($log2);
+ $this->assertContains($message, stream_get_contents($log2));
+
+ // prove the two memory streams are different
+ // and both handlers were indeed called
+ fwrite($log1, 'foo');
+ $this->assertNotEquals(ftell($log1), ftell($log2));
+ }
+
+ public function testLoggerThrowsWhenNoHandlers()
+ {
+ $logger = new Horde_Log_Logger();
+ try {
+ $logger->log('message', Horde_Log::INFO);
+ $this->fail();
+ } catch (Horde_Log_Exception $e) {
+ $this->assertRegexp('/no handler/i', $e->getMessage());
+ }
+ }
+
+ // Levels
+
+ public function testLogThrowsOnBadLogLevel()
+ {
+ $logger = new Horde_Log_Logger($this->handler);
+ try {
+ $logger->log('foo', 42);
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/bad log level/i', $e->getMessage());
+ }
+ }
+
+ public function testLogThrough__callThrowsOnBadLogLevel()
+ {
+ $logger = new Horde_Log_Logger($this->handler);
+ try {
+ $logger->nonexistantLevel('');
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/bad log level/i', $e->getMessage());
+ }
+ }
+
+ public function testAddingLevelThrowsWhenOverridingBuiltinLogLevel()
+ {
+ try {
+ $logger = new Horde_Log_Logger($this->handler);
+ $logger->addLevel('BOB', 0);
+ $this->fail();
+ } catch (Exception $e) {
+ $this->assertType('Horde_Log_Exception', $e);
+ $this->assertRegExp('/existing log level/i', $e->getMessage());
+ }
+
+ }
+
+ public function testAddLogLevel()
+ {
+ $logger = new Horde_Log_Logger($this->handler);
+ $logger->addLevel($levelName = 'EIGHT', $level = 8);
+
+ $logger->eight($message = 'eight message');
+
+ rewind($this->log);
+ $logdata = stream_get_contents($this->log);
+ $this->assertContains($levelName, $logdata);
+ $this->assertContains($message, $logdata);
+ }
+}