home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February (DVD) / PCWorld_2008-02_DVD.iso / v cisle / PHP / PHP.exe / xampp-win32-1.6.5-installer.exe / php / PEAR / Log.php < prev    next >
Encoding:
PHP Script  |  2007-12-20  |  24.6 KB  |  825 lines

  1. <?php
  2. /**
  3.  * $Header: /repository/pear/Log/Log.php,v 1.64 2006/10/08 23:03:15 jon Exp $
  4.  * $Horde: horde/lib/Log.php,v 1.15 2000/06/29 23:39:45 jon Exp $
  5.  *
  6.  * @version $Revision: 1.64 $
  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.      *
  74.      * @var integer
  75.      * @access private
  76.      */
  77.     var $_mask = PEAR_LOG_ALL;
  78.  
  79.     /**
  80.      * Holds all Log_observer objects that wish to be notified of new messages.
  81.      *
  82.      * @var array
  83.      * @access private
  84.      */
  85.     var $_listeners = array();
  86.  
  87.     /**
  88.      * Maps canonical format keys to position arguments for use in building
  89.      * "line format" strings.
  90.      *
  91.      * @var array
  92.      * @access private
  93.      */
  94.     var $_formatMap = array('%{timestamp}'  => '%1$s',
  95.                             '%{ident}'      => '%2$s',
  96.                             '%{priority}'   => '%3$s',
  97.                             '%{message}'    => '%4$s',
  98.                             '%{file}'       => '%5$s',
  99.                             '%{line}'       => '%6$s',
  100.                             '%{function}'   => '%7$s',
  101.                             '%\{'           => '%%{');
  102.  
  103.  
  104.     /**
  105.      * Attempts to return a concrete Log instance of type $handler.
  106.      *
  107.      * @param string $handler   The type of concrete Log subclass to return.
  108.      *                          Attempt to dynamically include the code for
  109.      *                          this subclass. Currently, valid values are
  110.      *                          'console', 'syslog', 'sql', 'file', and 'mcal'.
  111.      *
  112.      * @param string $name      The name of the actually log file, table, or
  113.      *                          other specific store to use. Defaults to an
  114.      *                          empty string, with which the subclass will
  115.      *                          attempt to do something intelligent.
  116.      *
  117.      * @param string $ident     The identity reported to the log system.
  118.      *
  119.      * @param array  $conf      A hash containing any additional configuration
  120.      *                          information that a subclass might need.
  121.      *
  122.      * @param int $level        Log messages up to and including this level.
  123.      *
  124.      * @return object Log       The newly created concrete Log instance, or
  125.      *                          null on an error.
  126.      * @access public
  127.      * @since Log 1.0
  128.      */
  129.     function &factory($handler, $name = '', $ident = '', $conf = array(),
  130.                       $level = PEAR_LOG_DEBUG)
  131.     {
  132.         $handler = strtolower($handler);
  133.         $class = 'Log_' . $handler;
  134.         $classfile = 'Log/' . $handler . '.php';
  135.  
  136.         /*
  137.          * Attempt to include our version of the named class, but don't treat
  138.          * a failure as fatal.  The caller may have already included their own
  139.          * version of the named class.
  140.          */
  141.         if (!class_exists($class)) {
  142.             include_once $classfile;
  143.         }
  144.  
  145.         /* If the class exists, return a new instance of it. */
  146.         if (class_exists($class)) {
  147.             $obj = &new $class($name, $ident, $conf, $level);
  148.             return $obj;
  149.         }
  150.  
  151.         $null = null;
  152.         return $null;
  153.     }
  154.  
  155.     /**
  156.      * Attempts to return a reference to a concrete Log instance of type
  157.      * $handler, only creating a new instance if no log instance with the same
  158.      * parameters currently exists.
  159.      *
  160.      * You should use this if there are multiple places you might create a
  161.      * logger, you don't want to create multiple loggers, and you don't want to
  162.      * check for the existance of one each time. The singleton pattern does all
  163.      * the checking work for you.
  164.      *
  165.      * <b>You MUST call this method with the $var = &Log::singleton() syntax.
  166.      * Without the ampersand (&) in front of the method name, you will not get
  167.      * a reference, you will get a copy.</b>
  168.      *
  169.      * @param string $handler   The type of concrete Log subclass to return.
  170.      *                          Attempt to dynamically include the code for
  171.      *                          this subclass. Currently, valid values are
  172.      *                          'console', 'syslog', 'sql', 'file', and 'mcal'.
  173.      *
  174.      * @param string $name      The name of the actually log file, table, or
  175.      *                          other specific store to use.  Defaults to an
  176.      *                          empty string, with which the subclass will
  177.      *                          attempt to do something intelligent.
  178.      *
  179.      * @param string $ident     The identity reported to the log system.
  180.      *
  181.      * @param array $conf       A hash containing any additional configuration
  182.      *                          information that a subclass might need.
  183.      *
  184.      * @param int $level        Log messages up to and including this level.
  185.      *
  186.      * @return object Log       The newly created concrete Log instance, or
  187.      *                          null on an error.
  188.      * @access public
  189.      * @since Log 1.0
  190.      */
  191.     function &singleton($handler, $name = '', $ident = '', $conf = array(),
  192.                         $level = PEAR_LOG_DEBUG)
  193.     {
  194.         static $instances;
  195.         if (!isset($instances)) $instances = array();
  196.  
  197.         $signature = serialize(array($handler, $name, $ident, $conf, $level));
  198.         if (!isset($instances[$signature])) {
  199.             $instances[$signature] = &Log::factory($handler, $name, $ident,
  200.                                                    $conf, $level);
  201.         }
  202.  
  203.         return $instances[$signature];
  204.     }
  205.  
  206.     /**
  207.      * Abstract implementation of the open() method.
  208.      * @since Log 1.0
  209.      */
  210.     function open()
  211.     {
  212.         return false;
  213.     }
  214.  
  215.     /**
  216.      * Abstract implementation of the close() method.
  217.      * @since Log 1.0
  218.      */
  219.     function close()
  220.     {
  221.         return false;
  222.     }
  223.  
  224.     /**
  225.      * Abstract implementation of the flush() method.
  226.      * @since Log 1.8.2
  227.      */
  228.     function flush()
  229.     {
  230.         return false;
  231.     }
  232.  
  233.     /**
  234.      * Abstract implementation of the log() method.
  235.      * @since Log 1.0
  236.      */
  237.     function log($message, $priority = null)
  238.     {
  239.         return false;
  240.     }
  241.  
  242.     /**
  243.      * A convenience function for logging a emergency event.  It will log a
  244.      * message at the PEAR_LOG_EMERG log level.
  245.      *
  246.      * @param   mixed   $message    String or object containing the message
  247.      *                              to log.
  248.      *
  249.      * @return  boolean True if the message was successfully logged.
  250.      *
  251.      * @access  public
  252.      * @since   Log 1.7.0
  253.      */
  254.     function emerg($message)
  255.     {
  256.         return $this->log($message, PEAR_LOG_EMERG);
  257.     }
  258.  
  259.     /**
  260.      * A convenience function for logging an alert event.  It will log a
  261.      * message at the PEAR_LOG_ALERT log level.
  262.      *
  263.      * @param   mixed   $message    String or object containing the message
  264.      *                              to log.
  265.      *
  266.      * @return  boolean True if the message was successfully logged.
  267.      *
  268.      * @access  public
  269.      * @since   Log 1.7.0
  270.      */
  271.     function alert($message)
  272.     {
  273.         return $this->log($message, PEAR_LOG_ALERT);
  274.     }
  275.  
  276.     /**
  277.      * A convenience function for logging a critical event.  It will log a
  278.      * message at the PEAR_LOG_CRIT log level.
  279.      *
  280.      * @param   mixed   $message    String or object containing the message
  281.      *                              to log.
  282.      *
  283.      * @return  boolean True if the message was successfully logged.
  284.      *
  285.      * @access  public
  286.      * @since   Log 1.7.0
  287.      */
  288.     function crit($message)
  289.     {
  290.         return $this->log($message, PEAR_LOG_CRIT);
  291.     }
  292.  
  293.     /**
  294.      * A convenience function for logging a error event.  It will log a
  295.      * message at the PEAR_LOG_ERR log level.
  296.      *
  297.      * @param   mixed   $message    String or object containing the message
  298.      *                              to log.
  299.      *
  300.      * @return  boolean True if the message was successfully logged.
  301.      *
  302.      * @access  public
  303.      * @since   Log 1.7.0
  304.      */
  305.     function err($message)
  306.     {
  307.         return $this->log($message, PEAR_LOG_ERR);
  308.     }
  309.  
  310.     /**
  311.      * A convenience function for logging a warning event.  It will log a
  312.      * message at the PEAR_LOG_WARNING log level.
  313.      *
  314.      * @param   mixed   $message    String or object containing the message
  315.      *                              to log.
  316.      *
  317.      * @return  boolean True if the message was successfully logged.
  318.      *
  319.      * @access  public
  320.      * @since   Log 1.7.0
  321.      */
  322.     function warning($message)
  323.     {
  324.         return $this->log($message, PEAR_LOG_WARNING);
  325.     }
  326.  
  327.     /**
  328.      * A convenience function for logging a notice event.  It will log a
  329.      * message at the PEAR_LOG_NOTICE log level.
  330.      *
  331.      * @param   mixed   $message    String or object containing the message
  332.      *                              to log.
  333.      *
  334.      * @return  boolean True if the message was successfully logged.
  335.      *
  336.      * @access  public
  337.      * @since   Log 1.7.0
  338.      */
  339.     function notice($message)
  340.     {
  341.         return $this->log($message, PEAR_LOG_NOTICE);
  342.     }
  343.  
  344.     /**
  345.      * A convenience function for logging a information event.  It will log a
  346.      * message at the PEAR_LOG_INFO log level.
  347.      *
  348.      * @param   mixed   $message    String or object containing the message
  349.      *                              to log.
  350.      *
  351.      * @return  boolean True if the message was successfully logged.
  352.      *
  353.      * @access  public
  354.      * @since   Log 1.7.0
  355.      */
  356.     function info($message)
  357.     {
  358.         return $this->log($message, PEAR_LOG_INFO);
  359.     }
  360.  
  361.     /**
  362.      * A convenience function for logging a debug event.  It will log a
  363.      * message at the PEAR_LOG_DEBUG log level.
  364.      *
  365.      * @param   mixed   $message    String or object containing the message
  366.      *                              to log.
  367.      *
  368.      * @return  boolean True if the message was successfully logged.
  369.      *
  370.      * @access  public
  371.      * @since   Log 1.7.0
  372.      */
  373.     function debug($message)
  374.     {
  375.         return $this->log($message, PEAR_LOG_DEBUG);
  376.     }
  377.  
  378.     /**
  379.      * Returns the string representation of the message data.
  380.      *
  381.      * If $message is an object, _extractMessage() will attempt to extract
  382.      * the message text using a known method (such as a PEAR_Error object's
  383.      * getMessage() method).  If a known method, cannot be found, the
  384.      * serialized representation of the object will be returned.
  385.      *
  386.      * If the message data is already a string, it will be returned unchanged.
  387.      *
  388.      * @param  mixed $message   The original message data.  This may be a
  389.      *                          string or any object.
  390.      *
  391.      * @return string           The string representation of the message.
  392.      *
  393.      * @access private
  394.      */
  395.     function _extractMessage($message)
  396.     {
  397.         /*
  398.          * If we've been given an object, attempt to extract the message using
  399.          * a known method.  If we can't find such a method, default to the
  400.          * "human-readable" version of the object.
  401.          *
  402.          * We also use the human-readable format for arrays.
  403.          */
  404.         if (is_object($message)) {
  405.             if (method_exists($message, 'getmessage')) {
  406.                 $message = $message->getMessage();
  407.             } else if (method_exists($message, 'tostring')) {
  408.                 $message = $message->toString();
  409.             } else if (method_exists($message, '__tostring')) {
  410.                 if (version_compare(PHP_VERSION, '5.0.0', 'ge')) {
  411.                     $message = (string)$message;
  412.                 } else {
  413.                     $message = $message->__toString();
  414.                 }
  415.             } else {
  416.                 $message = print_r($message, true);
  417.             }
  418.         } else if (is_array($message)) {
  419.             if (isset($message['message'])) {
  420.                 $message = $message['message'];
  421.             } else {
  422.                 $message = print_r($message, true);
  423.             }
  424.         }
  425.  
  426.         /* Otherwise, we assume the message is a string. */
  427.         return $message;
  428.     }
  429.  
  430.     /**
  431.      * Using debug_backtrace(), returns the file, line, and enclosing function
  432.      * name of the source code context from which log() was invoked.
  433.      *
  434.      * @param   int     $depth  The initial number of frames we should step
  435.      *                          back into the trace.
  436.      *
  437.      * @return  array   Array containing three strings: the filename, the line,
  438.      *                  and the function name from which log() was called.
  439.      *
  440.      * @access  private
  441.      * @since   Log 1.9.4
  442.      */
  443.     function _getBacktraceVars($depth)
  444.     {
  445.         /* Start by generating a backtrace from the current call (here). */
  446.         $backtrace = debug_backtrace();
  447.  
  448.         /*
  449.          * If we were ultimately invoked by the composite handler, we need to
  450.          * increase our depth one additional level to compensate.
  451.          */
  452.         if (strcasecmp(@$backtrace[$depth+1]['class'], 'Log_composite') == 0) {
  453.             $depth++;
  454.         }
  455.  
  456.         /*
  457.          * We're interested in the frame which invoked the log() function, so
  458.          * we need to walk back some number of frames into the backtrace.  The
  459.          * $depth parameter tells us where to start looking.   We go one step
  460.          * further back to find the name of the encapsulating function from
  461.          * which log() was called.
  462.          */
  463.         $file = @$backtrace[$depth]['file'];
  464.         $line = @$backtrace[$depth]['line'];
  465.         $func = @$backtrace[$depth + 1]['function'];
  466.  
  467.         /*
  468.          * However, if log() was called from one of our "shortcut" functions,
  469.          * we're going to need to go back an additional step.
  470.          */
  471.         if (in_array($func, array('emerg', 'alert', 'crit', 'err', 'warning',
  472.                                   'notice', 'info', 'debug'))) {
  473.             $file = @$backtrace[$depth + 1]['file'];
  474.             $line = @$backtrace[$depth + 1]['line'];
  475.             $func = @$backtrace[$depth + 2]['function'];
  476.         }
  477.  
  478.         /*
  479.          * If we couldn't extract a function name (perhaps because we were
  480.          * executed from the "main" context), provide a default value.
  481.          */
  482.         if (is_null($func)) {
  483.             $func = '(none)';
  484.         }
  485.  
  486.         /* Return a 3-tuple containing (file, line, function). */
  487.         return array($file, $line, $func);
  488.     }
  489.  
  490.     /**
  491.      * Produces a formatted log line based on a format string and a set of
  492.      * variables representing the current log record and state.
  493.      *
  494.      * @return  string  Formatted log string.
  495.      *
  496.      * @access  private
  497.      * @since   Log 1.9.4
  498.      */
  499.     function _format($format, $timestamp, $priority, $message)
  500.     {
  501.         /*
  502.          * If the format string references any of the backtrace-driven
  503.          * variables (%5, %6, %7), generate the backtrace and fetch them.
  504.          */
  505.         if (strpos($format, '%5') || strpos($format, '%6') || strpos($format, '%7')) {
  506.             list($file, $line, $func) = $this->_getBacktraceVars(2);
  507.         }
  508.  
  509.         /*
  510.          * Build the formatted string.  We use the sprintf() function's
  511.          * "argument swapping" capability to dynamically select and position
  512.          * the variables which will ultimately appear in the log string.
  513.          */
  514.         return sprintf($format,
  515.                        $timestamp,
  516.                        $this->_ident,
  517.                        $this->priorityToString($priority),
  518.                        $message,
  519.                        isset($file) ? $file : '',
  520.                        isset($line) ? $line : '',
  521.                        isset($func) ? $func : '');
  522.     }
  523.  
  524.     /**
  525.      * Returns the string representation of a PEAR_LOG_* integer constant.
  526.      *
  527.      * @param int $priority     A PEAR_LOG_* integer constant.
  528.      *
  529.      * @return string           The string representation of $level.
  530.      *
  531.      * @since   Log 1.0
  532.      */
  533.     function priorityToString($priority)
  534.     {
  535.         $levels = array(
  536.             PEAR_LOG_EMERG   => 'emergency',
  537.             PEAR_LOG_ALERT   => 'alert',
  538.             PEAR_LOG_CRIT    => 'critical',
  539.             PEAR_LOG_ERR     => 'error',
  540.             PEAR_LOG_WARNING => 'warning',
  541.             PEAR_LOG_NOTICE  => 'notice',
  542.             PEAR_LOG_INFO    => 'info',
  543.             PEAR_LOG_DEBUG   => 'debug'
  544.         );
  545.  
  546.         return $levels[$priority];
  547.     }
  548.  
  549.     /**
  550.      * Returns the the PEAR_LOG_* integer constant for the given string
  551.      * representation of a priority name.  This function performs a
  552.      * case-insensitive search.
  553.      *
  554.      * @param string $name      String containing a priority name.
  555.      *
  556.      * @return string           The PEAR_LOG_* integer contstant corresponding
  557.      *                          the the specified priority name.
  558.      *
  559.      * @since   Log 1.9.0
  560.      */
  561.     function stringToPriority($name)
  562.     {
  563.         $levels = array(
  564.             'emergency' => PEAR_LOG_EMERG,
  565.             'alert'     => PEAR_LOG_ALERT,
  566.             'critical'  => PEAR_LOG_CRIT,
  567.             'error'     => PEAR_LOG_ERR,
  568.             'warning'   => PEAR_LOG_WARNING,
  569.             'notice'    => PEAR_LOG_NOTICE,
  570.             'info'      => PEAR_LOG_INFO,
  571.             'debug'     => PEAR_LOG_DEBUG
  572.         );
  573.  
  574.         return $levels[strtolower($name)];
  575.     }
  576.  
  577.     /**
  578.      * Calculate the log mask for the given priority.
  579.      *
  580.      * This method may be called statically.
  581.      *
  582.      * @param integer   $priority   The priority whose mask will be calculated.
  583.      *
  584.      * @return integer  The calculated log mask.
  585.      *
  586.      * @access  public
  587.      * @since   Log 1.7.0
  588.      */
  589.     function MASK($priority)
  590.     {
  591.         return (1 << $priority);
  592.     }
  593.  
  594.     /**
  595.      * Calculate the log mask for all priorities up to the given priority.
  596.      *
  597.      * This method may be called statically.
  598.      *
  599.      * @param integer   $priority   The maximum priority covered by this mask.
  600.      *
  601.      * @return integer  The resulting log mask.
  602.      *
  603.      * @access  public
  604.      * @since   Log 1.7.0
  605.      *
  606.      * @deprecated deprecated since Log 1.9.4; use Log::MAX() instead
  607.      */
  608.     function UPTO($priority)
  609.     {
  610.         return Log::MAX($priority);
  611.     }
  612.  
  613.     /**
  614.      * Calculate the log mask for all priorities greater than or equal to the
  615.      * given priority.  In other words, $priority will be the lowest priority
  616.      * matched by the resulting mask.
  617.      *
  618.      * This method may be called statically.
  619.      *
  620.      * @param integer   $priority   The minimum priority covered by this mask.
  621.      *
  622.      * @return integer  The resulting log mask.
  623.      *
  624.      * @access  public
  625.      * @since   Log 1.9.4
  626.      */
  627.     function MIN($priority)
  628.     {
  629.         return PEAR_LOG_ALL ^ ((1 << $priority) - 1);
  630.     }
  631.  
  632.     /**
  633.      * Calculate the log mask for all priorities less than or equal to the
  634.      * given priority.  In other words, $priority will be the highests priority
  635.      * matched by the resulting mask.
  636.      *
  637.      * This method may be called statically.
  638.      *
  639.      * @param integer   $priority   The maximum priority covered by this mask.
  640.      *
  641.      * @return integer  The resulting log mask.
  642.      *
  643.      * @access  public
  644.      * @since   Log 1.9.4
  645.      */
  646.     function MAX($priority)
  647.     {
  648.         return ((1 << ($priority + 1)) - 1);
  649.     }
  650.  
  651.     /**
  652.      * Set and return the level mask for the current Log instance.
  653.      *
  654.      * @param integer $mask     A bitwise mask of log levels.
  655.      *
  656.      * @return integer          The current level mask.
  657.      *
  658.      * @access  public
  659.      * @since   Log 1.7.0
  660.      */
  661.     function setMask($mask)
  662.     {
  663.         $this->_mask = $mask;
  664.  
  665.         return $this->_mask;
  666.     }
  667.  
  668.     /**
  669.      * Returns the current level mask.
  670.      *
  671.      * @return interger         The current level mask.
  672.      *
  673.      * @access  public
  674.      * @since   Log 1.7.0
  675.      */
  676.     function getMask()
  677.     {
  678.         return $this->_mask;
  679.     }
  680.  
  681.     /**
  682.      * Check if the given priority is included in the current level mask.
  683.      *
  684.      * @param integer   $priority   The priority to check.
  685.      *
  686.      * @return boolean  True if the given priority is included in the current
  687.      *                  log mask.
  688.      *
  689.      * @access  private
  690.      * @since   Log 1.7.0
  691.      */
  692.     function _isMasked($priority)
  693.     {
  694.         return (Log::MASK($priority) & $this->_mask);
  695.     }
  696.  
  697.     /**
  698.      * Returns the current default priority.
  699.      *
  700.      * @return integer  The current default priority.
  701.      *
  702.      * @access  public
  703.      * @since   Log 1.8.4
  704.      */
  705.     function getPriority()
  706.     {
  707.         return $this->_priority;
  708.     }
  709.  
  710.     /**
  711.      * Sets the default priority to the specified value.
  712.      *
  713.      * @param   integer $priority   The new default priority.
  714.      *
  715.      * @access  public
  716.      * @since   Log 1.8.4
  717.      */
  718.     function setPriority($priority)
  719.     {
  720.         $this->_priority = $priority;
  721.     }
  722.  
  723.     /**
  724.      * Adds a Log_observer instance to the list of observers that are listening
  725.      * for messages emitted by this Log instance.
  726.      *
  727.      * @param object    $observer   The Log_observer instance to attach as a
  728.      *                              listener.
  729.      *
  730.      * @param boolean   True if the observer is successfully attached.
  731.      *
  732.      * @access  public
  733.      * @since   Log 1.0
  734.      */
  735.     function attach(&$observer)
  736.     {
  737.         if (!is_a($observer, 'Log_observer')) {
  738.             return false;
  739.         }
  740.  
  741.         $this->_listeners[$observer->_id] = &$observer;
  742.  
  743.         return true;
  744.     }
  745.  
  746.     /**
  747.      * Removes a Log_observer instance from the list of observers.
  748.      *
  749.      * @param object    $observer   The Log_observer instance to detach from
  750.      *                              the list of listeners.
  751.      *
  752.      * @param boolean   True if the observer is successfully detached.
  753.      *
  754.      * @access  public
  755.      * @since   Log 1.0
  756.      */
  757.     function detach($observer)
  758.     {
  759.         if (!is_a($observer, 'Log_observer') ||
  760.             !isset($this->_listeners[$observer->_id])) {
  761.             return false;
  762.         }
  763.  
  764.         unset($this->_listeners[$observer->_id]);
  765.  
  766.         return true;
  767.     }
  768.  
  769.     /**
  770.      * Informs each registered observer instance that a new message has been
  771.      * logged.
  772.      *
  773.      * @param array     $event      A hash describing the log event.
  774.      *
  775.      * @access private
  776.      */
  777.     function _announce($event)
  778.     {
  779.         foreach ($this->_listeners as $id => $listener) {
  780.             if ($event['priority'] <= $this->_listeners[$id]->_priority) {
  781.                 $this->_listeners[$id]->notify($event);
  782.             }
  783.         }
  784.     }
  785.  
  786.     /**
  787.      * Indicates whether this is a composite class.
  788.      *
  789.      * @return boolean          True if this is a composite class.
  790.      *
  791.      * @access  public
  792.      * @since   Log 1.0
  793.      */
  794.     function isComposite()
  795.     {
  796.         return false;
  797.     }
  798.  
  799.     /**
  800.      * Sets this Log instance's identification string.
  801.      *
  802.      * @param string    $ident      The new identification string.
  803.      *
  804.      * @access  public
  805.      * @since   Log 1.6.3
  806.      */
  807.     function setIdent($ident)
  808.     {
  809.         $this->_ident = $ident;
  810.     }
  811.  
  812.     /**
  813.      * Returns the current identification string.
  814.      *
  815.      * @return string   The current Log instance's identification string.
  816.      *
  817.      * @access  public
  818.      * @since   Log 1.6.3
  819.      */
  820.     function getIdent()
  821.     {
  822.         return $this->_ident;
  823.     }
  824. }
  825.