1: <?php defined('_JOOS_CORE') or exit();
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
16: class joosDebug
17: {
18: private static $instance;
19:
20: private static $_log = array();
21:
22: private static $_inc = array();
23:
24: public static function instance()
25: {
26: if (self::$instance === null) {
27: self::$instance = new self;
28: }
29:
30: return self::$instance;
31: }
32:
33: private function __clone()
34: {
35: }
36:
37: public static function log($str, array $params = array())
38: {
39: $value = strtr($str, $params);
40: self::$_log[] = joosFilter::htmlspecialchars($value);
41: }
42:
43: public static function add($text, $top = 0)
44: {
45: $top ? array_unshift(self::$_log, $text) : self::$_log[] = $text;
46: }
47:
48: public static function add_top($text)
49: {
50: self::add($text, true);
51: }
52:
53: public static function inc($key)
54: {
55: if (!isset(self::$_inc[$key])) {
56: self::$_inc[$key] = 0;
57: }
58: self::$_inc[$key]++;
59: }
60:
61: public static function get()
62: {
63: $f = '';
64:
65: $f .= '<div id="ptb_data_cont_custom" class="ptb_data_cont" style="display: none;">
66: <ul class="ptb_tabs">
67: <li id="ptb_tab_custom_default">messages <span>(' . count(self::$_log) . ')</span></li>
68: </ul>
69: <div id="ptb_tab_cont_custom_default" class="ptb_tab_cont">
70: <table class="ptb_tab_cont_table">
71: <tbody>
72: <tr>
73: <th style="width:20px;">№</th>
74: <th>message</th>
75: </tr>';
76: $c = 1;
77: foreach (self::$_log as $value) {
78: $f .= '<tr><td>' . $c . '</td><td> ' . $value . '</td></tr>';
79: $c++;
80: }
81: unset($c);
82: $f .= '<tr class="total">
83: <th></th>
84: <th>total ' . count(self::$_log) . ' messages</th>
85: </tr>
86: </tbody>
87: </table>
88: </div>
89: </div>';
90:
91:
92: $files = get_included_files();
93: $f .= '<div id="ptb_data_cont_files" class="ptb_data_cont" style="display: none;">
94: <ul class="ptb_tabs">
95: <li id="ptb_tab_files">files <span>(' . count($files) . ')</span></li>
96: </ul>
97: <div id="ptb_tab_cont_files" class="ptb_tab_cont">
98: <table class="ptb_tab_cont_table">
99: <tbody>
100: <tr>
101: <th style="width:20px;">№</th>
102: <th>file</th>
103: </tr>';
104: $c = 1;
105: foreach ($files as $value) {
106: $f .= '<tr><td>' . $c . '</td><td> ' . $value . '</td></tr>';
107: $c++;
108: }
109: unset($c);
110: $f .= '<tr class="total">
111: <th></th>
112: <th>total ' . count($files) . ' files</th>
113: </tr>
114: </tbody>
115: </table>
116: </div>
117: </div>';
118:
119: $profs = joosDatabase::instance()->set_query('show profiles;')->load_assoc_list();
120:
121:
122: echo '<span style="display:none"><![CDATA[<noindex>]]></span>
123: <!-- ============================= PROFILER TOOLBAR ============================= -->
124: <script type="text/javascript" src="' . JPATH_SITE . '/media/js/profilertoolbar.js"></script>
125: <link rel="stylesheet" href="' . JPATH_SITE . '/media/css/profilertoolbar.css">
126: <div id="ptb">
127: <ul id="ptb_toolbar" class="ptb_bg">
128: <li class="time" title="application execution time"><span class="icon"></span> ' . self::$_log[1] . '</li>
129: <li class="ram" title="memory peak usage"><span class="icon"></span> ' . self::$_log[0] . ' </li>
130: <li class="custom"><span class="icon"></span> logs <span class="total">(' . count($files) . ')</span></li>
131: <li class="sql"><span class="icon"></span> sql <span class="total">(' . count($profs) . ')</span></li>
132: <li class="files"><span class="icon"></span> files <span class="total">(' . count($files) . ')</span></li>
133: <li class="hide" title="Hide Profiler Toolbar"><span class="icon"></span></li>
134: <li class="show" title="Show Profiler Toolbar"><span class="icon"></span></li>
135: </ul>
136: <div id="ptb_data" class="ptb_bg" style="display: none;">
137: ' . self::db_debug() . '
138: ' . $f . '
139: </div>
140: </div>
141: <!-- ============================= /PROFILER TOOLBAR ============================= -->
142: <span style="display:none"><![CDATA[</noindex>]]></span>';
143: }
144:
145: private static function db_debug()
146: {
147: $profs = joosDatabase::instance()->set_query('show profiles;')->load_assoc_list();
148:
149: $total_time = 0;
150: $r = '
151: <div id="ptb_data_cont_sql" class="ptb_data_cont">
152: <ul class="ptb_tabs">
153: <li id="ptb_tab_sqldefault">default <span>(' . count($profs) . ')</span></li>
154: </ul>
155: <div id="ptb_tab_cont_sqldefault" class="ptb_tab_cont">
156: <table class="ptb_tab_cont_table">
157: <tbody>
158: <tr>
159: <th style="width:20px;">№</th>
160: <th>query</th>
161: <th style="width:100px;">time</th>
162: </tr>';
163: if (isset($profs[0])) {
164: foreach ($profs as $prof) {
165: $r .= '<tr valign="top"><td>' . $prof['Query_ID'] . ' </td><td> ' . $prof['Query'] . ' </td><td class="tRight"> ' . $prof['Duration'] . ' s</td></tr>';
166: $total_time += $prof['Duration'];
167: }
168: }
169: $r .= '<tr class="total">
170: <td></td>
171: <td>total ' . count($profs) . ' queries</td>
172: <td class="tRight">' . $total_time . ' s</td>
173: </tr>
174: </tbody>
175: </table>
176: </div>
177: </div>';
178:
179: return $r;
180: }
181:
182: 183: 184: 185: 186: 187: 188: 189: 190: 191:
192: public static function dump()
193: {
194: joosRequest::send_headers_by_code(503);
195:
196:
197: $trace = debug_backtrace();
198: if (isset($trace[1]['file'])) {
199: $file_content = self::get_file_context($trace[1]['file'], $trace[1]['line']);
200: } else {
201: $file_content = self::get_file_context($trace[0]['file'], $trace[0]['line']);
202: }
203:
204: if (ob_get_level()) {
205: ob_end_clean();
206: }
207: ob_start();
208:
209: $func_args = func_get_args();
210:
211: $args_count = count($func_args);
212: var_dump($args_count == 1 ? $func_args[0] : $func_args);
213: $output = ob_get_clean();
214: $output = preg_replace('/]\=>\n(\s+)/m', '] => ', $output);
215:
216: 217: 218:
219: $result = joosFilter::htmlspecialchars($output);
220: $file_content = joosFilter::htmlspecialchars($file_content);
221:
222: $result = <<<HTML
223: <style>
224: body { background-color: #fff; color: #333; }
225: body, p, ol, ul, td { font-family: verdana, arial, helvetica, sans-serif; font-size: 13px; line-height: 25px; }
226: pre { background-color: #eee; padding: 10px; font-size: 11px; line-height: 18px; }
227: a { color: #000; }
228: a:visited { color: #666; }
229: a:hover { color: #fff; background-color:#000; }
230: </style>
231: <div style="width:99%; position:relative">
232: <h2 id='Title'>Результат отладки</h2>
233: <div id="Context" style="display: block;">Место вызова:<pre>{$file_content}</pre></div>
234: <div id="Context" style="display: block;">Полученные параметры:<pre>{$result}</pre></div>
235: HTML;
236: $result .= "</div>";
237:
238: echo $result;
239: die();
240: }
241:
242: 243: 244: 245:
246: private static function get_file_context($file, $line_number)
247: {
248: $context = array();
249: $i = 0;
250: foreach (file($file) as $line) {
251: $i++;
252: if ($i >= $line_number - 3 && $i <= $line_number + 3) {
253: if ($i == $line_number) {
254: $context[] = ' >> ' . $i . "\t" . $line;
255: } else {
256: $context[] = "\t" . $i . "\t" . $line;
257: }
258: }
259: if ($i > $line_number + 3) {
260: break;
261: }
262: }
263:
264: return "\n" . implode("", $context);
265: }
266:
267: }
268: