Commit bbdf245d5c5cb4039c3e8baa8f18c647c46a1b59

Authored by Neil Blakey-Milner
1 parent 90aabaa4

Add the PEAR Log class, version 1.8.7.


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@3150 c91229c3-7414-0410-bfa2-8a42b809f60b
pear/Log.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + * $Horde: horde/lib/Log.php,v 1.15 2000/06/29 23:39:45 jon Exp $
  5 + *
  6 + * @version $Revision$
  7 + * @package Log
  8 + */
  9 +
  10 +define('PEAR_LOG_EMERG', 0); /** System is unusable */
  11 +define('PEAR_LOG_ALERT', 1); /** Immediate action required */
  12 +define('PEAR_LOG_CRIT', 2); /** Critical conditions */
  13 +define('PEAR_LOG_ERR', 3); /** Error conditions */
  14 +define('PEAR_LOG_WARNING', 4); /** Warning conditions */
  15 +define('PEAR_LOG_NOTICE', 5); /** Normal but significant */
  16 +define('PEAR_LOG_INFO', 6); /** Informational */
  17 +define('PEAR_LOG_DEBUG', 7); /** Debug-level messages */
  18 +
  19 +define('PEAR_LOG_ALL', bindec('11111111')); /** All messages */
  20 +define('PEAR_LOG_NONE', bindec('00000000')); /** No message */
  21 +
  22 +/* Log types for PHP's native error_log() function. */
  23 +define('PEAR_LOG_TYPE_SYSTEM', 0); /** Use PHP's system logger */
  24 +define('PEAR_LOG_TYPE_MAIL', 1); /** Use PHP's mail() function */
  25 +define('PEAR_LOG_TYPE_DEBUG', 2); /** Use PHP's debugging connection */
  26 +define('PEAR_LOG_TYPE_FILE', 3); /** Append to a file */
  27 +
  28 +/**
  29 + * The Log:: class implements both an abstraction for various logging
  30 + * mechanisms and the Subject end of a Subject-Observer pattern.
  31 + *
  32 + * @author Chuck Hagenbuch <chuck@horde.org>
  33 + * @author Jon Parise <jon@php.net>
  34 + * @since Horde 1.3
  35 + * @package Log
  36 + */
  37 +class Log
  38 +{
  39 + /**
  40 + * Indicates whether or not the log can been opened / connected.
  41 + *
  42 + * @var boolean
  43 + * @access private
  44 + */
  45 + var $_opened = false;
  46 +
  47 + /**
  48 + * Instance-specific unique identification number.
  49 + *
  50 + * @var integer
  51 + * @access private
  52 + */
  53 + var $_id = 0;
  54 +
  55 + /**
  56 + * The label that uniquely identifies this set of log messages.
  57 + *
  58 + * @var string
  59 + * @access private
  60 + */
  61 + var $_ident = '';
  62 +
  63 + /**
  64 + * The default priority to use when logging an event.
  65 + *
  66 + * @var integer
  67 + * @access private
  68 + */
  69 + var $_priority = PEAR_LOG_INFO;
  70 +
  71 + /**
  72 + * The bitmask of allowed log levels.
  73 + * @var integer
  74 + * @access private
  75 + */
  76 + var $_mask = PEAR_LOG_ALL;
  77 +
  78 + /**
  79 + * Holds all Log_observer objects that wish to be notified of new messages.
  80 + *
  81 + * @var array
  82 + * @access private
  83 + */
  84 + var $_listeners = array();
  85 +
  86 +
  87 + /**
  88 + * Attempts to return a concrete Log instance of type $handler.
  89 + *
  90 + * @param string $handler The type of concrete Log subclass to return.
  91 + * Attempt to dynamically include the code for
  92 + * this subclass. Currently, valid values are
  93 + * 'console', 'syslog', 'sql', 'file', and 'mcal'.
  94 + *
  95 + * @param string $name The name of the actually log file, table, or
  96 + * other specific store to use. Defaults to an
  97 + * empty string, with which the subclass will
  98 + * attempt to do something intelligent.
  99 + *
  100 + * @param string $ident The identity reported to the log system.
  101 + *
  102 + * @param array $conf A hash containing any additional configuration
  103 + * information that a subclass might need.
  104 + *
  105 + * @param int $level Log messages up to and including this level.
  106 + *
  107 + * @return object Log The newly created concrete Log instance, or an
  108 + * false on an error.
  109 + * @access public
  110 + * @since Log 1.0
  111 + */
  112 + function &factory($handler, $name = '', $ident = '', $conf = array(),
  113 + $level = PEAR_LOG_DEBUG)
  114 + {
  115 + $handler = strtolower($handler);
  116 + $class = 'Log_' . $handler;
  117 + $classfile = 'Log/' . $handler . '.php';
  118 +
  119 + /*
  120 + * Attempt to include our version of the named class, but don't treat
  121 + * a failure as fatal. The caller may have already included their own
  122 + * version of the named class.
  123 + */
  124 + @include_once $classfile;
  125 +
  126 + /* If the class exists, return a new instance of it. */
  127 + if (class_exists($class)) {
  128 + return new $class($name, $ident, $conf, $level);
  129 + }
  130 +
  131 + return false;
  132 + }
  133 +
  134 + /**
  135 + * Attempts to return a reference to a concrete Log instance of type
  136 + * $handler, only creating a new instance if no log instance with the same
  137 + * parameters currently exists.
  138 + *
  139 + * You should use this if there are multiple places you might create a
  140 + * logger, you don't want to create multiple loggers, and you don't want to
  141 + * check for the existance of one each time. The singleton pattern does all
  142 + * the checking work for you.
  143 + *
  144 + * <b>You MUST call this method with the $var = &Log::singleton() syntax.
  145 + * Without the ampersand (&) in front of the method name, you will not get
  146 + * a reference, you will get a copy.</b>
  147 + *
  148 + * @param string $handler The type of concrete Log subclass to return.
  149 + * Attempt to dynamically include the code for
  150 + * this subclass. Currently, valid values are
  151 + * 'console', 'syslog', 'sql', 'file', and 'mcal'.
  152 + *
  153 + * @param string $name The name of the actually log file, table, or
  154 + * other specific store to use. Defaults to an
  155 + * empty string, with which the subclass will
  156 + * attempt to do something intelligent.
  157 + *
  158 + * @param string $ident The identity reported to the log system.
  159 + *
  160 + * @param array $conf A hash containing any additional configuration
  161 + * information that a subclass might need.
  162 + *
  163 + * @param int $level Log messages up to and including this level.
  164 + *
  165 + * @return object Log The newly created concrete Log instance, or an
  166 + * false on an error.
  167 + * @access public
  168 + * @since Log 1.0
  169 + */
  170 + function &singleton($handler, $name = '', $ident = '', $conf = array(),
  171 + $level = PEAR_LOG_DEBUG)
  172 + {
  173 + static $instances;
  174 + if (!isset($instances)) $instances = array();
  175 +
  176 + $signature = serialize(array($handler, $name, $ident, $conf, $level));
  177 + if (!isset($instances[$signature])) {
  178 + $instances[$signature] = &Log::factory($handler, $name, $ident,
  179 + $conf, $level);
  180 + }
  181 +
  182 + return $instances[$signature];
  183 + }
  184 +
  185 + /**
  186 + * Abstract implementation of the open() method.
  187 + * @since Log 1.0
  188 + */
  189 + function open()
  190 + {
  191 + return false;
  192 + }
  193 +
  194 + /**
  195 + * Abstract implementation of the close() method.
  196 + * @since Log 1.0
  197 + */
  198 + function close()
  199 + {
  200 + return false;
  201 + }
  202 +
  203 + /**
  204 + * Abstract implementation of the flush() method.
  205 + * @since Log 1.8.2
  206 + */
  207 + function flush()
  208 + {
  209 + return false;
  210 + }
  211 +
  212 + /**
  213 + * Abstract implementation of the log() method.
  214 + * @since Log 1.0
  215 + */
  216 + function log($message, $priority = null)
  217 + {
  218 + return false;
  219 + }
  220 +
  221 + /**
  222 + * A convenience function for logging a emergency event. It will log a
  223 + * message at the PEAR_LOG_EMERG log level.
  224 + *
  225 + * @param mixed $message String or object containing the message
  226 + * to log.
  227 + *
  228 + * @return boolean True if the message was successfully logged.
  229 + *
  230 + * @access public
  231 + * @since Log 1.7.0
  232 + */
  233 + function emerg($message)
  234 + {
  235 + return $this->log($message, PEAR_LOG_EMERG);
  236 + }
  237 +
  238 + /**
  239 + * A convenience function for logging an alert event. It will log a
  240 + * message at the PEAR_LOG_ALERT log level.
  241 + *
  242 + * @param mixed $message String or object containing the message
  243 + * to log.
  244 + *
  245 + * @return boolean True if the message was successfully logged.
  246 + *
  247 + * @access public
  248 + * @since Log 1.7.0
  249 + */
  250 + function alert($message)
  251 + {
  252 + return $this->log($message, PEAR_LOG_ALERT);
  253 + }
  254 +
  255 + /**
  256 + * A convenience function for logging a critical event. It will log a
  257 + * message at the PEAR_LOG_CRIT log level.
  258 + *
  259 + * @param mixed $message String or object containing the message
  260 + * to log.
  261 + *
  262 + * @return boolean True if the message was successfully logged.
  263 + *
  264 + * @access public
  265 + * @since Log 1.7.0
  266 + */
  267 + function crit($message)
  268 + {
  269 + return $this->log($message, PEAR_LOG_CRIT);
  270 + }
  271 +
  272 + /**
  273 + * A convenience function for logging a error event. It will log a
  274 + * message at the PEAR_LOG_ERR log level.
  275 + *
  276 + * @param mixed $message String or object containing the message
  277 + * to log.
  278 + *
  279 + * @return boolean True if the message was successfully logged.
  280 + *
  281 + * @access public
  282 + * @since Log 1.7.0
  283 + */
  284 + function err($message)
  285 + {
  286 + return $this->log($message, PEAR_LOG_ERR);
  287 + }
  288 +
  289 + /**
  290 + * A convenience function for logging a warning event. It will log a
  291 + * message at the PEAR_LOG_WARNING log level.
  292 + *
  293 + * @param mixed $message String or object containing the message
  294 + * to log.
  295 + *
  296 + * @return boolean True if the message was successfully logged.
  297 + *
  298 + * @access public
  299 + * @since Log 1.7.0
  300 + */
  301 + function warning($message)
  302 + {
  303 + return $this->log($message, PEAR_LOG_WARNING);
  304 + }
  305 +
  306 + /**
  307 + * A convenience function for logging a notice event. It will log a
  308 + * message at the PEAR_LOG_NOTICE log level.
  309 + *
  310 + * @param mixed $message String or object containing the message
  311 + * to log.
  312 + *
  313 + * @return boolean True if the message was successfully logged.
  314 + *
  315 + * @access public
  316 + * @since Log 1.7.0
  317 + */
  318 + function notice($message)
  319 + {
  320 + return $this->log($message, PEAR_LOG_NOTICE);
  321 + }
  322 +
  323 + /**
  324 + * A convenience function for logging a information event. It will log a
  325 + * message at the PEAR_LOG_INFO log level.
  326 + *
  327 + * @param mixed $message String or object containing the message
  328 + * to log.
  329 + *
  330 + * @return boolean True if the message was successfully logged.
  331 + *
  332 + * @access public
  333 + * @since Log 1.7.0
  334 + */
  335 + function info($message)
  336 + {
  337 + return $this->log($message, PEAR_LOG_INFO);
  338 + }
  339 +
  340 + /**
  341 + * A convenience function for logging a debug event. It will log a
  342 + * message at the PEAR_LOG_DEBUG log level.
  343 + *
  344 + * @param mixed $message String or object containing the message
  345 + * to log.
  346 + *
  347 + * @return boolean True if the message was successfully logged.
  348 + *
  349 + * @access public
  350 + * @since Log 1.7.0
  351 + */
  352 + function debug($message)
  353 + {
  354 + return $this->log($message, PEAR_LOG_DEBUG);
  355 + }
  356 +
  357 + /**
  358 + * Returns the string representation of the message data.
  359 + *
  360 + * If $message is an object, _extractMessage() will attempt to extract
  361 + * the message text using a known method (such as a PEAR_Error object's
  362 + * getMessage() method). If a known method, cannot be found, the
  363 + * serialized representation of the object will be returned.
  364 + *
  365 + * If the message data is already a string, it will be returned unchanged.
  366 + *
  367 + * @param mixed $message The original message data. This may be a
  368 + * string or any object.
  369 + *
  370 + * @return string The string representation of the message.
  371 + *
  372 + * @access private
  373 + */
  374 + function _extractMessage($message)
  375 + {
  376 + /*
  377 + * If we've been given an object, attempt to extract the message using
  378 + * a known method. If we can't find such a method, default to the
  379 + * "human-readable" version of the object.
  380 + *
  381 + * We also use the human-readable format for arrays.
  382 + */
  383 + if (is_object($message)) {
  384 + if (method_exists($message, 'getmessage')) {
  385 + $message = $message->getMessage();
  386 + } else if (method_exists($message, 'tostring')) {
  387 + $message = $message->toString();
  388 + } else if (method_exists($message, '__tostring')) {
  389 + $message = (string)$message;
  390 + } else {
  391 + $message = print_r($message, true);
  392 + }
  393 + } else if (is_array($message)) {
  394 + if (isset($message['message'])) {
  395 + $message = $message['message'];
  396 + } else {
  397 + $message = print_r($message, true);
  398 + }
  399 + }
  400 +
  401 + /* Otherwise, we assume the message is a string. */
  402 + return $message;
  403 + }
  404 +
  405 + /**
  406 + * Returns the string representation of a PEAR_LOG_* integer constant.
  407 + *
  408 + * @param int $priority A PEAR_LOG_* integer constant.
  409 + *
  410 + * @return string The string representation of $level.
  411 + *
  412 + * @since Log 1.0
  413 + */
  414 + function priorityToString($priority)
  415 + {
  416 + $levels = array(
  417 + PEAR_LOG_EMERG => 'emergency',
  418 + PEAR_LOG_ALERT => 'alert',
  419 + PEAR_LOG_CRIT => 'critical',
  420 + PEAR_LOG_ERR => 'error',
  421 + PEAR_LOG_WARNING => 'warning',
  422 + PEAR_LOG_NOTICE => 'notice',
  423 + PEAR_LOG_INFO => 'info',
  424 + PEAR_LOG_DEBUG => 'debug'
  425 + );
  426 +
  427 + return $levels[$priority];
  428 + }
  429 +
  430 + /**
  431 + * Calculate the log mask for the given priority.
  432 + *
  433 + * @param integer $priority The priority whose mask will be calculated.
  434 + *
  435 + * @return integer The calculated log mask.
  436 + *
  437 + * @access public
  438 + * @since Log 1.7.0
  439 + */
  440 + function MASK($priority)
  441 + {
  442 + return (1 << $priority);
  443 + }
  444 +
  445 + /**
  446 + * Calculate the log mask for all priorities up to the given priority.
  447 + *
  448 + * @param integer $priority The maximum priority covered by this mask.
  449 + *
  450 + * @return integer The calculated log mask.
  451 + *
  452 + * @access public
  453 + * @since Log 1.7.0
  454 + */
  455 + function UPTO($priority)
  456 + {
  457 + return ((1 << ($priority + 1)) - 1);
  458 + }
  459 +
  460 + /**
  461 + * Set and return the level mask for the current Log instance.
  462 + *
  463 + * @param integer $mask A bitwise mask of log levels.
  464 + *
  465 + * @return integer The current level mask.
  466 + *
  467 + * @access public
  468 + * @since Log 1.7.0
  469 + */
  470 + function setMask($mask)
  471 + {
  472 + $this->_mask = $mask;
  473 +
  474 + return $this->_mask;
  475 + }
  476 +
  477 + /**
  478 + * Returns the current level mask.
  479 + *
  480 + * @return interger The current level mask.
  481 + *
  482 + * @access public
  483 + * @since Log 1.7.0
  484 + */
  485 + function getMask()
  486 + {
  487 + return $this->_mask;
  488 + }
  489 +
  490 + /**
  491 + * Check if the given priority is included in the current level mask.
  492 + *
  493 + * @param integer $priority The priority to check.
  494 + *
  495 + * @return boolean True if the given priority is included in the current
  496 + * log mask.
  497 + *
  498 + * @access private
  499 + * @since Log 1.7.0
  500 + */
  501 + function _isMasked($priority)
  502 + {
  503 + return (Log::MASK($priority) & $this->_mask);
  504 + }
  505 +
  506 + /**
  507 + * Returns the current default priority.
  508 + *
  509 + * @return integer The current default priority.
  510 + *
  511 + * @access public
  512 + * @since Log 1.8.4
  513 + */
  514 + function getPriority()
  515 + {
  516 + return $this->_priority;
  517 + }
  518 +
  519 + /**
  520 + * Sets the default priority to the specified value.
  521 + *
  522 + * @param integer $priority The new default priority.
  523 + *
  524 + * @access public
  525 + * @since Log 1.8.4
  526 + */
  527 + function setPriority($priority)
  528 + {
  529 + $this->_priority = $priority;
  530 + }
  531 +
  532 + /**
  533 + * Adds a Log_observer instance to the list of observers that are listening
  534 + * for messages emitted by this Log instance.
  535 + *
  536 + * @param object $observer The Log_observer instance to attach as a
  537 + * listener.
  538 + *
  539 + * @param boolean True if the observer is successfully attached.
  540 + *
  541 + * @access public
  542 + * @since Log 1.0
  543 + */
  544 + function attach(&$observer)
  545 + {
  546 + if (!is_a($observer, 'Log_observer')) {
  547 + return false;
  548 + }
  549 +
  550 + $this->_listeners[$observer->_id] = &$observer;
  551 +
  552 + return true;
  553 + }
  554 +
  555 + /**
  556 + * Removes a Log_observer instance from the list of observers.
  557 + *
  558 + * @param object $observer The Log_observer instance to detach from
  559 + * the list of listeners.
  560 + *
  561 + * @param boolean True if the observer is successfully detached.
  562 + *
  563 + * @access public
  564 + * @since Log 1.0
  565 + */
  566 + function detach($observer)
  567 + {
  568 + if (!is_a($observer, 'Log_observer') ||
  569 + !isset($this->_listeners[$observer->_id])) {
  570 + return false;
  571 + }
  572 +
  573 + unset($this->_listeners[$observer->_id]);
  574 +
  575 + return true;
  576 + }
  577 +
  578 + /**
  579 + * Informs each registered observer instance that a new message has been
  580 + * logged.
  581 + *
  582 + * @param array $event A hash describing the log event.
  583 + *
  584 + * @access private
  585 + */
  586 + function _announce($event)
  587 + {
  588 + foreach ($this->_listeners as $id => $listener) {
  589 + if ($event['priority'] <= $this->_listeners[$id]->_priority) {
  590 + $this->_listeners[$id]->notify($event);
  591 + }
  592 + }
  593 + }
  594 +
  595 + /**
  596 + * Indicates whether this is a composite class.
  597 + *
  598 + * @return boolean True if this is a composite class.
  599 + *
  600 + * @access public
  601 + * @since Log 1.0
  602 + */
  603 + function isComposite()
  604 + {
  605 + return false;
  606 + }
  607 +
  608 + /**
  609 + * Sets this Log instance's identification string.
  610 + *
  611 + * @param string $ident The new identification string.
  612 + *
  613 + * @access public
  614 + * @since Log 1.6.3
  615 + */
  616 + function setIdent($ident)
  617 + {
  618 + $this->_ident = $ident;
  619 + }
  620 +
  621 + /**
  622 + * Returns the current identification string.
  623 + *
  624 + * @return string The current Log instance's identification string.
  625 + *
  626 + * @access public
  627 + * @since Log 1.6.3
  628 + */
  629 + function getIdent()
  630 + {
  631 + return $this->_ident;
  632 + }
  633 +}
  634 +
  635 +?>
