1: <?php
2: /**
3: * Document for class GeoDebug
4: *
5: * PHP Version 5.6
6: *
7: * @category Class
8: * @package Geolib
9: * @author Peter Pitchford <peter@geotonics.com>
10: * @license GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
11: * @link http://geotonics.com/#geolib
12: */
13:
14: /**
15: * Class for static debugging functions
16: *
17: * @category Debugging
18: * @package Geolib
19: * @author Original Author <peter@geotonics.com>
20: * @license GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
21: * @version Release: .1
22: * @link http://geotonics.com/#geolib
23: * @since Class available since Release .1
24: */
25: class GeoDebug
26: {
27: /**
28: * Initialize Debug session
29: * @return void
30: */
31: public static function init()
32: {
33:
34: if (!Geo::session("saveDebugVars")) {
35: Geo::setSession('debugVars');
36: }
37:
38: // Add previously generated error messages to geolib debugging messages.
39: // This is useful if you want to display errors from before ge0lib is included.
40: // Add previous errors like this: $_SESSION["geolib"]["geoDebugErrors"]["debug name"]="Debug content";
41: $geoDebugErrors=Geo::session("geoDebugErrors");
42:
43: if ($geoDebugErrors) {
44: foreach ($geoDebugErrors as $key => $value) {
45: self::db($value, $key);
46: }
47: }
48:
49: if (self::isOn()) {
50: ini_set('display_errors', 1);
51:
52: // report all errors
53: error_reporting(E_ALL);
54:
55: //set error handler
56: set_error_handler(array("GeoDebug", "customError"), E_NOTICE | E_WARNING | E_STRICT);
57:
58: // collect REQUEST variables for debugging
59: $requestVariables=self::req();
60:
61: if ($requestVariables) {
62: self::db(self::req(), "REQUEST VARIABLES for " . $_SERVER["PHP_SELF"], null, null, true);
63: }
64: }
65:
66: }
67:
68:
69: /**
70: * Error handler function
71: *
72: * @param int $errno Error number
73: * @param string $errstr Error string
74: * @param string $file File where error takes place
75: * @param string $line Line where error takes place
76: *
77: * @return void.
78: */
79: public static function customError($errno, $errstr, $file, $line)
80: {
81:
82:
83: if (error_reporting() === 0) {
84: // continue script execution, skipping standard PHP error handler
85: return null;
86: }
87:
88: switch($errno){
89: case E_WARNING:
90: $level="Warning";
91: break;
92: case E_NOTICE:
93: $level="Notice";
94: break;
95: case E_STRICT:
96: $level="Strict Standards";
97: break;
98: }
99:
100: self::db(
101: div(
102: array($level.": ".$errstr, $file, b("line ".$line)),
103: null,
104: null,
105: "background:#F8C498"
106: ),
107: true,
108: null,
109: null,
110: true
111: );
112:
113: }
114:
115:
116: /**
117: * This function is depreciated. Use Geodebug::debug() instead.
118: * Start or end debugging session by setting debugging flag
119: *
120: * @param bool $end End debugging session. Default is start debugging.
121: * @param bool $temp Start temporary debugging and reset debugging flag to original value upon output
122: *
123: * @return void.
124: */
125: public static function debugging($end = null, $temp = null)
126: {
127: $isDebugSession=Geo::session("isDebugSession");
128:
129: if ($temp) {
130: Geo::setSession('origIsDebugSession', $isDebugSession);
131: }
132:
133: Geo::setSession('isDebugSession', !$end);
134: }
135:
136: /**
137: * Start or end debugging session by setting debugging flag
138: *
139: * @param bool $start Start debugging session. Default is end debugging
140: * @param bool $temp Start temporary debugging and reset debugging flag to original value upon output
141: *
142: * @return void.
143: */
144: public static function debug($start = null, $temp = null)
145: {
146: $isDebugSession=Geo::session("isDebugSession");
147:
148: if ($temp) {
149: Geo::setSession('origIsDebugSession', $isDebugSession);
150: }
151:
152: Geo::setSession('isDebugSession', $start);
153: }
154:
155: /**
156: * Formats debugging variables for display
157: *
158: * @param mixed $variable Any type of variable being debugged
159: * @param string $name Name used for displaying debug variable
160: * @param bool $isHtml Display strings as html. Default displays html highlited tags.
161: *
162: * @return html debug content - is formatted with html
163: */
164: public static function vr(
165: $variable = "<span style='color:red'>DEBUG</span>",
166: $name = "Variable",
167: $isHtml = null
168: ) {
169:
170: $result='';
171:
172: if (is_array($variable) || is_object($variable)) {
173: $size = sizeof($variable);
174: $variable = "<pre>" . print_r($variable, true) . "</pre>";
175: if (isset($name)) {
176: $result.="<h4>" . $name . ":" . $size . "</h4>" . $variable;
177: }
178: } else {
179: if (!$isHtml) {
180: $variable= highlight_string($variable." ", true);
181: }
182:
183: $result.= "<div>".geoif($name, "<b>" . $name . ":</b>"). $variable . "</div>";
184: }
185: return $result;
186: }
187:
188: /**
189: * Adds content to debugging array
190: *
191: * @param mixed $variable Variable being debugged
192: * @param string $name Name used for displaying debug variable
193: * @param bool $addBacktrace Determines whether to add backtrace to debug display
194: * @param bool $return Determines whether debugging content is displayed
195: * or saved. Default is saved.
196: * @param bool $noHighlight Display strings as html. Default displays html tags.
197: * @param bool $always Always debug, even when not in debugging mode
198: * @param int $traceLevel Indicates which part of the backtrace array to display
199: * @param text $userSessionName User session name
200: *
201: * @return html debug content is formatted with html
202: */
203: public static function db(
204: $variable = null,
205: $name = "debug",
206: $addBacktrace = null,
207: $return = null,
208: $noHighlight = null,
209: $always = true,
210: $traceLevel = 0,
211: $userSessionName = "default"
212: ) {
213:
214: if (self::isOn() || $always) {
215: $dbOut=Geo::session('dbOut');
216: if (!$return && $dbOut) {
217: $return=$dbOut;
218: }
219:
220: $backtrace = debug_backtrace();
221:
222: if ($name===true) {
223: $isTrace=true;
224:
225: if (isset($backtrace[$traceLevel+2])) {
226: $name=$backtrace[$traceLevel+2]["function"]."()";
227: } else {
228: $name='no function';
229: }
230:
231: } else {
232: $isTrace=null;
233: }
234:
235: $debug='';
236:
237: // One line for primary backtrace
238:
239: if (!$isTrace) {
240: $debug.="<div>".
241: $backtrace[$traceLevel]['file'].
242: ' line '.
243: $backtrace[$traceLevel]['line'] .
244: "</div>";
245: }
246:
247: $debug.= self::vr($variable, $name, $noHighlight);
248:
249: if ($addBacktrace) {
250: // Clean up extended backtrace
251: if (sizeof($backtrace)>1) {
252: unset($backtrace[$traceLevel]);
253:
254: foreach ($backtrace as $key => $trace) {
255: unset($backtrace[$key]["object"]);
256: }
257:
258: $debug.= self::vr($backtrace, $name . ' Backtrace');
259: }
260:
261: }
262:
263: switch ($return) {
264: case 1:
265: echo $debug;
266: break;
267: case 2:
268: return $debug;
269: break;
270: default:
271: $debug = "<div style='background:#E8E8E8;color:#000000; padding:6px 12px'>".
272: $debug.
273: "</div>";
274: Geo::setSession(null, $debug, 'debugVars', $userSessionName);
275: break;
276: }
277: }
278: }
279:
280: /**
281: * Return boolean or other content based on debug mode
282: *
283: * @param mixed $true Value to be returned in debug mode. Default is true
284: * @param mixed $false Value to be returned in non debug mode Default is null
285: *
286: * @return mixed result value
287: */
288: public static function isOn($true = true, $false = null)
289: {
290: if (Geo::session('isDebugSession')) {
291: return $true;
292: }
293: return $false;
294: }
295:
296: /**
297: * Reset Debug session: If temporary session is in progress, return to original debug setting, clean debug flags
298: *
299: * @return mixed result value
300: */
301: public static function reset()
302: {
303: $origIsDebugSession=Geo::session("origIsDebugSession");
304: if ($origIsDebugSession) {
305: Geo::setSession('isDebugSession', $origIsDebugSession);
306: }
307: Geo::setSession("origIsDebugSession");
308: Geo::setSession("saveDebugVars");
309: Geo::setSession("debugVars");
310:
311: }
312:
313: /**
314: * Debug variables are deleted by default when an html page is printed.
315: * If this is added to a page, debug variables are saved and added to the next page. (useful for ajax pages)
316: *
317: * @param bool $startFromHere Determines whether to delete exising debugging at this point
318: *
319: * @return void.
320: */
321: public static function saveDebugVars($startFromHere = null)
322: {
323: if ($startFromHere) {
324: Geo::setSession('debugVars');
325: }
326: if (self::isOn()) {
327: Geo::setSession('saveDebugVars', true);
328: }
329: }
330:
331: /**
332: * Collect $_POST, $_GET and $_FILES variables for display in debugging
333: *
334: * @param bool $print Determines whether to print or return result. Default is to return Result
335: * @param bool $always Determines whether to return results even when there are no values.
336: *
337: * @return html Display of results.
338: */
339: public static function req($print = null, $always = null)
340: {
341: $result = '';
342: if ($_POST) {
343: $result .= self::vr($_POST, '$_POST');
344: }
345:
346: if ($_GET) {
347: $result .= self::vr($_GET, '$_GET');
348: }
349:
350: if ($_FILES) {
351: $result .= self::vr($_FILES, '$_FILES');
352: }
353:
354: if ($result || $always) {
355: if (!$result) {
356: $result = div("NO REQUEST VARIABLES");
357: }
358:
359: $result .= div(time());
360:
361: if ($print) {
362: echo $result;
363: } else {
364: return $result;
365: }
366: }
367: }
368:
369: /**
370: * Creates full trace or selected trace level
371: *
372: * @param string $name Identifies trace in debugging output
373: * @param int $level Limits trace to a single level of backtrace
374: * Default is level 1
375: * If true, return entire backtrace
376: * @param bool $return Determines whether to print out or add to debugging
377: * @param bool $dontTraceFrom Don't add a one line trace to the location of the calling function.
378: *
379: * @return text|array One line, or array if returning entire backtrace
380: */
381: public static function trace($name = null, $level = 1, $return = null, $dontTraceFrom = null)
382: {
383: $backtrace = debug_backtrace();
384:
385: if (!isset($level)) {
386: $level = 1;
387: }
388:
389: $upLevel=$level-1;
390:
391: if(isset($backtrace[$level]['class'])){
392: $fromClass=$backtrace[$level]['class']." ".$backtrace[$level]['function'].": ";
393: } else {
394: $fromClass="";
395: }
396:
397: $tracedFrom="Traced from ".$fromClass.$backtrace[$upLevel]['file'] .
398: " line " .
399: $backtrace[$upLevel]['line'];
400:
401: if ($level === true) {
402: $traceLine = $backtrace;
403: $traceLine[$upLevel]=$tracedFrom;
404: } else {
405: $trace="";
406:
407: if (isset($backtrace[$level + 1])) {
408: $trace.= $backtrace[$level + 1]['function']."()::";
409: }
410:
411: $trace.=$backtrace[$level]['file'].' line ' . $backtrace[$level]['line'];
412: $traceArr=array($trace);
413:
414: if (!$dontTraceFrom) {
415: $traceArr[]=$tracedFrom;
416: }
417:
418: $traceLine = div($traceArr);
419: }
420:
421: if ($return) {
422: return $traceLine;
423: }
424:
425: if ($name!==true) {
426: $name.=" trace";
427: }
428:
429: self::db($traceLine, $name, null, null, true);
430: }
431:
432: /**
433: * Returns a simple one line trace to the next trace level
434: *
435: * @param string $name Optional name to mark the trace with
436: *
437: * @return string one line trace
438: */
439: public static function miniTrace($name = "miniTrace")
440: {
441: $backtrace = debug_backtrace();
442: return $name.":".$backtrace[1]['file'] .
443: " line " .
444: $backtrace[1]['line']."<br>";
445: }
446:
447: /**
448: * Writes or appends string to a file. Usefull for logging debugging variables.
449: *
450: * @param string $content Content to write
451: * @param string $title Name used to identify content in log file.
452: * @param bool $alwaysLog Always log to file. Default is to only log when in debug mode.
453: * @param string $mode Mode indicator for PHP fwrite. Usually either "a" for append or "w" for write.
454: * Appends by default
455: * @param string $fileName Name of file to write to.
456: * @param string $theFile Name of file generating the log.
457: *
458: * @return bool Indicates write success or failure
459: */
460: public static function logToFile(
461: $content,
462: $title = "log",
463: $alwaysLog = null,
464: $mode = "a",
465: $fileName = "geoLog.htm",
466: $theFile = null
467: ) {
468:
469: if (self::isOn() || $alwaysLog) {
470: if (defined("GEOBASE")) {
471: $fileName = GEOBASE . $fileName;
472: }
473:
474: if ($mode === true) {
475: $mode = 'w';
476: }
477:
478: if ($theFile) {
479: if ($theFile === true) {
480: $content .= self::vr(debug_backtrace(), 'backtrace');
481: } else {
482: $title = $theFile . "<br/>" . $title;
483: }
484: }
485:
486: $content = self::vr($content, $title, true);
487: $debug = Geo::writeToFile($fileName, $content, $mode, true);
488: return $debug;
489: }
490: }
491:
492: /**
493: * Dump debug variables in $_SESSION['geolib']['isDebugSession']
494: *
495: * @param int $height Layout height
496: * @param int $width Layout width
497: * @param bool $dontDelete Don't delete debug variables
498: * @param text $style Added styles
499: * @param test $userSessionName Name of user session
500: *
501: * @return html
502: *
503: * Debug variables are deleted by default after they are dumped
504: */
505: public static function vars(
506: $height = null,
507: $width = null,
508: $dontDelete = null,
509: $style = '',
510: $userSessionName = null
511: ) {
512:
513: //geo::trace(true);
514: if (Geo::session('isDebugSession')) {
515: $result='';
516: if (!$userSessionName) {
517: $userSessionName="default";
518: }
519:
520: //geoVar($_SESSION,'thesession');
521: $debugVars=Geo::session($userSessionName, 'debugVars');
522:
523: //geoVar($debugVars,'debugVars');
524: if ($debugVars) {
525: if (!$style) {
526: $style = "margin:1em 0; overflow:auto;clear:both;";
527: if ($height) {
528: $style .= ' max-height:' . $height . "px;";
529: }
530: if ($width) {
531: if ($width === true) {
532: $style .= " width:100%";
533: } else {
534: $style .= ' width:' . $width . "px;";
535: }
536: }
537: }
538:
539: $result = div(
540: "\n ".
541: // Javascript link to close debug area
542: geoJsLink(
543: geoImg(GEO_URI."images/redx.png"),
544: null,
545: 'Close Debug Area',
546: "closeDebugArea",
547: array(
548: "style"=>"float:right;cursor:pointer;",
549: "onclick" => "this.parentNode.style.display = 'none';"
550: )
551: )."\n ".div($debugVars, null, null, null, array("style"=>'margin:.5em;',"class"=>"geodb")),
552: null,
553: null,
554: null,
555: array(
556: "style"=>"text-align:left; background:#fff; border:solid 1px #C8C8C8; z-index:99;". $style,
557: "class"=>"debugVars"
558: )
559: );
560: }
561:
562: if (!$dontDelete && !Geo::session("saveDebugVars")) {
563: Geo::setSession('debugVars');
564: Geo::setSession('geoDebugErrors');
565: }
566:
567: return $result;
568: }
569: }
570: }
571: