Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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