... ...
pear/Log/composite.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + * $Horde: horde/lib/Log/composite.php,v 1.2 2000/06/28 21:36:13 jon Exp $
  5 + *
  6 + * @version $Revision$
  7 + * @package Log
  8 + */
  9 +
  10 +/**
  11 + * The Log_composite:: class implements a Composite pattern which
  12 + * allows multiple Log implementations to receive the same events.
  13 + *
  14 + * @author Chuck Hagenbuch <chuck@horde.org>
  15 + * @author Jon Parise <jon@php.net>
  16 + *
  17 + * @since Horde 1.3
  18 + * @since Log 1.0
  19 + * @package Log
  20 + *
  21 + * @example composite.php Using the composite handler.
  22 + */
  23 +class Log_composite extends Log
  24 +{
  25 + /**
  26 + * Array holding all of the Log instances to which log events should be
  27 + * sent.
  28 + *
  29 + * @var array
  30 + * @access private
  31 + */
  32 + var $_children = array();
  33 +
  34 +
  35 + /**
  36 + * Constructs a new composite Log object.
  37 + *
  38 + * @param boolean $name This parameter is ignored.
  39 + * @param boolean $ident This parameter is ignored.
  40 + * @param boolean $conf This parameter is ignored.
  41 + * @param boolean $level This parameter is ignored.
  42 + *
  43 + * @access public
  44 + */
  45 + function Log_composite($name = false, $ident = false, $conf = false,
  46 + $level = PEAR_LOG_DEBUG)
  47 + {
  48 + }
  49 +
  50 + /**
  51 + * Opens the child connections.
  52 + *
  53 + * @access public
  54 + */
  55 + function open()
  56 + {
  57 + if (!$this->_opened) {
  58 + foreach ($this->_children as $id => $child) {
  59 + $this->_children[$id]->open();
  60 + }
  61 + $this->_opened = true;
  62 + }
  63 + }
  64 +
  65 + /**
  66 + * Closes any child instances.
  67 + *
  68 + * @access public
  69 + */
  70 + function close()
  71 + {
  72 + if ($this->_opened) {
  73 + foreach ($this->_children as $id => $child) {
  74 + $this->_children[$id]->close();
  75 + }
  76 + $this->_opened = false;
  77 + }
  78 + }
  79 +
  80 + /**
  81 + * Flushes all open child instances.
  82 + *
  83 + * @access public
  84 + * @since Log 1.8.2
  85 + */
  86 + function flush()
  87 + {
  88 + if ($this->_opened) {
  89 + foreach ($this->_children as $id => $child) {
  90 + $this->_children[$id]->flush();
  91 + }
  92 + }
  93 + }
  94 +
  95 + /**
  96 + * Sends $message and $priority to each child of this composite.
  97 + *
  98 + * @param mixed $message String or object containing the message
  99 + * to log.
  100 + * @param string $priority (optional) The priority of the message.
  101 + * Valid values are: PEAR_LOG_EMERG,
  102 + * PEAR_LOG_ALERT, PEAR_LOG_CRIT,
  103 + * PEAR_LOG_ERR, PEAR_LOG_WARNING,
  104 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and
  105 + * PEAR_LOG_DEBUG.
  106 + *
  107 + * @return boolean True if the entry is successfully logged.
  108 + *
  109 + * @access public
  110 + */
  111 + function log($message, $priority = null)
  112 + {
  113 + /* If a priority hasn't been specified, use the default value. */
  114 + if ($priority === null) {
  115 + $priority = $this->_priority;
  116 + }
  117 +
  118 + foreach ($this->_children as $id => $child) {
  119 + $this->_children[$id]->log($message, $priority);
  120 + }
  121 +
  122 + $this->_announce(array('priority' => $priority, 'message' => $message));
  123 +
  124 + return true;
  125 + }
  126 +
  127 + /**
  128 + * Returns true if this is a composite.
  129 + *
  130 + * @return boolean True if this is a composite class.
  131 + *
  132 + * @access public
  133 + */
  134 + function isComposite()
  135 + {
  136 + return true;
  137 + }
  138 +
  139 + /**
  140 + * Sets this identification string for all of this composite's children.
  141 + *
  142 + * @param string $ident The new identification string.
  143 + *
  144 + * @access public
  145 + * @since Log 1.6.7
  146 + */
  147 + function setIdent($ident)
  148 + {
  149 + foreach ($this->_children as $id => $child) {
  150 + $this->_children[$id]->setIdent($ident);
  151 + }
  152 + }
  153 +
  154 + /**
  155 + * Adds a Log instance to the list of children.
  156 + *
  157 + * @param object $child The Log instance to add.
  158 + *
  159 + * @return boolean True if the Log instance was successfully added.
  160 + *
  161 + * @access public
  162 + */
  163 + function addChild(&$child)
  164 + {
  165 + /* Make sure this is a Log instance. */
  166 + if (!is_a($child, 'Log')) {
  167 + return false;
  168 + }
  169 +
  170 + $this->_children[$child->_id] = &$child;
  171 +
  172 + return true;
  173 + }
  174 +
  175 + /**
  176 + * Removes a Log instance from the list of children.
  177 + *
  178 + * @param object $child The Log instance to remove.
  179 + *
  180 + * @return boolean True if the Log instance was successfully removed.
  181 + *
  182 + * @access public
  183 + */
  184 + function removeChild($child)
  185 + {
  186 + if (!is_a($child, 'Log') || !isset($this->_children[$child->_id])) {
  187 + return false;
  188 + }
  189 +
  190 + unset($this->_children[$child->_id]);
  191 +
  192 + return true;
  193 + }
  194 +}
  195 +
  196 +?>
