Spam protection, AntiSpam, FireWall by CleanTalk - Version 5.146

Version Description

Sep 17 2020 = * Fix: Deprecated function wp_blacklist_check() fixed. * Fix: Roles exclusion fixed. * Mod: Namespace import in \Cleantalk\ApbctWP\Firewall\SFW. * Fix: Comments checking fixed. * Fix: Spam scan tabs layout fixed. * New: Countdown timer implemented for the AntiCrawler page. * Mod: User-agent signature added to the AC checking. * Mod: Find-spam classes for comments and users refactored * Upd: Spam scan - scanning users/comments updated. * Fix: Double requests for Ninja Forms. * New: 'wpms' flag in sender_info. * Fix: Visible params gathering. * Fix: WooCommerce AJAX order call 2. * Fix: Block page grammar fixed. * Fix: Users/comments list - unnecessary button removed. * Upd: Skiping AC blocking after 3 sec for real users. * New: Countdown timer for AF block page implemented. * New: Countdown timer for SFW block page implemented.

Download this release

Release Info

Developer glomberg
Plugin Icon 128x128 Spam protection, AntiSpam, FireWall by CleanTalk
Version 5.146
Comparing to
See all releases

Code changes from version 5.145.2 to 5.146

Files changed (36) hide show
  1. cleantalk.php +3 -1
  2. css/cleantalk-spam-check.min.css +1 -1
  3. inc/cleantalk-admin.php +0 -6
  4. inc/cleantalk-ajax.php +1 -1
  5. inc/cleantalk-common.php +7 -6
  6. inc/cleantalk-find-spam.php +55 -66
  7. inc/cleantalk-pluggable.php +23 -0
  8. inc/cleantalk-public.php +12 -4
  9. inc/cleantalk-updater.php +18 -0
  10. inc/find-spam/ClassCleantalkCommentsListTableScan.php +0 -42
  11. inc/find-spam/ClassCleantalkUsersListTableScan.php +0 -47
  12. js/apbct-disable-comments.min.js +2 -2
  13. js/apbct-public.min.js +1 -1
  14. js/apbct-public.min.js.map +1 -1
  15. js/cleantalk-comments-checkspam.min.js +1 -1
  16. js/cleantalk-comments-checkspam.min.js.map +1 -1
  17. js/cleantalk-users-checkspam.min.js +1 -1
  18. js/cleantalk-users-checkspam.min.js.map +1 -1
  19. lib/Cleantalk/ApbctWP/CleantalkListTable.php +1437 -0
  20. inc/find-spam/ClassCleantalkFindSpamChecker.php → lib/Cleantalk/ApbctWP/FindSpam/Checker.php +143 -131
  21. inc/find-spam/ClassCleantalkFindSpamCommentsChecker.php → lib/Cleantalk/ApbctWP/FindSpam/CommentsChecker.php +499 -484
  22. inc/find-spam/ClassCleantalkCommentsListTable.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/Comments.php +307 -306
  23. inc/find-spam/ClassCleantalkCommentsListTableLogs.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/CommentsLogs.php +63 -62
  24. inc/find-spam/ClassCleantalkCommentsListTableSpam.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/CommentsScan.php +53 -52
  25. inc/find-spam/ClassCleantalkUsersListTable.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/Users.php +263 -262
  26. inc/find-spam/ClassCleantalkUsersListTableLogs.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/UsersLogs.php +63 -62
  27. inc/find-spam/ClassCleantalkUsersListTableSpam.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/UsersScan.php +64 -63
  28. inc/find-spam/ClassCleantalkFindSpamPage.php → lib/Cleantalk/ApbctWP/FindSpam/Page.php +126 -135
  29. inc/find-spam/ClassCleantalkFindSpamUsersChecker.php → lib/Cleantalk/ApbctWP/FindSpam/UsersChecker.php +646 -631
  30. lib/Cleantalk/ApbctWP/Firewall/AntiCrawler.php +9 -7
  31. lib/Cleantalk/ApbctWP/Firewall/AntiFlood.php +1 -1
  32. lib/Cleantalk/ApbctWP/Firewall/SFW.php +3 -3
  33. lib/Cleantalk/ApbctWP/Firewall/die_page_anticrawler.html +27 -5
  34. lib/Cleantalk/ApbctWP/Firewall/die_page_antiflood.html +23 -1
  35. lib/Cleantalk/ApbctWP/Firewall/die_page_sfw.html +23 -1
  36. readme.txt +21 -1
cleantalk.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Anti-Spam by CleanTalk
4
  Plugin URI: https://cleantalk.org
5
  Description: Max power, all-in-one, no Captcha, premium anti-spam plugin. No comment spam, no registration spam, no contact spam, protects any WordPress forms.
6
- Version: 5.145.2
7
  Author: СleanTalk <welcome@cleantalk.org>
8
  Author URI: https://cleantalk.org
9
  Text Domain: cleantalk-spam-protect
@@ -686,6 +686,7 @@ function apbct_activation( $network = false ) {
686
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
687
  `id` VARCHAR(40) NOT NULL,
688
  `ip` VARCHAR(40) NOT NULL,
 
689
  `entries` INT DEFAULT 0,
690
  `interval_start` INT NOT NULL,
691
  PRIMARY KEY (`id`));';
@@ -794,6 +795,7 @@ function apbct_activation__new_blog($blog_id, $user_id, $domain, $path, $site_id
794
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
795
  `id` VARCHAR(40) NOT NULL,
796
  `ip` VARCHAR(40) NOT NULL,
 
797
  `entries` INT DEFAULT 0,
798
  `interval_start` INT NOT NULL,
799
  PRIMARY KEY (`id`));';
3
  Plugin Name: Anti-Spam by CleanTalk
4
  Plugin URI: https://cleantalk.org
5
  Description: Max power, all-in-one, no Captcha, premium anti-spam plugin. No comment spam, no registration spam, no contact spam, protects any WordPress forms.
6
+ Version: 5.146
7
  Author: СleanTalk <welcome@cleantalk.org>
8
  Author URI: https://cleantalk.org
9
  Text Domain: cleantalk-spam-protect
686
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
687
  `id` VARCHAR(40) NOT NULL,
688
  `ip` VARCHAR(40) NOT NULL,
689
+ `ua` VARCHAR(40) NOT NULL,
690
  `entries` INT DEFAULT 0,
691
  `interval_start` INT NOT NULL,
692
  PRIMARY KEY (`id`));';
795
  $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
796
  `id` VARCHAR(40) NOT NULL,
797
  `ip` VARCHAR(40) NOT NULL,
798
+ `ua` VARCHAR(40) NOT NULL,
799
  `entries` INT DEFAULT 0,
800
  `interval_start` INT NOT NULL,
801
  PRIMARY KEY (`id`));';
css/cleantalk-spam-check.min.css CHANGED
@@ -1 +1 @@
1
- #ct_checking_status,#ct_cooling_notice,#ct_error_message h3,#ct_error_message h4{text-align:center;width:90%}#ct_preloader{display:none;width:100%;text-align:center}#ct_preloader img{border:none!important}#ct_working_message{display:none;margin:1em auto auto;padding:3px;width:70%;border:2px dotted gray;background:#ff9}#ct_pause{display:none}.ct_check_params_elem_sub{margin:15px 0 0 25px;width:150px;display:inline-block}.ct_check_params_elem_sub_sub{margin:15px 0 0 50px}button#ct_check_spam_button{background:#2ea2cc;border-color:#0074a2;color:#fff;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15)}button#ct_check_spam_button:hover{color:#000}.ct_date{display:inline;width:150px}.ct_check_params_desc{display:inline-block;margin:5px 10px 10px 15px}#ct_check_tabs{border:1px solid #c5c5c5;border-radius:3px;padding:.2em;background:#fff}#ct_check_tabs ul{margin:0;padding:.2em .2em 0;border:1px solid #c5c5c5;border-radius:3px;background:#e9e9e9;color:#333;font-weight:700;display:flex}#ct_check_tabs ul li{list-style:none;position:relative;margin:1px .2em -1px 0;padding:0;white-space:nowrap;border:1px solid #c5c5c5;border-radius:3px 3px 0 0;background:#f6f6f6;font-weight:400}#ct_check_tabs ul li.active{border-color:#003eff;background:#007fff}#ct_check_tabs ul li a{display:block;padding:.5em 1em;text-decoration:none}#ct_check_tabs ul li.active a{color:#fff}#ct_check_content{display:block;border-width:0;padding:1em 1.4em;background:0 0}
1
+ #ct_checking_count,#ct_checking_status,#ct_cooling_notice,#ct_error_message h3,#ct_error_message h4{text-align:center;width:90%}#ct_preloader{display:none;width:100%;text-align:center}#ct_preloader img{border:none!important}#ct_working_message{display:none;margin:1em auto auto;padding:3px;width:70%;border:2px dotted gray;background:#ff9}#ct_pause{display:none}.ct_check_params_elem_sub{margin:15px 0 0 25px;width:150px;display:inline-block}.ct_check_params_elem_sub_sub{margin:15px 0 0 50px}button#ct_check_spam_button{background:#2ea2cc;border-color:#0074a2;color:#fff;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15)}button#ct_check_spam_button:hover{color:#000}.ct_date{display:inline;width:150px}.ct_check_params_desc{display:inline-block;margin:5px 10px 10px 15px}#ct_check_tabs{border:1px solid #c5c5c5;border-radius:3px;padding:.2em;background:#fff}#ct_check_tabs ul{margin:0;padding:.2em .2em 0;border:1px solid #c5c5c5;border-radius:3px;background:#e9e9e9;color:#333;font-weight:700;display:flex}#ct_check_tabs ul li{list-style:none;position:relative;margin:1px .2em -1px 0;padding:0;white-space:nowrap;border:1px solid #c5c5c5;border-radius:3px 3px 0 0;background:#fff;font-weight:400}#ct_check_tabs ul li.active{border-bottom:1px solid transparent}#ct_check_tabs ul li a{display:block;padding:.5em 1em;text-decoration:none}#ct_check_tabs ul li.active a{font-weight:700}#ct_check_content{display:block;border-width:0;padding:1em 1.4em;background:0 0}
inc/cleantalk-admin.php CHANGED
@@ -24,11 +24,9 @@ function apbct_add_buttons_to_comments_and_users( $unused_argument ) {
24
 
25
  if( 'users' == $current_screen->base ) {
26
  $button_url__check = $current_screen->base . '.php?page=ct_check_users';
27
- $button_url__results = $current_screen->base . '.php?page=ct_check_users_total';
28
  $button_description = 'users';
29
  } elseif ( 'edit-comments' == $current_screen->base ) {
30
  $button_url__check = $current_screen->base . '.php?page=ct_check_spam';
31
- $button_url__results = $current_screen->base . '.php?page=ct_check_spam_total';
32
  $button_description = 'comments';
33
  } else {
34
  return;
@@ -39,10 +37,6 @@ function apbct_add_buttons_to_comments_and_users( $unused_argument ) {
39
  <img src="' . $apbct->logo__small__colored . '" alt="Cleantalk Antispam logo" height="" style="width: 17px; vertical-align: text-bottom;" />
40
  ' . sprintf(__( 'Find spam %s', 'cleantalk-spam-protect'), $button_description ) . '
41
  </a>
42
- <a href="' . $button_url__results . '" class="button" style="margin:1px 0 0 0; display: inline-block;">
43
- <img src="' . $apbct->logo__small__colored . '" alt="Cleantalk Antispam logo" height="" style="width: 17px; vertical-align: text-bottom;" />
44
- ' . sprintf(__( 'View spam %s', 'cleantalk-spam-protect'), $button_description ) . '
45
- </a>
46
  <a href="https://cleantalk.org/my/show_requests?service_id=' . $apbct->data['service_id'] . '&int=week" target="_blank" class="button" style="margin:1px 0 0 0; display: inline-block;">
47
  <img src="' . $apbct->logo__small__colored . '" alt="Cleantalk Antispam logo" height="" style="width: 17px; vertical-align: text-bottom;" />
48
  ' . __( 'CleanTalk Anti-Spam Log', 'cleantalk-spam-protect') . '
24
 
25
  if( 'users' == $current_screen->base ) {
26
  $button_url__check = $current_screen->base . '.php?page=ct_check_users';
 
27
  $button_description = 'users';
28
  } elseif ( 'edit-comments' == $current_screen->base ) {
29
  $button_url__check = $current_screen->base . '.php?page=ct_check_spam';
 
30
  $button_description = 'comments';
31
  } else {
32
  return;
37
  <img src="' . $apbct->logo__small__colored . '" alt="Cleantalk Antispam logo" height="" style="width: 17px; vertical-align: text-bottom;" />
38
  ' . sprintf(__( 'Find spam %s', 'cleantalk-spam-protect'), $button_description ) . '
39
  </a>
 
 
 
 
40
  <a href="https://cleantalk.org/my/show_requests?service_id=' . $apbct->data['service_id'] . '&int=week" target="_blank" class="button" style="margin:1px 0 0 0; display: inline-block;">
41
  <img src="' . $apbct->logo__small__colored . '" alt="Cleantalk Antispam logo" height="" style="width: 17px; vertical-align: text-bottom;" />
42
  ' . __( 'CleanTalk Anti-Spam Log', 'cleantalk-spam-protect') . '
inc/cleantalk-ajax.php CHANGED
@@ -387,7 +387,7 @@ function ct_ajax_hook($message_obj = false, $additional = false)
387
  $ct_post_temp['comment'] = $_POST['comment'];
388
  }
389
  //Woocommerce checkout
390
- if(isset($_POST['action']) && $_POST['action']=='woocommerce_checkout'){
391
  $post_info['comment_type'] = 'order';
392
  if( empty( $apbct->settings['wc_checkout_test'] ) ){
393
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
387
  $ct_post_temp['comment'] = $_POST['comment'];
388
  }
389
  //Woocommerce checkout
390
+ if( \Cleantalk\Variables\Post::get( 'action' ) == 'woocommerce_checkout' || \Cleantalk\Variables\Post::get( 'action' ) == 'save_data' ){
391
  $post_info['comment_type'] = 'order';
392
  if( empty( $apbct->settings['wc_checkout_test'] ) ){
393
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
inc/cleantalk-common.php CHANGED
@@ -86,6 +86,12 @@ function apbct_base_call($params = array(), $reg_flag = false){
86
 
87
  global $apbct, $cleantalk_executed;
88
 
 
 
 
 
 
 
89
  $cleantalk_executed = true;
90
 
91
  $sender_info = !empty($params['sender_info'])
@@ -100,12 +106,6 @@ function apbct_base_call($params = array(), $reg_flag = false){
100
  ->delete();
101
  }
102
 
103
- // URL, IP, Role exclusions
104
- if( ! $cleantalk_executed && apbct_exclusions_check() ){
105
- do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
106
- return false;
107
- }
108
-
109
  // Reversed url exclusions. Pass everything except one.
110
  if( ! apbct_exclusions_check__url__reversed() ){
111
  return array(
@@ -362,6 +362,7 @@ function apbct_get_sender_info() {
362
  : (array)json_decode(filter_input(INPUT_COOKIE, 'apbct_urls'), true);
363
 
364
  return array(
 
365
  'remote_addr' => \Cleantalk\ApbctWP\Helper::ip__get(array('remote_addr'), false),
366
  'REFFERRER' => apbct_get_server_variable( 'HTTP_REFERER' ),
367
  'USER_AGENT' => apbct_get_server_variable( 'HTTP_USER_AGENT' ),
86
 
87
  global $apbct, $cleantalk_executed;
88
 
89
+ // URL, IP, Role exclusions
90
+ if( ! $cleantalk_executed && apbct_exclusions_check() ){
91
+ do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
92
+ return array( 'ct_result' => new CleantalkResponse() );
93
+ }
94
+
95
  $cleantalk_executed = true;
96
 
97
  $sender_info = !empty($params['sender_info'])
106
  ->delete();
107
  }
108
 
 
 
 
 
 
 
109
  // Reversed url exclusions. Pass everything except one.
110
  if( ! apbct_exclusions_check__url__reversed() ){
111
  return array(
362
  : (array)json_decode(filter_input(INPUT_COOKIE, 'apbct_urls'), true);
363
 
364
  return array(
365
+ 'wpms' => is_multisite() ? 'yes' : 'no',
366
  'remote_addr' => \Cleantalk\ApbctWP\Helper::ip__get(array('remote_addr'), false),
367
  'REFFERRER' => apbct_get_server_variable( 'HTTP_REFERER' ),
368
  'USER_AGENT' => apbct_get_server_variable( 'HTTP_USER_AGENT' ),
inc/cleantalk-find-spam.php CHANGED
@@ -1,66 +1,55 @@
1
- <?php
2
-
3
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkFindSpamPage.php');
4
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkFindSpamChecker.php');
5
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkFindSpamUsersChecker.php');
6
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkFindSpamCommentsChecker.php');
7
-
8
- // Adding menu items for USERS and COMMENTS spam checking pages
9
- add_action( 'admin_menu', 'ct_add_find_spam_pages' );
10
- function ct_add_find_spam_pages(){
11
-
12
- // Check users pages
13
- $ct_check_users = add_users_page( __( "Check for spam", 'cleantalk-spam-protect'), __( "Find spam users", 'cleantalk-spam-protect'), 'activate_plugins', 'ct_check_users', array( 'ClassCleantalkFindSpamPage', 'showFindSpamPage' ) );
14
- $ct_check_users_total = add_users_page( __( "Previous scan results", 'cleantalk-spam-protect'), '', 'activate_plugins', 'ct_check_users_total', array( 'ClassCleantalkFindSpamPage', 'showFindSpamPage' ) );
15
- $ct_check_users_logs = add_users_page( __( "Scan logs", 'cleantalk-spam-protect'), '', 'activate_plugins', 'ct_check_users_logs', array( 'ClassCleantalkFindSpamPage', 'showFindSpamPage' ) );
16
-
17
- // Cheack comments pages
18
- $ct_check_spam = add_comments_page( __( "Check for spam", 'cleantalk-spam-protect'), __( "Find spam comments", 'cleantalk-spam-protect'), 'activate_plugins', 'ct_check_spam', array( 'ClassCleantalkFindSpamPage', 'showFindSpamPage' ) );
19
- $ct_check_spam_total = add_comments_page( __( "Previous scan results", 'cleantalk-spam-protect'), '', 'activate_plugins', 'ct_check_spam_total', array( 'ClassCleantalkFindSpamPage', 'showFindSpamPage' ) );
20
- $ct_check_spam_logs = add_comments_page( __( "Scan logs", 'cleantalk-spam-protect'), '', 'activate_plugins', 'ct_check_spam_logs', array( 'ClassCleantalkFindSpamPage', 'showFindSpamPage' ) );
21
-
22
- // Remove some pages from main menu
23
- remove_submenu_page( 'users.php', 'ct_check_users_total' );
24
- remove_submenu_page( 'users.php', 'ct_check_users_logs' );
25
- remove_submenu_page( 'edit-comments.php', 'ct_check_spam_total' );
26
- remove_submenu_page( 'edit-comments.php', 'ct_check_spam_logs' );
27
-
28
- // Set screen option for every pages
29
- add_action( "load-$ct_check_users", array( 'ClassCleantalkFindSpamPage', 'setScreenOption' ) );
30
- add_action( "load-$ct_check_users_total", array( 'ClassCleantalkFindSpamPage', 'setScreenOption' ) );
31
- add_action( "load-$ct_check_users_logs", array( 'ClassCleantalkFindSpamPage', 'setScreenOption' ) );
32
- add_action( "load-$ct_check_spam", array( 'ClassCleantalkFindSpamPage', 'setScreenOption' ) );
33
- add_action( "load-$ct_check_spam_total", array( 'ClassCleantalkFindSpamPage', 'setScreenOption' ) );
34
- add_action( "load-$ct_check_spam_logs", array( 'ClassCleantalkFindSpamPage', 'setScreenOption' ) );
35
-
36
- }
37
-
38
- // Set AJAX actions
39
- add_action( 'wp_ajax_ajax_clear_users', array( 'ClassCleantalkFindSpamUsersChecker', 'ct_ajax_clear_users' ) );
40
- add_action( 'wp_ajax_ajax_check_users', array( 'ClassCleantalkFindSpamUsersChecker', 'ct_ajax_check_users' ) );
41
- add_action( 'wp_ajax_ajax_info_users', array( 'ClassCleantalkFindSpamUsersChecker', 'ct_ajax_info' ) );
42
- add_action( 'wp_ajax_ajax_ct_get_csv_file', array( 'ClassCleantalkFindSpamUsersChecker', 'ct_get_csv_file' ) );
43
- add_action( 'wp_ajax_ajax_delete_all_users', array( 'ClassCleantalkFindSpamUsersChecker', 'ct_ajax_delete_all_users' ) );
44
-
45
- add_action( 'wp_ajax_ajax_clear_comments', array( 'ClassCleantalkFindSpamCommentsChecker', 'ct_ajax_clear_comments' ) );
46
- add_action( 'wp_ajax_ajax_check_comments', array( 'ClassCleantalkFindSpamCommentsChecker', 'ct_ajax_check_comments' ) );
47
- add_action( 'wp_ajax_ajax_info_comments', array( 'ClassCleantalkFindSpamCommentsChecker', 'ct_ajax_info' ) );
48
- add_action( 'wp_ajax_ajax_delete_all', array( 'ClassCleantalkFindSpamCommentsChecker', 'ct_ajax_delete_all' ) );
49
-
50
- // Debug
51
- add_action( 'wp_ajax_ajax_insert_users', array( 'ClassCleantalkFindSpamUsersChecker', 'ct_ajax_insert_users' ) );
52
-
53
- // Hook for saving "per_page" option
54
- add_action( 'wp_loaded', 'ct_save_screen_option' );
55
- function ct_save_screen_option() {
56
-
57
- // Saving screen option for the pagination (per page option)
58
- add_filter( 'set-screen-option', function( $status, $option, $value ){
59
- return ( $option == 'spam_per_page' ) ? (int) $value : $status;
60
- }, 10, 3 );
61
-
62
- }
63
-
64
- // Add checked icons into users table
65
- add_filter( 'manage_users_columns', array( 'ClassCleantalkFindSpamUsersChecker', 'ct_manage_users_columns' ), 10, 1 );
66
- add_filter( 'manage_users_custom_column', array( 'ClassCleantalkFindSpamUsersChecker', 'ct_manage_users_custom_column' ), 10, 3 );
1
+ <?php
2
+
3
+ // Adding menu items for USERS and COMMENTS spam checking pages
4
+ add_action( 'admin_menu', 'ct_add_find_spam_pages' );
5
+ function ct_add_find_spam_pages(){
6
+
7
+ // Check users pages
8
+ $ct_check_users = add_users_page( __( "Check for spam", 'cleantalk-spam-protect'), __( "Find spam users", 'cleantalk-spam-protect'), 'activate_plugins', 'ct_check_users', array( '\Cleantalk\ApbctWP\FindSpam\Page', 'showFindSpamPage' ) );
9
+ $ct_check_users_logs = add_users_page( __( "Scan logs", 'cleantalk-spam-protect'), '', 'activate_plugins', 'ct_check_users_logs', array( '\Cleantalk\ApbctWP\FindSpam\Page', 'showFindSpamPage' ) );
10
+
11
+ // Cheack comments pages
12
+ $ct_check_spam = add_comments_page( __( "Check for spam", 'cleantalk-spam-protect'), __( "Find spam comments", 'cleantalk-spam-protect'), 'activate_plugins', 'ct_check_spam', array( '\Cleantalk\ApbctWP\FindSpam\Page', 'showFindSpamPage' ) );
13
+ $ct_check_spam_logs = add_comments_page( __( "Scan logs", 'cleantalk-spam-protect'), '', 'activate_plugins', 'ct_check_spam_logs', array( '\Cleantalk\ApbctWP\FindSpam\Page', 'showFindSpamPage' ) );
14
+
15
+ // Remove some pages from main menu
16
+ remove_submenu_page( 'users.php', 'ct_check_users_logs' );
17
+ remove_submenu_page( 'edit-comments.php', 'ct_check_spam_logs' );
18
+
19
+ // Set screen option for every pages
20
+ add_action( "load-$ct_check_users", array( '\Cleantalk\ApbctWP\FindSpam\Page', 'setScreenOption' ) );
21
+ add_action( "load-$ct_check_users_logs", array( '\Cleantalk\ApbctWP\FindSpam\Page', 'setScreenOption' ) );
22
+ add_action( "load-$ct_check_spam", array( '\Cleantalk\ApbctWP\FindSpam\Page', 'setScreenOption' ) );
23
+ add_action( "load-$ct_check_spam_logs", array( '\Cleantalk\ApbctWP\FindSpam\Page', 'setScreenOption' ) );
24
+
25
+ }
26
+
27
+ // Set AJAX actions
28
+ add_action( 'wp_ajax_ajax_clear_users', array( '\Cleantalk\ApbctWP\FindSpam\UsersChecker', 'ct_ajax_clear_users' ) );
29
+ add_action( 'wp_ajax_ajax_check_users', array( '\Cleantalk\ApbctWP\FindSpam\UsersChecker', 'ct_ajax_check_users' ) );
30
+ add_action( 'wp_ajax_ajax_info_users', array( '\Cleantalk\ApbctWP\FindSpam\UsersChecker', 'ct_ajax_info' ) );
31
+ add_action( 'wp_ajax_ajax_ct_get_csv_file', array( '\Cleantalk\ApbctWP\FindSpam\UsersChecker', 'ct_get_csv_file' ) );
32
+ add_action( 'wp_ajax_ajax_delete_all_users', array( '\Cleantalk\ApbctWP\FindSpam\UsersChecker', 'ct_ajax_delete_all_users' ) );
33
+
34
+ add_action( 'wp_ajax_ajax_clear_comments', array( '\Cleantalk\ApbctWP\FindSpam\CommentsChecker', 'ct_ajax_clear_comments' ) );
35
+ add_action( 'wp_ajax_ajax_check_comments', array( '\Cleantalk\ApbctWP\FindSpam\CommentsChecker', 'ct_ajax_check_comments' ) );
36
+ add_action( 'wp_ajax_ajax_info_comments', array( '\Cleantalk\ApbctWP\FindSpam\CommentsChecker', 'ct_ajax_info' ) );
37
+ add_action( 'wp_ajax_ajax_delete_all', array( '\Cleantalk\ApbctWP\FindSpam\CommentsChecker', 'ct_ajax_delete_all' ) );
38
+
39
+ // Debug
40
+ add_action( 'wp_ajax_ajax_insert_users', array( '\Cleantalk\ApbctWP\FindSpam\UsersChecker', 'ct_ajax_insert_users' ) );
41
+
42
+ // Hook for saving "per_page" option
43
+ add_action( 'wp_loaded', 'ct_save_screen_option' );
44
+ function ct_save_screen_option() {
45
+
46
+ // Saving screen option for the pagination (per page option)
47
+ add_filter( 'set-screen-option', function( $status, $option, $value ){
48
+ return ( $option == 'spam_per_page' ) ? (int) $value : $status;
49
+ }, 10, 3 );
50
+
51
+ }
52
+
53
+ // Add checked icons into users table
54
+ add_filter( 'manage_users_columns', array( '\Cleantalk\ApbctWP\FindSpam\UsersChecker', 'ct_manage_users_columns' ), 10, 1 );
55
+ add_filter( 'manage_users_custom_column', array( '\Cleantalk\ApbctWP\FindSpam\UsersChecker', 'ct_manage_users_custom_column' ), 10, 3 );
 
 
 
 
 
 
 
 
 
 
 
inc/cleantalk-pluggable.php CHANGED
@@ -285,4 +285,27 @@ function apbct_wp_doing_cron() {
285
  return ( defined( 'DOING_CRON' ) && DOING_CRON );
286
  }
287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  }
285
  return ( defined( 'DOING_CRON' ) && DOING_CRON );
286
  }
287
 
288
+ }
289
+
290
+ /**
291
+ * Checks if a comment contains disallowed characters or words.
292
+ *
293
+ * @param $author
294
+ * @param $email
295
+ * @param $url
296
+ * @param $comment
297
+ * @param $user_ip
298
+ * @param $user_agent
299
+ * @return bool
300
+ */
301
+ function apbct_wp_blacklist_check($author, $email, $url, $comment, $user_ip, $user_agent ) {
302
+
303
+ global $wp_version;
304
+
305
+ if( version_compare($wp_version, '5.5.0', '>=') ) {
306
+ return wp_check_comment_disallowed_list( $author, $email, $url, $comment, $user_ip, $user_agent );
307
+ } else {
308
+ return wp_blacklist_check( $author, $email, $url, $comment, $user_ip, $user_agent );
309
+ }
310
+
311
  }
inc/cleantalk-public.php CHANGED
@@ -1278,7 +1278,7 @@ function ct_preprocess_comment($comment) {
1278
  return $comment;
1279
  }
1280
 
1281
- $local_blacklists = wp_blacklist_check(
1282
  $comment['comment_author'],
1283
  $comment['comment_author_email'],
1284
  $comment['comment_author_url'],
@@ -2437,12 +2437,19 @@ function apbct_form__contactForm7__changeMailNotification($component){
2437
  */
2438
  function apbct_form__ninjaForms__testSpam() {
2439
 
2440
- global $apbct;
2441
 
 
 
 
 
 
 
 
2442
  if(
2443
  $apbct->settings['contact_forms_test'] == 0
2444
  || ($apbct->settings['protect_logged_in'] != 1 && is_user_logged_in()) // Skip processing for logged in users.
2445
- || apbct_exclusions_check__url()
2446
  ){
2447
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
2448
  return;
@@ -3322,7 +3329,8 @@ function ct_contact_form_validate() {
3322
  ( isset( $_POST['AppKey'] ) && ( isset( $_POST['cbAP'] ) && $_POST['cbAP'] == 'Caspio' ) ) || // Caspio exclusion (ticket #16444)
3323
  isset($_POST['wpforms_id'], $_POST['wpforms_author']) || //Skip wpforms
3324
  ( isset( $_POST['somfrp_action'], $_POST['submitted'] ) && $_POST['somfrp_action'] == 'somfrp_lost_pass' ) || // Frontend Reset Password exclusion
3325
- ( isset( $_POST['action'] ) && $_POST['action'] == 'dokan_save_account_details' )
 
3326
  ) {
3327
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
3328
  return null;
1278
  return $comment;
1279
  }
1280
 
1281
+ $local_blacklists = apbct_wp_blacklist_check(
1282
  $comment['comment_author'],
1283
  $comment['comment_author_email'],
1284
  $comment['comment_author_url'],
2437
  */
2438
  function apbct_form__ninjaForms__testSpam() {
2439
 
2440
+ global $apbct, $cleantalk_executed;
2441
 
2442
+ if( $cleantalk_executed ){
2443
+ do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
2444
+ return;
2445
+ }
2446
+
2447
+ $cleantalk_executed = true;
2448
+
2449
  if(
2450
  $apbct->settings['contact_forms_test'] == 0
2451
  || ($apbct->settings['protect_logged_in'] != 1 && is_user_logged_in()) // Skip processing for logged in users.
2452
+ || apbct_exclusions_check__url()
2453
  ){
2454
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
2455
  return;
3329
  ( isset( $_POST['AppKey'] ) && ( isset( $_POST['cbAP'] ) && $_POST['cbAP'] == 'Caspio' ) ) || // Caspio exclusion (ticket #16444)
3330
  isset($_POST['wpforms_id'], $_POST['wpforms_author']) || //Skip wpforms
3331
  ( isset( $_POST['somfrp_action'], $_POST['submitted'] ) && $_POST['somfrp_action'] == 'somfrp_lost_pass' ) || // Frontend Reset Password exclusion
3332
+ ( isset( $_POST['action'] ) && $_POST['action'] == 'dokan_save_account_details' ) ||
3333
+ \Cleantalk\Variables\Post::get('action') === 'frm_get_lookup_text_value' // Exception for Formidable multilevel form
3334
  ) {
3335
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
3336
  return null;
inc/cleantalk-updater.php CHANGED
@@ -594,4 +594,22 @@ function apbct_update_to_5_143_2() {
594
 
595
  apbct_activation__create_tables( $sqls, $apbct->db_prefix );
596
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
597
  }
594
 
595
  apbct_activation__create_tables( $sqls, $apbct->db_prefix );
596
 
597
+ }
598
+
599
+ function apbct_update_to_5_146() {
600
+
601
+ global $apbct;
602
+
603
+ $sqls[] = 'DROP TABLE IF EXISTS `%scleantalk_ac_log`;';
604
+
605
+ $sqls[] = 'CREATE TABLE IF NOT EXISTS `%scleantalk_ac_log` (
606
+ `id` VARCHAR(40) NOT NULL,
607
+ `ip` VARCHAR(40) NOT NULL,
608
+ `ua` VARCHAR(40) NOT NULL,
609
+ `entries` INT DEFAULT 0,
610
+ `interval_start` INT NOT NULL,
611
+ PRIMARY KEY (`id`));';
612
+
613
+ apbct_activation__create_tables( $sqls, $apbct->db_prefix );
614
+
615
  }
inc/find-spam/ClassCleantalkCommentsListTableScan.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
-
4
- class ABPCTCommentsListTableScan extends ABPCTCommentsListTable
5
- {
6
-
7
- function prepare_items() {
8
-
9
- $columns = $this->get_columns();
10
- $this->_column_headers = array( $columns, array(), array() );
11
-
12
- $per_page_option = get_current_screen()->get_option( 'per_page', 'option' );
13
- $per_page = get_user_meta( get_current_user_id(), $per_page_option, true );
14
- if( ! $per_page ) {
15
- $per_page = 10;
16
- }
17
-
18
- $scanned_comments = $this->getSpamNow();
19
-
20
- $this->set_pagination_args( array(
21
- 'total_items' => count( $scanned_comments->get_comments() ),
22
- 'per_page' => $per_page,
23
- ) );
24
-
25
- $current_page = (int) $this->get_pagenum();
26
-
27
- $scanned_comments_to_show = array_slice( $scanned_comments->get_comments(), ( ( $current_page - 1 ) * $per_page ), $per_page );
28
-
29
- foreach( $scanned_comments_to_show as $comment ) {
30
-
31
- $this->items[] = array(
32
- 'ct_id' => $comment->comment_ID,
33
- 'ct_author' => $comment->comment_author,
34
- 'ct_comment' => $comment,
35
- 'ct_response_to' => $comment->comment_post_ID,
36
- );
37
-
38
- }
39
-
40
- }
41
-
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/find-spam/ClassCleantalkUsersListTableScan.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
-
3
-
4
- class ABPCTUsersListTableScan extends ABPCTUsersListTable
5
- {
6
-
7
- function prepare_items() {
8
-
9
- $columns = $this->get_columns();
10
- $this->_column_headers = array( $columns, array(), array() );
11
-
12
- $per_page_option = get_current_screen()->get_option( 'per_page', 'option' );
13
- $per_page = get_user_meta( get_current_user_id(), $per_page_option, true );
14
- if( ! $per_page ) {
15
- $per_page = 10;
16
- }
17
-
18
- $scanned_users = $this->getSpamNow();
19
-
20
- $this->set_pagination_args( array(
21
- 'total_items' => $scanned_users->get_total(),
22
- 'per_page' => $per_page,
23
- ) );
24
-
25
- $current_page = (int) $this->get_pagenum();
26
-
27
- $scanned_users_to_show = array_slice( $scanned_users->get_results(), ( ( $current_page - 1 ) * $per_page ), $per_page );
28
-
29
- foreach( $scanned_users_to_show as $user_id ) {
30
-
31
- $user_obj = get_userdata( $user_id );
32
-
33
- $this->items[] = array(
34
- 'ct_id' => $user_obj->ID,
35
- 'ct_username' => $user_obj,
36
- 'ct_name' => $user_obj->display_name,
37
- 'ct_email' => $user_obj->user_email,
38
- 'ct_signed_up' => $user_obj->user_registered,
39
- 'ct_role' => implode( ', ', $user_obj->roles ),
40
- 'ct_posts' => count_user_posts( $user_id ),
41
- );
42
-
43
- }
44
-
45
- }
46
-
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/apbct-disable-comments.min.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";wp.domReady(function(){wp.blocks&&wp.blocks.getBlockTypes().forEach(function(e){apbctDisableComments.disabled_blocks.includes(e.name)&&wp.blocks.unregisterBlockType(e.name)})});
2
- //# sourceMappingURL=apbct-disable-comments.min.js.map
1
+ "use strict";wp.domReady(function(){wp.blocks&&wp.blocks.getBlockTypes().forEach(function(e){apbctDisableComments.disabled_blocks.includes(e.name)&&wp.blocks.unregisterBlockType(e.name)})});
2
+ //# sourceMappingURL=apbct-disable-comments.min.js.map
js/apbct-public.min.js CHANGED
@@ -1,2 +1,2 @@
1
- function ctSetCookie(e,t){document.cookie=e+"="+encodeURIComponent(t)+"; path=/; samesite=lax"}function apbct_collect_visible_fields_and_set_cookie(e){var t=[],o="",n=0,i=[];for(var a in e.elements)isNaN(+a)||(t[a]=e.elements[a]);(t=t.filter(function(e){return"none"!==getComputedStyle(e).display&&"hidden"!==getComputedStyle(e).visibility&&"0"!==getComputedStyle(e).opacity&&"hidden"!==e.getAttribute("type")&&"submit"!==e.getAttribute("type")&&""!==e.value&&null!==e.getAttribute("name")&&-1===i.indexOf(e.getAttribute("name"))&&(n++,-1===["radio","checkbox"].indexOf(e.getAttribute("type"))||(i.push(e.getAttribute("name")),!1))})).forEach(function(e,t,n){o+=" "+e.getAttribute("name")}),ctSetCookie("apbct_visible_fields",o=o.trim()),ctSetCookie("apbct_visible_fields_count",n)}function apbct_js_keys__set_input_value(e,t,n,o){if(null!==document.getElementById(n.input_name)){var i=document.getElementById(n.input_name).value;document.getElementById(n.input_name).value=document.getElementById(n.input_name).value.replace(i,e.js_key)}}function apbct_public_sendAJAX(t,n,o){var i=n.callback||null,a=n.callback_context||null,c=n.callback_params||null,e=n.async||!0,l=n.notJson||null,s=n.timeout||15e3,r=(o=o||null,n.button||null),u=n.spinner||null,p=n.progressbar||null,d=n.silent||null,m=n.no_nonce||null;"string"==typeof t?(m||(t=t+"&_ajax_nonce="+ctPublic._ajax_nonce),t=t+"&no_cache="+Math.random()):(m||(t._ajax_nonce=ctPublic._ajax_nonce),t.no_cache=Math.random()),r&&(r.setAttribute("disabled","disabled"),r.style.cursor="not-allowed"),u&&jQuery(u).css("display","inline"),jQuery.ajax({type:"POST",url:ctPublic._ajax_url,data:t,async:e,success:function(e){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),l||(e=JSON.parse(e)),e.error?(setTimeout(function(){p&&p.fadeOut("slow")},1e3),alert("Error happens: "+(e.error||"Unkown"))):i&&(c?i.apply(a,c.concat(e,t,n,o)):i(e,t,n,o))},error:function(e,t,n){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),n&&!d&&(console.log("APBCT_AJAX_ERROR"),console.log(e),console.log(t),console.log("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"),alert("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"))},timeout:s})}!function(){var e=new Date,t=(new Date).getTime(),n=!0,o=[],i=0;function a(e,t,n){"function"==typeof window.addEventListener?e.addEventListener(t,n):e.attachEvent(t,n)}function c(e,t,n){"function"==typeof window.removeEventListener?e.removeEventListener(t,n):e.detachEvent(t,n)}ctSetCookie("ct_ps_timestamp",Math.floor((new Date).getTime()/1e3)),ctSetCookie("ct_fkp_timestamp","0"),ctSetCookie("ct_pointer_data","0"),ctSetCookie("ct_timezone","0"),setTimeout(function(){ctSetCookie("ct_timezone",e.getTimezoneOffset()/60*-1)},1e3);var l=function(e){ctSetCookie("ct_fkp_timestamp",Math.floor((new Date).getTime()/1e3)),c(window,"mousedown",l),c(window,"keydown",l)},s=setInterval(function(){n=!0},150),r=setInterval(function(){ctSetCookie("ct_pointer_data",JSON.stringify(o))},1200),u=function(e){!0===n&&(o.push([Math.round(e.clientY),Math.round(e.clientX),Math.round((new Date).getTime()-t)]),n=!1,50<=++i&&(c(window,"mousemove",u),clearInterval(s),clearInterval(r)))};a(window,"mousemove",u),a(window,"mousedown",l),a(window,"keydown",l),a(window,"DOMContentLoaded",function(){ctSetCookie("apbct_visible_fields",0),ctSetCookie("apbct_visible_fields_count",0),setTimeout(function(){for(var e=0;e<document.forms.length;e++){var t=document.forms[e];t.classList.contains("slp_search_form")||t.parentElement.classList.contains("mec-booking")||t.action.toString().indexOf("activehosted.com")||t.id&&"caspioform"==t.id||-1!==action.indexOf("activehosted.com")&&(t.onsubmit_prev=t.onsubmit,t.onsubmit=function(e){e.preventDefault(),apbct_collect_visible_fields_and_set_cookie(this),e.target.onsubmit_prev instanceof Function&&setTimeout(function(){e.target.onsubmit_prev.call(e.target,e)},500)})}},1e3)})}(),"undefined"!=typeof jQuery&&jQuery(document).ajaxComplete(function(e,t,n){if(t.responseText&&-1!==t.responseText.indexOf('"apbct')){var o=JSON.parse(t.responseText);void 0!==o.apbct&&(o=o.apbct).blocked&&(alert(o.comment),1==+o.stop_script&&window.stop())}});
2
  //# sourceMappingURL=apbct-public.min.js.map
1
+ function ctSetCookie(e,t){document.cookie=e+"="+encodeURIComponent(t)+"; path=/; samesite=lax"}function apbct_collect_visible_fields_and_set_cookie(e){var t=[],o="",n=0,i=[];for(var a in e.elements)isNaN(+a)||(t[a]=e.elements[a]);(t=t.filter(function(e){return"none"!==getComputedStyle(e).display&&"hidden"!==getComputedStyle(e).visibility&&"0"!==getComputedStyle(e).opacity&&"hidden"!==e.getAttribute("type")&&"submit"!==e.getAttribute("type")&&""!==e.value&&null!==e.getAttribute("name")&&-1===i.indexOf(e.getAttribute("name"))&&(n++,-1===["radio","checkbox"].indexOf(e.getAttribute("type"))||(i.push(e.getAttribute("name")),!1))})).forEach(function(e,t,n){o+=" "+e.getAttribute("name")}),ctSetCookie("apbct_visible_fields",o=o.trim()),ctSetCookie("apbct_visible_fields_count",n)}function apbct_js_keys__set_input_value(e,t,n,o){var i;null!==document.getElementById(n.input_name)&&(i=document.getElementById(n.input_name).value,document.getElementById(n.input_name).value=document.getElementById(n.input_name).value.replace(i,e.js_key))}function apbct_public_sendAJAX(t,n,o){var i=n.callback||null,a=n.callback_context||null,c=n.callback_params||null,e=n.async||!0,l=n.notJson||null,s=n.timeout||15e3,o=o||null,r=n.button||null,u=n.spinner||null,p=n.progressbar||null,d=n.silent||null,m=n.no_nonce||null;"string"==typeof t?(m||(t=t+"&_ajax_nonce="+ctPublic._ajax_nonce),t=t+"&no_cache="+Math.random()):(m||(t._ajax_nonce=ctPublic._ajax_nonce),t.no_cache=Math.random()),r&&(r.setAttribute("disabled","disabled"),r.style.cursor="not-allowed"),u&&jQuery(u).css("display","inline"),jQuery.ajax({type:"POST",url:ctPublic._ajax_url,data:t,async:e,success:function(e){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),l||(e=JSON.parse(e)),e.error?(setTimeout(function(){p&&p.fadeOut("slow")},1e3),alert("Error happens: "+(e.error||"Unkown"))):i&&(c?i.apply(a,c.concat(e,t,n,o)):i(e,t,n,o))},error:function(e,t,n){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),n&&!d&&(console.log("APBCT_AJAX_ERROR"),console.log(e),console.log(t),console.log("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"),alert("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"))},timeout:s})}!function(){var e=new Date,t=(new Date).getTime(),n=!0,o=[],i=0;function a(e,t,n){"function"==typeof window.addEventListener?e.addEventListener(t,n):e.attachEvent(t,n)}function c(e,t,n){"function"==typeof window.removeEventListener?e.removeEventListener(t,n):e.detachEvent(t,n)}ctSetCookie("ct_ps_timestamp",Math.floor((new Date).getTime()/1e3)),ctSetCookie("ct_fkp_timestamp","0"),ctSetCookie("ct_pointer_data","0"),ctSetCookie("ct_timezone","0"),setTimeout(function(){ctSetCookie("ct_timezone",e.getTimezoneOffset()/60*-1)},1e3);var l=function(){ctSetCookie("ct_fkp_timestamp",Math.floor((new Date).getTime()/1e3)),c(window,"mousedown",l),c(window,"keydown",l)},s=setInterval(function(){n=!0},150),r=setInterval(function(){ctSetCookie("ct_pointer_data",JSON.stringify(o))},1200),u=function(e){!0===n&&(o.push([Math.round(e.clientY),Math.round(e.clientX),Math.round((new Date).getTime()-t)]),n=!1,50<=++i&&(c(window,"mousemove",u),clearInterval(s),clearInterval(r)))};a(window,"mousemove",u),a(window,"mousedown",l),a(window,"keydown",l),a(window,"DOMContentLoaded",function(){ctSetCookie("apbct_visible_fields",0),ctSetCookie("apbct_visible_fields_count",0),setTimeout(function(){for(var e=0;e<document.forms.length;e++){var t=document.forms[e];t.classList.contains("slp_search_form")||t.parentElement.classList.contains("mec-booking")||-1!==t.action.toString().indexOf("activehosted.com")||t.id&&"caspioform"==t.id||(t.onsubmit_prev=t.onsubmit,t.onsubmit=function(e){apbct_collect_visible_fields_and_set_cookie(this),e.target.onsubmit_prev instanceof Function&&setTimeout(function(){e.target.onsubmit_prev.call(e.target,e)},500)})}},1e3)})}(),"undefined"!=typeof jQuery&&jQuery(document).ajaxComplete(function(e,t,n){var o;!t.responseText||-1===t.responseText.indexOf('"apbct')||void 0!==(o=JSON.parse(t.responseText)).apbct&&(o=o.apbct).blocked&&(alert(o.comment),1==+o.stop_script&&window.stop())});
2
  //# sourceMappingURL=apbct-public.min.js.map
js/apbct-public.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["apbct-public.js"],"names":["ctSetCookie","c_name","value","document","cookie","encodeURIComponent","apbct_collect_visible_fields_and_set_cookie","form","inputs","inputs_visible","inputs_visible_count","inputs_with_duplicate_names","key","elements","isNaN","filter","elem","getComputedStyle","display","visibility","opacity","getAttribute","indexOf","push","forEach","i","trim","apbct_js_keys__set_input_value","result","data","params","obj","getElementById","input_name","ct_input_value","replace","js_key","apbct_public_sendAJAX","callback","callback_context","callback_params","async","notJson","timeout","button","spinner","progressbar","silent","no_nonce","ctPublic","_ajax_nonce","Math","random","no_cache","setAttribute","style","cursor","jQuery","css","ajax","type","url","_ajax_url","success","removeAttribute","JSON","parse","error","setTimeout","fadeOut","alert","apply","concat","jqXHR","textStatus","errorThrown","console","log","ct_date","Date","ctTimeMs","getTime","ctMouseEventTimerFlag","ctMouseData","ctMouseDataCounter","apbct_attach_event_handler","event","window","addEventListener","attachEvent","apbct_remove_event_handler","removeEventListener","detachEvent","floor","getTimezoneOffset","ctFunctionFirstKey","ctMouseReadInterval","setInterval","ctMouseWriteDataInterval","stringify","ctFunctionMouseMove","round","clientY","clientX","clearInterval","forms","length","classList","contains","parentElement","action","toString","id","onsubmit_prev","onsubmit","preventDefault","this","target","Function","call","ajaxComplete","xhr","settings","responseText","response","apbct","blocked","comment","stop_script","stop"],"mappings":"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","file":"apbct-public.min.js","sourcesContent":["(function() {\n\n\tvar ct_date = new Date(),\n\t\tctTimeMs = new Date().getTime(),\n\t\tctMouseEventTimerFlag = true, //Reading interval flag\n\t\tctMouseData = [],\n\t\tctMouseDataCounter = 0;\n\n\tfunction apbct_attach_event_handler(elem, event, callback){\n\t\tif(typeof window.addEventListener === \"function\") elem.addEventListener(event, callback);\n\t\telse elem.attachEvent(event, callback);\n\t}\n\n\tfunction apbct_remove_event_handler(elem, event, callback){\n\t\tif(typeof window.removeEventListener === \"function\") elem.removeEventListener(event, callback);\n\t\telse elem.detachEvent(event, callback);\n\t}\n\n\tctSetCookie(\"ct_ps_timestamp\", Math.floor(new Date().getTime()/1000));\n\tctSetCookie(\"ct_fkp_timestamp\", \"0\");\n\tctSetCookie(\"ct_pointer_data\", \"0\");\n\tctSetCookie(\"ct_timezone\", \"0\");\n\n\tsetTimeout(function(){\n\t\tctSetCookie(\"ct_timezone\", ct_date.getTimezoneOffset()/60*(-1));\n\t},1000);\n\n\t//Writing first key press timestamp\n\tvar ctFunctionFirstKey = function output(event){\n\t\tvar KeyTimestamp = Math.floor(new Date().getTime()/1000);\n\t\tctSetCookie(\"ct_fkp_timestamp\", KeyTimestamp);\n\t\tctKeyStopStopListening();\n\t};\n\n\t//Reading interval\n\tvar ctMouseReadInterval = setInterval(function(){\n\t\tctMouseEventTimerFlag = true;\n\t}, 150);\n\n\t//Writting interval\n\tvar ctMouseWriteDataInterval = setInterval(function(){\n\t\tctSetCookie(\"ct_pointer_data\", JSON.stringify(ctMouseData));\n\t}, 1200);\n\n\t//Logging mouse position each 150 ms\n\tvar ctFunctionMouseMove = function output(event){\n\t\tif(ctMouseEventTimerFlag === true){\n\n\t\t\tctMouseData.push([\n\t\t\t\tMath.round(event.clientY),\n\t\t\t\tMath.round(event.clientX),\n\t\t\t\tMath.round(new Date().getTime() - ctTimeMs)\n\t\t\t]);\n\n\t\t\tctMouseDataCounter++;\n\t\t\tctMouseEventTimerFlag = false;\n\t\t\tif(ctMouseDataCounter >= 50){\n\t\t\t\tctMouseStopData();\n\t\t\t}\n\t\t}\n\t};\n\n\t//Stop mouse observing function\n\tfunction ctMouseStopData(){\n\t\tapbct_remove_event_handler(window, \"mousemove\", ctFunctionMouseMove);\n\t\tclearInterval(ctMouseReadInterval);\n\t\tclearInterval(ctMouseWriteDataInterval);\n\t}\n\n\t//Stop key listening function\n\tfunction ctKeyStopStopListening(){\n\t\tapbct_remove_event_handler(window, \"mousedown\", ctFunctionFirstKey);\n\t\tapbct_remove_event_handler(window, \"keydown\", ctFunctionFirstKey);\n\t}\n\n\tapbct_attach_event_handler(window, \"mousemove\", ctFunctionMouseMove);\n\tapbct_attach_event_handler(window, \"mousedown\", ctFunctionFirstKey);\n\tapbct_attach_event_handler(window, \"keydown\", ctFunctionFirstKey);\n\n\t// Ready function\n\tfunction apbct_ready(){\n\n\t\tctSetCookie(\"apbct_visible_fields\", 0);\n\t\tctSetCookie(\"apbct_visible_fields_count\", 0);\n\n\t\tsetTimeout(function(){\n\n\t\t\tfor(var i = 0; i < document.forms.length; i++){\n\t\t\t\tvar form = document.forms[i];\n\n\t\t\t\t//Exclusion for forms\n\t\t\t\tif (\n\t\t\t\t\tform.classList.contains('slp_search_form') || //StoreLocatorPlus form\n\t\t\t\t\tform.parentElement.classList.contains('mec-booking') ||\n\t\t\t\t\tform.action.toString().indexOf('activehosted.com') || // Active Campaign\n\t\t\t\t\t(form.id && form.id == 'caspioform') //Caspio Form\n\t\t\t\t)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif(\n\t\t\t\t\taction.indexOf('activehosted.com') !== -1 // Exclusion for ActiveCampaign\n\n\t\t\t\t) {\n\n\t\t\t\t\tform.onsubmit_prev = form.onsubmit;\n\t\t\t\t\tform.onsubmit = function (event) {\n\n\t\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t\tapbct_collect_visible_fields_and_set_cookie(this);\n\n\t\t\t\t\t\t// Call previous submit action\n\t\t\t\t\t\tif (event.target.onsubmit_prev instanceof Function) {\n\t\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\t\tevent.target.onsubmit_prev.call(event.target, event);\n\t\t\t\t\t\t\t}, 500);\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}, 1000);\n\t}\n\tapbct_attach_event_handler(window, \"DOMContentLoaded\", apbct_ready);\n\n}());\n\nfunction ctSetCookie(c_name, value) {\n\tdocument.cookie = c_name + \"=\" + encodeURIComponent(value) + \"; path=/; samesite=lax\";\n}\n\nfunction apbct_collect_visible_fields_and_set_cookie(form ) {\n\n\t// Get only fields\n\tvar inputs = [],\n\t\tinputs_visible = '',\n\t\tinputs_visible_count = 0,\n\t\tinputs_with_duplicate_names = [];\n\n\tfor(var key in form.elements){\n\t\tif(!isNaN(+key))\n\t\t\tinputs[key] = form.elements[key];\n\t}\n\n\t// Filter fields\n\tinputs = inputs.filter(function(elem){\n\n\t\t// Filter fields\n\t\tif( getComputedStyle(elem).display === \"none\" || // hidden\n\t\t\tgetComputedStyle(elem).visibility === \"hidden\" || // hidden\n\t\t\tgetComputedStyle(elem).opacity === \"0\" || // hidden\n\t\t\telem.getAttribute(\"type\") === \"hidden\" || // type == hidden\n\t\t\telem.getAttribute(\"type\") === \"submit\" || // type == submit\n\t\t\telem.value === \"\" || // empty value\n\t\t\telem.getAttribute('name') === null ||\n\t\t\tinputs_with_duplicate_names.indexOf( elem.getAttribute('name') ) !== -1 // name already added\n\t\t){\n\t\t\treturn false;\n\t\t}\n\n\t\t// Visible fields count\n\t\tinputs_visible_count++;\n\n\t\t// Filter inputs with same names for type == radio\n\t\tif( -1 !== ['radio', 'checkbox'].indexOf( elem.getAttribute(\"type\") )){\n\t\t\tinputs_with_duplicate_names.push( elem.getAttribute('name') );\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t});\n\n\t// Visible fields\n\tinputs.forEach(function(elem, i, elements){\n\t\tinputs_visible += \" \" + elem.getAttribute(\"name\");\n\t});\n\tinputs_visible = inputs_visible.trim();\n\n\tctSetCookie(\"apbct_visible_fields\", inputs_visible);\n\tctSetCookie(\"apbct_visible_fields_count\", inputs_visible_count);\n\n}\n\nfunction apbct_js_keys__set_input_value(result, data, params, obj){\n\tif (document.getElementById(params.input_name) !== null) {\n\t\tvar ct_input_value = document.getElementById(params.input_name).value;\n\t\tdocument.getElementById(params.input_name).value = document.getElementById(params.input_name).value.replace(ct_input_value, result.js_key);\n\t}\n}\nfunction apbct_public_sendAJAX(data, params, obj){\n\n\t// Default params\n\tvar callback = params.callback || null;\n\tvar callback_context = params.callback_context || null;\n\tvar callback_params = params.callback_params || null;\n\tvar async = params.async || true;\n\tvar notJson = params.notJson || null;\n\tvar timeout = params.timeout || 15000;\n\tvar obj = obj || null;\n\tvar button = params.button || null;\n\tvar spinner = params.spinner || null;\n\tvar progressbar = params.progressbar || null;\n\tvar silent = params.silent || null;\n\tvar no_nonce = params.no_nonce || null;\n\n\tif(typeof (data) === 'string') {\n\t\tif( ! no_nonce )\n\t\t\tdata = data + '&_ajax_nonce=' + ctPublic._ajax_nonce;\n\t\tdata = data + '&no_cache=' + Math.random()\n\t} else {\n\t\tif( ! no_nonce )\n\t\t\tdata._ajax_nonce = ctPublic._ajax_nonce;\n\t\tdata.no_cache = Math.random();\n\t}\n\t// Button and spinner\n\tif(button) {button.setAttribute('disabled', 'disabled'); button.style.cursor = 'not-allowed'; }\n\tif(spinner) jQuery(spinner).css('display', 'inline');\n\n\tjQuery.ajax({\n\t\ttype: \"POST\",\n\t\turl: ctPublic._ajax_url,\n\t\tdata: data,\n\t\tasync: async,\n\t\tsuccess: function(result){\n\t\t\tif(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\n\t\t\tif(spinner) jQuery(spinner).css('display', 'none');\n\t\t\tif(!notJson) result = JSON.parse(result);\n\t\t\tif(result.error){\n\t\t\t\tsetTimeout(function(){ if(progressbar) progressbar.fadeOut('slow'); }, 1000);\n\t\t\t\talert('Error happens: ' + (result.error || 'Unkown'));\n\t\t\t}else{\n\t\t\t\tif(callback) {\n\t\t\t\t\tif (callback_params)\n\t\t\t\t\t\tcallback.apply( callback_context, callback_params.concat( result, data, params, obj ) );\n\t\t\t\t\telse\n\t\t\t\t\t\tcallback(result, data, params, obj);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\terror: function(jqXHR, textStatus, errorThrown){\n\t\t\tif(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\n\t\t\tif(spinner) jQuery(spinner).css('display', 'none');\n\t\t\tif( errorThrown && ! silent ) {\n\t\t\t\tconsole.log('APBCT_AJAX_ERROR');\n\t\t\t\tconsole.log(jqXHR);\n\t\t\t\tconsole.log(textStatus);\n\t\t\t\tconsole.log('Anti-spam by Cleantalk plugin error: ' + errorThrown + 'Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\n\t\t\t\talert('Anti-spam by Cleantalk plugin error: ' + errorThrown + 'Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\n\t\t\t}\n\t\t},\n\t\ttimeout: timeout,\n\t});\n}\nif(typeof jQuery !== 'undefined') {\n\n\t// Capturing responses and output block message for unknown AJAX forms\n\tjQuery(document).ajaxComplete(function (event, xhr, settings) {\n\t\tif (xhr.responseText && xhr.responseText.indexOf('\"apbct') !== -1) {\n\t\t\tvar response = JSON.parse(xhr.responseText);\n\t\t\tif (typeof response.apbct !== 'undefined') {\n\t\t\t\tresponse = response.apbct;\n\t\t\t\tif (response.blocked) {\n\t\t\t\t\talert(response.comment);\n\t\t\t\t\tif(+response.stop_script == 1)\n\t\t\t\t\t\twindow.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n}"]}
1
+ {"version":3,"file":"apbct-public.min.js","sources":["apbct-public.js"],"sourcesContent":["(function() {\r\n\r\n\tvar ct_date = new Date(),\r\n\t\tctTimeMs = new Date().getTime(),\r\n\t\tctMouseEventTimerFlag = true, //Reading interval flag\r\n\t\tctMouseData = [],\r\n\t\tctMouseDataCounter = 0;\r\n\r\n\tfunction apbct_attach_event_handler(elem, event, callback){\r\n\t\tif(typeof window.addEventListener === \"function\") elem.addEventListener(event, callback);\r\n\t\telse elem.attachEvent(event, callback);\r\n\t}\r\n\r\n\tfunction apbct_remove_event_handler(elem, event, callback){\r\n\t\tif(typeof window.removeEventListener === \"function\") elem.removeEventListener(event, callback);\r\n\t\telse elem.detachEvent(event, callback);\r\n\t}\r\n\r\n\tctSetCookie(\"ct_ps_timestamp\", Math.floor(new Date().getTime()/1000));\r\n\tctSetCookie(\"ct_fkp_timestamp\", \"0\");\r\n\tctSetCookie(\"ct_pointer_data\", \"0\");\r\n\tctSetCookie(\"ct_timezone\", \"0\");\r\n\r\n\tsetTimeout(function(){\r\n\t\tctSetCookie(\"ct_timezone\", ct_date.getTimezoneOffset()/60*(-1));\r\n\t},1000);\r\n\r\n\t//Writing first key press timestamp\r\n\tvar ctFunctionFirstKey = function output(event){\r\n\t\tvar KeyTimestamp = Math.floor(new Date().getTime()/1000);\r\n\t\tctSetCookie(\"ct_fkp_timestamp\", KeyTimestamp);\r\n\t\tctKeyStopStopListening();\r\n\t};\r\n\r\n\t//Reading interval\r\n\tvar ctMouseReadInterval = setInterval(function(){\r\n\t\tctMouseEventTimerFlag = true;\r\n\t}, 150);\r\n\r\n\t//Writting interval\r\n\tvar ctMouseWriteDataInterval = setInterval(function(){\r\n\t\tctSetCookie(\"ct_pointer_data\", JSON.stringify(ctMouseData));\r\n\t}, 1200);\r\n\r\n\t//Logging mouse position each 150 ms\r\n\tvar ctFunctionMouseMove = function output(event){\r\n\t\tif(ctMouseEventTimerFlag === true){\r\n\r\n\t\t\tctMouseData.push([\r\n\t\t\t\tMath.round(event.clientY),\r\n\t\t\t\tMath.round(event.clientX),\r\n\t\t\t\tMath.round(new Date().getTime() - ctTimeMs)\r\n\t\t\t]);\r\n\r\n\t\t\tctMouseDataCounter++;\r\n\t\t\tctMouseEventTimerFlag = false;\r\n\t\t\tif(ctMouseDataCounter >= 50){\r\n\t\t\t\tctMouseStopData();\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t//Stop mouse observing function\r\n\tfunction ctMouseStopData(){\r\n\t\tapbct_remove_event_handler(window, \"mousemove\", ctFunctionMouseMove);\r\n\t\tclearInterval(ctMouseReadInterval);\r\n\t\tclearInterval(ctMouseWriteDataInterval);\r\n\t}\r\n\r\n\t//Stop key listening function\r\n\tfunction ctKeyStopStopListening(){\r\n\t\tapbct_remove_event_handler(window, \"mousedown\", ctFunctionFirstKey);\r\n\t\tapbct_remove_event_handler(window, \"keydown\", ctFunctionFirstKey);\r\n\t}\r\n\r\n\tapbct_attach_event_handler(window, \"mousemove\", ctFunctionMouseMove);\r\n\tapbct_attach_event_handler(window, \"mousedown\", ctFunctionFirstKey);\r\n\tapbct_attach_event_handler(window, \"keydown\", ctFunctionFirstKey);\r\n\r\n\t// Ready function\r\n\tfunction apbct_ready(){\r\n\r\n\t\tctSetCookie(\"apbct_visible_fields\", 0);\r\n\t\tctSetCookie(\"apbct_visible_fields_count\", 0);\r\n\r\n\t\tsetTimeout(function(){\r\n\r\n\t\t\tfor(var i = 0; i < document.forms.length; i++){\r\n\t\t\t\tvar form = document.forms[i];\r\n\r\n\t\t\t\t//Exclusion for forms\r\n\t\t\t\tif (\r\n\t\t\t\t\tform.classList.contains('slp_search_form') || //StoreLocatorPlus form\r\n\t\t\t\t\tform.parentElement.classList.contains('mec-booking') ||\r\n\t\t\t\t\tform.action.toString().indexOf('activehosted.com') !== -1 || // Active Campaign\r\n\t\t\t\t\t(form.id && form.id == 'caspioform') //Caspio Form\r\n\t\t\t\t)\r\n\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\tform.onsubmit_prev = form.onsubmit;\r\n\t\t\t\tform.onsubmit = function (event) {\r\n\r\n\t\t\t\t\tapbct_collect_visible_fields_and_set_cookie(this);\r\n\r\n\t\t\t\t\t// Call previous submit action\r\n\t\t\t\t\tif (event.target.onsubmit_prev instanceof Function) {\r\n\t\t\t\t\t\tsetTimeout(function () {\r\n\t\t\t\t\t\t\tevent.target.onsubmit_prev.call(event.target, event);\r\n\t\t\t\t\t\t}, 500);\r\n\t\t\t\t\t}\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}, 1000);\r\n\t}\r\n\tapbct_attach_event_handler(window, \"DOMContentLoaded\", apbct_ready);\r\n\r\n}());\r\n\r\nfunction ctSetCookie(c_name, value) {\r\n\tdocument.cookie = c_name + \"=\" + encodeURIComponent(value) + \"; path=/; samesite=lax\";\r\n}\r\n\r\nfunction apbct_collect_visible_fields_and_set_cookie(form ) {\r\n\r\n\t// Get only fields\r\n\tvar inputs = [],\r\n\t\tinputs_visible = '',\r\n\t\tinputs_visible_count = 0,\r\n\t\tinputs_with_duplicate_names = [];\r\n\r\n\tfor(var key in form.elements){\r\n\t\tif(!isNaN(+key))\r\n\t\t\tinputs[key] = form.elements[key];\r\n\t}\r\n\r\n\t// Filter fields\r\n\tinputs = inputs.filter(function(elem){\r\n\r\n\t\t// Filter fields\r\n\t\tif( getComputedStyle(elem).display === \"none\" || // hidden\r\n\t\t\tgetComputedStyle(elem).visibility === \"hidden\" || // hidden\r\n\t\t\tgetComputedStyle(elem).opacity === \"0\" || // hidden\r\n\t\t\telem.getAttribute(\"type\") === \"hidden\" || // type == hidden\r\n\t\t\telem.getAttribute(\"type\") === \"submit\" || // type == submit\r\n\t\t\telem.value === \"\" || // empty value\r\n\t\t\telem.getAttribute('name') === null ||\r\n\t\t\tinputs_with_duplicate_names.indexOf( elem.getAttribute('name') ) !== -1 // name already added\r\n\t\t){\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t// Visible fields count\r\n\t\tinputs_visible_count++;\r\n\r\n\t\t// Filter inputs with same names for type == radio\r\n\t\tif( -1 !== ['radio', 'checkbox'].indexOf( elem.getAttribute(\"type\") )){\r\n\t\t\tinputs_with_duplicate_names.push( elem.getAttribute('name') );\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t});\r\n\r\n\t// Visible fields\r\n\tinputs.forEach(function(elem, i, elements){\r\n\t\tinputs_visible += \" \" + elem.getAttribute(\"name\");\r\n\t});\r\n\tinputs_visible = inputs_visible.trim();\r\n\r\n\tctSetCookie(\"apbct_visible_fields\", inputs_visible);\r\n\tctSetCookie(\"apbct_visible_fields_count\", inputs_visible_count);\r\n\r\n}\r\n\r\nfunction apbct_js_keys__set_input_value(result, data, params, obj){\r\n\tif (document.getElementById(params.input_name) !== null) {\r\n\t\tvar ct_input_value = document.getElementById(params.input_name).value;\r\n\t\tdocument.getElementById(params.input_name).value = document.getElementById(params.input_name).value.replace(ct_input_value, result.js_key);\r\n\t}\r\n}\r\nfunction apbct_public_sendAJAX(data, params, obj){\r\n\r\n\t// Default params\r\n\tvar callback = params.callback || null;\r\n\tvar callback_context = params.callback_context || null;\r\n\tvar callback_params = params.callback_params || null;\r\n\tvar async = params.async || true;\r\n\tvar notJson = params.notJson || null;\r\n\tvar timeout = params.timeout || 15000;\r\n\tvar obj = obj || null;\r\n\tvar button = params.button || null;\r\n\tvar spinner = params.spinner || null;\r\n\tvar progressbar = params.progressbar || null;\r\n\tvar silent = params.silent || null;\r\n\tvar no_nonce = params.no_nonce || null;\r\n\r\n\tif(typeof (data) === 'string') {\r\n\t\tif( ! no_nonce )\r\n\t\t\tdata = data + '&_ajax_nonce=' + ctPublic._ajax_nonce;\r\n\t\tdata = data + '&no_cache=' + Math.random()\r\n\t} else {\r\n\t\tif( ! no_nonce )\r\n\t\t\tdata._ajax_nonce = ctPublic._ajax_nonce;\r\n\t\tdata.no_cache = Math.random();\r\n\t}\r\n\t// Button and spinner\r\n\tif(button) {button.setAttribute('disabled', 'disabled'); button.style.cursor = 'not-allowed'; }\r\n\tif(spinner) jQuery(spinner).css('display', 'inline');\r\n\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ctPublic._ajax_url,\r\n\t\tdata: data,\r\n\t\tasync: async,\r\n\t\tsuccess: function(result){\r\n\t\t\tif(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\r\n\t\t\tif(spinner) jQuery(spinner).css('display', 'none');\r\n\t\t\tif(!notJson) result = JSON.parse(result);\r\n\t\t\tif(result.error){\r\n\t\t\t\tsetTimeout(function(){ if(progressbar) progressbar.fadeOut('slow'); }, 1000);\r\n\t\t\t\talert('Error happens: ' + (result.error || 'Unkown'));\r\n\t\t\t}else{\r\n\t\t\t\tif(callback) {\r\n\t\t\t\t\tif (callback_params)\r\n\t\t\t\t\t\tcallback.apply( callback_context, callback_params.concat( result, data, params, obj ) );\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tcallback(result, data, params, obj);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\terror: function(jqXHR, textStatus, errorThrown){\r\n\t\t\tif(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\r\n\t\t\tif(spinner) jQuery(spinner).css('display', 'none');\r\n\t\t\tif( errorThrown && ! silent ) {\r\n\t\t\t\tconsole.log('APBCT_AJAX_ERROR');\r\n\t\t\t\tconsole.log(jqXHR);\r\n\t\t\t\tconsole.log(textStatus);\r\n\t\t\t\tconsole.log('Anti-spam by Cleantalk plugin error: ' + errorThrown + 'Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\r\n\t\t\t\talert('Anti-spam by Cleantalk plugin error: ' + errorThrown + 'Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\r\n\t\t\t}\r\n\t\t},\r\n\t\ttimeout: timeout,\r\n\t});\r\n}\r\nif(typeof jQuery !== 'undefined') {\r\n\r\n\t// Capturing responses and output block message for unknown AJAX forms\r\n\tjQuery(document).ajaxComplete(function (event, xhr, settings) {\r\n\t\tif (xhr.responseText && xhr.responseText.indexOf('\"apbct') !== -1) {\r\n\t\t\tvar response = JSON.parse(xhr.responseText);\r\n\t\t\tif (typeof response.apbct !== 'undefined') {\r\n\t\t\t\tresponse = response.apbct;\r\n\t\t\t\tif (response.blocked) {\r\n\t\t\t\t\talert(response.comment);\r\n\t\t\t\t\tif(+response.stop_script == 1)\r\n\t\t\t\t\t\twindow.stop();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n}"],"names":["ctSetCookie","c_name","value","document","cookie","encodeURIComponent","apbct_collect_visible_fields_and_set_cookie","form","inputs","inputs_visible","inputs_visible_count","inputs_with_duplicate_names","key","elements","isNaN","filter","elem","getComputedStyle","display","visibility","opacity","getAttribute","indexOf","push","forEach","i","trim","apbct_js_keys__set_input_value","result","data","params","obj","ct_input_value","getElementById","input_name","replace","js_key","apbct_public_sendAJAX","callback","callback_context","callback_params","async","notJson","timeout","button","spinner","progressbar","silent","no_nonce","ctPublic","_ajax_nonce","Math","random","no_cache","setAttribute","style","cursor","jQuery","css","ajax","type","url","_ajax_url","success","removeAttribute","JSON","parse","error","setTimeout","fadeOut","alert","apply","concat","jqXHR","textStatus","errorThrown","console","log","ct_date","Date","ctTimeMs","getTime","ctMouseEventTimerFlag","ctMouseData","ctMouseDataCounter","apbct_attach_event_handler","event","window","addEventListener","attachEvent","apbct_remove_event_handler","removeEventListener","detachEvent","floor","getTimezoneOffset","ctFunctionFirstKey","ctMouseReadInterval","setInterval","ctMouseWriteDataInterval","stringify","ctFunctionMouseMove","round","clientY","clientX","clearInterval","forms","length","classList","contains","parentElement","action","toString","id","onsubmit_prev","onsubmit","this","target","Function","call","ajaxComplete","xhr","settings","response","responseText","apbct","blocked","comment","stop_script","stop"],"mappings":"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"}
js/cleantalk-comments-checkspam.min.js CHANGED
@@ -1,2 +1,2 @@
1
- var ct_working=!(String.prototype.printf=function(){var e=this;for(var t in arguments)var c=e.substring(0,e.indexOf("%s",0)),_=e.substring(e.indexOf("%s",0)+2,e.length),e=c+arguments[t]+_;return e}),ct_new_check=!0,ct_cooling_down_flag=!1,ct_close_animate=!0,ct_accurate_check=!1,ct_pause=!1,ct_prev_accurate=ctCommentsCheck.ct_prev_accurate,ct_prev_from=ctCommentsCheck.ct_prev_from,ct_prev_till=ctCommentsCheck.ct_prev_till,ct_cool_down_time=9e4,ct_requests_counter=0,ct_max_requests=60,ct_ajax_nonce=ctCommentsCheck.ct_ajax_nonce,ct_comments_total=0,ct_comments_checked=0,ct_comments_spam=0,ct_comments_bad=0,ct_unchecked="unset",ct_date_from=0,ct_date_till=0;function animate_comment(e,t){ct_close_animate?.3==e?jQuery("#comment-"+t).fadeTo(200,e,function(){animate_comment(1,t)}):jQuery("#comment-"+t).fadeTo(200,e,function(){animate_comment(.3,t)}):ct_close_animate=!0}function ct_clear_comments(){var e=0,t=0;jQuery("#ct_allow_date_range").is(":checked")&&(e=jQuery("#ct_date_range_from").val(),t=jQuery("#ct_date_range_till").val());var c={action:"ajax_clear_comments",security:ct_ajax_nonce,from:e,till:t};jQuery.ajax({type:"POST",url:ajaxurl,data:c,success:function(e){ct_show_info(),ct_send_comments()}})}function ct_cooling_down_toggle(){ct_cooling_down_flag=!1,ct_send_comments(),ct_show_info()}function ct_send_comments(){if(!0!==ct_cooling_down_flag){if(ct_max_requests<=ct_requests_counter)return setTimeout(ct_cooling_down_toggle,ct_cool_down_time),void(ct_cooling_down_flag=!(ct_requests_counter=0));ct_requests_counter++;var e={action:"ajax_check_comments",security:ct_ajax_nonce,new_check:ct_new_check,unchecked:ct_unchecked};ct_accurate_check&&(e.accurate_check=!0),ct_date_from&&ct_date_till&&(e.from=ct_date_from,e.till=ct_date_till),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){var t,c;e=jQuery.parseJSON(e),parseInt(e.error)?(ct_working=!1,confirm(e.error_message+". Do you want to proceed?")?ct_send_comments():(t="edit-comments.php?page=ct_check_spam",0!=ct_date_from&&0!=ct_date_till&&(t+="&from="+ct_date_from+"&till="+ct_date_till),location.href=t)):(ct_new_check=!1,1==parseInt(e.end)||!0===ct_pause?(1==parseInt(e.end)&&(document.cookie="ct_paused_spam_check=0; path=/; samesite=lax"),ct_working=!1,jQuery("#ct_working_message").hide(),t="edit-comments.php?page=ct_check_spam",0!=ct_date_from&&0!=ct_date_till&&(t+="&from="+ct_date_from+"&till="+ct_date_till),location.href=t):0==parseInt(e.end)&&(ct_comments_checked+=e.checked,ct_comments_spam+=e.spam,ct_comments_bad+=e.bad,ct_unchecked=ct_comments_total-ct_comments_checked-ct_comments_bad,c=(c=String(ctCommentsCheck.ct_status_string)).printf(ct_comments_checked,ct_comments_spam,ct_comments_bad),0<parseInt(ct_comments_spam)&&(c+=ctCommentsCheck.ct_status_string_warning),jQuery("#ct_checking_status").html(c),jQuery("#ct_error_message").hide(),+ct_comments_total<ct_comments_checked+ct_comments_bad&&(document.cookie="ct_comments_start_check=1; path=/; samesite=lax",document.cookie="ct_comments_safe_check=1; path=/; samesite=lax",location.href="edit-comments.php?page=ct_check_spam"),ct_send_comments()))},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Check comments"),setTimeout(ct_send_comments(),3e3)},timeout:25e3})}}function ct_show_info(){if(ct_working){if(1==ct_cooling_down_flag)return jQuery("#ct_cooling_notice").html("Waiting for API to cool down. (About a minute)"),void jQuery("#ct_cooling_notice").show();var e;jQuery("#ct_cooling_notice").hide(),ct_comments_total||(e={action:"ajax_info_comments",security:ct_ajax_nonce},ct_date_from&&ct_date_till&&(e.from=ct_date_from,e.till=ct_date_till),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){e=jQuery.parseJSON(e),jQuery("#ct_checking_status").html(e.message),ct_comments_total=e.total,ct_comments_spam=e.spam,ct_comments_checked=e.checked,ct_comments_bad=e.bad},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Check comments"),setTimeout(ct_show_info(),3e3)},timeout:15e3}))}}function ct_toggle_depended(e,t){t=t||null;var c=jQuery(e.data("depended"));e.data("state")||t?(e.data("state",!1),c.prop("disabled",!0),c.removeProp("checked"),c.data("depended")&&ct_toggle_depended(c,!0)):(e.data("state",!0),c.removeProp("disabled"))}function ct_delete_all(_){var e={action:"ajax_delete_all",security:ct_ajax_nonce};jQuery("."+_.target.id).addClass("disabled"),jQuery(".spinner").css("visibility","visible"),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){0<e?(jQuery("#cleantalk_comments_left").html(e),ct_delete_all(_)):(jQuery("."+_.target.id).removeClass("disabled"),jQuery(".spinner").css("visibility","hidden"),location.href="edit-comments.php?page=ct_check_spam_total")},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Check comments"),setTimeout(ct_delete_all(_),3e3)},timeout:25e3})}jQuery(document).ready(function(){jQuery("#ct_allow_date_range").data({depended:".ct_date",state:!1}),ct_prev_accurate&&jQuery("#ct_accurate_check").prop("checked",!0),ct_prev_from&&(jQuery("#ct_allow_date_range").prop("checked",!0).data("state",!0),jQuery("#ct_date_range_from").removeProp("disabled").val(ct_prev_from),jQuery("#ct_date_range_till").removeProp("disabled").val(ct_prev_till)),jQuery("#ct_allow_date_range, #ct_accurate_check").on("change",function(){ct_toggle_depended(jQuery(this))}),jQuery.datepicker.setDefaults(jQuery.datepicker.regional.en);var a=jQuery("#ct_date_range_from, #ct_date_range_till").datepicker({dateFormat:"M d yy",maxDate:"+0D",changeMonth:!0,changeYear:!0,showAnim:"slideDown",onSelect:function(e){var t="ct_date_range_from"==this.id?"minDate":"maxDate",c=jQuery(this).data("datepicker"),_=jQuery.datepicker.parseDate(c.settings.dateFormat||jQuery.datepicker._defaults.dateFormat,e,c.settings);a.not(this).datepicker("option",t,_)}});function e(e){e=e||null,jQuery("#ct_allow_date_range").is(":checked")&&(ct_date_from=jQuery("#ct_date_range_from").val(),ct_date_till=jQuery("#ct_date_range_till").val(),""==ct_date_from||""==ct_date_till)?alert("Please, specify a date range."):(jQuery("#ct_accurate_check").is(":checked")&&(ct_accurate_check=!0),jQuery(".ct_to_hide").hide(),jQuery("#ct_working_message").show(),jQuery("#ct_preloader").show(),jQuery("#ct_pause").show(),ct_working=!0,e?(ct_show_info(),ct_send_comments()):ct_clear_comments())}jQuery("#ct_check_spam_button").click(function(){e(!(document.cookie="ct_paused_spam_check=0; path=/; samesite=lax"))}),jQuery("#ct_proceed_check_button").click(function(){e(!0)}),jQuery("#ct_pause").on("click",function(){ct_pause=!0;var e={accurate:ct_accurate_check,from:ct_date_from,till:ct_date_till};document.cookie="ct_paused_spam_check="+JSON.stringify(e)+"; path=/; samesite=lax"}),"1"===ctCommentsCheck.start&&(document.cookie="ct_comments_start_check=0; expires="+new Date(0).toUTCString()+"; path=/; samesite=lax",jQuery("#ct_check_spam_button").click()),jQuery(".ct_delete_all").click(function(e){return!!confirm(ctCommentsCheck.ct_confirm_deletion_all)&&void ct_delete_all(e)})});
2
  //# sourceMappingURL=cleantalk-comments-checkspam.min.js.map
1
+ var ct_working=!(String.prototype.printf=function(){var e=this;for(var t in arguments)var c=e.substring(0,e.indexOf("%s",0)),_=e.substring(e.indexOf("%s",0)+2,e.length),e=c+arguments[t]+_;return e}),ct_new_check=!0,ct_cooling_down_flag=!1,ct_close_animate=!0,ct_accurate_check=!1,ct_pause=!1,ct_prev_accurate=ctCommentsCheck.ct_prev_accurate,ct_prev_from=ctCommentsCheck.ct_prev_from,ct_prev_till=ctCommentsCheck.ct_prev_till,ct_cool_down_time=9e4,ct_requests_counter=0,ct_max_requests=60,ct_ajax_nonce=ctCommentsCheck.ct_ajax_nonce,ct_comments_total=0,ct_comments_checked=0,ct_comments_spam=0,ct_comments_bad=0,ct_unchecked="unset",ct_date_from=0,ct_date_till=0;function animate_comment(e,t){ct_close_animate?.3==e?jQuery("#comment-"+t).fadeTo(200,e,function(){animate_comment(1,t)}):jQuery("#comment-"+t).fadeTo(200,e,function(){animate_comment(.3,t)}):ct_close_animate=!0}function ct_clear_comments(){var e=0,t=0;jQuery("#ct_allow_date_range").is(":checked")&&(e=jQuery("#ct_date_range_from").val(),t=jQuery("#ct_date_range_till").val());var c={action:"ajax_clear_comments",security:ct_ajax_nonce,from:e,till:t};jQuery.ajax({type:"POST",url:ajaxurl,data:c,success:function(e){ct_show_info(),ct_send_comments()}})}function ct_cooling_down_toggle(){ct_cooling_down_flag=!1,ct_send_comments(),ct_show_info()}function ct_send_comments(){if(!0!==ct_cooling_down_flag){if(ct_max_requests<=ct_requests_counter)return setTimeout(ct_cooling_down_toggle,ct_cool_down_time),void(ct_cooling_down_flag=!(ct_requests_counter=0));ct_requests_counter++;var e={action:"ajax_check_comments",security:ct_ajax_nonce,new_check:ct_new_check,unchecked:ct_unchecked};ct_accurate_check&&(e.accurate_check=!0),ct_date_from&&ct_date_till&&(e.from=ct_date_from,e.till=ct_date_till),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){var t,c;e=jQuery.parseJSON(e),parseInt(e.error)?(ct_working=!1,confirm(e.error_message+". Do you want to proceed?")?ct_send_comments():(t="edit-comments.php?page=ct_check_spam",0!=ct_date_from&&0!=ct_date_till&&(t+="&from="+ct_date_from+"&till="+ct_date_till),location.href=t)):(ct_new_check=!1,1==parseInt(e.end)||!0===ct_pause?(1==parseInt(e.end)&&(document.cookie="ct_paused_spam_check=0; path=/; samesite=lax"),ct_working=!1,jQuery("#ct_working_message").hide(),t="edit-comments.php?page=ct_check_spam",0!=ct_date_from&&0!=ct_date_till&&(t+="&from="+ct_date_from+"&till="+ct_date_till),location.href=t):0==parseInt(e.end)&&(ct_comments_checked+=e.checked,ct_comments_spam+=e.spam,ct_comments_bad+=e.bad,ct_unchecked=ct_comments_total-ct_comments_checked-ct_comments_bad,c=(c=String(ctCommentsCheck.ct_status_string)).printf(ct_comments_checked,ct_comments_spam,ct_comments_bad),0<parseInt(ct_comments_spam)&&(c+=ctCommentsCheck.ct_status_string_warning),jQuery("#ct_checking_status").html(c),jQuery("#ct_error_message").hide(),+ct_comments_total<ct_comments_checked+ct_comments_bad&&(document.cookie="ct_comments_start_check=1; path=/; samesite=lax",document.cookie="ct_comments_safe_check=1; path=/; samesite=lax",location.href="edit-comments.php?page=ct_check_spam"),ct_send_comments()))},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Check comments"),setTimeout(ct_send_comments(),3e3)},timeout:25e3})}}function ct_show_info(){if(ct_working){if(1==ct_cooling_down_flag)return jQuery("#ct_cooling_notice").html("Waiting for API to cool down. (About a minute)"),void jQuery("#ct_cooling_notice").show();var e;jQuery("#ct_cooling_notice").hide(),ct_comments_total||(e={action:"ajax_info_comments",security:ct_ajax_nonce},ct_date_from&&ct_date_till&&(e.from=ct_date_from,e.till=ct_date_till),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){e=jQuery.parseJSON(e),jQuery("#ct_checking_status").html(e.message),ct_comments_total=e.total,ct_comments_spam=e.spam,ct_comments_checked=e.checked,ct_comments_bad=e.bad},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Check comments"),setTimeout(ct_show_info(),3e3)},timeout:15e3}))}}function ct_toggle_depended(e,t){t=t||null;var c=jQuery(e.data("depended"));e.data("state")||t?(e.data("state",!1),c.prop("disabled",!0),c.removeProp("checked"),c.data("depended")&&ct_toggle_depended(c,!0)):(e.data("state",!0),c.removeProp("disabled"))}function ct_delete_all(_){var e={action:"ajax_delete_all",security:ct_ajax_nonce};jQuery("."+_.target.id).addClass("disabled"),jQuery(".spinner").css("visibility","visible"),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){0<e?(jQuery("#cleantalk_comments_left").html(e),ct_delete_all(_)):(jQuery("."+_.target.id).removeClass("disabled"),jQuery(".spinner").css("visibility","hidden"),location.href="edit-comments.php?page=ct_check_spam_total")},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Check comments"),setTimeout(ct_delete_all(_),3e3)},timeout:25e3})}jQuery(document).ready(function(){ct_prev_accurate&&jQuery("#ct_accurate_check").prop("checked",!0),ct_prev_from&&(jQuery("#ct_allow_date_range").prop("checked",!0).data("state",!0),jQuery("#ct_date_range_from").removeProp("disabled").val(ct_prev_from),jQuery("#ct_date_range_till").removeProp("disabled").val(ct_prev_till)),jQuery("#ct_allow_date_range").on("change",function(){document.cookie="ct_spam_dates_from="+jQuery("#ct_date_range_from").val()+"; path=/; samesite=lax",document.cookie="ct_spam_dates_till="+jQuery("#ct_date_range_till").val()+"; path=/; samesite=lax",this.checked?(document.cookie="ct_spam_dates_allowed=1; path=/; samesite=lax",jQuery(".ct_date").prop("checked",!0).removeProp("disabled")):(document.cookie="ct_spam_dates_allowed=0; path=/; samesite=lax",jQuery(".ct_date").prop("disabled",!0).removeProp("checked"))}),jQuery.datepicker.setDefaults(jQuery.datepicker.regional.en);var a=jQuery("#ct_date_range_from, #ct_date_range_till").datepicker({dateFormat:"M d yy",maxDate:"+0D",changeMonth:!0,changeYear:!0,showAnim:"slideDown",onSelect:function(e){var t="ct_date_range_from"==this.id?"minDate":"maxDate",c=jQuery(this).data("datepicker"),_=jQuery.datepicker.parseDate(c.settings.dateFormat||jQuery.datepicker._defaults.dateFormat,e,c.settings);a.not(this).datepicker("option",t,_),document.cookie="ct_spam_dates_from="+jQuery("#ct_date_range_from").val()+"; path=/; samesite=lax",document.cookie="ct_spam_dates_till="+jQuery("#ct_date_range_till").val()+"; path=/; samesite=lax"}});function e(e){e=e||null,jQuery("#ct_allow_date_range").is(":checked")&&(ct_date_from=jQuery("#ct_date_range_from").val(),ct_date_till=jQuery("#ct_date_range_till").val(),""==ct_date_from||""==ct_date_till)?alert("Please, specify a date range."):(jQuery("#ct_accurate_check").is(":checked")&&(ct_accurate_check=!0),jQuery(".ct_to_hide").hide(),jQuery("#ct_working_message").show(),jQuery("#ct_preloader").show(),jQuery("#ct_pause").show(),ct_working=!0,e?(ct_show_info(),ct_send_comments()):ct_clear_comments())}jQuery("#ct_check_spam_button").click(function(){e(!(document.cookie="ct_paused_spam_check=0; path=/; samesite=lax"))}),jQuery("#ct_proceed_check_button").click(function(){e(!0)}),jQuery("#ct_pause").on("click",function(){ct_pause=!0;var e={accurate:ct_accurate_check,from:ct_date_from,till:ct_date_till};document.cookie="ct_paused_spam_check="+JSON.stringify(e)+"; path=/; samesite=lax"}),"1"===ctCommentsCheck.start&&(document.cookie="ct_comments_start_check=0; expires="+new Date(0).toUTCString()+"; path=/; samesite=lax",jQuery("#ct_check_spam_button").click()),jQuery(".ct_delete_all").click(function(e){return!!confirm(ctCommentsCheck.ct_confirm_deletion_all)&&void ct_delete_all(e)})});
2
  //# sourceMappingURL=cleantalk-comments-checkspam.min.js.map
js/cleantalk-comments-checkspam.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cleantalk-comments-checkspam.min.js","sources":["cleantalk-comments-checkspam.js"],"sourcesContent":["// Printf for JS\r\nString.prototype.printf = function(){\r\n var formatted = this;\r\n for( var arg in arguments ) {\r\n\t\tvar before_formatted = formatted.substring(0, formatted.indexOf(\"%s\", 0));\r\n\t\tvar after_formatted = formatted.substring(formatted.indexOf(\"%s\", 0)+2, formatted.length);\r\n\t\tformatted = before_formatted + arguments[arg] + after_formatted;\r\n }\r\n return formatted;\r\n};\r\n\r\n// Flags\r\nvar ct_working = false,\r\n\tct_new_check = true,\r\n\tct_cooling_down_flag = false,\r\n\tct_close_animate = true,\r\n\tct_accurate_check = false,\r\n\tct_pause = false,\r\n\tct_prev_accurate = ctCommentsCheck.ct_prev_accurate,\r\n\tct_prev_from = ctCommentsCheck.ct_prev_from,\t\r\n\tct_prev_till = ctCommentsCheck.ct_prev_till;\r\n// Settings\r\nvar ct_cool_down_time = 90000,\r\n\tct_requests_counter = 0,\r\n\tct_max_requests = 60;\r\n// Variables\r\nvar ct_ajax_nonce = ctCommentsCheck.ct_ajax_nonce,\r\n\tct_comments_total = 0,\r\n\tct_comments_checked = 0,\r\n\tct_comments_spam = 0,\r\n\tct_comments_bad = 0,\r\n\tct_unchecked = 'unset',\r\n\tct_date_from = 0,\r\n\tct_date_till = 0;\r\n\r\nfunction animate_comment(to,id){\r\n\tif(ct_close_animate){\r\n\t\tif(to==0.3){\r\n\t\t\tjQuery('#comment-'+id).fadeTo(200,to,function(){\r\n\t\t\t\tanimate_comment(1,id)\r\n\t\t\t});\r\n\t\t}else{\r\n\t\t\tjQuery('#comment-'+id).fadeTo(200,to,function(){\r\n\t\t\t\tanimate_comment(0.3,id)\r\n\t\t\t});\r\n\t\t}\r\n\t}else{\r\n\t\tct_close_animate=true;\r\n\t}\r\n}\r\n\r\nfunction ct_clear_comments(){\r\n\r\n\tvar from = 0, till = 0;\r\n\tif(jQuery('#ct_allow_date_range').is(':checked')) {\r\n\t\tfrom = jQuery('#ct_date_range_from').val();\r\n\t\ttill = jQuery('#ct_date_range_till').val();\r\n\t}\r\n\tvar data = {\r\n\t\t'action' : 'ajax_clear_comments',\r\n\t\t'security' : ct_ajax_nonce,\r\n\t\t'from' : from,\r\n\t\t'till' : till\r\n\t};\r\n\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function(msg){\r\n\t\t\tct_show_info();\r\n\t\t\tct_send_comments();\r\n\t\t}\r\n\t});\r\n}\r\n\r\n//Continues the check after cooldown time\r\n//Called by ct_send_users();\r\nfunction ct_cooling_down_toggle(){\r\n\tct_cooling_down_flag = false;\r\n\tct_send_comments();\r\n\tct_show_info();\r\n}\r\n\r\nfunction ct_send_comments(){\r\n\t\r\n\tif(ct_cooling_down_flag === true)\r\n\t\treturn;\r\n\t\r\n\tif(ct_requests_counter >= ct_max_requests){\r\n\t\tsetTimeout(ct_cooling_down_toggle, ct_cool_down_time);\r\n\t\tct_requests_counter = 0;\r\n\t\tct_cooling_down_flag = true;\r\n\t\treturn;\r\n\t}else{\r\n\t\tct_requests_counter++;\r\n\t}\r\n\t\r\n\tvar data = {\r\n\t\t'action': 'ajax_check_comments',\r\n\t\t'security': ct_ajax_nonce,\r\n\t\t'new_check': ct_new_check,\r\n\t\t'unchecked': ct_unchecked\r\n\t};\r\n\t\r\n\tif(ct_accurate_check)\r\n\t\tdata['accurate_check'] = true;\r\n\t\r\n\tif(ct_date_from && ct_date_till){\r\n\t\tdata['from'] = ct_date_from;\r\n\t\tdata['till'] = ct_date_till;\r\n\t}\r\n\t\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function(msg){\r\n\t\t\t\r\n\t\t\tmsg = jQuery.parseJSON(msg);\r\n\t\t\t\r\n\t\t\tif(parseInt(msg.error)){\r\n\t\t\t\tct_working=false;\r\n\t\t\t\tif(!confirm(msg.error_message+\". Do you want to proceed?\")){\r\n\t\t\t\t\tvar new_href = 'edit-comments.php?page=ct_check_spam';\r\n\t\t\t\t\tif(ct_date_from != 0 && ct_date_till != 0)\r\n\t\t\t\t\t\tnew_href+='&from='+ct_date_from+'&till='+ct_date_till;\r\n\t\t\t\t\tlocation.href = new_href;\r\n\t\t\t\t}else\r\n\t\t\t\t\tct_send_comments();\r\n\t\t\t}else{\r\n\t\t\t\tct_new_check = false;\r\n\t\t\t\tif(parseInt(msg.end) == 1 || ct_pause === true){\r\n\t\t\t\t\tif(parseInt(msg.end) == 1)\r\n\t\t\t\t\t\tdocument.cookie = 'ct_paused_spam_check=0; path=/; samesite=lax';\r\n\t\t\t\t\tct_working=false;\r\n\t\t\t\t\tjQuery('#ct_working_message').hide();\r\n\t\t\t\t\tvar new_href = 'edit-comments.php?page=ct_check_spam';\r\n\t\t\t\t\tif(ct_date_from != 0 && ct_date_till != 0)\r\n\t\t\t\t\t\tnew_href+='&from='+ct_date_from+'&till='+ct_date_till;\r\n\t\t\t\t\tlocation.href = new_href;\r\n\t\t\t\t}else if(parseInt(msg.end) == 0){\r\n\t\t\t\t\tct_comments_checked += msg.checked;\r\n\t\t\t\t\tct_comments_spam += msg.spam;\r\n\t\t\t\t\tct_comments_bad += msg.bad;\r\n\t\t\t\t\tct_unchecked = ct_comments_total - ct_comments_checked - ct_comments_bad;\r\n\t\t\t\t\tvar status_string = String(ctCommentsCheck.ct_status_string);\r\n\t\t\t\t\tvar status_string = status_string.printf(ct_comments_checked, ct_comments_spam, ct_comments_bad);\r\n\t\t\t\t\tif(parseInt(ct_comments_spam) > 0)\r\n\t\t\t\t\t\tstatus_string += ctCommentsCheck.ct_status_string_warning;\r\n\t\t\t\t\tjQuery('#ct_checking_status').html(status_string);\r\n\t\t\t\t\tjQuery('#ct_error_message').hide();\r\n\t\t\t\t\t// If DB woks not properly\r\n\t\t\t\t\tif(+ct_comments_total < ct_comments_checked + ct_comments_bad){\r\n\t\t\t\t\t\tdocument.cookie = 'ct_comments_start_check=1; path=/; samesite=lax';\r\n\t\t\t\t\t\tdocument.cookie = 'ct_comments_safe_check=1; path=/; samesite=lax';\r\n\t\t\t\t\t\tlocation.href = 'edit-comments.php?page=ct_check_spam';\r\n\t\t\t\t\t}\r\n\t\t\t\t\tct_send_comments();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n error: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\tjQuery('#cleantalk_js_func').html('Check comments');\r\n\t\t\tsetTimeout(ct_send_comments(), 3000); \r\n },\r\n timeout: 25000\r\n\t});\r\n}\r\nfunction ct_show_info(){\r\n\t\r\n\tif(ct_working){\r\n\t\t\r\n\t\tif(ct_cooling_down_flag == true){\r\n\t\t\tjQuery('#ct_cooling_notice').html('Waiting for API to cool down. (About a minute)');\r\n\t\t\tjQuery('#ct_cooling_notice').show();\r\n\t\t\treturn;\t\t\t\r\n\t\t}else{\r\n\t\t\tjQuery('#ct_cooling_notice').hide();\r\n\t\t}\r\n\t\t\r\n\t\tif(!ct_comments_total){\r\n\t\t\t\r\n\t\t\tvar data = {\r\n\t\t\t\t'action': 'ajax_info_comments',\r\n\t\t\t\t'security': ct_ajax_nonce\r\n\t\t\t};\r\n\t\t\t\r\n\t\t\tif(ct_date_from && ct_date_till){\r\n\t\t\t\tdata['from'] = ct_date_from;\r\n\t\t\t\tdata['till'] = ct_date_till;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tjQuery.ajax({\r\n\t\t\t\ttype: \"POST\",\r\n\t\t\t\turl: ajaxurl,\r\n\t\t\t\tdata: data,\r\n\t\t\t\tsuccess: function(msg){\r\n\t\t\t\t\tmsg = jQuery.parseJSON(msg);\r\n\t\t\t\t\tjQuery('#ct_checking_status').html(msg.message);\r\n\t\t\t\t\tct_comments_total = msg.total;\r\n\t\t\t\t\tct_comments_spam = msg.spam;\r\n\t\t\t\t\tct_comments_checked = msg.checked;\r\n\t\t\t\t\tct_comments_bad = msg.bad;\r\n\t\t\t\t},\r\n\t\t\t\terror: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\t\t\tjQuery('#cleantalk_js_func').html('Check comments');\r\n\t\t\t\t\tsetTimeout(ct_show_info(), 3000); \r\n\t\t\t\t},\r\n\t\t\t\ttimeout: 15000\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// Function to toggle dependences\r\nfunction ct_toggle_depended(obj, secondary){\r\n\r\n secondary = secondary || null;\r\n\r\n\tvar depended = jQuery(obj.data('depended')),\r\n\t\tstate = obj.data('state');\r\n\t\t\r\n\tif(!state && !secondary){\r\n\t\tobj.data('state', true);\r\n\t\tdepended.removeProp('disabled');\r\n\t}else{\r\n\t\tobj.data('state', false);\r\n\t\tdepended.prop('disabled', true);\r\n\t\tdepended.removeProp('checked');\r\n\t\tif(depended.data('depended'))\r\n\t\t\tct_toggle_depended(depended, true);\r\n\t}\r\n}\r\n\r\nfunction ct_delete_all( e ) {\r\n\r\n\tvar data = {\r\n\t\t'action': 'ajax_delete_all',\r\n\t\t'security': ct_ajax_nonce\r\n\t};\r\n\r\n\tjQuery('.' + e.target.id).addClass('disabled');\r\n\tjQuery('.spinner').css('visibility', 'visible');\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function( msg ){\r\n\t\t\tif( msg > 0 ){\r\n\t\t\t\tjQuery('#cleantalk_comments_left').html(msg);\r\n\t\t\t\tct_delete_all( e );\r\n\t\t\t}else{\r\n\t\t\t\tjQuery('.' + e.target.id).removeClass('disabled');\r\n\t\t\t\tjQuery('.spinner').css('visibility', 'hidden');\r\n\t\t\t\tlocation.href='edit-comments.php?page=ct_check_spam_total';\r\n\t\t\t}\r\n\t\t},\r\n\t\terror: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\tjQuery('#cleantalk_js_func').html('Check comments');\r\n\t\t\tsetTimeout(ct_delete_all( e ), 3000);\r\n\t\t},\r\n\t\ttimeout: 25000\r\n\t});\r\n\r\n}\r\n\r\njQuery(document).ready(function(){\r\n\r\n\t// Setting dependences\r\n\t// jQuery('#ct_accurate_check') .data({'depended': '#ct_allow_date_range', 'state': false});\r\n\tjQuery('#ct_allow_date_range').data({'depended': '.ct_date', 'state': false});\r\n\t\r\n\t// Prev check parameters\r\n\tif(ct_prev_accurate){\r\n\t\tjQuery(\"#ct_accurate_check\").prop('checked', true);\r\n\t}\r\n\tif(ct_prev_from){\r\n\t\tjQuery(\"#ct_allow_date_range\").prop('checked', true).data('state', true);\r\n\t\tjQuery(\"#ct_date_range_from\").removeProp('disabled').val(ct_prev_from);\r\n\t\tjQuery(\"#ct_date_range_till\").removeProp('disabled').val(ct_prev_till);\r\n\t}\r\n\t\r\n\t// Toggle dependences\r\n\tjQuery(\"#ct_allow_date_range, #ct_accurate_check\").on('change', function(){\r\n\t\tct_toggle_depended(jQuery(this));\r\n\t});\r\n\r\n jQuery.datepicker.setDefaults(jQuery.datepicker.regional['en']);\r\n\tvar dates = jQuery('#ct_date_range_from, #ct_date_range_till').datepicker(\r\n\t\t{\r\n\t\t\tdateFormat: 'M d yy',\r\n\t\t\tmaxDate:\"+0D\",\r\n\t\t\tchangeMonth:true,\r\n\t\t\tchangeYear:true,\r\n\t\t\tshowAnim: 'slideDown',\r\n\t\t\tonSelect: function(selectedDate){\r\n\t\t\tvar option = this.id == \"ct_date_range_from\" ? \"minDate\" : \"maxDate\",\r\n\t\t\t\tinstance = jQuery( this ).data( \"datepicker\" ),\r\n\t\t\t\tdate = jQuery.datepicker.parseDate(\r\n\t\t\t\t\tinstance.settings.dateFormat || jQuery.datepicker._defaults.dateFormat,\r\n\t\t\t\t\tselectedDate, instance.settings);\r\n\t\t\t\tdates.not(this).datepicker(\"option\", option, date);\r\n\t\t\t}\r\n\t\t}\r\n\t);\r\n\t\r\n\tfunction ct_start_check(continue_check){\r\n\r\n continue_check = continue_check || null;\r\n\r\n\t\tif(jQuery('#ct_allow_date_range').is(':checked')){\r\n\t\t\t\r\n\t\t\tct_date_from = jQuery('#ct_date_range_from').val(),\r\n\t\t\tct_date_till = jQuery('#ct_date_range_till').val();\r\n\t\t\t\t\t\t\r\n\t\t\tif(!(ct_date_from != '' && ct_date_till != '')){\r\n\t\t\t\talert('Please, specify a date range.');\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif(jQuery('#ct_accurate_check').is(':checked')){\r\n\t\t\tct_accurate_check = true;\r\n\t\t}\r\n\t\t\r\n\t\tjQuery('.ct_to_hide').hide();\r\n\t\tjQuery('#ct_working_message').show();\r\n\t\tjQuery('#ct_preloader').show();\r\n\t\tjQuery('#ct_pause').show();\r\n\r\n\t\tct_working=true;\r\n\t\t\r\n\t\tif(continue_check){\r\n\t\t\tct_show_info();\r\n\t\t\tct_send_comments();\r\n\t\t}else\r\n\t\t\tct_clear_comments();\r\n\t\t\r\n\t}\r\n\t\r\n\t// Check comments\r\n\tjQuery(\"#ct_check_spam_button\").click(function(){\r\n\t\tdocument.cookie = 'ct_paused_spam_check=0; path=/; samesite=lax';\r\n\t\tct_start_check(false);\r\n\t});\r\n\tjQuery(\"#ct_proceed_check_button\").click(function(){\r\n\t\tct_start_check(true);\r\n\t});\r\n\r\n\t// Pause the check\r\n\tjQuery('#ct_pause').on('click', function(){\r\n\t\tct_pause = true;\r\n\t\tvar ct_check = {\r\n\t\t\t'accurate': ct_accurate_check,\r\n\t\t\t'from' : ct_date_from,\r\n\t\t\t'till' : ct_date_till\r\n\t\t};\r\n\t\tdocument.cookie = 'ct_paused_spam_check=' + JSON.stringify(ct_check) + '; path=/; samesite=lax';\r\n\t});\r\n\r\n\r\n\tif(ctCommentsCheck.start === '1'){\r\n\t\tdocument.cookie = 'ct_comments_start_check=0; expires=' + new Date(0).toUTCString() + '; path=/; samesite=lax';\r\n\t\tjQuery('#ct_check_spam_button').click();\t\r\n\t}\r\n\r\n\t// Delete all spam comments\r\n\tjQuery(\".ct_delete_all\").click(function( e ){\r\n\r\n\t\tif (!confirm(ctCommentsCheck.ct_confirm_deletion_all))\r\n\t\t\treturn false;\r\n\r\n\t\tct_delete_all( e );\r\n\r\n\t});\r\n\r\n});"],"names":["ct_working","String","prototype","printf","formatted","this","arg","arguments","before_formatted","substring","indexOf","after_formatted","length","ct_new_check","ct_cooling_down_flag","ct_close_animate","ct_accurate_check","ct_pause","ct_prev_accurate","ctCommentsCheck","ct_prev_from","ct_prev_till","ct_cool_down_time","ct_requests_counter","ct_max_requests","ct_ajax_nonce","ct_comments_total","ct_comments_checked","ct_comments_spam","ct_comments_bad","ct_unchecked","ct_date_from","ct_date_till","animate_comment","to","id","jQuery","fadeTo","ct_clear_comments","from","till","is","val","data","action","security","ajax","type","url","ajaxurl","success","msg","ct_show_info","ct_send_comments","ct_cooling_down_toggle","setTimeout","new_check","unchecked","new_href","status_string","parseJSON","parseInt","error","confirm","error_message","location","href","end","document","cookie","hide","checked","spam","bad","ct_status_string","ct_status_string_warning","html","jqXHR","textStatus","errorThrown","show","timeout","message","total","ct_toggle_depended","obj","secondary","depended","prop","removeProp","ct_delete_all","e","target","addClass","css","removeClass","ready","state","on","datepicker","setDefaults","regional","dates","dateFormat","maxDate","changeMonth","changeYear","showAnim","onSelect","selectedDate","option","instance","date","parseDate","settings","_defaults","not","ct_start_check","continue_check","alert","click","ct_check","accurate","JSON","stringify","start","Date","toUTCString","ct_confirm_deletion_all"],"mappings":"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"}
1
+ {"version":3,"file":"cleantalk-comments-checkspam.min.js","sources":["cleantalk-comments-checkspam.js"],"sourcesContent":["// Printf for JS\r\nString.prototype.printf = function(){\r\n var formatted = this;\r\n for( var arg in arguments ) {\r\n\t\tvar before_formatted = formatted.substring(0, formatted.indexOf(\"%s\", 0));\r\n\t\tvar after_formatted = formatted.substring(formatted.indexOf(\"%s\", 0)+2, formatted.length);\r\n\t\tformatted = before_formatted + arguments[arg] + after_formatted;\r\n }\r\n return formatted;\r\n};\r\n\r\n// Flags\r\nvar ct_working = false,\r\n\tct_new_check = true,\r\n\tct_cooling_down_flag = false,\r\n\tct_close_animate = true,\r\n\tct_accurate_check = false,\r\n\tct_pause = false,\r\n\tct_prev_accurate = ctCommentsCheck.ct_prev_accurate,\r\n\tct_prev_from = ctCommentsCheck.ct_prev_from,\t\r\n\tct_prev_till = ctCommentsCheck.ct_prev_till;\r\n// Settings\r\nvar ct_cool_down_time = 90000,\r\n\tct_requests_counter = 0,\r\n\tct_max_requests = 60;\r\n// Variables\r\nvar ct_ajax_nonce = ctCommentsCheck.ct_ajax_nonce,\r\n\tct_comments_total = 0,\r\n\tct_comments_checked = 0,\r\n\tct_comments_spam = 0,\r\n\tct_comments_bad = 0,\r\n\tct_unchecked = 'unset',\r\n\tct_date_from = 0,\r\n\tct_date_till = 0;\r\n\r\nfunction animate_comment(to,id){\r\n\tif(ct_close_animate){\r\n\t\tif(to==0.3){\r\n\t\t\tjQuery('#comment-'+id).fadeTo(200,to,function(){\r\n\t\t\t\tanimate_comment(1,id)\r\n\t\t\t});\r\n\t\t}else{\r\n\t\t\tjQuery('#comment-'+id).fadeTo(200,to,function(){\r\n\t\t\t\tanimate_comment(0.3,id)\r\n\t\t\t});\r\n\t\t}\r\n\t}else{\r\n\t\tct_close_animate=true;\r\n\t}\r\n}\r\n\r\nfunction ct_clear_comments(){\r\n\r\n\tvar from = 0, till = 0;\r\n\tif(jQuery('#ct_allow_date_range').is(':checked')) {\r\n\t\tfrom = jQuery('#ct_date_range_from').val();\r\n\t\ttill = jQuery('#ct_date_range_till').val();\r\n\t}\r\n\tvar data = {\r\n\t\t'action' : 'ajax_clear_comments',\r\n\t\t'security' : ct_ajax_nonce,\r\n\t\t'from' : from,\r\n\t\t'till' : till\r\n\t};\r\n\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function(msg){\r\n\t\t\tct_show_info();\r\n\t\t\tct_send_comments();\r\n\t\t}\r\n\t});\r\n}\r\n\r\n//Continues the check after cooldown time\r\n//Called by ct_send_users();\r\nfunction ct_cooling_down_toggle(){\r\n\tct_cooling_down_flag = false;\r\n\tct_send_comments();\r\n\tct_show_info();\r\n}\r\n\r\nfunction ct_send_comments(){\r\n\t\r\n\tif(ct_cooling_down_flag === true)\r\n\t\treturn;\r\n\t\r\n\tif(ct_requests_counter >= ct_max_requests){\r\n\t\tsetTimeout(ct_cooling_down_toggle, ct_cool_down_time);\r\n\t\tct_requests_counter = 0;\r\n\t\tct_cooling_down_flag = true;\r\n\t\treturn;\r\n\t}else{\r\n\t\tct_requests_counter++;\r\n\t}\r\n\t\r\n\tvar data = {\r\n\t\t'action': 'ajax_check_comments',\r\n\t\t'security': ct_ajax_nonce,\r\n\t\t'new_check': ct_new_check,\r\n\t\t'unchecked': ct_unchecked\r\n\t};\r\n\t\r\n\tif(ct_accurate_check)\r\n\t\tdata['accurate_check'] = true;\r\n\t\r\n\tif(ct_date_from && ct_date_till){\r\n\t\tdata['from'] = ct_date_from;\r\n\t\tdata['till'] = ct_date_till;\r\n\t}\r\n\t\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function(msg){\r\n\t\t\t\r\n\t\t\tmsg = jQuery.parseJSON(msg);\r\n\t\t\t\r\n\t\t\tif(parseInt(msg.error)){\r\n\t\t\t\tct_working=false;\r\n\t\t\t\tif(!confirm(msg.error_message+\". Do you want to proceed?\")){\r\n\t\t\t\t\tvar new_href = 'edit-comments.php?page=ct_check_spam';\r\n\t\t\t\t\tif(ct_date_from != 0 && ct_date_till != 0)\r\n\t\t\t\t\t\tnew_href+='&from='+ct_date_from+'&till='+ct_date_till;\r\n\t\t\t\t\tlocation.href = new_href;\r\n\t\t\t\t}else\r\n\t\t\t\t\tct_send_comments();\r\n\t\t\t}else{\r\n\t\t\t\tct_new_check = false;\r\n\t\t\t\tif(parseInt(msg.end) == 1 || ct_pause === true){\r\n\t\t\t\t\tif(parseInt(msg.end) == 1)\r\n\t\t\t\t\t\tdocument.cookie = 'ct_paused_spam_check=0; path=/; samesite=lax';\r\n\t\t\t\t\tct_working=false;\r\n\t\t\t\t\tjQuery('#ct_working_message').hide();\r\n\t\t\t\t\tvar new_href = 'edit-comments.php?page=ct_check_spam';\r\n\t\t\t\t\tif(ct_date_from != 0 && ct_date_till != 0)\r\n\t\t\t\t\t\tnew_href+='&from='+ct_date_from+'&till='+ct_date_till;\r\n\t\t\t\t\tlocation.href = new_href;\r\n\t\t\t\t}else if(parseInt(msg.end) == 0){\r\n\t\t\t\t\tct_comments_checked += msg.checked;\r\n\t\t\t\t\tct_comments_spam += msg.spam;\r\n\t\t\t\t\tct_comments_bad += msg.bad;\r\n\t\t\t\t\tct_unchecked = ct_comments_total - ct_comments_checked - ct_comments_bad;\r\n\t\t\t\t\tvar status_string = String(ctCommentsCheck.ct_status_string);\r\n\t\t\t\t\tvar status_string = status_string.printf(ct_comments_checked, ct_comments_spam, ct_comments_bad);\r\n\t\t\t\t\tif(parseInt(ct_comments_spam) > 0)\r\n\t\t\t\t\t\tstatus_string += ctCommentsCheck.ct_status_string_warning;\r\n\t\t\t\t\tjQuery('#ct_checking_status').html(status_string);\r\n\t\t\t\t\tjQuery('#ct_error_message').hide();\r\n\t\t\t\t\t// If DB woks not properly\r\n\t\t\t\t\tif(+ct_comments_total < ct_comments_checked + ct_comments_bad){\r\n\t\t\t\t\t\tdocument.cookie = 'ct_comments_start_check=1; path=/; samesite=lax';\r\n\t\t\t\t\t\tdocument.cookie = 'ct_comments_safe_check=1; path=/; samesite=lax';\r\n\t\t\t\t\t\tlocation.href = 'edit-comments.php?page=ct_check_spam';\r\n\t\t\t\t\t}\r\n\t\t\t\t\tct_send_comments();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n error: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\tjQuery('#cleantalk_js_func').html('Check comments');\r\n\t\t\tsetTimeout(ct_send_comments(), 3000); \r\n },\r\n timeout: 25000\r\n\t});\r\n}\r\nfunction ct_show_info(){\r\n\t\r\n\tif(ct_working){\r\n\t\t\r\n\t\tif(ct_cooling_down_flag == true){\r\n\t\t\tjQuery('#ct_cooling_notice').html('Waiting for API to cool down. (About a minute)');\r\n\t\t\tjQuery('#ct_cooling_notice').show();\r\n\t\t\treturn;\t\t\t\r\n\t\t}else{\r\n\t\t\tjQuery('#ct_cooling_notice').hide();\r\n\t\t}\r\n\t\t\r\n\t\tif(!ct_comments_total){\r\n\t\t\t\r\n\t\t\tvar data = {\r\n\t\t\t\t'action': 'ajax_info_comments',\r\n\t\t\t\t'security': ct_ajax_nonce\r\n\t\t\t};\r\n\t\t\t\r\n\t\t\tif(ct_date_from && ct_date_till){\r\n\t\t\t\tdata['from'] = ct_date_from;\r\n\t\t\t\tdata['till'] = ct_date_till;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tjQuery.ajax({\r\n\t\t\t\ttype: \"POST\",\r\n\t\t\t\turl: ajaxurl,\r\n\t\t\t\tdata: data,\r\n\t\t\t\tsuccess: function(msg){\r\n\t\t\t\t\tmsg = jQuery.parseJSON(msg);\r\n\t\t\t\t\tjQuery('#ct_checking_status').html(msg.message);\r\n\t\t\t\t\tct_comments_total = msg.total;\r\n\t\t\t\t\tct_comments_spam = msg.spam;\r\n\t\t\t\t\tct_comments_checked = msg.checked;\r\n\t\t\t\t\tct_comments_bad = msg.bad;\r\n\t\t\t\t},\r\n\t\t\t\terror: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\t\t\tjQuery('#cleantalk_js_func').html('Check comments');\r\n\t\t\t\t\tsetTimeout(ct_show_info(), 3000); \r\n\t\t\t\t},\r\n\t\t\t\ttimeout: 15000\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// Function to toggle dependences\r\nfunction ct_toggle_depended(obj, secondary){\r\n\r\n secondary = secondary || null;\r\n\r\n\tvar depended = jQuery(obj.data('depended')),\r\n\t\tstate = obj.data('state');\r\n\t\t\r\n\tif(!state && !secondary){\r\n\t\tobj.data('state', true);\r\n\t\tdepended.removeProp('disabled');\r\n\t}else{\r\n\t\tobj.data('state', false);\r\n\t\tdepended.prop('disabled', true);\r\n\t\tdepended.removeProp('checked');\r\n\t\tif(depended.data('depended'))\r\n\t\t\tct_toggle_depended(depended, true);\r\n\t}\r\n}\r\n\r\nfunction ct_delete_all( e ) {\r\n\r\n\tvar data = {\r\n\t\t'action': 'ajax_delete_all',\r\n\t\t'security': ct_ajax_nonce\r\n\t};\r\n\r\n\tjQuery('.' + e.target.id).addClass('disabled');\r\n\tjQuery('.spinner').css('visibility', 'visible');\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function( msg ){\r\n\t\t\tif( msg > 0 ){\r\n\t\t\t\tjQuery('#cleantalk_comments_left').html(msg);\r\n\t\t\t\tct_delete_all( e );\r\n\t\t\t}else{\r\n\t\t\t\tjQuery('.' + e.target.id).removeClass('disabled');\r\n\t\t\t\tjQuery('.spinner').css('visibility', 'hidden');\r\n\t\t\t\tlocation.href='edit-comments.php?page=ct_check_spam_total';\r\n\t\t\t}\r\n\t\t},\r\n\t\terror: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\tjQuery('#cleantalk_js_func').html('Check comments');\r\n\t\t\tsetTimeout(ct_delete_all( e ), 3000);\r\n\t\t},\r\n\t\ttimeout: 25000\r\n\t});\r\n\r\n}\r\n\r\njQuery(document).ready(function(){\r\n\t\r\n\t// Prev check parameters\r\n\tif(ct_prev_accurate){\r\n\t\tjQuery(\"#ct_accurate_check\").prop('checked', true);\r\n\t}\r\n\tif(ct_prev_from){\r\n\t\tjQuery(\"#ct_allow_date_range\").prop('checked', true).data('state', true);\r\n\t\tjQuery(\"#ct_date_range_from\").removeProp('disabled').val(ct_prev_from);\r\n\t\tjQuery(\"#ct_date_range_till\").removeProp('disabled').val(ct_prev_till);\r\n\t}\r\n\t\r\n\t// Toggle dependences\r\n\tjQuery(\"#ct_allow_date_range\").on('change', function(){\r\n\t\tdocument.cookie = 'ct_spam_dates_from='+ jQuery('#ct_date_range_from').val() +'; path=/; samesite=lax';\r\n\t\tdocument.cookie = 'ct_spam_dates_till='+ jQuery('#ct_date_range_till').val() +'; path=/; samesite=lax';\r\n\t\tif( this.checked ) {\r\n\t\t\tdocument.cookie = 'ct_spam_dates_allowed=1; path=/; samesite=lax';\r\n\t\t\tjQuery('.ct_date').prop('checked', true).removeProp('disabled');\r\n\t\t} else {\r\n\t\t\tdocument.cookie = 'ct_spam_dates_allowed=0; path=/; samesite=lax';\r\n\t\t\tjQuery('.ct_date').prop('disabled', true).removeProp('checked');\r\n\t\t}\r\n\t});\r\n\r\n jQuery.datepicker.setDefaults(jQuery.datepicker.regional['en']);\r\n\tvar dates = jQuery('#ct_date_range_from, #ct_date_range_till').datepicker(\r\n\t\t{\r\n\t\t\tdateFormat: 'M d yy',\r\n\t\t\tmaxDate:\"+0D\",\r\n\t\t\tchangeMonth:true,\r\n\t\t\tchangeYear:true,\r\n\t\t\tshowAnim: 'slideDown',\r\n\t\t\tonSelect: function(selectedDate){\r\n\t\t\tvar option = this.id == \"ct_date_range_from\" ? \"minDate\" : \"maxDate\",\r\n\t\t\t\tinstance = jQuery( this ).data( \"datepicker\" ),\r\n\t\t\t\tdate = jQuery.datepicker.parseDate(\r\n\t\t\t\t\tinstance.settings.dateFormat || jQuery.datepicker._defaults.dateFormat,\r\n\t\t\t\t\tselectedDate, instance.settings);\r\n\t\t\t\tdates.not(this).datepicker(\"option\", option, date);\r\n\t\t\t\tdocument.cookie = 'ct_spam_dates_from='+ jQuery('#ct_date_range_from').val() +'; path=/; samesite=lax';\r\n\t\t\t\tdocument.cookie = 'ct_spam_dates_till='+ jQuery('#ct_date_range_till').val() +'; path=/; samesite=lax';\r\n\t\t\t}\r\n\t\t}\r\n\t);\r\n\t\r\n\tfunction ct_start_check(continue_check){\r\n\r\n continue_check = continue_check || null;\r\n\r\n\t\tif(jQuery('#ct_allow_date_range').is(':checked')){\r\n\t\t\t\r\n\t\t\tct_date_from = jQuery('#ct_date_range_from').val();\r\n\t\t\tct_date_till = jQuery('#ct_date_range_till').val();\r\n\t\t\t\t\t\t\r\n\t\t\tif(!(ct_date_from != '' && ct_date_till != '')){\r\n\t\t\t\talert('Please, specify a date range.');\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif(jQuery('#ct_accurate_check').is(':checked')){\r\n\t\t\tct_accurate_check = true;\r\n\t\t}\r\n\t\t\r\n\t\tjQuery('.ct_to_hide').hide();\r\n\t\tjQuery('#ct_working_message').show();\r\n\t\tjQuery('#ct_preloader').show();\r\n\t\tjQuery('#ct_pause').show();\r\n\r\n\t\tct_working=true;\r\n\t\t\r\n\t\tif(continue_check){\r\n\t\t\tct_show_info();\r\n\t\t\tct_send_comments();\r\n\t\t}else\r\n\t\t\tct_clear_comments();\r\n\t\t\r\n\t}\r\n\t\r\n\t// Check comments\r\n\tjQuery(\"#ct_check_spam_button\").click(function(){\r\n\t\tdocument.cookie = 'ct_paused_spam_check=0; path=/; samesite=lax';\r\n\t\tct_start_check(false);\r\n\t});\r\n\tjQuery(\"#ct_proceed_check_button\").click(function(){\r\n\t\tct_start_check(true);\r\n\t});\r\n\r\n\t// Pause the check\r\n\tjQuery('#ct_pause').on('click', function(){\r\n\t\tct_pause = true;\r\n\t\tvar ct_check = {\r\n\t\t\t'accurate': ct_accurate_check,\r\n\t\t\t'from' : ct_date_from,\r\n\t\t\t'till' : ct_date_till\r\n\t\t};\r\n\t\tdocument.cookie = 'ct_paused_spam_check=' + JSON.stringify(ct_check) + '; path=/; samesite=lax';\r\n\t});\r\n\r\n\r\n\tif(ctCommentsCheck.start === '1'){\r\n\t\tdocument.cookie = 'ct_comments_start_check=0; expires=' + new Date(0).toUTCString() + '; path=/; samesite=lax';\r\n\t\tjQuery('#ct_check_spam_button').click();\t\r\n\t}\r\n\r\n\t// Delete all spam comments\r\n\tjQuery(\".ct_delete_all\").click(function( e ){\r\n\r\n\t\tif (!confirm(ctCommentsCheck.ct_confirm_deletion_all))\r\n\t\t\treturn false;\r\n\r\n\t\tct_delete_all( e );\r\n\r\n\t});\r\n\r\n});"],"names":["ct_working","String","prototype","printf","formatted","this","arg","arguments","before_formatted","substring","indexOf","after_formatted","length","ct_new_check","ct_cooling_down_flag","ct_close_animate","ct_accurate_check","ct_pause","ct_prev_accurate","ctCommentsCheck","ct_prev_from","ct_prev_till","ct_cool_down_time","ct_requests_counter","ct_max_requests","ct_ajax_nonce","ct_comments_total","ct_comments_checked","ct_comments_spam","ct_comments_bad","ct_unchecked","ct_date_from","ct_date_till","animate_comment","to","id","jQuery","fadeTo","ct_clear_comments","from","till","is","val","data","action","security","ajax","type","url","ajaxurl","success","msg","ct_show_info","ct_send_comments","ct_cooling_down_toggle","setTimeout","new_check","unchecked","new_href","status_string","parseJSON","parseInt","error","confirm","error_message","location","href","end","document","cookie","hide","checked","spam","bad","ct_status_string","ct_status_string_warning","html","jqXHR","textStatus","errorThrown","show","timeout","message","total","ct_toggle_depended","obj","secondary","depended","prop","removeProp","ct_delete_all","e","target","addClass","css","removeClass","ready","on","datepicker","setDefaults","regional","dates","dateFormat","maxDate","changeMonth","changeYear","showAnim","onSelect","selectedDate","option","instance","date","parseDate","settings","_defaults","not","ct_start_check","continue_check","alert","click","ct_check","accurate","JSON","stringify","start","Date","toUTCString","ct_confirm_deletion_all"],"mappings":"AAYA,IAAIA,aAXJC,OAAOC,UAAUC,OAAS,WACtB,IAAIC,EAAYC,KAChB,IAAK,IAAIC,KAAOC,UAClB,IAAIC,EAAmBJ,EAAUK,UAAU,EAAGL,EAAUM,QAAQ,KAAM,IAClEC,EAAmBP,EAAUK,UAAUL,EAAUM,QAAQ,KAAM,GAAG,EAAGN,EAAUQ,QACnFR,EAAYI,EAAmBD,UAAUD,GAAOK,EAE9C,OAAOP,IAKVS,cAAe,EACfC,sBAAuB,EACvBC,kBAAmB,EACnBC,mBAAoB,EACpBC,UAAW,EACXC,iBAAmBC,gBAAgBD,iBACnCE,aAAeD,gBAAgBC,aAC/BC,aAAeF,gBAAgBE,aAE5BC,kBAAoB,IACvBC,oBAAsB,EACtBC,gBAAkB,GAEfC,cAAgBN,gBAAgBM,cACnCC,kBAAoB,EACpBC,oBAAsB,EACtBC,iBAAmB,EACnBC,gBAAkB,EAClBC,aAAe,QACfC,aAAe,EACfC,aAAe,EAEhB,SAASC,gBAAgBC,EAAGC,GACxBpB,iBACK,IAAJmB,EACFE,OAAO,YAAYD,GAAIE,OAAO,IAAIH,EAAG,WACpCD,gBAAgB,EAAEE,KAGnBC,OAAO,YAAYD,GAAIE,OAAO,IAAIH,EAAG,WACpCD,gBAAgB,GAAIE,KAItBpB,kBAAiB,EAInB,SAASuB,oBAER,IAAIC,EAAO,EAAGC,EAAO,EAClBJ,OAAO,wBAAwBK,GAAG,cACpCF,EAAOH,OAAO,uBAAuBM,MACrCF,EAAOJ,OAAO,uBAAuBM,OAEtC,IAAIC,EAAO,CACVC,OAAa,sBACbC,SAAapB,cACbc,KAAaA,EACbC,KAAaA,GAGdJ,OAAOU,KAAK,CACXC,KAAM,OACNC,IAAKC,QACLN,KAAMA,EACNO,QAAS,SAASC,GACjBC,eACAC,sBAOH,SAASC,yBACRxC,sBAAuB,EACvBuC,mBACAD,eAGD,SAASC,mBAER,IAA4B,IAAzBvC,qBAAH,CAGA,GAA0BU,iBAAvBD,oBAIF,OAHAgC,WAAWD,uBAAwBhC,wBAEnCR,uBADAS,oBAAsB,IAItBA,sBAGD,IAAIoB,EAAO,CACVC,OAAU,sBACVC,SAAYpB,cACZ+B,UAAa3C,aACb4C,UAAa3B,cAGXd,oBACF2B,EAAqB,gBAAI,GAEvBZ,cAAgBC,eAClBW,EAAW,KAAIZ,aACfY,EAAW,KAAIX,cAGhBI,OAAOU,KAAK,CACXC,KAAM,OACNC,IAAKC,QACLN,KAAMA,EACNO,QAAS,SAASC,GAIjB,IAgBMO,EAUAC,EA5BNR,EAAMf,OAAOwB,UAAUT,GAEpBU,SAASV,EAAIW,QACf9D,YAAW,EACP+D,QAAQZ,EAAIa,cAAc,6BAM7BX,oBALIK,EAAW,uCACI,GAAhB3B,cAAqC,GAAhBC,eACvB0B,GAAU,SAAS3B,aAAa,SAASC,cAC1CiC,SAASC,KAAOR,KAIjB7C,cAAe,EACS,GAArBgD,SAASV,EAAIgB,OAA0B,IAAblD,UACJ,GAArB4C,SAASV,EAAIgB,OACfC,SAASC,OAAS,gDACnBrE,YAAW,EACXoC,OAAO,uBAAuBkC,OAC1BZ,EAAW,uCACI,GAAhB3B,cAAqC,GAAhBC,eACvB0B,GAAU,SAAS3B,aAAa,SAASC,cAC1CiC,SAASC,KAAOR,GACa,GAArBG,SAASV,EAAIgB,OACrBxC,qBAAuBwB,EAAIoB,QAC3B3C,kBAAoBuB,EAAIqB,KACxB3C,iBAAmBsB,EAAIsB,IACvB3C,aAAeJ,kBAAoBC,oBAAsBE,gBAErD8B,GADAA,EAAgB1D,OAAOkB,gBAAgBuD,mBACTvE,OAAOwB,oBAAqBC,iBAAkBC,iBAChD,EAA7BgC,SAASjC,oBACX+B,GAAiBxC,gBAAgBwD,0BAClCvC,OAAO,uBAAuBwC,KAAKjB,GACnCvB,OAAO,qBAAqBkC,QAExB5C,kBAAoBC,oBAAsBE,kBAC7CuC,SAASC,OAAS,kDAClBD,SAASC,OAAS,iDAClBJ,SAASC,KAAO,wCAEjBb,sBAIGS,MAAO,SAASe,EAAOC,EAAYC,GACxC3C,OAAO,qBAAqB4C,OAC5B5C,OAAO,yBAAyBwC,KAAKE,GACrC1C,OAAO,sBAAsBwC,KAAK,kBAClCrB,WAAWF,mBAAoB,MAE1B4B,QAAS,QAGjB,SAAS7B,eAER,GAAGpD,WAAW,CAEb,GAA2B,GAAxBc,qBAGF,OAFAsB,OAAO,sBAAsBwC,KAAK,uDAClCxC,OAAO,sBAAsB4C,OAM9B,IAEKrC,EALJP,OAAO,sBAAsBkC,OAG1B5C,oBAECiB,EAAO,CACVC,OAAU,qBACVC,SAAYpB,eAGVM,cAAgBC,eAClBW,EAAW,KAAIZ,aACfY,EAAW,KAAIX,cAGhBI,OAAOU,KAAK,CACXC,KAAM,OACNC,IAAKC,QACLN,KAAMA,EACNO,QAAS,SAASC,GACjBA,EAAMf,OAAOwB,UAAUT,GACvBf,OAAO,uBAAuBwC,KAAKzB,EAAI+B,SACvCxD,kBAAsByB,EAAIgC,MAC1BvD,iBAAsBuB,EAAIqB,KAC1B7C,oBAAsBwB,EAAIoB,QAC1B1C,gBAAsBsB,EAAIsB,KAE3BX,MAAO,SAASe,EAAOC,EAAYC,GAClC3C,OAAO,qBAAqB4C,OAC5B5C,OAAO,yBAAyBwC,KAAKE,GACrC1C,OAAO,sBAAsBwC,KAAK,kBAClCrB,WAAWH,eAAgB,MAE5B6B,QAAS,SAOb,SAASG,mBAAmBC,EAAKC,GAE7BA,EAAYA,GAAa,KAE5B,IAAIC,EAAWnD,OAAOiD,EAAI1C,KAAK,aACtB0C,EAAI1C,KAAK,UAEJ2C,GAIbD,EAAI1C,KAAK,SAAS,GAClB4C,EAASC,KAAK,YAAY,GAC1BD,EAASE,WAAW,WACjBF,EAAS5C,KAAK,aAChByC,mBAAmBG,GAAU,KAP9BF,EAAI1C,KAAK,SAAS,GAClB4C,EAASE,WAAW,aAUtB,SAASC,cAAeC,GAEvB,IAAIhD,EAAO,CACVC,OAAU,kBACVC,SAAYpB,eAGbW,OAAO,IAAMuD,EAAEC,OAAOzD,IAAI0D,SAAS,YACnCzD,OAAO,YAAY0D,IAAI,aAAc,WACrC1D,OAAOU,KAAK,CACXC,KAAM,OACNC,IAAKC,QACLN,KAAMA,EACNO,QAAS,SAAUC,GACR,EAANA,GACHf,OAAO,4BAA4BwC,KAAKzB,GACxCuC,cAAeC,KAEfvD,OAAO,IAAMuD,EAAEC,OAAOzD,IAAI4D,YAAY,YACtC3D,OAAO,YAAY0D,IAAI,aAAc,UACrC7B,SAASC,KAAK,+CAGhBJ,MAAO,SAASe,EAAOC,EAAYC,GAClC3C,OAAO,qBAAqB4C,OAC5B5C,OAAO,yBAAyBwC,KAAKE,GACrC1C,OAAO,sBAAsBwC,KAAK,kBAClCrB,WAAWmC,cAAeC,GAAK,MAEhCV,QAAS,OAKX7C,OAAOgC,UAAU4B,MAAM,WAGnB9E,kBACFkB,OAAO,sBAAsBoD,KAAK,WAAW,GAE3CpE,eACFgB,OAAO,wBAAwBoD,KAAK,WAAW,GAAM7C,KAAK,SAAS,GACnEP,OAAO,uBAAuBqD,WAAW,YAAY/C,IAAItB,cACzDgB,OAAO,uBAAuBqD,WAAW,YAAY/C,IAAIrB,eAI1De,OAAO,wBAAwB6D,GAAG,SAAU,WAC3C7B,SAASC,OAAS,sBAAuBjC,OAAO,uBAAuBM,MAAO,yBAC9E0B,SAASC,OAAS,sBAAuBjC,OAAO,uBAAuBM,MAAO,yBAC1ErC,KAAKkE,SACRH,SAASC,OAAS,gDAClBjC,OAAO,YAAYoD,KAAK,WAAW,GAAMC,WAAW,cAEpDrB,SAASC,OAAS,gDAClBjC,OAAO,YAAYoD,KAAK,YAAY,GAAMC,WAAW,cAIpDrD,OAAO8D,WAAWC,YAAY/D,OAAO8D,WAAWE,SAAa,IAChE,IAAIC,EAAQjE,OAAO,4CAA4C8D,WAC9D,CACCI,WAAY,SACZC,QAAQ,MACRC,aAAY,EACZC,YAAW,EACXC,SAAU,YACVC,SAAU,SAASC,GACnB,IAAIC,EAAoB,sBAAXxG,KAAK8B,GAA6B,UAAY,UAC1D2E,EAAW1E,OAAQ/B,MAAOsC,KAAM,cAChCoE,EAAO3E,OAAO8D,WAAWc,UACxBF,EAASG,SAASX,YAAclE,OAAO8D,WAAWgB,UAAUZ,WAC5DM,EAAcE,EAASG,UACxBZ,EAAMc,IAAI9G,MAAM6F,WAAW,SAAUW,EAAQE,GAC7C3C,SAASC,OAAS,sBAAuBjC,OAAO,uBAAuBM,MAAO,yBAC9E0B,SAASC,OAAS,sBAAuBjC,OAAO,uBAAuBM,MAAO,4BAKjF,SAAS0E,EAAeC,GAEjBA,EAAiBA,GAAkB,KAEtCjF,OAAO,wBAAwBK,GAAG,cAEpCV,aAAeK,OAAO,uBAAuBM,MAC7CV,aAAeI,OAAO,uBAAuBM,MAExB,IAAhBX,cAAsC,IAAhBC,cAC1BsF,MAAM,kCAKLlF,OAAO,sBAAsBK,GAAG,cAClCzB,mBAAoB,GAGrBoB,OAAO,eAAekC,OACtBlC,OAAO,uBAAuB4C,OAC9B5C,OAAO,iBAAiB4C,OACxB5C,OAAO,aAAa4C,OAEpBhF,YAAW,EAERqH,GACFjE,eACAC,oBAEAf,qBAKFF,OAAO,yBAAyBmF,MAAM,WAErCH,IADAhD,SAASC,OAAS,mDAGnBjC,OAAO,4BAA4BmF,MAAM,WACxCH,GAAe,KAIhBhF,OAAO,aAAa6D,GAAG,QAAS,WAC/BhF,UAAW,EACX,IAAIuG,EAAW,CACdC,SAAYzG,kBACZuB,KAAYR,aACZS,KAAYR,cAEboC,SAASC,OAAS,wBAA0BqD,KAAKC,UAAUH,GAAY,2BAI3C,MAA1BrG,gBAAgByG,QAClBxD,SAASC,OAAS,sCAAwC,IAAIwD,KAAK,GAAGC,cAAgB,yBACtF1F,OAAO,yBAAyBmF,SAIjCnF,OAAO,kBAAkBmF,MAAM,SAAU5B,GAExC,QAAK5B,QAAQ5C,gBAAgB4G,+BAG7BrC,cAAeC"}
js/cleantalk-users-checkspam.min.js CHANGED
@@ -1,2 +1,2 @@
1
- String.prototype.printf=function(){var e=this;for(var t in arguments)var c=e.substring(0,e.indexOf("%s",0)),a=e.substring(e.indexOf("%s",0)+2,e.length),e=c+arguments[t]+a;return e};var ct_working=!(document.cookie="ct_check_users__amount=100; path=/; samesite=lax"),ct_new_check=!0,ct_cooling_down_flag=!1,ct_close_animate=!0,ct_accurate_check=!1,ct_pause=!1,ct_prev_accurate=ctUsersCheck.ct_prev_accurate,ct_prev_from=ctUsersCheck.ct_prev_from,ct_prev_till=ctUsersCheck.ct_prev_till,ct_cool_down_time=9e4,ct_requests_counter=0,ct_max_requests=60,ct_ajax_nonce=ctUsersCheck.ct_ajax_nonce,ct_users_total=0,ct_users_checked=0,ct_users_spam=0,ct_users_bad=0,ct_unchecked="unset",ct_date_from=0,ct_date_till=0;function apbct_cookie__get(_,r){var s={};return"string"==typeof(_=_||null)&&(_=_.split()),"none"===(r=r||["apbct_","ct_"])&&(r=null),"string"==typeof r&&(r=r.split()),document.cookie.split(";").forEach(function(e,t,c){var a=e.trim().split("=");_&&_.forEach(function(e,t,c){a[0]===e&&(s[a[0]]=a[1])}),r&&r.forEach(function(e,t,c){0===a[0].indexOf(e)&&(s[a[0]]=a[1])})}),s}function apbct_get_cookie(e){var t=apbct_cookie__get(e,e);return"object"==typeof t&&void 0!==t[e]?t[e]:null}function animate_comment(e,t){ct_close_animate?.3===e?jQuery("#comment-"+t).fadeTo(200,e,function(){animate_comment(1,t)}):jQuery("#comment-"+t).fadeTo(200,e,function(){animate_comment(.3,t)}):ct_close_animate=!0}function ct_clear_users(){var e=0,t=0;jQuery("#ct_allow_date_range").is(":checked")&&(e=jQuery("#ct_date_range_from").val(),t=jQuery("#ct_date_range_till").val());var c={action:"ajax_clear_users",security:ct_ajax_nonce,from:e,till:t,no_cache:Math.random()};jQuery.ajax({type:"POST",url:ajaxurl,data:c,success:function(e){ct_show_users_info(),ct_send_users()}})}function ct_cooling_down_toggle(){ct_cooling_down_flag=!1,ct_send_users(),ct_show_users_info()}function ct_send_users(){if(!0!==ct_cooling_down_flag){if(ct_max_requests<=ct_requests_counter)return setTimeout(ct_cooling_down_toggle,ct_cool_down_time),void(ct_cooling_down_flag=!(ct_requests_counter=0));ct_requests_counter++;var a=apbct_get_cookie("ct_check_users__amount"),e={action:"ajax_check_users",security:ct_ajax_nonce,new_check:ct_new_check,unchecked:ct_unchecked,amount:a,no_cache:Math.random()};ct_accurate_check&&(e.accurate_check=!0),ct_date_from&&ct_date_till&&(e.from=ct_date_from,e.till=ct_date_till),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){var t,c;e=jQuery.parseJSON(e),parseInt(e.error)?(ct_working=!1,confirm(e.error_message+". Do you want to proceed?")?ct_send_users():(t="users.php?page=ct_check_users",0!=ct_date_from&&0!=ct_date_till&&(t+="&from="+ct_date_from+"&till="+ct_date_till),location.href=t)):(ct_new_check=!1,1==parseInt(e.end)||1==ct_pause?(1==parseInt(e.end)&&(document.cookie="ct_paused_users_check=0; path=/; samesite=lax"),ct_working=!1,jQuery("#ct_working_message").hide(),t="users.php?page=ct_check_users&ct_worked=1",0!=ct_date_from&&0!=ct_date_till&&(t+="&from="+ct_date_from+"&till="+ct_date_till),location.href=t):0==parseInt(e.end)&&(ct_users_checked=parseInt(ct_users_checked)+parseInt(e.checked),ct_users_spam=parseInt(ct_users_spam)+parseInt(e.spam),ct_users_bad=parseInt(ct_users_bad)+parseInt(e.bad),ct_unchecked=ct_users_total-ct_users_checked-ct_users_bad,c=(c=String(ctUsersCheck.ct_status_string)).printf(ct_users_checked,ct_users_spam,ct_users_bad),0<parseInt(ct_users_spam)&&(c+=ctUsersCheck.ct_status_string_warning),jQuery("#ct_checking_status").html(c),jQuery("#ct_error_message").hide(),ct_send_users()))},error:function(e,t,c){20<a&&(a-=20,document.cookie="ct_check_users__amount="+a+"; path=/; samesite=lax"),jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Check users"),setTimeout(ct_send_users(),3e3)},timeout:25e3})}}function ct_show_users_info(){if(ct_working){if(!0===ct_cooling_down_flag)return void jQuery("#ct_cooling_notice").html("Waiting for API to cool down. (About a minute)").show();var e;jQuery("#ct_cooling_notice").hide(),ct_users_total||(e={action:"ajax_info_users",security:ct_ajax_nonce,no_cache:Math.random()},ct_date_from&&ct_date_till&&(e.from=ct_date_from,e.till=ct_date_till),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){e=jQuery.parseJSON(e),jQuery("#ct_checking_status").html(e.message),ct_users_spam=e.spam,ct_users_checked=e.checked,ct_users_bad=e.bad},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Show users"),setTimeout(ct_show_users_info(),3e3)},timeout:15e3}))}}function ct_toggle_depended(e,t){t=t||null;var c=jQuery(e.data("depended"));e.data("state")||t?(e.data("state",!1),c.prop("disabled",!0),c.removeProp("checked"),c.data("depended")&&ct_toggle_depended(c,!0)):(e.data("state",!0),c.removeProp("disabled"))}function ct_start_check(e){e=e||null,jQuery("#ct_allow_date_range").is(":checked")&&(ct_date_from=jQuery("#ct_date_range_from").val(),ct_date_till=jQuery("#ct_date_range_till").val(),""===ct_date_from||""===ct_date_till)?alert("Please, specify a date range."):(jQuery("#ct_accurate_check").is(":checked")&&(ct_accurate_check=!0),jQuery(".ct_to_hide").hide(),jQuery("#ct_working_message").show(),jQuery("#ct_preloader").show(),jQuery("#ct_pause").show(),ct_working=!0,e?(ct_show_users_info(),ct_send_users()):ct_clear_users())}function ct_delete_all_users(a){var t={action:"ajax_delete_all_users",security:ct_ajax_nonce,no_cache:Math.random()};jQuery("."+a.target.id).addClass("disabled"),jQuery(".spinner").css("visibility","visible"),jQuery.ajax({type:"POST",url:ajaxurl,data:t,success:function(e){0<e?(jQuery("#cleantalk_users_left").html(e),ct_delete_all_users(a,t)):(jQuery("."+a.target.id).removeClass("disabled"),jQuery(".spinner").css("visibility","hidden"),location.href="users.php?page=ct_check_users_total")},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("All users deleteion"),setTimeout(ct_delete_all_users(a),3e3)},timeout:25e3})}jQuery(document).ready(function(){jQuery("#ct_allow_date_range").data({depended:".ct_date",state:!1}),ct_prev_accurate&&jQuery("#ct_accurate_check").prop("checked",!0),ct_prev_from&&(jQuery("#ct_allow_date_range").prop("checked",!0).data("state",!0),jQuery("#ct_date_range_from").removeProp("disabled").val(ct_prev_from),jQuery("#ct_date_range_till").removeProp("disabled").val(ct_prev_till)),jQuery("#ct_allow_date_range, #ct_accurate_check").on("change",function(){ct_toggle_depended(jQuery(this))}),jQuery.datepicker.setDefaults(jQuery.datepicker.regional.en);var _=jQuery("#ct_date_range_from, #ct_date_range_till").datepicker({dateFormat:"M d yy",maxDate:"+0D",changeMonth:!0,changeYear:!0,showAnim:"slideDown",onSelect:function(e){var t="ct_date_range_from"==this.id?"minDate":"maxDate",c=jQuery(this).data("datepicker"),a=jQuery.datepicker.parseDate(c.settings.dateFormat||jQuery.datepicker._defaults.dateFormat,e,c.settings);_.not(this).datepicker("option",t,a)}});function t(t){t=t||null;var e={action:"ajax_insert_users",security:ct_ajax_nonce,no_cache:Math.random()};t&&(e.delete=!0),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){t?alert("Deleted "+e+" users"):alert("Inserted "+e+" users")}})}jQuery("#ct_check_spam_button").click(function(){ct_start_check(!(document.cookie="ct_paused_users_check=0; path=/; samesite=lax"))}),jQuery("#ct_proceed_check_button").click(function(){ct_start_check(!0)}),jQuery("#ct_pause").on("click",function(){ct_pause=!0;var e={accurate:ct_accurate_check,from:ct_date_from,till:ct_date_till};document.cookie="ct_paused_users_check="+JSON.stringify(e)+"; path=/; samesite=lax"}),jQuery(".cleantalk_delete_from_list_button").click(function(){ct_id=jQuery(this).attr("data-id");var e={action:"ajax_ct_approve_user",security:ct_ajax_nonce,id:ct_id,no_cache:Math.random()};jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){jQuery("#comment-"+ct_id).fadeOut("slow",function(){jQuery("#comment-"+ct_id).remove()})}});e={action:"ct_feedback_user",security:ct_ajax_nonce,user_id:ct_id,status:"approve",no_cache:Math.random()};jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){},error:function(e,t,c){},timeout:5e3})}),jQuery(".ct_get_csv_file").click(function(a){var e={action:"ajax_ct_get_csv_file",security:ct_ajax_nonce,filename:ctUsersCheck.ct_csv_filename,no_cache:Math.random()};jQuery("."+a.target.id).addClass("disabled"),jQuery(".spinner").css("visibility","visible"),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){var t,c;0===parseInt(e)?alert(ctUsersCheck.ct_bad_csv):(t=URL.createObjectURL(new Blob([e])),(c=document.createElement("a")).href=t,c.download=ctUsersCheck.ct_csv_filename+".csv",document.body.appendChild(c),c.click()),jQuery("."+a.target.id).removeClass("disabled"),jQuery(".spinner").css("visibility","hidden")}})}),jQuery(".ct_insert_users").click(function(e){t()}),jQuery(".ct_insert_users__delete").click(function(e){t(!0)}),jQuery(".ct_delete_all_users").click(function(e){return!!confirm(ctUsersCheck.ct_confirm_deletion_all)&&void ct_delete_all_users(e)})});
2
  //# sourceMappingURL=cleantalk-users-checkspam.min.js.map
1
+ String.prototype.printf=function(){var e=this;for(var t in arguments)var c=e.substring(0,e.indexOf("%s",0)),a=e.substring(e.indexOf("%s",0)+2,e.length),e=c+arguments[t]+a;return e};var ct_working=!(document.cookie="ct_check_users__amount=100; path=/; samesite=lax"),ct_new_check=!0,ct_cooling_down_flag=!1,ct_close_animate=!0,ct_accurate_check=!1,ct_pause=!1,ct_prev_accurate=ctUsersCheck.ct_prev_accurate,ct_prev_from=ctUsersCheck.ct_prev_from,ct_prev_till=ctUsersCheck.ct_prev_till,ct_cool_down_time=9e4,ct_requests_counter=0,ct_max_requests=60,ct_ajax_nonce=ctUsersCheck.ct_ajax_nonce,ct_users_total=0,ct_users_checked=0,ct_users_spam=0,ct_users_bad=0,ct_unchecked="unset",ct_date_from=0,ct_date_till=0;function apbct_cookie__get(_,r){var s={};return"string"==typeof(_=_||null)&&(_=_.split()),"none"===(r=r||["apbct_","ct_"])&&(r=null),"string"==typeof r&&(r=r.split()),document.cookie.split(";").forEach(function(e,t,c){var a=e.trim().split("=");_&&_.forEach(function(e,t,c){a[0]===e&&(s[a[0]]=a[1])}),r&&r.forEach(function(e,t,c){0===a[0].indexOf(e)&&(s[a[0]]=a[1])})}),s}function apbct_get_cookie(e){var t=apbct_cookie__get(e,e);return"object"==typeof t&&void 0!==t[e]?t[e]:null}function animate_comment(e,t){ct_close_animate?.3===e?jQuery("#comment-"+t).fadeTo(200,e,function(){animate_comment(1,t)}):jQuery("#comment-"+t).fadeTo(200,e,function(){animate_comment(.3,t)}):ct_close_animate=!0}function ct_clear_users(){var e=0,t=0;jQuery("#ct_allow_date_range").is(":checked")&&(e=jQuery("#ct_date_range_from").val(),t=jQuery("#ct_date_range_till").val());var c={action:"ajax_clear_users",security:ct_ajax_nonce,from:e,till:t,no_cache:Math.random()};jQuery.ajax({type:"POST",url:ajaxurl,data:c,success:function(e){ct_show_users_info(),ct_send_users()}})}function ct_cooling_down_toggle(){ct_cooling_down_flag=!1,ct_send_users(),ct_show_users_info()}function ct_send_users(){if(!0!==ct_cooling_down_flag){if(ct_max_requests<=ct_requests_counter)return setTimeout(ct_cooling_down_toggle,ct_cool_down_time),void(ct_cooling_down_flag=!(ct_requests_counter=0));ct_requests_counter++;var a=apbct_get_cookie("ct_check_users__amount"),e={action:"ajax_check_users",security:ct_ajax_nonce,new_check:ct_new_check,unchecked:ct_unchecked,amount:a,no_cache:Math.random()};ct_accurate_check&&(e.accurate_check=!0),ct_date_from&&ct_date_till&&(e.from=ct_date_from,e.till=ct_date_till),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){var t,c;e=jQuery.parseJSON(e),parseInt(e.error)?(ct_working=!1,confirm(e.error_message+". Do you want to proceed?")?ct_send_users():(t="users.php?page=ct_check_users",0!=ct_date_from&&0!=ct_date_till&&(t+="&from="+ct_date_from+"&till="+ct_date_till),location.href=t)):(ct_new_check=!1,1==parseInt(e.end)||1==ct_pause?(1==parseInt(e.end)&&(document.cookie="ct_paused_users_check=0; path=/; samesite=lax"),ct_working=!1,jQuery("#ct_working_message").hide(),t="users.php?page=ct_check_users&ct_worked=1",0!=ct_date_from&&0!=ct_date_till&&(t+="&from="+ct_date_from+"&till="+ct_date_till),location.href=t):0==parseInt(e.end)&&(ct_users_checked=parseInt(ct_users_checked)+parseInt(e.checked),ct_users_spam=parseInt(ct_users_spam)+parseInt(e.spam),ct_users_bad=parseInt(ct_users_bad)+parseInt(e.bad),ct_unchecked=ct_users_total-ct_users_checked-ct_users_bad,c=(c=String(ctUsersCheck.ct_status_string)).printf(ct_users_checked,ct_users_spam,ct_users_bad),0<parseInt(ct_users_spam)&&(c+=ctUsersCheck.ct_status_string_warning),jQuery("#ct_checking_status").html(c),jQuery("#ct_error_message").hide(),ct_send_users()))},error:function(e,t,c){20<a&&(a-=20,document.cookie="ct_check_users__amount="+a+"; path=/; samesite=lax"),jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Check users"),setTimeout(ct_send_users(),3e3)},timeout:25e3})}}function ct_show_users_info(){if(ct_working){if(!0===ct_cooling_down_flag)return void jQuery("#ct_cooling_notice").html("Waiting for API to cool down. (About a minute)").show();var e;jQuery("#ct_cooling_notice").hide(),ct_users_total||(e={action:"ajax_info_users",security:ct_ajax_nonce,no_cache:Math.random()},ct_date_from&&ct_date_till&&(e.from=ct_date_from,e.till=ct_date_till),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){e=jQuery.parseJSON(e),jQuery("#ct_checking_status").html(e.message),ct_users_spam=e.spam,ct_users_checked=e.checked,ct_users_bad=e.bad},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("Show users"),setTimeout(ct_show_users_info(),3e3)},timeout:15e3}))}}function ct_toggle_depended(e,t){t=t||null;var c=jQuery(e.data("depended"));e.data("state")||t?(e.data("state",!1),c.prop("disabled",!0),c.removeProp("checked"),c.data("depended")&&ct_toggle_depended(c,!0)):(e.data("state",!0),c.removeProp("disabled"))}function ct_start_check(e){e=e||null,jQuery("#ct_allow_date_range").is(":checked")&&(ct_date_from=jQuery("#ct_date_range_from").val(),ct_date_till=jQuery("#ct_date_range_till").val(),""===ct_date_from||""===ct_date_till)?alert("Please, specify a date range."):(jQuery("#ct_accurate_check").is(":checked")&&(ct_accurate_check=!0),jQuery(".ct_to_hide").hide(),jQuery("#ct_working_message").show(),jQuery("#ct_preloader").show(),jQuery("#ct_pause").show(),ct_working=!0,e?(ct_show_users_info(),ct_send_users()):ct_clear_users())}function ct_delete_all_users(a){var t={action:"ajax_delete_all_users",security:ct_ajax_nonce,no_cache:Math.random()};jQuery("."+a.target.id).addClass("disabled"),jQuery(".spinner").css("visibility","visible"),jQuery.ajax({type:"POST",url:ajaxurl,data:t,success:function(e){0<e?(jQuery("#cleantalk_users_left").html(e),ct_delete_all_users(a,t)):(jQuery("."+a.target.id).removeClass("disabled"),jQuery(".spinner").css("visibility","hidden"),location.href="users.php?page=ct_check_users_total")},error:function(e,t,c){jQuery("#ct_error_message").show(),jQuery("#cleantalk_ajax_error").html(t),jQuery("#cleantalk_js_func").html("All users deleteion"),setTimeout(ct_delete_all_users(a),3e3)},timeout:25e3})}jQuery(document).ready(function(){ct_prev_accurate&&jQuery("#ct_accurate_check").prop("checked",!0),ct_prev_from&&(jQuery("#ct_allow_date_range").prop("checked",!0).data("state",!0),jQuery("#ct_date_range_from").removeProp("disabled").val(ct_prev_from),jQuery("#ct_date_range_till").removeProp("disabled").val(ct_prev_till)),jQuery("#ct_allow_date_range").on("change",function(){document.cookie="ct_users_dates_from="+jQuery("#ct_date_range_from").val()+"; path=/; samesite=lax",document.cookie="ct_users_dates_till="+jQuery("#ct_date_range_till").val()+"; path=/; samesite=lax",this.checked?(document.cookie="ct_users_dates_allowed=1; path=/; samesite=lax",jQuery(".ct_date").prop("checked",!0).removeProp("disabled")):(document.cookie="ct_users_dates_allowed=0; path=/; samesite=lax",jQuery(".ct_date").prop("disabled",!0).removeProp("checked"))}),jQuery.datepicker.setDefaults(jQuery.datepicker.regional.en);var _=jQuery("#ct_date_range_from, #ct_date_range_till").datepicker({dateFormat:"M d yy",maxDate:"+0D",changeMonth:!0,changeYear:!0,showAnim:"slideDown",onSelect:function(e){var t="ct_date_range_from"==this.id?"minDate":"maxDate",c=jQuery(this).data("datepicker"),a=jQuery.datepicker.parseDate(c.settings.dateFormat||jQuery.datepicker._defaults.dateFormat,e,c.settings);_.not(this).datepicker("option",t,a),document.cookie="ct_users_dates_from="+jQuery("#ct_date_range_from").val()+"; path=/; samesite=lax",document.cookie="ct_users_dates_till="+jQuery("#ct_date_range_till").val()+"; path=/; samesite=lax"}});function t(t){t=t||null;var e={action:"ajax_insert_users",security:ct_ajax_nonce,no_cache:Math.random()};t&&(e.delete=!0),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){t?alert("Deleted "+e+" users"):alert("Inserted "+e+" users")}})}jQuery("#ct_check_spam_button").click(function(){ct_start_check(!(document.cookie="ct_paused_users_check=0; path=/; samesite=lax"))}),jQuery("#ct_proceed_check_button").click(function(){ct_start_check(!0)}),jQuery("#ct_pause").on("click",function(){ct_pause=!0;var e={accurate:ct_accurate_check,from:ct_date_from,till:ct_date_till};document.cookie="ct_paused_users_check="+JSON.stringify(e)+"; path=/; samesite=lax"}),jQuery(".cleantalk_delete_from_list_button").click(function(){ct_id=jQuery(this).attr("data-id");var e={action:"ajax_ct_approve_user",security:ct_ajax_nonce,id:ct_id,no_cache:Math.random()};jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){jQuery("#comment-"+ct_id).fadeOut("slow",function(){jQuery("#comment-"+ct_id).remove()})}});e={action:"ct_feedback_user",security:ct_ajax_nonce,user_id:ct_id,status:"approve",no_cache:Math.random()};jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){},error:function(e,t,c){},timeout:5e3})}),jQuery(".ct_get_csv_file").click(function(a){var e={action:"ajax_ct_get_csv_file",security:ct_ajax_nonce,filename:ctUsersCheck.ct_csv_filename,no_cache:Math.random()};jQuery("."+a.target.id).addClass("disabled"),jQuery(".spinner").css("visibility","visible"),jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(e){var t,c;0===parseInt(e)?alert(ctUsersCheck.ct_bad_csv):(t=URL.createObjectURL(new Blob([e])),(c=document.createElement("a")).href=t,c.download=ctUsersCheck.ct_csv_filename+".csv",document.body.appendChild(c),c.click()),jQuery("."+a.target.id).removeClass("disabled"),jQuery(".spinner").css("visibility","hidden")}})}),jQuery(".ct_insert_users").click(function(e){t()}),jQuery(".ct_insert_users__delete").click(function(e){t(!0)}),jQuery(".ct_delete_all_users").click(function(e){return!!confirm(ctUsersCheck.ct_confirm_deletion_all)&&void ct_delete_all_users(e)})});
2
  //# sourceMappingURL=cleantalk-users-checkspam.min.js.map
js/cleantalk-users-checkspam.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cleantalk-users-checkspam.min.js","sources":["cleantalk-users-checkspam.js"],"sourcesContent":["// Printf for JS\r\nString.prototype.printf = function(){\r\n var formatted = this;\r\n for( var arg in arguments ) {\r\n\t\tvar before_formatted = formatted.substring(0, formatted.indexOf(\"%s\", 0));\r\n\t\tvar after_formatted = formatted.substring(formatted.indexOf(\"%s\", 0)+2, formatted.length);\r\n\t\tformatted = before_formatted + arguments[arg] + after_formatted;\r\n }\r\n return formatted;\r\n};\r\n\r\n// Set deafult amount to check by request.\r\ndocument.cookie = \"ct_check_users__amount=\" + 100 + \"; path=/; samesite=lax\";\r\n\r\n// Flags\r\nvar ct_working = false,\r\n\tct_new_check = true,\r\n\tct_cooling_down_flag = false,\r\n\tct_close_animate = true,\r\n\tct_accurate_check = false,\r\n\tct_pause = false,\r\n\tct_prev_accurate = ctUsersCheck.ct_prev_accurate,\r\n\tct_prev_from = ctUsersCheck.ct_prev_from,\t\r\n\tct_prev_till = ctUsersCheck.ct_prev_till;\r\n// Settings\r\nvar ct_cool_down_time = 90000,\r\n\tct_requests_counter = 0,\r\n\tct_max_requests = 60;\r\n// Variables\r\nvar ct_ajax_nonce = ctUsersCheck.ct_ajax_nonce,\r\n\tct_users_total = 0,\r\n\tct_users_checked = 0,\r\n\tct_users_spam = 0,\r\n\tct_users_bad = 0,\r\n\tct_unchecked = 'unset',\r\n\tct_date_from = 0,\r\n\tct_date_till = 0;\r\n\r\n/* Function: Reuturns cookie with prefix */\r\nfunction apbct_cookie__get(names, prefixes){\r\n\tvar cookie = {};\r\n\tnames = names || null;\r\n\tif(typeof names == 'string') names = names.split();\r\n\tprefixes = prefixes || ['apbct_', 'ct_'];\r\n\tif(prefixes === 'none') prefixes = null;\r\n\tif(typeof prefixes == 'string') prefixes = prefixes.split();\r\n\tdocument.cookie.split(';').forEach(function(item, i, arr){\r\n\t\tvar curr = item.trim().split('=');\r\n\t\t// Detect by full cookie name\r\n\t\tif(names){\r\n\t\t\tnames.forEach(function(name, i, all){\r\n\t\t\t\tif(curr[0] === name)\r\n\t\t\t\t\tcookie[curr[0]] = (curr[1]);\r\n\t\t\t});\r\n\t\t}\r\n\t\t// Detect by name prefix\r\n\t\tif(prefixes){\r\n\t\t\tprefixes.forEach(function(prefix, i, all){\r\n\t\t\t\tif(curr[0].indexOf(prefix) === 0)\r\n\t\t\t\t\tcookie[curr[0]] = (curr[1]);\r\n\t\t\t});\r\n\t\t}\r\n\t});\r\n\treturn cookie;\r\n}\r\n\r\nfunction apbct_get_cookie( name ){\r\n\tvar cookie = apbct_cookie__get( name, name );\r\n\tif(typeof cookie === 'object' && typeof cookie[name] != 'undefined'){\r\n\t\treturn cookie[name];\r\n\t}else\r\n\t\treturn null;\r\n}\r\n\r\nfunction animate_comment(to,id){\r\n\tif(ct_close_animate){\r\n\t\tif(to === 0.3){\r\n\t\t\tjQuery('#comment-'+id).fadeTo(200,to,function(){\r\n\t\t\t\tanimate_comment(1,id)\r\n\t\t\t});\r\n\t\t}else{\r\n\t\t\tjQuery('#comment-'+id).fadeTo(200,to,function(){\r\n\t\t\t\tanimate_comment(0.3,id)\r\n\t\t\t});\r\n\t\t}\r\n\t}else{\r\n\t\tct_close_animate=true;\r\n\t}\r\n}\r\n\r\nfunction ct_clear_users(){\r\n\r\n\tvar from = 0, till = 0;\r\n\tif(jQuery('#ct_allow_date_range').is(':checked')) {\r\n\t\tfrom = jQuery('#ct_date_range_from').val();\r\n\t\ttill = jQuery('#ct_date_range_till').val();\r\n\t}\r\n\tvar data = {\r\n\t\t'action' : 'ajax_clear_users',\r\n\t\t'security' : ct_ajax_nonce,\r\n\t\t'from' : from,\r\n\t\t'till' : till,\r\n\t\t'no_cache': Math.random()\r\n\t};\r\n\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function(msg){\r\n\t\t\tct_show_users_info();\r\n\t\t\tct_send_users();\r\n\t\t}\r\n\t});\r\n\r\n}\r\n\r\n//Continues the check after cooldown time\r\n//Called by ct_send_users();\r\nfunction ct_cooling_down_toggle(){\r\n\tct_cooling_down_flag = false;\r\n\tct_send_users();\r\n\tct_show_users_info();\r\n}\r\n\r\nfunction ct_send_users(){\r\n\t\r\n\tif(ct_cooling_down_flag === true)\r\n\t\treturn;\r\n\t\r\n\tif(ct_requests_counter >= ct_max_requests){\r\n\t\tsetTimeout(ct_cooling_down_toggle, ct_cool_down_time);\r\n\t\tct_requests_counter = 0;\r\n\t\tct_cooling_down_flag = true;\r\n\t\treturn;\r\n\t}else{\r\n\t\tct_requests_counter++;\r\n\t}\r\n\r\n\tvar check_amount = apbct_get_cookie('ct_check_users__amount');\r\n\r\n\tvar data = {\r\n\t\taction: 'ajax_check_users',\r\n\t\tsecurity: ct_ajax_nonce,\r\n\t\tnew_check: ct_new_check,\r\n\t\tunchecked: ct_unchecked,\r\n\t\tamount: check_amount,\r\n\t\t'no_cache': Math.random()\r\n\t};\r\n\t\r\n\tif(ct_accurate_check)\r\n\t\tdata['accurate_check'] = true;\r\n\t\r\n\tif(ct_date_from && ct_date_till){\r\n\t\tdata['from'] = ct_date_from;\r\n\t\tdata['till'] = ct_date_till;\r\n\t}\r\n\t\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function(msg){\r\n\t\t\t\r\n\t\t\tmsg = jQuery.parseJSON(msg);\r\n\t\t\t\r\n\t\t\tif(parseInt(msg.error)){\r\n\t\t\t\tct_working=false;\r\n\t\t\t\tif(!confirm(msg.error_message+\". Do you want to proceed?\")){\r\n\t\t\t\t\tvar new_href = 'users.php?page=ct_check_users';\r\n\t\t\t\t\tif(ct_date_from != 0 && ct_date_till != 0)\r\n\t\t\t\t\t\tnew_href+='&from='+ct_date_from+'&till='+ct_date_till;\r\n\t\t\t\t\tlocation.href = new_href;\r\n\t\t\t\t}else\r\n\t\t\t\t\tct_send_users();\r\n\t\t\t}else{\r\n\t\t\t\tct_new_check = false;\r\n\t\t\t\tif(parseInt(msg.end) == 1 || ct_pause == true){\r\n\t\t\t\t\tif(parseInt(msg.end) == 1)\r\n\t\t\t\t\t\tdocument.cookie = 'ct_paused_users_check=0; path=/; samesite=lax';\r\n\t\t\t\t\tct_working=false;\r\n\t\t\t\t\tjQuery('#ct_working_message').hide();\r\n\t\t\t\t\tvar new_href = 'users.php?page=ct_check_users&ct_worked=1';\r\n\t\t\t\t\tif(ct_date_from != 0 && ct_date_till != 0)\r\n\t\t\t\t\t\tnew_href+='&from='+ct_date_from+'&till='+ct_date_till;\r\n\t\t\t\t\tlocation.href = new_href;\r\n\t\t\t\t}else if(parseInt(msg.end) == 0){\r\n\t\t\t\t\tct_users_checked = parseInt( ct_users_checked ) + parseInt( msg.checked );\r\n\t\t\t\t\tct_users_spam = parseInt( ct_users_spam ) + parseInt (msg.spam );\r\n\t\t\t\t\tct_users_bad = parseInt( ct_users_bad ) + parseInt( msg.bad );\r\n\t\t\t\t\tct_unchecked = ct_users_total - ct_users_checked - ct_users_bad;\r\n\t\t\t\t\tvar status_string = String(ctUsersCheck.ct_status_string);\r\n\t\t\t\t\tvar status_string = status_string.printf(ct_users_checked, ct_users_spam, ct_users_bad);\r\n\t\t\t\t\tif(parseInt(ct_users_spam) > 0)\r\n\t\t\t\t\t\tstatus_string += ctUsersCheck.ct_status_string_warning;\r\n\t\t\t\t\tjQuery('#ct_checking_status').html(status_string);\r\n\t\t\t\t\tjQuery('#ct_error_message').hide();\r\n\t\t\t\t\tct_send_users();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n error: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\tif(check_amount > 20){\r\n\t\t\t\tcheck_amount -= 20;\r\n\t\t\t\tdocument.cookie = \"ct_check_users__amount=\" + check_amount + \"; path=/; samesite=lax\";\r\n\t\t\t}\r\n\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\tjQuery('#cleantalk_js_func').html('Check users');\r\n\t\t\tsetTimeout(ct_send_users(), 3000);\r\n },\r\n timeout: 25000\r\n\t});\r\n}\r\nfunction ct_show_users_info(){\r\n\t\r\n\tif( ct_working ){\r\n\t\t\r\n\t\tif(ct_cooling_down_flag === true){\r\n\t\t\tjQuery('#ct_cooling_notice').html('Waiting for API to cool down. (About a minute)').show();\r\n\t\t\treturn;\t\t\t\r\n\t\t}else{\r\n\t\t\tjQuery('#ct_cooling_notice').hide();\r\n\t\t}\r\n\t\t\r\n\t\tif( ! ct_users_total ){\r\n\t\t\t\r\n\t\t\tvar data = {\r\n\t\t\t\t'action': 'ajax_info_users',\r\n\t\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t\t'no_cache': Math.random()\r\n\t\t\t};\r\n\t\t\t\r\n\t\t\tif( ct_date_from && ct_date_till ){\r\n\t\t\t\tdata['from'] = ct_date_from;\r\n\t\t\t\tdata['till'] = ct_date_till;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tjQuery.ajax({\r\n\t\t\t\ttype: \"POST\",\r\n\t\t\t\turl: ajaxurl,\r\n\t\t\t\tdata: data,\r\n\t\t\t\tsuccess: function(msg){\r\n\t\t\t\t\tmsg = jQuery.parseJSON(msg);\r\n\t\t\t\t\tjQuery('#ct_checking_status').html(msg.message);\r\n\t\t\t\t\tct_users_spam = msg.spam;\r\n\t\t\t\t\tct_users_checked = msg.checked;\r\n\t\t\t\t\tct_users_bad = msg.bad;\r\n\t\t\t\t},\r\n\t\t\t\terror: function (jqXHR, textStatus, errorThrown){\r\n\t\t\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\t\t\tjQuery('#cleantalk_js_func').html('Show users');\r\n\t\t\t\t\tsetTimeout(ct_show_users_info(), 3000);\r\n\t\t\t\t},\r\n\t\t\t\ttimeout: 15000\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n}\r\n// Function to toggle dependences\r\nfunction ct_toggle_depended(obj, secondary){\r\n\r\n secondary = secondary || null;\r\n\r\n\tvar depended = jQuery(obj.data('depended')),\r\n\t\tstate = obj.data('state');\r\n\t\t\r\n\tif(!state && !secondary){\r\n\t\tobj.data('state', true);\r\n\t\tdepended.removeProp('disabled');\r\n\t}else{\r\n\t\tobj.data('state', false);\r\n\t\tdepended.prop('disabled', true);\r\n\t\tdepended.removeProp('checked');\r\n\t\tif(depended.data('depended'))\r\n\t\t\tct_toggle_depended(depended, true);\r\n\t}\r\n}\r\n\r\n// Main function of checking\r\nfunction ct_start_check( continue_check ){\r\n\r\n\tcontinue_check = continue_check || null;\r\n\r\n\tif(jQuery('#ct_allow_date_range').is(':checked')){\r\n\r\n\t\tct_date_from = jQuery('#ct_date_range_from').val();\r\n\t\tct_date_till = jQuery('#ct_date_range_till').val();\r\n\r\n\t\tif(!(ct_date_from !== '' && ct_date_till !== '')){\r\n\t\t\talert('Please, specify a date range.');\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n\r\n\tif(jQuery('#ct_accurate_check').is(':checked')){\r\n\t\tct_accurate_check = true;\r\n\t}\r\n\r\n\tjQuery('.ct_to_hide').hide();\r\n\tjQuery('#ct_working_message').show();\r\n\tjQuery('#ct_preloader').show();\r\n\tjQuery('#ct_pause').show();\r\n\r\n\tct_working = true;\r\n\r\n\tif( continue_check ){\r\n\t\tct_show_users_info();\r\n\t\tct_send_users();\r\n\t} else {\r\n\t\tct_clear_users();\r\n\t}\r\n\r\n}\r\n\r\nfunction ct_delete_all_users( e ){\r\n\r\n\tvar data = {\r\n\t\t'action': 'ajax_delete_all_users',\r\n\t\t'security': ct_ajax_nonce,\r\n\t\t'no_cache': Math.random()\r\n\t};\r\n\r\n\tjQuery('.' + e.target.id).addClass('disabled');\r\n\tjQuery('.spinner').css('visibility', 'visible');\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function( msg ){\r\n\t\t\tif( msg > 0 ){\r\n\t\t\t\tjQuery('#cleantalk_users_left').html(msg);\r\n\t\t\t\tct_delete_all_users( e, data );\r\n\t\t\t}else{\r\n\t\t\t\tjQuery('.' + e.target.id).removeClass('disabled');\r\n\t\t\t\tjQuery('.spinner').css('visibility', 'hidden');\r\n\t\t\t\tlocation.href='users.php?page=ct_check_users_total';\r\n\t\t\t}\r\n\t\t},\r\n\t\terror: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\tjQuery('#cleantalk_js_func').html('All users deleteion');\r\n\t\t\tsetTimeout(ct_delete_all_users( e ), 3000);\r\n\t\t},\r\n\t\ttimeout: 25000\r\n\t});\r\n}\r\n\r\njQuery(document).ready(function(){\r\n\r\n\t// Setting dependences\r\n\t// jQuery('#ct_accurate_check') .data({'depended': '#ct_allow_date_range', 'state': false});\r\n\tjQuery('#ct_allow_date_range').data({'depended': '.ct_date', 'state': false});\r\n\t\r\n\t// Prev check parameters\r\n\tif(ct_prev_accurate){\r\n\t\tjQuery(\"#ct_accurate_check\").prop('checked', true);\r\n\t}\r\n\tif(ct_prev_from){\r\n\t\tjQuery(\"#ct_allow_date_range\").prop('checked', true).data('state', true);\r\n\t\tjQuery(\"#ct_date_range_from\").removeProp('disabled').val(ct_prev_from);\r\n\t\tjQuery(\"#ct_date_range_till\").removeProp('disabled').val(ct_prev_till);\r\n\t}\r\n\t\r\n\t// Toggle dependences\r\n\tjQuery(\"#ct_allow_date_range, #ct_accurate_check\").on('change', function(){\r\n\t\tct_toggle_depended(jQuery(this));\r\n\t});\r\n\r\n\tjQuery.datepicker.setDefaults(jQuery.datepicker.regional['en']);\r\n\tvar dates = jQuery('#ct_date_range_from, #ct_date_range_till').datepicker(\r\n\t\t{\r\n\t\t\tdateFormat: 'M d yy',\r\n\t\t\tmaxDate:\"+0D\",\r\n\t\t\tchangeMonth:true,\r\n\t\t\tchangeYear:true,\r\n\t\t\tshowAnim: 'slideDown',\r\n\t\t\tonSelect: function(selectedDate){\r\n\t\t\tvar option = this.id == \"ct_date_range_from\" ? \"minDate\" : \"maxDate\",\r\n\t\t\t\tinstance = jQuery( this ).data( \"datepicker\" ),\r\n\t\t\t\tdate = jQuery.datepicker.parseDate(\r\n\t\t\t\t\tinstance.settings.dateFormat || jQuery.datepicker._defaults.dateFormat,\r\n\t\t\t\t\tselectedDate, instance.settings);\r\n\t\t\t\tdates.not(this).datepicker(\"option\", option, date);\r\n\t\t\t}\r\n\t\t}\r\n\t);\r\n\t\r\n\t// Check users\r\n\tjQuery(\"#ct_check_spam_button\").click(function(){\r\n\t\tdocument.cookie = 'ct_paused_users_check=0; path=/; samesite=lax';\r\n\t\tct_start_check(false);\r\n\t});\r\n\tjQuery(\"#ct_proceed_check_button\").click(function(){\r\n\t\tct_start_check(true);\r\n\t});\r\n\t\r\n\t// Pause the check\r\n\tjQuery('#ct_pause').on('click', function(){\r\n\t\tct_pause = true;\r\n\t\tvar ct_check = {\r\n\t\t\t'accurate': ct_accurate_check,\r\n\t\t\t'from' : ct_date_from,\r\n\t\t\t'till' : ct_date_till\r\n\t\t};\r\n\t\tdocument.cookie = 'ct_paused_users_check=' + JSON.stringify(ct_check) + '; path=/; samesite=lax';\r\n\t});\r\n\t\t\r\n\t//Approve button\r\n\tjQuery(\".cleantalk_delete_from_list_button\").click(function(){\r\n\t\tct_id = jQuery(this).attr(\"data-id\");\r\n\t\t\r\n\t\t// Approving\r\n\t\tvar data = {\r\n\t\t\t'action': 'ajax_ct_approve_user',\r\n\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t'id': ct_id,\r\n\t\t\t'no_cache': Math.random()\r\n\t\t};\r\n\t\tjQuery.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: ajaxurl,\r\n\t\t\tdata: data,\r\n\t\t\tsuccess: function(msg){\r\n\t\t\t\tjQuery(\"#comment-\"+ct_id).fadeOut('slow', function(){\r\n\t\t\t\t\tjQuery(\"#comment-\"+ct_id).remove();\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t});\r\n\t\t\r\n\t\t// Positive feedback\r\n\t\tvar data = {\r\n\t\t\t'action': 'ct_feedback_user',\r\n\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t'user_id': ct_id,\r\n\t\t\t'status': 'approve',\r\n\t\t\t'no_cache': Math.random()\r\n\t\t};\r\n\t\tjQuery.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: ajaxurl,\r\n\t\t\tdata: data,\r\n\t\t\tsuccess: function(msg){\r\n\t\t\t\tif(msg == 1){\r\n\t\t\t\t\t// Success\r\n\t\t\t\t}\r\n\t\t\t\tif(msg == 0){\r\n\t\t\t\t\t// Error occurred\r\n\t\t\t\t}\r\n\t\t\t\tif(msg == 'no_hash'){\r\n\t\t\t\t\t// No hash\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\terror: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\t\t\r\n\t\t\t},\r\n\t\t\ttimeout: 5000\r\n\t\t});\r\n\t\t\r\n\t});\r\n\t\r\n\t// Request to Download CSV file.\r\n\tjQuery(\".ct_get_csv_file\").click(function( e ){\r\n\t\tvar data = {\r\n\t\t\t'action': 'ajax_ct_get_csv_file',\r\n\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t'filename': ctUsersCheck.ct_csv_filename,\r\n\t\t\t'no_cache': Math.random()\r\n\t\t};\r\n\t\tjQuery('.' + e.target.id).addClass('disabled');\r\n\t\tjQuery('.spinner').css('visibility', 'visible');\r\n\t\tjQuery.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: ajaxurl,\r\n\t\t\tdata: data,\r\n\t\t\tsuccess: function(msg){\r\n\t\t\t\tif( parseInt(msg) === 0 ) {\r\n\t\t\t\t\talert(ctUsersCheck.ct_bad_csv);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvar url = URL.createObjectURL(new Blob([msg]));\r\n\r\n\t\t\t\t\tvar dummy = document.createElement('a');\r\n\t\t\t\t\tdummy.href = url;\r\n\t\t\t\t\tdummy.download = ctUsersCheck.ct_csv_filename + '.csv';\r\n\r\n\t\t\t\t\tdocument.body.appendChild(dummy);\r\n\t\t\t\t\tdummy.click();\r\n\t\t\t\t}\r\n\t\t\t\tjQuery('.' + e.target.id).removeClass('disabled');\r\n\t\t\t\tjQuery('.spinner').css('visibility', 'hidden');\r\n\t\t\t}\r\n\t\t});\r\n\t});\r\n\r\n\t// Delete inserted users\r\n\tjQuery(\".ct_insert_users\").click(function( e ){\r\n\t\tct_insert_users();\r\n\t});\r\n\r\n\t// Insert users\r\n\tjQuery(\".ct_insert_users__delete\").click(function( e ){\r\n\t\tct_insert_users( true );\r\n\t});\r\n\r\n\t// Delete all spam users\r\n\tjQuery(\".ct_delete_all_users\").click(function( e ){\r\n\r\n\t\tif ( ! confirm( ctUsersCheck.ct_confirm_deletion_all ) )\r\n\t\t\treturn false;\r\n\r\n\t\tct_delete_all_users( e );\r\n\r\n\t});\r\n\r\n\tfunction ct_insert_users(delete_accounts){\r\n\r\n\t\tdelete_accounts = delete_accounts || null;\r\n\r\n\t\tvar data = {\r\n\t\t\t'action': 'ajax_insert_users',\r\n\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t'no_cache': Math.random()\r\n\t\t};\r\n\r\n\t\tif(delete_accounts)\r\n\t\t\tdata['delete'] = true;\r\n\r\n\t\tjQuery.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: ajaxurl,\r\n\t\t\tdata: data,\r\n\t\t\tsuccess: function(msg){\r\n\t\t\t\tif(delete_accounts)\r\n\t\t\t\t\talert('Deleted ' + msg + ' users');\r\n\t\t\t\telse\r\n\t\t\t\t\talert('Inserted ' + msg + ' users');\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n});"],"names":["String","prototype","printf","formatted","this","arg","arguments","before_formatted","substring","indexOf","after_formatted","length","ct_working","document","cookie","ct_new_check","ct_cooling_down_flag","ct_close_animate","ct_accurate_check","ct_pause","ct_prev_accurate","ctUsersCheck","ct_prev_from","ct_prev_till","ct_cool_down_time","ct_requests_counter","ct_max_requests","ct_ajax_nonce","ct_users_total","ct_users_checked","ct_users_spam","ct_users_bad","ct_unchecked","ct_date_from","ct_date_till","apbct_cookie__get","names","prefixes","split","forEach","item","i","arr","curr","trim","name","all","prefix","apbct_get_cookie","animate_comment","to","id","jQuery","fadeTo","ct_clear_users","from","till","is","val","data","action","security","no_cache","Math","random","ajax","type","url","ajaxurl","success","msg","ct_show_users_info","ct_send_users","ct_cooling_down_toggle","setTimeout","check_amount","new_check","unchecked","amount","new_href","status_string","parseJSON","parseInt","error","confirm","error_message","location","href","end","hide","checked","spam","bad","ct_status_string","ct_status_string_warning","html","jqXHR","textStatus","errorThrown","show","timeout","message","ct_toggle_depended","obj","secondary","depended","prop","removeProp","ct_start_check","continue_check","alert","ct_delete_all_users","e","target","addClass","css","removeClass","ready","state","on","datepicker","setDefaults","regional","dates","dateFormat","maxDate","changeMonth","changeYear","showAnim","onSelect","selectedDate","option","instance","date","parseDate","settings","_defaults","not","ct_insert_users","delete_accounts","click","ct_check","accurate","JSON","stringify","ct_id","attr","fadeOut","remove","user_id","status","filename","ct_csv_filename","dummy","ct_bad_csv","URL","createObjectURL","Blob","createElement","download","body","appendChild","ct_confirm_deletion_all"],"mappings":"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"}
1
+ {"version":3,"file":"cleantalk-users-checkspam.min.js","sources":["cleantalk-users-checkspam.js"],"sourcesContent":["// Printf for JS\r\nString.prototype.printf = function(){\r\n var formatted = this;\r\n for( var arg in arguments ) {\r\n\t\tvar before_formatted = formatted.substring(0, formatted.indexOf(\"%s\", 0));\r\n\t\tvar after_formatted = formatted.substring(formatted.indexOf(\"%s\", 0)+2, formatted.length);\r\n\t\tformatted = before_formatted + arguments[arg] + after_formatted;\r\n }\r\n return formatted;\r\n};\r\n\r\n// Set deafult amount to check by request.\r\ndocument.cookie = \"ct_check_users__amount=\" + 100 + \"; path=/; samesite=lax\";\r\n\r\n// Flags\r\nvar ct_working = false,\r\n\tct_new_check = true,\r\n\tct_cooling_down_flag = false,\r\n\tct_close_animate = true,\r\n\tct_accurate_check = false,\r\n\tct_pause = false,\r\n\tct_prev_accurate = ctUsersCheck.ct_prev_accurate,\r\n\tct_prev_from = ctUsersCheck.ct_prev_from,\t\r\n\tct_prev_till = ctUsersCheck.ct_prev_till;\r\n// Settings\r\nvar ct_cool_down_time = 90000,\r\n\tct_requests_counter = 0,\r\n\tct_max_requests = 60;\r\n// Variables\r\nvar ct_ajax_nonce = ctUsersCheck.ct_ajax_nonce,\r\n\tct_users_total = 0,\r\n\tct_users_checked = 0,\r\n\tct_users_spam = 0,\r\n\tct_users_bad = 0,\r\n\tct_unchecked = 'unset',\r\n\tct_date_from = 0,\r\n\tct_date_till = 0;\r\n\r\n/* Function: Reuturns cookie with prefix */\r\nfunction apbct_cookie__get(names, prefixes){\r\n\tvar cookie = {};\r\n\tnames = names || null;\r\n\tif(typeof names == 'string') names = names.split();\r\n\tprefixes = prefixes || ['apbct_', 'ct_'];\r\n\tif(prefixes === 'none') prefixes = null;\r\n\tif(typeof prefixes == 'string') prefixes = prefixes.split();\r\n\tdocument.cookie.split(';').forEach(function(item, i, arr){\r\n\t\tvar curr = item.trim().split('=');\r\n\t\t// Detect by full cookie name\r\n\t\tif(names){\r\n\t\t\tnames.forEach(function(name, i, all){\r\n\t\t\t\tif(curr[0] === name)\r\n\t\t\t\t\tcookie[curr[0]] = (curr[1]);\r\n\t\t\t});\r\n\t\t}\r\n\t\t// Detect by name prefix\r\n\t\tif(prefixes){\r\n\t\t\tprefixes.forEach(function(prefix, i, all){\r\n\t\t\t\tif(curr[0].indexOf(prefix) === 0)\r\n\t\t\t\t\tcookie[curr[0]] = (curr[1]);\r\n\t\t\t});\r\n\t\t}\r\n\t});\r\n\treturn cookie;\r\n}\r\n\r\nfunction apbct_get_cookie( name ){\r\n\tvar cookie = apbct_cookie__get( name, name );\r\n\tif(typeof cookie === 'object' && typeof cookie[name] != 'undefined'){\r\n\t\treturn cookie[name];\r\n\t}else\r\n\t\treturn null;\r\n}\r\n\r\nfunction animate_comment(to,id){\r\n\tif(ct_close_animate){\r\n\t\tif(to === 0.3){\r\n\t\t\tjQuery('#comment-'+id).fadeTo(200,to,function(){\r\n\t\t\t\tanimate_comment(1,id)\r\n\t\t\t});\r\n\t\t}else{\r\n\t\t\tjQuery('#comment-'+id).fadeTo(200,to,function(){\r\n\t\t\t\tanimate_comment(0.3,id)\r\n\t\t\t});\r\n\t\t}\r\n\t}else{\r\n\t\tct_close_animate=true;\r\n\t}\r\n}\r\n\r\nfunction ct_clear_users(){\r\n\r\n\tvar from = 0, till = 0;\r\n\tif(jQuery('#ct_allow_date_range').is(':checked')) {\r\n\t\tfrom = jQuery('#ct_date_range_from').val();\r\n\t\ttill = jQuery('#ct_date_range_till').val();\r\n\t}\r\n\tvar data = {\r\n\t\t'action' : 'ajax_clear_users',\r\n\t\t'security' : ct_ajax_nonce,\r\n\t\t'from' : from,\r\n\t\t'till' : till,\r\n\t\t'no_cache': Math.random()\r\n\t};\r\n\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function(msg){\r\n\t\t\tct_show_users_info();\r\n\t\t\tct_send_users();\r\n\t\t}\r\n\t});\r\n\r\n}\r\n\r\n//Continues the check after cooldown time\r\n//Called by ct_send_users();\r\nfunction ct_cooling_down_toggle(){\r\n\tct_cooling_down_flag = false;\r\n\tct_send_users();\r\n\tct_show_users_info();\r\n}\r\n\r\nfunction ct_send_users(){\r\n\t\r\n\tif(ct_cooling_down_flag === true)\r\n\t\treturn;\r\n\t\r\n\tif(ct_requests_counter >= ct_max_requests){\r\n\t\tsetTimeout(ct_cooling_down_toggle, ct_cool_down_time);\r\n\t\tct_requests_counter = 0;\r\n\t\tct_cooling_down_flag = true;\r\n\t\treturn;\r\n\t}else{\r\n\t\tct_requests_counter++;\r\n\t}\r\n\r\n\tvar check_amount = apbct_get_cookie('ct_check_users__amount');\r\n\r\n\tvar data = {\r\n\t\taction: 'ajax_check_users',\r\n\t\tsecurity: ct_ajax_nonce,\r\n\t\tnew_check: ct_new_check,\r\n\t\tunchecked: ct_unchecked,\r\n\t\tamount: check_amount,\r\n\t\t'no_cache': Math.random()\r\n\t};\r\n\t\r\n\tif(ct_accurate_check)\r\n\t\tdata['accurate_check'] = true;\r\n\t\r\n\tif(ct_date_from && ct_date_till){\r\n\t\tdata['from'] = ct_date_from;\r\n\t\tdata['till'] = ct_date_till;\r\n\t}\r\n\t\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function(msg){\r\n\t\t\t\r\n\t\t\tmsg = jQuery.parseJSON(msg);\r\n\t\t\t\r\n\t\t\tif(parseInt(msg.error)){\r\n\t\t\t\tct_working=false;\r\n\t\t\t\tif(!confirm(msg.error_message+\". Do you want to proceed?\")){\r\n\t\t\t\t\tvar new_href = 'users.php?page=ct_check_users';\r\n\t\t\t\t\tif(ct_date_from != 0 && ct_date_till != 0)\r\n\t\t\t\t\t\tnew_href+='&from='+ct_date_from+'&till='+ct_date_till;\r\n\t\t\t\t\tlocation.href = new_href;\r\n\t\t\t\t}else\r\n\t\t\t\t\tct_send_users();\r\n\t\t\t}else{\r\n\t\t\t\tct_new_check = false;\r\n\t\t\t\tif(parseInt(msg.end) == 1 || ct_pause == true){\r\n\t\t\t\t\tif(parseInt(msg.end) == 1)\r\n\t\t\t\t\t\tdocument.cookie = 'ct_paused_users_check=0; path=/; samesite=lax';\r\n\t\t\t\t\tct_working=false;\r\n\t\t\t\t\tjQuery('#ct_working_message').hide();\r\n\t\t\t\t\tvar new_href = 'users.php?page=ct_check_users&ct_worked=1';\r\n\t\t\t\t\tif(ct_date_from != 0 && ct_date_till != 0)\r\n\t\t\t\t\t\tnew_href+='&from='+ct_date_from+'&till='+ct_date_till;\r\n\t\t\t\t\tlocation.href = new_href;\r\n\t\t\t\t}else if(parseInt(msg.end) == 0){\r\n\t\t\t\t\tct_users_checked = parseInt( ct_users_checked ) + parseInt( msg.checked );\r\n\t\t\t\t\tct_users_spam = parseInt( ct_users_spam ) + parseInt (msg.spam );\r\n\t\t\t\t\tct_users_bad = parseInt( ct_users_bad ) + parseInt( msg.bad );\r\n\t\t\t\t\tct_unchecked = ct_users_total - ct_users_checked - ct_users_bad;\r\n\t\t\t\t\tvar status_string = String(ctUsersCheck.ct_status_string);\r\n\t\t\t\t\tvar status_string = status_string.printf(ct_users_checked, ct_users_spam, ct_users_bad);\r\n\t\t\t\t\tif(parseInt(ct_users_spam) > 0)\r\n\t\t\t\t\t\tstatus_string += ctUsersCheck.ct_status_string_warning;\r\n\t\t\t\t\tjQuery('#ct_checking_status').html(status_string);\r\n\t\t\t\t\tjQuery('#ct_error_message').hide();\r\n\t\t\t\t\tct_send_users();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n error: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\tif(check_amount > 20){\r\n\t\t\t\tcheck_amount -= 20;\r\n\t\t\t\tdocument.cookie = \"ct_check_users__amount=\" + check_amount + \"; path=/; samesite=lax\";\r\n\t\t\t}\r\n\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\tjQuery('#cleantalk_js_func').html('Check users');\r\n\t\t\tsetTimeout(ct_send_users(), 3000);\r\n },\r\n timeout: 25000\r\n\t});\r\n}\r\nfunction ct_show_users_info(){\r\n\t\r\n\tif( ct_working ){\r\n\t\t\r\n\t\tif(ct_cooling_down_flag === true){\r\n\t\t\tjQuery('#ct_cooling_notice').html('Waiting for API to cool down. (About a minute)').show();\r\n\t\t\treturn;\t\t\t\r\n\t\t}else{\r\n\t\t\tjQuery('#ct_cooling_notice').hide();\r\n\t\t}\r\n\t\t\r\n\t\tif( ! ct_users_total ){\r\n\t\t\t\r\n\t\t\tvar data = {\r\n\t\t\t\t'action': 'ajax_info_users',\r\n\t\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t\t'no_cache': Math.random()\r\n\t\t\t};\r\n\t\t\t\r\n\t\t\tif( ct_date_from && ct_date_till ){\r\n\t\t\t\tdata['from'] = ct_date_from;\r\n\t\t\t\tdata['till'] = ct_date_till;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tjQuery.ajax({\r\n\t\t\t\ttype: \"POST\",\r\n\t\t\t\turl: ajaxurl,\r\n\t\t\t\tdata: data,\r\n\t\t\t\tsuccess: function(msg){\r\n\t\t\t\t\tmsg = jQuery.parseJSON(msg);\r\n\t\t\t\t\tjQuery('#ct_checking_status').html(msg.message);\r\n\t\t\t\t\tct_users_spam = msg.spam;\r\n\t\t\t\t\tct_users_checked = msg.checked;\r\n\t\t\t\t\tct_users_bad = msg.bad;\r\n\t\t\t\t},\r\n\t\t\t\terror: function (jqXHR, textStatus, errorThrown){\r\n\t\t\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\t\t\tjQuery('#cleantalk_js_func').html('Show users');\r\n\t\t\t\t\tsetTimeout(ct_show_users_info(), 3000);\r\n\t\t\t\t},\r\n\t\t\t\ttimeout: 15000\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n}\r\n// Function to toggle dependences\r\nfunction ct_toggle_depended(obj, secondary){\r\n\r\n secondary = secondary || null;\r\n\r\n\tvar depended = jQuery(obj.data('depended')),\r\n\t\tstate = obj.data('state');\r\n\t\t\r\n\tif(!state && !secondary){\r\n\t\tobj.data('state', true);\r\n\t\tdepended.removeProp('disabled');\r\n\t}else{\r\n\t\tobj.data('state', false);\r\n\t\tdepended.prop('disabled', true);\r\n\t\tdepended.removeProp('checked');\r\n\t\tif(depended.data('depended'))\r\n\t\t\tct_toggle_depended(depended, true);\r\n\t}\r\n}\r\n\r\n// Main function of checking\r\nfunction ct_start_check( continue_check ){\r\n\r\n\tcontinue_check = continue_check || null;\r\n\r\n\tif(jQuery('#ct_allow_date_range').is(':checked')){\r\n\r\n\t\tct_date_from = jQuery('#ct_date_range_from').val();\r\n\t\tct_date_till = jQuery('#ct_date_range_till').val();\r\n\r\n\t\tif(!(ct_date_from !== '' && ct_date_till !== '')){\r\n\t\t\talert('Please, specify a date range.');\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n\r\n\tif(jQuery('#ct_accurate_check').is(':checked')){\r\n\t\tct_accurate_check = true;\r\n\t}\r\n\r\n\tjQuery('.ct_to_hide').hide();\r\n\tjQuery('#ct_working_message').show();\r\n\tjQuery('#ct_preloader').show();\r\n\tjQuery('#ct_pause').show();\r\n\r\n\tct_working = true;\r\n\r\n\tif( continue_check ){\r\n\t\tct_show_users_info();\r\n\t\tct_send_users();\r\n\t} else {\r\n\t\tct_clear_users();\r\n\t}\r\n\r\n}\r\n\r\nfunction ct_delete_all_users( e ){\r\n\r\n\tvar data = {\r\n\t\t'action': 'ajax_delete_all_users',\r\n\t\t'security': ct_ajax_nonce,\r\n\t\t'no_cache': Math.random()\r\n\t};\r\n\r\n\tjQuery('.' + e.target.id).addClass('disabled');\r\n\tjQuery('.spinner').css('visibility', 'visible');\r\n\tjQuery.ajax({\r\n\t\ttype: \"POST\",\r\n\t\turl: ajaxurl,\r\n\t\tdata: data,\r\n\t\tsuccess: function( msg ){\r\n\t\t\tif( msg > 0 ){\r\n\t\t\t\tjQuery('#cleantalk_users_left').html(msg);\r\n\t\t\t\tct_delete_all_users( e, data );\r\n\t\t\t}else{\r\n\t\t\t\tjQuery('.' + e.target.id).removeClass('disabled');\r\n\t\t\t\tjQuery('.spinner').css('visibility', 'hidden');\r\n\t\t\t\tlocation.href='users.php?page=ct_check_users_total';\r\n\t\t\t}\r\n\t\t},\r\n\t\terror: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\tjQuery('#ct_error_message').show();\r\n\t\t\tjQuery('#cleantalk_ajax_error').html(textStatus);\r\n\t\t\tjQuery('#cleantalk_js_func').html('All users deleteion');\r\n\t\t\tsetTimeout(ct_delete_all_users( e ), 3000);\r\n\t\t},\r\n\t\ttimeout: 25000\r\n\t});\r\n}\r\n\r\njQuery(document).ready(function(){\r\n\r\n\t// Setting dependences\r\n\t\r\n\t// Prev check parameters\r\n\tif(ct_prev_accurate){\r\n\t\tjQuery(\"#ct_accurate_check\").prop('checked', true);\r\n\t}\r\n\tif(ct_prev_from){\r\n\t\tjQuery(\"#ct_allow_date_range\").prop('checked', true).data('state', true);\r\n\t\tjQuery(\"#ct_date_range_from\").removeProp('disabled').val(ct_prev_from);\r\n\t\tjQuery(\"#ct_date_range_till\").removeProp('disabled').val(ct_prev_till);\r\n\t}\r\n\t\r\n\t// Toggle dependences\r\n\tjQuery(\"#ct_allow_date_range\").on('change', function(){\r\n\t\tdocument.cookie = 'ct_users_dates_from='+ jQuery('#ct_date_range_from').val() +'; path=/; samesite=lax';\r\n\t\tdocument.cookie = 'ct_users_dates_till='+ jQuery('#ct_date_range_till').val() +'; path=/; samesite=lax';\r\n\t\tif( this.checked ) {\r\n\t\t\tdocument.cookie = 'ct_users_dates_allowed=1; path=/; samesite=lax';\r\n\t\t\tjQuery('.ct_date').prop('checked', true).removeProp('disabled');\r\n\t\t} else {\r\n\t\t\tdocument.cookie = 'ct_users_dates_allowed=0; path=/; samesite=lax';\r\n\t\t\tjQuery('.ct_date').prop('disabled', true).removeProp('checked');\r\n\t\t}\r\n\t});\r\n\r\n\tjQuery.datepicker.setDefaults(jQuery.datepicker.regional['en']);\r\n\tvar dates = jQuery('#ct_date_range_from, #ct_date_range_till').datepicker(\r\n\t\t{\r\n\t\t\tdateFormat: 'M d yy',\r\n\t\t\tmaxDate:\"+0D\",\r\n\t\t\tchangeMonth:true,\r\n\t\t\tchangeYear:true,\r\n\t\t\tshowAnim: 'slideDown',\r\n\t\t\tonSelect: function(selectedDate){\r\n\t\t\tvar option = this.id == \"ct_date_range_from\" ? \"minDate\" : \"maxDate\",\r\n\t\t\t\tinstance = jQuery( this ).data( \"datepicker\" ),\r\n\t\t\t\tdate = jQuery.datepicker.parseDate(\r\n\t\t\t\t\tinstance.settings.dateFormat || jQuery.datepicker._defaults.dateFormat,\r\n\t\t\t\t\tselectedDate, instance.settings);\r\n\t\t\t\tdates.not(this).datepicker(\"option\", option, date);\r\n\t\t\t\tdocument.cookie = 'ct_users_dates_from='+ jQuery('#ct_date_range_from').val() +'; path=/; samesite=lax';\r\n\t\t\t\tdocument.cookie = 'ct_users_dates_till='+ jQuery('#ct_date_range_till').val() +'; path=/; samesite=lax';\r\n\t\t\t}\r\n\t\t}\r\n\t);\r\n\t\r\n\t// Check users\r\n\tjQuery(\"#ct_check_spam_button\").click(function(){\r\n\t\tdocument.cookie = 'ct_paused_users_check=0; path=/; samesite=lax';\r\n\t\tct_start_check(false);\r\n\t});\r\n\tjQuery(\"#ct_proceed_check_button\").click(function(){\r\n\t\tct_start_check(true);\r\n\t});\r\n\t\r\n\t// Pause the check\r\n\tjQuery('#ct_pause').on('click', function(){\r\n\t\tct_pause = true;\r\n\t\tvar ct_check = {\r\n\t\t\t'accurate': ct_accurate_check,\r\n\t\t\t'from' : ct_date_from,\r\n\t\t\t'till' : ct_date_till\r\n\t\t};\r\n\t\tdocument.cookie = 'ct_paused_users_check=' + JSON.stringify(ct_check) + '; path=/; samesite=lax';\r\n\t});\r\n\t\t\r\n\t//Approve button\r\n\tjQuery(\".cleantalk_delete_from_list_button\").click(function(){\r\n\t\tct_id = jQuery(this).attr(\"data-id\");\r\n\t\t\r\n\t\t// Approving\r\n\t\tvar data = {\r\n\t\t\t'action': 'ajax_ct_approve_user',\r\n\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t'id': ct_id,\r\n\t\t\t'no_cache': Math.random()\r\n\t\t};\r\n\t\tjQuery.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: ajaxurl,\r\n\t\t\tdata: data,\r\n\t\t\tsuccess: function(msg){\r\n\t\t\t\tjQuery(\"#comment-\"+ct_id).fadeOut('slow', function(){\r\n\t\t\t\t\tjQuery(\"#comment-\"+ct_id).remove();\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t});\r\n\t\t\r\n\t\t// Positive feedback\r\n\t\tvar data = {\r\n\t\t\t'action': 'ct_feedback_user',\r\n\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t'user_id': ct_id,\r\n\t\t\t'status': 'approve',\r\n\t\t\t'no_cache': Math.random()\r\n\t\t};\r\n\t\tjQuery.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: ajaxurl,\r\n\t\t\tdata: data,\r\n\t\t\tsuccess: function(msg){\r\n\t\t\t\tif(msg == 1){\r\n\t\t\t\t\t// Success\r\n\t\t\t\t}\r\n\t\t\t\tif(msg == 0){\r\n\t\t\t\t\t// Error occurred\r\n\t\t\t\t}\r\n\t\t\t\tif(msg == 'no_hash'){\r\n\t\t\t\t\t// No hash\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\terror: function(jqXHR, textStatus, errorThrown) {\r\n\t\t\t\t\r\n\t\t\t},\r\n\t\t\ttimeout: 5000\r\n\t\t});\r\n\t\t\r\n\t});\r\n\t\r\n\t// Request to Download CSV file.\r\n\tjQuery(\".ct_get_csv_file\").click(function( e ){\r\n\t\tvar data = {\r\n\t\t\t'action': 'ajax_ct_get_csv_file',\r\n\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t'filename': ctUsersCheck.ct_csv_filename,\r\n\t\t\t'no_cache': Math.random()\r\n\t\t};\r\n\t\tjQuery('.' + e.target.id).addClass('disabled');\r\n\t\tjQuery('.spinner').css('visibility', 'visible');\r\n\t\tjQuery.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: ajaxurl,\r\n\t\t\tdata: data,\r\n\t\t\tsuccess: function(msg){\r\n\t\t\t\tif( parseInt(msg) === 0 ) {\r\n\t\t\t\t\talert(ctUsersCheck.ct_bad_csv);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvar url = URL.createObjectURL(new Blob([msg]));\r\n\r\n\t\t\t\t\tvar dummy = document.createElement('a');\r\n\t\t\t\t\tdummy.href = url;\r\n\t\t\t\t\tdummy.download = ctUsersCheck.ct_csv_filename + '.csv';\r\n\r\n\t\t\t\t\tdocument.body.appendChild(dummy);\r\n\t\t\t\t\tdummy.click();\r\n\t\t\t\t}\r\n\t\t\t\tjQuery('.' + e.target.id).removeClass('disabled');\r\n\t\t\t\tjQuery('.spinner').css('visibility', 'hidden');\r\n\t\t\t}\r\n\t\t});\r\n\t});\r\n\r\n\t// Delete inserted users\r\n\tjQuery(\".ct_insert_users\").click(function( e ){\r\n\t\tct_insert_users();\r\n\t});\r\n\r\n\t// Insert users\r\n\tjQuery(\".ct_insert_users__delete\").click(function( e ){\r\n\t\tct_insert_users( true );\r\n\t});\r\n\r\n\t// Delete all spam users\r\n\tjQuery(\".ct_delete_all_users\").click(function( e ){\r\n\r\n\t\tif ( ! confirm( ctUsersCheck.ct_confirm_deletion_all ) )\r\n\t\t\treturn false;\r\n\r\n\t\tct_delete_all_users( e );\r\n\r\n\t});\r\n\r\n\tfunction ct_insert_users(delete_accounts){\r\n\r\n\t\tdelete_accounts = delete_accounts || null;\r\n\r\n\t\tvar data = {\r\n\t\t\t'action': 'ajax_insert_users',\r\n\t\t\t'security': ct_ajax_nonce,\r\n\t\t\t'no_cache': Math.random()\r\n\t\t};\r\n\r\n\t\tif(delete_accounts)\r\n\t\t\tdata['delete'] = true;\r\n\r\n\t\tjQuery.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: ajaxurl,\r\n\t\t\tdata: data,\r\n\t\t\tsuccess: function(msg){\r\n\t\t\t\tif(delete_accounts)\r\n\t\t\t\t\talert('Deleted ' + msg + ' users');\r\n\t\t\t\telse\r\n\t\t\t\t\talert('Inserted ' + msg + ' users');\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n});"],"names":["String","prototype","printf","formatted","this","arg","arguments","before_formatted","substring","indexOf","after_formatted","length","ct_working","document","cookie","ct_new_check","ct_cooling_down_flag","ct_close_animate","ct_accurate_check","ct_pause","ct_prev_accurate","ctUsersCheck","ct_prev_from","ct_prev_till","ct_cool_down_time","ct_requests_counter","ct_max_requests","ct_ajax_nonce","ct_users_total","ct_users_checked","ct_users_spam","ct_users_bad","ct_unchecked","ct_date_from","ct_date_till","apbct_cookie__get","names","prefixes","split","forEach","item","i","arr","curr","trim","name","all","prefix","apbct_get_cookie","animate_comment","to","id","jQuery","fadeTo","ct_clear_users","from","till","is","val","data","action","security","no_cache","Math","random","ajax","type","url","ajaxurl","success","msg","ct_show_users_info","ct_send_users","ct_cooling_down_toggle","setTimeout","check_amount","new_check","unchecked","amount","new_href","status_string","parseJSON","parseInt","error","confirm","error_message","location","href","end","hide","checked","spam","bad","ct_status_string","ct_status_string_warning","html","jqXHR","textStatus","errorThrown","show","timeout","message","ct_toggle_depended","obj","secondary","depended","prop","removeProp","ct_start_check","continue_check","alert","ct_delete_all_users","e","target","addClass","css","removeClass","ready","on","datepicker","setDefaults","regional","dates","dateFormat","maxDate","changeMonth","changeYear","showAnim","onSelect","selectedDate","option","instance","date","parseDate","settings","_defaults","not","ct_insert_users","delete_accounts","click","ct_check","accurate","JSON","stringify","ct_id","attr","fadeOut","remove","user_id","status","filename","ct_csv_filename","dummy","ct_bad_csv","URL","createObjectURL","Blob","createElement","download","body","appendChild","ct_confirm_deletion_all"],"mappings":"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"}
lib/Cleantalk/ApbctWP/CleantalkListTable.php ADDED
@@ -0,0 +1,1437 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP;
4
+
5
+ /**
6
+ * This is copy of the WP_List_Table class for the future compability
7
+ */
8
+
9
+ /**
10
+ * Administration API: WP_List_Table class
11
+ *
12
+ * @package WordPress
13
+ * @subpackage List_Table
14
+ * @since 3.1.0
15
+ */
16
+
17
+ /**
18
+ * Base class for displaying a list of items in an ajaxified HTML table.
19
+ *
20
+ * @since 3.1.0
21
+ * @access private
22
+ */
23
+ class CleantalkListTable {
24
+
25
+ /**
26
+ * The current list of items.
27
+ *
28
+ * @since 3.1.0
29
+ * @var array
30
+ */
31
+ public $items;
32
+
33
+ /**
34
+ * Various information about the current table.
35
+ *
36
+ * @since 3.1.0
37
+ * @var array
38
+ */
39
+ protected $_args;
40
+
41
+ /**
42
+ * Various information needed for displaying the pagination.
43
+ *
44
+ * @since 3.1.0
45
+ * @var array
46
+ */
47
+ protected $_pagination_args = array();
48
+
49
+ /**
50
+ * The current screen.
51
+ *
52
+ * @since 3.1.0
53
+ * @var object
54
+ */
55
+ protected $screen;
56
+
57
+ /**
58
+ * Cached bulk actions.
59
+ *
60
+ * @since 3.1.0
61
+ * @var array
62
+ */
63
+ private $_actions;
64
+
65
+ /**
66
+ * Cached pagination output.
67
+ *
68
+ * @since 3.1.0
69
+ * @var string
70
+ */
71
+ private $_pagination;
72
+
73
+ /**
74
+ * The view switcher modes.
75
+ *
76
+ * @since 4.1.0
77
+ * @var array
78
+ */
79
+ protected $modes = array();
80
+
81
+ /**
82
+ * Stores the value returned by ->get_column_info().
83
+ *
84
+ * @since 4.1.0
85
+ * @var array
86
+ */
87
+ protected $_column_headers;
88
+
89
+ /**
90
+ * {@internal Missing Summary}
91
+ *
92
+ * @var array
93
+ */
94
+ protected $compat_fields = array( '_args', '_pagination_args', 'screen', '_actions', '_pagination' );
95
+
96
+ /**
97
+ * {@internal Missing Summary}
98
+ *
99
+ * @var array
100
+ */
101
+ protected $compat_methods = array(
102
+ 'set_pagination_args',
103
+ 'get_views',
104
+ 'get_bulk_actions',
105
+ 'bulk_actions',
106
+ 'row_actions',
107
+ 'months_dropdown',
108
+ 'view_switcher',
109
+ 'comments_bubble',
110
+ 'get_items_per_page',
111
+ 'pagination',
112
+ 'get_sortable_columns',
113
+ 'get_column_info',
114
+ 'get_table_classes',
115
+ 'display_tablenav',
116
+ 'extra_tablenav',
117
+ 'single_row_columns',
118
+ );
119
+
120
+ /**
121
+ * Constructor.
122
+ *
123
+ * The child class should call this constructor from its own constructor to override
124
+ * the default $args.
125
+ *
126
+ * @since 3.1.0
127
+ *
128
+ * @param array|string $args {
129
+ * Array or string of arguments.
130
+ *
131
+ * @type string $plural Plural value used for labels and the objects being listed.
132
+ * This affects things such as CSS class-names and nonces used
133
+ * in the list table, e.g. 'posts'. Default empty.
134
+ * @type string $singular Singular label for an object being listed, e.g. 'post'.
135
+ * Default empty
136
+ * @type bool $ajax Whether the list table supports Ajax. This includes loading
137
+ * and sorting data, for example. If true, the class will call
138
+ * the _js_vars() method in the footer to provide variables
139
+ * to any scripts handling Ajax events. Default false.
140
+ * @type string $screen String containing the hook name used to determine the current
141
+ * screen. If left null, the current screen will be automatically set.
142
+ * Default null.
143
+ * }
144
+ */
145
+ public function __construct( $args = array() ) {
146
+ $args = wp_parse_args(
147
+ $args,
148
+ array(
149
+ 'plural' => '',
150
+ 'singular' => '',
151
+ 'ajax' => false,
152
+ 'screen' => null,
153
+ )
154
+ );
155
+
156
+ $this->screen = convert_to_screen( $args['screen'] );
157
+
158
+ add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 );
159
+
160
+ if ( ! $args['plural'] ) {
161
+ $args['plural'] = $this->screen->base;
162
+ }
163
+
164
+ $args['plural'] = sanitize_key( $args['plural'] );
165
+ $args['singular'] = sanitize_key( $args['singular'] );
166
+
167
+ $this->_args = $args;
168
+
169
+ if ( $args['ajax'] ) {
170
+ // wp_enqueue_script( 'list-table' );
171
+ add_action( 'admin_footer', array( $this, '_js_vars' ) );
172
+ }
173
+
174
+ if ( empty( $this->modes ) ) {
175
+ $this->modes = array(
176
+ 'list' => __( 'List View' ),
177
+ 'excerpt' => __( 'Excerpt View' ),
178
+ );
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Make private properties readable for backward compatibility.
184
+ *
185
+ * @since 4.0.0
186
+ *
187
+ * @param string $name Property to get.
188
+ * @return mixed Property.
189
+ */
190
+ public function __get( $name ) {
191
+ if ( in_array( $name, $this->compat_fields ) ) {
192
+ return $this->$name;
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Make private properties settable for backward compatibility.
198
+ *
199
+ * @since 4.0.0
200
+ *
201
+ * @param string $name Property to check if set.
202
+ * @param mixed $value Property value.
203
+ * @return mixed Newly-set property.
204
+ */
205
+ public function __set( $name, $value ) {
206
+ if ( in_array( $name, $this->compat_fields ) ) {
207
+ return $this->$name = $value;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Make private properties checkable for backward compatibility.
213
+ *
214
+ * @since 4.0.0
215
+ *
216
+ * @param string $name Property to check if set.
217
+ * @return bool Whether the property is set.
218
+ */
219
+ public function __isset( $name ) {
220
+ if ( in_array( $name, $this->compat_fields ) ) {
221
+ return isset( $this->$name );
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Make private properties un-settable for backward compatibility.
227
+ *
228
+ * @since 4.0.0
229
+ *
230
+ * @param string $name Property to unset.
231
+ */
232
+ public function __unset( $name ) {
233
+ if ( in_array( $name, $this->compat_fields ) ) {
234
+ unset( $this->$name );
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Make private/protected methods readable for backward compatibility.
240
+ *
241
+ * @since 4.0.0
242
+ *
243
+ * @param string $name Method to call.
244
+ * @param array $arguments Arguments to pass when calling.
245
+ * @return mixed|bool Return value of the callback, false otherwise.
246
+ */
247
+ public function __call( $name, $arguments ) {
248
+ if ( in_array( $name, $this->compat_methods ) ) {
249
+ return $this->$name( ...$arguments );
250
+ }
251
+ return false;
252
+ }
253
+
254
+ /**
255
+ * Checks the current user's permissions
256
+ *
257
+ * @since 3.1.0
258
+ * @abstract
259
+ */
260
+ public function ajax_user_can() {
261
+ die( 'function WP_List_Table::ajax_user_can() must be over-ridden in a sub-class.' );
262
+ }
263
+
264
+ /**
265
+ * Prepares the list of items for displaying.
266
+ *
267
+ * @uses WP_List_Table::set_pagination_args()
268
+ *
269
+ * @since 3.1.0
270
+ * @abstract
271
+ */
272
+ public function prepare_items() {
273
+ die( 'function WP_List_Table::prepare_items() must be over-ridden in a sub-class.' );
274
+ }
275
+
276
+ /**
277
+ * An internal method that sets all the necessary pagination arguments
278
+ *
279
+ * @since 3.1.0
280
+ *
281
+ * @param array|string $args Array or string of arguments with information about the pagination.
282
+ */
283
+ protected function set_pagination_args( $args ) {
284
+ $args = wp_parse_args(
285
+ $args,
286
+ array(
287
+ 'total_items' => 0,
288
+ 'total_pages' => 0,
289
+ 'per_page' => 0,
290
+ )
291
+ );
292
+
293
+ if ( ! $args['total_pages'] && $args['per_page'] > 0 ) {
294
+ $args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
295
+ }
296
+
297
+ // Redirect if page number is invalid and headers are not already sent.
298
+ if ( ! headers_sent() && ! wp_doing_ajax() && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) {
299
+ wp_redirect( add_query_arg( 'paged', $args['total_pages'] ) );
300
+ exit;
301
+ }
302
+
303
+ $this->_pagination_args = $args;
304
+ }
305
+
306
+ /**
307
+ * Access the pagination args.
308
+ *
309
+ * @since 3.1.0
310
+ *
311
+ * @param string $key Pagination argument to retrieve. Common values include 'total_items',
312
+ * 'total_pages', 'per_page', or 'infinite_scroll'.
313
+ * @return int Number of items that correspond to the given pagination argument.
314
+ */
315
+ public function get_pagination_arg( $key ) {
316
+ if ( 'page' === $key ) {
317
+ return $this->get_pagenum();
318
+ }
319
+
320
+ if ( isset( $this->_pagination_args[ $key ] ) ) {
321
+ return $this->_pagination_args[ $key ];
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Whether the table has items to display or not
327
+ *
328
+ * @since 3.1.0
329
+ *
330
+ * @return bool
331
+ */
332
+ public function has_items() {
333
+ return ! empty( $this->items );
334
+ }
335
+
336
+ /**
337
+ * Message to be displayed when there are no items
338
+ *
339
+ * @since 3.1.0
340
+ */
341
+ public function no_items() {
342
+ _e( 'No items found.' );
343
+ }
344
+
345
+ /**
346
+ * Displays the search box.
347
+ *
348
+ * @since 3.1.0
349
+ *
350
+ * @param string $text The 'submit' button label.
351
+ * @param string $input_id ID attribute value for the search input field.
352
+ */
353
+ public function search_box( $text, $input_id ) {
354
+ if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) {
355
+ return;
356
+ }
357
+
358
+ $input_id = $input_id . '-search-input';
359
+
360
+ if ( ! empty( $_REQUEST['orderby'] ) ) {
361
+ echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
362
+ }
363
+ if ( ! empty( $_REQUEST['order'] ) ) {
364
+ echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
365
+ }
366
+ if ( ! empty( $_REQUEST['post_mime_type'] ) ) {
367
+ echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
368
+ }
369
+ if ( ! empty( $_REQUEST['detached'] ) ) {
370
+ echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
371
+ }
372
+ ?>
373
+ <p class="search-box">
374
+ <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo $text; ?>:</label>
375
+ <input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s" value="<?php _admin_search_query(); ?>" />
376
+ <?php submit_button( $text, '', '', false, array( 'id' => 'search-submit' ) ); ?>
377
+ </p>
378
+ <?php
379
+ }
380
+
381
+ /**
382
+ * Get an associative array ( id => link ) with the list
383
+ * of views available on this table.
384
+ *
385
+ * @since 3.1.0
386
+ *
387
+ * @return array
388
+ */
389
+ protected function get_views() {
390
+ return array();
391
+ }
392
+
393
+ /**
394
+ * Display the list of views available on this table.
395
+ *
396
+ * @since 3.1.0
397
+ */
398
+ public function views() {
399
+ $views = $this->get_views();
400
+ /**
401
+ * Filters the list of available list table views.
402
+ *
403
+ * The dynamic portion of the hook name, `$this->screen->id`, refers
404
+ * to the ID of the current screen, usually a string.
405
+ *
406
+ * @since 3.5.0
407
+ *
408
+ * @param string[] $views An array of available list table views.
409
+ */
410
+ $views = apply_filters( "views_{$this->screen->id}", $views );
411
+
412
+ if ( empty( $views ) ) {
413
+ return;
414
+ }
415
+
416
+ $this->screen->render_screen_reader_content( 'heading_views' );
417
+
418
+ echo "<ul class='subsubsub'>\n";
419
+ foreach ( $views as $class => $view ) {
420
+ $views[ $class ] = "\t<li class='$class'>$view";
421
+ }
422
+ echo implode( " |</li>\n", $views ) . "</li>\n";
423
+ echo '</ul>';
424
+ }
425
+
426
+ /**
427
+ * Get an associative array ( option_name => option_title ) with the list
428
+ * of bulk actions available on this table.
429
+ *
430
+ * @since 3.1.0
431
+ *
432
+ * @return array
433
+ */
434
+ protected function get_bulk_actions() {
435
+ return array();
436
+ }
437
+
438
+ /**
439
+ * Display the bulk actions dropdown.
440
+ *
441
+ * @since 3.1.0
442
+ *
443
+ * @param string $which The location of the bulk actions: 'top' or 'bottom'.
444
+ * This is designated as optional for backward compatibility.
445
+ */
446
+ protected function bulk_actions( $which = '' ) {
447
+ if ( is_null( $this->_actions ) ) {
448
+ $this->_actions = $this->get_bulk_actions();
449
+ /**
450
+ * Filters the list table Bulk Actions drop-down.
451
+ *
452
+ * The dynamic portion of the hook name, `$this->screen->id`, refers
453
+ * to the ID of the current screen, usually a string.
454
+ *
455
+ * This filter can currently only be used to remove bulk actions.
456
+ *
457
+ * @since 3.5.0
458
+ *
459
+ * @param string[] $actions An array of the available bulk actions.
460
+ */
461
+ $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
462
+ $two = '';
463
+ } else {
464
+ $two = '2';
465
+ }
466
+
467
+ if ( empty( $this->_actions ) ) {
468
+ return;
469
+ }
470
+
471
+ echo '<label for="bulk-action-selector-' . esc_attr( $which ) . '" class="screen-reader-text">' . __( 'Select bulk action' ) . '</label>';
472
+ echo '<select name="action' . $two . '" id="bulk-action-selector-' . esc_attr( $which ) . "\">\n";
473
+ echo '<option value="-1">' . __( 'Bulk Actions' ) . "</option>\n";
474
+
475
+ foreach ( $this->_actions as $name => $title ) {
476
+ $class = 'edit' === $name ? ' class="hide-if-no-js"' : '';
477
+
478
+ echo "\t" . '<option value="' . $name . '"' . $class . '>' . $title . "</option>\n";
479
+ }
480
+
481
+ echo "</select>\n";
482
+
483
+ submit_button( __( 'Apply' ), 'action', '', false, array( 'id' => "doaction$two" ) );
484
+ echo "\n";
485
+ }
486
+
487
+ /**
488
+ * Get the current action selected from the bulk actions dropdown.
489
+ *
490
+ * @since 3.1.0
491
+ *
492
+ * @return string|false The action name or False if no action was selected
493
+ */
494
+ public function current_action() {
495
+ if ( isset( $_REQUEST['filter_action'] ) && ! empty( $_REQUEST['filter_action'] ) ) {
496
+ return false;
497
+ }
498
+
499
+ if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ) {
500
+ return $_REQUEST['action'];
501
+ }
502
+
503
+ if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] ) {
504
+ return $_REQUEST['action2'];
505
+ }
506
+
507
+ return false;
508
+ }
509
+
510
+ /**
511
+ * Generate row actions div
512
+ *
513
+ * @since 3.1.0
514
+ *
515
+ * @param string[] $actions An array of action links.
516
+ * @param bool $always_visible Whether the actions should be always visible.
517
+ * @return string
518
+ */
519
+ protected function row_actions( $actions, $always_visible = false ) {
520
+ $action_count = count( $actions );
521
+ $i = 0;
522
+
523
+ if ( ! $action_count ) {
524
+ return '';
525
+ }
526
+
527
+ $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
528
+ foreach ( $actions as $action => $link ) {
529
+ ++$i;
530
+ ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
531
+ $out .= "<span class='$action'>$link$sep</span>";
532
+ }
533
+ $out .= '</div>';
534
+
535
+ $out .= '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>';
536
+
537
+ return $out;
538
+ }
539
+
540
+ /**
541
+ * Display a monthly dropdown for filtering items
542
+ *
543
+ * @since 3.1.0
544
+ *
545
+ * @global wpdb $wpdb WordPress database abstraction object.
546
+ * @global WP_Locale $wp_locale WordPress date and time locale object.
547
+ *
548
+ * @param string $post_type
549
+ */
550
+ protected function months_dropdown( $post_type ) {
551
+ global $wpdb, $wp_locale;
552
+
553
+ /**
554
+ * Filters whether to remove the 'Months' drop-down from the post list table.
555
+ *
556
+ * @since 4.2.0
557
+ *
558
+ * @param bool $disable Whether to disable the drop-down. Default false.
559
+ * @param string $post_type The post type.
560
+ */
561
+ if ( apply_filters( 'disable_months_dropdown', false, $post_type ) ) {
562
+ return;
563
+ }
564
+
565
+ $extra_checks = "AND post_status != 'auto-draft'";
566
+ if ( ! isset( $_GET['post_status'] ) || 'trash' !== $_GET['post_status'] ) {
567
+ $extra_checks .= " AND post_status != 'trash'";
568
+ } elseif ( isset( $_GET['post_status'] ) ) {
569
+ $extra_checks = $wpdb->prepare( ' AND post_status = %s', $_GET['post_status'] );
570
+ }
571
+
572
+ $months = $wpdb->get_results(
573
+ $wpdb->prepare(
574
+ "
575
+ SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
576
+ FROM $wpdb->posts
577
+ WHERE post_type = %s
578
+ $extra_checks
579
+ ORDER BY post_date DESC
580
+ ",
581
+ $post_type
582
+ )
583
+ );
584
+
585
+ /**
586
+ * Filters the 'Months' drop-down results.
587
+ *
588
+ * @since 3.7.0
589
+ *
590
+ * @param object $months The months drop-down query results.
591
+ * @param string $post_type The post type.
592
+ */
593
+ $months = apply_filters( 'months_dropdown_results', $months, $post_type );
594
+
595
+ $month_count = count( $months );
596
+
597
+ if ( ! $month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) {
598
+ return;
599
+ }
600
+
601
+ $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
602
+ ?>
603
+ <label for="filter-by-date" class="screen-reader-text"><?php _e( 'Filter by date' ); ?></label>
604
+ <select name="m" id="filter-by-date">
605
+ <option<?php selected( $m, 0 ); ?> value="0"><?php _e( 'All dates' ); ?></option>
606
+ <?php
607
+ foreach ( $months as $arc_row ) {
608
+ if ( 0 == $arc_row->year ) {
609
+ continue;
610
+ }
611
+
612
+ $month = zeroise( $arc_row->month, 2 );
613
+ $year = $arc_row->year;
614
+
615
+ printf(
616
+ "<option %s value='%s'>%s</option>\n",
617
+ selected( $m, $year . $month, false ),
618
+ esc_attr( $arc_row->year . $month ),
619
+ /* translators: 1: Month name, 2: 4-digit year. */
620
+ sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year )
621
+ );
622
+ }
623
+ ?>
624
+ </select>
625
+ <?php
626
+ }
627
+
628
+ /**
629
+ * Display a view switcher
630
+ *
631
+ * @since 3.1.0
632
+ *
633
+ * @param string $current_mode
634
+ */
635
+ protected function view_switcher( $current_mode ) {
636
+ ?>
637
+ <input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" />
638
+ <div class="view-switch">
639
+ <?php
640
+ foreach ( $this->modes as $mode => $title ) {
641
+ $classes = array( 'view-' . $mode );
642
+ $aria_current = '';
643
+
644
+ if ( $current_mode === $mode ) {
645
+ $classes[] = 'current';
646
+ $aria_current = ' aria-current="page"';
647
+ }
648
+ printf(
649
+ "<a href='%s' class='%s' id='view-switch-$mode'$aria_current><span class='screen-reader-text'>%s</span></a>\n",
650
+ esc_url( add_query_arg( 'mode', $mode ) ),
651
+ implode( ' ', $classes ),
652
+ $title
653
+ );
654
+ }
655
+ ?>
656
+ </div>
657
+ <?php
658
+ }
659
+
660
+ /**
661
+ * Display a comment count bubble
662
+ *
663
+ * @since 3.1.0
664
+ *
665
+ * @param int $post_id The post ID.
666
+ * @param int $pending_comments Number of pending comments.
667
+ */
668
+ protected function comments_bubble( $post_id, $pending_comments ) {
669
+ $approved_comments = get_comments_number();
670
+
671
+ $approved_comments_number = number_format_i18n( $approved_comments );
672
+ $pending_comments_number = number_format_i18n( $pending_comments );
673
+
674
+ $approved_only_phrase = sprintf(
675
+ /* translators: %s: Number of comments. */
676
+ _n( '%s comment', '%s comments', $approved_comments ),
677
+ $approved_comments_number
678
+ );
679
+
680
+ $approved_phrase = sprintf(
681
+ /* translators: %s: Number of comments. */
682
+ _n( '%s approved comment', '%s approved comments', $approved_comments ),
683
+ $approved_comments_number
684
+ );
685
+
686
+ $pending_phrase = sprintf(
687
+ /* translators: %s: Number of comments. */
688
+ _n( '%s pending comment', '%s pending comments', $pending_comments ),
689
+ $pending_comments_number
690
+ );
691
+
692
+ // No comments at all.
693
+ if ( ! $approved_comments && ! $pending_comments ) {
694
+ printf(
695
+ '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">%s</span>',
696
+ __( 'No comments' )
697
+ );
698
+ // Approved comments have different display depending on some conditions.
699
+ } elseif ( $approved_comments ) {
700
+ printf(
701
+ '<a href="%s" class="post-com-count post-com-count-approved"><span class="comment-count-approved" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
702
+ esc_url(
703
+ add_query_arg(
704
+ array(
705
+ 'p' => $post_id,
706
+ 'comment_status' => 'approved',
707
+ ),
708
+ admin_url( 'edit-comments.php' )
709
+ )
710
+ ),
711
+ $approved_comments_number,
712
+ $pending_comments ? $approved_phrase : $approved_only_phrase
713
+ );
714
+ } else {
715
+ printf(
716
+ '<span class="post-com-count post-com-count-no-comments"><span class="comment-count comment-count-no-comments" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>',
717
+ $approved_comments_number,
718
+ $pending_comments ? __( 'No approved comments' ) : __( 'No comments' )
719
+ );
720
+ }
721
+
722
+ if ( $pending_comments ) {
723
+ printf(
724
+ '<a href="%s" class="post-com-count post-com-count-pending"><span class="comment-count-pending" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
725
+ esc_url(
726
+ add_query_arg(
727
+ array(
728
+ 'p' => $post_id,
729
+ 'comment_status' => 'moderated',
730
+ ),
731
+ admin_url( 'edit-comments.php' )
732
+ )
733
+ ),
734
+ $pending_comments_number,
735
+ $pending_phrase
736
+ );
737
+ } else {
738
+ printf(
739
+ '<span class="post-com-count post-com-count-pending post-com-count-no-pending"><span class="comment-count comment-count-no-pending" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>',
740
+ $pending_comments_number,
741
+ $approved_comments ? __( 'No pending comments' ) : __( 'No comments' )
742
+ );
743
+ }
744
+ }
745
+
746
+ /**
747
+ * Get the current page number
748
+ *
749
+ * @since 3.1.0
750
+ *
751
+ * @return int
752
+ */
753
+ public function get_pagenum() {
754
+ $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0;
755
+
756
+ if ( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] ) {
757
+ $pagenum = $this->_pagination_args['total_pages'];
758
+ }
759
+
760
+ return max( 1, $pagenum );
761
+ }
762
+
763
+ /**
764
+ * Get number of items to display on a single page
765
+ *
766
+ * @since 3.1.0
767
+ *
768
+ * @param string $option
769
+ * @param int $default
770
+ * @return int
771
+ */
772
+ protected function get_items_per_page( $option, $default = 20 ) {
773
+ $per_page = (int) get_user_option( $option );
774
+ if ( empty( $per_page ) || $per_page < 1 ) {
775
+ $per_page = $default;
776
+ }
777
+
778
+ /**
779
+ * Filters the number of items to be displayed on each page of the list table.
780
+ *
781
+ * The dynamic hook name, $option, refers to the `per_page` option depending
782
+ * on the type of list table in use. Possible values include: 'edit_comments_per_page',
783
+ * 'sites_network_per_page', 'site_themes_network_per_page', 'themes_network_per_page',
784
+ * 'users_network_per_page', 'edit_post_per_page', 'edit_page_per_page',
785
+ * 'edit_{$post_type}_per_page', etc.
786
+ *
787
+ * @since 2.9.0
788
+ *
789
+ * @param int $per_page Number of items to be displayed. Default 20.
790
+ */
791
+ return (int) apply_filters( "{$option}", $per_page );
792
+ }
793
+
794
+ /**
795
+ * Display the pagination.
796
+ *
797
+ * @since 3.1.0
798
+ *
799
+ * @param string $which
800
+ */
801
+ protected function pagination( $which ) {
802
+ if ( empty( $this->_pagination_args ) ) {
803
+ return;
804
+ }
805
+
806
+ $total_items = $this->_pagination_args['total_items'];
807
+ $total_pages = $this->_pagination_args['total_pages'];
808
+ $infinite_scroll = false;
809
+ if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
810
+ $infinite_scroll = $this->_pagination_args['infinite_scroll'];
811
+ }
812
+
813
+ if ( 'top' === $which && $total_pages > 1 ) {
814
+ $this->screen->render_screen_reader_content( 'heading_pagination' );
815
+ }
816
+
817
+ $output = '<span class="displaying-num">' . sprintf(
818
+ /* translators: %s: Number of items. */
819
+ _n( '%s item', '%s items', $total_items ),
820
+ number_format_i18n( $total_items )
821
+ ) . '</span>';
822
+
823
+ $current = $this->get_pagenum();
824
+ $removable_query_args = wp_removable_query_args();
825
+
826
+ $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
827
+
828
+ $current_url = remove_query_arg( $removable_query_args, $current_url );
829
+
830
+ $page_links = array();
831
+
832
+ $total_pages_before = '<span class="paging-input">';
833
+ $total_pages_after = '</span></span>';
834
+
835
+ $disable_first = false;
836
+ $disable_last = false;
837
+ $disable_prev = false;
838
+ $disable_next = false;
839
+
840
+ if ( $current == 1 ) {
841
+ $disable_first = true;
842
+ $disable_prev = true;
843
+ }
844
+ if ( $current == 2 ) {
845
+ $disable_first = true;
846
+ }
847
+ if ( $current == $total_pages ) {
848
+ $disable_last = true;
849
+ $disable_next = true;
850
+ }
851
+ if ( $current == $total_pages - 1 ) {
852
+ $disable_last = true;
853
+ }
854
+
855
+ if ( $disable_first ) {
856
+ $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>';
857
+ } else {
858
+ $page_links[] = sprintf(
859
+ "<a class='first-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
860
+ esc_url( remove_query_arg( 'paged', $current_url ) ),
861
+ __( 'First page' ),
862
+ '&laquo;'
863
+ );
864
+ }
865
+
866
+ if ( $disable_prev ) {
867
+ $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>';
868
+ } else {
869
+ $page_links[] = sprintf(
870
+ "<a class='prev-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
871
+ esc_url( add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ) ),
872
+ __( 'Previous page' ),
873
+ '&lsaquo;'
874
+ );
875
+ }
876
+
877
+ if ( 'bottom' === $which ) {
878
+ $html_current_page = $current;
879
+ $total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page' ) . '</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">';
880
+ } else {
881
+ $html_current_page = sprintf(
882
+ "%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' /><span class='tablenav-paging-text'>",
883
+ '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page' ) . '</label>',
884
+ $current,
885
+ strlen( $total_pages )
886
+ );
887
+ }
888
+ $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
889
+ $page_links[] = $total_pages_before . sprintf(
890
+ /* translators: 1: Current page, 2: Total pages. */
891
+ _x( '%1$s of %2$s', 'paging' ),
892
+ $html_current_page,
893
+ $html_total_pages
894
+ ) . $total_pages_after;
895
+
896
+ if ( $disable_next ) {
897
+ $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
898
+ } else {
899
+ $page_links[] = sprintf(
900
+ "<a class='next-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
901
+ esc_url( add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ) ),
902
+ __( 'Next page' ),
903
+ '&rsaquo;'
904
+ );
905
+ }
906
+
907
+ if ( $disable_last ) {
908
+ $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>';
909
+ } else {
910
+ $page_links[] = sprintf(
911
+ "<a class='last-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
912
+ esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
913
+ __( 'Last page' ),
914
+ '&raquo;'
915
+ );
916
+ }
917
+
918
+ $pagination_links_class = 'pagination-links';
919
+ if ( ! empty( $infinite_scroll ) ) {
920
+ $pagination_links_class .= ' hide-if-js';
921
+ }
922
+ $output .= "\n<span class='$pagination_links_class'>" . join( "\n", $page_links ) . '</span>';
923
+
924
+ if ( $total_pages ) {
925
+ $page_class = $total_pages < 2 ? ' one-page' : '';
926
+ } else {
927
+ $page_class = ' no-pages';
928
+ }
929
+ $this->_pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
930
+
931
+ echo $this->_pagination;
932
+ }
933
+
934
+ /**
935
+ * Get a list of columns. The format is:
936
+ * 'internal-name' => 'Title'
937
+ *
938
+ * @since 3.1.0
939
+ * @abstract
940
+ *
941
+ * @return array
942
+ */
943
+ public function get_columns() {
944
+ die( 'function WP_List_Table::get_columns() must be over-ridden in a sub-class.' );
945
+ }
946
+
947
+ /**
948
+ * Get a list of sortable columns. The format is:
949
+ * 'internal-name' => 'orderby'
950
+ * or
951
+ * 'internal-name' => array( 'orderby', true )
952
+ *
953
+ * The second format will make the initial sorting order be descending
954
+ *
955
+ * @since 3.1.0
956
+ *
957
+ * @return array
958
+ */
959
+ protected function get_sortable_columns() {
960
+ return array();
961
+ }
962
+
963
+ /**
964
+ * Gets the name of the default primary column.
965
+ *
966
+ * @since 4.3.0
967
+ *
968
+ * @return string Name of the default primary column, in this case, an empty string.
969
+ */
970
+ protected function get_default_primary_column_name() {
971
+ $columns = $this->get_columns();
972
+ $column = '';
973
+
974
+ if ( empty( $columns ) ) {
975
+ return $column;
976
+ }
977
+
978
+ // We need a primary defined so responsive views show something,
979
+ // so let's fall back to the first non-checkbox column.
980
+ foreach ( $columns as $col => $column_name ) {
981
+ if ( 'cb' === $col ) {
982
+ continue;
983
+ }
984
+
985
+ $column = $col;
986
+ break;
987
+ }
988
+
989
+ return $column;
990
+ }
991
+
992
+ /**
993
+ * Public wrapper for WP_List_Table::get_default_primary_column_name().
994
+ *
995
+ * @since 4.4.0
996
+ *
997
+ * @return string Name of the default primary column.
998
+ */
999
+ public function get_primary_column() {
1000
+ return $this->get_primary_column_name();
1001
+ }
1002
+
1003
+ /**
1004
+ * Gets the name of the primary column.
1005
+ *
1006
+ * @since 4.3.0
1007
+ *
1008
+ * @return string The name of the primary column.
1009
+ */
1010
+ protected function get_primary_column_name() {
1011
+ $columns = get_column_headers( $this->screen );
1012
+ $default = $this->get_default_primary_column_name();
1013
+
1014
+ // If the primary column doesn't exist fall back to the
1015
+ // first non-checkbox column.
1016
+ if ( ! isset( $columns[ $default ] ) ) {
1017
+ $default = CleantalkListTable::get_default_primary_column_name();
1018
+ }
1019
+
1020
+ /**
1021
+ * Filters the name of the primary column for the current list table.
1022
+ *
1023
+ * @since 4.3.0
1024
+ *
1025
+ * @param string $default Column name default for the specific list table, e.g. 'name'.
1026
+ * @param string $context Screen ID for specific list table, e.g. 'plugins'.
1027
+ */
1028
+ $column = apply_filters( 'list_table_primary_column', $default, $this->screen->id );
1029
+
1030
+ if ( empty( $column ) || ! isset( $columns[ $column ] ) ) {
1031
+ $column = $default;
1032
+ }
1033
+
1034
+ return $column;
1035
+ }
1036
+
1037
+ /**
1038
+ * Get a list of all, hidden and sortable columns, with filter applied
1039
+ *
1040
+ * @since 3.1.0
1041
+ *
1042
+ * @return array
1043
+ */
1044
+ protected function get_column_info() {
1045
+ // $_column_headers is already set / cached
1046
+ if ( isset( $this->_column_headers ) && is_array( $this->_column_headers ) ) {
1047
+ // Back-compat for list tables that have been manually setting $_column_headers for horse reasons.
1048
+ // In 4.3, we added a fourth argument for primary column.
1049
+ $column_headers = array( array(), array(), array(), $this->get_primary_column_name() );
1050
+ foreach ( $this->_column_headers as $key => $value ) {
1051
+ $column_headers[ $key ] = $value;
1052
+ }
1053
+
1054
+ return $column_headers;
1055
+ }
1056
+
1057
+ $columns = get_column_headers( $this->screen );
1058
+ $hidden = get_hidden_columns( $this->screen );
1059
+
1060
+ $sortable_columns = $this->get_sortable_columns();
1061
+ /**
1062
+ * Filters the list table sortable columns for a specific screen.
1063
+ *
1064
+ * The dynamic portion of the hook name, `$this->screen->id`, refers
1065
+ * to the ID of the current screen, usually a string.
1066
+ *
1067
+ * @since 3.5.0
1068
+ *
1069
+ * @param array $sortable_columns An array of sortable columns.
1070
+ */
1071
+ $_sortable = apply_filters( "manage_{$this->screen->id}_sortable_columns", $sortable_columns );
1072
+
1073
+ $sortable = array();
1074
+ foreach ( $_sortable as $id => $data ) {
1075
+ if ( empty( $data ) ) {
1076
+ continue;
1077
+ }
1078
+
1079
+ $data = (array) $data;
1080
+ if ( ! isset( $data[1] ) ) {
1081
+ $data[1] = false;
1082
+ }
1083
+
1084
+ $sortable[ $id ] = $data;
1085
+ }
1086
+
1087
+ $primary = $this->get_primary_column_name();
1088
+ $this->_column_headers = array( $columns, $hidden, $sortable, $primary );
1089
+
1090
+ return $this->_column_headers;
1091
+ }
1092
+
1093
+ /**
1094
+ * Return number of visible columns
1095
+ *
1096
+ * @since 3.1.0
1097
+ *
1098
+ * @return int
1099
+ */
1100
+ public function get_column_count() {
1101
+ list ( $columns, $hidden ) = $this->get_column_info();
1102
+ $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) );
1103
+ return count( $columns ) - count( $hidden );
1104
+ }
1105
+
1106
+ /**
1107
+ * Print column headers, accounting for hidden and sortable columns.
1108
+ *
1109
+ * @since 3.1.0
1110
+ *
1111
+ * @staticvar int $cb_counter
1112
+ *
1113
+ * @param bool $with_id Whether to set the id attribute or not
1114
+ */
1115
+ public function print_column_headers( $with_id = true ) {
1116
+ list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
1117
+
1118
+ $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
1119
+ $current_url = remove_query_arg( 'paged', $current_url );
1120
+
1121
+ if ( isset( $_GET['orderby'] ) ) {
1122
+ $current_orderby = $_GET['orderby'];
1123
+ } else {
1124
+ $current_orderby = '';
1125
+ }
1126
+
1127
+ if ( isset( $_GET['order'] ) && 'desc' === $_GET['order'] ) {
1128
+ $current_order = 'desc';
1129
+ } else {
1130
+ $current_order = 'asc';
1131
+ }
1132
+
1133
+ if ( ! empty( $columns['cb'] ) ) {
1134
+ static $cb_counter = 1;
1135
+ $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>'
1136
+ . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
1137
+ $cb_counter++;
1138
+ }
1139
+
1140
+ foreach ( $columns as $column_key => $column_display_name ) {
1141
+ $class = array( 'manage-column', "column-$column_key" );
1142
+
1143
+ if ( in_array( $column_key, $hidden ) ) {
1144
+ $class[] = 'hidden';
1145
+ }
1146
+
1147
+ if ( 'cb' === $column_key ) {
1148
+ $class[] = 'check-column';
1149
+ } elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) {
1150
+ $class[] = 'num';
1151
+ }
1152
+
1153
+ if ( $column_key === $primary ) {
1154
+ $class[] = 'column-primary';
1155
+ }
1156
+
1157
+ if ( isset( $sortable[ $column_key ] ) ) {
1158
+ list( $orderby, $desc_first ) = $sortable[ $column_key ];
1159
+
1160
+ if ( $current_orderby === $orderby ) {
1161
+ $order = 'asc' === $current_order ? 'desc' : 'asc';
1162
+ $class[] = 'sorted';
1163
+ $class[] = $current_order;
1164
+ } else {
1165
+ $order = $desc_first ? 'desc' : 'asc';
1166
+ $class[] = 'sortable';
1167
+ $class[] = $desc_first ? 'asc' : 'desc';
1168
+ }
1169
+
1170
+ $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
1171
+ }
1172
+
1173
+ $tag = ( 'cb' === $column_key ) ? 'td' : 'th';
1174
+ $scope = ( 'th' === $tag ) ? 'scope="col"' : '';
1175
+ $id = $with_id ? "id='$column_key'" : '';
1176
+
1177
+ if ( ! empty( $class ) ) {
1178
+ $class = "class='" . join( ' ', $class ) . "'";
1179
+ }
1180
+
1181
+ echo "<$tag $scope $id $class>$column_display_name</$tag>";
1182
+ }
1183
+ }
1184
+
1185
+ /**
1186
+ * Displays the table.
1187
+ *
1188
+ * @since 3.1.0
1189
+ */
1190
+ public function display() {
1191
+ $singular = $this->_args['singular'];
1192
+
1193
+ $this->display_tablenav( 'top' );
1194
+
1195
+ $this->screen->render_screen_reader_content( 'heading_list' );
1196
+ ?>
1197
+ <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
1198
+ <thead>
1199
+ <tr>
1200
+ <?php $this->print_column_headers(); ?>
1201
+ </tr>
1202
+ </thead>
1203
+
1204
+ <tbody id="the-list"
1205
+ <?php
1206
+ if ( $singular ) {
1207
+ echo " data-wp-lists='list:$singular'";
1208
+ }
1209
+ ?>
1210
+ >
1211
+ <?php $this->display_rows_or_placeholder(); ?>
1212
+ </tbody>
1213
+
1214
+ <tfoot>
1215
+ <tr>
1216
+ <?php $this->print_column_headers( false ); ?>
1217
+ </tr>
1218
+ </tfoot>
1219
+
1220
+ </table>
1221
+ <?php
1222
+ $this->display_tablenav( 'bottom' );
1223
+ }
1224
+
1225
+ /**
1226
+ * Get a list of CSS classes for the WP_List_Table table tag.
1227
+ *
1228
+ * @since 3.1.0
1229
+ *
1230
+ * @return array List of CSS classes for the table tag.
1231
+ */
1232
+ protected function get_table_classes() {
1233
+ return array( 'widefat', 'fixed', 'striped', $this->_args['plural'] );
1234
+ }
1235
+
1236
+ /**
1237
+ * Generate the table navigation above or below the table
1238
+ *
1239
+ * @since 3.1.0
1240
+ * @param string $which
1241
+ */
1242
+ protected function display_tablenav( $which ) {
1243
+ if ( 'top' === $which ) {
1244
+ wp_nonce_field( 'bulk-' . $this->_args['plural'] );
1245
+ }
1246
+ ?>
1247
+ <div class="tablenav <?php echo esc_attr( $which ); ?>">
1248
+
1249
+ <?php if ( $this->has_items() ) : ?>
1250
+ <div class="alignleft actions bulkactions">
1251
+ <?php $this->bulk_actions( $which ); ?>
1252
+ </div>
1253
+ <?php
1254
+ endif;
1255
+ $this->extra_tablenav( $which );
1256
+ $this->pagination( $which );
1257
+ ?>
1258
+
1259
+ <br class="clear" />
1260
+ </div>
1261
+ <?php
1262
+ }
1263
+
1264
+ /**
1265
+ * Extra controls to be displayed between bulk actions and pagination
1266
+ *
1267
+ * @since 3.1.0
1268
+ *
1269
+ * @param string $which
1270
+ */
1271
+ protected function extra_tablenav( $which ) {}
1272
+
1273
+ /**
1274
+ * Generate the tbody element for the list table.
1275
+ *
1276
+ * @since 3.1.0
1277
+ */
1278
+ public function display_rows_or_placeholder() {
1279
+ if ( $this->has_items() ) {
1280
+ $this->display_rows();
1281
+ } else {
1282
+ echo '<tr class="no-items"><td class="colspanchange" colspan="' . $this->get_column_count() . '">';
1283
+ $this->no_items();
1284
+ echo '</td></tr>';
1285
+ }
1286
+ }
1287
+
1288
+ /**
1289
+ * Generate the table rows
1290
+ *
1291
+ * @since 3.1.0
1292
+ */
1293
+ public function display_rows() {
1294
+ foreach ( $this->items as $item ) {
1295
+ $this->single_row( $item );
1296
+ }
1297
+ }
1298
+
1299
+ /**
1300
+ * Generates content for a single row of the table
1301
+ *
1302
+ * @since 3.1.0
1303
+ *
1304
+ * @param object $item The current item
1305
+ */
1306
+ public function single_row( $item ) {
1307
+ echo '<tr>';
1308
+ $this->single_row_columns( $item );
1309
+ echo '</tr>';
1310
+ }
1311
+
1312
+ /**
1313
+ * @param object $item
1314
+ * @param string $column_name
1315
+ */
1316
+ protected function column_default( $item, $column_name ) {}
1317
+
1318
+ /**
1319
+ * @param object $item
1320
+ */
1321
+ protected function column_cb( $item ) {}
1322
+
1323
+ /**
1324
+ * Generates the columns for a single row of the table
1325
+ *
1326
+ * @since 3.1.0
1327
+ *
1328
+ * @param object $item The current item
1329
+ */
1330
+ protected function single_row_columns( $item ) {
1331
+ list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
1332
+
1333
+ foreach ( $columns as $column_name => $column_display_name ) {
1334
+ $classes = "$column_name column-$column_name";
1335
+ if ( $primary === $column_name ) {
1336
+ $classes .= ' has-row-actions column-primary';
1337
+ }
1338
+
1339
+ if ( in_array( $column_name, $hidden ) ) {
1340
+ $classes .= ' hidden';
1341
+ }
1342
+
1343
+ // Comments column uses HTML in the display name with screen reader text.
1344
+ // Instead of using esc_attr(), we strip tags to get closer to a user-friendly string.
1345
+ $data = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"';
1346
+
1347
+ $attributes = "class='$classes' $data";
1348
+
1349
+ if ( 'cb' === $column_name ) {
1350
+ echo '<th scope="row" class="check-column">';
1351
+ echo $this->column_cb( $item );
1352
+ echo '</th>';
1353
+ } elseif ( method_exists( $this, '_column_' . $column_name ) ) {
1354
+ echo call_user_func(
1355
+ array( $this, '_column_' . $column_name ),
1356
+ $item,
1357
+ $classes,
1358
+ $data,
1359
+ $primary
1360
+ );
1361
+ } elseif ( method_exists( $this, 'column_' . $column_name ) ) {
1362
+ echo "<td $attributes>";
1363
+ echo call_user_func( array( $this, 'column_' . $column_name ), $item );
1364
+ echo $this->handle_row_actions( $item, $column_name, $primary );
1365
+ echo '</td>';
1366
+ } else {
1367
+ echo "<td $attributes>";
1368
+ echo $this->column_default( $item, $column_name );
1369
+ echo $this->handle_row_actions( $item, $column_name, $primary );
1370
+ echo '</td>';
1371
+ }
1372
+ }
1373
+ }
1374
+
1375
+ /**
1376
+ * Generates and display row actions links for the list table.
1377
+ *
1378
+ * @since 4.3.0
1379
+ *
1380
+ * @param object $item The item being acted upon.
1381
+ * @param string $column_name Current column name.
1382
+ * @param string $primary Primary column name.
1383
+ * @return string The row actions HTML, or an empty string if the current column is the primary column.
1384
+ */
1385
+ protected function handle_row_actions( $item, $column_name, $primary ) {
1386
+ return $column_name === $primary ? '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>' : '';
1387
+ }
1388
+
1389
+ /**
1390
+ * Handle an incoming ajax request (called from admin-ajax.php)
1391
+ *
1392
+ * @since 3.1.0
1393
+ */
1394
+ public function ajax_response() {
1395
+ $this->prepare_items();
1396
+
1397
+ ob_start();
1398
+ if ( ! empty( $_REQUEST['no_placeholder'] ) ) {
1399
+ $this->display_rows();
1400
+ } else {
1401
+ $this->display_rows_or_placeholder();
1402
+ }
1403
+
1404
+ $rows = ob_get_clean();
1405
+
1406
+ $response = array( 'rows' => $rows );
1407
+
1408
+ if ( isset( $this->_pagination_args['total_items'] ) ) {
1409
+ $response['total_items_i18n'] = sprintf(
1410
+ /* translators: Number of items. */
1411
+ _n( '%s item', '%s items', $this->_pagination_args['total_items'] ),
1412
+ number_format_i18n( $this->_pagination_args['total_items'] )
1413
+ );
1414
+ }
1415
+ if ( isset( $this->_pagination_args['total_pages'] ) ) {
1416
+ $response['total_pages'] = $this->_pagination_args['total_pages'];
1417
+ $response['total_pages_i18n'] = number_format_i18n( $this->_pagination_args['total_pages'] );
1418
+ }
1419
+
1420
+ die( wp_json_encode( $response ) );
1421
+ }
1422
+
1423
+ /**
1424
+ * Send required variables to JavaScript land
1425
+ */
1426
+ public function _js_vars() {
1427
+ $args = array(
1428
+ 'class' => get_class( $this ),
1429
+ 'screen' => array(
1430
+ 'id' => $this->screen->id,
1431
+ 'base' => $this->screen->base,
1432
+ ),
1433
+ );
1434
+
1435
+ printf( "<script type='text/javascript'>list_args = %s;</script>\n", wp_json_encode( $args ) );
1436
+ }
1437
+ }
inc/find-spam/ClassCleantalkFindSpamChecker.php → lib/Cleantalk/ApbctWP/FindSpam/Checker.php RENAMED
@@ -1,132 +1,144 @@
1
- <?php
2
-
3
-
4
- abstract class ClassCleantalkFindSpamChecker
5
- {
6
-
7
- protected $page_title = '';
8
-
9
- protected $apbct;
10
-
11
- protected $page_script_name;
12
-
13
- protected $page_slug;
14
-
15
- protected $list_table;
16
-
17
- public function __construct() {
18
-
19
- global $apbct;
20
- $this->apbct = $apbct;
21
-
22
- // jQueryUI
23
- wp_enqueue_script( 'jqueryui', plugins_url('/cleantalk-spam-protect/js/jquery-ui.min.js'), array('jquery'), '1.12.1' );
24
- wp_enqueue_style( 'jqueryui_css', plugins_url('/cleantalk-spam-protect/css/jquery-ui.min.css'), array(), '1.21.1', 'all' );
25
- wp_enqueue_style( 'jqueryui_theme_css', plugins_url('/cleantalk-spam-protect/css/jquery-ui.theme.min.css'), array(), '1.21.1', 'all' );
26
-
27
- // Common CSS
28
- wp_enqueue_style( 'cleantalk_admin_css_settings_page', plugins_url('/cleantalk-spam-protect/css/cleantalk-spam-check.min.css'), array( 'jqueryui_css' ), APBCT_VERSION, 'all' );
29
-
30
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/ClassApbctListTable.php');
31
-
32
- }
33
-
34
- public function getPageTitle() {
35
-
36
- return $this->page_title;
37
-
38
- }
39
-
40
- public function getPageScriptName() {
41
-
42
- return $this->page_script_name;
43
-
44
- }
45
-
46
- /**
47
- * @return mixed
48
- */
49
- public function getPageSlug()
50
- {
51
- return $this->page_slug;
52
- }
53
-
54
- /**
55
- * @return mixed
56
- */
57
- public function getApbct()
58
- {
59
- return $this->apbct;
60
- }
61
-
62
- abstract function getCurrentScanPage();
63
-
64
- abstract function getTotalSpamPage();
65
-
66
- abstract function getSpamLogsPage();
67
-
68
- protected function getCurrentScanPanel( $spam_checker ) {
69
- ?>
70
-
71
- <!-- Main info -->
72
- <h3 id="ct_checking_status"><?php echo $spam_checker::ct_ajax_info(true) ; ?></h3>
73
-
74
- <!-- Check options -->
75
- <div class="ct_to_hide" id="ct_check_params_wrapper">
76
- <button class="button ct_check_params_elem" id="ct_check_spam_button" <?php echo !$this->apbct->data['moderate'] ? 'disabled="disabled"' : ''; ?>><?php _e("Start check", 'cleantalk-spam-protect'); ?></button>
77
- <?php if(!empty($_COOKIE['ct_paused_'.$this->page_slug.'_check'])) { ?><button class="button ct_check_params_elem" id="ct_proceed_check_button"><?php _e("Continue check", 'cleantalk-spam-protect'); ?></button><?php } ?>
78
- <p class="ct_check_params_desc"><?php _e("The plugin will check all $this->page_slug against blacklists database and show you senders that have spam activity on other websites.", 'cleantalk-spam-protect'); ?></p>
79
- <br />
80
- <div class="ct_check_params_elem ct_check_params_elem_sub">
81
- <input id="ct_accurate_check" type="checkbox" value="1" /><label for="ct_accurate_check"><strong><?php _e("Accurate check", 'cleantalk-spam-protect'); ?></strong></label>
82
- </div>
83
- <p class="ct_check_params_desc"><?php _e("Allows to use $this->page_slug's dates to perform more accurate check. Could seriously slow down the check.", 'cleantalk-spam-protect'); ?></p>
84
- <br />
85
- <div class="ct_check_params_elem ct_check_params_elem_sub">
86
- <input id="ct_allow_date_range" type="checkbox" value="1" /><label for="ct_allow_date_range"><strong><?php _e("Specify date range", 'cleantalk-spam-protect'); ?></strong></label>
87
- </div>
88
- <div class="ct_check_params_desc">
89
- <label for="ct_date_range_from"></label><input class="ct_date" type="text" id="ct_date_range_from" value="<?php echo $this->lastCheckDate(); ?>" disabled readonly />
90
- <label for="ct_date_range_till"></label><input class="ct_date" type="text" id="ct_date_range_till" value="<?php echo date( "M j Y"); ?>" disabled readonly />
91
- </div>
92
- <div class="ct_check_params_desc">
93
- <p><?php esc_html_e( "Begin/end dates of creation $this->page_slug to check. If no date is specified, the plugin uses the last $this->page_slug check date.", 'cleantalk-spam-protect'); ?></p>
94
- </div>
95
- <br>
96
- <?php apbct_admin__badge__get_premium(); ?>
97
- </div>
98
-
99
- <!-- Cooling notice -->
100
- <h3 id="ct_cooling_notice"></h3>
101
-
102
- <!-- Preloader and working message -->
103
- <div id="ct_preloader">
104
- <img src="<?php echo APBCT_URL_PATH . '/inc/images/preloader.gif'; ?>" alt="Cleantalk preloader" />
105
- </div>
106
- <div id="ct_working_message">
107
- <?php _e("Please wait for a while. CleanTalk is checking all $this->page_slug via blacklist database at cleantalk.org. You will have option to delete found spam $this->page_slug after plugin finish.", 'cleantalk-spam-protect'); ?>
108
- </div>
109
-
110
- <!-- Pause button -->
111
- <button class="button" id="ct_pause">Pause check</button>
112
- <?php
113
- }
114
-
115
- public static function writeSpamLog( $scan_type, $scan_date, $cnt_checked, $cnt_spam, $cnt_bad ) {
116
-
117
- global $wpdb;
118
- $wpdb->insert(
119
- APBCT_SPAMSCAN_LOGS,
120
- array(
121
- 'scan_type' => $scan_type,
122
- 'start_time' => $scan_date, //@ToDo this is the END date. Need to place both: start and and of scanning
123
- 'count_to_scan' => $cnt_checked,
124
- 'found_spam' => $cnt_spam,
125
- 'found_bad' => $cnt_bad
126
- ),
127
- array( '%s', '%s', '%d', '%d', '%d' )
128
- );
129
-
130
- }
131
-
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam;
4
+
5
+ use Cleantalk\Variables\Cookie;
6
+
7
+ abstract class Checker
8
+ {
9
+
10
+ protected $page_title = '';
11
+
12
+ protected $apbct;
13
+
14
+ protected $page_script_name;
15
+
16
+ protected $page_slug;
17
+
18
+ protected $list_table;
19
+
20
+ public function __construct() {
21
+
22
+ global $apbct;
23
+ $this->apbct = $apbct;
24
+
25
+ // jQueryUI
26
+ wp_enqueue_script( 'jqueryui', plugins_url('/cleantalk-spam-protect/js/jquery-ui.min.js'), array('jquery'), '1.12.1' );
27
+ wp_enqueue_style( 'jqueryui_css', plugins_url('/cleantalk-spam-protect/css/jquery-ui.min.css'), array(), '1.21.1', 'all' );
28
+ wp_enqueue_style( 'jqueryui_theme_css', plugins_url('/cleantalk-spam-protect/css/jquery-ui.theme.min.css'), array(), '1.21.1', 'all' );
29
+
30
+ // Common CSS
31
+ wp_enqueue_style( 'cleantalk_admin_css_settings_page', plugins_url('/cleantalk-spam-protect/css/cleantalk-spam-check.min.css'), array( 'jqueryui_css' ), APBCT_VERSION, 'all' );
32
+
33
+ }
34
+
35
+ public function getPageTitle() {
36
+
37
+ return $this->page_title;
38
+
39
+ }
40
+
41
+ public function getPageScriptName() {
42
+
43
+ return $this->page_script_name;
44
+
45
+ }
46
+
47
+ /**
48
+ * @return mixed
49
+ */
50
+ public function getPageSlug()
51
+ {
52
+ return $this->page_slug;
53
+ }
54
+
55
+ /**
56
+ * @return mixed
57
+ */
58
+ public function getApbct()
59
+ {
60
+ return $this->apbct;
61
+ }
62
+
63
+ abstract function getCurrentScanPage();
64
+
65
+ abstract function getSpamLogsPage();
66
+
67
+ protected function getCurrentScanPanel( $spam_checker ) {
68
+
69
+ $dates_allowed = '';
70
+ $dates_disabled = 'disabled';
71
+ if( Cookie::get('ct_' . $this->page_slug . '_dates_allowed') ) {
72
+ $dates_allowed = 'checked';
73
+ $dates_disabled = '';
74
+ }
75
+ $dates_from = Cookie::get('ct_' . $this->page_slug . '_dates_from');
76
+ $dates_till = Cookie::get('ct_' . $this->page_slug . '_dates_till');
77
+
78
+ ?>
79
+
80
+ <!-- Count -->
81
+ <h3 id="ct_checking_count"><?php echo $spam_checker::get_count_text() ; ?></h3>
82
+
83
+ <!-- Main info -->
84
+ <h3 id="ct_checking_status"><?php echo $spam_checker::ct_ajax_info(true) ; ?></h3>
85
+
86
+ <!-- Check options -->
87
+ <div class="ct_to_hide" id="ct_check_params_wrapper">
88
+ <button class="button ct_check_params_elem" id="ct_check_spam_button" <?php echo !$this->apbct->data['moderate'] ? 'disabled="disabled"' : ''; ?>><?php _e("Start check", 'cleantalk-spam-protect'); ?></button>
89
+ <?php if(!empty($_COOKIE['ct_paused_'.$this->page_slug.'_check'])) { ?><button class="button ct_check_params_elem" id="ct_proceed_check_button"><?php _e("Continue check", 'cleantalk-spam-protect'); ?></button><?php } ?>
90
+ <p class="ct_check_params_desc"><?php _e("The plugin will check all $this->page_slug against blacklists database and show you senders that have spam activity on other websites.", 'cleantalk-spam-protect'); ?></p>
91
+ <br />
92
+ <div class="ct_check_params_elem ct_check_params_elem_sub">
93
+ <input id="ct_accurate_check" type="checkbox" value="1" /><label for="ct_accurate_check"><strong><?php _e("Accurate check", 'cleantalk-spam-protect'); ?></strong></label>
94
+ </div>
95
+ <p class="ct_check_params_desc"><?php _e("Allows to use $this->page_slug's dates to perform more accurate check. Could seriously slow down the check.", 'cleantalk-spam-protect'); ?></p>
96
+ <br />
97
+ <div class="ct_check_params_elem ct_check_params_elem_sub">
98
+ <input id="ct_allow_date_range" type="checkbox" value="1" <?php echo $dates_allowed; ?> /><label for="ct_allow_date_range"><strong><?php _e("Specify date range", 'cleantalk-spam-protect'); ?></strong></label>
99
+ </div>
100
+ <div class="ct_check_params_desc">
101
+ <label for="ct_date_range_from"></label><input class="ct_date" type="text" id="ct_date_range_from" value="<?php echo $dates_from; ?>" <?php echo $dates_disabled; ?> readonly />
102
+ <label for="ct_date_range_till"></label><input class="ct_date" type="text" id="ct_date_range_till" value="<?php echo $dates_till; ?>" <?php echo $dates_disabled; ?> readonly />
103
+ </div>
104
+ <div class="ct_check_params_desc">
105
+ <p><?php esc_html_e( "Begin/end dates of creation $this->page_slug to check. If no date is specified, the plugin will check all entries.", 'cleantalk-spam-protect'); ?></p>
106
+ </div>
107
+ <br>
108
+ <?php apbct_admin__badge__get_premium(); ?>
109
+ </div>
110
+
111
+ <!-- Cooling notice -->
112
+ <h3 id="ct_cooling_notice"></h3>
113
+
114
+ <!-- Preloader and working message -->
115
+ <div id="ct_preloader">
116
+ <img src="<?php echo APBCT_URL_PATH . '/inc/images/preloader.gif'; ?>" alt="Cleantalk preloader" />
117
+ </div>
118
+ <div id="ct_working_message">
119
+ <?php _e("Please wait for a while. CleanTalk is checking all $this->page_slug via blacklist database at cleantalk.org. You will have option to delete found spam $this->page_slug after plugin finish.", 'cleantalk-spam-protect'); ?>
120
+ </div>
121
+
122
+ <!-- Pause button -->
123
+ <button class="button" id="ct_pause">Pause check</button>
124
+ <?php
125
+ }
126
+
127
+ public static function writeSpamLog( $scan_type, $scan_date, $cnt_checked, $cnt_spam, $cnt_bad ) {
128
+
129
+ global $wpdb;
130
+ $wpdb->insert(
131
+ APBCT_SPAMSCAN_LOGS,
132
+ array(
133
+ 'scan_type' => $scan_type,
134
+ 'start_time' => $scan_date, //@ToDo this is the END date. Need to place both: start and and of scanning
135
+ 'count_to_scan' => $cnt_checked,
136
+ 'found_spam' => $cnt_spam,
137
+ 'found_bad' => $cnt_bad
138
+ ),
139
+ array( '%s', '%s', '%d', '%d', '%d' )
140
+ );
141
+
142
+ }
143
+
144
  }
inc/find-spam/ClassCleantalkFindSpamCommentsChecker.php → lib/Cleantalk/ApbctWP/FindSpam/CommentsChecker.php RENAMED
@@ -1,485 +1,500 @@
1
- <?php
2
-
3
-
4
- class ClassCleantalkFindSpamCommentsChecker extends ClassCleantalkFindSpamChecker
5
- {
6
-
7
- public function __construct() {
8
-
9
- parent::__construct();
10
-
11
- $this->page_title = esc_html__( 'Check comments for spam', 'cleantalk-spam-protect');
12
- $this->page_script_name = 'edit-comments.php';
13
- $this->page_slug = 'spam';
14
-
15
- // Preparing data
16
- if(!empty($_COOKIE['ct_paused_comments_check']))
17
- $prev_check = json_decode(stripslashes($_COOKIE['ct_paused_comments_check']), true);
18
-
19
- wp_enqueue_script( 'ct_comments_checkspam', plugins_url('/cleantalk-spam-protect/js/cleantalk-comments-checkspam.min.js'), array( 'jquery', 'jqueryui' ), APBCT_VERSION );
20
- wp_localize_script( 'ct_comments_checkspam', 'ctCommentsCheck', array(
21
- 'ct_ajax_nonce' => wp_create_nonce('ct_secret_nonce'),
22
- 'ct_prev_accurate' => !empty($prev_check['accurate']) ? true : false,
23
- 'ct_prev_from' => !empty($prev_check['from']) ? $prev_check['from'] : false,
24
- 'ct_prev_till' => !empty($prev_check['till']) ? $prev_check['till'] : false,
25
- 'ct_timeout_confirm' => __('Failed from timeout. Going to check comments again.', 'cleantalk-spam-protect'),
26
- 'ct_confirm_deletion_all' => __('Delete all spam comments?', 'cleantalk-spam-protect'),
27
- 'ct_comments_added_after' => __('comments', 'cleantalk-spam-protect'),
28
- 'ct_status_string' => __('Checked %s, found %s spam comments and %s bad comments (without IP or email).', 'cleantalk-spam-protect'),
29
- 'ct_status_string_warning' => '<p>'.__('Please do backup of WordPress database before delete any accounts!', 'cleantalk-spam-protect').'</p>',
30
- 'start' => !empty($_COOKIE['ct_comments_start_check']) ? true : false,
31
- ));
32
-
33
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkCommentsListTable.php');
34
-
35
- }
36
-
37
- public function getCurrentScanPage() {
38
-
39
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkCommentsListTableScan.php');
40
- $this->list_table = new ABPCTCommentsListTableScan();
41
-
42
- $this->getCurrentScanPanel( $this );
43
- echo '<form action="" method="POST">';
44
- $this->list_table->display();
45
- echo '</form>';
46
-
47
- }
48
-
49
- public function getTotalSpamPage(){
50
-
51
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkCommentsListTableSpam.php');
52
- $this->list_table = new ABPCTCommentsListTableSpam();
53
-
54
- echo '<form action="" method="POST">';
55
- $this->list_table->display();
56
- echo '</form>';
57
-
58
- }
59
-
60
- public function getSpamLogsPage(){
61
-
62
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkCommentsListTableLogs.php');
63
- $this->list_table = new ABPCTCommentsListTableLogs();
64
-
65
- echo '<form action="" method="POST">';
66
- $this->list_table->display();
67
- echo '</form>';
68
-
69
- }
70
-
71
- /**
72
- * Get date last checked comment or date of the first comment
73
- *
74
- * @return string date "M j Y"
75
- */
76
- public static function lastCheckDate() {
77
-
78
- $params = array(
79
- 'fields' => 'ids',
80
- 'meta_key' => 'ct_checked',
81
- 'orderby' => 'ct_checked',
82
- 'order' => 'ASC'
83
- );
84
- $checked_comments = get_comments( $params );
85
-
86
- if ( ! empty($checked_comments) ) {
87
-
88
- return get_comment_date( "M j Y", end( $checked_comments ) );
89
-
90
- } else {
91
-
92
- $params = array(
93
- 'fields' => 'ids',
94
- 'orderby' => 'comment_date_gmt',
95
- 'order' => 'ASC',
96
- 'number' => 1
97
- );
98
- $first_comment = get_comments( $params );
99
-
100
- return get_comment_date( "M j Y", current( $first_comment ) );
101
-
102
- }
103
-
104
- }
105
-
106
- public static function ct_ajax_check_comments(){
107
-
108
- check_ajax_referer( 'ct_secret_nonce', 'security' );
109
-
110
- global $wpdb, $apbct;
111
-
112
- if(isset($_POST['from'], $_POST['till'])){
113
- $from_date = date('Y-m-d', intval(strtotime($_POST['from'])));
114
- $till_date = date('Y-m-d', intval(strtotime($_POST['till'])));
115
- }
116
-
117
- // Gettings comments 100 unchecked comments
118
- if(isset($_COOKIE['ct_comments_safe_check'])){
119
- $c = $wpdb->get_results("
120
- SELECT comment_ID, comment_date_gmt, comment_author_IP, comment_author_email
121
- FROM {$wpdb->comments} as comm
122
- WHERE
123
- (comm.comment_approved = '1' OR comm.comment_approved = '0')
124
- AND NOT EXISTS(
125
- SELECT comment_id, meta_key
126
- FROM {$wpdb->commentmeta} as meta
127
- WHERE comm.comment_ID = meta.comment_id AND (meta_key = 'ct_checked' OR meta_key = 'ct_bad')
128
- )
129
- ORDER BY comment_date_gmt
130
- LIMIT 100",
131
- ARRAY_A
132
- );
133
- }else{
134
- $params = array(
135
- 'meta_query' => array(
136
- 'relation' => 'AND',
137
- array(
138
- 'key' => 'ct_checked_now',
139
- 'compare' => 'NOT EXISTS'
140
- ),
141
- array(
142
- 'key' => 'ct_checked',
143
- 'compare' => 'NOT EXISTS'
144
- ),
145
- array(
146
- 'key' => 'ct_bad',
147
- 'compare' => 'NOT EXISTS'
148
- )
149
- ),
150
- 'orderby' => 'comment_date_gmt',
151
- 'order' => 'ASC',
152
- 'number' => 100
153
- );
154
- if(isset($from_date, $till_date)){
155
- $params['date_query'] = array(
156
- 'column' => 'comment_date_gmt',
157
- 'after' => $from_date,
158
- 'before' => $till_date,
159
- 'inclusive' => true,
160
- );
161
- }
162
- $c = get_comments( $params );
163
- }
164
-
165
- $check_result = array(
166
- 'end' => 0,
167
- 'checked' => 0,
168
- 'spam' => 0,
169
- 'bad' => 0,
170
- 'error' => 0
171
- );
172
-
173
- if(sizeof($c)>0){
174
-
175
- // Coverting $c to objects
176
- if(is_array($c[0])){
177
- foreach($c as $key => $value){
178
- $c[$key] = (object)$value;
179
- } unset($key, $value);
180
- }
181
-
182
- if(!empty($_POST['accurate_check'])){
183
- // Leaving comments only with first comment's date. Unsetting others.
184
-
185
- foreach($c as $comment_index => $comment){
186
-
187
- if(!isset($curr_date))
188
- $curr_date = (substr($comment->comment_date_gmt, 0, 10) ? substr($comment->comment_date_gmt, 0, 10) : '');
189
-
190
- if(substr($comment->comment_date_gmt, 0, 10) != $curr_date)
191
- unset($c[$comment_index]);
192
-
193
- }
194
- unset($comment_index, $comment);
195
- }
196
-
197
- // Checking comments IP/Email. Gathering $data for check.
198
- $data = Array();
199
- for($i=0;$i<sizeof($c);$i++){
200
-
201
- $curr_ip = $c[$i]->comment_author_IP;
202
- $curr_email = $c[$i]->comment_author_email;
203
-
204
- // Check for identity
205
- $curr_ip = preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $curr_ip) === 1 ? $curr_ip : null;
206
- $curr_email = preg_match('/^\S+@\S+\.\S+$/', $curr_email) === 1 ? $curr_email : null;
207
-
208
- if(empty($curr_ip) && empty($curr_email)){
209
- $check_result['bad']++;
210
- update_comment_meta($c[$i]->comment_ID,'ct_bad','1');
211
- update_comment_meta($c[$i]->comment_ID,'ct_checked','1');
212
- unset($c[$i]);
213
- }else{
214
- if(!empty($curr_ip))
215
- $data[] = $curr_ip;
216
- if(!empty($curr_email))
217
- $data[] = $curr_email;
218
- // Patch for empty IP/Email
219
- $c[$i]->comment_author_IP = empty($curr_ip) ? 'none' : $curr_ip;
220
- $c[$i]->comment_author_email = empty($curr_email) ? 'none' : $curr_email;
221
- }
222
- }
223
-
224
- // Recombining after checking and unsettting
225
- $c = array_values($c);
226
-
227
- // Drop if data empty and there's no comments to check
228
- if(count($data) == 0){
229
- if($_POST['unchecked'] === 0)
230
- $check_result['end'] = 1;
231
- print json_encode($check_result);
232
- die();
233
- }
234
-
235
- $result = \Cleantalk\ApbctWP\API::method__spam_check_cms($apbct->api_key, $data, !empty($_POST['accurate_check']) ? $curr_date : null);
236
-
237
- if(empty($result['error'])){
238
-
239
- for($i=0;$i<sizeof($c);$i++){
240
-
241
- $mark_spam_ip = false;
242
- $mark_spam_email = false;
243
-
244
- $check_result['checked']++;
245
- update_comment_meta($c[$i]->comment_ID,'ct_checked',date("Y-m-d H:m:s"));
246
- update_comment_meta( $c[$i]->comment_ID, 'ct_checked_now', date("Y-m-d H:m:s"), true) ;
247
-
248
- $uip=$c[$i]->comment_author_IP;
249
- $uim=$c[$i]->comment_author_email;
250
-
251
- if(isset($result[$uip]) && $result[$uip]['appears'] == 1)
252
- $mark_spam_ip = true;
253
-
254
- if(isset($result[$uim]) && $result[$uim]['appears'] == 1)
255
- $mark_spam_email = true;
256
-
257
- if ($mark_spam_ip || $mark_spam_email){
258
- $check_result['spam']++;
259
- update_comment_meta($c[$i]->comment_ID,'ct_marked_as_spam','1');
260
- }
261
- }
262
- print json_encode($check_result);
263
-
264
- }else{
265
- $check_result['error'] = 1;
266
- $check_result['error_message'] = $result['error'];
267
- echo json_encode($check_result);
268
- }
269
- }else{
270
-
271
- $check_result['end'] = 1;
272
-
273
- $log_data = static::get_log_data();
274
- static::writeSpamLog( 'comments', date("Y-m-d H:i:s"), $log_data['checked'], $log_data['spam'], $log_data['bad'] );
275
-
276
- print json_encode($check_result);
277
-
278
- }
279
-
280
- die;
281
- }
282
-
283
- public static function ct_ajax_info($direct_call = false){
284
-
285
- if (!$direct_call)
286
- check_ajax_referer( 'ct_secret_nonce', 'security' );
287
-
288
- // Checked comments
289
- $params_checked = array(
290
- 'meta_key' => 'ct_checked_now',
291
- 'orderby' => 'ct_checked_now'
292
- );
293
- $checked_comments = new WP_Comment_Query($params_checked);
294
- $cnt_checked = count( $checked_comments->get_comments() );
295
-
296
- // Spam comments
297
- $params_spam = array(
298
- 'meta_query' => array(
299
- 'relation' => 'AND',
300
- array(
301
- 'key' => 'ct_marked_as_spam',
302
- 'compare' => 'EXISTS'
303
- ),
304
- array(
305
- 'key' => 'ct_checked_now',
306
- 'compare' => 'EXISTS'
307
- ),
308
- ),
309
- );
310
- $spam_comments = new WP_Comment_Query($params_spam);
311
- $cnt_spam = count( $spam_comments->get_comments() );
312
-
313
- // Bad comments (without IP and Email)
314
- $params_bad = array(
315
- 'meta_query' => array(
316
- 'relation' => 'AND',
317
- array(
318
- 'key' => 'ct_bad',
319
- 'compare' => 'EXISTS'
320
- ),
321
- array(
322
- 'key' => 'ct_checked_now',
323
- 'compare' => 'EXISTS'
324
- ),
325
- ),
326
- );
327
- $bad_comments = new WP_Comment_Query($params_bad);
328
- $cnt_bad = count( $bad_comments->get_comments() );
329
-
330
- $return = array(
331
- 'message' => '',
332
- 'spam' => $cnt_spam,
333
- 'checked' => $cnt_checked,
334
- 'bad' => $cnt_bad,
335
- );
336
-
337
- if( ! $direct_call ) {
338
- $return['message'] .= sprintf (
339
- esc_html__('Checked %s, found %s spam comments and %s bad comments (without IP or email)', 'cleantalk-spam-protect'),
340
- $cnt_checked,
341
- $cnt_spam,
342
- $cnt_bad
343
- );
344
- } else {
345
- if( isset( $return['checked'] ) && 0 == $return['checked'] ) {
346
- $return['message'] = esc_html__( 'Never checked yet or no new spam.', 'cleantalk-spam-protect');
347
- } else {
348
- $return['message'] .= sprintf (
349
- __("Last check %s: checked %s comments, found %s spam comments and %s bad comments (without IP or email).", 'cleantalk-spam-protect'),
350
- self::lastCheckDate(),
351
- $cnt_checked,
352
- $cnt_spam,
353
- $cnt_bad
354
- );
355
- }
356
- }
357
-
358
- $backup_notice = '&nbsp;';
359
- if ($cnt_spam > 0){
360
- $backup_notice = __("Please do backup of WordPress database before delete any comments!", 'cleantalk-spam-protect');
361
- }
362
- $return['message'] .= "<p>$backup_notice</p>";
363
-
364
- if($direct_call){
365
- return $return['message'];
366
- }else{
367
- echo json_encode($return);
368
- die();
369
- }
370
-
371
- }
372
-
373
- public static function ct_ajax_clear_comments(){
374
-
375
- check_ajax_referer( 'ct_secret_nonce', 'security' );
376
-
377
- global $wpdb;
378
- $wpdb->query("DELETE FROM {$wpdb->commentmeta} WHERE meta_key IN ('ct_checked_now')");
379
-
380
- if ( isset($_POST['from']) && isset($_POST['till']) ) {
381
- if ( preg_match('/[a-zA-Z]{3}\s{1}\d{1,2}\s{1}\d{4}/', $_POST['from'] ) && preg_match('/[a-zA-Z]{3}\s{1}\d{1,2}\s{1}\d{4}/', $_POST['till'] ) ) {
382
-
383
- $from = date('Y-m-d', intval(strtotime($_POST['from']))) . ' 00:00:00';
384
- $till = date('Y-m-d', intval(strtotime($_POST['till']))) . ' 23:59:59';
385
-
386
- $wpdb->query("DELETE FROM {$wpdb->commentmeta} WHERE
387
- meta_key IN ('ct_checked','ct_marked_as_spam','ct_bad')
388
- AND meta_value >= '{$from}'
389
- AND meta_value <= '{$till}';");
390
-
391
- die();
392
-
393
- }
394
- }
395
-
396
- }
397
-
398
- private static function get_log_data() {
399
-
400
- // Checked users
401
- $params_spam = array(
402
- 'meta_key' => 'ct_checked_now',
403
- );
404
- $spam_comments = new WP_Comment_Query($params_spam);
405
- $cnt_checked = count( $spam_comments->get_comments() );
406
-
407
- // Spam users
408
- $params_spam = array(
409
- 'meta_query' => array(
410
- 'relation' => 'AND',
411
- array(
412
- 'key' => 'ct_marked_as_spam',
413
- 'compare' => 'EXISTS'
414
- ),
415
- array(
416
- 'key' => 'ct_checked_now',
417
- 'compare' => 'EXISTS'
418
- ),
419
- ),
420
- );
421
- $spam_comments = new WP_Comment_Query($params_spam);
422
- $cnt_spam = count( $spam_comments->get_comments() );
423
-
424
- // Bad users (without IP and Email)
425
- $params_bad = array(
426
- 'meta_query' => array(
427
- 'relation' => 'AND',
428
- array(
429
- 'key' => 'ct_bad',
430
- 'compare' => 'EXISTS'
431
- ),
432
- array(
433
- 'key' => 'ct_checked_now',
434
- 'compare' => 'EXISTS'
435
- ),
436
- ),
437
- );
438
- $spam_comments = new WP_Comment_Query($params_bad);
439
- $cnt_bad = count( $spam_comments->get_comments() );
440
-
441
- return array(
442
- 'spam' => $cnt_spam,
443
- 'checked' => $cnt_checked,
444
- 'bad' => $cnt_bad,
445
- );
446
-
447
- }
448
-
449
- public static function ct_ajax_delete_all(){
450
-
451
- check_ajax_referer( 'ct_secret_nonce', 'security' );
452
-
453
- $args_spam = array(
454
- 'number'=>100,
455
- 'meta_query' => array(
456
- array(
457
- 'key' => 'ct_marked_as_spam',
458
- 'value' => '1',
459
- 'compare' => 'NUMERIC'
460
- )
461
- )
462
- );
463
- $c_spam = get_comments( $args_spam );
464
-
465
- $args_spam = array(
466
- 'count'=>true,
467
- 'meta_query' => array(
468
- Array(
469
- 'key' => 'ct_marked_as_spam',
470
- 'value' => '1',
471
- 'compare' => 'NUMERIC'
472
- )
473
- )
474
- );
475
- $cnt_all = get_comments($args_spam);
476
-
477
- for( $i=0; $i < sizeof( $c_spam ); $i++ ){
478
- wp_delete_comment( $c_spam[$i]->comment_ID, false );
479
- usleep(10000);
480
- }
481
- print $cnt_all;
482
- die();
483
- }
484
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam;
4
+
5
+ class CommentsChecker extends Checker
6
+ {
7
+
8
+ public function __construct() {
9
+
10
+ parent::__construct();
11
+
12
+ $this->page_title = esc_html__( 'Check comments for spam', 'cleantalk-spam-protect');
13
+ $this->page_script_name = 'edit-comments.php';
14
+ $this->page_slug = 'spam';
15
+
16
+ // Preparing data
17
+ if(!empty($_COOKIE['ct_paused_comments_check']))
18
+ $prev_check = json_decode(stripslashes($_COOKIE['ct_paused_comments_check']), true);
19
+
20
+ wp_enqueue_script( 'ct_comments_checkspam', plugins_url('/cleantalk-spam-protect/js/cleantalk-comments-checkspam.min.js'), array( 'jquery', 'jqueryui' ), APBCT_VERSION );
21
+ wp_localize_script( 'ct_comments_checkspam', 'ctCommentsCheck', array(
22
+ 'ct_ajax_nonce' => wp_create_nonce('ct_secret_nonce'),
23
+ 'ct_prev_accurate' => !empty($prev_check['accurate']) ? true : false,
24
+ 'ct_prev_from' => !empty($prev_check['from']) ? $prev_check['from'] : false,
25
+ 'ct_prev_till' => !empty($prev_check['till']) ? $prev_check['till'] : false,
26
+ 'ct_timeout_confirm' => __('Failed from timeout. Going to check comments again.', 'cleantalk-spam-protect'),
27
+ 'ct_confirm_deletion_all' => __('Delete all spam comments?', 'cleantalk-spam-protect'),
28
+ 'ct_comments_added_after' => __('comments', 'cleantalk-spam-protect'),
29
+ 'ct_status_string' => __('Checked %s, found %s spam comments and %s bad comments (without IP or email).', 'cleantalk-spam-protect'),
30
+ 'ct_status_string_warning' => '<p>'.__('Please do backup of WordPress database before delete any accounts!', 'cleantalk-spam-protect').'</p>',
31
+ 'start' => !empty($_COOKIE['ct_comments_start_check']) ? true : false,
32
+ ));
33
+
34
+ }
35
+
36
+ public function getCurrentScanPage() {
37
+
38
+ $this->list_table = new \Cleantalk\ApbctWP\FindSpam\ListTable\CommentsScan();
39
+
40
+ $this->getCurrentScanPanel( $this );
41
+ echo '<form action="" method="POST">';
42
+ $this->list_table->display();
43
+ echo '</form>';
44
+
45
+ }
46
+
47
+ public function getSpamLogsPage(){
48
+
49
+ $this->list_table = new \Cleantalk\ApbctWP\FindSpam\ListTable\CommentsLogs();
50
+
51
+ echo '<form action="" method="POST">';
52
+ $this->list_table->display();
53
+ echo '</form>';
54
+
55
+ }
56
+
57
+ /**
58
+ * Getting a count of total comments of the website and return formatted string about this.
59
+ *
60
+ * @return string
61
+ */
62
+ public static function get_count_text() {
63
+
64
+ $res = wp_count_comments();
65
+
66
+ if( $res->all ) {
67
+ $text = sprintf( esc_html__ ('Total count of comments: %s.', 'cleantalk-spam-protect' ), $res->all );
68
+ } else {
69
+ $text = esc_html__( 'No comments found.', 'cleantalk-spam-protect' );
70
+ }
71
+
72
+ return $text;
73
+
74
+ }
75
+
76
+ /**
77
+ * Get date last checked comment or date of the first comment
78
+ *
79
+ * @return string date "M j Y"
80
+ */
81
+ public static function lastCheckDate() {
82
+
83
+ global $wpdb;
84
+ $query = "SELECT * FROM " . APBCT_SPAMSCAN_LOGS . " WHERE scan_type = 'comments' ORDER BY start_time DESC";
85
+ $res = $wpdb->get_row( $query, ARRAY_A );
86
+
87
+ if ( $res ) {
88
+
89
+ return date( "M j Y", strtotime( $res['start_time'] ) );
90
+
91
+ } else {
92
+
93
+ $params = array(
94
+ 'fields' => 'ids',
95
+ 'orderby' => 'comment_date_gmt',
96
+ 'order' => 'ASC',
97
+ 'number' => 1
98
+ );
99
+ $first_comment = get_comments( $params );
100
+
101
+ return get_comment_date( "M j Y", current( $first_comment ) );
102
+
103
+ }
104
+
105
+ }
106
+
107
+ public static function ct_ajax_check_comments(){
108
+
109
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
110
+
111
+ global $wpdb, $apbct;
112
+
113
+ if(isset($_POST['from'], $_POST['till'])){
114
+ $from_date = date('Y-m-d', intval(strtotime($_POST['from'])));
115
+ $till_date = date('Y-m-d', intval(strtotime($_POST['till'])));
116
+ }
117
+
118
+ // Gettings comments 100 unchecked comments
119
+ if(isset($_COOKIE['ct_comments_safe_check'])){
120
+ $c = $wpdb->get_results("
121
+ SELECT comment_ID, comment_date_gmt, comment_author_IP, comment_author_email
122
+ FROM {$wpdb->comments} as comm
123
+ WHERE
124
+ (comm.comment_approved = '1' OR comm.comment_approved = '0')
125
+ AND NOT EXISTS(
126
+ SELECT comment_id, meta_key
127
+ FROM {$wpdb->commentmeta} as meta
128
+ WHERE comm.comment_ID = meta.comment_id AND (meta_key = 'ct_checked' OR meta_key = 'ct_bad')
129
+ )
130
+ ORDER BY comment_date_gmt
131
+ LIMIT 100",
132
+ ARRAY_A
133
+ );
134
+ }else{
135
+ $params = array(
136
+ 'meta_query' => array(
137
+ 'relation' => 'AND',
138
+ array(
139
+ 'key' => 'ct_checked_now',
140
+ 'compare' => 'NOT EXISTS'
141
+ ),
142
+ array(
143
+ 'key' => 'ct_checked',
144
+ 'compare' => 'NOT EXISTS'
145
+ ),
146
+ array(
147
+ 'key' => 'ct_bad',
148
+ 'compare' => 'NOT EXISTS'
149
+ )
150
+ ),
151
+ 'orderby' => 'comment_date_gmt',
152
+ 'order' => 'ASC',
153
+ 'number' => 100
154
+ );
155
+ if(isset($from_date, $till_date)){
156
+ $params['date_query'] = array(
157
+ 'column' => 'comment_date_gmt',
158
+ 'after' => $from_date,
159
+ 'before' => $till_date,
160
+ 'inclusive' => true,
161
+ );
162
+ }
163
+ $c = get_comments( $params );
164
+ }
165
+
166
+ $check_result = array(
167
+ 'end' => 0,
168
+ 'checked' => 0,
169
+ 'spam' => 0,
170
+ 'bad' => 0,
171
+ 'error' => 0
172
+ );
173
+
174
+ if(sizeof($c)>0){
175
+
176
+ // Coverting $c to objects
177
+ if(is_array($c[0])){
178
+ foreach($c as $key => $value){
179
+ $c[$key] = (object)$value;
180
+ } unset($key, $value);
181
+ }
182
+
183
+ if(!empty($_POST['accurate_check'])){
184
+ // Leaving comments only with first comment's date. Unsetting others.
185
+
186
+ foreach($c as $comment_index => $comment){
187
+
188
+ if(!isset($curr_date))
189
+ $curr_date = (substr($comment->comment_date_gmt, 0, 10) ? substr($comment->comment_date_gmt, 0, 10) : '');
190
+
191
+ if(substr($comment->comment_date_gmt, 0, 10) != $curr_date)
192
+ unset($c[$comment_index]);
193
+
194
+ }
195
+ unset($comment_index, $comment);
196
+ }
197
+
198
+ // Checking comments IP/Email. Gathering $data for check.
199
+ $data = Array();
200
+ for($i=0;$i<sizeof($c);$i++){
201
+
202
+ $curr_ip = $c[$i]->comment_author_IP;
203
+ $curr_email = $c[$i]->comment_author_email;
204
+
205
+ // Check for identity
206
+ $curr_ip = preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $curr_ip) === 1 ? $curr_ip : null;
207
+ $curr_email = preg_match('/^\S+@\S+\.\S+$/', $curr_email) === 1 ? $curr_email : null;
208
+
209
+ if(empty($curr_ip) && empty($curr_email)){
210
+ $check_result['bad']++;
211
+ update_comment_meta($c[$i]->comment_ID,'ct_bad','1');
212
+ update_comment_meta($c[$i]->comment_ID,'ct_checked','1');
213
+ update_comment_meta($c[$i]->comment_ID,'ct_checked_now','1');
214
+ unset($c[$i]);
215
+ }else{
216
+ if(!empty($curr_ip))
217
+ $data[] = $curr_ip;
218
+ if(!empty($curr_email))
219
+ $data[] = $curr_email;
220
+ // Patch for empty IP/Email
221
+ $c[$i]->comment_author_IP = empty($curr_ip) ? 'none' : $curr_ip;
222
+ $c[$i]->comment_author_email = empty($curr_email) ? 'none' : $curr_email;
223
+ }
224
+ }
225
+
226
+ // Recombining after checking and unsettting
227
+ $c = array_values($c);
228
+
229
+ // Drop if data empty and there's no comments to check
230
+ if(count($data) == 0){
231
+ if($_POST['unchecked'] === 0)
232
+ $check_result['end'] = 1;
233
+ print json_encode($check_result);
234
+ die();
235
+ }
236
+
237
+ $result = \Cleantalk\ApbctWP\API::method__spam_check_cms($apbct->api_key, $data, !empty($_POST['accurate_check']) ? $curr_date : null);
238
+
239
+ if(empty($result['error'])){
240
+
241
+ for($i=0;$i<sizeof($c);$i++){
242
+
243
+ $mark_spam_ip = false;
244
+ $mark_spam_email = false;
245
+
246
+ $check_result['checked']++;
247
+ update_comment_meta($c[$i]->comment_ID,'ct_checked',date("Y-m-d H:m:s"));
248
+ update_comment_meta( $c[$i]->comment_ID, 'ct_checked_now', date("Y-m-d H:m:s"), true) ;
249
+
250
+ $uip=$c[$i]->comment_author_IP;
251
+ $uim=$c[$i]->comment_author_email;
252
+
253
+ if(isset($result[$uip]) && $result[$uip]['appears'] == 1)
254
+ $mark_spam_ip = true;
255
+
256
+ if(isset($result[$uim]) && $result[$uim]['appears'] == 1)
257
+ $mark_spam_email = true;
258
+
259
+ if ($mark_spam_ip || $mark_spam_email){
260
+ $check_result['spam']++;
261
+ update_comment_meta($c[$i]->comment_ID,'ct_marked_as_spam','1');
262
+ }
263
+ }
264
+ print json_encode($check_result);
265
+
266
+ }else{
267
+ $check_result['error'] = 1;
268
+ $check_result['error_message'] = $result['error'];
269
+ echo json_encode($check_result);
270
+ }
271
+ }else{
272
+
273
+ $check_result['end'] = 1;
274
+
275
+ $log_data = static::get_log_data();
276
+ static::writeSpamLog( 'comments', date("Y-m-d H:i:s"), $log_data['checked'], $log_data['spam'], $log_data['bad'] );
277
+
278
+ print json_encode($check_result);
279
+
280
+ }
281
+
282
+ die;
283
+ }
284
+
285
+ public static function ct_ajax_info($direct_call = false){
286
+
287
+ if (!$direct_call)
288
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
289
+
290
+ // Checked comments
291
+ $params_checked = array(
292
+ 'meta_key' => 'ct_checked_now',
293
+ 'orderby' => 'ct_checked_now'
294
+ );
295
+ $checked_comments = new \WP_Comment_Query($params_checked);
296
+ $cnt_checked = count( $checked_comments->get_comments() );
297
+
298
+ // Spam comments
299
+ $params_spam = array(
300
+ 'meta_query' => array(
301
+ 'relation' => 'AND',
302
+ array(
303
+ 'key' => 'ct_marked_as_spam',
304
+ 'compare' => 'EXISTS'
305
+ ),
306
+ array(
307
+ 'key' => 'ct_checked_now',
308
+ 'compare' => 'EXISTS'
309
+ ),
310
+ ),
311
+ );
312
+ $spam_comments = new \WP_Comment_Query($params_spam);
313
+ $cnt_spam = count( $spam_comments->get_comments() );
314
+
315
+ // Bad comments (without IP and Email)
316
+ $params_bad = array(
317
+ 'meta_query' => array(
318
+ 'relation' => 'AND',
319
+ array(
320
+ 'key' => 'ct_bad',
321
+ 'compare' => 'EXISTS'
322
+ ),
323
+ array(
324
+ 'key' => 'ct_checked_now',
325
+ 'compare' => 'EXISTS'
326
+ ),
327
+ ),
328
+ );
329
+ $bad_comments = new \WP_Comment_Query($params_bad);
330
+ $cnt_bad = count( $bad_comments->get_comments() );
331
+
332
+ $return = array(
333
+ 'message' => '',
334
+ 'spam' => $cnt_spam,
335
+ 'checked' => $cnt_checked,
336
+ 'bad' => $cnt_bad,
337
+ );
338
+
339
+ if( ! $direct_call ) {
340
+ $return['message'] .= sprintf (
341
+ esc_html__('Checked %s, found %s spam comments and %s bad comments (without IP or email)', 'cleantalk-spam-protect'),
342
+ $cnt_checked,
343
+ $cnt_spam,
344
+ $cnt_bad
345
+ );
346
+ } else {
347
+
348
+ global $wpdb;
349
+
350
+ $query = "SELECT * FROM " . APBCT_SPAMSCAN_LOGS . " WHERE scan_type = 'comments' ORDER BY start_time DESC";
351
+ $res = $wpdb->get_row( $query, ARRAY_A );
352
+
353
+ if ( $res ) {
354
+
355
+ $return['message'] .= sprintf (
356
+ __("Last check %s: checked %s comments, found %s spam comments and %s bad comments (without IP or email).", 'cleantalk-spam-protect'),
357
+ self::lastCheckDate(),
358
+ $cnt_checked,
359
+ $cnt_spam,
360
+ $cnt_bad
361
+ );
362
+
363
+ } else {
364
+ // Never checked
365
+ $return['message'] = esc_html__( 'Never checked yet or no new spam.', 'cleantalk-spam-protect');
366
+ }
367
+
368
+ }
369
+
370
+ $backup_notice = '&nbsp;';
371
+ if ($cnt_spam > 0){
372
+ $backup_notice = __("Please do backup of WordPress database before delete any comments!", 'cleantalk-spam-protect');
373
+ }
374
+ $return['message'] .= "<p>$backup_notice</p>";
375
+
376
+ if($direct_call){
377
+ return $return['message'];
378
+ }else{
379
+ echo json_encode($return);
380
+ die();
381
+ }
382
+
383
+ }
384
+
385
+ public static function ct_ajax_clear_comments(){
386
+
387
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
388
+
389
+ global $wpdb;
390
+ $wpdb->query("DELETE FROM {$wpdb->commentmeta} WHERE meta_key IN ('ct_checked_now')");
391
+
392
+ if ( isset($_POST['from']) && isset($_POST['till']) ) {
393
+ if ( preg_match('/[a-zA-Z]{3}\s{1}\d{1,2}\s{1}\d{4}/', $_POST['from'] ) && preg_match('/[a-zA-Z]{3}\s{1}\d{1,2}\s{1}\d{4}/', $_POST['till'] ) ) {
394
+
395
+ $from = date('Y-m-d', intval(strtotime($_POST['from']))) . ' 00:00:00';
396
+ $till = date('Y-m-d', intval(strtotime($_POST['till']))) . ' 23:59:59';
397
+
398
+ $wpdb->query("DELETE FROM {$wpdb->commentmeta} WHERE
399
+ meta_key IN ('ct_checked','ct_marked_as_spam','ct_bad')
400
+ AND meta_value >= '{$from}'
401
+ AND meta_value <= '{$till}';");
402
+ die();
403
+
404
+ } else {
405
+ $wpdb->query("DELETE FROM {$wpdb->commentmeta} WHERE
406
+ meta_key IN ('ct_checked','ct_marked_as_spam','ct_bad')");
407
+ die();
408
+ }
409
+ }
410
+
411
+ }
412
+
413
+ private static function get_log_data() {
414
+
415
+ // Checked users
416
+ $params_spam = array(
417
+ 'meta_key' => 'ct_checked_now',
418
+ );
419
+ $spam_comments = new \WP_Comment_Query($params_spam);
420
+ $cnt_checked = count( $spam_comments->get_comments() );
421
+
422
+ // Spam users
423
+ $params_spam = array(
424
+ 'meta_query' => array(
425
+ 'relation' => 'AND',
426
+ array(
427
+ 'key' => 'ct_marked_as_spam',
428
+ 'compare' => 'EXISTS'
429
+ ),
430
+ array(
431
+ 'key' => 'ct_checked_now',
432
+ 'compare' => 'EXISTS'
433
+ ),
434
+ ),
435
+ );
436
+ $spam_comments = new \WP_Comment_Query($params_spam);
437
+ $cnt_spam = count( $spam_comments->get_comments() );
438
+
439
+ // Bad users (without IP and Email)
440
+ $params_bad = array(
441
+ 'meta_query' => array(
442
+ 'relation' => 'AND',
443
+ array(
444
+ 'key' => 'ct_bad',
445
+ 'compare' => 'EXISTS'
446
+ ),
447
+ array(
448
+ 'key' => 'ct_checked_now',
449
+ 'compare' => 'EXISTS'
450
+ ),
451
+ ),
452
+ );
453
+ $spam_comments = new \WP_Comment_Query($params_bad);
454
+ $cnt_bad = count( $spam_comments->get_comments() );
455
+
456
+ return array(
457
+ 'spam' => $cnt_spam,
458
+ 'checked' => $cnt_checked,
459
+ 'bad' => $cnt_bad,
460
+ );
461
+
462
+ }
463
+
464
+ public static function ct_ajax_delete_all(){
465
+
466
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
467
+
468
+ $args_spam = array(
469
+ 'number'=>100,
470
+ 'meta_query' => array(
471
+ array(
472
+ 'key' => 'ct_marked_as_spam',
473
+ 'value' => '1',
474
+ 'compare' => 'NUMERIC'
475
+ )
476
+ )
477
+ );
478
+ $c_spam = get_comments( $args_spam );
479
+
480
+ $args_spam = array(
481
+ 'count'=>true,
482
+ 'meta_query' => array(
483
+ Array(
484
+ 'key' => 'ct_marked_as_spam',
485
+ 'value' => '1',
486
+ 'compare' => 'NUMERIC'
487
+ )
488
+ )
489
+ );
490
+ $cnt_all = get_comments($args_spam);
491
+
492
+ for( $i=0; $i < sizeof( $c_spam ); $i++ ){
493
+ wp_delete_comment( $c_spam[$i]->comment_ID, false );
494
+ usleep(10000);
495
+ }
496
+ print $cnt_all;
497
+ die();
498
+ }
499
+
500
  }
inc/find-spam/ClassCleantalkCommentsListTable.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/Comments.php RENAMED
@@ -1,307 +1,308 @@
1
- <?php
2
-
3
-
4
- class ABPCTCommentsListTable extends ABPCT_List_Table
5
- {
6
- protected $apbct;
7
-
8
- function __construct(){
9
-
10
- parent::__construct(array(
11
- 'singular' => 'spam',
12
- 'plural' => 'spam'
13
- ));
14
-
15
- $this->bulk_actions_handler();
16
-
17
- $this->row_actions_handler();
18
-
19
- $this->prepare_items();
20
-
21
- global $apbct;
22
- $this->apbct = $apbct;
23
-
24
- }
25
- // Set columns
26
- function get_columns(){
27
- return array(
28
- 'cb' => '<input type="checkbox" />',
29
- 'ct_author' => esc_html__( 'Author', 'cleantalk-spam-protect'),
30
- 'ct_comment' => esc_html__( 'Comment', 'cleantalk-spam-protect'),
31
- 'ct_response_to' => esc_html__( ' In Response To', 'cleantalk-spam-protect'),
32
- );
33
- }
34
-
35
- // CheckBox column
36
- function column_cb( $item ){
37
- echo '<input type="checkbox" name="spamids[]" id="cb-select-'. $item['ct_id'] .'" value="'. $item['ct_id'] .'" />';
38
- }
39
-
40
- // Author (first) column
41
- function column_ct_author( $item ) {
42
-
43
- $column_content = '';
44
- $email = $item['ct_comment']->comment_author_email;
45
- $ip = $item['ct_comment']->comment_author_IP;
46
-
47
- // Avatar, nickname
48
- $column_content .= '<strong>'. $item['ct_comment']->comment_author . '</strong>';
49
- $column_content .= '<br /><br />';
50
-
51
- // Email
52
- if( ! empty( $email ) ){
53
- $column_content .= "<a href='mailto:$email'>$email</a>"
54
- .( ! $this->apbct->white_label
55
- ? "<a href='https://cleantalk.org/blacklists/$email' target='_blank'>"
56
- ."&nbsp;<img src='" . APBCT_URL_PATH . "/inc/images/new_window.gif' alt='Ico: open in new window' border='0' style='float:none' />"
57
- ."</a>"
58
- : '');
59
- } else {
60
- $column_content .= esc_html__( 'No email', 'cleantalk-spam-protect');
61
- }
62
-
63
- $column_content .= '<br/>';
64
-
65
- // IP
66
- if( ! empty( $ip ) ) {
67
- $column_content .= "<a href='edit-comments.php?s=$ip&mode=detail'>$ip</a>"
68
- .( ! $this->apbct->white_label
69
- ?"<a href='https://cleantalk.org/blacklists/$ip ' target='_blank'>"
70
- ."&nbsp;<img src='" . APBCT_URL_PATH . "/inc/images/new_window.gif' alt='Ico: open in new window' border='0' style='float:none' />"
71
- ."</a>"
72
- : '');
73
- }else
74
- $column_content .= esc_html__( 'No IP adress', 'cleantalk-spam-protect');
75
-
76
- return $column_content;
77
-
78
- }
79
-
80
- function column_ct_comment( $item ){
81
-
82
- $id = $item['ct_id'];
83
- $column_content = '';
84
-
85
- $column_content .= '<div class="column-comment">';
86
-
87
- $column_content .= '<div class="submitted-on">';
88
-
89
- $column_content .= sprintf( __( 'Submitted on <a href="%1$s">%2$s at %3$s</a>' ), get_comment_link($id),
90
- get_comment_date( __( 'Y/m/d' ),$id ),
91
- get_comment_date( get_option( 'time_format' ),$id )
92
- );
93
-
94
- $column_content .= '</div>';
95
-
96
- $column_content .= '<p>' . $item['ct_comment']->comment_content . '</p>';
97
-
98
- $column_content .= '</div>';
99
-
100
- $actions = array(
101
- 'approve' => sprintf( '<span class="approve"><a href="?page=%s&action=%s&spam=%s">Approve</a></span>', $_REQUEST['page'],'approve', $id ),
102
- 'delete' => sprintf( '<a href="?page=%s&action=%s&spam=%s">Delete</a>', $_REQUEST['page'],'delete', $id ),
103
- );
104
-
105
- return sprintf( '%1$s %2$s', $column_content, $this->row_actions( $actions ) );
106
-
107
- }
108
-
109
- function column_ct_response_to( $item ) {
110
- $post_id = $item['ct_response_to'];
111
- ?>
112
- <div>
113
- <span>
114
- <a href="/wp-admin/post.php?post=<?php echo $post_id; ?>&action=edit"><?php print get_the_title( $post_id ); ?></a>
115
- <br/>
116
- <a href="/wp-admin/edit-comments.php?p=<?php echo $post_id; ?>" class="post-com-count">
117
- <span class="comment-count"><?php
118
- $p_cnt = wp_count_comments( $post_id );
119
- echo $p_cnt->total_comments;
120
- ?></span>
121
- </a>
122
- </span>
123
- <a href="<?php print get_permalink( $post_id ); ?>"><?php _e( 'View Post' );?></a>
124
- </div>
125
- <?php
126
- }
127
-
128
- // Rest of columns
129
- function column_default( $item, $column_name ) {
130
- switch( $column_name ) {
131
- case 'ct_author':
132
- case 'ct_comment':
133
- case 'ct_response_to':
134
- case 'ct_start':
135
- case 'ct_checked':
136
- case 'ct_spam':
137
- case 'ct_bad':
138
- return $item[ $column_name ];
139
- default:
140
- return print_r( $item, true ) ;
141
- }
142
- }
143
-
144
- function get_bulk_actions() {
145
- $actions = array(
146
- 'delete' => 'Delete'
147
- );
148
- return $actions;
149
- }
150
-
151
- function bulk_actions_handler() {
152
-
153
- if( empty($_POST['spamids']) || empty($_POST['_wpnonce']) ) return;
154
-
155
- if ( ! $action = $this->current_action() ) return;
156
-
157
- if( ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-' . $this->_args['plural'] ) )
158
- wp_die('nonce error');
159
-
160
- if( 'delete' == $action ) {
161
- $this->removeSpam( $_POST['spamids'] );
162
- }
163
-
164
- }
165
-
166
- function row_actions_handler() {
167
-
168
- if( empty($_GET['action']) ) return;
169
-
170
- if( $_GET['action'] == 'approve' ) {
171
-
172
- $id = filter_input( INPUT_GET, 'spam', FILTER_SANITIZE_NUMBER_INT );
173
- $this->approveSpam( $id );
174
-
175
- }
176
-
177
- if( $_GET['action'] == 'delete' ) {
178
-
179
- $id = filter_input( INPUT_GET, 'spam', FILTER_SANITIZE_NUMBER_INT );
180
- $this->removeSpam( array( $id ) );
181
-
182
- }
183
-
184
- }
185
-
186
- function no_items() {
187
- esc_html_e( 'No spam found.', 'cleantalk-spam-protect');
188
- }
189
-
190
- //********************************************//
191
- // LOGIC //
192
- //*******************************************//
193
-
194
- function approveSpam( $id ) {
195
-
196
- $comment_meta = delete_comment_meta( $id, 'ct_marked_as_spam' );
197
-
198
- if( $comment_meta ) {
199
-
200
- $comment = get_comment($id, 'ARRAY_A');
201
- $comment['comment_approved'] = 1;
202
-
203
- wp_update_comment( $comment );
204
- apbct_comment__send_feedback( $id, 'approve', false, true );
205
-
206
- }
207
-
208
- }
209
-
210
- function removeSpam( $ids ) {
211
-
212
- $ids_string = implode( ', ', $ids );
213
- global $wpdb;
214
-
215
- $wpdb->query("DELETE FROM {$wpdb->comments} WHERE
216
- comment_ID IN ($ids_string)");
217
-
218
- }
219
-
220
- public function getTotal() {
221
-
222
- $total_comments = new WP_Comment_Query();
223
- return $total_comments;
224
-
225
- }
226
-
227
- public function getChecked() {
228
-
229
- $params_spam = array(
230
- 'meta_key' => 'ct_checked',
231
- );
232
- $spam_comments = new WP_Comment_Query($params_spam);
233
- return $spam_comments;
234
-
235
- }
236
-
237
- public function getCheckedNow() {
238
-
239
- $params_spam = array(
240
- 'meta_key' => 'ct_checked_now',
241
- );
242
- $spam_comments = new WP_Comment_Query($params_spam);
243
- return $spam_comments;
244
-
245
- }
246
-
247
- public function getSpam() {
248
-
249
- $params_spam = array(
250
- 'meta_key' => 'ct_marked_as_spam',
251
- );
252
- $spam_comments = new WP_Comment_Query($params_spam);
253
- return $spam_comments;
254
-
255
- }
256
-
257
- public function getSpamNow() {
258
-
259
- // Spam comments
260
- $params_spam = array(
261
- 'meta_query' => array(
262
- 'relation' => 'AND',
263
- array(
264
- 'key' => 'ct_marked_as_spam',
265
- 'compare' => 'EXISTS'
266
- ),
267
- array(
268
- 'key' => 'ct_checked_now',
269
- 'compare' => 'EXISTS'
270
- ),
271
- )
272
- );
273
- $spam_comments = new WP_Comment_Query($params_spam);
274
- return $spam_comments;
275
-
276
- }
277
-
278
- public function getBad() { // Without IP and EMAIL
279
-
280
- $params_bad = array(
281
- 'meta_key' => 'ct_bad',
282
- );
283
- $bad_users = new WP_Comment_Query($params_bad);
284
- return $bad_users;
285
-
286
- }
287
-
288
- public function getScansLogs() {
289
-
290
- global $wpdb;
291
- $query = "SELECT * FROM " . APBCT_SPAMSCAN_LOGS . " WHERE scan_type = 'comments'";
292
- $res = $wpdb->get_results( $query, ARRAY_A );
293
- return $res;
294
-
295
- }
296
-
297
- protected function removeLogs( $ids ) {
298
-
299
- $ids_string = implode( ', ', $ids );
300
- global $wpdb;
301
-
302
- $wpdb->query("DELETE FROM " . APBCT_SPAMSCAN_LOGS . " WHERE
303
- ID IN ($ids_string)");
304
-
305
- }
306
-
 
307
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam\ListTable;
4
+
5
+ class Comments extends \Cleantalk\ApbctWP\CleantalkListTable
6
+ {
7
+ protected $apbct;
8
+
9
+ function __construct(){
10
+
11
+ parent::__construct(array(
12
+ 'singular' => 'spam',
13
+ 'plural' => 'spam'
14
+ ));
15
+
16
+ $this->bulk_actions_handler();
17
+
18
+ $this->row_actions_handler();
19
+
20
+ $this->prepare_items();
21
+
22
+ global $apbct;
23
+ $this->apbct = $apbct;
24
+
25
+ }
26
+ // Set columns
27
+ function get_columns(){
28
+ return array(
29
+ 'cb' => '<input type="checkbox" />',
30
+ 'ct_author' => esc_html__( 'Author', 'cleantalk-spam-protect'),
31
+ 'ct_comment' => esc_html__( 'Comment', 'cleantalk-spam-protect'),
32
+ 'ct_response_to' => esc_html__( ' In Response To', 'cleantalk-spam-protect'),
33
+ );
34
+ }
35
+
36
+ // CheckBox column
37
+ function column_cb( $item ){
38
+ echo '<input type="checkbox" name="spamids[]" id="cb-select-'. $item['ct_id'] .'" value="'. $item['ct_id'] .'" />';
39
+ }
40
+
41
+ // Author (first) column
42
+ function column_ct_author( $item ) {
43
+
44
+ $column_content = '';
45
+ $email = $item['ct_comment']->comment_author_email;
46
+ $ip = $item['ct_comment']->comment_author_IP;
47
+
48
+ // Avatar, nickname
49
+ $column_content .= '<strong>'. $item['ct_comment']->comment_author . '</strong>';
50
+ $column_content .= '<br /><br />';
51
+
52
+ // Email
53
+ if( ! empty( $email ) ){
54
+ $column_content .= "<a href='mailto:$email'>$email</a>"
55
+ .( ! $this->apbct->white_label
56
+ ? "<a href='https://cleantalk.org/blacklists/$email' target='_blank'>"
57
+ ."&nbsp;<img src='" . APBCT_URL_PATH . "/inc/images/new_window.gif' alt='Ico: open in new window' border='0' style='float:none' />"
58
+ ."</a>"
59
+ : '');
60
+ } else {
61
+ $column_content .= esc_html__( 'No email', 'cleantalk-spam-protect');
62
+ }
63
+
64
+ $column_content .= '<br/>';
65
+
66
+ // IP
67
+ if( ! empty( $ip ) ) {
68
+ $column_content .= "<a href='edit-comments.php?s=$ip&mode=detail'>$ip</a>"
69
+ .( ! $this->apbct->white_label
70
+ ?"<a href='https://cleantalk.org/blacklists/$ip ' target='_blank'>"
71
+ ."&nbsp;<img src='" . APBCT_URL_PATH . "/inc/images/new_window.gif' alt='Ico: open in new window' border='0' style='float:none' />"
72
+ ."</a>"
73
+ : '');
74
+ }else
75
+ $column_content .= esc_html__( 'No IP adress', 'cleantalk-spam-protect');
76
+
77
+ return $column_content;
78
+
79
+ }
80
+
81
+ function column_ct_comment( $item ){
82
+
83
+ $id = $item['ct_id'];
84
+ $column_content = '';
85
+
86
+ $column_content .= '<div class="column-comment">';
87
+
88
+ $column_content .= '<div class="submitted-on">';
89
+
90
+ $column_content .= sprintf( __( 'Submitted on <a href="%1$s">%2$s at %3$s</a>' ), get_comment_link($id),
91
+ get_comment_date( __( 'Y/m/d' ),$id ),
92
+ get_comment_date( get_option( 'time_format' ),$id )
93
+ );
94
+
95
+ $column_content .= '</div>';
96
+
97
+ $column_content .= '<p>' . $item['ct_comment']->comment_content . '</p>';
98
+
99
+ $column_content .= '</div>';
100
+
101
+ $actions = array(
102
+ 'approve' => sprintf( '<span class="approve"><a href="?page=%s&action=%s&spam=%s">Approve</a></span>', $_REQUEST['page'],'approve', $id ),
103
+ 'delete' => sprintf( '<a href="?page=%s&action=%s&spam=%s">Delete</a>', $_REQUEST['page'],'delete', $id ),
104
+ );
105
+
106
+ return sprintf( '%1$s %2$s', $column_content, $this->row_actions( $actions ) );
107
+
108
+ }
109
+
110
+ function column_ct_response_to( $item ) {
111
+ $post_id = $item['ct_response_to'];
112
+ ?>
113
+ <div>
114
+ <span>
115
+ <a href="/wp-admin/post.php?post=<?php echo $post_id; ?>&action=edit"><?php print get_the_title( $post_id ); ?></a>
116
+ <br/>
117
+ <a href="/wp-admin/edit-comments.php?p=<?php echo $post_id; ?>" class="post-com-count">
118
+ <span class="comment-count"><?php
119
+ $p_cnt = wp_count_comments( $post_id );
120
+ echo $p_cnt->total_comments;
121
+ ?></span>
122
+ </a>
123
+ </span>
124
+ <a href="<?php print get_permalink( $post_id ); ?>"><?php _e( 'View Post' );?></a>
125
+ </div>
126
+ <?php
127
+ }
128
+
129
+ // Rest of columns
130
+ function column_default( $item, $column_name ) {
131
+ switch( $column_name ) {
132
+ case 'ct_author':
133
+ case 'ct_comment':
134
+ case 'ct_response_to':
135
+ case 'ct_start':
136
+ case 'ct_checked':
137
+ case 'ct_spam':
138
+ case 'ct_bad':
139
+ return $item[ $column_name ];
140
+ default:
141
+ return print_r( $item, true ) ;
142
+ }
143
+ }
144
+
145
+ function get_bulk_actions() {
146
+ $actions = array(
147
+ 'delete' => 'Delete'
148
+ );
149
+ return $actions;
150
+ }
151
+
152
+ function bulk_actions_handler() {
153
+
154
+ if( empty($_POST['spamids']) || empty($_POST['_wpnonce']) ) return;
155
+
156
+ if ( ! $action = $this->current_action() ) return;
157
+
158
+ if( ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-' . $this->_args['plural'] ) )
159
+ wp_die('nonce error');
160
+
161
+ if( 'delete' == $action ) {
162
+ $this->removeSpam( $_POST['spamids'] );
163
+ }
164
+
165
+ }
166
+
167
+ function row_actions_handler() {
168
+
169
+ if( empty($_GET['action']) ) return;
170
+
171
+ if( $_GET['action'] == 'approve' ) {
172
+
173
+ $id = filter_input( INPUT_GET, 'spam', FILTER_SANITIZE_NUMBER_INT );
174
+ $this->approveSpam( $id );
175
+
176
+ }
177
+
178
+ if( $_GET['action'] == 'delete' ) {
179
+
180
+ $id = filter_input( INPUT_GET, 'spam', FILTER_SANITIZE_NUMBER_INT );
181
+ $this->removeSpam( array( $id ) );
182
+
183
+ }
184
+
185
+ }
186
+
187
+ function no_items() {
188
+ esc_html_e( 'No spam found.', 'cleantalk-spam-protect');
189
+ }
190
+
191
+ //********************************************//
192
+ // LOGIC //
193
+ //*******************************************//
194
+
195
+ function approveSpam( $id ) {
196
+
197
+ $comment_meta = delete_comment_meta( $id, 'ct_marked_as_spam' );
198
+
199
+ if( $comment_meta ) {
200
+
201
+ $comment = get_comment($id, 'ARRAY_A');
202
+ $comment['comment_approved'] = 1;
203
+
204
+ wp_update_comment( $comment );
205
+ apbct_comment__send_feedback( $id, 'approve', false, true );
206
+
207
+ }
208
+
209
+ }
210
+
211
+ function removeSpam( $ids ) {
212
+
213
+ $ids_string = implode( ', ', $ids );
214
+ global $wpdb;
215
+
216
+ $wpdb->query("DELETE FROM {$wpdb->comments} WHERE
217
+ comment_ID IN ($ids_string)");
218
+
219
+ }
220
+
221
+ public function getTotal() {
222
+
223
+ $total_comments = new \WP_Comment_Query();
224
+ return $total_comments;
225
+
226
+ }
227
+
228
+ public function getChecked() {
229
+
230
+ $params_spam = array(
231
+ 'meta_key' => 'ct_checked',
232
+ );
233
+ $spam_comments = new \WP_Comment_Query($params_spam);
234
+ return $spam_comments;
235
+
236
+ }
237
+
238
+ public function getCheckedNow() {
239
+
240
+ $params_spam = array(
241
+ 'meta_key' => 'ct_checked_now',
242
+ );
243
+ $spam_comments = new \WP_Comment_Query($params_spam);
244
+ return $spam_comments;
245
+
246
+ }
247
+
248
+ public function getSpam() {
249
+
250
+ $params_spam = array(
251
+ 'meta_key' => 'ct_marked_as_spam',
252
+ );
253
+ $spam_comments = new \WP_Comment_Query($params_spam);
254
+ return $spam_comments;
255
+
256
+ }
257
+
258
+ public function getSpamNow() {
259
+
260
+ // Spam comments
261
+ $params_spam = array(
262
+ 'meta_query' => array(
263
+ 'relation' => 'AND',
264
+ array(
265
+ 'key' => 'ct_marked_as_spam',
266
+ 'compare' => 'EXISTS'
267
+ ),
268
+ array(
269
+ 'key' => 'ct_checked_now',
270
+ 'compare' => 'EXISTS'
271
+ ),
272
+ )
273
+ );
274
+ $spam_comments = new \WP_Comment_Query($params_spam);
275
+ return $spam_comments;
276
+
277
+ }
278
+
279
+ public function getBad() { // Without IP and EMAIL
280
+
281
+ $params_bad = array(
282
+ 'meta_key' => 'ct_bad',
283
+ );
284
+ $bad_users = new \WP_Comment_Query($params_bad);
285
+ return $bad_users;
286
+
287
+ }
288
+
289
+ public function getScansLogs() {
290
+
291
+ global $wpdb;
292
+ $query = "SELECT * FROM " . APBCT_SPAMSCAN_LOGS . " WHERE scan_type = 'comments'";
293
+ $res = $wpdb->get_results( $query, ARRAY_A );
294
+ return $res;
295
+
296
+ }
297
+
298
+ protected function removeLogs( $ids ) {
299
+
300
+ $ids_string = implode( ', ', $ids );
301
+ global $wpdb;
302
+
303
+ $wpdb->query("DELETE FROM " . APBCT_SPAMSCAN_LOGS . " WHERE
304
+ ID IN ($ids_string)");
305
+
306
+ }
307
+
308
  }
inc/find-spam/ClassCleantalkCommentsListTableLogs.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/CommentsLogs.php RENAMED
@@ -1,63 +1,64 @@
1
- <?php
2
-
3
-
4
- class ABPCTCommentsListTableLogs extends ABPCTCommentsListTable
5
- {
6
-
7
- // Set columns
8
- function get_columns(){
9
- return array(
10
- 'cb' => '<input type="checkbox" />',
11
- 'ct_start' => esc_html__( 'Start time', 'cleantalk-spam-protect'),
12
- 'ct_checked' => esc_html__( 'Checked', 'cleantalk-spam-protect'),
13
- 'ct_spam' => esc_html__( 'Found spam', 'cleantalk-spam-protect'),
14
- 'ct_bad' => esc_html__( 'Found bad', 'cleantalk-spam-protect'),
15
- );
16
- }
17
-
18
- function prepare_items(){
19
-
20
- $columns = $this->get_columns();
21
- $this->_column_headers = array( $columns, array(), array() );
22
-
23
- $logs = $this->getScansLogs();
24
-
25
- foreach( $logs as $log ) {
26
-
27
- $this->items[] = array(
28
- 'ct_id' => $log['id'],
29
- 'ct_start' => $log['start_time'],
30
- 'ct_checked' => $log['count_to_scan'],
31
- 'ct_spam' => $log['found_spam'],
32
- 'ct_bad' => $log['found_bad'],
33
- );
34
-
35
- }
36
-
37
- }
38
-
39
- function get_bulk_actions() {
40
- $actions = array(
41
- 'delete' => 'Delete'
42
- );
43
- return $actions;
44
- }
45
-
46
- function bulk_actions_handler() {
47
-
48
- if( empty($_POST['spamids']) || empty($_POST['_wpnonce']) ) return;
49
-
50
- if ( ! $action = $this->current_action() ) return;
51
-
52
- if( ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-' . $this->_args['plural'] ) )
53
- wp_die('nonce error');
54
-
55
- $this->removeLogs( $_POST['spamids'] );
56
-
57
- }
58
-
59
- function no_items() {
60
- esc_html_e( 'No logs found.', 'cleantalk-spam-protect');
61
- }
62
-
 
63
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam\ListTable;
4
+
5
+ class CommentsLogs extends Comments
6
+ {
7
+
8
+ // Set columns
9
+ function get_columns(){
10
+ return array(
11
+ 'cb' => '<input type="checkbox" />',
12
+ 'ct_start' => esc_html__( 'Start time', 'cleantalk-spam-protect'),
13
+ 'ct_checked' => esc_html__( 'Checked', 'cleantalk-spam-protect'),
14
+ 'ct_spam' => esc_html__( 'Found spam', 'cleantalk-spam-protect'),
15
+ 'ct_bad' => esc_html__( 'Found bad', 'cleantalk-spam-protect'),
16
+ );
17
+ }
18
+
19
+ function prepare_items(){
20
+
21
+ $columns = $this->get_columns();
22
+ $this->_column_headers = array( $columns, array(), array() );
23
+
24
+ $logs = $this->getScansLogs();
25
+
26
+ foreach( $logs as $log ) {
27
+
28
+ $this->items[] = array(
29
+ 'ct_id' => $log['id'],
30
+ 'ct_start' => $log['start_time'],
31
+ 'ct_checked' => $log['count_to_scan'],
32
+ 'ct_spam' => $log['found_spam'],
33
+ 'ct_bad' => $log['found_bad'],
34
+ );
35
+
36
+ }
37
+
38
+ }
39
+
40
+ function get_bulk_actions() {
41
+ $actions = array(
42
+ 'delete' => 'Delete'
43
+ );
44
+ return $actions;
45
+ }
46
+
47
+ function bulk_actions_handler() {
48
+
49
+ if( empty($_POST['spamids']) || empty($_POST['_wpnonce']) ) return;
50
+
51
+ if ( ! $action = $this->current_action() ) return;
52
+
53
+ if( ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-' . $this->_args['plural'] ) )
54
+ wp_die('nonce error');
55
+
56
+ $this->removeLogs( $_POST['spamids'] );
57
+
58
+ }
59
+
60
+ function no_items() {
61
+ esc_html_e( 'No logs found.', 'cleantalk-spam-protect');
62
+ }
63
+
64
  }
inc/find-spam/ClassCleantalkCommentsListTableSpam.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/CommentsScan.php RENAMED
@@ -1,53 +1,54 @@
1
- <?php
2
-
3
-
4
- class ABPCTCommentsListTableSpam extends ABPCTCommentsListTable
5
- {
6
-
7
- function prepare_items() {
8
-
9
- $columns = $this->get_columns();
10
- $this->_column_headers = array( $columns, array(), array() );
11
-
12
- $per_page_option = get_current_screen()->get_option( 'per_page', 'option' );
13
- $per_page = get_user_meta( get_current_user_id(), $per_page_option, true );
14
- if( ! $per_page ) {
15
- $per_page = 10;
16
- }
17
-
18
- $scanned_comments = $this->getSpam();
19
-
20
- $this->set_pagination_args( array(
21
- 'total_items' => count( $scanned_comments->get_comments() ),
22
- 'per_page' => $per_page,
23
- ) );
24
-
25
- $current_page = (int) $this->get_pagenum();
26
-
27
- $scanned_comments_to_show = array_slice( $scanned_comments->get_comments(), ( ( $current_page - 1 ) * $per_page ), $per_page );
28
-
29
- foreach( $scanned_comments_to_show as $comment ) {
30
-
31
- $this->items[] = array(
32
- 'ct_id' => $comment->comment_ID,
33
- 'ct_author' => $comment->comment_author,
34
- 'ct_comment' => $comment,
35
- 'ct_response_to' => $comment->comment_post_ID,
36
- );
37
-
38
- }
39
-
40
- }
41
-
42
- function extra_tablenav( $which ) {
43
- if( ! $this->has_items() ) return;
44
- $button_id = ($which) ? "ct_delete_all_$which" : "ct_delete_all";
45
- ?>
46
- <div class="alignleft actions bulkactions">
47
- <button type="button" id="<?php echo $button_id; ?>" class="button action ct_delete_all"><?php esc_html_e('Delete all comments from the list', 'cleantalk-spam-protect'); ?></button>
48
- <span class="spinner"></span>
49
- </div>
50
- <?php
51
- }
52
-
 
53
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam\ListTable;
4
+
5
+ class CommentsScan extends Comments
6
+ {
7
+
8
+ function prepare_items() {
9
+
10
+ $columns = $this->get_columns();
11
+ $this->_column_headers = array( $columns, array(), array() );
12
+
13
+ $per_page_option = get_current_screen()->get_option( 'per_page', 'option' );
14
+ $per_page = get_user_meta( get_current_user_id(), $per_page_option, true );
15
+ if( ! $per_page ) {
16
+ $per_page = 10;
17
+ }
18
+
19
+ $scanned_comments = $this->getSpamNow();
20
+
21
+ $this->set_pagination_args( array(
22
+ 'total_items' => count( $scanned_comments->get_comments() ),
23
+ 'per_page' => $per_page,
24
+ ) );
25
+
26
+ $current_page = (int) $this->get_pagenum();
27
+
28
+ $scanned_comments_to_show = array_slice( $scanned_comments->get_comments(), ( ( $current_page - 1 ) * $per_page ), $per_page );
29
+
30
+ foreach( $scanned_comments_to_show as $comment ) {
31
+
32
+ $this->items[] = array(
33
+ 'ct_id' => $comment->comment_ID,
34
+ 'ct_author' => $comment->comment_author,
35
+ 'ct_comment' => $comment,
36
+ 'ct_response_to' => $comment->comment_post_ID,
37
+ );
38
+
39
+ }
40
+
41
+ }
42
+
43
+ function extra_tablenav( $which ) {
44
+ if( ! $this->has_items() ) return;
45
+ $button_id = ($which) ? "ct_delete_all_$which" : "ct_delete_all";
46
+ ?>
47
+ <div class="alignleft actions bulkactions">
48
+ <button type="button" id="<?php echo $button_id; ?>" class="button action ct_delete_all"><?php esc_html_e('Delete all comments from the list', 'cleantalk-spam-protect'); ?></button>
49
+ <span class="spinner"></span>
50
+ </div>
51
+ <?php
52
+ }
53
+
54
  }
inc/find-spam/ClassCleantalkUsersListTable.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/Users.php RENAMED
@@ -1,263 +1,264 @@
1
- <?php
2
-
3
-
4
- class ABPCTUsersListTable extends ABPCT_List_Table
5
- {
6
-
7
- protected $apbct;
8
-
9
- function __construct(){
10
-
11
- parent::__construct(array(
12
- 'singular' => 'spam',
13
- 'plural' => 'spam'
14
- ));
15
-
16
- $this->bulk_actions_handler();
17
-
18
- $this->row_actions_handler();
19
-
20
- $this->prepare_items();
21
-
22
- global $apbct;
23
- $this->apbct = $apbct;
24
-
25
- }
26
-
27
- // Set columns
28
- function get_columns(){
29
- return array(
30
- 'cb' => '<input type="checkbox" />',
31
- 'ct_username' => esc_html__( 'Username', 'cleantalk-spam-protect'),
32
- 'ct_name' => esc_html__( 'Name', 'cleantalk-spam-protect'),
33
- 'ct_email' => esc_html__( 'E-mail', 'cleantalk-spam-protect'),
34
- 'ct_signed_up' => esc_html__( 'Signed up', 'cleantalk-spam-protect'),
35
- 'ct_role' => esc_html__( 'Role', 'cleantalk-spam-protect'),
36
- 'ct_posts' => esc_html__( 'Posts', 'cleantalk-spam-protect'),
37
- );
38
- }
39
-
40
- // CheckBox column
41
- function column_cb( $item ){
42
- echo '<input type="checkbox" name="spamids[]" id="cb-select-'. $item['ct_id'] .'" value="'. $item['ct_id'] .'" />';
43
- }
44
-
45
- // Username (first) column
46
- function column_ct_username( $item ) {
47
- $user_obj = $item['ct_username'];
48
- $email = $user_obj->user_email;
49
- $column_content = '';
50
-
51
- // Avatar, nickname
52
- $column_content .= '<strong>' . get_avatar( $user_obj->ID , 32) . '&nbsp;' . $user_obj->user_login . '</strong>';
53
- $column_content .= '<br /><br />';
54
-
55
- // Email
56
- if( ! empty( $email ) ){
57
- $column_content .= "<a href='mailto:$email'>$email</a>"
58
- .( ! $this->apbct->white_label
59
- ? "<a href='https://cleantalk.org/blacklists/$email' target='_blank'>"
60
- ."&nbsp;<img src='" . APBCT_URL_PATH . "/inc/images/new_window.gif' alt='Ico: open in new window' border='0' style='float:none' />"
61
- ."</a>"
62
- : '');
63
- } else {
64
- $column_content .= esc_html__( 'No email', 'cleantalk-spam-protect');
65
- }
66
- $column_content .= '<br/>';
67
-
68
- // IP
69
- $user_meta = get_user_meta( $user_obj->ID, 'session_tokens', true );
70
- if( ! empty( $user_meta ) && is_array( $user_meta ) ){
71
- $user_meta = array_values( $user_meta );
72
- if( ! empty( $user_meta[0]['ip'] ) ) {
73
- $ip = $user_meta[0]['ip'];
74
- $column_content .= "<a href='user-edit.php?user_id=$user_obj->ID'>$ip</a>"
75
- .( ! $this->apbct->white_label
76
- ?"<a href='https://cleantalk.org/blacklists/$ip ' target='_blank'>"
77
- ."&nbsp;<img src='" . APBCT_URL_PATH . "/inc/images/new_window.gif' alt='Ico: open in new window' border='0' style='float:none' />"
78
- ."</a>"
79
- : '');
80
- }else
81
- $column_content .= esc_html__( 'No IP adress', 'cleantalk-spam-protect');
82
- }else
83
- $column_content .= esc_html__( 'No IP adress', 'cleantalk-spam-protect');
84
-
85
- $actions = array(
86
- 'delete' => sprintf( '<a href="?page=%s&action=%s&spam=%s">Delete</a>', $_REQUEST['page'],'delete', $user_obj->ID ),
87
- );
88
-
89
- return sprintf( '%1$s %2$s', $column_content, $this->row_actions( $actions ) );
90
-
91
- }
92
-
93
- // Rest of columns
94
- function column_default( $item, $column_name ) {
95
- switch( $column_name ) {
96
- case 'ct_name':
97
- case 'ct_email':
98
- case 'ct_signed_up':
99
- case 'ct_role':
100
- case 'ct_posts':
101
- case 'ct_start':
102
- case 'ct_checked':
103
- case 'ct_spam':
104
- case 'ct_bad':
105
- return $item[ $column_name ];
106
- default:
107
- return print_r( $item, true ) ;
108
- }
109
- }
110
-
111
- function get_bulk_actions() {
112
- $actions = array(
113
- 'delete' => 'Delete'
114
- );
115
- return $actions;
116
- }
117
-
118
- function bulk_actions_handler() {
119
-
120
- if( empty($_POST['spamids']) || empty($_POST['_wpnonce']) ) return;
121
-
122
- if ( ! $action = $this->current_action() ) return;
123
-
124
- if( ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-' . $this->_args['plural'] ) )
125
- wp_die('nonce error');
126
-
127
- $this->removeSpam( $_POST['spamids'] );
128
-
129
- }
130
-
131
- function row_actions_handler() {
132
-
133
- if( empty($_GET['action']) ) return;
134
-
135
- if( $_GET['action'] == 'delete' ) {
136
-
137
- $id = filter_input( INPUT_GET, 'spam', FILTER_SANITIZE_NUMBER_INT );
138
- $this->removeSpam( array( $id ) );
139
-
140
- }
141
-
142
- }
143
-
144
- function no_items() {
145
- esc_html_e( 'No spam found.', 'cleantalk-spam-protect');
146
- }
147
-
148
- //********************************************//
149
- // LOGIC //
150
- //*******************************************//
151
-
152
- function removeSpam( $ids ) {
153
-
154
- $ids_string = implode( ', ', $ids );
155
- global $wpdb;
156
-
157
- $wpdb->query("DELETE FROM {$wpdb->users} WHERE
158
- ID IN ($ids_string)");
159
-
160
- }
161
-
162
- public function getTotal() {
163
-
164
- $params_total = array(
165
- 'fields' => 'ID',
166
- 'count'=>true,
167
- 'orderby' => 'user_registered'
168
- );
169
- $total_users = new WP_User_Query($params_total);
170
- return $total_users;
171
-
172
- }
173
-
174
- public function getChecked() {
175
-
176
- $params_spam = array(
177
- 'fields' => 'ID',
178
- 'meta_key' => 'ct_checked',
179
- 'count_total' => true,
180
- );
181
- $spam_users = new WP_User_Query($params_spam);
182
- return $spam_users;
183
-
184
- }
185
-
186
- public function getCheckedNow() {
187
-
188
- $params_spam = array(
189
- 'fields' => 'ID',
190
- 'meta_key' => 'ct_checked_now',
191
- 'count_total' => true,
192
- );
193
- $spam_users = new WP_User_Query($params_spam);
194
- return $spam_users;
195
-
196
- }
197
-
198
- public function getSpam() {
199
-
200
- $params_spam = array(
201
- 'fields' => 'ID',
202
- 'meta_key' => 'ct_marked_as_spam',
203
- 'count_total' => true,
204
- );
205
- $spam_users = new WP_User_Query($params_spam);
206
- return $spam_users;
207
-
208
- }
209
-
210
- public function getSpamNow() {
211
-
212
- $params_spam = array(
213
- 'fields' => 'ID',
214
- 'meta_query' => array(
215
- 'relation' => 'AND',
216
- array(
217
- 'key' => 'ct_marked_as_spam',
218
- 'compare' => 'EXISTS'
219
- ),
220
- array(
221
- 'key' => 'ct_checked_now',
222
- 'compare' => 'EXISTS'
223
- ),
224
- ),
225
- 'count_total' => true,
226
- );
227
- $spam_users = new WP_User_Query($params_spam);
228
- return $spam_users;
229
-
230
- }
231
-
232
- public function getBad() { // Without IP and EMAIL
233
-
234
- $params_bad = array(
235
- 'fields' => 'ID',
236
- 'meta_key' => 'ct_bad',
237
- 'count_total' => true,
238
- );
239
- $bad_users = new WP_User_Query($params_bad);
240
- return $bad_users;
241
-
242
- }
243
-
244
- public function getScansLogs() {
245
-
246
- global $wpdb;
247
- $query = "SELECT * FROM " . APBCT_SPAMSCAN_LOGS . " WHERE scan_type = 'users'";
248
- $res = $wpdb->get_results( $query, ARRAY_A );
249
- return $res;
250
-
251
- }
252
-
253
- protected function removeLogs( $ids ) {
254
-
255
- $ids_string = implode( ', ', $ids );
256
- global $wpdb;
257
-
258
- $wpdb->query("DELETE FROM " . APBCT_SPAMSCAN_LOGS . " WHERE
259
- ID IN ($ids_string)");
260
-
261
- }
262
-
 
263
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam\ListTable;
4
+
5
+ class Users extends \Cleantalk\ApbctWP\CleantalkListTable
6
+ {
7
+
8
+ protected $apbct;
9
+
10
+ function __construct(){
11
+
12
+ parent::__construct(array(
13
+ 'singular' => 'spam',
14
+ 'plural' => 'spam'
15
+ ));
16
+
17
+ $this->bulk_actions_handler();
18
+
19
+ $this->row_actions_handler();
20
+
21
+ $this->prepare_items();
22
+
23
+ global $apbct;
24
+ $this->apbct = $apbct;
25
+
26
+ }
27
+
28
+ // Set columns
29
+ function get_columns(){
30
+ return array(
31
+ 'cb' => '<input type="checkbox" />',
32
+ 'ct_username' => esc_html__( 'Username', 'cleantalk-spam-protect'),
33
+ 'ct_name' => esc_html__( 'Name', 'cleantalk-spam-protect'),
34
+ 'ct_email' => esc_html__( 'E-mail', 'cleantalk-spam-protect'),
35
+ 'ct_signed_up' => esc_html__( 'Signed up', 'cleantalk-spam-protect'),
36
+ 'ct_role' => esc_html__( 'Role', 'cleantalk-spam-protect'),
37
+ 'ct_posts' => esc_html__( 'Posts', 'cleantalk-spam-protect'),
38
+ );
39
+ }
40
+
41
+ // CheckBox column
42
+ function column_cb( $item ){
43
+ echo '<input type="checkbox" name="spamids[]" id="cb-select-'. $item['ct_id'] .'" value="'. $item['ct_id'] .'" />';
44
+ }
45
+
46
+ // Username (first) column
47
+ function column_ct_username( $item ) {
48
+ $user_obj = $item['ct_username'];
49
+ $email = $user_obj->user_email;
50
+ $column_content = '';
51
+
52
+ // Avatar, nickname
53
+ $column_content .= '<strong>' . get_avatar( $user_obj->ID , 32) . '&nbsp;' . $user_obj->user_login . '</strong>';
54
+ $column_content .= '<br /><br />';
55
+
56
+ // Email
57
+ if( ! empty( $email ) ){
58
+ $column_content .= "<a href='mailto:$email'>$email</a>"
59
+ .( ! $this->apbct->white_label
60
+ ? "<a href='https://cleantalk.org/blacklists/$email' target='_blank'>"
61
+ ."&nbsp;<img src='" . APBCT_URL_PATH . "/inc/images/new_window.gif' alt='Ico: open in new window' border='0' style='float:none' />"
62
+ ."</a>"
63
+ : '');
64
+ } else {
65
+ $column_content .= esc_html__( 'No email', 'cleantalk-spam-protect');
66
+ }
67
+ $column_content .= '<br/>';
68
+
69
+ // IP
70
+ $user_meta = get_user_meta( $user_obj->ID, 'session_tokens', true );
71
+ if( ! empty( $user_meta ) && is_array( $user_meta ) ){
72
+ $user_meta = array_values( $user_meta );
73
+ if( ! empty( $user_meta[0]['ip'] ) ) {
74
+ $ip = $user_meta[0]['ip'];
75
+ $column_content .= "<a href='user-edit.php?user_id=$user_obj->ID'>$ip</a>"
76
+ .( ! $this->apbct->white_label
77
+ ?"<a href='https://cleantalk.org/blacklists/$ip ' target='_blank'>"
78
+ ."&nbsp;<img src='" . APBCT_URL_PATH . "/inc/images/new_window.gif' alt='Ico: open in new window' border='0' style='float:none' />"
79
+ ."</a>"
80
+ : '');
81
+ }else
82
+ $column_content .= esc_html__( 'No IP adress', 'cleantalk-spam-protect');
83
+ }else
84
+ $column_content .= esc_html__( 'No IP adress', 'cleantalk-spam-protect');
85
+
86
+ $actions = array(
87
+ 'delete' => sprintf( '<a href="?page=%s&action=%s&spam=%s">Delete</a>', $_REQUEST['page'],'delete', $user_obj->ID ),
88
+ );
89
+
90
+ return sprintf( '%1$s %2$s', $column_content, $this->row_actions( $actions ) );
91
+
92
+ }
93
+
94
+ // Rest of columns
95
+ function column_default( $item, $column_name ) {
96
+ switch( $column_name ) {
97
+ case 'ct_name':
98
+ case 'ct_email':
99
+ case 'ct_signed_up':
100
+ case 'ct_role':
101
+ case 'ct_posts':
102
+ case 'ct_start':
103
+ case 'ct_checked':
104
+ case 'ct_spam':
105
+ case 'ct_bad':
106
+ return $item[ $column_name ];
107
+ default:
108
+ return print_r( $item, true ) ;
109
+ }
110
+ }
111
+
112
+ function get_bulk_actions() {
113
+ $actions = array(
114
+ 'delete' => 'Delete'
115
+ );
116
+ return $actions;
117
+ }
118
+
119
+ function bulk_actions_handler() {
120
+
121
+ if( empty($_POST['spamids']) || empty($_POST['_wpnonce']) ) return;
122
+
123
+ if ( ! $action = $this->current_action() ) return;
124
+
125
+ if( ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-' . $this->_args['plural'] ) )
126
+ wp_die('nonce error');
127
+
128
+ $this->removeSpam( $_POST['spamids'] );
129
+
130
+ }
131
+
132
+ function row_actions_handler() {
133
+
134
+ if( empty($_GET['action']) ) return;
135
+
136
+ if( $_GET['action'] == 'delete' ) {
137
+
138
+ $id = filter_input( INPUT_GET, 'spam', FILTER_SANITIZE_NUMBER_INT );
139
+ $this->removeSpam( array( $id ) );
140
+
141
+ }
142
+
143
+ }
144
+
145
+ function no_items() {
146
+ esc_html_e( 'No spam found.', 'cleantalk-spam-protect');
147
+ }
148
+
149
+ //********************************************//
150
+ // LOGIC //
151
+ //*******************************************//
152
+
153
+ function removeSpam( $ids ) {
154
+
155
+ $ids_string = implode( ', ', $ids );
156
+ global $wpdb;
157
+
158
+ $wpdb->query("DELETE FROM {$wpdb->users} WHERE
159
+ ID IN ($ids_string)");
160
+
161
+ }
162
+
163
+ public function getTotal() {
164
+
165
+ $params_total = array(
166
+ 'fields' => 'ID',
167
+ 'count'=>true,
168
+ 'orderby' => 'user_registered'
169
+ );
170
+ $total_users = new \WP_User_Query($params_total);
171
+ return $total_users;
172
+
173
+ }
174
+
175
+ public function getChecked() {
176
+
177
+ $params_spam = array(
178
+ 'fields' => 'ID',
179
+ 'meta_key' => 'ct_checked',
180
+ 'count_total' => true,
181
+ );
182
+ $spam_users = new \WP_User_Query($params_spam);
183
+ return $spam_users;
184
+
185
+ }
186
+
187
+ public function getCheckedNow() {
188
+
189
+ $params_spam = array(
190
+ 'fields' => 'ID',
191
+ 'meta_key' => 'ct_checked_now',
192
+ 'count_total' => true,
193
+ );
194
+ $spam_users = new \WP_User_Query($params_spam);
195
+ return $spam_users;
196
+
197
+ }
198
+
199
+ public function getSpam() {
200
+
201
+ $params_spam = array(
202
+ 'fields' => 'ID',
203
+ 'meta_key' => 'ct_marked_as_spam',
204
+ 'count_total' => true,
205
+ );
206
+ $spam_users = new \WP_User_Query($params_spam);
207
+ return $spam_users;
208
+
209
+ }
210
+
211
+ public function getSpamNow() {
212
+
213
+ $params_spam = array(
214
+ 'fields' => 'ID',
215
+ 'meta_query' => array(
216
+ 'relation' => 'AND',
217
+ array(
218
+ 'key' => 'ct_marked_as_spam',
219
+ 'compare' => 'EXISTS'
220
+ ),
221
+ array(
222
+ 'key' => 'ct_checked_now',
223
+ 'compare' => 'EXISTS'
224
+ ),
225
+ ),
226
+ 'count_total' => true,
227
+ );
228
+ $spam_users = new \WP_User_Query($params_spam);
229
+ return $spam_users;
230
+
231
+ }
232
+
233
+ public function getBad() { // Without IP and EMAIL
234
+
235
+ $params_bad = array(
236
+ 'fields' => 'ID',
237
+ 'meta_key' => 'ct_bad',
238
+ 'count_total' => true,
239
+ );
240
+ $bad_users = new \WP_User_Query($params_bad);
241
+ return $bad_users;
242
+
243
+ }
244
+
245
+ public function getScansLogs() {
246
+
247
+ global $wpdb;
248
+ $query = "SELECT * FROM " . APBCT_SPAMSCAN_LOGS . " WHERE scan_type = 'users'";
249
+ $res = $wpdb->get_results( $query, ARRAY_A );
250
+ return $res;
251
+
252
+ }
253
+
254
+ protected function removeLogs( $ids ) {
255
+
256
+ $ids_string = implode( ', ', $ids );
257
+ global $wpdb;
258
+
259
+ $wpdb->query("DELETE FROM " . APBCT_SPAMSCAN_LOGS . " WHERE
260
+ ID IN ($ids_string)");
261
+
262
+ }
263
+
264
  }
inc/find-spam/ClassCleantalkUsersListTableLogs.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/UsersLogs.php RENAMED
@@ -1,63 +1,64 @@
1
- <?php
2
-
3
-
4
- class ABPCTUsersListTableLogs extends ABPCTUsersListTable
5
- {
6
-
7
- // Set columns
8
- function get_columns(){
9
- return array(
10
- 'cb' => '<input type="checkbox" />',
11
- 'ct_start' => esc_html__( 'Start time', 'cleantalk-spam-protect'),
12
- 'ct_checked' => esc_html__( 'Checked', 'cleantalk-spam-protect'),
13
- 'ct_spam' => esc_html__( 'Found spam', 'cleantalk-spam-protect'),
14
- 'ct_bad' => esc_html__( 'Found bad', 'cleantalk-spam-protect'),
15
- );
16
- }
17
-
18
- function prepare_items(){
19
-
20
- $columns = $this->get_columns();
21
- $this->_column_headers = array( $columns, array(), array() );
22
-
23
- $logs = $this->getScansLogs();
24
-
25
- foreach( $logs as $log ) {
26
-
27
- $this->items[] = array(
28
- 'ct_id' => $log['id'],
29
- 'ct_start' => $log['start_time'],
30
- 'ct_checked' => $log['count_to_scan'],
31
- 'ct_spam' => $log['found_spam'],
32
- 'ct_bad' => $log['found_bad'],
33
- );
34
-
35
- }
36
-
37
- }
38
-
39
- function get_bulk_actions() {
40
- $actions = array(
41
- 'delete' => 'Delete'
42
- );
43
- return $actions;
44
- }
45
-
46
- function bulk_actions_handler() {
47
-
48
- if( empty($_POST['spamids']) || empty($_POST['_wpnonce']) ) return;
49
-
50
- if ( ! $action = $this->current_action() ) return;
51
-
52
- if( ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-' . $this->_args['plural'] ) )
53
- wp_die('nonce error');
54
-
55
- $this->removeLogs( $_POST['spamids'] );
56
-
57
- }
58
-
59
- function no_items() {
60
- esc_html_e( 'No logs found.', 'cleantalk-spam-protect');
61
- }
62
-
 
63
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam\ListTable;
4
+
5
+ class UsersLogs extends Users
6
+ {
7
+
8
+ // Set columns
9
+ function get_columns(){
10
+ return array(
11
+ 'cb' => '<input type="checkbox" />',
12
+ 'ct_start' => esc_html__( 'Start time', 'cleantalk-spam-protect'),
13
+ 'ct_checked' => esc_html__( 'Checked', 'cleantalk-spam-protect'),
14
+ 'ct_spam' => esc_html__( 'Found spam', 'cleantalk-spam-protect'),
15
+ 'ct_bad' => esc_html__( 'Found bad', 'cleantalk-spam-protect'),
16
+ );
17
+ }
18
+
19
+ function prepare_items(){
20
+
21
+ $columns = $this->get_columns();
22
+ $this->_column_headers = array( $columns, array(), array() );
23
+
24
+ $logs = $this->getScansLogs();
25
+
26
+ foreach( $logs as $log ) {
27
+
28
+ $this->items[] = array(
29
+ 'ct_id' => $log['id'],
30
+ 'ct_start' => $log['start_time'],
31
+ 'ct_checked' => $log['count_to_scan'],
32
+ 'ct_spam' => $log['found_spam'],
33
+ 'ct_bad' => $log['found_bad'],
34
+ );
35
+
36
+ }
37
+
38
+ }
39
+
40
+ function get_bulk_actions() {
41
+ $actions = array(
42
+ 'delete' => 'Delete'
43
+ );
44
+ return $actions;
45
+ }
46
+
47
+ function bulk_actions_handler() {
48
+
49
+ if( empty($_POST['spamids']) || empty($_POST['_wpnonce']) ) return;
50
+
51
+ if ( ! $action = $this->current_action() ) return;
52
+
53
+ if( ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-' . $this->_args['plural'] ) )
54
+ wp_die('nonce error');
55
+
56
+ $this->removeLogs( $_POST['spamids'] );
57
+
58
+ }
59
+
60
+ function no_items() {
61
+ esc_html_e( 'No logs found.', 'cleantalk-spam-protect');
62
+ }
63
+
64
  }
inc/find-spam/ClassCleantalkUsersListTableSpam.php → lib/Cleantalk/ApbctWP/FindSpam/ListTable/UsersScan.php RENAMED
@@ -1,64 +1,65 @@
1
- <?php
2
-
3
-
4
- class ABPCTUsersListTableSpam extends ABPCTUsersListTable
5
- {
6
-
7
- function prepare_items(){
8
-
9
- $columns = $this->get_columns();
10
- $this->_column_headers = array( $columns, array(), array() );
11
-
12
- $per_page_option = get_current_screen()->get_option( 'per_page', 'option' );
13
- $per_page = get_user_meta( get_current_user_id(), $per_page_option, true );
14
- if( ! $per_page ) {
15
- $per_page = 10;
16
- }
17
-
18
- $spam_users = $this->getSpam();
19
-
20
- $this->set_pagination_args( array(
21
- 'total_items' => $spam_users->get_total(),
22
- 'per_page' => $per_page,
23
- ) );
24
-
25
- $current_page = (int) $this->get_pagenum();
26
-
27
- $spam_users_to_show = array_slice( $spam_users->get_results(), ( ( $current_page - 1 ) * $per_page ), $per_page );
28
-
29
- foreach( $spam_users_to_show as $user_id ) {
30
-
31
- $user_obj = get_userdata( $user_id );
32
-
33
- $this->items[] = array(
34
- 'ct_id' => $user_obj->ID,
35
- 'ct_username' => $user_obj,
36
- 'ct_name' => $user_obj->display_name,
37
- 'ct_email' => $user_obj->user_email,
38
- 'ct_signed_up' => $user_obj->user_registered,
39
- 'ct_role' => implode( ', ', $user_obj->roles ),
40
- 'ct_posts' => count_user_posts( $user_id ),
41
- );
42
-
43
- }
44
-
45
- }
46
-
47
- function extra_tablenav( $which ) {
48
- if( isset( $_SERVER['SERVER_ADDR'] ) && $_SERVER['SERVER_ADDR'] === '127.0.0.1' ){
49
- ?>
50
- <button type="button" class="button action ct_insert_users">Insert users</button>
51
- <button type="button" class="button action ct_insert_users__delete">Delete inserted</button>
52
- <?php
53
- }
54
- if( ! $this->has_items() ) return;
55
- ?>
56
- <div class="alignleft actions bulkactions">
57
- <button type="button" id="ct_delete_all_users" class="button action ct_delete_all_users"><?php esc_html_e('Delete all users from list', 'cleantalk-spam-protect'); ?></button>
58
- <button type="button" id="ct_get_csv_file" class="button action ct_get_csv_file"><?php esc_html_e( 'Download results in CSV', 'cleantalk-spam-protect') ?></button>
59
- <span class="spinner"></span>
60
- </div>
61
- <?php
62
- }
63
-
 
64
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam\ListTable;
4
+
5
+ class UsersScan extends Users
6
+ {
7
+
8
+ function prepare_items() {
9
+
10
+ $columns = $this->get_columns();
11
+ $this->_column_headers = array( $columns, array(), array() );
12
+
13
+ $per_page_option = get_current_screen()->get_option( 'per_page', 'option' );
14
+ $per_page = get_user_meta( get_current_user_id(), $per_page_option, true );
15
+ if( ! $per_page ) {
16
+ $per_page = 10;
17
+ }
18
+
19
+ $scanned_users = $this->getSpamNow();
20
+
21
+ $this->set_pagination_args( array(
22
+ 'total_items' => $scanned_users->get_total(),
23
+ 'per_page' => $per_page,
24
+ ) );
25
+
26
+ $current_page = (int) $this->get_pagenum();
27
+
28
+ $scanned_users_to_show = array_slice( $scanned_users->get_results(), ( ( $current_page - 1 ) * $per_page ), $per_page );
29
+
30
+ foreach( $scanned_users_to_show as $user_id ) {
31
+
32
+ $user_obj = get_userdata( $user_id );
33
+
34
+ $this->items[] = array(
35
+ 'ct_id' => $user_obj->ID,
36
+ 'ct_username' => $user_obj,
37
+ 'ct_name' => $user_obj->display_name,
38
+ 'ct_email' => $user_obj->user_email,
39
+ 'ct_signed_up' => $user_obj->user_registered,
40
+ 'ct_role' => implode( ', ', $user_obj->roles ),
41
+ 'ct_posts' => count_user_posts( $user_id ),
42
+ );
43
+
44
+ }
45
+
46
+ }
47
+
48
+ function extra_tablenav( $which ) {
49
+ if( isset( $_SERVER['SERVER_ADDR'] ) && $_SERVER['SERVER_ADDR'] === '127.0.0.1' ){
50
+ ?>
51
+ <button type="button" class="button action ct_insert_users">Insert users</button>
52
+ <button type="button" class="button action ct_insert_users__delete">Delete inserted</button>
53
+ <?php
54
+ }
55
+ if( ! $this->has_items() ) return;
56
+ ?>
57
+ <div class="alignleft actions bulkactions">
58
+ <button type="button" id="ct_delete_all_users" class="button action ct_delete_all_users"><?php esc_html_e('Delete all users from list', 'cleantalk-spam-protect'); ?></button>
59
+ <button type="button" id="ct_get_csv_file" class="button action ct_get_csv_file"><?php esc_html_e( 'Download results in CSV', 'cleantalk-spam-protect') ?></button>
60
+ <span class="spinner"></span>
61
+ </div>
62
+ <?php
63
+ }
64
+
65
  }
inc/find-spam/ClassCleantalkFindSpamPage.php → lib/Cleantalk/ApbctWP/FindSpam/Page.php RENAMED
@@ -1,136 +1,127 @@
1
- <?php
2
-
3
-
4
- class ClassCleantalkFindSpamPage
5
- {
6
-
7
- private $spam_checker;
8
-
9
- private $current_tab;
10
-
11
- public function __construct( ClassCleantalkFindSpamChecker $apbct_spam_checker ) {
12
-
13
- $this->spam_checker = $apbct_spam_checker;
14
-
15
- switch ( current_action() ) {
16
-
17
- case 'users_page_ct_check_users' :
18
- case 'comments_page_ct_check_spam' :
19
- $this->current_tab = 1;
20
- $this->generatePageHeader();
21
- $this->spam_checker->getCurrentScanPage();
22
- break;
23
-
24
- case 'users_page_ct_check_users_total' :
25
- case 'comments_page_ct_check_spam_total' :
26
- $this->current_tab = 2;
27
- $this->generatePageHeader();
28
- $this->spam_checker->getTotalSpamPage();
29
- break;
30
-
31
- case 'users_page_ct_check_users_logs' :
32
- case 'comments_page_ct_check_spam_logs' :
33
- $this->current_tab = 3;
34
- $this->generatePageHeader();
35
- $this->spam_checker->getSpamLogsPage();
36
- break;
37
-
38
- }
39
-
40
- }
41
-
42
- /**
43
- * Output header section of the FindSpam pages
44
- *
45
- * @return void (HTML layout output)
46
- */
47
- public static function showFindSpamPage() {
48
- switch ( current_action() ) {
49
-
50
- case 'users_page_ct_check_users' :
51
- case 'users_page_ct_check_users_total' :
52
- case 'users_page_ct_check_users_logs' :
53
- self::generateCheckUsersPage();
54
- break;
55
-
56
- case 'comments_page_ct_check_spam' :
57
- case 'comments_page_ct_check_spam_total' :
58
- case 'comments_page_ct_check_spam_logs' :
59
- self::generateCheckSpamPage();
60
- break;
61
-
62
- }
63
-
64
- }
65
-
66
- private static function generateCheckUsersPage() {
67
-
68
- new self( new ClassCleantalkFindSpamUsersChecker() );
69
-
70
- self::closeTags();
71
-
72
- }
73
-
74
- private static function generateCheckSpamPage() {
75
-
76
- new self( new ClassCleantalkFindSpamCommentsChecker() );
77
-
78
- self::closeTags();
79
-
80
- }
81
-
82
- private function generatePageHeader() {
83
-
84
- // If access key is unset in
85
- if( ! apbct_api_key__is_correct() ){
86
- if( 1 == $this->spam_checker->getApbct()->moderate_ip ){
87
- echo '<h3>'
88
- .sprintf(
89
- __('Antispam hosting tariff does not allow you to use this feature. To do so, you need to enter an Access Key in the %splugin settings%s.', 'cleantalk-spam-protect'),
90
- '<a href="' . ( is_network_admin() ? 'settings.php?page=cleantalk' : 'options-general.php?page=cleantalk' ).'">',
91
- '</a>'
92
- )
93
- .'</h3>';
94
- }
95
- return;
96
- }
97
-
98
- ?>
99
- <div class="wrap">
100
- <h2><img src="<?php echo $this->spam_checker->getApbct()->logo__small__colored; ?>" alt="CleanTalk logo" /> <?php echo $this->spam_checker->getApbct()->plugin_name; ?></h2>
101
- <a style="color: gray; margin-left: 23px;" href="<?php echo $this->spam_checker->getApbct()->settings_link; ?>"><?php _e('Plugin Settings', 'cleantalk-spam-protect'); ?></a>
102
- <br />
103
- <h3><?php echo $this->spam_checker->getPageTitle(); ?></h3>
104
- <div id="ct_check_tabs">
105
- <ul>
106
- <li <?php echo (1 == $this->current_tab) ? 'class="active"' : ''; ?>><a href="<?php echo $this->spam_checker->getPageScriptName(); ?>?page=ct_check_<?php echo $this->spam_checker->getPageSlug(); ?>"><?php esc_html_e( 'Scan and new results', 'cleantalk-spam-protect') ?></a></li>
107
- <li <?php echo (2 == $this->current_tab) ? 'class="active"' : ''; ?>><a href="<?php echo $this->spam_checker->getPageScriptName(); ?>?page=ct_check_<?php echo $this->spam_checker->getPageSlug(); ?>_total"><?php esc_html_e( 'Previous scan results', 'cleantalk-spam-protect') ?></a></li>
108
- <li <?php echo (3 == $this->current_tab) ? 'class="active"' : ''; ?>><a href="<?php echo $this->spam_checker->getPageScriptName(); ?>?page=ct_check_<?php echo $this->spam_checker->getPageSlug(); ?>_logs"><?php esc_html_e( 'Scan logs', 'cleantalk-spam-protect') ?></a></li>
109
- </ul>
110
- <div id="ct_check_content">
111
- <?php
112
-
113
- }
114
-
115
- public static function setScreenOption() {
116
-
117
- $option = 'per_page';
118
- $args = array(
119
- 'label' => esc_html__( 'Show per page', 'cleantalk-spam-protect'),
120
- 'default' => 10,
121
- 'option' => 'spam_per_page',
122
- );
123
- add_screen_option( $option, $args );
124
-
125
- }
126
-
127
- private static function closeTags() {
128
-
129
- ?>
130
- </div>
131
- </div>
132
- <?php
133
-
134
- }
135
-
136
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam;
4
+
5
+ class Page
6
+ {
7
+
8
+ private $spam_checker;
9
+
10
+ private $current_tab;
11
+
12
+ public function __construct( Checker $apbct_spam_checker ) {
13
+
14
+ $this->spam_checker = $apbct_spam_checker;
15
+
16
+ switch ( current_action() ) {
17
+
18
+ case 'users_page_ct_check_users' :
19
+ case 'comments_page_ct_check_spam' :
20
+ $this->current_tab = 1;
21
+ $this->generatePageHeader();
22
+ $this->spam_checker->getCurrentScanPage();
23
+ break;
24
+
25
+ case 'users_page_ct_check_users_logs' :
26
+ case 'comments_page_ct_check_spam_logs' :
27
+ $this->current_tab = 3;
28
+ $this->generatePageHeader();
29
+ $this->spam_checker->getSpamLogsPage();
30
+ break;
31
+
32
+ }
33
+
34
+ }
35
+
36
+ /**
37
+ * Output header section of the FindSpam pages
38
+ *
39
+ * @return void (HTML layout output)
40
+ */
41
+ public static function showFindSpamPage() {
42
+ switch ( current_action() ) {
43
+
44
+ case 'users_page_ct_check_users' :
45
+ case 'users_page_ct_check_users_logs' :
46
+ self::generateCheckUsersPage();
47
+ break;
48
+
49
+ case 'comments_page_ct_check_spam' :
50
+ case 'comments_page_ct_check_spam_logs' :
51
+ self::generateCheckSpamPage();
52
+ break;
53
+
54
+ }
55
+
56
+ }
57
+
58
+ private static function generateCheckUsersPage() {
59
+
60
+ new self( new UsersChecker() );
61
+
62
+ self::closeTags();
63
+
64
+ }
65
+
66
+ private static function generateCheckSpamPage() {
67
+
68
+ new self( new CommentsChecker() );
69
+
70
+ self::closeTags();
71
+
72
+ }
73
+
74
+ private function generatePageHeader() {
75
+
76
+ // If access key is unset in
77
+ if( ! apbct_api_key__is_correct() ){
78
+ if( 1 == $this->spam_checker->getApbct()->moderate_ip ){
79
+ echo '<h3>'
80
+ .sprintf(
81
+ __('Antispam hosting tariff does not allow you to use this feature. To do so, you need to enter an Access Key in the %splugin settings%s.', 'cleantalk-spam-protect'),
82
+ '<a href="' . ( is_network_admin() ? 'settings.php?page=cleantalk' : 'options-general.php?page=cleantalk' ).'">',
83
+ '</a>'
84
+ )
85
+ .'</h3>';
86
+ }
87
+ return;
88
+ }
89
+
90
+ ?>
91
+ <div class="wrap">
92
+ <h2><img src="<?php echo $this->spam_checker->getApbct()->logo__small__colored; ?>" alt="CleanTalk logo" /> <?php echo $this->spam_checker->getApbct()->plugin_name; ?></h2>
93
+ <a style="color: gray; margin-left: 23px;" href="<?php echo $this->spam_checker->getApbct()->settings_link; ?>"><?php _e('Plugin Settings', 'cleantalk-spam-protect'); ?></a>
94
+ <br />
95
+ <h3><?php echo $this->spam_checker->getPageTitle(); ?></h3>
96
+ <div id="ct_check_tabs">
97
+ <ul>
98
+ <li <?php echo (1 == $this->current_tab) ? 'class="active"' : ''; ?>><a href="<?php echo $this->spam_checker->getPageScriptName(); ?>?page=ct_check_<?php echo $this->spam_checker->getPageSlug(); ?>"><?php esc_html_e( 'Scan and new results', 'cleantalk-spam-protect') ?></a></li>
99
+ <li <?php echo (3 == $this->current_tab) ? 'class="active"' : ''; ?>><a href="<?php echo $this->spam_checker->getPageScriptName(); ?>?page=ct_check_<?php echo $this->spam_checker->getPageSlug(); ?>_logs"><?php esc_html_e( 'Scan logs', 'cleantalk-spam-protect') ?></a></li>
100
+ </ul>
101
+ <div id="ct_check_content">
102
+ <?php
103
+
104
+ }
105
+
106
+ public static function setScreenOption() {
107
+
108
+ $option = 'per_page';
109
+ $args = array(
110
+ 'label' => esc_html__( 'Show per page', 'cleantalk-spam-protect'),
111
+ 'default' => 10,
112
+ 'option' => 'spam_per_page',
113
+ );
114
+ add_screen_option( $option, $args );
115
+
116
+ }
117
+
118
+ private static function closeTags() {
119
+
120
+ ?>
121
+ </div>
122
+ </div>
123
+ <?php
124
+
125
+ }
126
+
 
 
 
 
 
 
 
 
 
127
  }
inc/find-spam/ClassCleantalkFindSpamUsersChecker.php → lib/Cleantalk/ApbctWP/FindSpam/UsersChecker.php RENAMED
@@ -1,632 +1,647 @@
1
- <?php
2
-
3
-
4
- class ClassCleantalkFindSpamUsersChecker extends ClassCleantalkFindSpamChecker
5
- {
6
-
7
- public function __construct() {
8
-
9
- parent::__construct();
10
-
11
- $this->page_title = esc_html__( 'Check users for spam', 'cleantalk-spam-protect');
12
- $this->page_script_name = 'users.php';
13
- $this->page_slug = 'users';
14
-
15
- // Preparing data
16
- $current_user = wp_get_current_user();
17
- if( ! empty( $_COOKIE['ct_paused_users_check'] ) )
18
- $prev_check = json_decode( stripslashes( $_COOKIE['ct_paused_users_check'] ), true );
19
-
20
- wp_enqueue_script( 'ct_users_checkspam', plugins_url('/cleantalk-spam-protect/js/cleantalk-users-checkspam.min.js'), array( 'jquery', 'jqueryui' ), APBCT_VERSION );
21
- wp_localize_script( 'ct_users_checkspam', 'ctUsersCheck', array(
22
- 'ct_ajax_nonce' => wp_create_nonce('ct_secret_nonce'),
23
- 'ct_prev_accurate' => !empty($prev_check['accurate']) ? true : false,
24
- 'ct_prev_from' => !empty($prev_check['from']) ? $prev_check['from'] : false,
25
- 'ct_prev_till' => !empty($prev_check['till']) ? $prev_check['till'] : false,
26
- 'ct_timeout' => __('Failed from timeout. Going to check users again.', 'cleantalk-spam-protect'),
27
- 'ct_timeout_delete' => __('Failed from timeout. Going to run a new attempt to delete spam users.', 'cleantalk-spam-protect'),
28
- 'ct_confirm_deletion_all' => __('Delete all spam users?', 'cleantalk-spam-protect'),
29
- 'ct_iusers' => __('users.', 'cleantalk-spam-protect'),
30
- 'ct_csv_filename' => "user_check_by_".$current_user->user_login,
31
- 'ct_status_string' => __("Checked %s, found %s spam users and %s bad users (without IP or email)", 'cleantalk-spam-protect'),
32
- 'ct_status_string_warning' => "<p>".__("Please do backup of WordPress database before delete any accounts!", 'cleantalk-spam-protect')."</p>"
33
- ));
34
-
35
- wp_enqueue_style( 'cleantalk_admin_css_settings_page', plugins_url().'/cleantalk-spam-protect/css/cleantalk-spam-check.min.css', array(), APBCT_VERSION, 'all' );
36
-
37
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkUsersListTable.php');
38
-
39
- }
40
-
41
- public function getCurrentScanPage() {
42
-
43
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkUsersListTableScan.php');
44
- $this->list_table = new ABPCTUsersListTableScan();
45
-
46
- $this->getCurrentScanPanel( $this );
47
- echo '<form action="" method="POST">';
48
- $this->list_table->display();
49
- echo '</form>';
50
-
51
- }
52
-
53
- public function getTotalSpamPage(){
54
-
55
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkUsersListTableSpam.php');
56
- $this->list_table = new ABPCTUsersListTableSpam();
57
-
58
- echo '<form action="" method="POST">';
59
- $this->list_table->display();
60
- echo '</form>';
61
-
62
- }
63
-
64
- public function getSpamLogsPage(){
65
-
66
- require_once(CLEANTALK_PLUGIN_DIR . 'inc/find-spam/ClassCleantalkUsersListTableLogs.php');
67
- $this->list_table = new ABPCTUsersListTableLogs();
68
-
69
- echo '<form action="" method="POST">';
70
- $this->list_table->display();
71
- echo '</form>';
72
-
73
- }
74
-
75
- /**
76
- * Get date last checked user or date first registered user
77
- *
78
- * @return string date "M j Y"
79
- */
80
- public static function lastCheckDate() {
81
-
82
- // Checked users
83
- $params = array(
84
- 'fields' => 'ID',
85
- 'meta_key' => 'ct_checked',
86
- 'count_total' => true,
87
- 'orderby' => 'ct_checked'
88
- );
89
- $tmp = new WP_User_Query( $params );
90
- $cnt_checked = $tmp->get_total();
91
-
92
- if( $cnt_checked > 0 ) {
93
-
94
- // If we have checked users return last user reg date
95
- $users = $tmp->get_results();
96
- return self::getUserRegister( end( $users ) );
97
-
98
- } else {
99
-
100
- // If we have not any checked users return first user registered date
101
- $params = array(
102
- 'fields' => 'ID',
103
- 'number' => 1,
104
- 'orderby' => 'user_registered'
105
- );
106
- $tmp = new WP_User_Query( $params );
107
-
108
- return self::getUserRegister( current( $tmp->get_results() ) );
109
-
110
- }
111
-
112
- }
113
-
114
- /**
115
- * Get date user registered
116
- *
117
- * @param $user_id
118
- * @return string Date format"M j Y"
119
- */
120
- private static function getUserRegister( $user_id ) {
121
-
122
- $user_data = get_userdata( $user_id );
123
- $registered = $user_data->user_registered;
124
-
125
- return date( "M j Y", strtotime( $registered ) );
126
-
127
- }
128
-
129
- static function ct_ajax_check_users(){
130
-
131
- check_ajax_referer('ct_secret_nonce', 'security');
132
-
133
- global $apbct, $wpdb;
134
-
135
- $amount = !empty($_POST['amount']) && intval($_POST['amount'])
136
- ? intval($_POST['amount'])
137
- : 100;
138
-
139
- $skip_roles = array(
140
- 'administrator'
141
- );
142
-
143
- $from_till = '';
144
-
145
- if(isset($_POST['from'], $_POST['till'])){
146
-
147
- $from_date = date('Y-m-d', intval(strtotime($_POST['from']))) . ' 00:00:00';
148
- $till_date = date('Y-m-d', intval(strtotime($_POST['till']))) . ' 23:59:59';
149
-
150
- $from_till = " AND $wpdb->users.user_registered >= '$from_date' AND $wpdb->users.user_registered <= '$till_date'";
151
-
152
- }
153
-
154
- $u = $wpdb->get_results("
155
- SELECT {$wpdb->users}.ID, {$wpdb->users}.user_email, {$wpdb->users}.user_registered
156
- FROM {$wpdb->users}
157
- WHERE
158
- NOT EXISTS(SELECT * FROM {$wpdb->usermeta} as meta WHERE {$wpdb->users}.ID = meta.user_id AND meta.meta_key = 'ct_bad') AND
159
- NOT EXISTS(SELECT * FROM {$wpdb->usermeta} as meta WHERE {$wpdb->users}.ID = meta.user_id AND meta.meta_key = 'ct_checked') AND
160
- NOT EXISTS(SELECT * FROM {$wpdb->usermeta} as meta WHERE {$wpdb->users}.ID = meta.user_id AND meta.meta_key = 'ct_checked_now')
161
- $from_till
162
- ORDER BY {$wpdb->users}.user_registered ASC
163
- LIMIT $amount;"
164
- );
165
-
166
- $check_result = array(
167
- 'end' => 0,
168
- 'checked' => 0,
169
- 'spam' => 0,
170
- 'bad' => 0,
171
- 'error' => 0
172
- );
173
-
174
- if( count($u) > 0 ){
175
-
176
- if( ! empty( $_POST['accurate_check'] ) ){
177
- // Leaving users only with first comment's date. Unsetting others.
178
- foreach( $u as $user_index => $user ){
179
-
180
- if( ! isset( $curr_date ) )
181
- $curr_date = ( substr( $user->user_registered, 0, 10 ) ? substr( $user->user_registered, 0, 10 ) : '' );
182
-
183
- if( substr( $user->user_registered, 0, 10 ) != $curr_date )
184
- unset( $u[$user_index] );
185
-
186
- }
187
- unset( $user_index, $user );
188
- }
189
-
190
- // Checking comments IP/Email. Gathering $data for check.
191
- $data = array();
192
-
193
- for( $i=0; $i < count($u); $i++ ){
194
-
195
- $user_meta = get_user_meta( $u[$i]->ID, 'session_tokens', true );
196
- if( is_array( $user_meta ) )
197
- $user_meta = array_values( $user_meta );
198
-
199
- $curr_ip = !empty( $user_meta[0]['ip' ]) ? trim( $user_meta[0]['ip'] ) : '';
200
- $curr_email = !empty( $u[$i]->user_email ) ? trim( $u[$i]->user_email ) : '';
201
-
202
- // Check for identity
203
- $curr_ip = preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $curr_ip) === 1 ? $curr_ip : null;
204
- $curr_email = preg_match('/^\S+@\S+\.\S+$/', $curr_email) === 1 ? $curr_email : null;
205
-
206
- if( empty( $curr_ip ) && empty( $curr_email ) ){
207
- $check_result['bad']++;
208
- update_user_meta( $u[$i]->ID,'ct_bad','1',true );
209
- update_user_meta( $u[$i]->ID, 'ct_checked', date("Y-m-d H:m:s"), true) ;
210
- unset( $u[$i] );
211
- }else{
212
- if( !empty( $curr_ip ) )
213
- $data[] = $curr_ip;
214
- if( !empty( $curr_email ) )
215
- $data[] = $curr_email;
216
- // Patch for empty IP/Email
217
- $u[$i]->data = new \stdClass();
218
- $u[$i]->user_ip = empty($curr_ip) ? 'none' : $curr_ip;
219
- $u[$i]->user_email = empty($curr_email) ? 'none' : $curr_email;
220
- }
221
- }
222
-
223
- // Recombining after checking and unsettting
224
- $u = array_values( $u );
225
-
226
- // Drop if data empty and there's no users to check
227
- if( count( $data ) == 0 ){
228
- if( $_POST['unchecked'] === 0 )
229
- $check_result['end'] = 1;
230
- print json_encode( $check_result );
231
- die();
232
- }
233
-
234
- $result = \Cleantalk\ApbctWP\API::method__spam_check_cms( $apbct->api_key, $data, !empty($_POST['accurate_check']) ? $curr_date : null );
235
-
236
- if( empty( $result['error'] ) ){
237
-
238
- for( $i=0; $i < sizeof( $u ); $i++ ) {
239
-
240
- $check_result['checked']++;
241
- update_user_meta( $u[$i]->ID, 'ct_checked', date("Y-m-d H:m:s"), true) ;
242
- update_user_meta( $u[$i]->ID, 'ct_checked_now', date("Y-m-d H:m:s"), true) ;
243
-
244
- // Do not display forbidden roles.
245
- foreach ( $skip_roles as $role ) {
246
- $user_meta = get_userdata($u[$i]->ID);
247
- $user_roles = $user_meta->roles;
248
- if ( in_array( $role, $user_roles ) ){
249
- delete_user_meta( $u[$i]->ID, 'ct_marked_as_spam' );
250
- continue 2;
251
- }
252
- }
253
-
254
- $mark_spam_ip = false;
255
- $mark_spam_email = false;
256
-
257
- $uip = $u[$i]->user_ip;
258
- $uim = $u[$i]->user_email;
259
-
260
- if( isset( $result[$uip] ) && $result[$uip]['appears'] == 1 )
261
- $mark_spam_ip = true;
262
-
263
- if( isset($result[$uim]) && $result[$uim]['appears'] == 1 )
264
- $mark_spam_email = true;
265
-
266
- if ( $mark_spam_ip || $mark_spam_email ){
267
- $check_result['spam']++;
268
- update_user_meta( $u[$i]->ID, 'ct_marked_as_spam', '1', true );
269
- }
270
-
271
- }
272
-
273
- echo json_encode( $check_result );
274
-
275
- } else {
276
-
277
- $check_result['error'] = 1;
278
- $check_result['error_message'] = $result['error'];
279
-
280
- echo json_encode( $check_result );
281
-
282
- }
283
- } else {
284
-
285
- $check_result['end'] = 1;
286
-
287
- $log_data = static::get_log_data();
288
- static::writeSpamLog( 'users', date("Y-m-d H:i:s"), $log_data['checked'], $log_data['spam'], $log_data['bad'] );
289
-
290
- echo json_encode( $check_result );
291
-
292
- }
293
-
294
- die;
295
-
296
- }
297
-
298
- /**
299
- * Run query for deleting 'ct_checked_now' meta. Need for the new scan.
300
- *
301
- * @return void
302
- */
303
- public static function ct_ajax_clear_users()
304
- {
305
- check_ajax_referer( 'ct_secret_nonce', 'security' );
306
-
307
- global $wpdb;
308
- $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ('ct_checked_now')");
309
-
310
- if ( isset($_POST['from']) && isset($_POST['till']) ) {
311
- if ( preg_match('/[a-zA-Z]{3}\s{1}\d{1,2}\s{1}\d{4}/', $_POST['from'] ) && preg_match('/[a-zA-Z]{3}\s{1}\d{1,2}\s{1}\d{4}/', $_POST['till'] ) ) {
312
-
313
- $from = date('Y-m-d', intval(strtotime($_POST['from']))) . ' 00:00:00';
314
- $till = date('Y-m-d', intval(strtotime($_POST['till']))) . ' 23:59:59';
315
-
316
- $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE
317
- meta_key IN ('ct_checked','ct_marked_as_spam','ct_bad')
318
- AND meta_value >= '{$from}'
319
- AND meta_value <= '{$till}';");
320
-
321
- die();
322
-
323
- }
324
- }
325
-
326
- die();
327
- }
328
-
329
- public static function ct_ajax_info($direct_call = false) {
330
-
331
- if (!$direct_call)
332
- check_ajax_referer( 'ct_secret_nonce', 'security' );
333
-
334
- global $wpdb;
335
-
336
- // Checked users
337
- $cnt_checked = $wpdb->get_results("
338
- SELECT COUNT(*) AS cnt
339
- FROM {$wpdb->usermeta}
340
- WHERE meta_key='ct_checked_now'"
341
- )[0]->cnt;
342
-
343
- // Spam users
344
- $cnt_spam = $wpdb->get_results("
345
- SELECT COUNT({$wpdb->users}.ID) AS cnt
346
- FROM {$wpdb->users}
347
- INNER JOIN {$wpdb->usermeta} AS meta1 ON ( {$wpdb->users}.ID = meta1.user_id )
348
- INNER JOIN {$wpdb->usermeta} AS meta2 ON ( {$wpdb->users}.ID = meta2.user_id )
349
- WHERE
350
- meta1.meta_key = 'ct_marked_as_spam' AND
351
- meta2.meta_key = 'ct_checked_now';"
352
- )[0]->cnt;
353
-
354
- // Bad users (without IP and Email)
355
- $cnt_bad = $wpdb->get_results("
356
- SELECT COUNT({$wpdb->users}.ID) AS cnt
357
- FROM {$wpdb->users}
358
- INNER JOIN {$wpdb->usermeta} AS meta1 ON ( {$wpdb->users}.ID = meta1.user_id )
359
- INNER JOIN {$wpdb->usermeta} AS meta2 ON ( {$wpdb->users}.ID = meta2.user_id )
360
- WHERE
361
- meta1.meta_key = 'ct_bad' AND
362
- meta2.meta_key = 'ct_checked_now';"
363
- )[0]->cnt;
364
-
365
- $return = array(
366
- 'message' => '',
367
- 'spam' => $cnt_spam,
368
- 'checked' => $cnt_checked,
369
- 'bad' => $cnt_bad,
370
- );
371
-
372
- if( ! $direct_call ) {
373
- $return['message'] .= sprintf (
374
- esc_html__('Checked %s, found %s spam users and %s bad users (without IP or email)', 'cleantalk-spam-protect'),
375
- $cnt_checked,
376
- $cnt_spam,
377
- $cnt_bad
378
- );
379
- } else {
380
- if( isset( $return['checked'] ) && 0 == $return['checked'] ) {
381
- $return['message'] = esc_html__( 'Never checked yet or no new spam.', 'cleantalk-spam-protect');
382
- } else {
383
- $return['message'] .= sprintf (
384
- __("Last check %s: checked %s users, found %s spam users and %s bad users (without IP or email).", 'cleantalk-spam-protect'),
385
- self::lastCheckDate(),
386
- $cnt_checked,
387
- $cnt_spam,
388
- $cnt_bad
389
- );
390
- }
391
- }
392
-
393
- $backup_notice = '&nbsp;';
394
- if ($cnt_spam > 0) {
395
- $backup_notice = __("Please do backup of WordPress database before delete any accounts!", 'cleantalk-spam-protect');
396
- }
397
- $return['message'] .= "<p>$backup_notice</p>";
398
-
399
- if($direct_call){
400
- return $return['message'];
401
- }else{
402
- echo json_encode($return);
403
- die();
404
- }
405
- }
406
-
407
- private static function get_log_data() {
408
-
409
- global $wpdb;
410
-
411
- // Checked users
412
- $cnt_checked = $wpdb->get_results("
413
- SELECT COUNT(*) AS cnt
414
- FROM {$wpdb->usermeta}
415
- WHERE meta_key='ct_checked_now'"
416
- )[0]->cnt;
417
-
418
- // Spam users
419
- $cnt_spam = $wpdb->get_results("
420
- SELECT COUNT({$wpdb->users}.ID) AS cnt
421
- FROM {$wpdb->users}
422
- INNER JOIN {$wpdb->usermeta} AS meta1 ON ( {$wpdb->users}.ID = meta1.user_id )
423
- INNER JOIN {$wpdb->usermeta} AS meta2 ON ( {$wpdb->users}.ID = meta2.user_id )
424
- WHERE
425
- meta1.meta_key = 'ct_marked_as_spam' AND
426
- meta2.meta_key = 'ct_checked_now';"
427
- )[0]->cnt;
428
-
429
- // Bad users (without IP and Email)
430
- $cnt_bad = $wpdb->get_results("
431
- SELECT COUNT({$wpdb->users}.ID) AS cnt
432
- FROM {$wpdb->users}
433
- INNER JOIN {$wpdb->usermeta} AS meta1 ON ( {$wpdb->users}.ID = meta1.user_id )
434
- INNER JOIN {$wpdb->usermeta} AS meta2 ON ( {$wpdb->users}.ID = meta2.user_id )
435
- WHERE
436
- meta1.meta_key = 'ct_bad' AND
437
- meta2.meta_key = 'ct_checked_now';"
438
- )[0]->cnt;
439
-
440
- return array(
441
- 'spam' => $cnt_spam,
442
- 'checked' => $cnt_checked,
443
- 'bad' => $cnt_bad,
444
- );
445
-
446
- }
447
-
448
- /**
449
- * Admin action 'wp_ajax_ajax_ct_get_csv_file' - prints CSV file to AJAX
450
- */
451
- public static function ct_get_csv_file() {
452
-
453
- check_ajax_referer( 'ct_secret_nonce', 'security' );
454
-
455
- $text = 'login,email,ip' . PHP_EOL;
456
-
457
- $params = array(
458
- 'meta_query' => array(
459
- array(
460
- 'key' => 'ct_marked_as_spam',
461
- 'compare' => '1'
462
- ),
463
- ),
464
- 'orderby' => 'registered',
465
- 'order' => 'ASC',
466
- );
467
-
468
- $u = get_users( $params );
469
-
470
- for( $i=0; $i < count($u); $i++ ){
471
- $user_meta = get_user_meta( $u[$i]->ID, 'session_tokens', true );
472
- if( is_array( $user_meta ) )
473
- $user_meta = array_values( $user_meta );
474
- $text .= $u[$i]->user_login.',';
475
- $text .= $u[$i]->data->user_email.',';
476
- $text .= ! empty( $user_meta[0]['ip']) ? trim( $user_meta[0]['ip'] ) : '';
477
- $text .= PHP_EOL;
478
- }
479
-
480
- $filename = ! empty( $_POST['filename'] ) ? $_POST['filename'] : false;
481
-
482
- if( $filename !== false ) {
483
- header('Content-Type: text/csv');
484
- echo $text;
485
- } else {
486
- echo 'Export error.'; // file not exists or empty $_POST['filename']
487
- }
488
- die();
489
-
490
- }
491
-
492
- public static function ct_ajax_insert_users()
493
- {
494
-
495
- check_ajax_referer( 'ct_secret_nonce', 'security' );
496
-
497
- //* DELETION
498
- if(!empty($_POST['delete'])){
499
- $users = get_users(array('search' => 'user_*', 'search_columns' => array('login', 'nicename')));
500
- $deleted = 0;
501
- $amount_to_delete = 1000;
502
- foreach($users as $user){
503
- if($deleted >= $amount_to_delete)
504
- break;
505
- if(wp_delete_user($user->ID))
506
- $deleted++;
507
- }
508
- print "$deleted";
509
- die();
510
- }
511
- //*/
512
-
513
- //* INSERTION
514
- global $wpdb;
515
- $to_insert = 500;
516
- $result = $wpdb->get_results('SELECT network FROM `'. APBCT_TBL_FIREWALL_DATA .'` LIMIT '. $to_insert .';', ARRAY_A);
517
-
518
- if($result){
519
- $ip = array();
520
- foreach($result as $value){
521
- $ips[] = long2ip($value['network']);
522
- }
523
- unset($value);
524
-
525
- $inserted = 0;
526
- for($i=0; $i<$to_insert; $i++){
527
- $rnd=mt_rand(1,10000000);
528
-
529
- $user_name = "user_$rnd";
530
- $email="stop_email_$rnd@example.com";
531
-
532
- $user_id = wp_create_user(
533
- $user_name,
534
- rand(),
535
- $email
536
- );
537
-
538
- $curr_user = get_user_by('email', $email);
539
-
540
- update_user_meta($curr_user->ID, 'session_tokens', array($rnd => array('ip' => $ips[$i])));
541
-
542
- if (is_int($user_id))
543
- $inserted++;
544
-
545
- }
546
- }else{
547
- $inserted = '0';
548
- }
549
- //*/
550
-
551
- print "$inserted";
552
- die();
553
- }
554
-
555
- public static function ct_ajax_delete_all_users($count_all = 0)
556
- {
557
- check_ajax_referer( 'ct_secret_nonce', 'security' );
558
-
559
- global $wpdb;
560
-
561
- $r = $wpdb->get_results("select count(*) as cnt from $wpdb->usermeta where meta_key='ct_marked_as_spam';", OBJECT );
562
-
563
- if(!empty($r)){
564
-
565
- $count_all = $r ? $r[0]->cnt : 0;
566
-
567
- $args = array(
568
- 'meta_key' => 'ct_marked_as_spam',
569
- 'meta_value' => '1',
570
- 'fields' => array('ID'),
571
- 'number' => 50
572
- );
573
- $users = get_users($args);
574
-
575
- if ($users){
576
- foreach($users as $user){
577
- wp_delete_user($user->ID);
578
- usleep(5000);
579
- }
580
- }
581
- }
582
-
583
- die($count_all);
584
- }
585
-
586
- /**
587
- * Add hidden column into the users table
588
- *
589
- * @param $columns
590
- * @return mixed
591
- */
592
- public static function ct_manage_users_columns( $columns ) {
593
-
594
- $columns['apbct_status hidden'] = '';
595
- return $columns;
596
-
597
- }
598
-
599
- /**
600
- * Generates <span> with information about user scan using user's meta.
601
- *
602
- * @param $value
603
- * @param $column_name
604
- * @param $user_id
605
- * @return string
606
- */
607
- public static function ct_manage_users_custom_column( $value, $column_name, $user_id ) {
608
-
609
- if( 'apbct_status hidden' == $column_name ) {
610
-
611
- $is_checked = get_user_meta( $user_id, 'ct_checked', true);
612
- if( ! empty( $is_checked ) ) {
613
- $is_checked = date( 'M d Y', strtotime( $is_checked ) );
614
- $is_spam = get_user_meta( $user_id, 'ct_marked_as_spam', true );
615
- if( ! empty( $is_spam ) ) {
616
- $text = sprintf( esc_html__( 'SPAM. Checked %s.', 'cleantalk-spam-protect'), $is_checked );
617
- $value = '<span id="apbct_checked_spam">' . $text . '</span>';
618
- } else {
619
- $text = sprintf( esc_html__( 'Not spam. Checked %s.', 'cleantalk-spam-protect'), $is_checked );
620
- $value = '<span id="apbct_checked_not_spam">' . $text . '</span>';
621
- }
622
- } else {
623
- $value = '<span id="apbct_not_checked">' . esc_html__( 'Not checked yet. Anti-Spam by CleanTalk.', 'cleantalk-spam-protect') . '</span>';
624
- }
625
-
626
- }
627
-
628
- return $value;
629
-
630
- }
631
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
632
  }
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\FindSpam;
4
+
5
+ class UsersChecker extends Checker
6
+ {
7
+
8
+ public function __construct() {
9
+
10
+ parent::__construct();
11
+
12
+ $this->page_title = esc_html__( 'Check users for spam', 'cleantalk-spam-protect');
13
+ $this->page_script_name = 'users.php';
14
+ $this->page_slug = 'users';
15
+
16
+ // Preparing data
17
+ $current_user = wp_get_current_user();
18
+ if( ! empty( $_COOKIE['ct_paused_users_check'] ) )
19
+ $prev_check = json_decode( stripslashes( $_COOKIE['ct_paused_users_check'] ), true );
20
+
21
+ wp_enqueue_script( 'ct_users_checkspam', plugins_url('/cleantalk-spam-protect/js/cleantalk-users-checkspam.min.js'), array( 'jquery', 'jqueryui' ), APBCT_VERSION );
22
+ wp_localize_script( 'ct_users_checkspam', 'ctUsersCheck', array(
23
+ 'ct_ajax_nonce' => wp_create_nonce('ct_secret_nonce'),
24
+ 'ct_prev_accurate' => !empty($prev_check['accurate']) ? true : false,
25
+ 'ct_prev_from' => !empty($prev_check['from']) ? $prev_check['from'] : false,
26
+ 'ct_prev_till' => !empty($prev_check['till']) ? $prev_check['till'] : false,
27
+ 'ct_timeout' => __('Failed from timeout. Going to check users again.', 'cleantalk-spam-protect'),
28
+ 'ct_timeout_delete' => __('Failed from timeout. Going to run a new attempt to delete spam users.', 'cleantalk-spam-protect'),
29
+ 'ct_confirm_deletion_all' => __('Delete all spam users?', 'cleantalk-spam-protect'),
30
+ 'ct_iusers' => __('users.', 'cleantalk-spam-protect'),
31
+ 'ct_csv_filename' => "user_check_by_".$current_user->user_login,
32
+ 'ct_status_string' => __("Checked %s, found %s spam users and %s bad users (without IP or email)", 'cleantalk-spam-protect'),
33
+ 'ct_status_string_warning' => "<p>".__("Please do backup of WordPress database before delete any accounts!", 'cleantalk-spam-protect')."</p>"
34
+ ));
35
+
36
+ wp_enqueue_style( 'cleantalk_admin_css_settings_page', plugins_url().'/cleantalk-spam-protect/css/cleantalk-spam-check.min.css', array(), APBCT_VERSION, 'all' );
37
+
38
+ }
39
+
40
+ public function getCurrentScanPage() {
41
+
42
+ $this->list_table = new \Cleantalk\ApbctWP\FindSpam\ListTable\UsersScan();
43
+
44
+ $this->getCurrentScanPanel( $this );
45
+ echo '<form action="" method="POST">';
46
+ $this->list_table->display();
47
+ echo '</form>';
48
+
49
+ }
50
+
51
+ public function getSpamLogsPage(){
52
+
53
+ $this->list_table = new \Cleantalk\ApbctWP\FindSpam\ListTable\UsersLogs();
54
+
55
+ echo '<form action="" method="POST">';
56
+ $this->list_table->display();
57
+ echo '</form>';
58
+
59
+ }
60
+
61
+ /**
62
+ * Getting a count of total users of the website and return formatted string about this.
63
+ *
64
+ * @return string
65
+ */
66
+ public static function get_count_text() {
67
+
68
+ $res = count_users();
69
+
70
+ if( $res['total_users'] ) {
71
+ $text = sprintf( esc_html__ ('Total count of users: %s.', 'cleantalk-spam-protect' ), $res['total_users'] );
72
+ } else {
73
+ $text = esc_html__( 'No users found.', 'cleantalk-spam-protect' );
74
+ }
75
+
76
+ return $text;
77
+
78
+ }
79
+
80
+ /**
81
+ * Get date last checked user or date first registered user
82
+ *
83
+ * @return string date "M j Y"
84
+ */
85
+ public static function lastCheckDate() {
86
+
87
+ // Checked users
88
+ $params = array(
89
+ 'fields' => 'ID',
90
+ 'meta_key' => 'ct_checked',
91
+ 'count_total' => true,
92
+ 'orderby' => 'ct_checked'
93
+ );
94
+ $tmp = new \WP_User_Query( $params );
95
+ $cnt_checked = $tmp->get_total();
96
+
97
+ if( $cnt_checked > 0 ) {
98
+
99
+ // If we have checked users return last user reg date
100
+ $users = $tmp->get_results();
101
+ return self::getUserRegister( end( $users ) );
102
+
103
+ } else {
104
+
105
+ // If we have not any checked users return first user registered date
106
+ $params = array(
107
+ 'fields' => 'ID',
108
+ 'number' => 1,
109
+ 'orderby' => 'user_registered'
110
+ );
111
+ $tmp = new \WP_User_Query( $params );
112
+
113
+ return self::getUserRegister( current( $tmp->get_results() ) );
114
+
115
+ }
116
+
117
+ }
118
+
119
+ /**
120
+ * Get date user registered
121
+ *
122
+ * @param $user_id
123
+ * @return string Date format"M j Y"
124
+ */
125
+ private static function getUserRegister( $user_id ) {
126
+
127
+ $user_data = get_userdata( $user_id );
128
+ $registered = $user_data->user_registered;
129
+
130
+ return date( "M j Y", strtotime( $registered ) );
131
+
132
+ }
133
+
134
+ static function ct_ajax_check_users(){
135
+
136
+ check_ajax_referer('ct_secret_nonce', 'security');
137
+
138
+ global $apbct, $wpdb;
139
+
140
+ $amount = !empty($_POST['amount']) && intval($_POST['amount'])
141
+ ? intval($_POST['amount'])
142
+ : 100;
143
+
144
+ $skip_roles = array(
145
+ 'administrator'
146
+ );
147
+
148
+ $from_till = '';
149
+
150
+ if(isset($_POST['from'], $_POST['till'])){
151
+
152
+ $from_date = date('Y-m-d', intval(strtotime($_POST['from']))) . ' 00:00:00';
153
+ $till_date = date('Y-m-d', intval(strtotime($_POST['till']))) . ' 23:59:59';
154
+
155
+ $from_till = " AND $wpdb->users.user_registered >= '$from_date' AND $wpdb->users.user_registered <= '$till_date'";
156
+
157
+ }
158
+
159
+ $u = $wpdb->get_results("
160
+ SELECT {$wpdb->users}.ID, {$wpdb->users}.user_email, {$wpdb->users}.user_registered
161
+ FROM {$wpdb->users}
162
+ WHERE
163
+ NOT EXISTS(SELECT * FROM {$wpdb->usermeta} as meta WHERE {$wpdb->users}.ID = meta.user_id AND meta.meta_key = 'ct_bad') AND
164
+ NOT EXISTS(SELECT * FROM {$wpdb->usermeta} as meta WHERE {$wpdb->users}.ID = meta.user_id AND meta.meta_key = 'ct_checked') AND
165
+ NOT EXISTS(SELECT * FROM {$wpdb->usermeta} as meta WHERE {$wpdb->users}.ID = meta.user_id AND meta.meta_key = 'ct_checked_now')
166
+ $from_till
167
+ ORDER BY {$wpdb->users}.user_registered ASC
168
+ LIMIT $amount;"
169
+ );
170
+
171
+ $check_result = array(
172
+ 'end' => 0,
173
+ 'checked' => 0,
174
+ 'spam' => 0,
175
+ 'bad' => 0,
176
+ 'error' => 0
177
+ );
178
+
179
+ if( count($u) > 0 ){
180
+
181
+ if( ! empty( $_POST['accurate_check'] ) ){
182
+ // Leaving users only with first comment's date. Unsetting others.
183
+ foreach( $u as $user_index => $user ){
184
+
185
+ if( ! isset( $curr_date ) )
186
+ $curr_date = ( substr( $user->user_registered, 0, 10 ) ? substr( $user->user_registered, 0, 10 ) : '' );
187
+
188
+ if( substr( $user->user_registered, 0, 10 ) != $curr_date )
189
+ unset( $u[$user_index] );
190
+
191
+ }
192
+ unset( $user_index, $user );
193
+ }
194
+
195
+ // Checking comments IP/Email. Gathering $data for check.
196
+ $data = array();
197
+
198
+ for( $i=0; $i < count($u); $i++ ){
199
+
200
+ $user_meta = get_user_meta( $u[$i]->ID, 'session_tokens', true );
201
+ if( is_array( $user_meta ) )
202
+ $user_meta = array_values( $user_meta );
203
+
204
+ $curr_ip = !empty( $user_meta[0]['ip' ]) ? trim( $user_meta[0]['ip'] ) : '';
205
+ $curr_email = !empty( $u[$i]->user_email ) ? trim( $u[$i]->user_email ) : '';
206
+
207
+ // Check for identity
208
+ $curr_ip = preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $curr_ip) === 1 ? $curr_ip : null;
209
+ $curr_email = preg_match('/^\S+@\S+\.\S+$/', $curr_email) === 1 ? $curr_email : null;
210
+
211
+ if( empty( $curr_ip ) && empty( $curr_email ) ){
212
+ $check_result['bad']++;
213
+ update_user_meta( $u[$i]->ID,'ct_bad','1',true );
214
+ update_user_meta( $u[$i]->ID, 'ct_checked', date("Y-m-d H:m:s"), true) ;
215
+ update_user_meta( $u[$i]->ID, 'ct_checked_now', '1', true) ;
216
+ unset( $u[$i] );
217
+ }else{
218
+ if( !empty( $curr_ip ) )
219
+ $data[] = $curr_ip;
220
+ if( !empty( $curr_email ) )
221
+ $data[] = $curr_email;
222
+ // Patch for empty IP/Email
223
+ $u[$i]->data = new \stdClass();
224
+ $u[$i]->user_ip = empty($curr_ip) ? 'none' : $curr_ip;
225
+ $u[$i]->user_email = empty($curr_email) ? 'none' : $curr_email;
226
+ }
227
+ }
228
+
229
+ // Recombining after checking and unsettting
230
+ $u = array_values( $u );
231
+
232
+ // Drop if data empty and there's no users to check
233
+ if( count( $data ) == 0 ){
234
+ if( $_POST['unchecked'] === 0 )
235
+ $check_result['end'] = 1;
236
+ print json_encode( $check_result );
237
+ die();
238
+ }
239
+
240
+ $result = \Cleantalk\ApbctWP\API::method__spam_check_cms( $apbct->api_key, $data, !empty($_POST['accurate_check']) ? $curr_date : null );
241
+
242
+ if( empty( $result['error'] ) ){
243
+
244
+ for( $i=0; $i < sizeof( $u ); $i++ ) {
245
+
246
+ $check_result['checked']++;
247
+ update_user_meta( $u[$i]->ID, 'ct_checked', date("Y-m-d H:m:s"), true) ;
248
+ update_user_meta( $u[$i]->ID, 'ct_checked_now', date("Y-m-d H:m:s"), true) ;
249
+
250
+ // Do not display forbidden roles.
251
+ foreach ( $skip_roles as $role ) {
252
+ $user_meta = get_userdata($u[$i]->ID);
253
+ $user_roles = $user_meta->roles;
254
+ if ( in_array( $role, $user_roles ) ){
255
+ delete_user_meta( $u[$i]->ID, 'ct_marked_as_spam' );
256
+ continue 2;
257
+ }
258
+ }
259
+
260
+ $mark_spam_ip = false;
261
+ $mark_spam_email = false;
262
+
263
+ $uip = $u[$i]->user_ip;
264
+ $uim = $u[$i]->user_email;
265
+
266
+ if( isset( $result[$uip] ) && $result[$uip]['appears'] == 1 )
267
+ $mark_spam_ip = true;
268
+
269
+ if( isset($result[$uim]) && $result[$uim]['appears'] == 1 )
270
+ $mark_spam_email = true;
271
+
272
+ if ( $mark_spam_ip || $mark_spam_email ){
273
+ $check_result['spam']++;
274
+ update_user_meta( $u[$i]->ID, 'ct_marked_as_spam', '1', true );
275
+ }
276
+
277
+ }
278
+
279
+ echo json_encode( $check_result );
280
+
281
+ } else {
282
+
283
+ $check_result['error'] = 1;
284
+ $check_result['error_message'] = $result['error'];
285
+
286
+ echo json_encode( $check_result );
287
+
288
+ }
289
+ } else {
290
+
291
+ $check_result['end'] = 1;
292
+
293
+ $log_data = static::get_log_data();
294
+ static::writeSpamLog( 'users', date("Y-m-d H:i:s"), $log_data['checked'], $log_data['spam'], $log_data['bad'] );
295
+
296
+ echo json_encode( $check_result );
297
+
298
+ }
299
+
300
+ die;
301
+
302
+ }
303
+
304
+ /**
305
+ * Run query for deleting 'ct_checked_now' meta. Need for the new scan.
306
+ *
307
+ * @return void
308
+ */
309
+ public static function ct_ajax_clear_users()
310
+ {
311
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
312
+
313
+ global $wpdb;
314
+ $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ('ct_checked_now')");
315
+
316
+ if ( isset($_POST['from']) && isset($_POST['till']) ) {
317
+ if ( preg_match('/[a-zA-Z]{3}\s{1}\d{1,2}\s{1}\d{4}/', $_POST['from'] ) && preg_match('/[a-zA-Z]{3}\s{1}\d{1,2}\s{1}\d{4}/', $_POST['till'] ) ) {
318
+
319
+ $from = date('Y-m-d', intval(strtotime($_POST['from']))) . ' 00:00:00';
320
+ $till = date('Y-m-d', intval(strtotime($_POST['till']))) . ' 23:59:59';
321
+
322
+ $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE
323
+ meta_key IN ('ct_checked','ct_marked_as_spam','ct_bad')
324
+ AND meta_value >= '{$from}'
325
+ AND meta_value <= '{$till}';");
326
+ die();
327
+ } else {
328
+ $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE
329
+ meta_key IN ('ct_checked','ct_marked_as_spam','ct_bad')");
330
+ die();
331
+ }
332
+ }
333
+
334
+ die();
335
+ }
336
+
337
+ public static function ct_ajax_info($direct_call = false) {
338
+
339
+ if (!$direct_call)
340
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
341
+
342
+ global $wpdb;
343
+
344
+ // Checked users
345
+ $cnt_checked = $wpdb->get_results("
346
+ SELECT COUNT(*) AS cnt
347
+ FROM {$wpdb->usermeta}
348
+ WHERE meta_key='ct_checked_now'"
349
+ )[0]->cnt;
350
+
351
+ // Spam users
352
+ $cnt_spam = $wpdb->get_results("
353
+ SELECT COUNT({$wpdb->users}.ID) AS cnt
354
+ FROM {$wpdb->users}
355
+ INNER JOIN {$wpdb->usermeta} AS meta1 ON ( {$wpdb->users}.ID = meta1.user_id )
356
+ INNER JOIN {$wpdb->usermeta} AS meta2 ON ( {$wpdb->users}.ID = meta2.user_id )
357
+ WHERE
358
+ meta1.meta_key = 'ct_marked_as_spam' AND
359
+ meta2.meta_key = 'ct_checked_now';"
360
+ )[0]->cnt;
361
+
362
+ // Bad users (without IP and Email)
363
+ $cnt_bad = $wpdb->get_results("
364
+ SELECT COUNT({$wpdb->users}.ID) AS cnt
365
+ FROM {$wpdb->users}
366
+ INNER JOIN {$wpdb->usermeta} AS meta1 ON ( {$wpdb->users}.ID = meta1.user_id )
367
+ INNER JOIN {$wpdb->usermeta} AS meta2 ON ( {$wpdb->users}.ID = meta2.user_id )
368
+ WHERE
369
+ meta1.meta_key = 'ct_bad' AND
370
+ meta2.meta_key = 'ct_checked_now';"
371
+ )[0]->cnt;
372
+
373
+ $return = array(
374
+ 'message' => '',
375
+ 'spam' => $cnt_spam,
376
+ 'checked' => $cnt_checked,
377
+ 'bad' => $cnt_bad,
378
+ );
379
+
380
+ if( ! $direct_call ) {
381
+ $return['message'] .= sprintf (
382
+ esc_html__('Checked %s, found %s spam users and %s bad users (without IP or email)', 'cleantalk-spam-protect'),
383
+ $cnt_checked,
384
+ $cnt_spam,
385
+ $cnt_bad
386
+ );
387
+ } else {
388
+
389
+ global $wpdb;
390
+
391
+ $query = "SELECT * FROM " . APBCT_SPAMSCAN_LOGS . " WHERE scan_type = 'users' ORDER BY start_time DESC";
392
+ $res = $wpdb->get_row( $query, ARRAY_A );
393
+
394
+ if ( $res ) {
395
+ $return['message'] .= sprintf (
396
+ __("Last check %s: checked %s users, found %s spam users and %s bad users (without IP or email).", 'cleantalk-spam-protect'),
397
+ self::lastCheckDate(),
398
+ $cnt_checked,
399
+ $cnt_spam,
400
+ $cnt_bad
401
+ );
402
+ } else {
403
+ $return['message'] = esc_html__( 'Never checked yet or no new spam.', 'cleantalk-spam-protect');
404
+ }
405
+
406
+ }
407
+
408
+ $backup_notice = '&nbsp;';
409
+ if ($cnt_spam > 0) {
410
+ $backup_notice = __("Please do backup of WordPress database before delete any accounts!", 'cleantalk-spam-protect');
411
+ }
412
+ $return['message'] .= "<p>$backup_notice</p>";
413
+
414
+ if($direct_call){
415
+ return $return['message'];
416
+ }else{
417
+ echo json_encode($return);
418
+ die();
419
+ }
420
+ }
421
+
422
+ private static function get_log_data() {
423
+
424
+ global $wpdb;
425
+
426
+ // Checked users
427
+ $cnt_checked = $wpdb->get_results("
428
+ SELECT COUNT(*) AS cnt
429
+ FROM {$wpdb->usermeta}
430
+ WHERE meta_key='ct_checked_now'"
431
+ )[0]->cnt;
432
+
433
+ // Spam users
434
+ $cnt_spam = $wpdb->get_results("
435
+ SELECT COUNT({$wpdb->users}.ID) AS cnt
436
+ FROM {$wpdb->users}
437
+ INNER JOIN {$wpdb->usermeta} AS meta1 ON ( {$wpdb->users}.ID = meta1.user_id )
438
+ INNER JOIN {$wpdb->usermeta} AS meta2 ON ( {$wpdb->users}.ID = meta2.user_id )
439
+ WHERE
440
+ meta1.meta_key = 'ct_marked_as_spam' AND
441
+ meta2.meta_key = 'ct_checked_now';"
442
+ )[0]->cnt;
443
+
444
+ // Bad users (without IP and Email)
445
+ $cnt_bad = $wpdb->get_results("
446
+ SELECT COUNT({$wpdb->users}.ID) AS cnt
447
+ FROM {$wpdb->users}
448
+ INNER JOIN {$wpdb->usermeta} AS meta1 ON ( {$wpdb->users}.ID = meta1.user_id )
449
+ INNER JOIN {$wpdb->usermeta} AS meta2 ON ( {$wpdb->users}.ID = meta2.user_id )
450
+ WHERE
451
+ meta1.meta_key = 'ct_bad' AND
452
+ meta2.meta_key = 'ct_checked_now';"
453
+ )[0]->cnt;
454
+
455
+ return array(
456
+ 'spam' => $cnt_spam,
457
+ 'checked' => $cnt_checked,
458
+ 'bad' => $cnt_bad,
459
+ );
460
+
461
+ }
462
+
463
+ /**
464
+ * Admin action 'wp_ajax_ajax_ct_get_csv_file' - prints CSV file to AJAX
465
+ */
466
+ public static function ct_get_csv_file() {
467
+
468
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
469
+
470
+ $text = 'login,email,ip' . PHP_EOL;
471
+
472
+ $params = array(
473
+ 'meta_query' => array(
474
+ array(
475
+ 'key' => 'ct_marked_as_spam',
476
+ 'compare' => '1'
477
+ ),
478
+ ),
479
+ 'orderby' => 'registered',
480
+ 'order' => 'ASC',
481
+ );
482
+
483
+ $u = get_users( $params );
484
+
485
+ for( $i=0; $i < count($u); $i++ ){
486
+ $user_meta = get_user_meta( $u[$i]->ID, 'session_tokens', true );
487
+ if( is_array( $user_meta ) )
488
+ $user_meta = array_values( $user_meta );
489
+ $text .= $u[$i]->user_login.',';
490
+ $text .= $u[$i]->data->user_email.',';
491
+ $text .= ! empty( $user_meta[0]['ip']) ? trim( $user_meta[0]['ip'] ) : '';
492
+ $text .= PHP_EOL;
493
+ }
494
+
495
+ $filename = ! empty( $_POST['filename'] ) ? $_POST['filename'] : false;
496
+
497
+ if( $filename !== false ) {
498
+ header('Content-Type: text/csv');
499
+ echo $text;
500
+ } else {
501
+ echo 'Export error.'; // file not exists or empty $_POST['filename']
502
+ }
503
+ die();
504
+
505
+ }
506
+
507
+ public static function ct_ajax_insert_users()
508
+ {
509
+
510
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
511
+
512
+ //* DELETION
513
+ if(!empty($_POST['delete'])){
514
+ $users = get_users(array('search' => 'user_*', 'search_columns' => array('login', 'nicename')));
515
+ $deleted = 0;
516
+ $amount_to_delete = 1000;
517
+ foreach($users as $user){
518
+ if($deleted >= $amount_to_delete)
519
+ break;
520
+ if(wp_delete_user($user->ID))
521
+ $deleted++;
522
+ }
523
+ print "$deleted";
524
+ die();
525
+ }
526
+ //*/
527
+
528
+ //* INSERTION
529
+ global $wpdb;
530
+ $to_insert = 500;
531
+ $result = $wpdb->get_results('SELECT network FROM `'. APBCT_TBL_FIREWALL_DATA .'` LIMIT '. $to_insert .';', ARRAY_A);
532
+
533
+ if($result){
534
+ $ip = array();
535
+ foreach($result as $value){
536
+ $ips[] = long2ip($value['network']);
537
+ }
538
+ unset($value);
539
+
540
+ $inserted = 0;
541
+ for($i=0; $i<$to_insert; $i++){
542
+ $rnd=mt_rand(1,10000000);
543
+
544
+ $user_name = "user_$rnd";
545
+ $email="stop_email_$rnd@example.com";
546
+
547
+ $user_id = wp_create_user(
548
+ $user_name,
549
+ rand(),
550
+ $email
551
+ );
552
+
553
+ $curr_user = get_user_by('email', $email);
554
+
555
+ update_user_meta($curr_user->ID, 'session_tokens', array($rnd => array('ip' => $ips[$i])));
556
+
557
+ if (is_int($user_id))
558
+ $inserted++;
559
+
560
+ }
561
+ }else{
562
+ $inserted = '0';
563
+ }
564
+ //*/
565
+
566
+ print "$inserted";
567
+ die();
568
+ }
569
+
570
+ public static function ct_ajax_delete_all_users($count_all = 0)
571
+ {
572
+ check_ajax_referer( 'ct_secret_nonce', 'security' );
573
+
574
+ global $wpdb;
575
+
576
+ $r = $wpdb->get_results("select count(*) as cnt from $wpdb->usermeta where meta_key='ct_marked_as_spam';", OBJECT );
577
+
578
+ if(!empty($r)){
579
+
580
+ $count_all = $r ? $r[0]->cnt : 0;
581
+
582
+ $args = array(
583
+ 'meta_key' => 'ct_marked_as_spam',
584
+ 'meta_value' => '1',
585
+ 'fields' => array('ID'),
586
+ 'number' => 50
587
+ );
588
+ $users = get_users($args);
589
+
590
+ if ($users){
591
+ foreach($users as $user){
592
+ wp_delete_user($user->ID);
593
+ usleep(5000);
594
+ }
595
+ }
596
+ }
597
+
598
+ die($count_all);
599
+ }
600
+
601
+ /**
602
+ * Add hidden column into the users table
603
+ *
604
+ * @param $columns
605
+ * @return mixed
606
+ */
607
+ public static function ct_manage_users_columns( $columns ) {
608
+
609
+ $columns['apbct_status hidden'] = '';
610
+ return $columns;
611
+
612
+ }
613
+
614
+ /**
615
+ * Generates <span> with information about user scan using user's meta.
616
+ *
617
+ * @param $value
618
+ * @param $column_name
619
+ * @param $user_id
620
+ * @return string
621
+ */
622
+ public static function ct_manage_users_custom_column( $value, $column_name, $user_id ) {
623
+
624
+ if( 'apbct_status hidden' == $column_name ) {
625
+
626
+ $is_checked = get_user_meta( $user_id, 'ct_checked', true);
627
+ if( ! empty( $is_checked ) ) {
628
+ $is_checked = date( 'M d Y', strtotime( $is_checked ) );
629
+ $is_spam = get_user_meta( $user_id, 'ct_marked_as_spam', true );
630
+ if( ! empty( $is_spam ) ) {
631
+ $text = sprintf( esc_html__( 'SPAM. Checked %s.', 'cleantalk-spam-protect'), $is_checked );
632
+ $value = '<span id="apbct_checked_spam">' . $text . '</span>';
633
+ } else {
634
+ $text = sprintf( esc_html__( 'Not spam. Checked %s.', 'cleantalk-spam-protect'), $is_checked );
635
+ $value = '<span id="apbct_checked_not_spam">' . $text . '</span>';
636
+ }
637
+ } else {
638
+ $value = '<span id="apbct_not_checked">' . esc_html__( 'Not checked yet. Anti-Spam by CleanTalk.', 'cleantalk-spam-protect') . '</span>';
639
+ }
640
+
641
+ }
642
+
643
+ return $value;
644
+
645
+ }
646
+
647
  }
lib/Cleantalk/ApbctWP/Firewall/AntiCrawler.php CHANGED
@@ -2,7 +2,6 @@
2
 
3
  namespace Cleantalk\ApbctWP\Firewall;
4
 
5
-
6
  use Cleantalk\Common\Helper as Helper;
7
  use Cleantalk\Variables\Cookie;
8
  use Cleantalk\Variables\Server;
@@ -15,6 +14,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
15
  private $api_key = '';
16
  private $apbct = false;
17
  private $store_interval = 60;
 
18
 
19
  public $isExcluded = false;
20
 
@@ -29,6 +29,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
29
 
30
  $this->db__table__logs = $log_table ?: null;
31
  $this->db__table__ac_logs = $ac_logs_table ?: null;
 
32
 
33
  foreach( $params as $param_name => $param ){
34
  $this->$param_name = isset( $this->$param_name ) ? $param : false;
@@ -66,13 +67,12 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
66
 
67
  // Common check
68
  foreach( $this->ip_array as $ip_origin => $current_ip ){
69
-
70
- // @todo Rename ip column to sign. Use IP + UserAgent for it.
71
-
72
  $result = $this->db->fetch(
73
  "SELECT ip"
74
  . ' FROM `' . $this->db__table__ac_logs . '`'
75
  . " WHERE ip = '$current_ip'"
 
76
  . " LIMIT 1;"
77
  );
78
 
@@ -119,15 +119,17 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
119
  // @todo Rename ip column to sign. Use IP + UserAgent for it.
120
 
121
  foreach( $this->ip_array as $ip_origin => $current_ip ){
122
- $id = md5( $current_ip . $interval_time );
123
  $this->db->execute(
124
  "INSERT INTO " . $this->db__table__ac_logs . " SET
125
  id = '$id',
126
  ip = '$current_ip',
 
127
  entries = 1,
128
  interval_start = $interval_time
129
  ON DUPLICATE KEY UPDATE
130
  ip = ip,
 
131
  entries = entries + 1,
132
  interval_start = $interval_time;"
133
  );
@@ -181,8 +183,8 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
181
  // Translation
182
  $replaces = array(
183
  '{SFW_DIE_NOTICE_IP}' => __('Anti-Crawler Protection is activated for your IP ', 'cleantalk-spam-protect'),
184
- '{SFW_DIE_MAKE_SURE_JS_ENABLED}' => __( 'To continue working with web site, please make sure that you have enabled JavaScript.', 'cleantalk-spam-protect' ),
185
- '{SFW_DIE_YOU_WILL_BE_REDIRECTED}' => sprintf( __( 'You will be automatically redirected to the requested page after %d seconds.', 'cleantalk-spam-protect' ), 30 ),
186
  '{CLEANTALK_TITLE}' => __( 'Antispam by CleanTalk', 'cleantalk-spam-protect' ),
187
  '{REMOTE_ADDRESS}' => $result['ip'],
188
  '{SERVICE_ID}' => $this->apbct->data['service_id'],
2
 
3
  namespace Cleantalk\ApbctWP\Firewall;
4
 
 
5
  use Cleantalk\Common\Helper as Helper;
6
  use Cleantalk\Variables\Cookie;
7
  use Cleantalk\Variables\Server;
14
  private $api_key = '';
15
  private $apbct = false;
16
  private $store_interval = 60;
17
+ private $ua; //User-Agent
18
 
19
  public $isExcluded = false;
20
 
29
 
30
  $this->db__table__logs = $log_table ?: null;
31
  $this->db__table__ac_logs = $ac_logs_table ?: null;
32
+ $this->ua = md5( Server::get('HTTP_USER_AGENT') );
33
 
34
  foreach( $params as $param_name => $param ){
35
  $this->$param_name = isset( $this->$param_name ) ? $param : false;
67
 
68
  // Common check
69
  foreach( $this->ip_array as $ip_origin => $current_ip ){
70
+
 
 
71
  $result = $this->db->fetch(
72
  "SELECT ip"
73
  . ' FROM `' . $this->db__table__ac_logs . '`'
74
  . " WHERE ip = '$current_ip'"
75
+ . " AND ua = '$this->ua'"
76
  . " LIMIT 1;"
77
  );
78
 
119
  // @todo Rename ip column to sign. Use IP + UserAgent for it.
120
 
121
  foreach( $this->ip_array as $ip_origin => $current_ip ){
122
+ $id = md5( $current_ip . $this->ua. $interval_time );
123
  $this->db->execute(
124
  "INSERT INTO " . $this->db__table__ac_logs . " SET
125
  id = '$id',
126
  ip = '$current_ip',
127
+ ua = '$this->ua',
128
  entries = 1,
129
  interval_start = $interval_time
130
  ON DUPLICATE KEY UPDATE
131
  ip = ip,
132
+ ua = '$this->ua',
133
  entries = entries + 1,
134
  interval_start = $interval_time;"
135
  );
183
  // Translation
184
  $replaces = array(
185
  '{SFW_DIE_NOTICE_IP}' => __('Anti-Crawler Protection is activated for your IP ', 'cleantalk-spam-protect'),
186
+ '{SFW_DIE_MAKE_SURE_JS_ENABLED}' => __( 'To continue working with the web site, please make sure that you have enabled JavaScript.', 'cleantalk-spam-protect' ),
187
+ '{SFW_DIE_YOU_WILL_BE_REDIRECTED}' => sprintf( __( 'You will be automatically redirected to the requested page after %d seconds.', 'cleantalk-spam-protect' ), 3 ) . '<br>' . __( 'Don\'t close this page. Please, wait for 3 seconds to pass to the page.', 'cleantalk-spam-protect' ),
188
  '{CLEANTALK_TITLE}' => __( 'Antispam by CleanTalk', 'cleantalk-spam-protect' ),
189
  '{REMOTE_ADDRESS}' => $result['ip'],
190
  '{SERVICE_ID}' => $this->apbct->data['service_id'],
lib/Cleantalk/ApbctWP/Firewall/AntiFlood.php CHANGED
@@ -170,7 +170,7 @@ class AntiFlood extends \Cleantalk\Common\Firewall\FirewallModule{
170
  // Translation
171
  $replaces = array(
172
  '{SFW_DIE_NOTICE_IP}' => __( 'Anti-Flood is activated for your IP', 'cleantalk-spam-protect' ),
173
- '{SFW_DIE_MAKE_SURE_JS_ENABLED}' => __( 'To continue working with web site, please make sure that you have enabled JavaScript.', 'cleantalk-spam-protect' ),
174
  '{SFW_DIE_YOU_WILL_BE_REDIRECTED}' => sprintf( __( 'You will be automatically redirected to the requested page after %d seconds.', 'cleantalk-spam-protect' ), 30 ),
175
  '{CLEANTALK_TITLE}' => __( 'Antispam by CleanTalk', 'cleantalk-spam-protect' ),
176
  '{REMOTE_ADDRESS}' => $result['ip'],
170
  // Translation
171
  $replaces = array(
172
  '{SFW_DIE_NOTICE_IP}' => __( 'Anti-Flood is activated for your IP', 'cleantalk-spam-protect' ),
173
+ '{SFW_DIE_MAKE_SURE_JS_ENABLED}' => __( 'To continue working with the web site, please make sure that you have enabled JavaScript.', 'cleantalk-spam-protect' ),
174
  '{SFW_DIE_YOU_WILL_BE_REDIRECTED}' => sprintf( __( 'You will be automatically redirected to the requested page after %d seconds.', 'cleantalk-spam-protect' ), 30 ),
175
  '{CLEANTALK_TITLE}' => __( 'Antispam by CleanTalk', 'cleantalk-spam-protect' ),
176
  '{REMOTE_ADDRESS}' => $result['ip'],
lib/Cleantalk/ApbctWP/Firewall/SFW.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  namespace Cleantalk\ApbctWP\Firewall;
4
 
5
- use Cleantalk\ApbctWP\Helper as Helper;
6
  use Cleantalk\Variables\Cookie;
7
  use Cleantalk\Variables\Get;
8
  use Cleantalk\Variables\Server;
@@ -156,7 +156,7 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
156
  */
157
  public function update_log( $ip, $status ) {
158
 
159
- if( in_array( $status, array( 'PASS_SFW__BY_WHITELIST', 'PASS_SFW' ) ) ){
160
  return;
161
  }
162
 
@@ -227,7 +227,7 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
227
  // Translation
228
  $replaces = array(
229
  '{SFW_DIE_NOTICE_IP}' => __('SpamFireWall is activated for your IP ', 'cleantalk-spam-protect'),
230
- '{SFW_DIE_MAKE_SURE_JS_ENABLED}' => __( 'To continue working with web site, please make sure that you have enabled JavaScript.', 'cleantalk-spam-protect' ),
231
  '{SFW_DIE_CLICK_TO_PASS}' => __('Please click the link below to pass the protection,', 'cleantalk-spam-protect'),
232
  '{SFW_DIE_YOU_WILL_BE_REDIRECTED}' => sprintf(__('Or you will be automatically redirected to the requested page after %d seconds.', 'cleantalk-spam-protect'), 3),
233
  '{CLEANTALK_TITLE}' => ($this->test ? __('This is the testing page for SpamFireWall', 'cleantalk-spam-protect') : ''),
2
 
3
  namespace Cleantalk\ApbctWP\Firewall;
4
 
5
+ use Cleantalk\ApbctWP\Helper;
6
  use Cleantalk\Variables\Cookie;
7
  use Cleantalk\Variables\Get;
8
  use Cleantalk\Variables\Server;
156
  */
157
  public function update_log( $ip, $status ) {
158
 
159
+ if( in_array( $status, array( 'PASS_SFW__BY_WHITELIST', 'PASS_SFW', 'PASS_ANTIFLOOD', 'PASS_ANTICRAWLER' ) ) ){
160
  return;
161
  }
162
 
227
  // Translation
228
  $replaces = array(
229
  '{SFW_DIE_NOTICE_IP}' => __('SpamFireWall is activated for your IP ', 'cleantalk-spam-protect'),
230
+ '{SFW_DIE_MAKE_SURE_JS_ENABLED}' => __( 'To continue working with the web site, please make sure that you have enabled JavaScript.', 'cleantalk-spam-protect' ),
231
  '{SFW_DIE_CLICK_TO_PASS}' => __('Please click the link below to pass the protection,', 'cleantalk-spam-protect'),
232
  '{SFW_DIE_YOU_WILL_BE_REDIRECTED}' => sprintf(__('Or you will be automatically redirected to the requested page after %d seconds.', 'cleantalk-spam-protect'), 3),
233
  '{CLEANTALK_TITLE}' => ($this->test ? __('This is the testing page for SpamFireWall', 'cleantalk-spam-protect') : ''),
lib/Cleantalk/ApbctWP/Firewall/die_page_anticrawler.html CHANGED
@@ -26,18 +26,19 @@
26
  @media (max-width: 600px) {
27
  }
28
 
29
- .spinner {
30
  margin-left: auto;
31
  margin-right: auto;
32
  width: 70px;
33
  text-align: center;
 
 
34
  }
35
 
36
  .spinner > div {
37
  width: 14px;
38
  height: 14px;
39
  background-color: #333;
40
-
41
  border-radius: 100%;
42
  display: inline-block;
43
  -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
@@ -101,6 +102,7 @@
101
  <div class="bounce2"></div>
102
  <div class="bounce3"></div>
103
  </div>
 
104
  {GENERATED}
105
  <p>Browser time <span id='curr_date'></span></p>
106
  </div>
@@ -114,22 +116,42 @@
114
  <a href='https://cleantalk.org' target='_blank'>{CLEANTALK_TITLE}</a>
115
  </div>
116
  <script type='text/javascript'>
117
- var reload_timeout = 30000;
 
118
  document.getElementById('js_info').style.display = 'none';
119
  document.getElementById('js_passed').style.display = 'block';
120
  document.getElementById('curr_date').innerHTML = ct_date.toGMTString();
121
 
122
  setTimeout( function(){
123
- console.log('do');
124
  set_spamFireWallCookie('apbct_antibot', '{COOKIE_ANTICRAWLER}');
125
  set_spamFireWallCookie('apbct_anticrawler_passed','{COOKIE_ANTICRAWLER_PASSED}');
126
- }, 5000 );
127
 
128
  if(location.search.search('debug=1') === -1) {
129
  setTimeout(function(){
130
  window.location.href = window.location.origin + window.location.pathname + '?sfw=pass' + Math.round(ct_date.getTime()/1000);
131
  }, reload_timeout);
132
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  </script>
134
  </body>
135
  </html>
26
  @media (max-width: 600px) {
27
  }
28
 
29
+ .spinner, #timer {
30
  margin-left: auto;
31
  margin-right: auto;
32
  width: 70px;
33
  text-align: center;
34
+ font-size: 40px;
35
+ font-weight: bold;
36
  }
37
 
38
  .spinner > div {
39
  width: 14px;
40
  height: 14px;
41
  background-color: #333;
 
42
  border-radius: 100%;
43
  display: inline-block;
44
  -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
102
  <div class="bounce2"></div>
103
  <div class="bounce3"></div>
104
  </div>
105
+ <div id="timer"></div>
106
  {GENERATED}
107
  <p>Browser time <span id='curr_date'></span></p>
108
  </div>
116
  <a href='https://cleantalk.org' target='_blank'>{CLEANTALK_TITLE}</a>
117
  </div>
118
  <script type='text/javascript'>
119
+
120
+ var reload_timeout = 3000;
121
  document.getElementById('js_info').style.display = 'none';
122
  document.getElementById('js_passed').style.display = 'block';
123
  document.getElementById('curr_date').innerHTML = ct_date.toGMTString();
124
 
125
  setTimeout( function(){
 
126
  set_spamFireWallCookie('apbct_antibot', '{COOKIE_ANTICRAWLER}');
127
  set_spamFireWallCookie('apbct_anticrawler_passed','{COOKIE_ANTICRAWLER_PASSED}');
128
+ }, 2500 );
129
 
130
  if(location.search.search('debug=1') === -1) {
131
  setTimeout(function(){
132
  window.location.href = window.location.origin + window.location.pathname + '?sfw=pass' + Math.round(ct_date.getTime()/1000);
133
  }, reload_timeout);
134
  }
135
+
136
+ // Countdown function
137
+ var timer_block = document.getElementById('timer');
138
+ timer_block.innerText = reload_timeout/1000;
139
+ var time;
140
+ function countdown() {
141
+ time = parseInt( timer_block.innerText );
142
+ var current = parseInt( timer_block.innerText );
143
+ var cdw = setInterval( function(){
144
+ current = parseInt( current ) - 1;
145
+ timer_block.innerText = current;
146
+ if ( 0 === parseInt( current ) ) {
147
+ clearInterval( cdw );
148
+ }
149
+ }, 1000 );
150
+ }
151
+
152
+ // Run countdown
153
+ countdown();
154
+
155
  </script>
156
  </body>
157
  </html>
lib/Cleantalk/ApbctWP/Firewall/die_page_antiflood.html CHANGED
@@ -26,11 +26,13 @@
26
  @media (max-width: 600px) {
27
  }
28
 
29
- .spinner {
30
  margin-left: auto;
31
  margin-right: auto;
32
  width: 70px;
33
  text-align: center;
 
 
34
  }
35
 
36
  .spinner > div {
@@ -101,6 +103,7 @@
101
  <div class="bounce2"></div>
102
  <div class="bounce3"></div>
103
  </div>
 
104
  {GENERATED}
105
  <p>Browser time <span id='curr_date'></span></p>
106
  </div>
@@ -128,6 +131,25 @@
128
  window.location.href = window.location.origin + window.location.pathname + '?sfw=pass' + Math.round(ct_date.getTime()/1000);
129
  }, reload_timeout);
130
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  </script>
132
  </body>
133
  </html>
26
  @media (max-width: 600px) {
27
  }
28
 
29
+ .spinner, #timer {
30
  margin-left: auto;
31
  margin-right: auto;
32
  width: 70px;
33
  text-align: center;
34
+ font-size: 40px;
35
+ font-weight: bold;
36
  }
37
 
38
  .spinner > div {
103
  <div class="bounce2"></div>
104
  <div class="bounce3"></div>
105
  </div>
106
+ <div id="timer"></div>
107
  {GENERATED}
108
  <p>Browser time <span id='curr_date'></span></p>
109
  </div>
131
  window.location.href = window.location.origin + window.location.pathname + '?sfw=pass' + Math.round(ct_date.getTime()/1000);
132
  }, reload_timeout);
133
  }
134
+
135
+ // Countdown function
136
+ var timer_block = document.getElementById('timer');
137
+ timer_block.innerText = reload_timeout/1000;
138
+ var time;
139
+ function countdown() {
140
+ time = parseInt( timer_block.innerText );
141
+ var current = parseInt( timer_block.innerText );
142
+ var cdw = setInterval( function(){
143
+ current = parseInt( current ) - 1;
144
+ timer_block.innerText = current;
145
+ if ( 0 === parseInt( current ) ) {
146
+ clearInterval( cdw );
147
+ }
148
+ }, 1000 );
149
+ }
150
+
151
+ // Run countdown
152
+ countdown();
153
  </script>
154
  </body>
155
  </html>
lib/Cleantalk/ApbctWP/Firewall/die_page_sfw.html CHANGED
@@ -26,11 +26,13 @@
26
  @media (max-width: 600px) {
27
  }
28
 
29
- .spinner {
30
  margin-left: auto;
31
  margin-right: auto;
32
  width: 70px;
33
  text-align: center;
 
 
34
  }
35
 
36
  .spinner > div {
@@ -108,6 +110,7 @@
108
  <div class="bounce2"></div>
109
  <div class="bounce3"></div>
110
  </div>
 
111
  {GENERATED}
112
  <p>Browser time <span id='curr_date'></span></p>
113
  </div>
@@ -134,6 +137,25 @@
134
  window.location.href = window.location.origin + window.location.pathname + '?sfw=pass' + Math.round(ct_date.getTime()/1000);
135
  }, reload_timeout);
136
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  </script>
138
  {DEBUG}
139
  </body>
26
  @media (max-width: 600px) {
27
  }
28
 
29
+ .spinner, #timer {
30
  margin-left: auto;
31
  margin-right: auto;
32
  width: 70px;
33
  text-align: center;
34
+ font-size: 40px;
35
+ font-weight: bold;
36
  }
37
 
38
  .spinner > div {
110
  <div class="bounce2"></div>
111
  <div class="bounce3"></div>
112
  </div>
113
+ <div id="timer"></div>
114
  {GENERATED}
115
  <p>Browser time <span id='curr_date'></span></p>
116
  </div>
137
  window.location.href = window.location.origin + window.location.pathname + '?sfw=pass' + Math.round(ct_date.getTime()/1000);
138
  }, reload_timeout);
139
  }
140
+
141
+ // Countdown function
142
+ var timer_block = document.getElementById('timer');
143
+ timer_block.innerText = reload_timeout/1000;
144
+ var time;
145
+ function countdown() {
146
+ time = parseInt( timer_block.innerText );
147
+ var current = parseInt( timer_block.innerText );
148
+ var cdw = setInterval( function(){
149
+ current = parseInt( current ) - 1;
150
+ timer_block.innerText = current;
151
+ if ( 0 === parseInt( current ) ) {
152
+ clearInterval( cdw );
153
+ }
154
+ }, 1000 );
155
+ }
156
+
157
+ // Run countdown
158
+ countdown();
159
  </script>
160
  {DEBUG}
161
  </body>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: spam, antispam, woocommerce, comments, firewall
4
  Requires at least: 3.0
5
  Tested up to: 5.5
6
  Requires PHP: 5.4
7
- Stable tag: 5.145.2
8
  License: GPLv2
9
 
10
  Spam protection, anti-spam, firewall, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
@@ -580,6 +580,26 @@ If your website has forms that send data to external sources, you can enable opt
580
 
581
  == Changelog ==
582
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
583
  = 5.145.2 Sep 03 2020 =
584
  * Fix: WooCommerce AJAX order call.
585
  * Fix: AJAX error while getting JS key.
4
  Requires at least: 3.0
5
  Tested up to: 5.5
6
  Requires PHP: 5.4
7
+ Stable tag: 5.146
8
  License: GPLv2
9
 
10
  Spam protection, anti-spam, firewall, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
580
 
581
  == Changelog ==
582
 
583
+ = 5.146 Sep 17 2020 =
584
+ * Fix: Deprecated function wp_blacklist_check() fixed.
585
+ * Fix: Roles exclusion fixed.
586
+ * Mod: Namespace import in \Cleantalk\ApbctWP\Firewall\SFW.
587
+ * Fix: Comments checking fixed.
588
+ * Fix: Spam scan tabs layout fixed.
589
+ * New: Countdown timer implemented for the AntiCrawler page.
590
+ * Mod: User-agent signature added to the AC checking.
591
+ * Mod: Find-spam classes for comments and users refactored
592
+ * Upd: Spam scan - scanning users/comments updated.
593
+ * Fix: Double requests for Ninja Forms.
594
+ * New: 'wpms' flag in sender_info.
595
+ * Fix: Visible params gathering.
596
+ * Fix: WooCommerce AJAX order call 2.
597
+ * Fix: Block page grammar fixed.
598
+ * Fix: Users/comments list - unnecessary button removed.
599
+ * Upd: Skiping AC blocking after 3 sec for real users.
600
+ * New: Countdown timer for AF block page implemented.
601
+ * New: Countdown timer for SFW block page implemented.
602
+
603
  = 5.145.2 Sep 03 2020 =
604
  * Fix: WooCommerce AJAX order call.
605
  * Fix: AJAX error while getting JS key.