3 $sysdebug_dberrors = forge_get_config('sysdebug_dberrors');
4 $sysdebug_dbquery = forge_get_config('sysdebug_dbquery');
5 $sysdebug_ignored = forge_get_config('sysdebug_ignored');
9 // error handler function
10 function ffErrorHandler($errno, $errstr, $errfile, $errline)
12 global $ffErrors, $sysdebug_ignored, $sysdebug__aborted;
14 if ($sysdebug__aborted) {
15 /* inside the exception handler, ignore everything */
19 if (!$sysdebug_ignored && error_reporting() == 0)
20 /* prepended @ to statement => ignore */
23 $msg = "[$errno] $errstr ($errfile at $errline)";
25 // Display messages only once.
26 foreach ($ffErrors as $m) {
27 if ($m['message'] == $msg)
48 case E_USER_DEPRECATED:
58 if (forge_get_config('sysdebug_backtraces'))
60 '<pre style="font-weight:normal; font-size:90%; color:#000066; line-height:100%;">' .
61 htmlentities(debug_string_backtrace()) . "</pre>";
63 $ffErrors[] = array('type' => $type, 'message' => $msg);
64 /* Don't execute PHP internal error handler */
69 function ffOutputHandler($buffer) {
70 global $ffErrors, $sysdebug_enable, $sysdebug__aborted,
71 $sysdebug_lazymode_on, $sysdebug_doframe, $gfcommon,
72 $sysDTDs, $sysXMLNSs, $HTML;
74 if ($sysdebug__aborted) {
75 /* called from exception handler, discard */
76 $p = strrpos($buffer, "\r\n");
77 return (($p === false) ? "" : substr($buffer, $p + 2));
80 if (!getenv('SERVER_SOFTWARE')) {
84 /* in case we’re aborted */
85 if (!$sysdebug_enable)
88 /* if content-type != text/html* assume abortion */
89 if ($sysdebug_lazymode_on) {
90 $thdr = 'content-type:';
91 $tstr = 'content-type: text/html';
92 foreach (headers_list() as $h) {
93 if (strncasecmp($h, $thdr, strlen($thdr)))
95 if (strncasecmp($h, $tstr, strlen($tstr)))
96 /* application/something, maybe */
101 /* stop calling ffErrorHandler */
102 restore_error_handler();
104 $dtdpath = $gfcommon . 'include/';
105 // this is, sadly, necessary (especially in ff-plugin-mediawiki)
106 $pre_tag = "<pre style=\"margin:0; padding:0; border:0; line-height:125%;\">";
108 $divstring = "\n\n" . '<script language="JavaScript" type="text/javascript">//<![CDATA[
109 function toggle_ffErrors() {
110 var errorsblock = document.getElementById("ffErrorsBlock");
111 var errorsgroup = document.getElementById("ffErrors");
112 if (errorsblock.style.display == "none") {
113 errorsblock.style.display = "block";
114 errorsgroup.style.right = "10px";
116 errorsblock.style.display = "none";
117 errorsgroup.style.right = "300px";
119 }' . "\n//]]></script>\n<div id=\"ffErrors\">\n" .
120 '<a href="javascript:toggle_ffErrors();">Click to toggle</a>' .
121 "\n<div id=\"ffErrorsBlock\">";
123 $doctype = util_ifsetor($HTML->doctype);
125 $doctype = 'transitional';
128 if ($sysdebug_doframe) {
129 $initial = '<?xml version="1.0" encoding="utf-8"?>' .
130 $sysDTDs[$doctype]['doctype'] .
131 '<html xml:lang="en" ' . $sysXMLNSs .
132 "><head><title>AJAX frame</title></head><body>\n";
133 $bufferstrip = strlen($initial);
134 $buffer = $initial . $buffer . '</body></html>';
137 /* cut off </body></html> (hopefully only) at the end */
138 $buffer = rtrim($buffer); /* spaces, newlines, etc. */
139 $bufend = array(false, substr($buffer, -100));
140 if (substr($buffer, -strlen("</html>")) != "</html>") {
142 $ffErrors[] = array('type' => "error",
143 'message' => htmlentities("does not end with </html> tag"));
144 $buffer = str_ireplace("</html>", "", $buffer);
146 $buffer = substr($buffer, 0, -strlen("</html>"));
147 $buffer = rtrim($buffer); /* spaces, newlines, etc. */
148 if (substr($buffer, -strlen("</body>")) != "</body>") {
150 $ffErrors[] = array('type' => "error",
151 'message' => htmlentities("does not end with </body> tag"));
152 $buffer = str_ireplace("</body>", "", $buffer);
154 $buffer = substr($buffer, 0, -strlen("</body>"));
155 $buffer = rtrim($buffer); /* spaces, newlines, etc. */
158 $ffErrors[] = array('type' => "info",
159 'message' => "The output has ended thus: " .
160 htmlentities($bufend[1]));
163 /* append errors, if any */
165 foreach ($ffErrors as $msg) {
167 $buffer .= $divstring;
170 $buffer .= "\n <div class=\"" . $msg['type'] . '">' .
171 $msg['message'] . "</div>";
174 /* generate buffer for checking */
175 $cbuf = str_ireplace('http://www.w3.org/TR/xhtml1/DTD/',
176 'file://' . $dtdpath, $buffer);
178 $cbuf .= "\n</div></div>";
179 $cbuf .= "\n</body></html>\n";
181 /* now check XHTML validity… two means */
185 if (forge_get_config('sysdebug_xmlstarlet')) {
186 /* xmlstarlet (well-formed, DTD and DOCTYPE, encoding */
188 0 => array("pipe", "r"),
189 1 => array("pipe", "w"),
190 2 => array("pipe", "w"),
192 $xmlstarlet = proc_open("xmlstarlet val -d " .
193 escapeshellarg($dtdpath . $sysDTDs[$doctype]['dtdfile']) .
194 " -e -", $dspec, $pipes);
196 if (is_resource($xmlstarlet)) {
197 fwrite($pipes[0], $cbuf);
199 $sout = stream_get_contents($pipes[1]);
200 $serr = stream_get_contents($pipes[2]);
203 $rv = proc_close($xmlstarlet);
204 /* work around Debian #627158 */
205 $serr = join("\n", preg_grep(
206 '/^-:[0-9]*: Entity'." 'nbsp' ".'not defined$/',
207 explode("\n", $serr), PREG_GREP_INVERT));
210 'msg' => "could not run xmlstarlet"
214 'msg' => "xmlstarlet found that this document is not valid (errorlevel $rv)!",
215 'extra' => $pre_tag . htmlspecialchars(trim($serr .
216 "\n\n" . $sout)) . "</pre>",
223 $sysdebug_akelos = forge_get_config('sysdebug_akelos');
224 if ($sysdebug_akelos) {
225 /* Akelos XHTML Validator (most other stuff) */
226 require_once($gfcommon . "include/XhtmlValidator.php");
227 $XhtmlValidator = new XhtmlValidator();
228 $sbuf = explode("<html", $cbuf, 2);
229 $sbuf[1] = "<html" . $sbuf[1];
231 if ($XhtmlValidator->validate($vbuf) === false) {
232 //$vbuf = $XhtmlValidator->highlightErrors($sbuf[1]);
233 $errs = '<ul><li>' . join("</li>\n<li>",
234 $XhtmlValidator->getErrors()) . '</li></ul>';
236 'msg' => "Akelos XHTML Validator found some errors on this document!",
244 /* append XHTML source code, if validation failed */
246 if (!$sysdebug_akelos || $vbuf == $sbuf[1])
247 $vbuf = "<ol><li>" . $pre_tag . join(" </pre></li>\n<li>" . $pre_tag, explode("\n", htmlentities(rtrim($cbuf)))) . " </pre></li></ol>";
249 $vbuf = $pre_tag . htmlentities(rtrim($sbuf[0])) . "</pre>" . $vbuf;
251 'msg' => "Since XHTML validation failed, here’s the checked document for you to look at:",
257 /* append error messages from the validators */
258 foreach ($valck as $msg) {
260 $buffer .= $divstring;
263 if (!isset($msg['type']) || !$msg['type']) {
264 $msg['type'] = 'unknown';
266 $buffer .= "\n <div class=\"" . $msg['type'] . '">' . $msg['msg'];
267 if (isset($msg['extra']))
268 $buffer .= "\n <div style=\"font-weight:normal; font-size:90%; color:#333333;\">" .
269 $msg['extra'] . "</div>\n ";
273 /* return final buffer */
275 $buffer .= "\n</div></div>";
276 if ($sysdebug_doframe) {
277 return substr($buffer, $bufferstrip);
279 return $buffer . "\n</body></html>\n";
283 function ffExceptionHandler($e) {
284 global $sysdebug__aborted;
286 /* drop output buffers and error handler */
287 $sysdebug__aborted = true;
288 while (ob_get_length() > 0 && ob_end_clean()) {
291 restore_error_handler();
293 /* issue exception information */
294 header('HTTP/1.0 500 Exception not handled');
295 header('Content-type: text/plain');
296 echo "\r\nUncaught exception:\n" . str_replace("\r", "",
297 $e->getMessage() . "\n\nBacktrace:\n" . $e->getTraceAsString()) .
303 if (forge_get_config('sysdebug_phphandler')) {
304 // set to the user defined error handler
305 set_error_handler("ffErrorHandler");
308 set_exception_handler("ffExceptionHandler");
310 $sysdebug_lazymode_on = false;
311 $sysdebug_doframe = false;
312 $sysdebug__aborted = false;
313 ob_start("ffOutputHandler", 0, false);
315 function sysdebug_ajaxbody($enable=true) {
316 global $sysdebug_doframe;
318 $sysdebug_doframe = $enable;
321 function sysdebug_off($hdr=false, $replace=true, $resp=false) {
322 global $sysdebug_enable;
324 if ($sysdebug_enable) {
325 $sysdebug_enable = false;
326 $buf = ob_get_flush();
328 if ($buf === false) {
335 if ($hdr !== false) {
336 if ($resp === false) {
337 header($hdr, $replace);
339 header($hdr, $replace, $resp);
346 function sysdebug_lazymode($enable) {
347 global $sysdebug_lazymode_on;
349 $sysdebug_lazymode_on = $enable ? true : false;
352 function ffDebug($type,$intro,$pretext) {
360 $text .= htmlentities($intro);
363 $text .= '<pre style="font-weight:normal; font-size:90%; color:#000066;">' .
364 htmlentities($pretext) . "</pre>";