... ...
pear/Log/console.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + *
  5 + * @version $Revision$
  6 + * @package Log
  7 + */
  8 +
  9 +/**
  10 + * The Log_console class is a concrete implementation of the Log::
  11 + * abstract class which writes message to the text console.
  12 + *
  13 + * @author Jon Parise <jon@php.net>
  14 + * @since Log 1.1
  15 + * @package Log
  16 + *
  17 + * @example console.php Using the console handler.
  18 + */
  19 +class Log_console extends Log
  20 +{
  21 + /**
  22 + * Handle to the current output stream.
  23 + * @var resource
  24 + * @access private
  25 + */
  26 + var $_stream = STDOUT;
  27 +
  28 + /**
  29 + * Should the output be buffered or displayed immediately?
  30 + * @var string
  31 + * @access private
  32 + */
  33 + var $_buffering = false;
  34 +
  35 + /**
  36 + * String holding the buffered output.
  37 + * @var string
  38 + * @access private
  39 + */
  40 + var $_buffer = '';
  41 +
  42 + /**
  43 + * String containing the format of a log line.
  44 + * @var string
  45 + * @access private
  46 + */
  47 + var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
  48 +
  49 + /**
  50 + * String containing the timestamp format. It will be passed directly to
  51 + * strftime(). Note that the timestamp string will generated using the
  52 + * current locale.
  53 + * @var string
  54 + * @access private
  55 + */
  56 + var $_timeFormat = '%b %d %H:%M:%S';
  57 +
  58 + /**
  59 + * Hash that maps canonical format keys to position arguments for the
  60 + * "line format" string.
  61 + * @var array
  62 + * @access private
  63 + */
  64 + var $_formatMap = array('%{timestamp}' => '%1$s',
  65 + '%{ident}' => '%2$s',
  66 + '%{priority}' => '%3$s',
  67 + '%{message}' => '%4$s',
  68 + '%\{' => '%%{');
  69 +
  70 + /**
  71 + * Constructs a new Log_console object.
  72 + *
  73 + * @param string $name Ignored.
  74 + * @param string $ident The identity string.
  75 + * @param array $conf The configuration array.
  76 + * @param int $level Log messages up to and including this level.
  77 + * @access public
  78 + */
  79 + function Log_console($name, $ident = '', $conf = array(),
  80 + $level = PEAR_LOG_DEBUG)
  81 + {
  82 + $this->_id = md5(microtime());
  83 + $this->_ident = $ident;
  84 + $this->_mask = Log::UPTO($level);
  85 +
  86 + if (!empty($conf['stream'])) {
  87 + $this->_stream = $conf['stream'];
  88 + }
  89 +
  90 + if (isset($conf['buffering'])) {
  91 + $this->_buffering = $conf['buffering'];
  92 + }
  93 +
  94 + if (!empty($conf['lineFormat'])) {
  95 + $this->_lineFormat = str_replace(array_keys($this->_formatMap),
  96 + array_values($this->_formatMap),
  97 + $conf['lineFormat']);
  98 + }
  99 +
  100 + if (!empty($conf['timeFormat'])) {
  101 + $this->_timeFormat = $conf['timeFormat'];
  102 + }
  103 +
  104 + /*
  105 + * If output buffering has been requested, we need to register a
  106 + * shutdown function that will dump the buffer upon termination.
  107 + */
  108 + if ($this->_buffering) {
  109 + register_shutdown_function(array(&$this, '_Log_console'));
  110 + }
  111 + }
  112 +
  113 + /**
  114 + * Destructor
  115 + */
  116 + function _Log_console()
  117 + {
  118 + $this->flush();
  119 + }
  120 +
  121 + /**
  122 + * Flushes all pending ("buffered") data to the output stream.
  123 + *
  124 + * @access public
  125 + * @since Log 1.8.2
  126 + */
  127 + function flush()
  128 + {
  129 + /*
  130 + * If output buffering is enabled, dump the contents of the buffer to
  131 + * the output stream.
  132 + */
  133 + if ($this->_buffering && (strlen($this->_buffer) > 0)) {
  134 + fwrite($this->_stream, $this->_buffer);
  135 + $this->_buffer = '';
  136 + }
  137 +
  138 + return fflush($this->_stream);
  139 + }
  140 +
  141 + /**
  142 + * Writes $message to the text console. Also, passes the message
  143 + * along to any Log_observer instances that are observing this Log.
  144 + *
  145 + * @param mixed $message String or object containing the message to log.
  146 + * @param string $priority The priority of the message. Valid
  147 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  148 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  149 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  150 + * @return boolean True on success or false on failure.
  151 + * @access public
  152 + */
  153 + function log($message, $priority = null)
  154 + {
  155 + /* If a priority hasn't been specified, use the default value. */
  156 + if ($priority === null) {
  157 + $priority = $this->_priority;
  158 + }
  159 +
  160 + /* Abort early if the priority is above the maximum logging level. */
  161 + if (!$this->_isMasked($priority)) {
  162 + return false;
  163 + }
  164 +
  165 + /* Extract the string representation of the message. */
  166 + $message = $this->_extractMessage($message);
  167 +
  168 + /* Build the string containing the complete log line. */
  169 + $line = sprintf($this->_lineFormat, strftime($this->_timeFormat),
  170 + $this->_ident, $this->priorityToString($priority),
  171 + $message) . "\n";
  172 +
  173 + /*
  174 + * If buffering is enabled, append this line to the output buffer.
  175 + * Otherwise, print the line to the output stream immediately.
  176 + */
  177 + if ($this->_buffering) {
  178 + $this->_buffer .= $line;
  179 + } else {
  180 + fwrite($this->_stream, $line);
  181 + }
  182 +
  183 + /* Notify observers about this log message. */
  184 + $this->_announce(array('priority' => $priority, 'message' => $message));
  185 +
  186 + return true;
  187 + }
  188 +}
  189 +
  190 +?>
... ...
pear/Log/daemon.php 0 → 100644
  1 +<?php
  2 +// $Id$
  3 +
  4 +/**
  5 + * The Log_daemon class is a concrete implementation of the Log::
  6 + * abstract class which sends messages to syslog daemon on UNIX-like machines.
  7 + * This class uses the syslog protocol: http://www.ietf.org/rfc/rfc3164.txt
  8 + *
  9 + * @author Bart van der Schans <schans@dds.nl>
  10 + * @version $Revision$
  11 + * @package Log
  12 + */
  13 +class Log_daemon extends Log {
  14 +
  15 + /**
  16 + * Integer holding the log facility to use.
  17 + * @var string
  18 + */
  19 + var $_name = LOG_DAEMON;
  20 +
  21 + /**
  22 + * Var holding the resource pointer to the socket
  23 + * @var resource
  24 + */
  25 + var $_socket;
  26 +
  27 + /**
  28 + * The ip address or servername
  29 + * @see http://www.php.net/manual/en/transports.php
  30 + * @var string
  31 + */
  32 + var $_ip = '127.0.0.1';
  33 +
  34 + /**
  35 + * Protocol to use (tcp, udp, etc.)
  36 + * @see http://www.php.net/manual/en/transports.php
  37 + * @var string
  38 + */
  39 + var $_proto = 'udp';
  40 +
  41 + /**
  42 + * Port to connect to
  43 + * @var int
  44 + */
  45 + var $_port = 514;
  46 +
  47 + /**
  48 + * Maximum message length in bytes
  49 + * @var int
  50 + */
  51 + var $_maxsize = 4096;
  52 +
  53 + /**
  54 + * Socket timeout in seconds
  55 + * @var int
  56 + */
  57 + var $_timeout = 1;
  58 +
  59 +
  60 + /**
  61 + * Constructs a new syslog object.
  62 + *
  63 + * @param string $name The syslog facility.
  64 + * @param string $ident The identity string.
  65 + * @param array $conf The configuration array.
  66 + * @param int $maxLevel Maximum level at which to log.
  67 + * @access public
  68 + */
  69 + function Log_daemon($name, $ident = '', $conf = array(),
  70 + $level = PEAR_LOG_DEBUG)
  71 + {
  72 + /* Ensure we have a valid integer value for $name. */
  73 + if (empty($name) || !is_int($name)) {
  74 + $name = LOG_SYSLOG;
  75 + }
  76 +
  77 + $this->_id = md5(microtime());
  78 + $this->_name = $name;
  79 + $this->_ident = $ident;
  80 + $this->_mask = Log::UPTO($level);
  81 +
  82 + if (isset($conf['ip'])) {
  83 + $this->_ip = $conf['ip'];
  84 + }
  85 + if (isset($conf['proto'])) {
  86 + $this->_proto = $conf['proto'];
  87 + }
  88 + if (isset($conf['port'])) {
  89 + $this->_port = $conf['port'];
  90 + }
  91 + if (isset($conf['maxsize'])) {
  92 + $this->_maxsize = $conf['maxsize'];
  93 + }
  94 + if (isset($conf['timeout'])) {
  95 + $this->_timeout = $conf['timeout'];
  96 + }
  97 + $this->_proto = $this->_proto . '://';
  98 +
  99 + register_shutdown_function(array(&$this, '_Log_daemon'));
  100 + }
  101 +
  102 + /**
  103 + * Destructor.
  104 + *
  105 + * @access private
  106 + */
  107 + function _Log_daemon()
  108 + {
  109 + $this->close();
  110 + }
  111 +
  112 + /**
  113 + * Opens a connection to the system logger, if it has not already
  114 + * been opened. This is implicitly called by log(), if necessary.
  115 + * @access public
  116 + */
  117 + function open()
  118 + {
  119 + if (!$this->_opened) {
  120 + $this->_opened = (bool)($this->_socket = @fsockopen(
  121 + $this->_proto . $this->_ip,
  122 + $this->_port,
  123 + $errno,
  124 + $errstr,
  125 + $this->_timeout));
  126 + }
  127 + return $this->_opened;
  128 + }
  129 +
  130 + /**
  131 + * Closes the connection to the system logger, if it is open.
  132 + * @access public
  133 + */
  134 + function close()
  135 + {
  136 + if ($this->_opened) {
  137 + $this->_opened = false;
  138 + return fclose($this->_socket);
  139 + }
  140 + return true;
  141 + }
  142 +
  143 + /**
  144 + * Sends $message to the currently open syslog connection. Calls
  145 + * open() if necessary. Also passes the message along to any Log_observer
  146 + * instances that are observing this Log.
  147 + *
  148 + * @param string $message The textual message to be logged.
  149 + * @param int $priority (optional) The priority of the message. Valid
  150 + * values are: LOG_EMERG, LOG_ALERT, LOG_CRIT,
  151 + * LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO,
  152 + * and LOG_DEBUG. The default is LOG_INFO.
  153 + * @access public
  154 + */
  155 + function log($message, $priority = null)
  156 + {
  157 + /* If a priority hasn't been specified, use the default value. */
  158 + if ($priority === null) {
  159 + $priority = $this->_priority;
  160 + }
  161 +
  162 + /* Abort early if the priority is above the maximum logging level. */
  163 + if (!$this->_isMasked($priority)) {
  164 + return false;
  165 + }
  166 +
  167 + /* If the connection isn't open and can't be opened, return failure. */
  168 + if (!$this->_opened && !$this->open()) {
  169 + return false;
  170 + }
  171 +
  172 + /* Extract the string representation of the message. */
  173 + $message = $this->_extractMessage($message);
  174 +
  175 + /* Set the facility level. */
  176 + $facility_level = intval($this->_name) +
  177 + intval($this->_toSyslog($priority));
  178 +
  179 + /* Prepend ident info. */
  180 + if (!empty($this->_ident)) {
  181 + $message = $this->_ident . ' ' . $message;
  182 + }
  183 +
  184 + /* Check for message length. */
  185 + if (strlen($message) > $this->_maxsize) {
  186 + $message = substr($message, 0, ($this->_maxsize) - 10) . ' [...]';
  187 + }
  188 +
  189 + /* Write to socket. */
  190 + fwrite($this->_socket, '<' . $facility_level . '>' . $message . "\n");
  191 +
  192 + $this->_announce(array('priority' => $priority, 'message' => $message));
  193 + }
  194 +
  195 + /**
  196 + * Converts a PEAR_LOG_* constant into a syslog LOG_* constant.
  197 + *
  198 + * This function exists because, under Windows, not all of the LOG_*
  199 + * constants have unique values. Instead, the PEAR_LOG_* were introduced
  200 + * for global use, with the conversion to the LOG_* constants kept local to
  201 + * to the syslog driver.
  202 + *
  203 + * @param int $priority PEAR_LOG_* value to convert to LOG_* value.
  204 + *
  205 + * @return The LOG_* representation of $priority.
  206 + *
  207 + * @access private
  208 + */
  209 + function _toSyslog($priority)
  210 + {
  211 + static $priorities = array(
  212 + PEAR_LOG_EMERG => LOG_EMERG,
  213 + PEAR_LOG_ALERT => LOG_ALERT,
  214 + PEAR_LOG_CRIT => LOG_CRIT,
  215 + PEAR_LOG_ERR => LOG_ERR,
  216 + PEAR_LOG_WARNING => LOG_WARNING,
  217 + PEAR_LOG_NOTICE => LOG_NOTICE,
  218 + PEAR_LOG_INFO => LOG_INFO,
  219 + PEAR_LOG_DEBUG => LOG_DEBUG
  220 + );
  221 +
  222 + /* If we're passed an unknown priority, default to LOG_INFO. */
  223 + if (!is_int($priority) || !in_array($priority, $priorities)) {
  224 + return LOG_INFO;
  225 + }
  226 +
  227 + return $priorities[$priority];
  228 + }
  229 +}
