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.15 2009/07/03 16:34:02 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.4
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, $mode = null, $options = null, $userinfo = null
79 : ) {
80 0 : $this->__construct($message, $code, $mode, $options, $userinfo);
81 0 : }
82 :
83 : /**
84 : * Constructor (ZE2)
85 : *
86 : * @param string $message (optional) message
87 : * @param int $code (optional) error code
88 : * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
89 : * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
90 : * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
91 : * @param mixed $options (optional) error level, _OR_ in the case of
92 : * PEAR_ERROR_CALLBACK, the callback function
93 : * or object/method tuple.
94 : * @param string $userinfo (optional) additional user/debug info
95 : *
96 : * @since version 1.0.0 (2006-06-24)
97 : * @access public
98 : */
99 : function __construct($message = null,
100 : $code = null, $mode = null, $options = null, $userinfo = null
101 : ) {
102 5 : if ($mode === null) {
103 : $mode = PEAR_ERROR_RETURN;
104 : }
105 5 : $this->message = $message;
106 5 : $this->code = $code;
107 5 : $this->mode = $mode;
108 5 : $this->userinfo = $userinfo;
109 5 : $this->backtrace = debug_backtrace();
110 :
111 5 : if ($mode & PEAR_ERROR_CALLBACK) {
112 5 : $this->level = E_USER_NOTICE;
113 5 : $this->callback = $options;
114 5 : } else {
115 : if ($options === null) {
116 : switch ($userinfo['level']) {
117 : case 'exception':
118 : case 'error':
119 : $options = E_USER_ERROR;
120 : break;
121 : case 'warning':
122 : $options = E_USER_WARNING;
123 : break;
124 : default:
125 : $options = E_USER_NOTICE;
126 : }
127 : }
128 : $this->level = $options;
129 : $this->callback = null;
130 : }
131 5 : if ($this->mode & PEAR_ERROR_PRINT) {
132 : echo $this->_display($userinfo);
133 : }
134 5 : if ($this->mode & PEAR_ERROR_TRIGGER) {
135 : trigger_error($this->getMessage(), $this->level);
136 : }
137 5 : if ($this->mode & PEAR_ERROR_DIE) {
138 : $this->log();
139 : die();
140 : }
141 5 : if ($this->mode & PEAR_ERROR_CALLBACK) {
142 5 : if (is_callable($this->callback)) {
143 5 : call_user_func($this->callback, $this);
144 5 : } else {
145 : $this->log();
146 : }
147 5 : }
148 5 : }
149 :
150 : /**
151 : * Get error level from an error object
152 : *
153 : * @return int error level
154 : * @since version 1.0.0 (2006-06-24)
155 : * @access public
156 : */
157 : function getLevel()
158 : {
159 : return $this->level;
160 : }
161 :
162 : /**
163 : * Default callback function/method from an error object
164 : *
165 : * @return void
166 : * @since version 1.0.0 (2006-06-24)
167 : * @access public
168 : */
169 : function log()
170 : {
171 : $userinfo = $this->getUserInfo();
172 :
173 : $display_errors = ini_get('display_errors');
174 : $log_errors = ini_get('log_errors');
175 :
176 : if ($display_errors) {
177 : echo $this->_display($userinfo);
178 : }
179 :
180 : if ($log_errors) {
181 : $this->_log($userinfo);
182 : }
183 : }
184 :
185 : /**
186 : * Returns the context of execution formatted.
187 : *
188 : * @param string $format the context of execution format
189 : *
190 : * @return string
191 : * @since version 1.0.0 (2006-06-24)
192 : * @access public
193 : */
194 : function sprintContextExec($format)
195 : {
196 : $userinfo = $this->getUserInfo();
197 :
198 : if (isset($userinfo['context'])) {
199 : $context = $userinfo['context'];
200 : } else {
201 : $context = $this->getBacktrace();
202 : $context = @array_pop($context);
203 : }
204 :
205 : if ($context) {
206 : $file = $context['file'];
207 : $line = $context['line'];
208 :
209 : if (isset($context['class'])) {
210 : $func = $context['class'];
211 : $func .= $context['type'];
212 : $func .= $context['function'];
213 : } elseif (isset($context['function'])) {
214 : $func = $context['function'];
215 : } else {
216 : $func = '';
217 : }
218 : return sprintf($format, $file, $line, $func);
219 : }
220 : return '';
221 : }
222 :
223 : /**
224 : * Print an error message
225 : *
226 : * @param array $userinfo hash of parameters
227 : *
228 : * @return void
229 : * @since version 1.0.0 (2006-06-24)
230 : * @access private
231 : */
232 : function _display($userinfo)
233 : {
234 : $displayDefault = array(
235 : 'eol' => "<br/>\n",
236 : 'lineFormat' => '<b>%1$s</b>: %2$s %3$s',
237 : 'contextFormat' => 'in <b>%3$s</b> ' .
238 : '(file <b>%1$s</b> on line <b>%2$s</b>)'
239 : );
240 :
241 : $displayConf = $userinfo['display'];
242 : $display = array_merge($displayDefault, $displayConf);
243 : $contextExec = $this->sprintContextExec($display['contextFormat']);
244 :
245 : return sprintf(
246 : $display['lineFormat'] . $display['eol'],
247 : ucfirst($userinfo['level']), $this->getMessage(), $contextExec
248 : );
249 : }
250 :
251 : /**
252 : * Send an error message somewhere
253 : *
254 : * @param array $userinfo hash of parameters
255 : *
256 : * @return void
257 : * @since version 1.0.0 (2006-06-24)
258 : * @access private
259 : */
260 : function _log($userinfo)
261 : {
262 : $logDefault = array(
263 : 'eol' => "\n",
264 : 'lineFormat' => '%1$s %2$s [%3$s] %4$s %5$s',
265 : 'contextFormat' => 'in %3$s (file %1$s on line %2$s)',
266 : 'timeFormat' => '%b %d %H:%M:%S',
267 : 'ident' => $_SERVER['REMOTE_ADDR'],
268 : 'message_type' => 3,
269 : 'destination' => get_class($this) . '.log',
270 : 'extra_headers' => ''
271 : );
272 :
273 : $logConf = $userinfo['log'];
274 : $log = array_merge($logDefault, $logConf);
275 :
276 : $message_type = $log['message_type'];
277 : $destination = '';
278 : $extra_headers = '';
279 : $send = true;
280 :
281 : switch ($message_type) {
282 : case 0: // LOG_TYPE_SYSTEM:
283 : break;
284 : case 1: // LOG_TYPE_MAIL:
285 : $destination = $log['destination'];
286 : $extra_headers = $log['extra_headers'];
287 : break;
288 : case 3: // LOG_TYPE_FILE:
289 : $destination = $log['destination'];
290 : break;
291 : default:
292 : $send = false;
293 : }
294 :
295 : if ($send) {
296 : $time = explode(' ', microtime());
297 : $time = $time[1] + $time[0];
298 : $timestamp = isset($userinfo['time']) ? $userinfo['time'] : $time;
299 : $contextExec = $this->sprintContextExec($log['contextFormat']);
300 :
301 : $message = sprintf(
302 : $log['lineFormat'] . $log['eol'],
303 : strftime($log['timeFormat'], $timestamp),
304 : $log['ident'],
305 : $userinfo['level'],
306 : $this->getMessage(),
307 : $contextExec
308 : );
309 :
310 : error_log(
311 : strip_tags($message), $message_type, $destination, $extra_headers
312 : );
313 : }
314 : }
315 :
316 : /**
317 : * Default internal error handler
318 : *
319 : * Dies if the error is an exception (and would have died anyway)
320 : *
321 : * @param int $code a numeric error code.
322 : * Valid are HTML_CSS_ERROR_* constants
323 : * @param string $level error level ('exception', 'error', 'warning', ...)
324 : *
325 : * @return mixed
326 : * @since version 0.3.3 (2004-05-20)
327 : * @access private
328 : */
329 : function _handleError($code, $level)
330 : {
331 : if ($level == 'exception') {
332 : return PEAR_ERROR_DIE;
333 : } else {
334 : return null;
335 : }
336 : }
337 :
338 : /**
339 : * User callback to generate error messages for any instance
340 : *
341 : * @param int $code a numeric error code.
342 : * Valid are HTML_CSS_ERROR_* constants
343 : * @param mixed $userinfo if you need to pass along parameters
344 : * for dynamic messages
345 : *
346 : * @return string
347 : * @since version 1.0.0 (2006-06-24)
348 : * @access private
349 : */
350 : function _msgCallback($code, $userinfo)
351 : {
352 5 : $errorMessages = HTML_CSS_Error::_getErrorMessage();
353 :
354 5 : if (isset($errorMessages[$code])) {
355 5 : $mainmsg = $errorMessages[$code];
356 5 : } else {
357 0 : $mainmsg = $errorMessages[HTML_CSS_ERROR_UNKNOWN];
358 : }
359 :
360 5 : if (is_array($userinfo)) {
361 5 : foreach ($userinfo as $name => $val) {
362 5 : if (is_array($val)) {
363 : // @ is needed in case $val is a multi-dimensional array
364 0 : $val = @implode(', ', $val);
365 0 : }
366 5 : if (is_object($val)) {
367 0 : if (method_exists($val, '__toString')) {
368 0 : $val = $val->__toString();
369 0 : } else {
370 0 : continue;
371 : }
372 0 : }
373 5 : $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
374 5 : }
375 5 : }
376 :
377 5 : return $mainmsg;
378 : }
379 :
380 : /**
381 : * Error Message Template array
382 : *
383 : * @return string
384 : * @since version 1.0.0 (2006-06-24)
385 : * @access private
386 : */
387 : function _getErrorMessage()
388 : {
389 : $messages = array(
390 5 : HTML_CSS_ERROR_UNKNOWN =>
391 5 : 'unknown error',
392 5 : HTML_CSS_ERROR_INVALID_INPUT =>
393 : 'invalid input, parameter #%paramnum% '
394 : . '"%var%" was expecting '
395 5 : . '"%expected%", instead got "%was%"',
396 5 : HTML_CSS_ERROR_INVALID_GROUP =>
397 5 : 'group "%identifier%" already exist ',
398 5 : HTML_CSS_ERROR_NO_GROUP =>
399 5 : 'group "%identifier%" does not exist ',
400 5 : HTML_CSS_ERROR_NO_ELEMENT =>
401 5 : 'element "%identifier%" does not exist ',
402 5 : HTML_CSS_ERROR_NO_ELEMENT_PROPERTY =>
403 5 : 'element "%identifier%" does not have property "%property%" ',
404 5 : HTML_CSS_ERROR_NO_FILE =>
405 5 : 'filename "%identifier%" does not exist ',
406 5 : HTML_CSS_ERROR_WRITE_FILE =>
407 5 : 'failed to write to "%filename%"',
408 5 : HTML_CSS_ERROR_INVALID_DEPS =>
409 : 'invalid dependencies, %funcname% function '
410 : . 'require %dependency% '
411 5 : . 'but found %currentdep%',
412 5 : HTML_CSS_ERROR_INVALID_SOURCE =>
413 : 'invalid input, source #%sourcenum% : '
414 : . '%errcount% error(s), '
415 5 : . '%warncount% warning(s)',
416 5 : HTML_CSS_ERROR_NO_ATRULE =>
417 : 'At-Rule "%identifier%" does not exist '
418 5 : );
419 5 : return $messages;
420 : }
421 : }
|