1 : <?php
2 : /**
3 : * Copyright (c) 2005-2009, Laurent Laville <pear@laurent-laville.org>
4 : *
5 : * All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : *
11 : * * Redistributions of source code must retain the above copyright
12 : * notice, this list of conditions and the following disclaimer.
13 : * * Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : * * Neither the name of the authors nor the names of its contributors
17 : * may be used to endorse or promote products derived from this software
18 : * without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 : * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 : * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 : * POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : * PHP versions 4 and 5
33 : *
34 : * @category HTML
35 : * @package HTML_CSS
36 : * @author Laurent Laville <pear@laurent-laville.org>
37 : * @copyright 2005-2009 Laurent Laville
38 : * @license http://www.opensource.org/licenses/bsd-license.php BSD
39 : * @version CVS: $Id: Error.php,v 1.14 2009/01/19 23:27:17 farell Exp $
40 : * @link http://pear.php.net/package/HTML_CSS
41 : * @since File available since Release 1.0.0RC1
42 : */
43 :
44 1 : require_once 'PEAR.php';
45 :
46 : /**
47 : * This class creates a css error object, extending the PEAR_Error class.
48 : *
49 : * @category HTML
50 : * @package HTML_CSS
51 : * @author Laurent Laville <pear@laurent-laville.org>
52 : * @copyright 2005-2009 Laurent Laville
53 : * @license http://www.opensource.org/licenses/bsd-license.php BSD
54 : * @version Release: 1.5.3
55 : * @link http://pear.php.net/package/HTML_CSS
56 : * @since Class available since Release 1.0.0RC1
57 : */
58 :
59 1 : class HTML_CSS_Error extends PEAR_Error
60 : {
61 : /**
62 : * Constructor (ZE1)
63 : *
64 : * @param string $message (optional) message
65 : * @param int $code (optional) error code
66 : * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
67 : * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
68 : * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
69 : * @param mixed $options (optional) error level, _OR_ in the case of
70 : * PEAR_ERROR_CALLBACK, the callback function
71 : * or object/method tuple.
72 : * @param string $userinfo (optional) additional user/debug info
73 : *
74 : * @since version 1.0.0 (2006-06-24)
75 : * @access public
76 : */
77 : function HTML_CSS_Error($message = null,
78 : $code = null,
79 : $mode = null, $options = null,
80 : $userinfo = null)
81 : {
82 0 : $this->__construct($message, $code, $mode, $options, $userinfo);
83 0 : }
84 :
85 : /**
86 : * Constructor (ZE2)
87 : *
88 : * @param string $message (optional) message
89 : * @param int $code (optional) error code
90 : * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
91 : * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
92 : * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
93 : * @param mixed $options (optional) error level, _OR_ in the case of
94 : * PEAR_ERROR_CALLBACK, the callback function
95 : * or object/method tuple.
96 : * @param string $userinfo (optional) additional user/debug info
97 : *
98 : * @since version 1.0.0 (2006-06-24)
99 : * @access public
100 : */
101 : function __construct($message = null,
102 : $code = null,
103 : $mode = null, $options = null,
104 : $userinfo = null)
105 : {
106 4 : if ($mode === null) {
107 : $mode = PEAR_ERROR_RETURN;
108 : }
109 4 : $this->message = $message;
110 4 : $this->code = $code;
111 4 : $this->mode = $mode;
112 4 : $this->userinfo = $userinfo;
113 4 : $this->backtrace = debug_backtrace();
114 :
115 4 : if ($mode & PEAR_ERROR_CALLBACK) {
116 4 : $this->level = E_USER_NOTICE;
117 4 : $this->callback = $options;
118 4 : } else {
119 : if ($options === null) {
120 : switch ($userinfo['level']) {
121 : case 'exception':
122 : case 'error':
123 : $options = E_USER_ERROR;
124 : break;
125 : case 'warning':
126 : $options = E_USER_WARNING;
127 : break;
128 : default:
129 : $options = E_USER_NOTICE;
130 : }
131 : }
132 : $this->level = $options;
133 : $this->callback = null;
134 : }
135 4 : if ($this->mode & PEAR_ERROR_PRINT) {
136 : echo $this->_display($userinfo);
137 : }
138 4 : if ($this->mode & PEAR_ERROR_TRIGGER) {
139 : trigger_error($this->getMessage(), $this->level);
140 : }
141 4 : if ($this->mode & PEAR_ERROR_DIE) {
142 : $this->log();
143 : die();
144 : }
145 4 : if ($this->mode & PEAR_ERROR_CALLBACK) {
146 4 : if (is_callable($this->callback)) {
147 4 : call_user_func($this->callback, $this);
148 4 : } else {
149 : $this->log();
150 : }
151 4 : }
152 4 : }
153 :
154 : /**
155 : * Get error level from an error object
156 : *
157 : * @return int error level
158 : * @since version 1.0.0 (2006-06-24)
159 : * @access public
160 : */
161 : function getLevel()
162 : {
163 : return $this->level;
164 : }
165 :
166 : /**
167 : * Default callback function/method from an error object
168 : *
169 : * @return void
170 : * @since version 1.0.0 (2006-06-24)
171 : * @access public
172 : */
173 : function log()
174 : {
175 : $userinfo = $this->getUserInfo();
176 :
177 : $display_errors = ini_get('display_errors');
178 : $log_errors = ini_get('log_errors');
179 :
180 : if ($display_errors) {
181 : echo $this->_display($userinfo);
182 : }
183 :
184 : if ($log_errors) {
185 : $this->_log($userinfo);
186 : }
187 : }
188 :
189 : /**
190 : * Returns the context of execution formatted.
191 : *
192 : * @param string $format the context of execution format
193 : *
194 : * @return string
195 : * @since version 1.0.0 (2006-06-24)
196 : * @access public
197 : */
198 : function sprintContextExec($format)
199 : {
200 : $userinfo = $this->getUserInfo();
201 :
202 : if (isset($userinfo['context'])) {
203 : $context = $userinfo['context'];
204 : } else {
205 : $context = $this->getBacktrace();
206 : $context = @array_pop($context);
207 : }
208 :
209 : if ($context) {
210 : $file = $context['file'];
211 : $line = $context['line'];
212 :
213 : if (isset($context['class'])) {
214 : $func = $context['class'];
215 : $func .= $context['type'];
216 : $func .= $context['function'];
217 : } elseif (isset($context['function'])) {
218 : $func = $context['function'];
219 : } else {
220 : $func = '';
221 : }
222 : return sprintf($format, $file, $line, $func);
223 : }
224 : return '';
225 : }
226 :
227 : /**
228 : * Print an error message
229 : *
230 : * @param array $userinfo hash of parameters
231 : *
232 : * @return void
233 : * @since version 1.0.0 (2006-06-24)
234 : * @access private
235 : */
236 : function _display($userinfo)
237 : {
238 : $displayDefault = array(
239 : 'eol' => "<br/>\n",
240 : 'lineFormat' => '<b>%1$s</b>: %2$s %3$s',
241 : 'contextFormat' => 'in <b>%3$s</b> ' .
242 : '(file <b>%1$s</b> on line <b>%2$s</b>)'
243 : );
244 :
245 : $displayConf = $userinfo['display'];
246 : $display = array_merge($displayDefault, $displayConf);
247 : $contextExec = $this->sprintContextExec($display['contextFormat']);
248 :
249 : return sprintf($display['lineFormat'] . $display['eol'],
250 : ucfirst($userinfo['level']), $this->getMessage(), $contextExec);
251 : }
252 :
253 : /**
254 : * Send an error message somewhere
255 : *
256 : * @param array $userinfo hash of parameters
257 : *
258 : * @return void
259 : * @since version 1.0.0 (2006-06-24)
260 : * @access private
261 : */
262 : function _log($userinfo)
263 : {
264 : $logDefault = array(
265 : 'eol' => "\n",
266 : 'lineFormat' => '%1$s %2$s [%3$s] %4$s %5$s',
267 : 'contextFormat' => 'in %3$s (file %1$s on line %2$s)',
268 : 'timeFormat' => '%b %d %H:%M:%S',
269 : 'ident' => $_SERVER['REMOTE_ADDR'],
270 : 'message_type' => 3,
271 : 'destination' => get_class($this) . '.log',
272 : 'extra_headers' => ''
273 : );
274 :
275 : $logConf = $userinfo['log'];
276 : $log = array_merge($logDefault, $logConf);
277 :
278 : $message_type = $log['message_type'];
279 : $destination = '';
280 : $extra_headers = '';
281 : $send = true;
282 :
283 : switch ($message_type) {
284 : case 0: // LOG_TYPE_SYSTEM:
285 : break;
286 : case 1: // LOG_TYPE_MAIL:
287 : $destination = $log['destination'];
288 : $extra_headers = $log['extra_headers'];
289 : break;
290 : case 3: // LOG_TYPE_FILE:
291 : $destination = $log['destination'];
292 : break;
293 : default:
294 : $send = false;
295 : }
296 :
297 : if ($send) {
298 : $time = explode(' ', microtime());
299 : $time = $time[1] + $time[0];
300 : $timestamp = isset($userinfo['time']) ? $userinfo['time'] : $time;
301 : $contextExec = $this->sprintContextExec($log['contextFormat']);
302 :
303 : $message = sprintf($log['lineFormat'] . $log['eol'],
304 : strftime($log['timeFormat'], $timestamp),
305 : $log['ident'],
306 : $userinfo['level'],
307 : $this->getMessage(),
308 : $contextExec);
309 :
310 : error_log(strip_tags($message), $message_type, $destination,
311 : $extra_headers);
312 : }
313 : }
314 :
315 : /**
316 : * Default internal error handler
317 : *
318 : * Dies if the error is an exception (and would have died anyway)
319 : *
320 : * @param int $code a numeric error code.
321 : * Valid are HTML_CSS_ERROR_* constants
322 : * @param string $level error level ('exception', 'error', 'warning', ...)
323 : *
324 : * @return mixed
325 : * @since version 0.3.3 (2004-05-20)
326 : * @access private
327 : */
328 : function _handleError($code, $level)
329 : {
330 : if ($level == 'exception') {
331 : return PEAR_ERROR_DIE;
332 : } else {
333 : return null;
334 : }
335 : }
336 :
337 : /**
338 : * User callback to generate error messages for any instance
339 : *
340 : * @param int $code a numeric error code.
341 : * Valid are HTML_CSS_ERROR_* constants
342 : * @param mixed $userinfo if you need to pass along parameters
343 : * for dynamic messages
344 : *
345 : * @return string
346 : * @since version 1.0.0 (2006-06-24)
347 : * @access private
348 : */
349 : function _msgCallback($code, $userinfo)
350 : {
351 4 : $errorMessages = HTML_CSS_Error::_getErrorMessage();
352 :
353 4 : if (isset($errorMessages[$code])) {
354 4 : $mainmsg = $errorMessages[$code];
355 4 : } else {
356 0 : $mainmsg = $errorMessages[HTML_CSS_ERROR_UNKNOWN];
357 : }
358 :
359 4 : if (is_array($userinfo)) {
360 4 : foreach ($userinfo as $name => $val) {
361 4 : if (is_array($val)) {
362 : // @ is needed in case $val is a multi-dimensional array
363 0 : $val = @implode(', ', $val);
364 0 : }
365 4 : if (is_object($val)) {
366 0 : if (method_exists($val, '__toString')) {
367 0 : $val = $val->__toString();
368 0 : } else {
369 0 : continue;
370 : }
371 0 : }
372 4 : $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
373 4 : }
374 4 : }
375 :
376 4 : return $mainmsg;
377 : }
378 :
379 : /**
380 : * Error Message Template array
381 : *
382 : * @return string
383 : * @since version 1.0.0 (2006-06-24)
384 : * @access private
385 : */
386 : function _getErrorMessage()
387 : {
388 : $messages = array(
389 4 : HTML_CSS_ERROR_UNKNOWN =>
390 4 : 'unknown error',
391 4 : HTML_CSS_ERROR_INVALID_INPUT =>
392 : 'invalid input, parameter #%paramnum% '
393 : . '"%var%" was expecting '
394 4 : . '"%expected%", instead got "%was%"',
395 4 : HTML_CSS_ERROR_INVALID_GROUP =>
396 4 : 'group "%identifier%" already exist ',
397 4 : HTML_CSS_ERROR_NO_GROUP =>
398 4 : 'group "%identifier%" does not exist ',
399 4 : HTML_CSS_ERROR_NO_ELEMENT =>
400 4 : 'element "%identifier%" does not exist ',
401 4 : HTML_CSS_ERROR_NO_ELEMENT_PROPERTY =>
402 4 : 'element "%identifier%" does not have property "%property%" ',
403 4 : HTML_CSS_ERROR_NO_FILE =>
404 4 : 'filename "%identifier%" does not exist ',
405 4 : HTML_CSS_ERROR_WRITE_FILE =>
406 4 : 'failed to write to "%filename%"',
407 4 : HTML_CSS_ERROR_INVALID_DEPS =>
408 : 'invalid dependencies, %funcname% function '
409 : . 'require %dependency% '
410 4 : . 'but found %currentdep%',
411 4 : HTML_CSS_ERROR_INVALID_SOURCE =>
412 : 'invalid input, source #%sourcenum% : '
413 : . '%errcount% error(s), '
414 4 : . '%warncount% warning(s)',
415 4 : HTML_CSS_ERROR_NO_ATRULE =>
416 : 'At-Rule "%identifier%" does not exist '
417 4 : );
418 4 : return $messages;
419 : }
420 : }
|