... ...
pear/Log/display.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + *
  5 + * @version $Revision$
  6 + * @package Log
  7 + */
  8 +
  9 +/**
  10 + * The Log_display class is a concrete implementation of the Log::
  11 + * abstract class which writes message into browser in usual PHP maner.
  12 + * This may be useful because when you use PEAR::setErrorHandling in
  13 + * PEAR_ERROR_CALLBACK mode error messages are not displayed by
  14 + * PHP error handler.
  15 + *
  16 + * @author Paul Yanchenko <pusher@inaco.ru>
  17 + * @since Log 1.8.0
  18 + * @package Log
  19 + *
  20 + * @example display.php Using the display handler.
  21 + */
  22 +class Log_display extends Log
  23 +{
  24 + /**
  25 + * String to output before an error message
  26 + * @var string
  27 + * @access private
  28 + */
  29 + var $_error_prepend = '';
  30 +
  31 + /**
  32 + * String to output after an error message
  33 + * @var string
  34 + * @access private
  35 + */
  36 + var $_error_append = '';
  37 +
  38 +
  39 + /**
  40 + * Constructs a new Log_display object.
  41 + *
  42 + * @param string $name Ignored.
  43 + * @param string $ident The identity string.
  44 + * @param array $conf The configuration array.
  45 + * @param int $level Log messages up to and including this level.
  46 + * @access public
  47 + */
  48 + function Log_display($name = '', $ident = '', $conf = array(),
  49 + $level = PEAR_LOG_DEBUG)
  50 + {
  51 + $this->_id = md5(microtime());
  52 + $this->_ident = $ident;
  53 + $this->_mask = Log::UPTO($level);
  54 +
  55 + if (!empty($conf['error_prepend'])) {
  56 + $this->_error_prepend = $conf['error_prepend'];
  57 + } else {
  58 + $this->_error_prepend = ini_get('error_prepend_string');
  59 + }
  60 +
  61 + if (!empty($conf['error_append'])) {
  62 + $this->_error_append = $conf['error_append'];
  63 + } else {
  64 + $this->_error_append = ini_get('error_append_string');
  65 + }
  66 + }
  67 +
  68 + /**
  69 + * Writes $message to the text browser. Also, passes the message
  70 + * along to any Log_observer instances that are observing this Log.
  71 + *
  72 + * @param mixed $message String or object containing the message to log.
  73 + * @param string $priority The priority of the message. Valid
  74 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  75 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  76 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  77 + * @return boolean True on success or false on failure.
  78 + * @access public
  79 + */
  80 + function log($message, $priority = null)
  81 + {
  82 + /* If a priority hasn't been specified, use the default value. */
  83 + if ($priority === null) {
  84 + $priority = $this->_priority;
  85 + }
  86 +
  87 + /* Abort early if the priority is above the maximum logging level. */
  88 + if (!$this->_isMasked($priority)) {
  89 + return false;
  90 + }
  91 +
  92 + /* Extract the string representation of the message. */
  93 + $message = $this->_extractMessage($message);
  94 +
  95 + /* Build and output the complete log line. */
  96 + echo $this->_error_prepend .
  97 + '<b>' . ucfirst($this->priorityToString($priority)) . '</b>: '.
  98 + nl2br(htmlspecialchars($message)) .
  99 + $this->_error_append . "<br />\n";
  100 +
  101 + /* Notify observers about this log message. */
  102 + $this->_announce(array('priority' => $priority, 'message' => $message));
  103 +
  104 + return true;
  105 + }
  106 +}
  107 +
  108 +?>
... ...
pear/Log/error_log.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + *
  5 + * @version $Revision$
  6 + * @package Log
  7 + */
  8 +
  9 +/**
  10 + * The Log_error_log class is a concrete implementation of the Log abstract
  11 + * class that logs messages using PHP's error_log() function.
  12 + *
  13 + * @author Jon Parise <jon@php.net>
  14 + * @since Log 1.7.0
  15 + * @package Log
  16 + *
  17 + * @example error_log.php Using the error_log handler.
  18 + */
  19 +class Log_error_log extends Log
  20 +{
  21 + /**
  22 + * The error_log() log type.
  23 + * @var integer
  24 + * @access private
  25 + */
  26 + var $_type = PEAR_LOG_TYPE_SYSTEM;
  27 +
  28 + /**
  29 + * The type-specific destination value.
  30 + * @var string
  31 + * @access private
  32 + */
  33 + var $_destination = '';
  34 +
  35 + /**
  36 + * Additional headers to pass to the mail() function when the
  37 + * PEAR_LOG_TYPE_MAIL type is used.
  38 + * @var string
  39 + * @access private
  40 + */
  41 + var $_extra_headers = '';
  42 +
  43 + /**
  44 + * Constructs a new Log_error_log object.
  45 + *
  46 + * @param string $name Ignored.
  47 + * @param string $ident The identity string.
  48 + * @param array $conf The configuration array.
  49 + * @param int $level Log messages up to and including this level.
  50 + * @access public
  51 + */
  52 + function Log_error_log($name, $ident = '', $conf = array(),
  53 + $level = PEAR_LOG_DEBUG)
  54 + {
  55 + $this->_id = md5(microtime());
  56 + $this->_type = $name;
  57 + $this->_ident = $ident;
  58 + $this->_mask = Log::UPTO($level);
  59 +
  60 + if (!empty($conf['destination'])) {
  61 + $this->_destination = $conf['destination'];
  62 + }
  63 + if (!empty($conf['extra_headers'])) {
  64 + $this->_extra_headers = $conf['extra_headers'];
  65 + }
  66 + }
  67 +
  68 + /**
  69 + * Logs $message using PHP's error_log() function. The message is also
  70 + * passed along to any Log_observer instances that are observing this Log.
  71 + *
  72 + * @param mixed $message String or object containing the message to log.
  73 + * @param string $priority The priority of the message. Valid
  74 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  75 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  76 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  77 + * @return boolean True on success or false on failure.
  78 + * @access public
  79 + */
  80 + function log($message, $priority = null)
  81 + {
  82 + /* If a priority hasn't been specified, use the default value. */
  83 + if ($priority === null) {
  84 + $priority = $this->_priority;
  85 + }
  86 +
  87 + /* Abort early if the priority is above the maximum logging level. */
  88 + if (!$this->_isMasked($priority)) {
  89 + return false;
  90 + }
  91 +
  92 + /* Extract the string representation of the message. */
  93 + $message = $this->_extractMessage($message);
  94 +
  95 + $success = error_log($this->_ident . ': ' . $message, $this->_type,
  96 + $this->_destination, $this->_extra_headers);
  97 +
  98 + $this->_announce(array('priority' => $priority, 'message' => $message));
  99 +
  100 + return $success;
  101 + }
  102 +}
  103 +
  104 +?>
... ...
pear/Log/file.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + *
  5 + * @version $Revision$
  6 + * @package Log
  7 + */
  8 +
  9 +/**
  10 + * The Log_file class is a concrete implementation of the Log abstract
  11 + * class that logs messages to a text file.
  12 + *
  13 + * @author Jon Parise <jon@php.net>
  14 + * @author Roman Neuhauser <neuhauser@bellavista.cz>
  15 + * @since Log 1.0
  16 + * @package Log
  17 + *
  18 + * @example file.php Using the file handler.
  19 + */
  20 +class Log_file extends Log
  21 +{
  22 + /**
  23 + * String containing the name of the log file.
  24 + * @var string
  25 + * @access private
  26 + */
  27 + var $_filename = 'php.log';
  28 +
  29 + /**
  30 + * Handle to the log file.
  31 + * @var resource
  32 + * @access private
  33 + */
  34 + var $_fp = false;
  35 +
  36 + /**
  37 + * Should new log entries be append to an existing log file, or should the
  38 + * a new log file overwrite an existing one?
  39 + * @var boolean
  40 + * @access private
  41 + */
  42 + var $_append = true;
  43 +
  44 + /**
  45 + * Integer (in octal) containing the log file's permissions mode.
  46 + * @var integer
  47 + * @access private
  48 + */
  49 + var $_mode = 0644;
  50 +
  51 + /**
  52 + * String containing the format of a log line.
  53 + * @var string
  54 + * @access private
  55 + */
  56 + var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
  57 +
  58 + /**
  59 + * String containing the timestamp format. It will be passed directly to
  60 + * strftime(). Note that the timestamp string will generated using the
  61 + * current locale.
  62 + * @var string
  63 + * @access private
  64 + */
  65 + var $_timeFormat = '%b %d %H:%M:%S';
  66 +
  67 + /**
  68 + * Hash that maps canonical format keys to position arguments for the
  69 + * "line format" string.
  70 + * @var array
  71 + * @access private
  72 + */
  73 + var $_formatMap = array('%{timestamp}' => '%1$s',
  74 + '%{ident}' => '%2$s',
  75 + '%{priority}' => '%3$s',
  76 + '%{message}' => '%4$s',
  77 + '%\{' => '%%{');
  78 +
  79 + /**
  80 + * String containing the end-on-line character sequence.
  81 + * @var string
  82 + * @access private
  83 + */
  84 + var $_eol = "\n";
  85 +
  86 + /**
  87 + * Constructs a new Log_file object.
  88 + *
  89 + * @param string $name Ignored.
  90 + * @param string $ident The identity string.
  91 + * @param array $conf The configuration array.
  92 + * @param int $level Log messages up to and including this level.
  93 + * @access public
  94 + */
  95 + function Log_file($name, $ident = '', $conf = array(),
  96 + $level = PEAR_LOG_DEBUG)
  97 + {
  98 + $this->_id = md5(microtime());
  99 + $this->_filename = $name;
  100 + $this->_ident = $ident;
  101 + $this->_mask = Log::UPTO($level);
  102 +
  103 + if (isset($conf['append'])) {
  104 + $this->_append = $conf['append'];
  105 + }
  106 +
  107 + if (!empty($conf['mode'])) {
  108 + $this->_mode = $conf['mode'];
  109 + }
  110 +
  111 + if (!empty($conf['lineFormat'])) {
  112 + $this->_lineFormat = str_replace(array_keys($this->_formatMap),
  113 + array_values($this->_formatMap),
  114 + $conf['lineFormat']);
  115 + }
  116 +
  117 + if (!empty($conf['timeFormat'])) {
  118 + $this->_timeFormat = $conf['timeFormat'];
  119 + }
  120 +
  121 + if (!empty($conf['eol'])) {
  122 + $this->_eol = $conf['eol'];
  123 + } else {
  124 + $this->_eol = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n";
  125 + }
  126 +
  127 + register_shutdown_function(array(&$this, '_Log_file'));
  128 + }
  129 +
  130 + /**
  131 + * Destructor
  132 + */
  133 + function _Log_file()
  134 + {
  135 + if ($this->_opened) {
  136 + $this->close();
  137 + }
  138 + }
  139 +
  140 + /**
  141 + * Creates the given directory path. If the parent directories don't
  142 + * already exist, they will be created, too.
  143 + *
  144 + * @param string $path The full directory path to create.
  145 + * @param integer $mode The permissions mode with which the
  146 + * directories will be created.
  147 + *
  148 + * @return True if the full path is successfully created or already
  149 + * exists.
  150 + *
  151 + * @access private
  152 + */
  153 + function _mkpath($path, $mode = 0700)
  154 + {
  155 + static $depth = 0;
  156 +
  157 + /* Guard against potentially infinite recursion. */
  158 + if ($depth++ > 25) {
  159 + trigger_error("_mkpath(): Maximum recursion depth (25) exceeded",
  160 + E_USER_WARNING);
  161 + return false;
  162 + }
  163 +
  164 + /* We're only interested in the directory component of the path. */
  165 + $path = dirname($path);
  166 +
  167 + /* If the directory already exists, return success immediately. */
  168 + if (is_dir($path)) {
  169 + $depth = 0;
  170 + return true;
  171 + }
  172 +
  173 + /*
  174 + * In order to understand recursion, you must first understand
  175 + * recursion ...
  176 + */
  177 + if ($this->_mkpath($path, $mode) === false) {
  178 + return false;
  179 + }
  180 +
  181 + return @mkdir($path, $mode);
  182 + }
  183 +
  184 + /**
  185 + * Opens the log file for output. If the specified log file does not
  186 + * already exist, it will be created. By default, new log entries are
  187 + * appended to the end of the log file.
  188 + *
  189 + * This is implicitly called by log(), if necessary.
  190 + *
  191 + * @access public
  192 + */
  193 + function open()
  194 + {
  195 + if (!$this->_opened) {
  196 + /* If the log file's directory doesn't exist, create it. */
  197 + if (!is_dir(dirname($this->_filename))) {
  198 + $this->_mkpath($this->_filename);
  199 + }
  200 +
  201 + /* Obtain a handle to the log file. */
  202 + $this->_fp = fopen($this->_filename, ($this->_append) ? 'a' : 'w');
  203 +
  204 + $this->_opened = ($this->_fp !== false);
  205 +
  206 + /* Attempt to set the log file's mode. */
  207 + @chmod($this->_filename, $this->_mode);
  208 + }
  209 +
  210 + return $this->_opened;
  211 + }
  212 +
  213 + /**
  214 + * Closes the log file if it is open.
  215 + *
  216 + * @access public
  217 + */
  218 + function close()
  219 + {
  220 + /* If the log file is open, close it. */
  221 + if ($this->_opened && fclose($this->_fp)) {
  222 + $this->_opened = false;
  223 + }
  224 +
  225 + return ($this->_opened === false);
  226 + }
  227 +
  228 + /**
  229 + * Flushes all pending data to the file handle.
  230 + *
  231 + * @access public
  232 + * @since Log 1.8.2
  233 + */
  234 + function flush()
  235 + {
  236 + return fflush($this->_fp);
  237 + }
  238 +
  239 + /**
  240 + * Logs $message to the output window. The message is also passed along
  241 + * to any Log_observer instances that are observing this Log.
  242 + *
  243 + * @param mixed $message String or object containing the message to log.
  244 + * @param string $priority The priority of the message. Valid
  245 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  246 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  247 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  248 + * @return boolean True on success or false on failure.
  249 + * @access public
  250 + */
  251 + function log($message, $priority = null)
  252 + {
  253 + /* If a priority hasn't been specified, use the default value. */
  254 + if ($priority === null) {
  255 + $priority = $this->_priority;
  256 + }
  257 +
  258 + /* Abort early if the priority is above the maximum logging level. */
  259 + if (!$this->_isMasked($priority)) {
  260 + return false;
  261 + }
  262 +
  263 + /* If the log file isn't already open, open it now. */
  264 + if (!$this->_opened && !$this->open()) {
  265 + return false;
  266 + }
  267 +
  268 + /* Extract the string representation of the message. */
  269 + $message = $this->_extractMessage($message);
  270 +
  271 + /* Build the string containing the complete log line. */
  272 + $line = sprintf($this->_lineFormat, strftime($this->_timeFormat),
  273 + $this->_ident, $this->priorityToString($priority),
  274 + $message) . $this->_eol;
  275 +
  276 + /* Write the log line to the log file. */
  277 + $success = (fwrite($this->_fp, $line) !== false);
  278 +
  279 + /* Notify observers about this log message. */
  280 + $this->_announce(array('priority' => $priority, 'message' => $message));
  281 +
  282 + return $success;
  283 + }
  284 +}
  285 +
  286 +?>
