jdarwood007 commited on 2020-01-04 09:06:43
Showing 5 changed files, with 1201 additions and 1114 deletions.
... | ... |
@@ -23,1007 +23,43 @@ class SFS |
23 | 23 |
private $softwareVersion = '2.1'; |
24 | 24 |
|
25 | 25 |
/** |
26 |
- * @var string The URL for the admin page. |
|
27 |
- */ |
|
28 |
- private $adminPageURL = null; |
|
29 |
- private $adminLogURL = null; |
|
30 |
- |
|
31 |
- /** |
|
32 |
- * @var array Our settings information used on saving/changing settings. |
|
33 |
- */ |
|
34 |
- private $changedSettings = array(); |
|
35 |
- private $extraVerificationOptions = array(); |
|
36 |
- |
|
37 |
- /** |
|
38 |
- * @var mixed Search area handling. |
|
39 |
- */ |
|
40 |
- private $search_types = array(); |
|
41 |
- private $search_params = array(); |
|
42 |
- private $search_params_column = ''; |
|
43 |
- private $search_params_string = null; |
|
44 |
- private $search_params_type = null; |
|
45 |
- private $canDeleteLogs = false; |
|
46 |
- private $logSearch = array(); |
|
47 |
- |
|
48 |
- /** |
|
49 |
- * @var int How long we disable removing logs. |
|
50 |
- */ |
|
51 |
- private $hoursDisabled = 24; |
|
52 |
- |
|
53 |
- /** |
|
54 |
- * Simple setup for the class to be used later correctly. |
|
55 |
- * This simply loads the class into $smcFunc and we can grab this anywhere else later. |
|
56 |
- * |
|
57 |
- * @api |
|
58 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
59 |
- * @version 1.0 |
|
60 |
- * @since 1.0 |
|
61 |
- * @uses integrate_pre_load - Hook SMF2.0 |
|
62 |
- * @uses integrate_pre_load - Hook SMF2.1 |
|
63 |
- * @return void No return is generated |
|
64 |
- */ |
|
65 |
- public static function hook_pre_load(): void |
|
66 |
- { |
|
67 |
- global $smcFunc; |
|
68 |
- |
|
69 |
- $smcFunc['classSFS'] = new SFS(); |
|
70 |
- } |
|
71 |
- |
|
72 |
- /** |
|
73 |
- * Build the class, figure out what software/version we have. |
|
74 |
- * Loads up the defaults. |
|
75 |
- * |
|
76 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
77 |
- * @version 1.0 |
|
78 |
- * @since 1.0 |
|
79 |
- * @return void No return is generated |
|
80 |
- */ |
|
81 |
- public function __construct() |
|
82 |
- { |
|
83 |
- global $smcFunc; |
|
84 |
- |
|
85 |
- // Is this SMF 2.0? |
|
86 |
- if (!function_exists('loadCacheAccelerator')) |
|
87 |
- $this->softwareVersion = '2.0'; |
|
88 |
- |
|
89 |
- // Setup the defaults. |
|
90 |
- $this->loadDefaults(); |
|
91 |
- } |
|
92 |
- |
|
93 |
- /** |
|
94 |
- * Creates the hook to the class for the admin areas. |
|
95 |
- * |
|
96 |
- * @param array $admin_areas A associate array from the software with all valid admin areas. |
|
97 |
- * |
|
98 |
- * @api |
|
99 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
100 |
- * @see SFS::setupAdminAreas() |
|
101 |
- * @version 1.0 |
|
102 |
- * @since 1.0 |
|
103 |
- * @uses integrate__admin_areas - Hook SMF2.0 |
|
104 |
- * @uses integrate__admin_areas - Hook SMF2.1 |
|
105 |
- * @return void No return is generated |
|
106 |
- */ |
|
107 |
- public static function hook_admin_areas(array &$admin_areas) |
|
108 |
- { |
|
109 |
- global $smcFunc; |
|
110 |
- return $smcFunc['classSFS']->setupAdminAreas($admin_areas); |
|
111 |
- } |
|
112 |
- |
|
113 |
- /** |
|
114 |
- * Startup the Admin Panels Additions. |
|
115 |
- * Where things appear are based on what software/version you have. |
|
116 |
- * |
|
117 |
- * @param array $admin_areas A associate array from the software with all valid admin areas. |
|
118 |
- * |
|
119 |
- * @internal |
|
120 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
121 |
- * @version 1.0 |
|
122 |
- * @since 1.0 |
|
123 |
- * @uses integrate__admin_areas - Hook SMF2.0 |
|
124 |
- * @uses integrate__admin_areas - Hook SMF2.1 |
|
125 |
- * @return void No return is generated |
|
126 |
- */ |
|
127 |
- private function setupAdminAreas(array &$admin_areas): void |
|
128 |
- { |
|
129 |
- global $scripturl; |
|
130 |
- |
|
131 |
- // Add the menu item. |
|
132 |
- if ($this->versionCheck('2.0', 'smf')) |
|
133 |
- { |
|
134 |
- $this->adminPageURL = $scripturl . '?action=admin;area=modsettings;sa=sfs'; |
|
135 |
- $this->adminLogURL = $scripturl . '?action=admin;area=modsettings;sa=sfslog'; |
|
136 |
- |
|
137 |
- $admin_areas['config']['areas']['modsettings']['subsections']['sfs'] = array( |
|
138 |
- $this->txt('sfs_admin_area') |
|
139 |
- ); |
|
140 |
- $admin_areas['config']['areas']['modsettings']['subsections']['sfslog'] = array( |
|
141 |
- $this->txt('sfs_admin_logs') |
|
142 |
- ); |
|
143 |
- } |
|
144 |
- else |
|
145 |
- { |
|
146 |
- $this->adminPageURL = $scripturl . '?action=admin;area=securitysettings;sa=sfs'; |
|
147 |
- $this->adminLogURL = $scripturl . '?action=admin;area=logs;sa=sfslog'; |
|
148 |
- |
|
149 |
- $admin_areas['config']['areas']['securitysettings']['subsections']['sfs'] = array( |
|
150 |
- $this->txt('sfs_admin_area') |
|
151 |
- ); |
|
152 |
- $admin_areas['config']['areas']['securitysettings']['subsections']['sfslog'] = array( |
|
153 |
- $this->txt('sfs_admin_logs') |
|
154 |
- ); |
|
155 |
- } |
|
156 |
- } |
|
157 |
- |
|
158 |
- /** |
|
159 |
- * Setup the Modification's setup page. |
|
160 |
- * For some versions, we put the logs into the modifications sections, its easier. |
|
161 |
- * |
|
162 |
- * @param array $subActions A associate array from the software with all valid modification sections. |
|
163 |
- * |
|
164 |
- * @api |
|
165 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
166 |
- * @see SFS::setupModifyModifications() |
|
167 |
- * @version 1.0 |
|
168 |
- * @since 1.0 |
|
169 |
- * @uses integrate_modify_modifications - Hook SMF2.0 |
|
170 |
- * @uses integrate_modify_modifications - Hook SMF2.1 |
|
171 |
- * @return void No return is generated |
|
172 |
- */ |
|
173 |
- public static function hook_modify_modifications(array &$subActions) |
|
174 |
- { |
|
175 |
- global $smcFunc; |
|
176 |
- return $smcFunc['classSFS']->setupModifyModifications($subActions); |
|
177 |
- } |
|
178 |
- |
|
179 |
- /** |
|
180 |
- * Setup the Modifications section links. |
|
181 |
- * For some versions we add the logs here as well. |
|
182 |
- * |
|
183 |
- * @param array $subActions A associate array from the software with all valid modification sections. |
|
184 |
- * |
|
185 |
- * @internal |
|
186 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
187 |
- * @version 1.0 |
|
188 |
- * @since 1.0 |
|
189 |
- * @uses integrate_modify_modifications - Hook SMF2.0 |
|
190 |
- * @uses integrate_modify_modifications - Hook SMF2.1 |
|
191 |
- * @return void No return is generated |
|
192 |
- */ |
|
193 |
- private function setupModifyModifications(array &$subActions): void |
|
194 |
- { |
|
195 |
- $subActions['sfs'] = 'SFS::startupAdminConfiguration'; |
|
196 |
- |
|
197 |
- // Only in SMF 2.0 do we drop logs here. |
|
198 |
- if ($this->versionCheck('2.0', 'smf')) |
|
199 |
- $subActions['sfslog'] = 'SFS::startupLogs'; |
|
200 |
- } |
|
201 |
- |
|
202 |
- /** |
|
203 |
- * The configuration caller. |
|
204 |
- * |
|
205 |
- * @param bool $return_config If true, returns the configuration options for searches. |
|
206 |
- * |
|
207 |
- * @api |
|
208 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
209 |
- * @see SFS::setupSFSConfiguration |
|
210 |
- * @version 1.0 |
|
211 |
- * @since 1.0 |
|
212 |
- * @uses integrate_modify_modifications - Hook SMF2.0 |
|
213 |
- * @uses integrate_modify_modifications - Hook SMF2.1 |
|
214 |
- * @return void No return is generated |
|
215 |
- */ |
|
216 |
- public static function startupAdminConfiguration(bool $return_config = false) |
|
217 |
- { |
|
218 |
- global $smcFunc; |
|
219 |
- return $smcFunc['classSFS']->setupSFSConfiguration($return_config); |
|
220 |
- } |
|
221 |
- |
|
222 |
- /** |
|
223 |
- * The actual settings page. |
|
224 |
- * |
|
225 |
- * @param bool $return_config If true, returns the configuration options for searches. |
|
226 |
- * |
|
227 |
- * @internal |
|
228 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
229 |
- * @version 1.0 |
|
230 |
- * @since 1.0 |
|
231 |
- * @uses integrate_modify_modifications - Hook SMF2.0 |
|
232 |
- * @uses integrate_modify_modifications - Hook SMF2.1 |
|
233 |
- * @return void No return is generated |
|
234 |
- */ |
|
235 |
- private function setupSFSConfiguration(bool $return_config = false): array |
|
236 |
- { |
|
237 |
- global $scripturl, $context, $settings, $sc, $modSettings; |
|
238 |
- |
|
239 |
- $config_vars = array( |
|
240 |
- array('title', 'sfsgentitle', 'label' => $this->txt('sfs_general_title')), |
|
241 |
- |
|
242 |
- array('check', 'sfs_enabled'), |
|
243 |
- array('int', 'sfs_expire'), |
|
244 |
- '', |
|
245 |
- array('check', 'sfs_emailcheck'), |
|
246 |
- '', |
|
247 |
- array('check', 'sfs_usernamecheck'), |
|
248 |
- array('float', 'sfs_username_confidence'), |
|
249 |
- '', |
|
250 |
- array('check', 'sfs_ipcheck'), |
|
251 |
- array('check', 'sfs_ipcheck_autoban'), |
|
252 |
- '', |
|
253 |
- array('select', 'sfs_region', $this->sfsServerMapping('config')), |
|
254 |
- '', |
|
255 |
- array('check', 'sfs_wildcard_email'), |
|
256 |
- array('check', 'sfs_wildcard_username'), |
|
257 |
- array('check', 'sfs_wildcard_ip'), |
|
258 |
- '', |
|
259 |
- array('select', 'sfs_tor_check', array( |
|
260 |
- 0 => $this->txt('sfs_tor_check_block'), |
|
261 |
- 1 => $this->txt('sfs_tor_check_ignore'), |
|
262 |
- 2 => $this->txt('sfs_tor_check_bad'), |
|
263 |
- )), |
|
264 |
- |
|
265 |
- '', |
|
266 |
- array('title', 'sfsverftitle', 'label' => $this->txt('sfs_verification_title')), |
|
267 |
- array('desc', 'sfsverfdesc', 'label' => $this->txt('sfs_verification_desc')), |
|
268 |
- array('select', 'sfs_verification_options', array( |
|
269 |
- 'post' => $this->txt('sfs_verification_options_post'), |
|
270 |
- 'report' => $this->txt('sfs_verification_options_report'), |
|
271 |
- 'search' => $this->txt('sfs_verification_options_search'), |
|
272 |
- ), 'multiple' => true), |
|
273 |
- array('text', 'sfs_verification_options_extra', 'subtext' => $this->txt('sfs_verification_options_extra_subtext')), |
|
274 |
- |
|
275 |
- '', |
|
276 |
- array('select', 'sfs_verOptionsMembers', array( |
|
277 |
- 'post' => $this->txt('sfs_verification_options_post'), |
|
278 |
- 'search' => $this->txt('sfs_verification_options_search'), |
|
279 |
- ), 'multiple' => true), |
|
280 |
- array('text', 'sfs_verOptionsMemExtra', 'subtext' => $this->txt('sfs_verification_options_extra_subtext')), |
|
281 |
- array('int', 'sfs_verfOptMemPostThreshold'), |
|
282 |
- '', |
|
283 |
- array('check', 'sfs_log_debug'), |
|
284 |
- ); |
|
285 |
- |
|
286 |
- if ($return_config) |
|
287 |
- return $config_vars; |
|
288 |
- |
|
289 |
- // Saving? |
|
290 |
- if (isset($_GET['save'])) |
|
291 |
- { |
|
292 |
- // Turn the defaults off. |
|
293 |
- $this->unloadDefaults(); |
|
294 |
- checkSession(); |
|
295 |
- |
|
296 |
- // If we are automatically banning IPs, make sure we have a ban group. |
|
297 |
- if (isset($_POST['sfs_ipcheck_autoban']) && empty($modSettings['sfs_ipcheck_autoban_group'])) |
|
298 |
- $this->createBanGroup(true); |
|
299 |
- |
|
300 |
- saveDBSettings($config_vars); |
|
301 |
- |
|
302 |
- writeLog(); |
|
303 |
- redirectexit($this->adminPageURL); |
|
304 |
- } |
|
305 |
- |
|
306 |
- $context['post_url'] = $this->adminPageURL . ';save'; |
|
307 |
- |
|
308 |
- prepareDBSettingContext($config_vars); |
|
309 |
- |
|
310 |
- return array(); |
|
311 |
- } |
|
312 |
- |
|
313 |
- /** |
|
314 |
- * In some software/versions, we can hook into the logs section. |
|
315 |
- * In others we hook into the modifications settings. |
|
316 |
- * |
|
317 |
- * @param array $log_functions All possible log functions. |
|
318 |
- * |
|
319 |
- * @api |
|
320 |
- * @CalledIn SMF 2.1 |
|
321 |
- * @See SFS::startupLogs |
|
322 |
- * @version 1.0 |
|
323 |
- * @since 1.0 |
|
324 |
- * @uses integrate_manage_logs - Hook SMF2.1 |
|
325 |
- * @return void No return is generated |
|
326 |
- */ |
|
327 |
- public static function hook_manage_logs(array &$log_functions): bool |
|
328 |
- { |
|
329 |
- global $smcFunc; |
|
330 |
- |
|
331 |
- // Add our logs sub action. |
|
332 |
- $log_functions['sfslog'] = array('StopForumSpam.php', 'startupLogs'); |
|
333 |
- |
|
334 |
- global $smcFunc; |
|
335 |
- return $smcFunc['classSFS']->AddToLogMenu($log_functions); |
|
336 |
- } |
|
337 |
- |
|
338 |
- /** |
|
339 |
- * Add the SFS logs to the log menu. |
|
340 |
- * |
|
341 |
- * @param array $log_functions All possible log functions. |
|
342 |
- * |
|
343 |
- * @CalledIn SMF 2.1 |
|
344 |
- * @See SFS::startupLogs |
|
345 |
- * @version 1.1 |
|
346 |
- * @since 1.1 |
|
347 |
- * @return void No return is generated |
|
348 |
- */ |
|
349 |
- public function AddToLogMenu(array &$log_functions): bool |
|
350 |
- { |
|
351 |
- global $context; |
|
352 |
- |
|
353 |
- $context[$context['admin_menu_name']]['tab_data']['tabs']['sfslog'] = array( |
|
354 |
- 'description' => $this->txt('sfs_admin_logs'), |
|
355 |
- ); |
|
356 |
- |
|
357 |
- return true; |
|
358 |
- } |
|
359 |
- |
|
360 |
- /** |
|
361 |
- * Log startup caller. |
|
362 |
- * This has a $return_config just for simply complying with properly for searching the admin panel. |
|
363 |
- * |
|
364 |
- * @param bool $return_config If true, returns empty array to prevent breaking old SMF installs. |
|
365 |
- * |
|
366 |
- * @api |
|
367 |
- * @CalledIn SMF 2.1 |
|
368 |
- * @See SFS::loadLogs |
|
369 |
- * @version 1.0 |
|
370 |
- * @since 1.0 |
|
371 |
- * @uses hook_manage_logs - Hook SMF2.1 |
|
372 |
- * @uses setupModifyModifications - Injected SMF2.0 |
|
373 |
- * @return void No return is generated |
|
374 |
- */ |
|
375 |
- public static function startupLogs(bool $return_config = false): array |
|
376 |
- { |
|
377 |
- global $smcFunc; |
|
378 |
- |
|
379 |
- return $smcFunc['classSFS']->loadLogs(); |
|
380 |
- } |
|
381 |
- |
|
382 |
- /** |
|
383 |
- * Actually show the logs. |
|
384 |
- * This has a $return_config just for simply complying with properly for searching the admin panel. |
|
385 |
- * |
|
386 |
- * @param bool $return_config If true, returns empty array to prevent breaking old SMF installs. |
|
387 |
- * |
|
388 |
- * @api |
|
389 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
390 |
- * @See SFS::getSFSLogEntries |
|
391 |
- * @See SFS::getSFSLogEntriesCount |
|
392 |
- * @version 1.0 |
|
393 |
- * @since 1.0 |
|
394 |
- * @uses hook_manage_logs - Hook SMF2.1 |
|
395 |
- * @uses setupModifyModifications - Injected SMF2.0 |
|
396 |
- * @return void No return is generated |
|
397 |
- */ |
|
398 |
- public function loadLogs(bool $return_config = false): array |
|
399 |
- { |
|
400 |
- global $context, $smcFunc, $sourcedir; |
|
401 |
- |
|
402 |
- // No Configs. |
|
403 |
- if ($return_config) |
|
404 |
- return array(); |
|
405 |
- |
|
406 |
- loadLanguage('Modlog'); |
|
407 |
- |
|
408 |
- $context['form_url'] = $this->adminLogURL; |
|
409 |
- $context['log_url'] = $this->adminLogURL; |
|
410 |
- $context['page_title'] = $this->txt('sfs_admin_logs'); |
|
411 |
- $this->canDeleteLogs = allowedTo('admin_forum'); |
|
412 |
- |
|
413 |
- // Remove all.. |
|
414 |
- if ((isset($_POST['removeall']) || isset($_POST['delete'])) && $this->canDeleteLogs) |
|
415 |
- $this->handleLogDeletes(); |
|
416 |
- |
|
417 |
- $sort_types = array( |
|
418 |
- 'id_type' =>'l.id_type', |
|
419 |
- 'log_time' => 'l.log_time', |
|
420 |
- 'url' => 'l.url', |
|
421 |
- 'member' => 'mem.id_member', |
|
422 |
- 'username' => 'l.username', |
|
423 |
- 'email' => 'l.email', |
|
424 |
- 'ip' => 'l.ip', |
|
425 |
- 'ip2' => 'l.ip2', |
|
426 |
- ); |
|
427 |
- |
|
428 |
- $context['order'] = isset($_REQUEST['sort']) && isset($sort_types[$_REQUEST['sort']]) ? $_REQUEST['sort'] : 'time'; |
|
429 |
- |
|
430 |
- // Handle searches. |
|
431 |
- $this->handleLogSearch($context['log_url']); |
|
432 |
- |
|
433 |
- require_once($sourcedir . '/Subs-List.php'); |
|
434 |
- |
|
435 |
- $listOptions = array( |
|
436 |
- 'id' => 'sfslog_list', |
|
437 |
- 'title' => $this->txt('sfs_admin_logs'), |
|
438 |
- 'width' => '100%', |
|
439 |
- 'items_per_page' => '50', |
|
440 |
- 'no_items_label' => $this->txt('sfs_log_no_entries_found'), |
|
441 |
- 'base_href' => $context['log_url'], |
|
442 |
- 'default_sort_col' => 'time', |
|
443 |
- 'get_items' => $this->loadLogsGetItems(), |
|
444 |
- 'get_count' => $this->loadLogsGetCount(), |
|
445 |
- // This assumes we are viewing by user. |
|
446 |
- 'columns' => array( |
|
447 |
- 'type' => $this->loadLogsColumnType(), |
|
448 |
- 'time' => $this->loadLogsColumnTime(), |
|
449 |
- 'url' => $this->loadLogsColumnURL(), |
|
450 |
- 'member' => $this->loadLogsColumnMember(), |
|
451 |
- 'username' => $this->loadLogsColumnUsername(), |
|
452 |
- 'email' => $this->loadLogsColumnEmail(), |
|
453 |
- 'ip' => $this->loadLogsColumnIP(), |
|
454 |
- 'ip2' => $this->loadLogsColumnIP(true), |
|
455 |
- 'checks' => $this->loadLogsColumnChecks(), |
|
456 |
- 'result' => $this->loadLogsColumnResult(), |
|
457 |
- 'delete' => $this->loadLogsColumnDelete(), |
|
458 |
- ), |
|
459 |
- 'form' => array( |
|
460 |
- 'href' => $context['form_url'], |
|
461 |
- 'include_sort' => true, |
|
462 |
- 'include_start' => true, |
|
463 |
- 'hidden_fields' => array( |
|
464 |
- $context['session_var'] => $context['session_id'], |
|
465 |
- 'params' => $this->search_params |
|
466 |
- ), |
|
467 |
- ), |
|
468 |
- 'additional_rows' => array( |
|
469 |
- $this->loadLogsGetAddtionalRow(), |
|
470 |
- ), |
|
471 |
- ); |
|
472 |
- |
|
473 |
- // Create the watched user list. |
|
474 |
- createList($listOptions); |
|
475 |
- |
|
476 |
- $context['sub_template'] = 'show_list'; |
|
477 |
- $context['default_list'] = 'sfslog_list'; |
|
478 |
- |
|
479 |
- return array(); |
|
480 |
- } |
|
481 |
- |
|
482 |
- /** |
|
483 |
- * Handle when we want to delete a log and what to do. |
|
484 |
- * |
|
485 |
- * @internal |
|
486 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
487 |
- * @version 1.1 |
|
488 |
- * @since 1.1 |
|
489 |
- * @return void Nothing is returned, the logs are deleted as requested and admin redirected. |
|
490 |
- */ |
|
491 |
- private function handleLogDeletes(): void |
|
492 |
- { |
|
493 |
- if (isset($_POST['removeall']) && $this->canDeleteLogs) |
|
494 |
- $this->removeAllLogs(); |
|
495 |
- elseif (!empty($_POST['remove']) && isset($_POST['delete']) && $this->canDeleteLogs) |
|
496 |
- $this->removeLogs(array_unique($_POST['delete'])); |
|
497 |
- } |
|
498 |
- |
|
499 |
- /** |
|
500 |
- * loadLogs - Get Items. |
|
501 |
- * |
|
502 |
- * @internal |
|
503 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
504 |
- * @version 1.1 |
|
505 |
- * @since 1.1 |
|
506 |
- * @return array The options for the get_items |
|
507 |
- */ |
|
508 |
- private function loadLogsGetItems(): array |
|
509 |
- { |
|
510 |
- return array( |
|
511 |
- 'function' => array($this, 'getSFSLogEntries'), |
|
512 |
- 'params' => array( |
|
513 |
- (!empty($this->logSearch['string']) ? ' INSTR({raw:sql_type}, {string:search_string})' : ''), |
|
514 |
- array('sql_type' => $this->search_params_column, 'search_string' => $this->logSearch['string']), |
|
515 |
- ), |
|
516 |
- ); |
|
517 |
- } |
|
518 |
- |
|
519 |
- /** |
|
520 |
- * loadLogs - Get Count. |
|
521 |
- * |
|
522 |
- * @internal |
|
523 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
524 |
- * @version 1.1 |
|
525 |
- * @since 1.1 |
|
526 |
- * @return array The options for the get_items |
|
527 |
- */ |
|
528 |
- private function loadLogsGetCount(): array |
|
529 |
- { |
|
530 |
- return array( |
|
531 |
- 'function' => array($this, 'getSFSLogEntriesCount'), |
|
532 |
- 'params' => array( |
|
533 |
- (!empty($this->logSearch['string']) ? ' INSTR({raw:sql_type}, {string:search_string})' : ''), |
|
534 |
- array('sql_type' => $this->search_params_column, 'search_string' => $this->logSearch['string']), |
|
535 |
- ), |
|
536 |
- ); |
|
537 |
- } |
|
538 |
- |
|
539 |
- /** |
|
540 |
- * loadLogs - Load an additional row, for mostly deleting stuff. |
|
541 |
- * |
|
542 |
- * @internal |
|
543 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
544 |
- * @version 1.1 |
|
545 |
- * @since 1.1 |
|
546 |
- * @return array The options for the get_items |
|
547 |
- */ |
|
548 |
- private function loadLogsGetAddtionalRow(): array |
|
549 |
- { |
|
550 |
- global $smcFunc; |
|
551 |
- |
|
552 |
- return array( |
|
553 |
- 'position' => 'below_table_data', |
|
554 |
- 'value' => ' |
|
555 |
- ' . $this->txt('sfs_log_search') . ' (' . $this->logSearch['label'] . '): |
|
556 |
- <input type="text" name="search" size="18" value="' . $smcFunc['htmlspecialchars']($this->logSearch['string']) . '" class="input_text" /> <input type="submit" name="is_search" value="' . $this->txt('modlog_go') . '" class="button_submit" /> |
|
557 |
- ' . ($this->canDeleteLogs ? ' | |
|
558 |
- <input type="submit" name="remove" value="' . $this->txt('modlog_remove') . '" class="button_submit" /> |
|
559 |
- <input type="submit" name="removeall" value="' . $this->txt('modlog_removeall') . '" class="button_submit" />' : ''), |
|
560 |
- ); |
|
561 |
- } |
|
562 |
- |
|
563 |
- |
|
564 |
- /** |
|
565 |
- * loadLogs - Column - Type. |
|
566 |
- * |
|
567 |
- * @internal |
|
568 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
569 |
- * @version 1.1 |
|
570 |
- * @since 1.1 |
|
571 |
- * @return array The options for the column |
|
572 |
- */ |
|
573 |
- private function loadLogsColumnType(): array |
|
574 |
- { |
|
575 |
- return array( |
|
576 |
- 'header' => array( |
|
577 |
- 'value' => $this->txt('sfs_log_header_type'), |
|
578 |
- 'class' => 'lefttext', |
|
579 |
- ), |
|
580 |
- 'data' => array( |
|
581 |
- 'db' => 'type', |
|
582 |
- 'class' => 'smalltext', |
|
583 |
- ), |
|
584 |
- 'sort' => array( |
|
585 |
- ), |
|
586 |
- ); |
|
587 |
- } |
|
588 |
- |
|
589 |
- /** |
|
590 |
- * loadLogs - Column - Time. |
|
591 |
- * |
|
592 |
- * @internal |
|
593 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
594 |
- * @version 1.1 |
|
595 |
- * @since 1.1 |
|
596 |
- * @return array The options for the column |
|
597 |
- */ |
|
598 |
- private function loadLogsColumnTime(): array |
|
599 |
- { |
|
600 |
- return array( |
|
601 |
- 'header' => array( |
|
602 |
- 'value' => $this->txt('sfs_log_header_time'), |
|
603 |
- 'class' => 'lefttext', |
|
604 |
- ), |
|
605 |
- 'data' => array( |
|
606 |
- 'db' => 'time', |
|
607 |
- 'class' => 'smalltext', |
|
608 |
- ), |
|
609 |
- 'sort' => array( |
|
610 |
- 'default' => 'l.log_time DESC', |
|
611 |
- 'reverse' => 'l.log_time', |
|
612 |
- ), |
|
613 |
- ); |
|
614 |
- } |
|
615 |
- |
|
616 |
- /** |
|
617 |
- * loadLogs - Column - URL. |
|
618 |
- * |
|
619 |
- * @internal |
|
620 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
621 |
- * @version 1.1 |
|
622 |
- * @since 1.1 |
|
623 |
- * @return array The options for the column |
|
624 |
- */ |
|
625 |
- private function loadLogsColumnURL(): array |
|
626 |
- { |
|
627 |
- return array( |
|
628 |
- 'header' => array( |
|
629 |
- 'value' => $this->txt('sfs_log_header_url'), |
|
630 |
- 'class' => 'lefttext', |
|
631 |
- ), |
|
632 |
- 'data' => array( |
|
633 |
- 'db' => 'url', |
|
634 |
- 'class' => 'smalltext', |
|
635 |
- 'style' => 'word-break: break-word;', |
|
636 |
- ), |
|
637 |
- 'sort' => array( |
|
638 |
- 'default' => 'l.url DESC', |
|
639 |
- 'reverse' => 'l.url', |
|
640 |
- ), |
|
641 |
- ); |
|
642 |
- } |
|
643 |
- |
|
644 |
- /** |
|
645 |
- * loadLogs - Column - Member. |
|
646 |
- * |
|
647 |
- * @internal |
|
648 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
649 |
- * @version 1.1 |
|
650 |
- * @since 1.1 |
|
651 |
- * @return array The options for the column |
|
652 |
- */ |
|
653 |
- private function loadLogsColumnMember(): array |
|
654 |
- { |
|
655 |
- return array( |
|
656 |
- 'header' => array( |
|
657 |
- 'value' => $this->txt('sfs_log_header_member'), |
|
658 |
- 'class' => 'lefttext', |
|
659 |
- ), |
|
660 |
- 'data' => array( |
|
661 |
- 'db' => 'member_link', |
|
662 |
- 'class' => 'smalltext', |
|
663 |
- ), |
|
664 |
- 'sort' => array( |
|
665 |
- 'default' => 'mem.id_member', |
|
666 |
- 'reverse' => 'mem.id_member DESC', |
|
667 |
- ), |
|
668 |
- ); |
|
669 |
- } |
|
670 |
- |
|
671 |
- /** |
|
672 |
- * loadLogs - Column - Username. |
|
673 |
- * |
|
674 |
- * @internal |
|
675 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
676 |
- * @version 1.1 |
|
677 |
- * @since 1.1 |
|
678 |
- * @return array The options for the column |
|
679 |
- */ |
|
680 |
- private function loadLogsColumnUsername(): array |
|
681 |
- { |
|
682 |
- return array( |
|
683 |
- 'header' => array( |
|
684 |
- 'value' => $this->txt('sfs_log_header_username'), |
|
685 |
- 'class' => 'lefttext', |
|
686 |
- ), |
|
687 |
- 'data' => array( |
|
688 |
- 'db' => 'username', |
|
689 |
- 'class' => 'smalltext', |
|
690 |
- ), |
|
691 |
- 'sort' => array( |
|
692 |
- 'default' => 'l.username', |
|
693 |
- 'reverse' => 'l.username DESC', |
|
694 |
- ), |
|
695 |
- ); |
|
696 |
- } |
|
697 |
- |
|
698 |
- /** |
|
699 |
- * loadLogs - Column - Email. |
|
700 |
- * |
|
701 |
- * @internal |
|
702 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
703 |
- * @version 1.1 |
|
704 |
- * @since 1.1 |
|
705 |
- * @return array The options for the column |
|
706 |
- */ |
|
707 |
- private function loadLogsColumnEmail(): array |
|
708 |
- { |
|
709 |
- return array( |
|
710 |
- 'header' => array( |
|
711 |
- 'value' => $this->txt('sfs_log_header_email'), |
|
712 |
- 'class' => 'lefttext', |
|
713 |
- ), |
|
714 |
- 'data' => array( |
|
715 |
- 'db' => 'email', |
|
716 |
- 'class' => 'smalltext', |
|
717 |
- ), |
|
718 |
- 'sort' => array( |
|
719 |
- 'default' => 'l.email', |
|
720 |
- 'reverse' => 'l.email DESC', |
|
721 |
- ), |
|
722 |
- ); |
|
723 |
- } |
|
724 |
- |
|
725 |
- /** |
|
726 |
- * loadLogs - Column - IP. |
|
727 |
- * |
|
728 |
- * @param string $ip2 If true, use ip2 |
|
729 |
- * @internal |
|
730 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
731 |
- * @version 1.1 |
|
732 |
- * @since 1.1 |
|
733 |
- * @return array The options for the column |
|
734 |
- */ |
|
735 |
- private function loadLogsColumnIP(bool $ip2 = false): array |
|
736 |
- { |
|
737 |
- return array( |
|
738 |
- 'header' => array( |
|
739 |
- 'value' => $this->txt('sfs_log_header_ip' . ($ip2 ? '2' : '')), |
|
740 |
- 'class' => 'lefttext', |
|
741 |
- ), |
|
742 |
- 'data' => array( |
|
743 |
- 'db' => 'ip' . ($ip2 ? '2' : ''), |
|
744 |
- 'class' => 'smalltext', |
|
745 |
- ), |
|
746 |
- 'sort' => array( |
|
747 |
- 'default' => 'l.ip' . ($ip2 ? '2' : ''), |
|
748 |
- 'reverse' => 'l.ip' . ($ip2 ? '2' : '') . ' DESC', |
|
749 |
- ), |
|
750 |
- ); |
|
751 |
- } |
|
752 |
- |
|
753 |
- /** |
|
754 |
- * loadLogs - Column - Checks. |
|
755 |
- * |
|
756 |
- * @internal |
|
757 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
758 |
- * @version 1.1 |
|
759 |
- * @since 1.1 |
|
760 |
- * @return array The options for the column |
|
761 |
- */ |
|
762 |
- private function loadLogsColumnChecks(): array |
|
763 |
- { |
|
764 |
- return array( |
|
765 |
- 'header' => array( |
|
766 |
- 'value' => $this->txt('sfs_log_checks'), |
|
767 |
- 'class' => 'lefttext', |
|
768 |
- ), |
|
769 |
- 'data' => array( |
|
770 |
- 'db' => 'checks', |
|
771 |
- 'class' => 'smalltext', |
|
772 |
- 'style' => 'word-break: break-word;', |
|
773 |
- ), |
|
774 |
- 'sort' => array(), |
|
775 |
- ); |
|
776 |
- } |
|
777 |
- |
|
778 |
- /** |
|
779 |
- * loadLogs - Column - Result. |
|
780 |
- * |
|
781 |
- * @internal |
|
782 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
783 |
- * @version 1.1 |
|
784 |
- * @since 1.1 |
|
785 |
- * @return array The options for the column |
|
786 |
- */ |
|
787 |
- private function loadLogsColumnResult(): array |
|
788 |
- { |
|
789 |
- return array( |
|
790 |
- 'header' => array( |
|
791 |
- 'value' => $this->txt('sfs_log_result'), |
|
792 |
- 'class' => 'lefttext', |
|
793 |
- ), |
|
794 |
- 'data' => array( |
|
795 |
- 'db' => 'result', |
|
796 |
- 'class' => 'smalltext', |
|
797 |
- 'style' => 'word-break: break-word;', |
|
798 |
- ), |
|
799 |
- 'sort' => array(), |
|
800 |
- ); |
|
801 |
- } |
|
802 |
- |
|
803 |
- /** |
|
804 |
- * loadLogs - Column - Delete. |
|
805 |
- * |
|
806 |
- * @internal |
|
807 |
- * @CalledIn SMF2.0, SMF 2.1 |
|
808 |
- * @version 1.1 |
|
809 |
- * @since 1.1 |
|
810 |
- * @return array The options for the column |
|
811 |
- */ |
|
812 |
- private function loadLogsColumnDelete(): array |
|
813 |
- { |
|
814 |
- return array( |
|
815 |
- 'header' => array( |
|
816 |
- 'value' => '<input type="checkbox" name="all" class="input_check" onclick="invertAll(this, this.form);" />', |
|
817 |
- ), |
|
818 |
- 'data' => array( |
|
819 |
- 'function' => function($entry) |
|
820 |
- { |
|
821 |
- return '<input type="checkbox" class="input_check" name="delete[]" value="' . $entry['id'] . '"' . ($entry['editable'] ? '' : ' disabled="disabled"') . ' />'; |
|
822 |
- }, |
|
823 |
- 'style' => 'text-align: center;', |
|
824 |
- ), |
|
825 |
- ); |
|
826 |
- } |
|
827 |
- |
|
828 |
- /** |
|
829 |
- * Get the log data and returns it ready to go for GenericList handling. |
|
830 |
- * |
|
831 |
- * @param int $start The index for where we offset or start at for the list |
|
832 |
- * @param int $items_per_page How many items we are going to show on this page. |
|
833 |
- * @param string $sort The column we are sorting by. |
|
834 |
- * @param string $query_string The search string we are using to filter log data. |
|
835 |
- * @param array $query_params Extra parameters for searching. |
|
836 |
- * |
|
837 |
- * @api |
|
838 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
839 |
- * @See SFS::loadLogs |
|
840 |
- * @version 1.0 |
|
841 |
- * @since 1.0 |
|
842 |
- * @uses hook_manage_logs - Hook SMF2.1 |
|
843 |
- * @uses setupModifyModifications - Injected SMF2.0 |
|
844 |
- * @return void No return is generated |
|
845 |
- */ |
|
846 |
- public function getSFSLogEntries(int $start, int $items_per_page, string $sort, string $query_string = '', array $query_params = array()): array |
|
847 |
- { |
|
848 |
- global $scripturl, $context, $smcFunc; |
|
849 |
- |
|
850 |
- // Fetch all of our logs. |
|
851 |
- $result = $smcFunc['db_query']('', ' |
|
852 |
- SELECT |
|
853 |
- l.id_sfs, |
|
854 |
- l.id_type, |
|
855 |
- l.log_time, |
|
856 |
- l.url, |
|
857 |
- l.id_member, |
|
858 |
- l.username, |
|
859 |
- l.email, |
|
860 |
- l.ip, |
|
861 |
- l.ip2, |
|
862 |
- l.checks, |
|
863 |
- l.result, |
|
864 |
- mem.real_name, |
|
865 |
- mg.group_name |
|
866 |
- FROM {db_prefix}log_sfs AS l |
|
867 |
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = l.id_member) |
|
868 |
- LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_group_id} THEN mem.id_post_group ELSE mem.id_group END) |
|
869 |
- WHERE id_type IS NOT NULL' |
|
870 |
- . (!empty($query_string) ? ' |
|
871 |
- AND ' . $query_string : '') . ' |
|
872 |
- ORDER BY ' . $sort . ' |
|
873 |
- LIMIT ' . $start . ', ' . $items_per_page, |
|
874 |
- array_merge($query_params, array( |
|
875 |
- 'reg_group_id' => 0, |
|
876 |
- )) |
|
877 |
- ); |
|
878 |
- |
|
879 |
- $entries = array(); |
|
880 |
- while ($row = $smcFunc['db_fetch_assoc']($result)) |
|
881 |
- { |
|
882 |
- $entries[$row['id_sfs']] = array( |
|
883 |
- 'id' => $row['id_sfs'], |
|
884 |
- 'type' => $this->txt('sfs_log_types_' . $row['id_type']), |
|
885 |
- 'time' => timeformat($row['log_time']), |
|
886 |
- 'url' => preg_replace('~http(s)?://~i', 'hxxp\\1://', $row['url']), |
|
887 |
- 'timestamp' => forum_time(true, $row['log_time']), |
|
888 |
- 'member_link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>' : (empty($row['real_name']) ? ($this->txt('guest') . (!empty($row['extra']['member_acted']) ? ' (' . $row['extra']['member_acted'] . ')' : '')) : $row['real_name']), |
|
889 |
- 'username' => $row['username'], |
|
890 |
- 'email' => $row['email'], |
|
891 |
- 'ip' => '<a href="' . sprintf($this->urlSFSipCheck, $row['ip']) . '">' . $row['ip'] . '</a>', |
|
892 |
- 'ip2' => '<a href="' . sprintf($this->urlSFSipCheck, $row['ip2']) . '">' . $row['ip2'] . '</a>', |
|
893 |
- 'editable' => true, //time() > $row['log_time'] + $this->hoursDisabled * 3600, |
|
894 |
- 'checks_raw' => $row['checks'], |
|
895 |
- 'result_raw' => $row['result'], |
|
896 |
- ); |
|
897 |
- |
|
898 |
- $checksDecoded = $this->decodeJSON($row['checks']); |
|
899 |
- |
|
900 |
- // If we know what check triggered this, link it up to be searched. |
|
901 |
- if ($row['id_type'] == 1) |
|
902 |
- $entries[$row['id_sfs']]['checks'] = '<a href="' . sprintf($this->urlSFSsearch, $checksDecoded['value']) . '">' . $checksDecoded['value'] . '</a>'; |
|
903 |
- elseif ($row['id_type'] == 2) |
|
904 |
- $entries[$row['id_sfs']]['checks'] = '<a href="' . sprintf($this->urlSFSsearch, $checksDecoded['value']) . '">' . $checksDecoded['value'] . '</a>'; |
|
905 |
- elseif ($row['id_type'] == 3) |
|
906 |
- $entries[$row['id_sfs']]['checks'] = '<a href="' . sprintf($this->urlSFSsearch, $checksDecoded['value']) . '">' . $checksDecoded['value'] . '</a>'; |
|
907 |
- // No idea what triggered it, parse it out cleanly. Could be debug data as well. |
|
908 |
- else |
|
909 |
- { |
|
910 |
- $entries[$row['id_sfs']]['checks'] = ''; |
|
911 |
- |
|
912 |
- foreach ($checksDecoded as $ckey => $vkey) |
|
913 |
- foreach ($vkey as $key => $value) |
|
914 |
- $entries[$row['id_sfs']]['checks'] .= ucfirst($key) . ':' . $value . '<br>'; |
|
915 |
- } |
|
916 |
- |
|
917 |
- // This tells us what it matched on exactly. |
|
918 |
- if (strpos($row['result'], ',') !== false) |
|
919 |
- { |
|
920 |
- list($resultType, $resultMatch, $extra) = explode(',', $row['result'] . ',,,'); |
|
921 |
- $entries[$row['id_sfs']]['result'] = sprintf($this->txt('sfs_log_matched_on'), $resultType, $resultMatch); |
|
922 |
- |
|
923 |
- // If this was a IP ban, note it. |
|
924 |
- if ($resultType == 'ip' && !empty($extra)) |
|
925 |
- $entries[$row['id_sfs']]['result'] .= ' ' . $this->txt('sfs_log_auto_banned'); |
|
926 |
- if ($resultType == 'username' && !empty($extra)) |
|
927 |
- $entries[$row['id_sfs']]['result'] .= ' ' . sprintf($this->txt('sfs_log_confidence'), $extra); |
|
928 |
- } |
|
929 |
- else |
|
930 |
- $entries[$row['id_sfs']]['result'] = $row['result']; |
|
931 |
- |
|
932 |
- } |
|
933 |
- $smcFunc['db_free_result']($result); |
|
934 |
- |
|
935 |
- return $entries; |
|
936 |
- } |
|
937 |
- |
|
938 |
- /** |
|
939 |
- * Get the log counts and returns it ready to go for GenericList handling. |
|
940 |
- * |
|
941 |
- * @param string $query_string The search string we are using to filter log data. |
|
942 |
- * @param array $query_params Extra parameters for searching. |
|
943 |
- * |
|
944 |
- * @api |
|
945 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
946 |
- * @See SFS::loadLogs |
|
947 |
- * @version 1.0 |
|
948 |
- * @since 1.0 |
|
949 |
- * @uses hook_manage_logs - Hook SMF2.1 |
|
950 |
- * @uses setupModifyModifications - Injected SMF2.0 |
|
951 |
- * @return void No return is generated |
|
952 |
- */ |
|
953 |
- public function getSFSLogEntriesCount(string $query_string = '', array $query_params = array()): int |
|
954 |
- { |
|
955 |
- global $smcFunc, $user_info; |
|
956 |
- |
|
957 |
- $result = $smcFunc['db_query']('', ' |
|
958 |
- SELECT COUNT(*) |
|
959 |
- FROM {db_prefix}log_sfs AS l |
|
960 |
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = l.id_member) |
|
961 |
- LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_group_id} THEN mem.id_post_group ELSE mem.id_group END) |
|
962 |
- WHERE id_type IS NOT NULL' |
|
963 |
- . (!empty($query_string) ? ' |
|
964 |
- AND ' . $query_string : ''), |
|
965 |
- array_merge($query_params, array( |
|
966 |
- 'reg_group_id' => 0, |
|
967 |
- )) |
|
968 |
- ); |
|
969 |
- list ($entry_count) = $smcFunc['db_fetch_row']($result); |
|
970 |
- $smcFunc['db_free_result']($result); |
|
971 |
- |
|
972 |
- return (int) $entry_count; |
|
973 |
- } |
|
974 |
- |
|
975 |
- /** |
|
976 |
- * Remove all logs, except those less than 24 hours old. |
|
26 |
+ * Simple setup for the class to be used later correctly. |
|
27 |
+ * This simply loads the class into $smcFunc and we can grab this anywhere else later. |
|
977 | 28 |
* |
978 | 29 |
* @api |
979 | 30 |
* @CalledIn SMF 2.0, SMF 2.1 |
980 |
- * @See SFS::loadLogs |
|
981 | 31 |
* @version 1.0 |
982 | 32 |
* @since 1.0 |
33 |
+ * @uses integrate_pre_load - Hook SMF2.0 |
|
34 |
+ * @uses integrate_pre_load - Hook SMF2.1 |
|
983 | 35 |
* @return void No return is generated |
984 | 36 |
*/ |
985 |
- private function removeAllLogs(): void |
|
37 |
+ public static function hook_pre_load(): void |
|
986 | 38 |
{ |
987 |
- global $smcFunc; |
|
988 |
- |
|
989 |
- checkSession(); |
|
39 |
+ global $smcFunc, $sourcedir; |
|
990 | 40 |
|
991 |
- $smcFunc['db_query']('', ' |
|
992 |
- DELETE FROM {db_prefix}log_sfs |
|
993 |
- WHERE log_time < {int:twenty_four_hours_wait}', |
|
994 |
- array( |
|
995 |
- 'twenty_four_hours_wait' => time() - $this->hoursDisabled * 3600, |
|
996 |
- ) |
|
997 |
- ); |
|
41 |
+ $smcFunc['classSFS'] = new SFS(); |
|
998 | 42 |
} |
999 | 43 |
|
1000 | 44 |
/** |
1001 |
- * Remove specific logs, except those less than 24 hours old. |
|
1002 |
- * |
|
1003 |
- * @param array $entries A array of the ids that we want to remove. |
|
45 |
+ * Build the class, figure out what software/version we have. |
|
46 |
+ * Loads up the defaults. |
|
1004 | 47 |
* |
1005 |
- * @api |
|
1006 | 48 |
* @CalledIn SMF 2.0, SMF 2.1 |
1007 |
- * @See SFS::loadLogs |
|
1008 | 49 |
* @version 1.0 |
1009 | 50 |
* @since 1.0 |
1010 | 51 |
* @return void No return is generated |
1011 | 52 |
*/ |
1012 |
- private function removeLogs(array $entries): void |
|
53 |
+ public function __construct() |
|
1013 | 54 |
{ |
1014 | 55 |
global $smcFunc; |
1015 | 56 |
|
1016 |
- checkSession(); |
|
57 |
+ // Is this SMF 2.0? |
|
58 |
+ if (!function_exists('loadCacheAccelerator')) |
|
59 |
+ $this->softwareVersion = '2.0'; |
|
1017 | 60 |
|
1018 |
- $smcFunc['db_query']('', ' |
|
1019 |
- DELETE FROM {db_prefix}log_sfs |
|
1020 |
- WHERE id_sfs IN ({array_string:delete_actions}) |
|
1021 |
- AND log_time < {int:twenty_four_hours_wait}', |
|
1022 |
- array( |
|
1023 |
- 'twenty_four_hours_wait' => time() - $this->hoursDisabled * 3600, |
|
1024 |
- 'delete_actions' => $entries, |
|
1025 |
- ) |
|
1026 |
- ); |
|
61 |
+ // Setup the defaults. |
|
62 |
+ $this->loadDefaults(); |
|
1027 | 63 |
} |
1028 | 64 |
|
1029 | 65 |
/** |
... | ... |
@@ -1652,7 +688,7 @@ class SFS |
1652 | 688 |
* @since 1.0 |
1653 | 689 |
* @return array The parsed json string is now an array. |
1654 | 690 |
*/ |
1655 |
- private function decodeJSON(string $requestData): array |
|
691 |
+ public function decodeJSON(string $requestData): array |
|
1656 | 692 |
{ |
1657 | 693 |
global $smcFunc; |
1658 | 694 |
|
... | ... |
@@ -1741,7 +777,7 @@ class SFS |
1741 | 777 |
* @since 1.0 |
1742 | 778 |
* @return array The list of servers. |
1743 | 779 |
*/ |
1744 |
- private function sfsServerMapping($returnType = null) |
|
780 |
+ public function sfsServerMapping($returnType = null) |
|
1745 | 781 |
{ |
1746 | 782 |
// Global list of servers. |
1747 | 783 |
$serverList = array( |
... | ... |
@@ -1943,126 +979,6 @@ class SFS |
1943 | 979 |
return $txt[$key]; |
1944 | 980 |
} |
1945 | 981 |
|
1946 |
- /** |
|
1947 |
- * Handle searching for logs. |
|
1948 |
- * |
|
1949 |
- * @param string $url The base_href |
|
1950 |
- * @internal |
|
1951 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
1952 |
- * @version 1.0 |
|
1953 |
- * @since 1.0 |
|
1954 |
- * @return void No return is generated here. |
|
1955 |
- */ |
|
1956 |
- private function handleLogSearch(string &$url): void |
|
1957 |
- { |
|
1958 |
- global $context, $txt; |
|
1959 |
- |
|
1960 |
- // If we have some data from a search, lets bring it back out. |
|
1961 |
- $this->search_params = $this->handleLogSearchParams(); |
|
1962 |
- |
|
1963 |
- // What we can search. |
|
1964 |
- $this->search_types = $this->handleLogSearchTypes(); |
|
1965 |
- $this->search_params_string = $this->handleLogSearchParamsString(); |
|
1966 |
- $this->search_params_type = $this->handleLogSearchParamsType(); |
|
1967 |
- |
|
1968 |
- $this->search_params_column = $this->search_types[$this->search_params_type]['sql']; |
|
1969 |
- |
|
1970 |
- // Setup the search context. |
|
1971 |
- $this->search_params = empty($search_params_string) ? '' : base64_encode(json_encode(array( |
|
1972 |
- 'string' => $this->search_params_string, |
|
1973 |
- 'type' => $this->search_params_type, |
|
1974 |
- ))); |
|
1975 |
- $this->logSearch = array( |
|
1976 |
- 'string' => $this->search_params_string, |
|
1977 |
- 'type' => $this->search_params_type, |
|
1978 |
- 'label' => $this->search_types[$this->search_params_type]['label'], |
|
1979 |
- ); |
|
1980 |
- |
|
1981 |
- if (!empty($this->search_params)) |
|
1982 |
- $url .= ';params=' . $this->search_params; |
|
1983 |
- } |
|
1984 |
- |
|
1985 |
- /** |
|
1986 |
- * Handle Search Params |
|
1987 |
- * |
|
1988 |
- * @internal |
|
1989 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
1990 |
- * @version 1.1 |
|
1991 |
- * @since 1.0 |
|
1992 |
- * @return bool True upon success, false otherwise. |
|
1993 |
- */ |
|
1994 |
- private function handleLogSearchParams(): array |
|
1995 |
- { |
|
1996 |
- // If we have something to search for saved, get it back out. |
|
1997 |
- if (!empty($_REQUEST['params']) && empty($_REQUEST['is_search'])) |
|
1998 |
- { |
|
1999 |
- $search_params = base64_decode(strtr($params, array(' ' => '+'))); |
|
2000 |
- $search_params = $this->decodeJSON($this->search_params); |
|
2001 |
- |
|
2002 |
- if (!empty($search_params)) |
|
2003 |
- return $search_params; |
|
2004 |
- } |
|
2005 |
- |
|
2006 |
- return array(); |
|
2007 |
- } |
|
2008 |
- |
|
2009 |
- /** |
|
2010 |
- * Handle Search Types |
|
2011 |
- * |
|
2012 |
- * @internal |
|
2013 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
2014 |
- * @version 1.1 |
|
2015 |
- * @since 1.0 |
|
2016 |
- * @return array The valid Search Types. |
|
2017 |
- */ |
|
2018 |
- private function handleLogSearchTypes(): array |
|
2019 |
- { |
|
2020 |
- return array( |
|
2021 |
- 'url' => array('sql' => 'l.url', 'label' => $this->txt('sfs_log_search_url')), |
|
2022 |
- 'member' => array('sql' => 'mem.real_name', 'label' => $this->txt('sfs_log_search_member')), |
|
2023 |
- 'username' => array('sql' => 'l.username', 'label' => $this->txt('sfs_log_search_username')), |
|
2024 |
- 'email' => array('sql' => 'l.email', 'label' => $this->txt('sfs_log_search_email')), |
|
2025 |
- 'ip' => array('sql' => 'lm.ip', 'label' => $this->txt('sfs_log_search_ip')), |
|
2026 |
- 'ip2' => array('sql' => 'lm.ip2', 'label' => $this->txt('sfs_log_search_ip2')) |
|
2027 |
- ); |
|
2028 |
- } |
|
2029 |
- |
|
2030 |
- /** |
|
2031 |
- * Handle Search Params String |
|
2032 |
- * |
|
2033 |
- * @internal |
|
2034 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
2035 |
- * @version 1.1 |
|
2036 |
- * @since 1.0 |
|
2037 |
- * @return string What we are searching for, validated and cleaned. |
|
2038 |
- */ |
|
2039 |
- private function handleLogSearchParamsString(): string |
|
2040 |
- { |
|
2041 |
- if (!isset($this->search_params['string']) || (!empty($_REQUEST['search']) && $this->search_params['string'] != $_REQUEST['search'])) |
|
2042 |
- return empty($_REQUEST['search']) ? '' : $_REQUEST['search']; |
|
2043 |
- else |
|
2044 |
- return $this->search_params['string']; |
|
2045 |
- } |
|
2046 |
- |
|
2047 |
- /** |
|
2048 |
- * Handle Search Params Type |
|
2049 |
- * |
|
2050 |
- * @internal |
|
2051 |
- * @CalledIn SMF 2.0, SMF 2.1 |
|
2052 |
- * @version 1.1 |
|
2053 |
- * @since 1.0 |
|
2054 |
- * @return string What we are searching for, validated and cleaned. |
|
2055 |
- */ |
|
2056 |
- private function handleLogSearchParamsType(): string |
|
2057 |
- { |
|
2058 |
- global $context; |
|
2059 |
- |
|
2060 |
- if (isset($_REQUEST['search_type']) || empty($this->search_params['type']) || !isset($searchTypes[$this->search_params['type']])) |
|
2061 |
- return isset($_REQUEST['search_type']) && isset($this->search_types[$_REQUEST['search_type']]) ? $_REQUEST['search_type'] : (isset($this->search_types[$context['order']]) ? $context['order'] : 'member'); |
|
2062 |
- else |
|
2063 |
- return $this->search_params['type']; |
|
2064 |
- } |
|
2065 |
- |
|
2066 | 982 |
/** |
2067 | 983 |
* Create a Ban Group if needed to handle automatic IP bans. |
2068 | 984 |
* We attempt to use the known ban function to create bans, otherwise we just fall back to a standard insert. |
... | ... |
@@ -2073,7 +989,7 @@ class SFS |
2073 | 989 |
* @since 1.0 |
2074 | 990 |
* @return bool True upon success, false otherwise. |
2075 | 991 |
*/ |
2076 |
- private function createBanGroup(bool $noChecks = false): bool |
|
992 |
+ public function createBanGroup(bool $noChecks = false): bool |
|
2077 | 993 |
{ |
2078 | 994 |
global $smcFunc, $modSettings, $sourcedir, $txt; |
2079 | 995 |
|
... | ... |
@@ -2294,4 +1210,21 @@ class SFS |
2294 | 1210 |
|
2295 | 1211 |
return true; |
2296 | 1212 |
} |
1213 |
+ |
|
1214 |
+ /** |
|
1215 |
+ * Get some data |
|
1216 |
+ * |
|
1217 |
+ * @param string $variable The data we are looking for.. |
|
1218 |
+ * |
|
1219 |
+ * @internal |
|
1220 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
1221 |
+ * @version 1.1 |
|
1222 |
+ * @since 1.0 |
|
1223 |
+ * @return bool True upon success, false otherwise. |
|
1224 |
+ */ |
|
1225 |
+ public function get(string $variable) |
|
1226 |
+ { |
|
1227 |
+ if (in_array($variable, array('softwareName', 'softwareVersion'))) |
|
1228 |
+ return $this->{$variable}; |
|
1229 |
+ } |
|
2297 | 1230 |
} |
2298 | 1231 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,1136 @@ |
1 |
+<?php |
|
2 |
+ |
|
3 |
+/** |
|
4 |
+ * The Admin class for Stop Forum Spam |
|
5 |
+ * @package StopForumSpam |
|
6 |
+ * @author SleePy <sleepy @ simplemachines (dot) org> |
|
7 |
+ * @copyright 2019 |
|
8 |
+ * @license 3-Clause BSD https://opensource.org/licenses/BSD-3-Clause |
|
9 |
+ * @version 1.0.1 |
|
10 |
+ */ |
|
11 |
+class SFSA |
|
12 |
+{ |
|
13 |
+ public static $SFSAclass = null; |
|
14 |
+ private $SFSclass = null; |
|
15 |
+ |
|
16 |
+ /** |
|
17 |
+ * @var string URLS we need to SFS for UI presentation. |
|
18 |
+ */ |
|
19 |
+ private $urlSFSipCheck = 'https://www.stopforumspam.com/ipcheck/%1$s'; |
|
20 |
+ private $urlSFSsearch = 'https://www.stopforumspam.com/search/%1$s'; |
|
21 |
+ |
|
22 |
+ /** |
|
23 |
+ * @var string The URL for the admin page. |
|
24 |
+ */ |
|
25 |
+ private $adminPageURL = null; |
|
26 |
+ private $adminLogURL = null; |
|
27 |
+ |
|
28 |
+ /** |
|
29 |
+ * @var array Our settings information used on saving/changing settings. |
|
30 |
+ */ |
|
31 |
+ private $changedSettings = array(); |
|
32 |
+ private $extraVerificationOptions = array(); |
|
33 |
+ |
|
34 |
+ /** |
|
35 |
+ * @var mixed Search area handling. |
|
36 |
+ */ |
|
37 |
+ private $search_types = array(); |
|
38 |
+ private $search_params = array(); |
|
39 |
+ private $search_params_column = ''; |
|
40 |
+ private $search_params_string = null; |
|
41 |
+ private $search_params_type = null; |
|
42 |
+ private $canDeleteLogs = false; |
|
43 |
+ private $logSearch = array(); |
|
44 |
+ |
|
45 |
+ /** |
|
46 |
+ * @var int How long we disable removing logs. |
|
47 |
+ */ |
|
48 |
+ private $hoursDisabled = 24; |
|
49 |
+ |
|
50 |
+ /** |
|
51 |
+ * Creates a self reference to the ASL class for use later. |
|
52 |
+ * |
|
53 |
+ * @version 1.0 |
|
54 |
+ * @since 1.0 |
|
55 |
+ * @return void No return is generated |
|
56 |
+ */ |
|
57 |
+ public static function selfClass() |
|
58 |
+ { |
|
59 |
+ global $smcFunc; |
|
60 |
+ |
|
61 |
+ if (is_null(self::$SFSAclass)) |
|
62 |
+ { |
|
63 |
+ self::$SFSAclass = new SFSA(); |
|
64 |
+ $smcFunc['SFSA'] = self::$SFSAclass; |
|
65 |
+ } |
|
66 |
+ |
|
67 |
+ return self::$SFSAclass; |
|
68 |
+ } |
|
69 |
+ |
|
70 |
+ /** |
|
71 |
+ * Build the class, figure out what software/version we have. |
|
72 |
+ * Loads up the defaults. |
|
73 |
+ * |
|
74 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
75 |
+ * @version 1.0 |
|
76 |
+ * @since 1.0 |
|
77 |
+ * @return void No return is generated |
|
78 |
+ */ |
|
79 |
+ public function __construct() |
|
80 |
+ { |
|
81 |
+ global $smcFunc; |
|
82 |
+ |
|
83 |
+ $this->SFSclass = &$smcFunc['classSFS']; |
|
84 |
+ |
|
85 |
+ // Is this SMF 2.0? |
|
86 |
+ $this->softwareVersion = $smcFunc['classSFS']->get('softwareVersion'); |
|
87 |
+ } |
|
88 |
+ |
|
89 |
+ /** |
|
90 |
+ * Creates the hook to the class for the admin areas. |
|
91 |
+ * |
|
92 |
+ * @param array $admin_areas A associate array from the software with all valid admin areas. |
|
93 |
+ * |
|
94 |
+ * @api |
|
95 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
96 |
+ * @see SFSA::setupAdminAreas() |
|
97 |
+ * @version 1.0 |
|
98 |
+ * @since 1.0 |
|
99 |
+ * @uses integrate__admin_areas - Hook SMF2.0 |
|
100 |
+ * @uses integrate__admin_areas - Hook SMF2.1 |
|
101 |
+ * @return void No return is generated |
|
102 |
+ */ |
|
103 |
+ public static function hook_admin_areas(array &$admin_areas) |
|
104 |
+ { |
|
105 |
+ return self::selfClass()->setupAdminAreas($admin_areas); |
|
106 |
+ } |
|
107 |
+ |
|
108 |
+ /** |
|
109 |
+ * Startup the Admin Panels Additions. |
|
110 |
+ * Where things appear are based on what software/version you have. |
|
111 |
+ * |
|
112 |
+ * @param array $admin_areas A associate array from the software with all valid admin areas. |
|
113 |
+ * |
|
114 |
+ * @internal |
|
115 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
116 |
+ * @version 1.0 |
|
117 |
+ * @since 1.0 |
|
118 |
+ * @uses integrate__admin_areas - Hook SMF2.0 |
|
119 |
+ * @uses integrate__admin_areas - Hook SMF2.1 |
|
120 |
+ * @return void No return is generated |
|
121 |
+ */ |
|
122 |
+ private function setupAdminAreas(array &$admin_areas): void |
|
123 |
+ { |
|
124 |
+ global $scripturl; |
|
125 |
+ |
|
126 |
+ // Add the menu item. |
|
127 |
+ if ($this->SFSclass->versionCheck('2.0', 'smf')) |
|
128 |
+ { |
|
129 |
+ $this->adminPageURL = $scripturl . '?action=admin;area=modsettings;sa=sfs'; |
|
130 |
+ $this->adminLogURL = $scripturl . '?action=admin;area=modsettings;sa=sfslog'; |
|
131 |
+ |
|
132 |
+ $admin_areas['config']['areas']['modsettings']['subsections']['sfs'] = array( |
|
133 |
+ $this->SFSclass->txt('sfs_admin_area') |
|
134 |
+ ); |
|
135 |
+ $admin_areas['config']['areas']['modsettings']['subsections']['sfslog'] = array( |
|
136 |
+ $this->SFSclass->txt('sfs_admin_logs') |
|
137 |
+ ); |
|
138 |
+ } |
|
139 |
+ else |
|
140 |
+ { |
|
141 |
+ $this->adminPageURL = $scripturl . '?action=admin;area=securitysettings;sa=sfs'; |
|
142 |
+ $this->adminLogURL = $scripturl . '?action=admin;area=logs;sa=sfslog'; |
|
143 |
+ |
|
144 |
+ $admin_areas['config']['areas']['securitysettings']['subsections']['sfs'] = array( |
|
145 |
+ $this->SFSclass->txt('sfs_admin_area') |
|
146 |
+ ); |
|
147 |
+ $admin_areas['config']['areas']['securitysettings']['subsections']['sfslog'] = array( |
|
148 |
+ $this->SFSclass->txt('sfs_admin_logs') |
|
149 |
+ ); |
|
150 |
+ } |
|
151 |
+ } |
|
152 |
+ |
|
153 |
+ /** |
|
154 |
+ * Setup the Modification's setup page. |
|
155 |
+ * For some versions, we put the logs into the modifications sections, its easier. |
|
156 |
+ * |
|
157 |
+ * @param array $subActions A associate array from the software with all valid modification sections. |
|
158 |
+ * |
|
159 |
+ * @api |
|
160 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
161 |
+ * @see SFSA::setupModifyModifications() |
|
162 |
+ * @version 1.0 |
|
163 |
+ * @since 1.0 |
|
164 |
+ * @uses integrate_modify_modifications - Hook SMF2.0 |
|
165 |
+ * @uses integrate_modify_modifications - Hook SMF2.1 |
|
166 |
+ * @return void No return is generated |
|
167 |
+ */ |
|
168 |
+ public static function hook_modify_modifications(array &$subActions) |
|
169 |
+ { |
|
170 |
+ return self::selfClass()->setupModifyModifications($subActions); |
|
171 |
+ } |
|
172 |
+ |
|
173 |
+ /** |
|
174 |
+ * Setup the Modifications section links. |
|
175 |
+ * For some versions we add the logs here as well. |
|
176 |
+ * |
|
177 |
+ * @param array $subActions A associate array from the software with all valid modification sections. |
|
178 |
+ * |
|
179 |
+ * @internal |
|
180 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
181 |
+ * @version 1.0 |
|
182 |
+ * @since 1.0 |
|
183 |
+ * @uses integrate_modify_modifications - Hook SMF2.0 |
|
184 |
+ * @uses integrate_modify_modifications - Hook SMF2.1 |
|
185 |
+ * @return void No return is generated |
|
186 |
+ */ |
|
187 |
+ private function setupModifyModifications(array &$subActions): void |
|
188 |
+ { |
|
189 |
+ $subActions['sfs'] = 'SFSA::startupAdminConfiguration'; |
|
190 |
+ |
|
191 |
+ // Only in SMF 2.0 do we drop logs here. |
|
192 |
+ if ($this->SFSclass->versionCheck('2.0', 'smf')) |
|
193 |
+ $subActions['sfslog'] = 'SFSA::startupLogs'; |
|
194 |
+ } |
|
195 |
+ |
|
196 |
+ /** |
|
197 |
+ * The configuration caller. |
|
198 |
+ * |
|
199 |
+ * @param bool $return_config If true, returns the configuration options for searches. |
|
200 |
+ * |
|
201 |
+ * @api |
|
202 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
203 |
+ * @see SFSA::setupSFSConfiguration |
|
204 |
+ * @version 1.0 |
|
205 |
+ * @since 1.0 |
|
206 |
+ * @uses integrate_modify_modifications - Hook SMF2.0 |
|
207 |
+ * @uses integrate_modify_modifications - Hook SMF2.1 |
|
208 |
+ * @return void No return is generated |
|
209 |
+ */ |
|
210 |
+ public static function startupAdminConfiguration(bool $return_config = false) |
|
211 |
+ { |
|
212 |
+ return self::selfClass()->setupSFSConfiguration($return_config); |
|
213 |
+ } |
|
214 |
+ |
|
215 |
+ /** |
|
216 |
+ * The actual settings page. |
|
217 |
+ * |
|
218 |
+ * @param bool $return_config If true, returns the configuration options for searches. |
|
219 |
+ * |
|
220 |
+ * @internal |
|
221 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
222 |
+ * @version 1.0 |
|
223 |
+ * @since 1.0 |
|
224 |
+ * @uses integrate_modify_modifications - Hook SMF2.0 |
|
225 |
+ * @uses integrate_modify_modifications - Hook SMF2.1 |
|
226 |
+ * @return void No return is generated |
|
227 |
+ */ |
|
228 |
+ private function setupSFSConfiguration(bool $return_config = false): array |
|
229 |
+ { |
|
230 |
+ global $scripturl, $context, $settings, $sc, $modSettings; |
|
231 |
+ |
|
232 |
+ $config_vars = array( |
|
233 |
+ array('title', 'sfsgentitle', 'label' => $this->SFSclass->txt('sfs_general_title')), |
|
234 |
+ |
|
235 |
+ array('check', 'sfs_enabled'), |
|
236 |
+ array('int', 'sfs_expire'), |
|
237 |
+ '', |
|
238 |
+ array('check', 'sfs_emailcheck'), |
|
239 |
+ '', |
|
240 |
+ array('check', 'sfs_usernamecheck'), |
|
241 |
+ array('float', 'sfs_username_confidence'), |
|
242 |
+ '', |
|
243 |
+ array('check', 'sfs_ipcheck'), |
|
244 |
+ array('check', 'sfs_ipcheck_autoban'), |
|
245 |
+ '', |
|
246 |
+ array('select', 'sfs_region', $this->SFSclass->sfsServerMapping('config')), |
|
247 |
+ '', |
|
248 |
+ array('check', 'sfs_wildcard_email'), |
|
249 |
+ array('check', 'sfs_wildcard_username'), |
|
250 |
+ array('check', 'sfs_wildcard_ip'), |
|
251 |
+ '', |
|
252 |
+ array('select', 'sfs_tor_check', array( |
|
253 |
+ 0 => $this->SFSclass->txt('sfs_tor_check_block'), |
|
254 |
+ 1 => $this->SFSclass->txt('sfs_tor_check_ignore'), |
|
255 |
+ 2 => $this->SFSclass->txt('sfs_tor_check_bad'), |
|
256 |
+ )), |
|
257 |
+ |
|
258 |
+ '', |
|
259 |
+ array('title', 'sfsverftitle', 'label' => $this->SFSclass->txt('sfs_verification_title')), |
|
260 |
+ array('desc', 'sfsverfdesc', 'label' => $this->SFSclass->txt('sfs_verification_desc')), |
|
261 |
+ array('select', 'sfs_verification_options', array( |
|
262 |
+ 'post' => $this->SFSclass->txt('sfs_verification_options_post'), |
|
263 |
+ 'report' => $this->SFSclass->txt('sfs_verification_options_report'), |
|
264 |
+ 'search' => $this->SFSclass->txt('sfs_verification_options_search'), |
|
265 |
+ ), 'multiple' => true), |
|
266 |
+ array('text', 'sfs_verification_options_extra', 'subtext' => $this->SFSclass->txt('sfs_verification_options_extra_subtext')), |
|
267 |
+ |
|
268 |
+ '', |
|
269 |
+ array('select', 'sfs_verOptionsMembers', array( |
|
270 |
+ 'post' => $this->SFSclass->txt('sfs_verification_options_post'), |
|
271 |
+ 'search' => $this->SFSclass->txt('sfs_verification_options_search'), |
|
272 |
+ ), 'multiple' => true), |
|
273 |
+ array('text', 'sfs_verOptionsMemExtra', 'subtext' => $this->SFSclass->txt('sfs_verification_options_extra_subtext')), |
|
274 |
+ array('int', 'sfs_verfOptMemPostThreshold'), |
|
275 |
+ '', |
|
276 |
+ array('check', 'sfs_log_debug'), |
|
277 |
+ ); |
|
278 |
+ |
|
279 |
+ if ($return_config) |
|
280 |
+ return $config_vars; |
|
281 |
+ |
|
282 |
+ // Saving? |
|
283 |
+ if (isset($_GET['save'])) |
|
284 |
+ { |
|
285 |
+ // Turn the defaults off. |
|
286 |
+ $this->unloadDefaults(); |
|
287 |
+ checkSession(); |
|
288 |
+ |
|
289 |
+ // If we are automatically banning IPs, make sure we have a ban group. |
|
290 |
+ if (isset($_POST['sfs_ipcheck_autoban']) && empty($modSettings['sfs_ipcheck_autoban_group'])) |
|
291 |
+ $this->SFSclass->createBanGroup(true); |
|
292 |
+ |
|
293 |
+ saveDBSettings($config_vars); |
|
294 |
+ |
|
295 |
+ writeLog(); |
|
296 |
+ redirectexit($this->adminPageURL); |
|
297 |
+ } |
|
298 |
+ |
|
299 |
+ $context['post_url'] = $this->adminPageURL . ';save'; |
|
300 |
+ |
|
301 |
+ prepareDBSettingContext($config_vars); |
|
302 |
+ |
|
303 |
+ return array(); |
|
304 |
+ } |
|
305 |
+ |
|
306 |
+ /** |
|
307 |
+ * In some software/versions, we can hook into the logs section. |
|
308 |
+ * In others we hook into the modifications settings. |
|
309 |
+ * |
|
310 |
+ * @param array $log_functions All possible log functions. |
|
311 |
+ * |
|
312 |
+ * @api |
|
313 |
+ * @CalledIn SMF 2.1 |
|
314 |
+ * @See SFSA::startupLogs |
|
315 |
+ * @version 1.0 |
|
316 |
+ * @since 1.0 |
|
317 |
+ * @uses integrate_manage_logs - Hook SMF2.1 |
|
318 |
+ * @return void No return is generated |
|
319 |
+ */ |
|
320 |
+ public static function hook_manage_logs(array &$log_functions): bool |
|
321 |
+ { |
|
322 |
+ // Add our logs sub action. |
|
323 |
+ $log_functions['sfslog'] = array('StopForumSpam.php', 'startupLogs'); |
|
324 |
+ |
|
325 |
+ return self::selfClass()->AddToLogMenu($log_functions); |
|
326 |
+ } |
|
327 |
+ |
|
328 |
+ /** |
|
329 |
+ * Add the SFS logs to the log menu. |
|
330 |
+ * |
|
331 |
+ * @param array $log_functions All possible log functions. |
|
332 |
+ * |
|
333 |
+ * @CalledIn SMF 2.1 |
|
334 |
+ * @See SFSA::startupLogs |
|
335 |
+ * @version 1.1 |
|
336 |
+ * @since 1.1 |
|
337 |
+ * @return void No return is generated |
|
338 |
+ */ |
|
339 |
+ public function AddToLogMenu(array &$log_functions): bool |
|
340 |
+ { |
|
341 |
+ global $context; |
|
342 |
+ |
|
343 |
+ $context[$context['admin_menu_name']]['tab_data']['tabs']['sfslog'] = array( |
|
344 |
+ 'description' => $this->SFSclass->txt('sfs_admin_logs'), |
|
345 |
+ ); |
|
346 |
+ |
|
347 |
+ return true; |
|
348 |
+ } |
|
349 |
+ |
|
350 |
+ /** |
|
351 |
+ * Log startup caller. |
|
352 |
+ * This has a $return_config just for simply complying with properly for searching the admin panel. |
|
353 |
+ * |
|
354 |
+ * @param bool $return_config If true, returns empty array to prevent breaking old SMF installs. |
|
355 |
+ * |
|
356 |
+ * @api |
|
357 |
+ * @CalledIn SMF 2.1 |
|
358 |
+ * @See SFSA::loadLogs |
|
359 |
+ * @version 1.0 |
|
360 |
+ * @since 1.0 |
|
361 |
+ * @uses hook_manage_logs - Hook SMF2.1 |
|
362 |
+ * @uses setupModifyModifications - Injected SMF2.0 |
|
363 |
+ * @return void No return is generated |
|
364 |
+ */ |
|
365 |
+ public static function startupLogs(bool $return_config = false): array |
|
366 |
+ { |
|
367 |
+ return self::selfClass()->loadLogs(); |
|
368 |
+ } |
|
369 |
+ |
|
370 |
+ /** |
|
371 |
+ * Actually show the logs. |
|
372 |
+ * This has a $return_config just for simply complying with properly for searching the admin panel. |
|
373 |
+ * |
|
374 |
+ * @param bool $return_config If true, returns empty array to prevent breaking old SMF installs. |
|
375 |
+ * |
|
376 |
+ * @api |
|
377 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
378 |
+ * @See SFSA::getSFSLogEntries |
|
379 |
+ * @See SFSA::getSFSLogEntriesCount |
|
380 |
+ * @version 1.0 |
|
381 |
+ * @since 1.0 |
|
382 |
+ * @uses hook_manage_logs - Hook SMF2.1 |
|
383 |
+ * @uses setupModifyModifications - Injected SMF2.0 |
|
384 |
+ * @return void No return is generated |
|
385 |
+ */ |
|
386 |
+ public function loadLogs(bool $return_config = false): array |
|
387 |
+ { |
|
388 |
+ global $context, $smcFunc, $sourcedir; |
|
389 |
+ |
|
390 |
+ // No Configs. |
|
391 |
+ if ($return_config) |
|
392 |
+ return array(); |
|
393 |
+ |
|
394 |
+ loadLanguage('Modlog'); |
|
395 |
+ |
|
396 |
+ $context['form_url'] = $this->adminLogURL; |
|
397 |
+ $context['log_url'] = $this->adminLogURL; |
|
398 |
+ $context['page_title'] = $this->SFSclass->txt('sfs_admin_logs'); |
|
399 |
+ $this->canDeleteLogs = allowedTo('admin_forum'); |
|
400 |
+ |
|
401 |
+ // Remove all.. |
|
402 |
+ if ((isset($_POST['removeall']) || isset($_POST['delete'])) && $this->canDeleteLogs) |
|
403 |
+ $this->handleLogDeletes(); |
|
404 |
+ |
|
405 |
+ $sort_types = array( |
|
406 |
+ 'id_type' =>'l.id_type', |
|
407 |
+ 'log_time' => 'l.log_time', |
|
408 |
+ 'url' => 'l.url', |
|
409 |
+ 'member' => 'mem.id_member', |
|
410 |
+ 'username' => 'l.username', |
|
411 |
+ 'email' => 'l.email', |
|
412 |
+ 'ip' => 'l.ip', |
|
413 |
+ 'ip2' => 'l.ip2', |
|
414 |
+ ); |
|
415 |
+ |
|
416 |
+ $context['order'] = isset($_REQUEST['sort']) && isset($sort_types[$_REQUEST['sort']]) ? $_REQUEST['sort'] : 'time'; |
|
417 |
+ |
|
418 |
+ // Handle searches. |
|
419 |
+ $this->handleLogSearch($context['log_url']); |
|
420 |
+ |
|
421 |
+ require_once($sourcedir . '/Subs-List.php'); |
|
422 |
+ |
|
423 |
+ $listOptions = array( |
|
424 |
+ 'id' => 'sfslog_list', |
|
425 |
+ 'title' => $this->SFSclass->txt('sfs_admin_logs'), |
|
426 |
+ 'width' => '100%', |
|
427 |
+ 'items_per_page' => '50', |
|
428 |
+ 'no_items_label' => $this->SFSclass->txt('sfs_log_no_entries_found'), |
|
429 |
+ 'base_href' => $context['log_url'], |
|
430 |
+ 'default_sort_col' => 'time', |
|
431 |
+ 'get_items' => $this->loadLogsGetItems(), |
|
432 |
+ 'get_count' => $this->loadLogsGetCount(), |
|
433 |
+ // This assumes we are viewing by user. |
|
434 |
+ 'columns' => array( |
|
435 |
+ 'type' => $this->loadLogsColumnType(), |
|
436 |
+ 'time' => $this->loadLogsColumnTime(), |
|
437 |
+ 'url' => $this->loadLogsColumnURL(), |
|
438 |
+ 'member' => $this->loadLogsColumnMember(), |
|
439 |
+ 'username' => $this->loadLogsColumnUsername(), |
|
440 |
+ 'email' => $this->loadLogsColumnEmail(), |
|
441 |
+ 'ip' => $this->loadLogsColumnIP(), |
|
442 |
+ 'ip2' => $this->loadLogsColumnIP(true), |
|
443 |
+ 'checks' => $this->loadLogsColumnChecks(), |
|
444 |
+ 'result' => $this->loadLogsColumnResult(), |
|
445 |
+ 'delete' => $this->loadLogsColumnDelete(), |
|
446 |
+ ), |
|
447 |
+ 'form' => array( |
|
448 |
+ 'href' => $context['form_url'], |
|
449 |
+ 'include_sort' => true, |
|
450 |
+ 'include_start' => true, |
|
451 |
+ 'hidden_fields' => array( |
|
452 |
+ $context['session_var'] => $context['session_id'], |
|
453 |
+ 'params' => $this->search_params |
|
454 |
+ ), |
|
455 |
+ ), |
|
456 |
+ 'additional_rows' => array( |
|
457 |
+ $this->loadLogsGetAddtionalRow(), |
|
458 |
+ ), |
|
459 |
+ ); |
|
460 |
+ |
|
461 |
+ // Create the watched user list. |
|
462 |
+ createList($listOptions); |
|
463 |
+ |
|
464 |
+ $context['sub_template'] = 'show_list'; |
|
465 |
+ $context['default_list'] = 'sfslog_list'; |
|
466 |
+ |
|
467 |
+ return array(); |
|
468 |
+ } |
|
469 |
+ |
|
470 |
+ /** |
|
471 |
+ * Handle when we want to delete a log and what to do. |
|
472 |
+ * |
|
473 |
+ * @internal |
|
474 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
475 |
+ * @version 1.1 |
|
476 |
+ * @since 1.1 |
|
477 |
+ * @return void Nothing is returned, the logs are deleted as requested and admin redirected. |
|
478 |
+ */ |
|
479 |
+ private function handleLogDeletes(): void |
|
480 |
+ { |
|
481 |
+ if (isset($_POST['removeall']) && $this->canDeleteLogs) |
|
482 |
+ $this->removeAllLogs(); |
|
483 |
+ elseif (!empty($_POST['remove']) && isset($_POST['delete']) && $this->canDeleteLogs) |
|
484 |
+ $this->removeLogs(array_unique($_POST['delete'])); |
|
485 |
+ } |
|
486 |
+ |
|
487 |
+ /** |
|
488 |
+ * loadLogs - Get Items. |
|
489 |
+ * |
|
490 |
+ * @internal |
|
491 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
492 |
+ * @version 1.1 |
|
493 |
+ * @since 1.1 |
|
494 |
+ * @return array The options for the get_items |
|
495 |
+ */ |
|
496 |
+ private function loadLogsGetItems(): array |
|
497 |
+ { |
|
498 |
+ return array( |
|
499 |
+ 'function' => array($this, 'getSFSLogEntries'), |
|
500 |
+ 'params' => array( |
|
501 |
+ (!empty($this->logSearch['string']) ? ' INSTR({raw:sql_type}, {string:search_string})' : ''), |
|
502 |
+ array('sql_type' => $this->search_params_column, 'search_string' => $this->logSearch['string']), |
|
503 |
+ ), |
|
504 |
+ ); |
|
505 |
+ } |
|
506 |
+ |
|
507 |
+ /** |
|
508 |
+ * loadLogs - Get Count. |
|
509 |
+ * |
|
510 |
+ * @internal |
|
511 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
512 |
+ * @version 1.1 |
|
513 |
+ * @since 1.1 |
|
514 |
+ * @return array The options for the get_items |
|
515 |
+ */ |
|
516 |
+ private function loadLogsGetCount(): array |
|
517 |
+ { |
|
518 |
+ return array( |
|
519 |
+ 'function' => array($this, 'getSFSLogEntriesCount'), |
|
520 |
+ 'params' => array( |
|
521 |
+ (!empty($this->logSearch['string']) ? ' INSTR({raw:sql_type}, {string:search_string})' : ''), |
|
522 |
+ array('sql_type' => $this->search_params_column, 'search_string' => $this->logSearch['string']), |
|
523 |
+ ), |
|
524 |
+ ); |
|
525 |
+ } |
|
526 |
+ |
|
527 |
+ /** |
|
528 |
+ * loadLogs - Load an additional row, for mostly deleting stuff. |
|
529 |
+ * |
|
530 |
+ * @internal |
|
531 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
532 |
+ * @version 1.1 |
|
533 |
+ * @since 1.1 |
|
534 |
+ * @return array The options for the get_items |
|
535 |
+ */ |
|
536 |
+ private function loadLogsGetAddtionalRow(): array |
|
537 |
+ { |
|
538 |
+ global $smcFunc; |
|
539 |
+ |
|
540 |
+ return array( |
|
541 |
+ 'position' => 'below_table_data', |
|
542 |
+ 'value' => ' |
|
543 |
+ ' . $this->SFSclass->txt('sfs_log_search') . ' (' . $this->logSearch['label'] . '): |
|
544 |
+ <input type="text" name="search" size="18" value="' . $smcFunc['htmlspecialchars']($this->logSearch['string']) . '" class="input_text" /> <input type="submit" name="is_search" value="' . $this->SFSclass->txt('modlog_go') . '" class="button_submit" /> |
|
545 |
+ ' . ($this->canDeleteLogs ? ' | |
|
546 |
+ <input type="submit" name="remove" value="' . $this->SFSclass->txt('modlog_remove') . '" class="button_submit" /> |
|
547 |
+ <input type="submit" name="removeall" value="' . $this->SFSclass->txt('modlog_removeall') . '" class="button_submit" />' : ''), |
|
548 |
+ ); |
|
549 |
+ } |
|
550 |
+ |
|
551 |
+ |
|
552 |
+ /** |
|
553 |
+ * loadLogs - Column - Type. |
|
554 |
+ * |
|
555 |
+ * @internal |
|
556 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
557 |
+ * @version 1.1 |
|
558 |
+ * @since 1.1 |
|
559 |
+ * @return array The options for the column |
|
560 |
+ */ |
|
561 |
+ private function loadLogsColumnType(): array |
|
562 |
+ { |
|
563 |
+ return array( |
|
564 |
+ 'header' => array( |
|
565 |
+ 'value' => $this->SFSclass->txt('sfs_log_header_type'), |
|
566 |
+ 'class' => 'lefttext', |
|
567 |
+ ), |
|
568 |
+ 'data' => array( |
|
569 |
+ 'db' => 'type', |
|
570 |
+ 'class' => 'smalltext', |
|
571 |
+ ), |
|
572 |
+ 'sort' => array( |
|
573 |
+ ), |
|
574 |
+ ); |
|
575 |
+ } |
|
576 |
+ |
|
577 |
+ /** |
|
578 |
+ * loadLogs - Column - Time. |
|
579 |
+ * |
|
580 |
+ * @internal |
|
581 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
582 |
+ * @version 1.1 |
|
583 |
+ * @since 1.1 |
|
584 |
+ * @return array The options for the column |
|
585 |
+ */ |
|
586 |
+ private function loadLogsColumnTime(): array |
|
587 |
+ { |
|
588 |
+ return array( |
|
589 |
+ 'header' => array( |
|
590 |
+ 'value' => $this->SFSclass->txt('sfs_log_header_time'), |
|
591 |
+ 'class' => 'lefttext', |
|
592 |
+ ), |
|
593 |
+ 'data' => array( |
|
594 |
+ 'db' => 'time', |
|
595 |
+ 'class' => 'smalltext', |
|
596 |
+ ), |
|
597 |
+ 'sort' => array( |
|
598 |
+ 'default' => 'l.log_time DESC', |
|
599 |
+ 'reverse' => 'l.log_time', |
|
600 |
+ ), |
|
601 |
+ ); |
|
602 |
+ } |
|
603 |
+ |
|
604 |
+ /** |
|
605 |
+ * loadLogs - Column - URL. |
|
606 |
+ * |
|
607 |
+ * @internal |
|
608 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
609 |
+ * @version 1.1 |
|
610 |
+ * @since 1.1 |
|
611 |
+ * @return array The options for the column |
|
612 |
+ */ |
|
613 |
+ private function loadLogsColumnURL(): array |
|
614 |
+ { |
|
615 |
+ return array( |
|
616 |
+ 'header' => array( |
|
617 |
+ 'value' => $this->SFSclass->txt('sfs_log_header_url'), |
|
618 |
+ 'class' => 'lefttext', |
|
619 |
+ ), |
|
620 |
+ 'data' => array( |
|
621 |
+ 'db' => 'url', |
|
622 |
+ 'class' => 'smalltext', |
|
623 |
+ 'style' => 'word-break: break-word;', |
|
624 |
+ ), |
|
625 |
+ 'sort' => array( |
|
626 |
+ 'default' => 'l.url DESC', |
|
627 |
+ 'reverse' => 'l.url', |
|
628 |
+ ), |
|
629 |
+ ); |
|
630 |
+ } |
|
631 |
+ |
|
632 |
+ /** |
|
633 |
+ * loadLogs - Column - Member. |
|
634 |
+ * |
|
635 |
+ * @internal |
|
636 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
637 |
+ * @version 1.1 |
|
638 |
+ * @since 1.1 |
|
639 |
+ * @return array The options for the column |
|
640 |
+ */ |
|
641 |
+ private function loadLogsColumnMember(): array |
|
642 |
+ { |
|
643 |
+ return array( |
|
644 |
+ 'header' => array( |
|
645 |
+ 'value' => $this->SFSclass->txt('sfs_log_header_member'), |
|
646 |
+ 'class' => 'lefttext', |
|
647 |
+ ), |
|
648 |
+ 'data' => array( |
|
649 |
+ 'db' => 'member_link', |
|
650 |
+ 'class' => 'smalltext', |
|
651 |
+ ), |
|
652 |
+ 'sort' => array( |
|
653 |
+ 'default' => 'mem.id_member', |
|
654 |
+ 'reverse' => 'mem.id_member DESC', |
|
655 |
+ ), |
|
656 |
+ ); |
|
657 |
+ } |
|
658 |
+ |
|
659 |
+ /** |
|
660 |
+ * loadLogs - Column - Username. |
|
661 |
+ * |
|
662 |
+ * @internal |
|
663 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
664 |
+ * @version 1.1 |
|
665 |
+ * @since 1.1 |
|
666 |
+ * @return array The options for the column |
|
667 |
+ */ |
|
668 |
+ private function loadLogsColumnUsername(): array |
|
669 |
+ { |
|
670 |
+ return array( |
|
671 |
+ 'header' => array( |
|
672 |
+ 'value' => $this->SFSclass->txt('sfs_log_header_username'), |
|
673 |
+ 'class' => 'lefttext', |
|
674 |
+ ), |
|
675 |
+ 'data' => array( |
|
676 |
+ 'db' => 'username', |
|
677 |
+ 'class' => 'smalltext', |
|
678 |
+ ), |
|
679 |
+ 'sort' => array( |
|
680 |
+ 'default' => 'l.username', |
|
681 |
+ 'reverse' => 'l.username DESC', |
|
682 |
+ ), |
|
683 |
+ ); |
|
684 |
+ } |
|
685 |
+ |
|
686 |
+ /** |
|
687 |
+ * loadLogs - Column - Email. |
|
688 |
+ * |
|
689 |
+ * @internal |
|
690 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
691 |
+ * @version 1.1 |
|
692 |
+ * @since 1.1 |
|
693 |
+ * @return array The options for the column |
|
694 |
+ */ |
|
695 |
+ private function loadLogsColumnEmail(): array |
|
696 |
+ { |
|
697 |
+ return array( |
|
698 |
+ 'header' => array( |
|
699 |
+ 'value' => $this->SFSclass->txt('sfs_log_header_email'), |
|
700 |
+ 'class' => 'lefttext', |
|
701 |
+ ), |
|
702 |
+ 'data' => array( |
|
703 |
+ 'db' => 'email', |
|
704 |
+ 'class' => 'smalltext', |
|
705 |
+ ), |
|
706 |
+ 'sort' => array( |
|
707 |
+ 'default' => 'l.email', |
|
708 |
+ 'reverse' => 'l.email DESC', |
|
709 |
+ ), |
|
710 |
+ ); |
|
711 |
+ } |
|
712 |
+ |
|
713 |
+ /** |
|
714 |
+ * loadLogs - Column - IP. |
|
715 |
+ * |
|
716 |
+ * @param string $ip2 If true, use ip2 |
|
717 |
+ * @internal |
|
718 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
719 |
+ * @version 1.1 |
|
720 |
+ * @since 1.1 |
|
721 |
+ * @return array The options for the column |
|
722 |
+ */ |
|
723 |
+ private function loadLogsColumnIP(bool $ip2 = false): array |
|
724 |
+ { |
|
725 |
+ return array( |
|
726 |
+ 'header' => array( |
|
727 |
+ 'value' => $this->SFSclass->txt('sfs_log_header_ip' . ($ip2 ? '2' : '')), |
|
728 |
+ 'class' => 'lefttext', |
|
729 |
+ ), |
|
730 |
+ 'data' => array( |
|
731 |
+ 'db' => 'ip' . ($ip2 ? '2' : ''), |
|
732 |
+ 'class' => 'smalltext', |
|
733 |
+ ), |
|
734 |
+ 'sort' => array( |
|
735 |
+ 'default' => 'l.ip' . ($ip2 ? '2' : ''), |
|
736 |
+ 'reverse' => 'l.ip' . ($ip2 ? '2' : '') . ' DESC', |
|
737 |
+ ), |
|
738 |
+ ); |
|
739 |
+ } |
|
740 |
+ |
|
741 |
+ /** |
|
742 |
+ * loadLogs - Column - Checks. |
|
743 |
+ * |
|
744 |
+ * @internal |
|
745 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
746 |
+ * @version 1.1 |
|
747 |
+ * @since 1.1 |
|
748 |
+ * @return array The options for the column |
|
749 |
+ */ |
|
750 |
+ private function loadLogsColumnChecks(): array |
|
751 |
+ { |
|
752 |
+ return array( |
|
753 |
+ 'header' => array( |
|
754 |
+ 'value' => $this->SFSclass->txt('sfs_log_checks'), |
|
755 |
+ 'class' => 'lefttext', |
|
756 |
+ ), |
|
757 |
+ 'data' => array( |
|
758 |
+ 'db' => 'checks', |
|
759 |
+ 'class' => 'smalltext', |
|
760 |
+ 'style' => 'word-break: break-word;', |
|
761 |
+ ), |
|
762 |
+ 'sort' => array(), |
|
763 |
+ ); |
|
764 |
+ } |
|
765 |
+ |
|
766 |
+ /** |
|
767 |
+ * loadLogs - Column - Result. |
|
768 |
+ * |
|
769 |
+ * @internal |
|
770 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
771 |
+ * @version 1.1 |
|
772 |
+ * @since 1.1 |
|
773 |
+ * @return array The options for the column |
|
774 |
+ */ |
|
775 |
+ private function loadLogsColumnResult(): array |
|
776 |
+ { |
|
777 |
+ return array( |
|
778 |
+ 'header' => array( |
|
779 |
+ 'value' => $this->SFSclass->txt('sfs_log_result'), |
|
780 |
+ 'class' => 'lefttext', |
|
781 |
+ ), |
|
782 |
+ 'data' => array( |
|
783 |
+ 'db' => 'result', |
|
784 |
+ 'class' => 'smalltext', |
|
785 |
+ 'style' => 'word-break: break-word;', |
|
786 |
+ ), |
|
787 |
+ 'sort' => array(), |
|
788 |
+ ); |
|
789 |
+ } |
|
790 |
+ |
|
791 |
+ /** |
|
792 |
+ * loadLogs - Column - Delete. |
|
793 |
+ * |
|
794 |
+ * @internal |
|
795 |
+ * @CalledIn SMF2.0, SMF 2.1 |
|
796 |
+ * @version 1.1 |
|
797 |
+ * @since 1.1 |
|
798 |
+ * @return array The options for the column |
|
799 |
+ */ |
|
800 |
+ private function loadLogsColumnDelete(): array |
|
801 |
+ { |
|
802 |
+ return array( |
|
803 |
+ 'header' => array( |
|
804 |
+ 'value' => '<input type="checkbox" name="all" class="input_check" onclick="invertAll(this, this.form);" />', |
|
805 |
+ ), |
|
806 |
+ 'data' => array( |
|
807 |
+ 'function' => function($entry) |
|
808 |
+ { |
|
809 |
+ return '<input type="checkbox" class="input_check" name="delete[]" value="' . $entry['id'] . '"' . ($entry['editable'] ? '' : ' disabled="disabled"') . ' />'; |
|
810 |
+ }, |
|
811 |
+ 'style' => 'text-align: center;', |
|
812 |
+ ), |
|
813 |
+ ); |
|
814 |
+ } |
|
815 |
+ |
|
816 |
+ /** |
|
817 |
+ * Get the log data and returns it ready to go for GenericList handling. |
|
818 |
+ * |
|
819 |
+ * @param int $start The index for where we offset or start at for the list |
|
820 |
+ * @param int $items_per_page How many items we are going to show on this page. |
|
821 |
+ * @param string $sort The column we are sorting by. |
|
822 |
+ * @param string $query_string The search string we are using to filter log data. |
|
823 |
+ * @param array $query_params Extra parameters for searching. |
|
824 |
+ * |
|
825 |
+ * @api |
|
826 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
827 |
+ * @See SFSA::loadLogs |
|
828 |
+ * @version 1.0 |
|
829 |
+ * @since 1.0 |
|
830 |
+ * @uses hook_manage_logs - Hook SMF2.1 |
|
831 |
+ * @uses setupModifyModifications - Injected SMF2.0 |
|
832 |
+ * @return void No return is generated |
|
833 |
+ */ |
|
834 |
+ public function getSFSLogEntries(int $start, int $items_per_page, string $sort, string $query_string = '', array $query_params = array()): array |
|
835 |
+ { |
|
836 |
+ global $scripturl, $context, $smcFunc; |
|
837 |
+ |
|
838 |
+ // Fetch all of our logs. |
|
839 |
+ $result = $smcFunc['db_query']('', ' |
|
840 |
+ SELECT |
|
841 |
+ l.id_sfs, |
|
842 |
+ l.id_type, |
|
843 |
+ l.log_time, |
|
844 |
+ l.url, |
|
845 |
+ l.id_member, |
|
846 |
+ l.username, |
|
847 |
+ l.email, |
|
848 |
+ l.ip, |
|
849 |
+ l.ip2, |
|
850 |
+ l.checks, |
|
851 |
+ l.result, |
|
852 |
+ mem.real_name, |
|
853 |
+ mg.group_name |
|
854 |
+ FROM {db_prefix}log_sfs AS l |
|
855 |
+ LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = l.id_member) |
|
856 |
+ LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_group_id} THEN mem.id_post_group ELSE mem.id_group END) |
|
857 |
+ WHERE id_type IS NOT NULL' |
|
858 |
+ . (!empty($query_string) ? ' |
|
859 |
+ AND ' . $query_string : '') . ' |
|
860 |
+ ORDER BY ' . $sort . ' |
|
861 |
+ LIMIT ' . $start . ', ' . $items_per_page, |
|
862 |
+ array_merge($query_params, array( |
|
863 |
+ 'reg_group_id' => 0, |
|
864 |
+ )) |
|
865 |
+ ); |
|
866 |
+ |
|
867 |
+ $entries = array(); |
|
868 |
+ while ($row = $smcFunc['db_fetch_assoc']($result)) |
|
869 |
+ { |
|
870 |
+ $entries[$row['id_sfs']] = array( |
|
871 |
+ 'id' => $row['id_sfs'], |
|
872 |
+ 'type' => $this->SFSclass->txt('sfs_log_types_' . $row['id_type']), |
|
873 |
+ 'time' => timeformat($row['log_time']), |
|
874 |
+ 'url' => preg_replace('~http(s)?://~i', 'hxxp\\1://', $row['url']), |
|
875 |
+ 'timestamp' => forum_time(true, $row['log_time']), |
|
876 |
+ 'member_link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>' : (empty($row['real_name']) ? ($this->SFSclass->txt('guest') . (!empty($row['extra']['member_acted']) ? ' (' . $row['extra']['member_acted'] . ')' : '')) : $row['real_name']), |
|
877 |
+ 'username' => $row['username'], |
|
878 |
+ 'email' => $row['email'], |
|
879 |
+ 'ip' => '<a href="' . sprintf($this->urlSFSipCheck, $row['ip']) . '">' . $row['ip'] . '</a>', |
|
880 |
+ 'ip2' => '<a href="' . sprintf($this->urlSFSipCheck, $row['ip2']) . '">' . $row['ip2'] . '</a>', |
|
881 |
+ 'editable' => true, //time() > $row['log_time'] + $this->hoursDisabled * 3600, |
|
882 |
+ 'checks_raw' => $row['checks'], |
|
883 |
+ 'result_raw' => $row['result'], |
|
884 |
+ ); |
|
885 |
+ |
|
886 |
+ $checksDecoded = $this->SFSclass->decodeJSON($row['checks']); |
|
887 |
+ |
|
888 |
+ // If we know what check triggered this, link it up to be searched. |
|
889 |
+ if ($row['id_type'] == 1) |
|
890 |
+ $entries[$row['id_sfs']]['checks'] = '<a href="' . sprintf($this->urlSFSsearch, $checksDecoded['value']) . '">' . $checksDecoded['value'] . '</a>'; |
|
891 |
+ elseif ($row['id_type'] == 2) |
|
892 |
+ $entries[$row['id_sfs']]['checks'] = '<a href="' . sprintf($this->urlSFSsearch, $checksDecoded['value']) . '">' . $checksDecoded['value'] . '</a>'; |
|
893 |
+ elseif ($row['id_type'] == 3) |
|
894 |
+ $entries[$row['id_sfs']]['checks'] = '<a href="' . sprintf($this->urlSFSsearch, $checksDecoded['value']) . '">' . $checksDecoded['value'] . '</a>'; |
|
895 |
+ // No idea what triggered it, parse it out cleanly. Could be debug data as well. |
|
896 |
+ else |
|
897 |
+ { |
|
898 |
+ $entries[$row['id_sfs']]['checks'] = ''; |
|
899 |
+ |
|
900 |
+ foreach ($checksDecoded as $ckey => $vkey) |
|
901 |
+ foreach ($vkey as $key => $value) |
|
902 |
+ $entries[$row['id_sfs']]['checks'] .= ucfirst($key) . ':' . $value . '<br>'; |
|
903 |
+ } |
|
904 |
+ |
|
905 |
+ // This tells us what it matched on exactly. |
|
906 |
+ if (strpos($row['result'], ',') !== false) |
|
907 |
+ { |
|
908 |
+ list($resultType, $resultMatch, $extra) = explode(',', $row['result'] . ',,,'); |
|
909 |
+ $entries[$row['id_sfs']]['result'] = sprintf($this->SFSclass->txt('sfs_log_matched_on'), $resultType, $resultMatch); |
|
910 |
+ |
|
911 |
+ // If this was a IP ban, note it. |
|
912 |
+ if ($resultType == 'ip' && !empty($extra)) |
|
913 |
+ $entries[$row['id_sfs']]['result'] .= ' ' . $this->SFSclass->txt('sfs_log_auto_banned'); |
|
914 |
+ if ($resultType == 'username' && !empty($extra)) |
|
915 |
+ $entries[$row['id_sfs']]['result'] .= ' ' . sprintf($this->SFSclass->txt('sfs_log_confidence'), $extra); |
|
916 |
+ } |
|
917 |
+ else |
|
918 |
+ $entries[$row['id_sfs']]['result'] = $row['result']; |
|
919 |
+ |
|
920 |
+ } |
|
921 |
+ $smcFunc['db_free_result']($result); |
|
922 |
+ |
|
923 |
+ return $entries; |
|
924 |
+ } |
|
925 |
+ |
|
926 |
+ /** |
|
927 |
+ * Get the log counts and returns it ready to go for GenericList handling. |
|
928 |
+ * |
|
929 |
+ * @param string $query_string The search string we are using to filter log data. |
|
930 |
+ * @param array $query_params Extra parameters for searching. |
|
931 |
+ * |
|
932 |
+ * @api |
|
933 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
934 |
+ * @See SFSA::loadLogs |
|
935 |
+ * @version 1.0 |
|
936 |
+ * @since 1.0 |
|
937 |
+ * @uses hook_manage_logs - Hook SMF2.1 |
|
938 |
+ * @uses setupModifyModifications - Injected SMF2.0 |
|
939 |
+ * @return void No return is generated |
|
940 |
+ */ |
|
941 |
+ public function getSFSLogEntriesCount(string $query_string = '', array $query_params = array()): int |
|
942 |
+ { |
|
943 |
+ global $smcFunc, $user_info; |
|
944 |
+ |
|
945 |
+ $result = $smcFunc['db_query']('', ' |
|
946 |
+ SELECT COUNT(*) |
|
947 |
+ FROM {db_prefix}log_sfs AS l |
|
948 |
+ LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = l.id_member) |
|
949 |
+ LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_group_id} THEN mem.id_post_group ELSE mem.id_group END) |
|
950 |
+ WHERE id_type IS NOT NULL' |
|
951 |
+ . (!empty($query_string) ? ' |
|
952 |
+ AND ' . $query_string : ''), |
|
953 |
+ array_merge($query_params, array( |
|
954 |
+ 'reg_group_id' => 0, |
|
955 |
+ )) |
|
956 |
+ ); |
|
957 |
+ list ($entry_count) = $smcFunc['db_fetch_row']($result); |
|
958 |
+ $smcFunc['db_free_result']($result); |
|
959 |
+ |
|
960 |
+ return (int) $entry_count; |
|
961 |
+ } |
|
962 |
+ |
|
963 |
+ /** |
|
964 |
+ * Remove all logs, except those less than 24 hours old. |
|
965 |
+ * |
|
966 |
+ * @api |
|
967 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
968 |
+ * @See SFSA::loadLogs |
|
969 |
+ * @version 1.0 |
|
970 |
+ * @since 1.0 |
|
971 |
+ * @return void No return is generated |
|
972 |
+ */ |
|
973 |
+ private function removeAllLogs(): void |
|
974 |
+ { |
|
975 |
+ global $smcFunc; |
|
976 |
+ |
|
977 |
+ checkSession(); |
|
978 |
+ |
|
979 |
+ $smcFunc['db_query']('', ' |
|
980 |
+ DELETE FROM {db_prefix}log_sfs |
|
981 |
+ WHERE log_time < {int:twenty_four_hours_wait}', |
|
982 |
+ array( |
|
983 |
+ 'twenty_four_hours_wait' => time() - $this->hoursDisabled * 3600, |
|
984 |
+ ) |
|
985 |
+ ); |
|
986 |
+ } |
|
987 |
+ |
|
988 |
+ /** |
|
989 |
+ * Remove specific logs, except those less than 24 hours old. |
|
990 |
+ * |
|
991 |
+ * @param array $entries A array of the ids that we want to remove. |
|
992 |
+ * |
|
993 |
+ * @api |
|
994 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
995 |
+ * @See SFSA::loadLogs |
|
996 |
+ * @version 1.0 |
|
997 |
+ * @since 1.0 |
|
998 |
+ * @return void No return is generated |
|
999 |
+ */ |
|
1000 |
+ private function removeLogs(array $entries): void |
|
1001 |
+ { |
|
1002 |
+ global $smcFunc; |
|
1003 |
+ |
|
1004 |
+ checkSession(); |
|
1005 |
+ |
|
1006 |
+ $smcFunc['db_query']('', ' |
|
1007 |
+ DELETE FROM {db_prefix}log_sfs |
|
1008 |
+ WHERE id_sfs IN ({array_string:delete_actions}) |
|
1009 |
+ AND log_time < {int:twenty_four_hours_wait}', |
|
1010 |
+ array( |
|
1011 |
+ 'twenty_four_hours_wait' => time() - $this->hoursDisabled * 3600, |
|
1012 |
+ 'delete_actions' => $entries, |
|
1013 |
+ ) |
|
1014 |
+ ); |
|
1015 |
+ } |
|
1016 |
+ |
|
1017 |
+ /** |
|
1018 |
+ * Handle searching for logs. |
|
1019 |
+ * |
|
1020 |
+ * @param string $url The base_href |
|
1021 |
+ * @internal |
|
1022 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
1023 |
+ * @version 1.0 |
|
1024 |
+ * @since 1.0 |
|
1025 |
+ * @return void No return is generated here. |
|
1026 |
+ */ |
|
1027 |
+ private function handleLogSearch(string &$url): void |
|
1028 |
+ { |
|
1029 |
+ global $context, $txt; |
|
1030 |
+ |
|
1031 |
+ // If we have some data from a search, lets bring it back out. |
|
1032 |
+ $this->search_params = $this->handleLogSearchParams(); |
|
1033 |
+ |
|
1034 |
+ // What we can search. |
|
1035 |
+ $this->search_types = $this->handleLogSearchTypes(); |
|
1036 |
+ $this->search_params_string = $this->handleLogSearchParamsString(); |
|
1037 |
+ $this->search_params_type = $this->handleLogSearchParamsType(); |
|
1038 |
+ |
|
1039 |
+ $this->search_params_column = $this->search_types[$this->search_params_type]['sql']; |
|
1040 |
+ |
|
1041 |
+ // Setup the search context. |
|
1042 |
+ $this->search_params = empty($this->search_params_string) ? '' : base64_encode(json_encode(array( |
|
1043 |
+ 'string' => $this->search_params_string, |
|
1044 |
+ 'type' => $this->search_params_type, |
|
1045 |
+ ))); |
|
1046 |
+ $this->logSearch = array( |
|
1047 |
+ 'string' => $this->search_params_string, |
|
1048 |
+ 'type' => $this->search_params_type, |
|
1049 |
+ 'label' => $this->search_types[$this->search_params_type]['label'], |
|
1050 |
+ ); |
|
1051 |
+ |
|
1052 |
+ if (!empty($this->search_params)) |
|
1053 |
+ $url .= ';params=' . $this->search_params; |
|
1054 |
+ } |
|
1055 |
+ |
|
1056 |
+ /** |
|
1057 |
+ * Handle Search Params |
|
1058 |
+ * |
|
1059 |
+ * @internal |
|
1060 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
1061 |
+ * @version 1.1 |
|
1062 |
+ * @since 1.0 |
|
1063 |
+ * @return bool True upon success, false otherwise. |
|
1064 |
+ */ |
|
1065 |
+ private function handleLogSearchParams(): array |
|
1066 |
+ { |
|
1067 |
+ // If we have something to search for saved, get it back out. |
|
1068 |
+ if (!empty($_REQUEST['params']) && empty($_REQUEST['is_search'])) |
|
1069 |
+ { |
|
1070 |
+ $search_params = base64_decode(strtr($params, array(' ' => '+'))); |
|
1071 |
+ $search_params = $this->SFSclass->decodeJSON($search_params); |
|
1072 |
+ |
|
1073 |
+ if (!empty($search_params)) |
|
1074 |
+ return $search_params; |
|
1075 |
+ } |
|
1076 |
+ |
|
1077 |
+ return array(); |
|
1078 |
+ } |
|
1079 |
+ |
|
1080 |
+ /** |
|
1081 |
+ * Handle Search Types |
|
1082 |
+ * |
|
1083 |
+ * @internal |
|
1084 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
1085 |
+ * @version 1.1 |
|
1086 |
+ * @since 1.0 |
|
1087 |
+ * @return array The valid Search Types. |
|
1088 |
+ */ |
|
1089 |
+ private function handleLogSearchTypes(): array |
|
1090 |
+ { |
|
1091 |
+ return array( |
|
1092 |
+ 'url' => array('sql' => 'l.url', 'label' => $this->SFSclass->txt('sfs_log_search_url')), |
|
1093 |
+ 'member' => array('sql' => 'mem.real_name', 'label' => $this->SFSclass->txt('sfs_log_search_member')), |
|
1094 |
+ 'username' => array('sql' => 'l.username', 'label' => $this->SFSclass->txt('sfs_log_search_username')), |
|
1095 |
+ 'email' => array('sql' => 'l.email', 'label' => $this->SFSclass->txt('sfs_log_search_email')), |
|
1096 |
+ 'ip' => array('sql' => 'lm.ip', 'label' => $this->SFSclass->txt('sfs_log_search_ip')), |
|
1097 |
+ 'ip2' => array('sql' => 'lm.ip2', 'label' => $this->SFSclass->txt('sfs_log_search_ip2')) |
|
1098 |
+ ); |
|
1099 |
+ } |
|
1100 |
+ |
|
1101 |
+ /** |
|
1102 |
+ * Handle Search Params String |
|
1103 |
+ * |
|
1104 |
+ * @internal |
|
1105 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
1106 |
+ * @version 1.1 |
|
1107 |
+ * @since 1.0 |
|
1108 |
+ * @return string What we are searching for, validated and cleaned. |
|
1109 |
+ */ |
|
1110 |
+ private function handleLogSearchParamsString(): string |
|
1111 |
+ { |
|
1112 |
+ if (!isset($this->search_params['string']) || (!empty($_REQUEST['search']) && $this->search_params['string'] != $_REQUEST['search'])) |
|
1113 |
+ return empty($_REQUEST['search']) ? '' : $_REQUEST['search']; |
|
1114 |
+ else |
|
1115 |
+ return $this->search_params['string']; |
|
1116 |
+ } |
|
1117 |
+ |
|
1118 |
+ /** |
|
1119 |
+ * Handle Search Params Type |
|
1120 |
+ * |
|
1121 |
+ * @internal |
|
1122 |
+ * @CalledIn SMF 2.0, SMF 2.1 |
|
1123 |
+ * @version 1.1 |
|
1124 |
+ * @since 1.0 |
|
1125 |
+ * @return string What we are searching for, validated and cleaned. |
|
1126 |
+ */ |
|
1127 |
+ private function handleLogSearchParamsType(): string |
|
1128 |
+ { |
|
1129 |
+ global $context; |
|
1130 |
+ |
|
1131 |
+ if (isset($_REQUEST['search_type']) || empty($this->search_params['type']) || !isset($this->search_types[$this->search_params['type']])) |
|
1132 |
+ return isset($_REQUEST['search_type']) && isset($this->search_types[$_REQUEST['search_type']]) ? $_REQUEST['search_type'] : (isset($this->search_types[$context['order']]) ? $context['order'] : 'member'); |
|
1133 |
+ else |
|
1134 |
+ return $this->search_params['type']; |
|
1135 |
+ } |
|
1136 |
+} |
|
0 | 1137 |
\ No newline at end of file |
... | ... |
@@ -43,12 +43,17 @@ |
43 | 43 |
<require-file name="StopForumSpam.php" destination="$sourcedir" /> |
44 | 44 |
|
45 | 45 |
<!-- All the hooks --> |
46 |
+ <!-- Main Section --> |
|
46 | 47 |
<hook hook="integrate_pre_include" function="$sourcedir/StopForumSpam.php" /> |
47 | 48 |
<hook hook="integrate_pre_load" function="SFS::hook_pre_load" /> |
48 |
- <hook hook="integrate_admin_areas" function="SFS::hook_admin_areas" /> |
|
49 |
- <hook hook="integrate_modify_modifications" function="SFS::hook_modify_modifications" /> |
|
50 | 49 |
<hook hook="integrate_register" function="SFS::hook_register" /> |
51 |
- <hook hook="integrate_manage_logs" function="SFS::hook_manage_logs" /> |
|
50 |
+ <hook hook="integrate_create_control_verification_test" function="SFS::hook_create_control_verification_test" /> |
|
51 |
+ |
|
52 |
+ <!-- Admin Section --> |
|
53 |
+ <hook hook="integrate_admin_include" function="$sourcedir/StopForumSpamAdmin.php" /> |
|
54 |
+ <hook hook="integrate_admin_areas" function="SFSA::hook_admin_areas" /> |
|
55 |
+ <hook hook="integrate_modify_modifications" function="SFSA::hook_modify_modifications" /> |
|
56 |
+ <hook hook="integrate_manage_logs" function="SFSA::hook_manage_logs" /> |
|
52 | 57 |
|
53 | 58 |
<redirect url="?action=admin;area=securitysettings;sa=sfs" /> |
54 | 59 |
</install> |
... | ... |
@@ -59,12 +64,17 @@ |
59 | 64 |
<code type="file">uninstall-sd-required.php</code> |
60 | 65 |
|
61 | 66 |
<!-- All the hooks, removed --> |
67 |
+ <!-- Main Section --> |
|
62 | 68 |
<hook hook="integrate_pre_include" function="$sourcedir/StopForumSpam.php" reverse="true" /> |
63 | 69 |
<hook hook="integrate_pre_load" function="SFS::hook_pre_load" reverse="true" /> |
64 |
- <hook hook="integrate_admin_areas" function="SFS::hook_admin_areas" reverse="true" /> |
|
65 |
- <hook hook="integrate_modify_modifications" function="SFS::hook_modify_modifications" reverse="true" /> |
|
66 | 70 |
<hook hook="integrate_register" function="SFS::hook_register" reverse="true" /> |
67 |
- <hook hook="integrate_manage_logs" function="SFS::hook_manage_logs" reverse="true" /> |
|
71 |
+ <hook hook="integrate_create_control_verification_test" function="SFSA::hook_create_control_verification_test" reverse="true" /> |
|
72 |
+ |
|
73 |
+ <!-- Admin Section --> |
|
74 |
+ <hook hook="integrate_admin_include" function="$sourcedir/StopForumSpamAdmin.php" reverse="true" /> |
|
75 |
+ <hook hook="integrate_admin_areas" function="SFSA::hook_admin_areas" reverse="true" /> |
|
76 |
+ <hook hook="integrate_modify_modifications" function="SFSA::hook_modify_modifications" reverse="true" /> |
|
77 |
+ <hook hook="integrate_manage_logs" function="SFSA::hook_manage_logs" reverse="true" /> |
|
68 | 78 |
|
69 | 79 |
<!-- language files, removed --> |
70 | 80 |
<remove-file name="$themes_dir/default/languages/StopForumSpam.english.php" /> |
... | ... |
@@ -19,12 +19,16 @@ if (SMF == 'SSI') |
19 | 19 |
db_extend('packages'); |
20 | 20 |
|
21 | 21 |
$hooks = array( |
22 |
+ // Main sections. |
|
22 | 23 |
'integrate_pre_include' => '$sourcedir/StopForumSpam.php', |
23 | 24 |
'integrate_pre_load' => 'SFS::hook_pre_load', |
24 |
- 'integrate_admin_areas' => 'SFS::hook_admin_areas', |
|
25 |
- 'integrate_modify_modifications' => 'SFS::hook_modify_modifications', |
|
26 | 25 |
'integrate_register' => 'SFS::hook_register', |
27 |
- 'integrate_manage_logs' => 'SFS::hook_manage_logs' |
|
26 |
+ |
|
27 |
+ // Admin Sections. |
|
28 |
+ 'integrate_admin_include' => '$sourcedir/StopForumSpamAdmin.php', |
|
29 |
+ 'integrate_admin_areas' => 'SFSA::hook_admin_areas', |
|
30 |
+ 'integrate_modify_modifications' => 'SFSA::hook_modify_modifications', |
|
31 |
+ 'integrate_manage_logs' => 'SFSA::hook_manage_logs' |
|
28 | 32 |
); |
29 | 33 |
|
30 | 34 |
foreach ($hooks as $hook => $func) |
... | ... |
@@ -19,12 +19,16 @@ if (SMF == 'SSI') |
19 | 19 |
db_extend('packages'); |
20 | 20 |
|
21 | 21 |
$hooks = array( |
22 |
+ // Main sections. |
|
22 | 23 |
'integrate_pre_include' => '$sourcedir/StopForumSpam.php', |
23 | 24 |
'integrate_pre_load' => 'SFS::hook_pre_load', |
24 |
- 'integrate_admin_areas' => 'SFS::hook_admin_areas', |
|
25 |
- 'integrate_modify_modifications' => 'SFS::hook_modify_modifications', |
|
26 | 25 |
'integrate_register' => 'SFS::hook_register', |
27 |
- 'integrate_manage_logs' => 'SFS::hook_manage_logs' |
|
26 |
+ |
|
27 |
+ // Admin Sections. |
|
28 |
+ 'integrate_admin_include' => '$sourcedir/StopForumSpamAdmin.php', |
|
29 |
+ 'integrate_admin_areas' => 'SFSA::hook_admin_areas', |
|
30 |
+ 'integrate_modify_modifications' => 'SFSA::hook_modify_modifications', |
|
31 |
+ 'integrate_manage_logs' => 'SFSA::hook_manage_logs' |
|
28 | 32 |
); |
29 | 33 |
|
30 | 34 |
foreach ($hooks as $hook => $func) |
31 | 35 |