1 | <?php |
---|
2 | /** |
---|
3 | * $Header: /repository/pear/Log/Log/win.php,v 1.21 2008/11/12 05:07:31 jon Exp $ |
---|
4 | * |
---|
5 | * @version $Revision: 1.21 $ |
---|
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('</head>'); |
---|
147 | $win.document.writeln('<body>'); |
---|
148 | $win.document.writeln('<table border="0" cellpadding="2" cellspacing="0">'); |
---|
149 | $win.document.writeln('<tr><th>Time</th>'); |
---|
150 | $identHeader |
---|
151 | $win.document.writeln('<th>Priority</th><th width="100%">Message</th></tr>'); |
---|
152 | </script> |
---|
153 | EOT; |
---|
154 | $this->_opened = true; |
---|
155 | } |
---|
156 | |
---|
157 | return $this->_opened; |
---|
158 | } |
---|
159 | |
---|
160 | /** |
---|
161 | * Closes the output stream if it is open. If there are still pending |
---|
162 | * lines in the output buffer, the output window will be opened so that |
---|
163 | * the buffer can be drained. |
---|
164 | * |
---|
165 | * @access public |
---|
166 | */ |
---|
167 | function close() |
---|
168 | { |
---|
169 | /* |
---|
170 | * If there are still lines waiting to be written, open the output |
---|
171 | * window so that we can drain the buffer. |
---|
172 | */ |
---|
173 | if (!$this->_opened && (count($this->_buffer) > 0)) { |
---|
174 | $this->open(); |
---|
175 | } |
---|
176 | |
---|
177 | if ($this->_opened) { |
---|
178 | $this->_writeln('</table>'); |
---|
179 | $this->_writeln('</body></html>'); |
---|
180 | $this->_opened = false; |
---|
181 | } |
---|
182 | |
---|
183 | return ($this->_opened === false); |
---|
184 | } |
---|
185 | |
---|
186 | /** |
---|
187 | * Writes a single line of text to the output window. |
---|
188 | * |
---|
189 | * @param string $line The line of text to write. |
---|
190 | * |
---|
191 | * @access private |
---|
192 | */ |
---|
193 | function _writeln($line) |
---|
194 | { |
---|
195 | /* Add this line to our output buffer. */ |
---|
196 | $this->_buffer[] = $line; |
---|
197 | |
---|
198 | /* Buffer the output until this page's headers have been sent. */ |
---|
199 | if (!headers_sent()) { |
---|
200 | return; |
---|
201 | } |
---|
202 | |
---|
203 | /* If we haven't already opened the output window, do so now. */ |
---|
204 | if (!$this->_opened && !$this->open()) { |
---|
205 | return false; |
---|
206 | } |
---|
207 | |
---|
208 | /* Drain the buffer to the output window. */ |
---|
209 | $win = $this->_name; |
---|
210 | foreach ($this->_buffer as $line) { |
---|
211 | echo "<script language='JavaScript'>\n"; |
---|
212 | echo "$win.document.writeln('" . addslashes($line) . "');\n"; |
---|
213 | echo "self.focus();\n"; |
---|
214 | echo "</script>\n"; |
---|
215 | } |
---|
216 | |
---|
217 | /* Now that the buffer has been drained, clear it. */ |
---|
218 | $this->_buffer = array(); |
---|
219 | } |
---|
220 | |
---|
221 | /** |
---|
222 | * Logs $message to the output window. The message is also passed along |
---|
223 | * to any Log_observer instances that are observing this Log. |
---|
224 | * |
---|
225 | * @param mixed $message String or object containing the message to log. |
---|
226 | * @param string $priority The priority of the message. Valid |
---|
227 | * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, |
---|
228 | * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, |
---|
229 | * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. |
---|
230 | * @return boolean True on success or false on failure. |
---|
231 | * @access public |
---|
232 | */ |
---|
233 | function log($message, $priority = null) |
---|
234 | { |
---|
235 | /* If a priority hasn't been specified, use the default value. */ |
---|
236 | if ($priority === null) { |
---|
237 | $priority = $this->_priority; |
---|
238 | } |
---|
239 | |
---|
240 | /* Abort early if the priority is above the maximum logging level. */ |
---|
241 | if (!$this->_isMasked($priority)) { |
---|
242 | return false; |
---|
243 | } |
---|
244 | |
---|
245 | /* Extract the string representation of the message. */ |
---|
246 | $message = $this->_extractMessage($message); |
---|
247 | $message = preg_replace('/\r\n|\n|\r/', '<br />', $message); |
---|
248 | |
---|
249 | list($usec, $sec) = explode(' ', microtime()); |
---|
250 | |
---|
251 | /* Build the output line that contains the log entry row. */ |
---|
252 | $line = '<tr>'; |
---|
253 | $line .= sprintf('<td>%s.%s</td>', |
---|
254 | strftime('%H:%M:%S', $sec), substr($usec, 2, 2)); |
---|
255 | if (!empty($this->_ident)) { |
---|
256 | $line .= '<td>' . $this->_ident . '</td>'; |
---|
257 | } |
---|
258 | $line .= '<td>' . ucfirst($this->priorityToString($priority)) . '</td>'; |
---|
259 | $line .= sprintf('<td class="l%d">%s</td>', $priority, $message); |
---|
260 | $line .= '</tr>'; |
---|
261 | |
---|
262 | $this->_writeln($line); |
---|
263 | |
---|
264 | $this->_announce(array('priority' => $priority, 'message' => $message)); |
---|
265 | |
---|
266 | return true; |
---|
267 | } |
---|
268 | |
---|
269 | } |
---|