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
 *
5
 * @version $Revision: 278003 $
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 styles.
42
     * @var array
43
     * @access private
44
     */
45
    var $_styles = array(
46
                        PEAR_LOG_EMERG   => 'color: red;',
47
                        PEAR_LOG_ALERT   => 'color: orange;',
48
                        PEAR_LOG_CRIT    => 'color: yellow;',
49
                        PEAR_LOG_ERR     => 'color: green;',
50
                        PEAR_LOG_WARNING => 'color: blue;',
51
                        PEAR_LOG_NOTICE  => 'color: indigo;',
52
                        PEAR_LOG_INFO    => 'color: violet;',
53
                        PEAR_LOG_DEBUG   => 'color: 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 = str_replace(' ', '_', $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['styles']) && is_array($conf['styles'])) {
84
            $this->_styles = $conf['styles'];
85
        }
86
        if (isset($conf['colors']) && is_array($conf['colors'])) {
87
            foreach ($conf['colors'] as $level => $color) {
88
                $this->_styles[$level] .= "color: $color;";
89
            }
90
        }
91
 
92
        register_shutdown_function(array(&$this, '_Log_win'));
93
    }
94
 
95
    /**
96
     * Destructor
97
     */
98
    function _Log_win()
99
    {
100
        if ($this->_opened || (count($this->_buffer) > 0)) {
101
            $this->close();
102
        }
103
    }
104
 
105
    /**
106
     * The first time open() is called, it will open a new browser window and
107
     * prepare it for output.
108
     *
109
     * This is implicitly called by log(), if necessary.
110
     *
111
     * @access public
112
     */
113
    function open()
114
    {
115
        if (!$this->_opened) {
116
            $win = $this->_name;
117
            $styles = $this->_styles;
118
 
119
            if (!empty($this->_ident)) {
120
                $identHeader = "$win.document.writeln('<th>Ident</th>')";
121
            } else {
122
                $identHeader = '';
123
            }
124
 
125
            echo <<< EOT
126
<script language="JavaScript">
127
$win = window.open('', '{$this->_name}', 'toolbar=no,scrollbars,width=600,height=400');
128
$win.document.writeln('<html>');
129
$win.document.writeln('<head>');
130
$win.document.writeln('<title>{$this->_title}</title>');
131
$win.document.writeln('<style type="text/css">');
132
$win.document.writeln('body { font-family: monospace; font-size: 8pt; }');
133
$win.document.writeln('td,th { font-size: 8pt; }');
134
$win.document.writeln('td,th { border-bottom: #999999 solid 1px; }');
135
$win.document.writeln('td,th { border-right: #999999 solid 1px; }');
136
$win.document.writeln('tr { text-align: left; vertical-align: top; }');
137
$win.document.writeln('td.l0 { $styles[0] }');
138
$win.document.writeln('td.l1 { $styles[1] }');
139
$win.document.writeln('td.l2 { $styles[2] }');
140
$win.document.writeln('td.l3 { $styles[3] }');
141
$win.document.writeln('td.l4 { $styles[4] }');
142
$win.document.writeln('td.l5 { $styles[5] }');
143
$win.document.writeln('td.l6 { $styles[6] }');
144
$win.document.writeln('td.l7 { $styles[7] }');
145
$win.document.writeln('</style>');
146
$win.document.writeln('<script type="text/javascript">');
147
$win.document.writeln('function scroll() {');
148
$win.document.writeln(' body = document.getElementById("{$this->_name}");');
149
$win.document.writeln(' body.scrollTop = body.scrollHeight;');
150
$win.document.writeln('}');
151
$win.document.writeln('<\/script>');
152
$win.document.writeln('</head>');
153
$win.document.writeln('<body id="{$this->_name}" onclick="scroll()">');
154
$win.document.writeln('<table border="0" cellpadding="2" cellspacing="0">');
155
$win.document.writeln('<tr><th>Time</th>');
156
$identHeader
157
$win.document.writeln('<th>Priority</th><th width="100%">Message</th></tr>');
158
</script>
159
EOT;
160
            $this->_opened = true;
161
        }
162
 
163
        return $this->_opened;
164
    }
165
 
166
    /**
167
     * Closes the output stream if it is open.  If there are still pending
168
     * lines in the output buffer, the output window will be opened so that
169
     * the buffer can be drained.
170
     *
171
     * @access public
172
     */
173
    function close()
174
    {
175
        /*
176
         * If there are still lines waiting to be written, open the output
177
         * window so that we can drain the buffer.
178
         */
179
        if (!$this->_opened && (count($this->_buffer) > 0)) {
180
            $this->open();
181
        }
182
 
183
        if ($this->_opened) {
184
            $this->_writeln('</table>');
185
            $this->_writeln('</body></html>');
186
            $this->_drainBuffer();
187
            $this->_opened = false;
188
        }
189
 
190
        return ($this->_opened === false);
191
    }
192
 
193
    /**
194
     * Writes the contents of the output buffer to the output window.
195
     *
196
     * @access private
197
     */
198
    function _drainBuffer()
199
    {
200
        $win = $this->_name;
201
        foreach ($this->_buffer as $line) {
202
            echo "<script language='JavaScript'>\n";
203
            echo "$win.document.writeln('" . addslashes($line) . "');\n";
204
            echo "self.focus();\n";
205
            echo "</script>\n";
206
        }
207
 
208
        /* Now that the buffer has been drained, clear it. */
209
        $this->_buffer = array();
210
    }
211
 
212
    /**
213
     * Writes a single line of text to the output buffer.
214
     *
215
     * @param string    $line   The line of text to write.
216
     *
217
     * @access private
218
     */
219
    function _writeln($line)
220
    {
221
        /* Add this line to our output buffer. */
222
        $this->_buffer[] = $line;
223
 
224
        /* Buffer the output until this page's headers have been sent. */
225
        if (!headers_sent()) {
226
            return;
227
        }
228
 
229
        /* If we haven't already opened the output window, do so now. */
230
        if (!$this->_opened && !$this->open()) {
231
            return;
232
        }
233
 
234
        /* Drain the buffer to the output window. */
235
        $this->_drainBuffer();
236
    }
237
 
238
    /**
239
     * Logs $message to the output window.  The message is also passed along
240
     * to any Log_observer instances that are observing this Log.
241
     *
242
     * @param mixed  $message  String or object containing the message to log.
243
     * @param string $priority The priority of the message.  Valid
244
     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
245
     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
246
     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
247
     * @return boolean  True on success or false on failure.
248
     * @access public
249
     */
250
    function log($message, $priority = null)
251
    {
252
        /* If a priority hasn't been specified, use the default value. */
253
        if ($priority === null) {
254
            $priority = $this->_priority;
255
        }
256
 
257
        /* Abort early if the priority is above the maximum logging level. */
258
        if (!$this->_isMasked($priority)) {
259
            return false;
260
        }
261
 
262
        /* Extract the string representation of the message. */
263
        $message = $this->_extractMessage($message);
264
        $message = preg_replace('/\r\n|\n|\r/', '<br />', $message);
265
 
266
        list($usec, $sec) = explode(' ', microtime());
267
 
268
        /* Build the output line that contains the log entry row. */
269
        $line  = '<tr>';
270
        $line .= sprintf('<td>%s.%s</td>',
271
                         strftime('%H:%M:%S', $sec), substr($usec, 2, 2));
272
        if (!empty($this->_ident)) {
273
            $line .= '<td>' . $this->_ident . '</td>';
274
        }
275
        $line .= '<td>' . ucfirst($this->priorityToString($priority)) . '</td>';
276
        $line .= sprintf('<td class="l%d">%s</td>', $priority, $message);
277
        $line .= '</tr>';
278
 
279
        $this->_writeln($line);
280
 
281
        $this->_announce(array('priority' => $priority, 'message' => $message));
282
 
283
        return true;
284
    }
285
 
286
}