... ...
pear/Log/mail.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + *
  5 + * @version $Revision$
  6 + * @package Log
  7 + */
  8 +
  9 +/**
  10 + * The Log_mail class is a concrete implementation of the Log:: abstract class
  11 + * which sends log messages to a mailbox.
  12 + * The mail is actually sent when you close() the logger, or when the destructor
  13 + * is called (when the script is terminated).
  14 + *
  15 + * PLEASE NOTE that you must create a Log_mail object using =&, like this :
  16 + * $logger =& Log::factory("mail", "recipient@example.com", ...)
  17 + *
  18 + * This is a PEAR requirement for destructors to work properly.
  19 + * See http://pear.php.net/manual/en/class.pear.php
  20 + *
  21 + * @author Ronnie Garcia <ronnie@mk2.net>
  22 + * @author Jon Parise <jon@php.net>
  23 + * @since Log 1.3
  24 + * @package Log
  25 + *
  26 + * @example mail.php Using the mail handler.
  27 + */
  28 +class Log_mail extends Log
  29 +{
  30 + /**
  31 + * String holding the recipient's email address.
  32 + * @var string
  33 + * @access private
  34 + */
  35 + var $_recipient = '';
  36 +
  37 + /**
  38 + * String holding the sender's email address.
  39 + * @var string
  40 + * @access private
  41 + */
  42 + var $_from = '';
  43 +
  44 + /**
  45 + * String holding the email's subject.
  46 + * @var string
  47 + * @access private
  48 + */
  49 + var $_subject = '[Log_mail] Log message';
  50 +
  51 + /**
  52 + * String holding an optional preamble for the log messages.
  53 + * @var string
  54 + * @access private
  55 + */
  56 + var $_preamble = '';
  57 +
  58 + /**
  59 + * String holding the mail message body.
  60 + * @var string
  61 + * @access private
  62 + */
  63 + var $_message = '';
  64 +
  65 +
  66 + /**
  67 + * Constructs a new Log_mail object.
  68 + *
  69 + * Here is how you can customize the mail driver with the conf[] hash :
  70 + * $conf['from'] : the mail's "From" header line,
  71 + * $conf['subject'] : the mail's "Subject" line.
  72 + *
  73 + * @param string $name The filename of the logfile.
  74 + * @param string $ident The identity string.
  75 + * @param array $conf The configuration array.
  76 + * @param int $level Log messages up to and including this level.
  77 + * @access public
  78 + */
  79 + function Log_mail($name, $ident = '', $conf = array(),
  80 + $level = PEAR_LOG_DEBUG)
  81 + {
  82 + $this->_id = md5(microtime());
  83 + $this->_recipient = $name;
  84 + $this->_ident = $ident;
  85 + $this->_mask = Log::UPTO($level);
  86 +
  87 + if (!empty($conf['from'])) {
  88 + $this->_from = $conf['from'];
  89 + } else {
  90 + $this->_from = ini_get('sendmail_from');
  91 + }
  92 +
  93 + if (!empty($conf['subject'])) {
  94 + $this->_subject = $conf['subject'];
  95 + }
  96 +
  97 + if (!empty($conf['preamble'])) {
  98 + $this->_preamble = $conf['preamble'];
  99 + }
  100 +
  101 + /* register the destructor */
  102 + register_shutdown_function(array(&$this, '_Log_mail'));
  103 + }
  104 +
  105 + /**
  106 + * Destructor. Calls close().
  107 + *
  108 + * @access private
  109 + */
  110 + function _Log_mail()
  111 + {
  112 + $this->close();
  113 + }
  114 +
  115 + /**
  116 + * Starts a new mail message.
  117 + * This is implicitly called by log(), if necessary.
  118 + *
  119 + * @access public
  120 + */
  121 + function open()
  122 + {
  123 + if (!$this->_opened) {
  124 + if (!empty($this->_preamble)) {
  125 + $this->_message = $this->_preamble . "\n\n";
  126 + }
  127 + $this->_opened = true;
  128 + }
  129 +
  130 + return $this->_opened;
  131 + }
  132 +
  133 + /**
  134 + * Closes the message, if it is open, and sends the mail.
  135 + * This is implicitly called by the destructor, if necessary.
  136 + *
  137 + * @access public
  138 + */
  139 + function close()
  140 + {
  141 + if ($this->_opened) {
  142 + if (!empty($this->_message)) {
  143 + $headers = "From: $this->_from\n";
  144 + $headers .= "User-Agent: Log_mail";
  145 +
  146 + if (mail($this->_recipient, $this->_subject, $this->_message,
  147 + $headers) == false) {
  148 + error_log("Log_mail: Failure executing mail()", 0);
  149 + return false;
  150 + }
  151 +
  152 + /* Clear the message string now that the email has been sent. */
  153 + $this->_message = '';
  154 + }
  155 + $this->_opened = false;
  156 + }
  157 +
  158 + return ($this->_opened === false);
  159 + }
  160 +
  161 + /**
  162 + * Flushes the log output by forcing the email message to be sent now.
  163 + * Events that are logged after flush() is called will be appended to a
  164 + * new email message.
  165 + *
  166 + * @access public
  167 + * @since Log 1.8.2
  168 + */
  169 + function flush()
  170 + {
  171 + /*
  172 + * It's sufficient to simply call close() to flush the output.
  173 + * The next call to log() will cause the handler to be reopened.
  174 + */
  175 + return $this->close();
  176 + }
  177 +
  178 + /**
  179 + * Writes $message to the currently open mail message.
  180 + * Calls open(), if necessary.
  181 + *
  182 + * @param mixed $message String or object containing the message to log.
  183 + * @param string $priority The priority of the message. Valid
  184 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  185 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  186 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  187 + * @return boolean True on success or false on failure.
  188 + * @access public
  189 + */
  190 + function log($message, $priority = null)
  191 + {
  192 + /* If a priority hasn't been specified, use the default value. */
  193 + if ($priority === null) {
  194 + $priority = $this->_priority;
  195 + }
  196 +
  197 + /* Abort early if the priority is above the maximum logging level. */
  198 + if (!$this->_isMasked($priority)) {
  199 + return false;
  200 + }
  201 +
  202 + /* If the message isn't open and can't be opened, return failure. */
  203 + if (!$this->_opened && !$this->open()) {
  204 + return false;
  205 + }
  206 +
  207 + /* Extract the string representation of the message. */
  208 + $message = $this->_extractMessage($message);
  209 +
  210 + $entry = sprintf("%s %s [%s] %s\n", strftime('%b %d %H:%M:%S'),
  211 + $this->_ident, Log::priorityToString($priority),
  212 + $message);
  213 +
  214 + $this->_message .= $entry;
  215 +
  216 + $this->_announce(array('priority' => $priority, 'message' => $message));
  217 +
  218 + return true;
  219 + }
  220 +}
  221 +
  222 +?>
... ...
pear/Log/mcal.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + * $Horde: horde/lib/Log/mcal.php,v 1.2 2000/06/28 21:36:13 jon Exp $
  5 + *
  6 + * @version $Revision$
  7 + * @package Log
  8 + */
  9 +
  10 +/**
  11 + * The Log_mcal class is a concrete implementation of the Log::
  12 + * abstract class which sends messages to a local or remote calendar
  13 + * store accessed through MCAL.
  14 + *
  15 + * @author Chuck Hagenbuch <chuck@horde.org>
  16 + * @since Horde 1.3
  17 + * @since Log 1.0
  18 + * @package Log
  19 + */
  20 +class Log_mcal extends Log {
  21 +
  22 + /**
  23 + * holding the calendar specification to connect to.
  24 + * @var string
  25 + * @access private
  26 + */
  27 + var $_calendar = '{localhost/mstore}';
  28 +
  29 + /**
  30 + * holding the username to use.
  31 + * @var string
  32 + * @access private
  33 + */
  34 + var $_username = '';
  35 +
  36 + /**
  37 + * holding the password to use.
  38 + * @var string
  39 + * @access private
  40 + */
  41 + var $_password = '';
  42 +
  43 + /**
  44 + * holding the options to pass to the calendar stream.
  45 + * @var integer
  46 + * @access private
  47 + */
  48 + var $_options = 0;
  49 +
  50 + /**
  51 + * ResourceID of the MCAL stream.
  52 + * @var string
  53 + * @access private
  54 + */
  55 + var $_stream = '';
  56 +
  57 + /**
  58 + * Integer holding the log facility to use.
  59 + * @var string
  60 + * @access private
  61 + */
  62 + var $_name = LOG_SYSLOG;
  63 +
  64 +
  65 + /**
  66 + * Constructs a new Log_mcal object.
  67 + *
  68 + * @param string $name The category to use for our events.
  69 + * @param string $ident The identity string.
  70 + * @param array $conf The configuration array.
  71 + * @param int $level Log messages up to and including this level.
  72 + * @access public
  73 + */
  74 + function Log_mcal($name, $ident = '', $conf = array(),
  75 + $level = PEAR_LOG_DEBUG)
  76 + {
  77 + $this->_id = md5(microtime());
  78 + $this->_name = $name;
  79 + $this->_ident = $ident;
  80 + $this->_mask = Log::UPTO($level);
  81 + $this->_calendar = $conf['calendar'];
  82 + $this->_username = $conf['username'];
  83 + $this->_password = $conf['password'];
  84 + $this->_options = $conf['options'];
  85 + }
  86 +
  87 + /**
  88 + * Opens a calendar stream, if it has not already been
  89 + * opened. This is implicitly called by log(), if necessary.
  90 + * @access public
  91 + */
  92 + function open()
  93 + {
  94 + if (!$this->_opened) {
  95 + $this->_stream = mcal_open($this->_calendar, $this->_username,
  96 + $this->_password, $this->_options);
  97 + $this->_opened = true;
  98 + }
  99 +
  100 + return $this->_opened;
  101 + }
  102 +
  103 + /**
  104 + * Closes the calendar stream, if it is open.
  105 + * @access public
  106 + */
  107 + function close()
  108 + {
  109 + if ($this->_opened) {
  110 + mcal_close($this->_stream);
  111 + $this->_opened = false;
  112 + }
  113 +
  114 + return ($this->_opened === false);
  115 + }
  116 +
  117 + /**
  118 + * Logs $message and associated information to the currently open
  119 + * calendar stream. Calls open() if necessary. Also passes the
  120 + * message along to any Log_observer instances that are observing
  121 + * this Log.
  122 + *
  123 + * @param mixed $message String or object containing the message to log.
  124 + * @param string $priority The priority of the message. Valid
  125 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  126 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  127 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  128 + * @return boolean True on success or false on failure.
  129 + * @access public
  130 + */
  131 + function log($message, $priority = null)
  132 + {
  133 + /* If a priority hasn't been specified, use the default value. */
  134 + if ($priority === null) {
  135 + $priority = $this->_priority;
  136 + }
  137 +
  138 + /* Abort early if the priority is above the maximum logging level. */
  139 + if (!$this->_isMasked($priority)) {
  140 + return false;
  141 + }
  142 +
  143 + /* If the connection isn't open and can't be opened, return failure. */
  144 + if (!$this->_opened && !$this->open()) {
  145 + return false;
  146 + }
  147 +
  148 + /* Extract the string representation of the message. */
  149 + $message = $this->_extractMessage($message);
  150 +
  151 + $date_str = date('Y:n:j:G:i:s');
  152 + $dates = explode(':', $date_str);
  153 +
  154 + mcal_event_init($this->_stream);
  155 + mcal_event_set_title($this->_stream, $this->_ident);
  156 + mcal_event_set_category($this->_stream, $this->_name);
  157 + mcal_event_set_description($this->_stream, $message);
  158 + mcal_event_add_attribute($this->_stream, 'priority', $priority);
  159 + mcal_event_set_start($this->_stream, $dates[0], $dates[1], $dates[2],
  160 + $dates[3], $dates[4], $dates[5]);
  161 + mcal_event_set_end($this->_stream, $dates[0], $dates[1], $dates[2],
  162 + $dates[3], $dates[4], $dates[5]);
  163 + mcal_append_event($this->_stream);
  164 +
  165 + $this->_announce(array('priority' => $priority, 'message' => $message));
  166 +
  167 + return true;
  168 + }
  169 +}
  170 +
  171 +?>
... ...
pear/Log/null.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + *
  5 + * @version $Revision$
  6 + * @package Log
  7 + */
  8 +
  9 +/**
  10 + * The Log_null class is a concrete implementation of the Log:: abstract
  11 + * class. It simply consumes log events.
  12 + *
  13 + * @author Jon Parise <jon@php.net>
  14 + * @since Log 1.8.2
  15 + * @package Log
  16 + *
  17 + * @example null.php Using the null handler.
  18 + */
  19 +class Log_null extends Log
  20 +{
  21 + /**
  22 + * Constructs a new Log_null object.
  23 + *
  24 + * @param string $name Ignored.
  25 + * @param string $ident The identity string.
  26 + * @param array $conf The configuration array.
  27 + * @param int $level Log messages up to and including this level.
  28 + * @access public
  29 + */
  30 + function Log_null($name, $ident = '', $conf = array(),
  31 + $level = PEAR_LOG_DEBUG)
  32 + {
  33 + $this->_id = md5(microtime());
  34 + $this->_ident = $ident;
  35 + $this->_mask = Log::UPTO($level);
  36 + }
  37 +
  38 + /**
  39 + * Simply consumes the log event. The message will still be passed
  40 + * along to any Log_observer instances that are observing this Log.
  41 + *
  42 + * @param mixed $message String or object containing the message to log.
  43 + * @param string $priority The priority of the message. Valid
  44 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  45 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  46 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  47 + * @return boolean True on success or false on failure.
  48 + * @access public
  49 + */
  50 + function log($message, $priority = null)
  51 + {
  52 + /* If a priority hasn't been specified, use the default value. */
  53 + if ($priority === null) {
  54 + $priority = $this->_priority;
  55 + }
  56 +
  57 + /* Abort early if the priority is above the maximum logging level. */
  58 + if (!$this->_isMasked($priority)) {
  59 + return false;
  60 + }
  61 +
  62 + $this->_announce(array('priority' => $priority, 'message' => $message));
  63 +
  64 + return true;
  65 + }
  66 +}
  67 +
  68 +?>
... ...
pear/Log/observer.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + * $Horde: horde/lib/Log/observer.php,v 1.5 2000/06/28 21:36:13 jon Exp $
  5 + *
  6 + * @version $Revision$
  7 + * @package Log
  8 + */
  9 +
  10 +/**
  11 + * The Log_observer:: class implements the Observer end of a Subject-Observer
  12 + * pattern for watching log activity and taking actions on exceptional events.
  13 + *
  14 + * @author Chuck Hagenbuch <chuck@horde.org>
  15 + * @since Horde 1.3
  16 + * @since Log 1.0
  17 + * @package Log
  18 + *
  19 + * @example observer_mail.php An example Log_observer implementation.
  20 + */
  21 +class Log_observer
  22 +{
  23 + /**
  24 + * Instance-specific unique identification number.
  25 + *
  26 + * @var integer
  27 + * @access private
  28 + */
  29 + var $_id = 0;
  30 +
  31 + /**
  32 + * The minimum priority level of message that we want to hear about.
  33 + * PEAR_LOG_EMERG is the highest priority, so we will only hear messages
  34 + * with an integer priority value less than or equal to ours. It defaults
  35 + * to PEAR_LOG_INFO, which listens to everything except PEAR_LOG_DEBUG.
  36 + *
  37 + * @var string
  38 + * @access private
  39 + */
  40 + var $_priority = PEAR_LOG_INFO;
  41 +
  42 + /**
  43 + * Creates a new basic Log_observer instance.
  44 + *
  45 + * @param integer $priority The highest priority at which to receive
  46 + * log event notifications.
  47 + *
  48 + * @access public
  49 + */
  50 + function Log_observer($priority = PEAR_LOG_INFO)
  51 + {
  52 + $this->_id = md5(microtime());
  53 + $this->_priority = $priority;
  54 + }
  55 +
  56 + /**
  57 + * Attempts to return a new concrete Log_observer instance of the requested
  58 + * type.
  59 + *
  60 + * @param string $type The type of concreate Log_observer subclass
  61 + * to return.
  62 + * @param integer $priority The highest priority at which to receive
  63 + * log event notifications.
  64 + * @param array $conf Optional associative array of additional
  65 + * configuration values.
  66 + *
  67 + * @return object The newly created concrete Log_observer
  68 + * instance, or an false on an error.
  69 + */
  70 + function &factory($type, $priority = PEAR_LOG_INFO, $conf = array())
  71 + {
  72 + $type = strtolower($type);
  73 + $class = 'Log_observer_' . $type;
  74 +
  75 + /* Support both the new-style and old-style file naming conventions. */
  76 + if (file_exists(dirname(__FILE__) . '/observer_' . $type . '.php')) {
  77 + $classfile = 'Log/observer_' . $type . '.php';
  78 + $newstyle = true;
  79 + } else {
  80 + $classfile = 'Log/' . $type . '.php';
  81 + $newstyle = false;
  82 + }
  83 +
  84 + /* Issue a warning if the old-style conventions are being used. */
  85 + if (!$newstyle)
  86 + {
  87 + trigger_error('Using old-style Log_observer conventions',
  88 + E_USER_WARNING);
  89 + }
  90 +
  91 + /*
  92 + * Attempt to include our version of the named class, but don't treat
  93 + * a failure as fatal. The caller may have already included their own
  94 + * version of the named class.
  95 + */
  96 + @include_once $classfile;
  97 +
  98 + /* If the class exists, return a new instance of it. */
  99 + if (class_exists($class)) {
  100 + /* Support both new-style and old-style construction. */
  101 + if ($newstyle) {
  102 + return new $class($priority, $conf);
  103 + } else {
  104 + return new $class($priority);
  105 + }
  106 + }
  107 +
  108 + return false;
  109 + }
  110 +
  111 + /**
  112 + * This is a stub method to make sure that Log_Observer classes do
  113 + * something when they are notified of a message. The default behavior
  114 + * is to just print the message, which is obviously not desireable in
  115 + * practically any situation - which is why you need to override this
  116 + * method. :)
  117 + *
  118 + * @param array $event A hash describing the log event.
  119 + */
  120 + function notify($event)
  121 + {
  122 + print_r($event);
  123 + }
  124 +}
  125 +
  126 +?>
... ...
pear/Log/sql.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + * $Horde: horde/lib/Log/sql.php,v 1.12 2000/08/16 20:27:34 chuck Exp $
  5 + *
  6 + * @version $Revision$
  7 + * @package Log
  8 + */
  9 +
  10 +/** PEAR's DB package */
  11 +require_once 'DB.php';
  12 +
  13 +/**
  14 + * The Log_sql class is a concrete implementation of the Log::
  15 + * abstract class which sends messages to an SQL server. Each entry
  16 + * occupies a separate row in the database.
  17 + *
  18 + * This implementation uses PHP's PEAR database abstraction layer.
  19 + *
  20 + * CREATE TABLE log_table (
  21 + * id INT NOT NULL,
  22 + * logtime TIMESTAMP NOT NULL,
  23 + * ident CHAR(16) NOT NULL,
  24 + * priority INT NOT NULL,
  25 + * message VARCHAR(200),
  26 + * PRIMARY KEY (id)
  27 + * );
  28 + *
  29 + * @author Jon Parise <jon@php.net>
  30 + * @since Horde 1.3
  31 + * @since Log 1.0
  32 + * @package Log
  33 + *
  34 + * @example sql.php Using the SQL handler.
  35 + */
  36 +class Log_sql extends Log {
  37 +
  38 + /**
  39 + * Array containing the dsn information.
  40 + * @var string
  41 + * @access private
  42 + */
  43 + var $_dsn = '';
  44 +
  45 + /**
  46 + * Object holding the database handle.
  47 + * @var object
  48 + * @access private
  49 + */
  50 + var $_db = null;
  51 +
  52 + /**
  53 + * Flag indicating that we're using an existing database connection.
  54 + * @var boolean
  55 + * @access private
  56 + */
  57 + var $_existingConnection = false;
  58 +
  59 + /**
  60 + * String holding the database table to use.
  61 + * @var string
  62 + * @access private
  63 + */
  64 + var $_table = 'log_table';
  65 +
  66 + /**
  67 + * String holding the name of the ID sequence.
  68 + * @var string
  69 + * @access private
  70 + */
  71 + var $_sequence = 'log_id';
  72 +
  73 + /**
  74 + * Maximum length of the $ident string. This corresponds to the size of
  75 + * the 'ident' column in the SQL table.
  76 + * @var integer
  77 + * @access private
  78 + */
  79 + var $_identLimit = 16;
  80 +
  81 +
  82 + /**
  83 + * Constructs a new sql logging object.
  84 + *
  85 + * @param string $name The target SQL table.
  86 + * @param string $ident The identification field.
  87 + * @param array $conf The connection configuration array.
  88 + * @param int $level Log messages up to and including this level.
  89 + * @access public
  90 + */
  91 + function Log_sql($name, $ident = '', $conf = array(),
  92 + $level = PEAR_LOG_DEBUG)
  93 + {
  94 + $this->_id = md5(microtime());
  95 + $this->_table = $name;
  96 + $this->_mask = Log::UPTO($level);
  97 +
  98 + /* If a specific sequence name was provided, use it. */
  99 + if (!empty($conf['sequence'])) {
  100 + $this->_sequence = $conf['sequence'];
  101 + }
  102 +
  103 + /* If a specific sequence name was provided, use it. */
  104 + if (isset($conf['identLimit'])) {
  105 + $this->_identLimit = $conf['identLimit'];
  106 + }
  107 +
  108 + /* Now that the ident limit is confirmed, set the ident string. */
  109 + $this->setIdent($ident);
  110 +
  111 + /* If an existing database connection was provided, use it. */
  112 + if (isset($conf['db'])) {
  113 + $this->_db = &$conf['db'];
  114 + $this->_existingConnection = true;
  115 + $this->_opened = true;
  116 + } else {
  117 + $this->_dsn = $conf['dsn'];
  118 + }
  119 + }
  120 +
  121 + /**
  122 + * Opens a connection to the database, if it has not already
  123 + * been opened. This is implicitly called by log(), if necessary.
  124 + *
  125 + * @return boolean True on success, false on failure.
  126 + * @access public
  127 + */
  128 + function open()
  129 + {
  130 + if (!$this->_opened) {
  131 + $this->_db = &DB::connect($this->_dsn, true);
  132 + if (DB::isError($this->_db)) {
  133 + return false;
  134 + }
  135 + $this->_opened = true;
  136 + }
  137 +
  138 + return $this->_opened;
  139 + }
  140 +
  141 + /**
  142 + * Closes the connection to the database if it is still open and we were
  143 + * the ones that opened it. It is the caller's responsible to close an
  144 + * existing connection that was passed to us via $conf['db'].
  145 + *
  146 + * @return boolean True on success, false on failure.
  147 + * @access public
  148 + */
  149 + function close()
  150 + {
  151 + if ($this->_opened && !$this->_existingConnection) {
  152 + $this->_opened = false;
  153 + return $this->_db->disconnect();
  154 + }
  155 +
  156 + return ($this->_opened === false);
  157 + }
  158 +
  159 + /**
  160 + * Sets this Log instance's identification string. Note that this
  161 + * SQL-specific implementation will limit the length of the $ident string
  162 + * to sixteen (16) characters.
  163 + *
  164 + * @param string $ident The new identification string.
  165 + *
  166 + * @access public
  167 + * @since Log 1.8.5
  168 + */
  169 + function setIdent($ident)
  170 + {
  171 + $this->_ident = substr($ident, 0, $this->_identLimit);
  172 + }
  173 +
  174 + /**
  175 + * Inserts $message to the currently open database. Calls open(),
  176 + * if necessary. Also passes the message along to any Log_observer
  177 + * instances that are observing this Log.
  178 + *
  179 + * @param mixed $message String or object containing the message to log.
  180 + * @param string $priority The priority of the message. Valid
  181 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  182 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  183 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  184 + * @return boolean True on success or false on failure.
  185 + * @access public
  186 + */
  187 + function log($message, $priority = null)
  188 + {
  189 + /* If a priority hasn't been specified, use the default value. */
  190 + if ($priority === null) {
  191 + $priority = $this->_priority;
  192 + }
  193 +
  194 + /* Abort early if the priority is above the maximum logging level. */
  195 + if (!$this->_isMasked($priority)) {
  196 + return false;
  197 + }
  198 +
  199 + /* If the connection isn't open and can't be opened, return failure. */
  200 + if (!$this->_opened && !$this->open()) {
  201 + return false;
  202 + }
  203 +
  204 + /* Extract the string representation of the message. */
  205 + $message = $this->_extractMessage($message);
  206 +
  207 + /* Build the SQL query for this log entry insertion. */
  208 + $id = $this->_db->nextId($this->_sequence);
  209 + $q = sprintf('insert into %s (id, logtime, ident, priority, message)' .
  210 + 'values(%d, CURRENT_TIMESTAMP, %s, %d, %s)',
  211 + $this->_table, $id, $this->_db->quote($this->_ident),
  212 + $priority, $this->_db->quote($message));
  213 +
  214 + $result = $this->_db->query($q);
  215 + if (DB::isError($result)) {
  216 + return false;
  217 + }
  218 +
  219 + $this->_announce(array('priority' => $priority, 'message' => $message));
  220 +
  221 + return true;
  222 + }
  223 +}
  224 +
  225 +?>
... ...
pear/Log/sqlite.php 0 → 100644
  1 +<?php
  2 +/* vim: set expandtab tabstop=4 shiftwidth=4: */
  3 +// +----------------------------------------------------------------------+
  4 +// | PHP version 4.0 |
  5 +// +----------------------------------------------------------------------+
  6 +// | Copyright (c) 1997-2004 The PHP Group |
  7 +// +----------------------------------------------------------------------+
  8 +// | This source file is subject to version 2.0 of the PHP license, |
  9 +// | that is bundled with this package in the file LICENSE, and is |
  10 +// | available at through the world-wide-web at |
  11 +// | http://www.php.net/license/2_02.txt. |
  12 +// | If you did not receive a copy of the PHP license and are unable to |
  13 +// | obtain it through the world-wide-web, please send a note to |
  14 +// | license@php.net so we can mail you a copy immediately. |
  15 +// +----------------------------------------------------------------------+
  16 +// | Authors: Bertrand Mansion <bmansion@mamasam.com> |
  17 +// +----------------------------------------------------------------------+
  18 +//
  19 +// $Id$
  20 +
  21 +/**
  22 + * The Log_sqlite class is a concrete implementation of the Log::
  23 + * abstract class which sends messages to an Sqlite database.
  24 + * Each entry occupies a separate row in the database.
  25 + *
  26 + * This implementation uses PHP native Sqlite functions.
  27 + *
  28 + * CREATE TABLE log_table (
  29 + * id INTEGER PRIMARY KEY NOT NULL,
  30 + * logtime NOT NULL,
  31 + * ident CHAR(16) NOT NULL,
  32 + * priority INT NOT NULL,
  33 + * message
  34 + * );
  35 + *
  36 + * @author Bertrand Mansion <bmansion@mamasam.com>
  37 + * @author Jon Parise <jon@php.net>
  38 + * @since Log 1.8.3
  39 + * @package Log
  40 + *
  41 + * @example sqlite.php Using the Sqlite handler.
  42 + */
  43 +class Log_sqlite extends Log
  44 +{
  45 + /**
  46 + * Array containing the connection defaults
  47 + * @var array
  48 + * @access private
  49 + */
  50 + var $_options = array('mode' => 0666,
  51 + 'persistent' => false);
  52 +
  53 + /**
  54 + * Object holding the database handle.
  55 + * @var object
  56 + * @access private
  57 + */
  58 + var $_db = null;
  59 +
  60 + /**
  61 + * Flag indicating that we're using an existing database connection.
  62 + * @var boolean
  63 + * @access private
  64 + */
  65 + var $_existingConnection = false;
  66 +
  67 + /**
  68 + * String holding the database table to use.
  69 + * @var string
  70 + * @access private
  71 + */
  72 + var $_table = 'log_table';
  73 +
  74 +
  75 + /**
  76 + * Constructs a new sql logging object.
  77 + *
  78 + * @param string $name The target SQL table.
  79 + * @param string $ident The identification field.
  80 + * @param mixed $conf Can be an array of configuration options used
  81 + * to open a new database connection
  82 + * or an already opened sqlite connection.
  83 + * @param int $level Log messages up to and including this level.
  84 + * @access public
  85 + */
  86 + function Log_sqlite($name, $ident = '', &$conf, $level = PEAR_LOG_DEBUG)
  87 + {
  88 + $this->_id = md5(microtime());
  89 + $this->_table = $name;
  90 + $this->_ident = $ident;
  91 + $this->_mask = Log::UPTO($level);
  92 +
  93 + if (is_array($conf)) {
  94 + foreach ($conf as $k => $opt) {
  95 + $this->_options[$k] = $opt;
  96 + }
  97 + } else {
  98 + // If an existing database connection was provided, use it.
  99 + $this->_db =& $conf;
  100 + $this->_existingConnection = true;
  101 + }
  102 + }
  103 +
  104 + /**
  105 + * Opens a connection to the database, if it has not already
  106 + * been opened. This is implicitly called by log(), if necessary.
  107 + *
  108 + * @return boolean True on success, false on failure.
  109 + * @access public
  110 + */
  111 + function open()
  112 + {
  113 + if (is_resource($this->_db)) {
  114 + $this->_opened = true;
  115 + return $this->_createTable();
  116 + } else {
  117 + /* Set the connection function based on the 'persistent' option. */
  118 + if (empty($this->_options['persistent'])) {
  119 + $connectFunction = 'sqlite_open';
  120 + } else {
  121 + $connectFunction = 'sqlite_popen';
  122 + }
  123 +
  124 + /* Attempt to connect to the database. */
  125 + if ($this->_db = $connectFunction($this->_options['filename'],
  126 + (int)$this->_options['mode'],
  127 + $error)) {
  128 + $this->_opened = true;
  129 + return $this->_createTable();
  130 + }
  131 + }
  132 +
  133 + return $this->_opened;
  134 + }
  135 +
  136 + /**
  137 + * Closes the connection to the database if it is still open and we were
  138 + * the ones that opened it. It is the caller's responsible to close an
  139 + * existing connection that was passed to us via $conf['db'].
  140 + *
  141 + * @return boolean True on success, false on failure.
  142 + * @access public
  143 + */
  144 + function close()
  145 + {
  146 + /* We never close existing connections. */
  147 + if ($this->_existingConnection) {
  148 + return false;
  149 + }
  150 +
  151 + if ($this->_opened) {
  152 + $this->_opened = false;
  153 + sqlite_close($this->_db);
  154 + }
  155 +
  156 + return ($this->_opened === false);
  157 + }
  158 +
  159 + /**
  160 + * Inserts $message to the currently open database. Calls open(),
  161 + * if necessary. Also passes the message along to any Log_observer
  162 + * instances that are observing this Log.
  163 + *
  164 + * @param mixed $message String or object containing the message to log.
  165 + * @param string $priority The priority of the message. Valid
  166 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  167 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  168 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  169 + * @return boolean True on success or false on failure.
  170 + * @access public
  171 + */
  172 + function log($message, $priority = null)
  173 + {
  174 + /* If a priority hasn't been specified, use the default value. */
  175 + if ($priority === null) {
  176 + $priority = $this->_priority;
  177 + }
  178 +
  179 + /* Abort early if the priority is above the maximum logging level. */
  180 + if (!$this->_isMasked($priority)) {
  181 + return false;
  182 + }
  183 +
  184 + /* If the connection isn't open and can't be opened, return failure. */
  185 + if (!$this->_opened && !$this->open()) {
  186 + return false;
  187 + }
  188 +
  189 + // Extract the string representation of the message.
  190 + $message = $this->_extractMessage($message);
  191 +
  192 + // Build the SQL query for this log entry insertion.
  193 + $q = sprintf('INSERT INTO [%s] (logtime, ident, priority, message) ' .
  194 + "VALUES ('%s', '%s', %d, '%s')",
  195 + $this->_table,
  196 + strftime('%Y-%m-%d %H:%M:%S', time()),
  197 + sqlite_escape_string($this->_ident),
  198 + $priority,
  199 + sqlite_escape_string($message));
  200 + if (!($res = @sqlite_unbuffered_query($this->_db, $q))) {
  201 + return false;
  202 + }
  203 + $this->_announce(array('priority' => $priority, 'message' => $message));
  204 +
  205 + return true;
  206 + }
  207 +
  208 + /**
  209 + * Checks whether the log table exists and creates it if necessary.
  210 + *
  211 + * @return boolean True on success or false on failure.
  212 + * @access private
  213 + */
  214 + function _createTable()
  215 + {
  216 + $q = "SELECT name FROM sqlite_master WHERE name='" . $this->_table .
  217 + "' AND type='table'";
  218 +
  219 + $res = sqlite_query($this->_db, $q);
  220 +
  221 + if (sqlite_num_rows($res) == 0) {
  222 + $q = 'CREATE TABLE [' . $this->_table . '] (' .
  223 + 'id INTEGER PRIMARY KEY NOT NULL, ' .
  224 + 'logtime NOT NULL, ' .
  225 + 'ident CHAR(16) NOT NULL, ' .
  226 + 'priority INT NOT NULL, ' .
  227 + 'message)';
  228 +
  229 + if (!($res = sqlite_unbuffered_query($this->_db, $q))) {
  230 + return false;
  231 + }
  232 + }
  233 +
  234 + return true;
  235 + }
  236 +}
  237 +
  238 +?>
