Mercurial > hg > vamp-website
comparison forum/Sources/ManageErrors.php @ 76:e3e11437ecea website
Add forum code
author | Chris Cannam |
---|---|
date | Sun, 07 Jul 2013 11:25:48 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
75:72f59aa7e503 | 76:e3e11437ecea |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * Simple Machines Forum (SMF) | |
5 * | |
6 * @package SMF | |
7 * @author Simple Machines http://www.simplemachines.org | |
8 * @copyright 2011 Simple Machines | |
9 * @license http://www.simplemachines.org/about/smf/license.php BSD | |
10 * | |
11 * @version 2.0.4 | |
12 */ | |
13 | |
14 if (!defined('SMF')) | |
15 die('Hacking attempt...'); | |
16 | |
17 /* Show a list of all errors that were logged on the forum. | |
18 | |
19 void ViewErrorLog() | |
20 - sets all the context up to show the error log for maintenance. | |
21 - uses the Errors template and error_log sub template. | |
22 - requires the maintain_forum permission. | |
23 - uses the 'view_errors' administration area. | |
24 - accessed from ?action=admin;area=logs;sa=errorlog. | |
25 | |
26 void deleteErrors() | |
27 - deletes all or some of the errors in the error log. | |
28 - applies any necessary filters to deletion. | |
29 - should only be called by ViewErrorLog(). | |
30 - attempts to TRUNCATE the table to reset the auto_increment. | |
31 - redirects back to the error log when done. | |
32 | |
33 void ViewFile() | |
34 - will do php highlighting on the file specified in $_REQUEST['file'] | |
35 - file must be readable | |
36 - full file path must be base64 encoded | |
37 - user must have admin_forum permission | |
38 - the line number number is specified by $_REQUEST['line'] | |
39 - Will try to get the 20 lines before and after the specified line | |
40 */ | |
41 | |
42 // View the forum's error log. | |
43 function ViewErrorLog() | |
44 { | |
45 global $scripturl, $txt, $context, $modSettings, $user_profile, $filter, $boarddir, $sourcedir, $themedir, $smcFunc; | |
46 | |
47 // Viewing contents of a file? | |
48 if (isset($_GET['file'])) | |
49 return ViewFile(); | |
50 | |
51 // Check for the administrative permission to do this. | |
52 isAllowedTo('admin_forum'); | |
53 | |
54 // Templates, etc... | |
55 loadLanguage('ManageMaintenance'); | |
56 loadTemplate('Errors'); | |
57 | |
58 // You can filter by any of the following columns: | |
59 $filters = array( | |
60 'id_member' => $txt['username'], | |
61 'ip' => $txt['ip_address'], | |
62 'session' => $txt['session'], | |
63 'url' => $txt['error_url'], | |
64 'message' => $txt['error_message'], | |
65 'error_type' => $txt['error_type'], | |
66 'file' => $txt['file'], | |
67 'line' => $txt['line'], | |
68 ); | |
69 | |
70 // Set up the filtering... | |
71 if (isset($_GET['value'], $_GET['filter']) && isset($filters[$_GET['filter']])) | |
72 $filter = array( | |
73 'variable' => $_GET['filter'], | |
74 'value' => array( | |
75 'sql' => in_array($_GET['filter'], array('message', 'url', 'file')) ? base64_decode(strtr($_GET['value'], array(' ' => '+'))) : $smcFunc['db_escape_wildcard_string']($_GET['value']), | |
76 ), | |
77 'href' => ';filter=' . $_GET['filter'] . ';value=' . $_GET['value'], | |
78 'entity' => $filters[$_GET['filter']] | |
79 ); | |
80 | |
81 // Deleting, are we? | |
82 if (isset($_POST['delall']) || isset($_POST['delete'])) | |
83 deleteErrors(); | |
84 | |
85 // Just how many errors are there? | |
86 $result = $smcFunc['db_query']('', ' | |
87 SELECT COUNT(*) | |
88 FROM {db_prefix}log_errors' . (isset($filter) ? ' | |
89 WHERE ' . $filter['variable'] . ' LIKE {string:filter}' : ''), | |
90 array( | |
91 'filter' => isset($filter) ? $filter['value']['sql'] : '', | |
92 ) | |
93 ); | |
94 list ($num_errors) = $smcFunc['db_fetch_row']($result); | |
95 $smcFunc['db_free_result']($result); | |
96 | |
97 // If this filter is empty... | |
98 if ($num_errors == 0 && isset($filter)) | |
99 redirectexit('action=admin;area=logs;sa=errorlog' . (isset($_REQUEST['desc']) ? ';desc' : '')); | |
100 | |
101 // Clean up start. | |
102 if (!isset($_GET['start']) || $_GET['start'] < 0) | |
103 $_GET['start'] = 0; | |
104 | |
105 // Do we want to reverse error listing? | |
106 $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up'; | |
107 | |
108 // Set the page listing up. | |
109 $context['page_index'] = constructPageIndex($scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : '') . (isset($filter) ? $filter['href'] : ''), $_GET['start'], $num_errors, $modSettings['defaultMaxMessages']); | |
110 $context['start'] = $_GET['start']; | |
111 | |
112 // Find and sort out the errors. | |
113 $request = $smcFunc['db_query']('', ' | |
114 SELECT id_error, id_member, ip, url, log_time, message, session, error_type, file, line | |
115 FROM {db_prefix}log_errors' . (isset($filter) ? ' | |
116 WHERE ' . $filter['variable'] . ' LIKE {string:filter}' : '') . ' | |
117 ORDER BY id_error ' . ($context['sort_direction'] == 'down' ? 'DESC' : '') . ' | |
118 LIMIT ' . $_GET['start'] . ', ' . $modSettings['defaultMaxMessages'], | |
119 array( | |
120 'filter' => isset($filter) ? $filter['value']['sql'] : '', | |
121 ) | |
122 ); | |
123 $context['errors'] = array(); | |
124 $members = array(); | |
125 | |
126 for ($i = 0; $row = $smcFunc['db_fetch_assoc']($request); $i ++) | |
127 { | |
128 $search_message = preg_replace('~<span class="remove">(.+?)</span>~', '%', $smcFunc['db_escape_wildcard_string']($row['message'])); | |
129 if ($search_message == $filter['value']['sql']) | |
130 $search_message = $smcFunc['db_escape_wildcard_string']($row['message']); | |
131 $show_message = strtr(strtr(preg_replace('~<span class="remove">(.+?)</span>~', '$1', $row['message']), array("\r" => '', '<br />' => "\n", '<' => '<', '>' => '>', '"' => '"')), array("\n" => '<br />')); | |
132 | |
133 $context['errors'][$row['id_error']] = array( | |
134 'alternate' => $i %2 == 0, | |
135 'member' => array( | |
136 'id' => $row['id_member'], | |
137 'ip' => $row['ip'], | |
138 'session' => $row['session'] | |
139 ), | |
140 'time' => timeformat($row['log_time']), | |
141 'timestamp' => $row['log_time'], | |
142 'url' => array( | |
143 'html' => htmlspecialchars((substr($row['url'], 0, 1) == '?' ? $scripturl : '') . $row['url']), | |
144 'href' => base64_encode($smcFunc['db_escape_wildcard_string']($row['url'])) | |
145 ), | |
146 'message' => array( | |
147 'html' => $show_message, | |
148 'href' => base64_encode($search_message) | |
149 ), | |
150 'id' => $row['id_error'], | |
151 'error_type' => array( | |
152 'type' => $row['error_type'], | |
153 'name' => isset($txt['errortype_'.$row['error_type']]) ? $txt['errortype_'.$row['error_type']] : $row['error_type'], | |
154 ), | |
155 'file' => array(), | |
156 ); | |
157 if (!empty($row['file']) && !empty($row['line'])) | |
158 { | |
159 // Eval'd files rarely point to the right location and cause havoc for linking, so don't link them. | |
160 $linkfile = strpos($row['file'], 'eval') === false || strpos($row['file'], '?') === false; // De Morgan's Law. Want this true unless both are present. | |
161 | |
162 $context['errors'][$row['id_error']]['file'] = array( | |
163 'file' => $row['file'], | |
164 'line' => $row['line'], | |
165 'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;file=' . base64_encode($row['file']) . ';line=' . $row['line'], | |
166 'link' => $linkfile ? '<a href="' . $scripturl . '?action=admin;area=logs;sa=errorlog;file=' . base64_encode($row['file']) . ';line=' . $row['line'] . '" onclick="return reqWin(this.href, 600, 400, false);">' . $row['file'] . '</a>' : $row['file'], | |
167 'search' => base64_encode($row['file']), | |
168 ); | |
169 } | |
170 | |
171 // Make a list of members to load later. | |
172 $members[$row['id_member']] = $row['id_member']; | |
173 } | |
174 $smcFunc['db_free_result']($request); | |
175 | |
176 // Load the member data. | |
177 if (!empty($members)) | |
178 { | |
179 // Get some additional member info... | |
180 $request = $smcFunc['db_query']('', ' | |
181 SELECT id_member, member_name, real_name | |
182 FROM {db_prefix}members | |
183 WHERE id_member IN ({array_int:member_list}) | |
184 LIMIT ' . count($members), | |
185 array( | |
186 'member_list' => $members, | |
187 ) | |
188 ); | |
189 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
190 $members[$row['id_member']] = $row; | |
191 $smcFunc['db_free_result']($request); | |
192 | |
193 // This is a guest... | |
194 $members[0] = array( | |
195 'id_member' => 0, | |
196 'member_name' => '', | |
197 'real_name' => $txt['guest_title'] | |
198 ); | |
199 | |
200 // Go through each error and tack the data on. | |
201 foreach ($context['errors'] as $id => $dummy) | |
202 { | |
203 $memID = $context['errors'][$id]['member']['id']; | |
204 $context['errors'][$id]['member']['username'] = $members[$memID]['member_name']; | |
205 $context['errors'][$id]['member']['name'] = $members[$memID]['real_name']; | |
206 $context['errors'][$id]['member']['href'] = empty($memID) ? '' : $scripturl . '?action=profile;u=' . $memID; | |
207 $context['errors'][$id]['member']['link'] = empty($memID) ? $txt['guest_title'] : '<a href="' . $scripturl . '?action=profile;u=' . $memID . '">' . $context['errors'][$id]['member']['name'] . '</a>'; | |
208 } | |
209 } | |
210 | |
211 // Filtering anything? | |
212 if (isset($filter)) | |
213 { | |
214 $context['filter'] = &$filter; | |
215 | |
216 // Set the filtering context. | |
217 if ($filter['variable'] == 'id_member') | |
218 { | |
219 $id = $filter['value']['sql']; | |
220 loadMemberData($id, false, 'minimal'); | |
221 $context['filter']['value']['html'] = '<a href="' . $scripturl . '?action=profile;u=' . $id . '">' . $user_profile[$id]['real_name'] . '</a>'; | |
222 } | |
223 elseif ($filter['variable'] == 'url') | |
224 $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars((substr($filter['value']['sql'], 0, 1) == '?' ? $scripturl : '') . $filter['value']['sql']), array('\_' => '_')) . '\''; | |
225 elseif ($filter['variable'] == 'message') | |
226 { | |
227 $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars($filter['value']['sql']), array("\n" => '<br />', '<br />' => '<br />', "\t" => ' ', '\_' => '_', '\\%' => '%', '\\\\' => '\\')) . '\''; | |
228 $context['filter']['value']['html'] = preg_replace('~&lt;span class=&quot;remove&quot;&gt;(.+?)&lt;/span&gt;~', '$1', $context['filter']['value']['html']); | |
229 } | |
230 elseif ($filter['variable'] == 'error_type') | |
231 { | |
232 $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars($filter['value']['sql']), array("\n" => '<br />', '<br />' => '<br />', "\t" => ' ', '\_' => '_', '\\%' => '%', '\\\\' => '\\')) . '\''; | |
233 } | |
234 else | |
235 $context['filter']['value']['html'] = &$filter['value']['sql']; | |
236 } | |
237 | |
238 $context['error_types'] = array(); | |
239 | |
240 $context['error_types']['all'] = array( | |
241 'label' => $txt['errortype_all'], | |
242 'description' => isset($txt['errortype_all_desc']) ? $txt['errortype_all_desc'] : '', | |
243 'url' => $scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : ''), | |
244 'is_selected' => empty($filter), | |
245 ); | |
246 | |
247 $sum = 0; | |
248 // What type of errors do we have and how many do we have? | |
249 $request = $smcFunc['db_query']('', ' | |
250 SELECT error_type, COUNT(*) AS num_errors | |
251 FROM {db_prefix}log_errors | |
252 GROUP BY error_type | |
253 ORDER BY error_type = {string:critical_type} DESC, error_type ASC', | |
254 array( | |
255 'critical_type' => 'critical', | |
256 ) | |
257 ); | |
258 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
259 { | |
260 // Total errors so far? | |
261 $sum += $row['num_errors']; | |
262 | |
263 $context['error_types'][$sum] = array( | |
264 'label' => (isset($txt['errortype_' . $row['error_type']]) ? $txt['errortype_' . $row['error_type']] : $row['error_type']) . ' (' . $row['num_errors'] . ')', | |
265 'description' => isset($txt['errortype_' . $row['error_type'] . '_desc']) ? $txt['errortype_' . $row['error_type'] . '_desc'] : '', | |
266 'url' => $scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : '') . ';filter=error_type;value=' . $row['error_type'], | |
267 'is_selected' => isset($filter) && $filter['value']['sql'] == $smcFunc['db_escape_wildcard_string']($row['error_type']), | |
268 ); | |
269 } | |
270 $smcFunc['db_free_result']($request); | |
271 | |
272 // Update the all errors tab with the total number of errors | |
273 $context['error_types']['all']['label'] .= ' (' . $sum . ')'; | |
274 | |
275 // Finally, work out what is the last tab! | |
276 if (isset($context['error_types'][$sum])) | |
277 $context['error_types'][$sum]['is_last'] = true; | |
278 else | |
279 $context['error_types']['all']['is_last'] = true; | |
280 | |
281 // And this is pretty basic ;). | |
282 $context['page_title'] = $txt['errlog']; | |
283 $context['has_filter'] = isset($filter); | |
284 $context['sub_template'] = 'error_log'; | |
285 } | |
286 | |
287 // Delete errors from the database. | |
288 function deleteErrors() | |
289 { | |
290 global $filter, $smcFunc; | |
291 | |
292 // Make sure the session exists and is correct; otherwise, might be a hacker. | |
293 checkSession(); | |
294 | |
295 // Delete all or just some? | |
296 if (isset($_POST['delall']) && !isset($filter)) | |
297 $smcFunc['db_query']('truncate_table', ' | |
298 TRUNCATE {db_prefix}log_errors', | |
299 array( | |
300 ) | |
301 ); | |
302 // Deleting all with a filter? | |
303 elseif (isset($_POST['delall']) && isset($filter)) | |
304 $smcFunc['db_query']('', ' | |
305 DELETE FROM {db_prefix}log_errors | |
306 WHERE ' . $filter['variable'] . ' LIKE {string:filter}', | |
307 array( | |
308 'filter' => $filter['value']['sql'], | |
309 ) | |
310 ); | |
311 // Just specific errors? | |
312 elseif (!empty($_POST['delete'])) | |
313 { | |
314 $smcFunc['db_query']('', ' | |
315 DELETE FROM {db_prefix}log_errors | |
316 WHERE id_error IN ({array_int:error_list})', | |
317 array( | |
318 'error_list' => array_unique($_POST['delete']), | |
319 ) | |
320 ); | |
321 | |
322 // Go back to where we were. | |
323 redirectexit('action=admin;area=logs;sa=errorlog' . (isset($_REQUEST['desc']) ? ';desc' : '') . ';start=' . $_GET['start'] . (isset($filter) ? ';filter=' . $_GET['filter'] . ';value=' . $_GET['value'] : '')); | |
324 } | |
325 | |
326 // Back to the error log! | |
327 redirectexit('action=admin;area=logs;sa=errorlog' . (isset($_REQUEST['desc']) ? ';desc' : '')); | |
328 } | |
329 | |
330 function ViewFile() | |
331 { | |
332 global $context, $txt, $boarddir, $sourcedir, $cachedir; | |
333 // Check for the administrative permission to do this. | |
334 isAllowedTo('admin_forum'); | |
335 | |
336 // Decode the file and get the line | |
337 $file = realpath(base64_decode($_REQUEST['file'])); | |
338 $real_board = realpath($boarddir); | |
339 $real_source = realpath($sourcedir); | |
340 $real_cache = realpath($cachedir); | |
341 $basename = strtolower(basename($file)); | |
342 $ext = strrchr($basename, '.'); | |
343 $line = isset($_REQUEST['line']) ? (int) $_REQUEST['line'] : 0; | |
344 | |
345 // Make sure the file we are looking for is one they are allowed to look at | |
346 if ($ext != '.php' || (strpos($file, $real_board) === false && strpos($file, $real_source) === false) || ($basename == 'settings.php' || $basename == 'settings_bak.php') || strpos($file, $real_cache) !== false || !is_readable($file)) | |
347 fatal_lang_error('error_bad_file', true, array(htmlspecialchars($file))); | |
348 | |
349 // get the min and max lines | |
350 $min = $line - 20 <= 0 ? 1 : $line - 20; | |
351 $max = $line + 21; // One additional line to make everything work out correctly | |
352 | |
353 if ($max <= 0 || $min >= $max) | |
354 fatal_lang_error('error_bad_line'); | |
355 | |
356 $file_data = explode('<br />', highlight_php_code(htmlspecialchars(implode('', file($file))))); | |
357 | |
358 // We don't want to slice off too many so lets make sure we stop at the last one | |
359 $max = min($max, max(array_keys($file_data))); | |
360 | |
361 $file_data = array_slice($file_data, $min-1, $max - $min); | |
362 | |
363 $context['file_data'] = array( | |
364 'contents' => $file_data, | |
365 'min' => $min, | |
366 'target' => $line, | |
367 'file' => strtr($file, array('"' => '\\"')), | |
368 ); | |
369 | |
370 loadTemplate('Errors'); | |
371 $context['template_layers'] = array(); | |
372 $context['sub_template'] = 'show_file'; | |
373 | |
374 } | |
375 | |
376 ?> |