... ...
pear/Log/syslog.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + * $Horde: horde/lib/Log/syslog.php,v 1.6 2000/06/28 21:36:13 jon Exp $
  5 + *
  6 + * @version $Revision$
  7 + * @package Log
  8 + */
  9 +
  10 +/**
  11 + * The Log_syslog class is a concrete implementation of the Log::
  12 + * abstract class which sends messages to syslog on UNIX-like machines
  13 + * (PHP emulates this with the Event Log on Windows machines).
  14 + *
  15 + * @author Chuck Hagenbuch <chuck@horde.org>
  16 + * @since Horde 1.3
  17 + * @since Log 1.0
  18 + * @package Log
  19 + *
  20 + * @example syslog.php Using the syslog handler.
  21 + */
  22 +class Log_syslog extends Log
  23 +{
  24 + /**
  25 + * Integer holding the log facility to use.
  26 + * @var string
  27 + * @access private
  28 + */
  29 + var $_name = LOG_SYSLOG;
  30 +
  31 + /**
  32 + * Constructs a new syslog object.
  33 + *
  34 + * @param string $name The syslog facility.
  35 + * @param string $ident The identity string.
  36 + * @param array $conf The configuration array.
  37 + * @param int $level Log messages up to and including this level.
  38 + * @access public
  39 + */
  40 + function Log_syslog($name, $ident = '', $conf = array(),
  41 + $level = PEAR_LOG_DEBUG)
  42 + {
  43 + /* Ensure we have a valid integer value for $name. */
  44 + if (empty($name) || !is_int($name)) {
  45 + $name = LOG_SYSLOG;
  46 + }
  47 +
  48 + $this->_id = md5(microtime());
  49 + $this->_name = $name;
  50 + $this->_ident = $ident;
  51 + $this->_mask = Log::UPTO($level);
  52 + }
  53 +
  54 + /**
  55 + * Opens a connection to the system logger, if it has not already
  56 + * been opened. This is implicitly called by log(), if necessary.
  57 + * @access public
  58 + */
  59 + function open()
  60 + {
  61 + if (!$this->_opened) {
  62 + openlog($this->_ident, LOG_PID, $this->_name);
  63 + $this->_opened = true;
  64 + }
  65 +
  66 + return $this->_opened;
  67 + }
  68 +
  69 + /**
  70 + * Closes the connection to the system logger, if it is open.
  71 + * @access public
  72 + */
  73 + function close()
  74 + {
  75 + if ($this->_opened) {
  76 + closelog();
  77 + $this->_opened = false;
  78 + }
  79 +
  80 + return ($this->_opened === false);
  81 + }
  82 +
  83 + /**
  84 + * Sends $message to the currently open syslog connection. Calls
  85 + * open() if necessary. Also passes the message along to any Log_observer
  86 + * instances that are observing this Log.
  87 + *
  88 + * @param mixed $message String or object containing the message to log.
  89 + * @param int $priority (optional) The priority of the message. Valid
  90 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  91 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  92 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  93 + * @return boolean True on success or false on failure.
  94 + * @access public
  95 + */
  96 + function log($message, $priority = null)
  97 + {
  98 + /* If a priority hasn't been specified, use the default value. */
  99 + if ($priority === null) {
  100 + $priority = $this->_priority;
  101 + }
  102 +
  103 + /* Abort early if the priority is above the maximum logging level. */
  104 + if (!$this->_isMasked($priority)) {
  105 + return false;
  106 + }
  107 +
  108 + /* If the connection isn't open and can't be opened, return failure. */
  109 + if (!$this->_opened && !$this->open()) {
  110 + return false;
  111 + }
  112 +
  113 + /* Extract the string representation of the message. */
  114 + $message = $this->_extractMessage($message);
  115 +
  116 + if (!syslog($this->_toSyslog($priority), $message)) {
  117 + return false;
  118 + }
  119 +
  120 + $this->_announce(array('priority' => $priority, 'message' => $message));
  121 +
  122 + return true;
  123 + }
  124 +
  125 + /**
  126 + * Converts a PEAR_LOG_* constant into a syslog LOG_* constant.
  127 + *
  128 + * This function exists because, under Windows, not all of the LOG_*
  129 + * constants have unique values. Instead, the PEAR_LOG_* were introduced
  130 + * for global use, with the conversion to the LOG_* constants kept local to
  131 + * to the syslog driver.
  132 + *
  133 + * @param int $priority PEAR_LOG_* value to convert to LOG_* value.
  134 + *
  135 + * @return The LOG_* representation of $priority.
  136 + *
  137 + * @access private
  138 + */
  139 + function _toSyslog($priority)
  140 + {
  141 + static $priorities = array(
  142 + PEAR_LOG_EMERG => LOG_EMERG,
  143 + PEAR_LOG_ALERT => LOG_ALERT,
  144 + PEAR_LOG_CRIT => LOG_CRIT,
  145 + PEAR_LOG_ERR => LOG_ERR,
  146 + PEAR_LOG_WARNING => LOG_WARNING,
  147 + PEAR_LOG_NOTICE => LOG_NOTICE,
  148 + PEAR_LOG_INFO => LOG_INFO,
  149 + PEAR_LOG_DEBUG => LOG_DEBUG
  150 + );
  151 +
  152 + /* If we're passed an unknown priority, default to LOG_INFO. */
  153 + if (!is_int($priority) || !in_array($priority, $priorities)) {
  154 + return LOG_INFO;
  155 + }
  156 +
  157 + return $priorities[$priority];
  158 + }
  159 +}
  160 +?>
... ...
pear/Log/win.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Header$
  4 + *
  5 + * @version $Revision$
  6 + * @package Log
  7 + */
  8 +
  9 +/**
  10 + * The Log_win class is a concrete implementation of the Log abstract
  11 + * class that logs messages to a separate browser window.
  12 + *
  13 + * The concept for this log handler is based on part by Craig Davis' article
  14 + * entitled "JavaScript Power PHP Debugging:
  15 + *
  16 + * http://www.zend.com/zend/tut/tutorial-DebugLib.php
  17 + *
  18 + * @author Jon Parise <jon@php.net>
  19 + * @since Log 1.7.0
  20 + * @package Log
  21 + *
  22 + * @example win.php Using the window handler.
  23 + */
  24 +class Log_win extends Log
  25 +{
  26 + /**
  27 + * The name of the output window.
  28 + * @var string
  29 + * @access private
  30 + */
  31 + var $_name = 'LogWindow';
  32 +
  33 + /**
  34 + * The title of the output window.
  35 + * @var string
  36 + * @access private
  37 + */
  38 + var $_title = 'Log Output Window';
  39 +
  40 + /**
  41 + * Mapping of log priorities to colors.
  42 + * @var array
  43 + * @access private
  44 + */
  45 + var $_colors = array(
  46 + PEAR_LOG_EMERG => 'red',
  47 + PEAR_LOG_ALERT => 'orange',
  48 + PEAR_LOG_CRIT => 'yellow',
  49 + PEAR_LOG_ERR => 'green',
  50 + PEAR_LOG_WARNING => 'blue',
  51 + PEAR_LOG_NOTICE => 'indigo',
  52 + PEAR_LOG_INFO => 'violet',
  53 + PEAR_LOG_DEBUG => 'black'
  54 + );
  55 +
  56 + /**
  57 + * String buffer that holds line that are pending output.
  58 + * @var array
  59 + * @access private
  60 + */
  61 + var $_buffer = array();
  62 +
  63 + /**
  64 + * Constructs a new Log_win object.
  65 + *
  66 + * @param string $name Ignored.
  67 + * @param string $ident The identity string.
  68 + * @param array $conf The configuration array.
  69 + * @param int $level Log messages up to and including this level.
  70 + * @access public
  71 + */
  72 + function Log_win($name, $ident = '', $conf = array(),
  73 + $level = PEAR_LOG_DEBUG)
  74 + {
  75 + $this->_id = md5(microtime());
  76 + $this->_name = $name;
  77 + $this->_ident = $ident;
  78 + $this->_mask = Log::UPTO($level);
  79 +
  80 + if (isset($conf['title'])) {
  81 + $this->_title = $conf['title'];
  82 + }
  83 + if (isset($conf['colors']) && is_array($conf['colors'])) {
  84 + $this->_colors = $conf['colors'];
  85 + }
  86 +
  87 + register_shutdown_function(array(&$this, '_Log_win'));
  88 + }
  89 +
  90 + /**
  91 + * Destructor
  92 + */
  93 + function _Log_win()
  94 + {
  95 + if ($this->_opened || (count($this->_buffer) > 0)) {
  96 + $this->close();
  97 + }
  98 + }
  99 +
  100 + /**
  101 + * The first time open() is called, it will open a new browser window and
  102 + * prepare it for output.
  103 + *
  104 + * This is implicitly called by log(), if necessary.
  105 + *
  106 + * @access public
  107 + */
  108 + function open()
  109 + {
  110 + if (!$this->_opened) {
  111 + $win = $this->_name;
  112 +
  113 + if (!empty($this->_ident)) {
  114 + $identHeader = "$win.document.writeln('<th>Ident</th>')";
  115 + } else {
  116 + $identHeader = '';
  117 + }
  118 +
  119 + echo <<< END_OF_SCRIPT
  120 +<script language="JavaScript">
  121 +$win = window.open('', '{$this->_name}', 'toolbar=no,scrollbars,width=600,height=400');
  122 +$win.document.writeln('<html>');
  123 +$win.document.writeln('<head>');
  124 +$win.document.writeln('<title>{$this->_title}</title>');
  125 +$win.document.writeln('<style type="text/css">');
  126 +$win.document.writeln('body { font-family: monospace; font-size: 8pt; }');
  127 +$win.document.writeln('td,th { font-size: 8pt; }');
  128 +$win.document.writeln('td,th { border-bottom: #999999 solid 1px; }');
  129 +$win.document.writeln('td,th { border-right: #999999 solid 1px; }');
  130 +$win.document.writeln('</style>');
  131 +$win.document.writeln('</head>');
  132 +$win.document.writeln('<body>');
  133 +$win.document.writeln('<table border="0" cellpadding="2" cellspacing="0">');
  134 +$win.document.writeln('<tr><th>Time</th>');
  135 +$identHeader
  136 +$win.document.writeln('<th>Priority</th><th width="100%">Message</th></tr>');
  137 +</script>
  138 +END_OF_SCRIPT;
  139 + $this->_opened = true;
  140 + }
  141 +
  142 + return $this->_opened;
  143 + }
  144 +
  145 + /**
  146 + * Closes the output stream if it is open. If there are still pending
  147 + * lines in the output buffer, the output window will be opened so that
  148 + * the buffer can be drained.
  149 + *
  150 + * @access public
  151 + */
  152 + function close()
  153 + {
  154 + /*
  155 + * If there are still lines waiting to be written, open the output
  156 + * window so that we can drain the buffer.
  157 + */
  158 + if (!$this->_opened && (count($this->_buffer) > 0)) {
  159 + $this->open();
  160 + }
  161 +
  162 + if ($this->_opened) {
  163 + $this->_writeln('</table>');
  164 + $this->_writeln('</body></html>');
  165 + $this->_opened = false;
  166 + }
  167 +
  168 + return ($this->_opened === false);
  169 + }
  170 +
  171 + /**
  172 + * Writes a single line of text to the output window.
  173 + *
  174 + * @param string $line The line of text to write.
  175 + *
  176 + * @access private
  177 + */
  178 + function _writeln($line)
  179 + {
  180 + /* Add this line to our output buffer. */
  181 + $this->_buffer[] = $line;
  182 +
  183 + /* Buffer the output until this page's headers have been sent. */
  184 + if (!headers_sent()) {
  185 + return;
  186 + }
  187 +
  188 + /* If we haven't already opened the output window, do so now. */
  189 + if (!$this->_opened && !$this->open()) {
  190 + return false;
  191 + }
  192 +
  193 + /* Drain the buffer to the output window. */
  194 + $win = $this->_name;
  195 + foreach ($this->_buffer as $line) {
  196 + echo "<script language='JavaScript'>\n";
  197 + echo "$win.document.writeln('" . addslashes($line) . "');\n";
  198 + echo "self.focus();\n";
  199 + echo "</script>\n";
  200 + }
  201 +
  202 + /* Now that the buffer has been drained, clear it. */
  203 + $this->_buffer = array();
  204 + }
  205 +
  206 + /**
  207 + * Logs $message to the output window. The message is also passed along
  208 + * to any Log_observer instances that are observing this Log.
  209 + *
  210 + * @param mixed $message String or object containing the message to log.
  211 + * @param string $priority The priority of the message. Valid
  212 + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  213 + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  214 + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  215 + * @return boolean True on success or false on failure.
  216 + * @access public
  217 + */
  218 + function log($message, $priority = null)
  219 + {
  220 + /* If a priority hasn't been specified, use the default value. */
  221 + if ($priority === null) {
  222 + $priority = $this->_priority;
  223 + }
  224 +
  225 + /* Abort early if the priority is above the maximum logging level. */
  226 + if (!$this->_isMasked($priority)) {
  227 + return false;
  228 + }
  229 +
  230 + /* Extract the string representation of the message. */
  231 + $message = $this->_extractMessage($message);
  232 +
  233 + list($usec, $sec) = explode(' ', microtime());
  234 +
  235 + /* Build the output line that contains the log entry row. */
  236 + $line = '<tr align="left" valign="top">';
  237 + $line .= sprintf('<td>%s.%s</td>',
  238 + strftime('%T', $sec), substr($usec, 2, 2));
  239 + if (!empty($this->_ident)) {
  240 + $line .= '<td>' . $this->_ident . '</td>';
  241 + }
  242 + $line .= '<td>' . ucfirst($this->priorityToString($priority)) . '</td>';
  243 + $line .= sprintf('<td style="color: %s">%s</td>',
  244 + $this->_colors[$priority],
  245 + preg_replace('/\r\n|\n|\r/', '<br />', $message));
  246 + $line .= '</tr>';
  247 +
  248 + $this->_writeln($line);
  249 +
  250 + $this->_announce(array('priority' => $priority, 'message' => $message));
  251 +
  252 + return true;
  253 + }
  254 +}
  255 +
  256 +?>
... ...