Version Description
Jan 29 2020 = * Fix: Using server protocol for AC checking. * Fix: Prevent caching db queries for SFW. * Fix: mgm registration temp fix. * Upd: Checking skipped request replaced. * Fix: Bookly plugin service requests checking skipped. * Fix: Youzier login form skipped. * Fix: InJob theme lost password skipped. * Upd: Showing plugin version on SFW block page. * Fix: fix request id rotation. * Mod: Show "Insert users" button only for local web servers. * Upd: Checking skipped request replaced for non-ajax requests. * Fix: BuddyPress edit profile checking skippped. * Fix: Unused code removed. * Upd: Helper::ip_get() method updated. * Fix: UltimateMember password reset skipped. * Del: Unused code removed. * New: Server::get() now can accept 'URI' as an parameter. Returns full URI like 'http://domain.net/request/path?parameter=value#fragment * Mod: apbct_exclusions_checkurl_reversed() simplifed and PHPDoc'ed. * Mod: apbct_base_call exclusions revised. * Mod: $cleantalk_executed chaos simplified. * Upd: Shedule sfw update once again if it failed. * Fix: Delete cleantalk options via uninstalling. * Fix: Deleting table for network sites fixed. * Fix: Using host header for AC checking. * Fix: Expression formatting fixed. * Mod: Cron. Do not runs when it already runs. * Mod: Cron class updated.
Release Info
Developer | glomberg |
Plugin | Spam protection, AntiSpam, FireWall by CleanTalk |
Version | 5.152 |
Comparing to | |
See all releases |
Code changes from version 5.151.4 to 5.152
- cleantalk.php +42 -68
- inc/cleantalk-ajax.php +6 -0
- inc/cleantalk-common.php +43 -31
- inc/cleantalk-pluggable.php +69 -0
- inc/cleantalk-public.php +15 -5
- inc/cleantalk-settings.php +5 -0
- lib/Cleantalk/ApbctWP/Cron.php +271 -140
- lib/Cleantalk/ApbctWP/FindSpam/ListTable/UsersScan.php +66 -64
- lib/Cleantalk/ApbctWP/Firewall/AntiCrawler.php +6 -8
- lib/Cleantalk/ApbctWP/Firewall/AntiFlood.php +2 -2
- lib/Cleantalk/ApbctWP/Firewall/SFW.php +4 -2
- lib/Cleantalk/Common/Helper.php +253 -142
- lib/Cleantalk/Common/Schema.php +1 -1
- lib/Cleantalk/Templates/Singleton.php +35 -35
- lib/Cleantalk/Variables/Cookie.php +1 -1
- lib/Cleantalk/Variables/Get.php +1 -1
- lib/Cleantalk/Variables/Post.php +1 -1
- lib/Cleantalk/Variables/Request.php +1 -1
- lib/Cleantalk/Variables/Server.php +44 -36
- lib/Cleantalk/Variables/ServerVariables.php +76 -84
- readme.txt +30 -1
@@ -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.
|
7 |
Author: СleanTalk <welcome@cleantalk.org>
|
8 |
Author URI: https://cleantalk.org
|
9 |
Text Domain: cleantalk-spam-protect
|
@@ -128,24 +128,22 @@ if( !defined( 'CLEANTALK_PLUGIN_DIR' ) ){
|
|
128 |
|
129 |
// Do update actions if version is changed
|
130 |
apbct_update_actions();
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
(
|
|
|
|
|
|
|
|
|
|
|
136 |
){
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
define('CT_CRON', true); // Letting know functions that they are running under CT_CRON
|
144 |
-
$ct_cron->runTasks();
|
145 |
-
unset($ct_cron);
|
146 |
-
|
147 |
-
}
|
148 |
-
}
|
149 |
|
150 |
//Delete cookie for admin trial notice
|
151 |
add_action('wp_logout', 'apbct__hook__wp_logout__delete_trial_notice_cookie');
|
@@ -241,10 +239,6 @@ if( !defined( 'CLEANTALK_PLUGIN_DIR' ) ){
|
|
241 |
// Profile Builder integration
|
242 |
add_filter( 'wppb_output_field_errors_filter', 'apbct_form_profile_builder__check_register', 1, 3 );
|
243 |
|
244 |
-
//Hooks for updating/adding settings
|
245 |
-
//add_action ('added_option', 'apbct_after_options_added', 10, 2);
|
246 |
-
//add_action ('updated_option', 'apbct_after_options_updated', 10, 3);
|
247 |
-
|
248 |
// Public actions
|
249 |
if( ! is_admin() && ! apbct_is_ajax() && ! apbct_is_customize_preview() ){
|
250 |
|
@@ -281,7 +275,7 @@ if( !defined( 'CLEANTALK_PLUGIN_DIR' ) ){
|
|
281 |
add_filter('script_loader_tag', 'apbct_add_async_attribute', 10, 3);
|
282 |
|
283 |
// Redirect admin to plugin settings.
|
284 |
-
if(!defined('WP_ALLOW_MULTISITE') || defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE == false)
|
285 |
add_action('admin_init', 'apbct_plugin_redirect');
|
286 |
|
287 |
// Deleting SFW tables when deleting websites
|
@@ -454,44 +448,6 @@ if( !defined( 'CLEANTALK_PLUGIN_DIR' ) ){
|
|
454 |
|
455 |
}
|
456 |
|
457 |
-
/**
|
458 |
-
* Hook for updating settings
|
459 |
-
*/
|
460 |
-
function apbct_after_options_updated( $option, $old_value, $value ) {
|
461 |
-
apbct_sfw_actions( $option, $value );
|
462 |
-
}
|
463 |
-
|
464 |
-
/**
|
465 |
-
* Hook for adding settings
|
466 |
-
*/
|
467 |
-
function apbct_after_options_added( $option, $value ) {
|
468 |
-
apbct_sfw_actions( $option, $value );
|
469 |
-
}
|
470 |
-
|
471 |
-
function apbct_sfw_actions( $option, $value ) {
|
472 |
-
|
473 |
-
global $apbct;
|
474 |
-
|
475 |
-
if ( $option == 'cleantalk_settings' ) {
|
476 |
-
|
477 |
-
$api_key = ! empty( $value['apikey'] ) || $apbct->moderate_ip ? $value['apikey'] : $apbct->api_key;
|
478 |
-
|
479 |
-
// SFW actions
|
480 |
-
if( $value['spam_firewall'] == 1 ){
|
481 |
-
|
482 |
-
$result = ct_sfw_update( true, $api_key );
|
483 |
-
if( ! empty( $result['error'] ) )
|
484 |
-
$apbct->error_add( 'sfw_update', $result['error'] );
|
485 |
-
|
486 |
-
$result = ct_sfw_send_logs( true, $api_key );
|
487 |
-
if( ! empty( $result['error'] ) )
|
488 |
-
$apbct->error_add( 'sfw_send_logs', $result['error'] );
|
489 |
-
|
490 |
-
}
|
491 |
-
}
|
492 |
-
|
493 |
-
}
|
494 |
-
|
495 |
/**
|
496 |
* Checking if the current request is the Remote Call
|
497 |
*
|
@@ -639,10 +595,6 @@ function apbct_sfw__check()
|
|
639 |
if($apbct->rc_running || (!empty($spbc) && $spbc->rc_running))
|
640 |
return;
|
641 |
|
642 |
-
$fw_init_options = array(
|
643 |
-
'set_cookies' => $apbct->settings['set_cookies']
|
644 |
-
);
|
645 |
-
|
646 |
$firewall = new \Cleantalk\Common\Firewall(
|
647 |
DB::getInstance()
|
648 |
);
|
@@ -730,7 +682,8 @@ function apbct_activation( $network = false ) {
|
|
730 |
}
|
731 |
|
732 |
// Additional options
|
733 |
-
add_option('ct_plugin_do_activation_redirect', true);
|
|
|
734 |
}
|
735 |
|
736 |
function apbct_activation__create_tables( $sqls, $db_prefix = '' ) {
|
@@ -852,6 +805,9 @@ function apbct_deactivation__delete_all_options(){
|
|
852 |
delete_option('cleantalk_debug');
|
853 |
delete_option('cleantalk_plugin_request_ids');
|
854 |
delete_option('cleantalk_fw_stats');
|
|
|
|
|
|
|
855 |
}
|
856 |
|
857 |
/**
|
@@ -870,7 +826,7 @@ function apbct_deactivation__delete_common_tables() {
|
|
870 |
$wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_sessions`;'); // Deleting session table
|
871 |
$wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_spamscan_logs`;'); // Deleting user/comments scan result table
|
872 |
$wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_ua_bl`;'); // Deleting AC UA black lists
|
873 |
-
$wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->
|
874 |
}
|
875 |
|
876 |
function apbct_deactivation__delete_blog_tables() {
|
@@ -952,6 +908,9 @@ function ct_get_cookie()
|
|
952 |
die();
|
953 |
}
|
954 |
|
|
|
|
|
|
|
955 |
function ct_sfw_update( $api_key = '', $immediate = false ){
|
956 |
|
957 |
global $apbct, $wpdb;
|
@@ -976,9 +935,14 @@ function ct_sfw_update( $api_key = '', $immediate = false ){
|
|
976 |
|
977 |
if( $apbct->settings['spam_firewall'] == 1 && ( ! empty($api_key) || $apbct->data['moderate_ip'] ) ) {
|
978 |
|
|
|
|
|
|
|
|
|
|
|
979 |
// Set new update ID
|
980 |
if( ! $apbct->fw_stats['firewall_updating_id'] || time() - $apbct->fw_stats['firewall_updating_last_start'] > 300 ){
|
981 |
-
$apbct->fw_stats['firewall_updating_id'] = md5( rand( 0, 100000 ) );
|
982 |
$apbct->fw_stats['firewall_updating_last_start'] = time();
|
983 |
$apbct->save( 'fw_stats' );
|
984 |
}
|
@@ -1041,6 +1005,8 @@ function ct_sfw_update( $api_key = '', $immediate = false ){
|
|
1041 |
);
|
1042 |
} else {
|
1043 |
|
|
|
|
|
1044 |
// @todo We have to handle errors here
|
1045 |
SFW::delete_main_data_tables( DB::getInstance() );
|
1046 |
// @todo We have to handle errors here
|
@@ -1058,6 +1024,14 @@ function ct_sfw_update( $api_key = '', $immediate = false ){
|
|
1058 |
$apbct->stats['sfw']['last_update_time'] = time();
|
1059 |
$apbct->save('stats');
|
1060 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1061 |
// Delete update errors
|
1062 |
$apbct->error_delete( 'sfw_update', 'save_settings' );
|
1063 |
|
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.152
|
7 |
Author: СleanTalk <welcome@cleantalk.org>
|
8 |
Author URI: https://cleantalk.org
|
9 |
Text Domain: cleantalk-spam-protect
|
128 |
|
129 |
// Do update actions if version is changed
|
130 |
apbct_update_actions();
|
131 |
+
|
132 |
+
// Self cron
|
133 |
+
$tasks_to_run = Cron::checkTasks(); // Check for current tasks. Drop tasks inner counters.
|
134 |
+
if(
|
135 |
+
! empty( $tasks_to_run ) && // There is tasks to run
|
136 |
+
! apbct_is_remote_call() && // Do not doing CRON in remote call action
|
137 |
+
(
|
138 |
+
! defined( 'DOING_CRON' ) ||
|
139 |
+
( defined( 'DOING_CRON' ) && DOING_CRON !== true )
|
140 |
+
)
|
141 |
){
|
142 |
+
$ct_cron = new Cron();
|
143 |
+
$ct_cron->setTasksToRun( $tasks_to_run );
|
144 |
+
$ct_cron->runTasks();
|
145 |
+
unset( $ct_cron );
|
146 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
//Delete cookie for admin trial notice
|
149 |
add_action('wp_logout', 'apbct__hook__wp_logout__delete_trial_notice_cookie');
|
239 |
// Profile Builder integration
|
240 |
add_filter( 'wppb_output_field_errors_filter', 'apbct_form_profile_builder__check_register', 1, 3 );
|
241 |
|
|
|
|
|
|
|
|
|
242 |
// Public actions
|
243 |
if( ! is_admin() && ! apbct_is_ajax() && ! apbct_is_customize_preview() ){
|
244 |
|
275 |
add_filter('script_loader_tag', 'apbct_add_async_attribute', 10, 3);
|
276 |
|
277 |
// Redirect admin to plugin settings.
|
278 |
+
if( ! defined('WP_ALLOW_MULTISITE') || ( defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE == false ) )
|
279 |
add_action('admin_init', 'apbct_plugin_redirect');
|
280 |
|
281 |
// Deleting SFW tables when deleting websites
|
448 |
|
449 |
}
|
450 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
451 |
/**
|
452 |
* Checking if the current request is the Remote Call
|
453 |
*
|
595 |
if($apbct->rc_running || (!empty($spbc) && $spbc->rc_running))
|
596 |
return;
|
597 |
|
|
|
|
|
|
|
|
|
598 |
$firewall = new \Cleantalk\Common\Firewall(
|
599 |
DB::getInstance()
|
600 |
);
|
682 |
}
|
683 |
|
684 |
// Additional options
|
685 |
+
add_option( 'ct_plugin_do_activation_redirect', true );
|
686 |
+
add_option( 'sfw_update_first', true );
|
687 |
}
|
688 |
|
689 |
function apbct_activation__create_tables( $sqls, $db_prefix = '' ) {
|
805 |
delete_option('cleantalk_debug');
|
806 |
delete_option('cleantalk_plugin_request_ids');
|
807 |
delete_option('cleantalk_fw_stats');
|
808 |
+
delete_option( 'ct_plugin_do_activation_redirect' );
|
809 |
+
delete_option( 'sfw_update_first' );
|
810 |
+
delete_option( 'sfw_sync_first' );
|
811 |
}
|
812 |
|
813 |
/**
|
826 |
$wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_sessions`;'); // Deleting session table
|
827 |
$wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_spamscan_logs`;'); // Deleting user/comments scan result table
|
828 |
$wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_ua_bl`;'); // Deleting AC UA black lists
|
829 |
+
$wpdb->query('DROP TABLE IF EXISTS `'. $wpdb->base_prefix.'cleantalk_sfw_temp`;'); // Deleting temporary SFW data
|
830 |
}
|
831 |
|
832 |
function apbct_deactivation__delete_blog_tables() {
|
908 |
die();
|
909 |
}
|
910 |
|
911 |
+
// This action triggered by wp_schedule_single_event( time() + 900, 'ct_sfw_update' );
|
912 |
+
add_action( 'ct_sfw_update', 'ct_sfw_update' );
|
913 |
+
|
914 |
function ct_sfw_update( $api_key = '', $immediate = false ){
|
915 |
|
916 |
global $apbct, $wpdb;
|
935 |
|
936 |
if( $apbct->settings['spam_firewall'] == 1 && ( ! empty($api_key) || $apbct->data['moderate_ip'] ) ) {
|
937 |
|
938 |
+
if( get_option( 'sfw_sync_first' ) ) {
|
939 |
+
$first = 'first';
|
940 |
+
} else {
|
941 |
+
$first = '';
|
942 |
+
}
|
943 |
// Set new update ID
|
944 |
if( ! $apbct->fw_stats['firewall_updating_id'] || time() - $apbct->fw_stats['firewall_updating_last_start'] > 300 ){
|
945 |
+
$apbct->fw_stats['firewall_updating_id'] = md5( rand( 0, 100000 ) ) . $first;
|
946 |
$apbct->fw_stats['firewall_updating_last_start'] = time();
|
947 |
$apbct->save( 'fw_stats' );
|
948 |
}
|
1005 |
);
|
1006 |
} else {
|
1007 |
|
1008 |
+
$is_first_updating = strpos( $apbct->fw_stats['firewall_updating_id'], 'first' );
|
1009 |
+
|
1010 |
// @todo We have to handle errors here
|
1011 |
SFW::delete_main_data_tables( DB::getInstance() );
|
1012 |
// @todo We have to handle errors here
|
1024 |
$apbct->stats['sfw']['last_update_time'] = time();
|
1025 |
$apbct->save('stats');
|
1026 |
|
1027 |
+
// Running sfw update once again in 15 min if entries is < 4000
|
1028 |
+
if( $is_first_updating !== false ) {
|
1029 |
+
if( $apbct->stats['sfw']['entries'] < 4000 ) {
|
1030 |
+
wp_schedule_single_event( time() + 900, 'ct_sfw_update' );
|
1031 |
+
}
|
1032 |
+
delete_option( 'sfw_sync_first' );
|
1033 |
+
}
|
1034 |
+
|
1035 |
// Delete update errors
|
1036 |
$apbct->error_delete( 'sfw_update', 'save_settings' );
|
1037 |
|
@@ -324,6 +324,7 @@ function ct_ajax_hook($message_obj = false, $additional = false)
|
|
324 |
'erforms_field_change_command', //ERForms internal request
|
325 |
'wl_out_of_stock_notify', // Sumo Waitlist
|
326 |
'rac_preadd_guest', //Rac internal request
|
|
|
327 |
);
|
328 |
|
329 |
// Skip test if
|
@@ -351,6 +352,11 @@ function ct_ajax_hook($message_obj = false, $additional = false)
|
|
351 |
return false;
|
352 |
}
|
353 |
|
|
|
|
|
|
|
|
|
|
|
354 |
//General post_info for all ajax calls
|
355 |
$post_info = array(
|
356 |
'comment_type' => 'feedback_ajax',
|
324 |
'erforms_field_change_command', //ERForms internal request
|
325 |
'wl_out_of_stock_notify', // Sumo Waitlist
|
326 |
'rac_preadd_guest', //Rac internal request
|
327 |
+
/* !! Do not add actions here. Use apbct_is_skip_request() function below !! */
|
328 |
);
|
329 |
|
330 |
// Skip test if
|
352 |
return false;
|
353 |
}
|
354 |
|
355 |
+
if( apbct_is_skip_request( true ) ) {
|
356 |
+
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__ . '(' . apbct_is_skip_request() . ')', $_POST );
|
357 |
+
return false;
|
358 |
+
}
|
359 |
+
|
360 |
//General post_info for all ajax calls
|
361 |
$post_info = array(
|
362 |
'comment_type' => 'feedback_ajax',
|
@@ -86,20 +86,43 @@ function apbct_plugin_loaded() {
|
|
86 |
function apbct_base_call($params = array(), $reg_flag = false){
|
87 |
|
88 |
global $apbct, $cleantalk_executed;
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
// URL, IP, Role exclusions
|
91 |
-
if(
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
93 |
return array( 'ct_result' => new CleantalkResponse() );
|
94 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
$cleantalk_executed = true;
|
96 |
|
97 |
-
|
98 |
-
$
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
103 |
}
|
104 |
$apbct->plugin_request_ids = $tmp;
|
105 |
$apbct->save('plugin_request_ids');
|
@@ -115,26 +138,12 @@ function apbct_base_call($params = array(), $reg_flag = false){
|
|
115 |
|
116 |
$apbct->plugin_request_ids = array_merge($apbct->plugin_request_ids, array($apbct->plugin_request_id => time() ) );
|
117 |
$apbct->save('plugin_request_ids');
|
118 |
-
|
|
|
|
|
119 |
$sender_info = !empty($params['sender_info'])
|
120 |
? \Cleantalk\ApbctWP\Helper::array_merge__save_numeric_keys__recursive(apbct_get_sender_info(), (array)$params['sender_info'])
|
121 |
: apbct_get_sender_info();
|
122 |
-
|
123 |
-
// Fields exclusions
|
124 |
-
if( ! empty( $params['message'] ) && is_array( $params['message'] ) ){
|
125 |
-
|
126 |
-
$params['message'] = apbct_array( $params['message'] )
|
127 |
-
->get_keys( $apbct->settings['exclusions__fields'], $apbct->settings['exclusions__fields__use_regexp'] )
|
128 |
-
->delete();
|
129 |
-
}
|
130 |
-
|
131 |
-
// Reversed url exclusions. Pass everything except one.
|
132 |
-
if( ! apbct_exclusions_check__url__reversed() ){
|
133 |
-
return array(
|
134 |
-
'ct' => false,
|
135 |
-
'ct_result' => new CleantalkResponse( null, null )
|
136 |
-
);
|
137 |
-
}
|
138 |
|
139 |
$default_params = array(
|
140 |
|
@@ -239,14 +248,13 @@ function apbct_base_call($params = array(), $reg_flag = false){
|
|
239 |
|
240 |
function apbct_exclusions_check($func = null){
|
241 |
|
242 |
-
global $apbct
|
243 |
|
244 |
// Common exclusions
|
245 |
if(
|
246 |
apbct_exclusions_check__ip() ||
|
247 |
apbct_exclusions_check__url() ||
|
248 |
-
apbct_is_user_role_in( $apbct->settings['exclusions__roles'] )
|
249 |
-
$cleantalk_executed
|
250 |
)
|
251 |
return true;
|
252 |
|
@@ -273,10 +281,14 @@ function apbct_exclusions_check($func = null){
|
|
273 |
return false;
|
274 |
}
|
275 |
|
|
|
|
|
|
|
|
|
|
|
276 |
function apbct_exclusions_check__url__reversed(){
|
277 |
-
return defined( 'APBCT_URL_EXCLUSIONS__REVERSED' ) &&
|
278 |
-
|
279 |
-
: true;
|
280 |
}
|
281 |
|
282 |
/**
|
86 |
function apbct_base_call($params = array(), $reg_flag = false){
|
87 |
|
88 |
global $apbct, $cleantalk_executed;
|
89 |
+
|
90 |
+
/* Exclusions */
|
91 |
+
if( $cleantalk_executed ){
|
92 |
+
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
93 |
+
return array( 'ct_result' => new CleantalkResponse() );
|
94 |
+
}
|
95 |
+
|
96 |
// URL, IP, Role exclusions
|
97 |
+
if( apbct_exclusions_check() ){
|
98 |
+
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
99 |
+
return array( 'ct_result' => new CleantalkResponse() );
|
100 |
+
}
|
101 |
+
|
102 |
+
// Reversed url exclusions. Pass everything except one.
|
103 |
+
if( apbct_exclusions_check__url__reversed() ){
|
104 |
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
105 |
return array( 'ct_result' => new CleantalkResponse() );
|
106 |
}
|
107 |
+
|
108 |
+
// Fields exclusions
|
109 |
+
if( ! empty( $params['message'] ) && is_array( $params['message'] ) ){
|
110 |
+
$params['message'] = apbct_array( $params['message'] )
|
111 |
+
->get_keys( $apbct->settings['exclusions__fields'], $apbct->settings['exclusions__fields__use_regexp'] )
|
112 |
+
->delete();
|
113 |
+
}
|
114 |
+
/* End of Exclusions */
|
115 |
+
|
116 |
$cleantalk_executed = true;
|
117 |
|
118 |
+
/* Request ID rotation */
|
119 |
+
$tmp = array();
|
120 |
+
if ($apbct->plugin_request_ids && !empty($apbct->plugin_request_ids)) {
|
121 |
+
$plugin_request_id__lifetime = 2;
|
122 |
+
foreach( $apbct->plugin_request_ids as $request_id => $request_time ){
|
123 |
+
if( time() - $request_time < $plugin_request_id__lifetime )
|
124 |
+
$tmp[ $request_id ] = $request_time;
|
125 |
+
}
|
126 |
}
|
127 |
$apbct->plugin_request_ids = $tmp;
|
128 |
$apbct->save('plugin_request_ids');
|
138 |
|
139 |
$apbct->plugin_request_ids = array_merge($apbct->plugin_request_ids, array($apbct->plugin_request_id => time() ) );
|
140 |
$apbct->save('plugin_request_ids');
|
141 |
+
/* End of Request ID rotation */
|
142 |
+
|
143 |
+
|
144 |
$sender_info = !empty($params['sender_info'])
|
145 |
? \Cleantalk\ApbctWP\Helper::array_merge__save_numeric_keys__recursive(apbct_get_sender_info(), (array)$params['sender_info'])
|
146 |
: apbct_get_sender_info();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
$default_params = array(
|
149 |
|
248 |
|
249 |
function apbct_exclusions_check($func = null){
|
250 |
|
251 |
+
global $apbct;
|
252 |
|
253 |
// Common exclusions
|
254 |
if(
|
255 |
apbct_exclusions_check__ip() ||
|
256 |
apbct_exclusions_check__url() ||
|
257 |
+
apbct_is_user_role_in( $apbct->settings['exclusions__roles'] )
|
|
|
258 |
)
|
259 |
return true;
|
260 |
|
281 |
return false;
|
282 |
}
|
283 |
|
284 |
+
/**
|
285 |
+
* Check if the reversed exclusions is set and doesn't match.
|
286 |
+
*
|
287 |
+
* @return bool
|
288 |
+
*/
|
289 |
function apbct_exclusions_check__url__reversed(){
|
290 |
+
return defined( 'APBCT_URL_EXCLUSIONS__REVERSED' ) &&
|
291 |
+
! \Cleantalk\Variables\Server::has_string( 'URI', APBCT_URL_EXCLUSIONS__REVERSED );
|
|
|
292 |
}
|
293 |
|
294 |
/**
|
@@ -324,3 +324,72 @@ function apbct_is_customize_preview() {
|
|
324 |
$uri = parse_url(Server::get('REQUEST_URI'));
|
325 |
return $uri && isset( $uri['query'] ) && strpos( $uri['query'], 'customize_changeset_uuid' ) !== false;
|
326 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
$uri = parse_url(Server::get('REQUEST_URI'));
|
325 |
return $uri && isset( $uri['query'] ) && strpos( $uri['query'], 'customize_changeset_uuid' ) !== false;
|
326 |
}
|
327 |
+
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Checking if the request must be skipped.
|
331 |
+
*
|
332 |
+
* @param $ajax bool The current request is the ajax request?
|
333 |
+
*
|
334 |
+
* @return bool|string false or request name for logging
|
335 |
+
*/
|
336 |
+
function apbct_is_skip_request( $ajax = false ) {
|
337 |
+
|
338 |
+
/* !!! Have to use more than one factor to detect the request - is_plugin active() && $_POST['action'] !!! */
|
339 |
+
//@ToDo Implement direct integration checking - if have the direct integration will be returned false
|
340 |
+
|
341 |
+
switch ( $ajax ) {
|
342 |
+
case true :
|
343 |
+
/*****************************************/
|
344 |
+
/* Here is ajax requests skipping */
|
345 |
+
/*****************************************/
|
346 |
+
|
347 |
+
// Bookly Plugin admin actions skip
|
348 |
+
if( apbct_is_plugin_active( 'bookly-responsive-appointment-booking-tool/main.php' ) &&
|
349 |
+
isset( $_POST['action'] ) &&
|
350 |
+
strpos( $_POST['action'], 'bookly' ) !== false &&
|
351 |
+
is_admin() )
|
352 |
+
{
|
353 |
+
return 'bookly_pro_update_staff_advanced';
|
354 |
+
}
|
355 |
+
// Youzier login form skip
|
356 |
+
if( apbct_is_plugin_active( 'youzer/youzer.php' ) &&
|
357 |
+
isset( $_POST['action'] ) &&
|
358 |
+
$_POST['action'] === 'yz_ajax_login' )
|
359 |
+
{
|
360 |
+
return 'youzier_login_form';
|
361 |
+
}
|
362 |
+
// InJob theme lost password skip
|
363 |
+
if( apbct_is_plugin_active( 'iwjob/iwjob.php' ) &&
|
364 |
+
isset( $_POST['action'] ) &&
|
365 |
+
$_POST['action'] === 'iwj_lostpass' )
|
366 |
+
{
|
367 |
+
return 'injob_theme_plugin';
|
368 |
+
}
|
369 |
+
|
370 |
+
break;
|
371 |
+
|
372 |
+
case false :
|
373 |
+
default:
|
374 |
+
/*****************************************/
|
375 |
+
/* Here is non-ajax requests skipping */
|
376 |
+
/*****************************************/
|
377 |
+
// BuddyPress edit profile checking skip
|
378 |
+
if( apbct_is_plugin_active( 'buddypress/bp-loader.php' ) &&
|
379 |
+
array_key_exists( 'profile-group-edit-submit', $_POST ) )
|
380 |
+
{
|
381 |
+
return 'buddypress_profile_edit';
|
382 |
+
}
|
383 |
+
// UltimateMember password reset skip
|
384 |
+
if( apbct_is_plugin_active( 'ultimate-member/ultimate-member.php' ) &&
|
385 |
+
isset( $_POST['_um_password_reset'] ) && $_POST['_um_password_reset'] == 1 )
|
386 |
+
{
|
387 |
+
return 'ultimatemember_password_reset';
|
388 |
+
}
|
389 |
+
|
390 |
+
break;
|
391 |
+
|
392 |
+
}
|
393 |
+
|
394 |
+
return false;
|
395 |
+
}
|
@@ -799,6 +799,8 @@ function apbct_search_add_noindex() {
|
|
799 |
*/
|
800 |
function ct_woocommerce_checkout_check() {
|
801 |
|
|
|
|
|
802 |
//Getting request params
|
803 |
$ct_temp_msg_data = ct_get_fields_any($_POST);
|
804 |
|
@@ -826,6 +828,10 @@ function ct_woocommerce_checkout_check() {
|
|
826 |
)
|
827 |
);
|
828 |
|
|
|
|
|
|
|
|
|
829 |
$ct_result = $base_call_result['ct_result'];
|
830 |
|
831 |
if ($ct_result->allow == 0) {
|
@@ -2030,6 +2036,8 @@ function ct_registration_errors($errors, $sanitized_user_login = null, $user_ema
|
|
2030 |
$_POST['FB_userdata']['email'] = '';
|
2031 |
$_POST['FB_userdata']['name'] = '';
|
2032 |
return;
|
|
|
|
|
2033 |
}else{
|
2034 |
if(is_wp_error($errors))
|
2035 |
$errors->add('ct_error', $ct_result->comment);
|
@@ -2467,8 +2475,6 @@ function apbct_form__ninjaForms__testSpam() {
|
|
2467 |
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
2468 |
return;
|
2469 |
}
|
2470 |
-
|
2471 |
-
$cleantalk_executed = true;
|
2472 |
|
2473 |
if(
|
2474 |
$apbct->settings['contact_forms_test'] == 0
|
@@ -3200,7 +3206,6 @@ function apbct_form__elementor_pro__testSpam() {
|
|
3200 |
|
3201 |
$post_info['comment_type'] = 'contact_form_wordpress_elementor_pro';
|
3202 |
|
3203 |
-
$cleantalk_executed = true;
|
3204 |
$base_call_result = apbct_base_call(
|
3205 |
array(
|
3206 |
'message' => $message,
|
@@ -3247,7 +3252,6 @@ function apbct_form__inevio__testSpam() {
|
|
3247 |
|
3248 |
$post_info['comment_type'] = 'contact_form_wordpress_inevio_theme';
|
3249 |
|
3250 |
-
$cleantalk_executed = true;
|
3251 |
$base_call_result = apbct_base_call(
|
3252 |
array(
|
3253 |
'message' => $message,
|
@@ -3358,6 +3362,7 @@ function ct_contact_form_validate() {
|
|
3358 |
( isset( $_POST['ihcaction'] ) && $_POST['ihcaction'] == 'reset_pass') || //Reset pass exclusion
|
3359 |
( isset( $_POST['action'], $_POST['register_unspecified_nonce_field'] ) && $_POST['action'] == 'register' ) || // Profile Builder have a direct integration
|
3360 |
( isset( $_POST['_wpmem_register_nonce'] ) && wp_verify_nonce( $_POST['_wpmem_register_nonce'], 'wpmem_longform_nonce' ) ) // WP Members have a direct integration
|
|
|
3361 |
) {
|
3362 |
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
3363 |
return null;
|
@@ -3405,6 +3410,12 @@ function ct_contact_form_validate() {
|
|
3405 |
}
|
3406 |
}
|
3407 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
3408 |
$post_info['comment_type'] = 'feedback_general_contact_form';
|
3409 |
|
3410 |
$ct_temp_msg_data = ct_get_fields_any($_POST);
|
@@ -3423,7 +3434,6 @@ function ct_contact_form_validate() {
|
|
3423 |
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
3424 |
return false;
|
3425 |
}
|
3426 |
-
$cleantalk_executed=true;
|
3427 |
|
3428 |
if(isset($_POST['TellAFriend_Link'])){
|
3429 |
$tmp = $_POST['TellAFriend_Link'];
|
799 |
*/
|
800 |
function ct_woocommerce_checkout_check() {
|
801 |
|
802 |
+
global $apbct, $cleantalk_executed;
|
803 |
+
|
804 |
//Getting request params
|
805 |
$ct_temp_msg_data = ct_get_fields_any($_POST);
|
806 |
|
828 |
)
|
829 |
);
|
830 |
|
831 |
+
if( $apbct->settings['wc_register_from_order'] ) {
|
832 |
+
$cleantalk_executed = false;
|
833 |
+
}
|
834 |
+
|
835 |
$ct_result = $base_call_result['ct_result'];
|
836 |
|
837 |
if ($ct_result->allow == 0) {
|
2036 |
$_POST['FB_userdata']['email'] = '';
|
2037 |
$_POST['FB_userdata']['name'] = '';
|
2038 |
return;
|
2039 |
+
}elseif(defined('MGM_PLUGIN_NAME')) {
|
2040 |
+
ct_die_extended($ct_result->comment);
|
2041 |
}else{
|
2042 |
if(is_wp_error($errors))
|
2043 |
$errors->add('ct_error', $ct_result->comment);
|
2475 |
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
2476 |
return;
|
2477 |
}
|
|
|
|
|
2478 |
|
2479 |
if(
|
2480 |
$apbct->settings['contact_forms_test'] == 0
|
3206 |
|
3207 |
$post_info['comment_type'] = 'contact_form_wordpress_elementor_pro';
|
3208 |
|
|
|
3209 |
$base_call_result = apbct_base_call(
|
3210 |
array(
|
3211 |
'message' => $message,
|
3252 |
|
3253 |
$post_info['comment_type'] = 'contact_form_wordpress_inevio_theme';
|
3254 |
|
|
|
3255 |
$base_call_result = apbct_base_call(
|
3256 |
array(
|
3257 |
'message' => $message,
|
3362 |
( isset( $_POST['ihcaction'] ) && $_POST['ihcaction'] == 'reset_pass') || //Reset pass exclusion
|
3363 |
( isset( $_POST['action'], $_POST['register_unspecified_nonce_field'] ) && $_POST['action'] == 'register' ) || // Profile Builder have a direct integration
|
3364 |
( isset( $_POST['_wpmem_register_nonce'] ) && wp_verify_nonce( $_POST['_wpmem_register_nonce'], 'wpmem_longform_nonce' ) ) // WP Members have a direct integration
|
3365 |
+
/* !! Do not add actions here. Use apbct_is_skip_request() function below !! */
|
3366 |
) {
|
3367 |
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
3368 |
return null;
|
3410 |
}
|
3411 |
}
|
3412 |
}
|
3413 |
+
|
3414 |
+
if( apbct_is_skip_request( false ) ) {
|
3415 |
+
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__ . '(' . apbct_is_skip_request() . ')', $_POST );
|
3416 |
+
return false;
|
3417 |
+
}
|
3418 |
+
|
3419 |
$post_info['comment_type'] = 'feedback_general_contact_form';
|
3420 |
|
3421 |
$ct_temp_msg_data = ct_get_fields_any($_POST);
|
3434 |
do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
|
3435 |
return false;
|
3436 |
}
|
|
|
3437 |
|
3438 |
if(isset($_POST['TellAFriend_Link'])){
|
3439 |
$tmp = $_POST['TellAFriend_Link'];
|
@@ -1581,6 +1581,11 @@ function apbct_settings__sync( $direct_call = false ){
|
|
1581 |
|
1582 |
// SFW actions
|
1583 |
if( $apbct->settings['spam_firewall'] == 1 ){
|
|
|
|
|
|
|
|
|
|
|
1584 |
|
1585 |
$result = ct_sfw_update( $apbct->settings['apikey'] );
|
1586 |
if( ! empty( $result['error'] ) )
|
1581 |
|
1582 |
// SFW actions
|
1583 |
if( $apbct->settings['spam_firewall'] == 1 ){
|
1584 |
+
|
1585 |
+
if( get_option( 'sfw_update_first' ) ) {
|
1586 |
+
add_option( 'sfw_sync_first', true );
|
1587 |
+
delete_option( 'sfw_update_first' );
|
1588 |
+
}
|
1589 |
|
1590 |
$result = ct_sfw_update( $apbct->settings['apikey'] );
|
1591 |
if( ! empty( $result['error'] ) )
|
@@ -2,152 +2,283 @@
|
|
2 |
|
3 |
namespace Cleantalk\ApbctWP;
|
4 |
|
5 |
-
|
6 |
-
*
|
7 |
-
*
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
class Cron
|
11 |
{
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
'period' => $period,
|
49 |
-
);
|
50 |
-
|
51 |
-
update_option(self::CRON_OPTION_NAME, $tasks);
|
52 |
-
|
53 |
-
return true;
|
54 |
-
}
|
55 |
-
|
56 |
-
// Removing cron task
|
57 |
-
static public function removeTask($task)
|
58 |
-
{
|
59 |
-
$tasks = get_option(self::CRON_OPTION_NAME);
|
60 |
-
|
61 |
-
$tasks = empty($tasks) ? array() : $tasks;
|
62 |
-
|
63 |
-
if(!isset($tasks[$task]))
|
64 |
-
return false;
|
65 |
-
|
66 |
-
unset($tasks[$task]);
|
67 |
-
|
68 |
-
update_option(self::CRON_OPTION_NAME, $tasks);
|
69 |
-
|
70 |
-
return true;
|
71 |
-
}
|
72 |
-
|
73 |
-
// Updates cron task, creates task if not exists
|
74 |
-
static public function updateTask($task, $handler, $period, $first_call = null){
|
75 |
-
self::addTask($task, $handler, $period, $first_call, true);
|
76 |
-
}
|
77 |
-
|
78 |
/**
|
79 |
-
*
|
80 |
*
|
81 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
*/
|
83 |
-
public function
|
84 |
{
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
}
|
87 |
-
|
88 |
-
// Getting tasks which should be run. Putting tasks that should be run to $this->tasks_to_run
|
89 |
-
public function checkTasks()
|
90 |
-
{
|
91 |
-
if(empty($this->tasks))
|
92 |
-
return true;
|
93 |
-
|
94 |
-
foreach($this->tasks as $task => $task_data){
|
95 |
-
|
96 |
-
if($task_data['next_call'] <= time())
|
97 |
-
$this->tasks_to_run[] = $task;
|
98 |
-
|
99 |
-
}unset($task, $task_data);
|
100 |
-
|
101 |
-
return $this->tasks_to_run;
|
102 |
-
}
|
103 |
-
|
104 |
-
// Run all tasks from $this->tasks_to_run. Saving all results to (array) $this->tasks_completed
|
105 |
-
public function runTasks()
|
106 |
-
{
|
107 |
-
if(empty($this->tasks_to_run))
|
108 |
-
return true;
|
109 |
-
|
110 |
-
foreach($this->tasks_to_run as $task){
|
111 |
-
|
112 |
-
$this->selectTask($task);
|
113 |
-
|
114 |
-
if(function_exists($this->handler)){
|
115 |
-
$this->tasks_completed[$task] = call_user_func($this->handler);
|
116 |
-
$this->next_call = time() + $this->period;
|
117 |
-
}else{
|
118 |
-
$this->tasks_completed[$task] = false;
|
119 |
-
}
|
120 |
-
|
121 |
-
$this->saveTask($task);
|
122 |
-
|
123 |
-
}unset($task, $task_data);
|
124 |
-
|
125 |
-
$this->saveTasks();
|
126 |
-
|
127 |
-
return $this->tasks_completed;
|
128 |
-
}
|
129 |
-
|
130 |
-
// Select task in private properties for comfortable use.
|
131 |
-
private function selectTask($task)
|
132 |
-
{
|
133 |
-
$this->task = $task;
|
134 |
-
$this->handler = $this->tasks[$task]['handler'];
|
135 |
-
$this->period = $this->tasks[$task]['period'];
|
136 |
-
$this->next_call = $this->tasks[$task]['next_call'];
|
137 |
-
}
|
138 |
-
|
139 |
-
// Save task in private properties for comfortable use
|
140 |
-
private function saveTask($task)
|
141 |
-
{
|
142 |
-
$task = $this->task;
|
143 |
-
$this->tasks[$task]['handler'] = $this->handler;
|
144 |
-
$this->tasks[$task]['period'] = $this->period;
|
145 |
-
$this->tasks[$task]['next_call'] = $this->next_call;
|
146 |
-
}
|
147 |
-
|
148 |
-
// Save option with tasks
|
149 |
-
private function saveTasks()
|
150 |
-
{
|
151 |
-
update_option(self::CRON_OPTION_NAME, $this->tasks);
|
152 |
-
}
|
153 |
}
|
2 |
|
3 |
namespace Cleantalk\ApbctWP;
|
4 |
|
5 |
+
/**
|
6 |
+
* CleanTalk Cron class
|
7 |
+
*
|
8 |
+
* @package Antispam by CleanTalk
|
9 |
+
* @subpackage Cron
|
10 |
+
* @Version 2.1.1
|
11 |
+
* @author Cleantalk team (welcome@cleantalk.org)
|
12 |
+
* @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
|
13 |
+
* @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
|
14 |
+
*
|
15 |
+
*/
|
16 |
|
17 |
class Cron
|
18 |
{
|
19 |
+
public $tasks = array(); // Array with tasks
|
20 |
+
public $tasks_to_run = array(); // Array with tasks which should be run now
|
21 |
+
public $tasks_completed = array(); // Result of executed tasks
|
22 |
+
|
23 |
+
// Currently selected task
|
24 |
+
public $task;
|
25 |
+
private $handler;
|
26 |
+
private $period;
|
27 |
+
private $next_call;
|
28 |
+
private $params;
|
29 |
+
|
30 |
+
// Option name with cron data
|
31 |
+
const CRON_OPTION_NAME = 'cleantalk_cron';
|
32 |
+
|
33 |
+
// Interval in seconds for restarting the task
|
34 |
+
const TASK_EXECUTION_MIN_INTERVAL = 120;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Cron constructor.
|
38 |
+
* Getting tasks option.
|
39 |
+
*/
|
40 |
+
public function __construct()
|
41 |
+
{
|
42 |
+
$this->tasks = self::getTasks();
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Getting all tasks
|
47 |
+
*
|
48 |
+
* @return array|bool|mixed|void
|
49 |
+
*/
|
50 |
+
public static function getTasks(){
|
51 |
+
$tasks = get_option(self::CRON_OPTION_NAME);
|
52 |
+
return empty($tasks) ? array() : $tasks;
|
53 |
+
}
|
54 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
/**
|
56 |
+
* Adding new cron task
|
57 |
*
|
58 |
+
* @param $task
|
59 |
+
* @param $handler
|
60 |
+
* @param $period
|
61 |
+
* @param null $first_call
|
62 |
+
* @param array $params
|
63 |
+
*
|
64 |
+
* @return bool
|
65 |
*/
|
66 |
+
public static function addTask($task, $handler, $period, $first_call = null, $params = array())
|
67 |
{
|
68 |
+
// First call time() + preiod
|
69 |
+
$first_call = !$first_call ? time()+$period : $first_call;
|
70 |
+
|
71 |
+
$tasks = self::getTasks();
|
72 |
+
|
73 |
+
if( isset( $tasks[ $task ] ) ){
|
74 |
+
return false;
|
75 |
+
}
|
76 |
+
|
77 |
+
// Task entry
|
78 |
+
$tasks[$task] = array(
|
79 |
+
'handler' => $handler,
|
80 |
+
'next_call' => $first_call,
|
81 |
+
'period' => $period,
|
82 |
+
'params' => $params,
|
83 |
+
);
|
84 |
+
|
85 |
+
return update_option(self::CRON_OPTION_NAME, $tasks);
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Removing cron task
|
90 |
+
*
|
91 |
+
* @param $task
|
92 |
+
*
|
93 |
+
* @return bool
|
94 |
+
*/
|
95 |
+
public static function removeTask($task)
|
96 |
+
{
|
97 |
+
$tasks = self::getTasks();
|
98 |
+
|
99 |
+
if( ! isset( $tasks[ $task ] ) ){
|
100 |
+
return false;
|
101 |
+
}
|
102 |
+
|
103 |
+
unset($tasks[$task]);
|
104 |
+
|
105 |
+
return update_option(self::CRON_OPTION_NAME, $tasks);
|
106 |
+
}
|
107 |
+
|
108 |
+
// Updates cron task, create task if not exists
|
109 |
+
public static function updateTask($task, $handler, $period, $first_call = null, $params = array()){
|
110 |
+
self::removeTask($task);
|
111 |
+
self::addTask($task, $handler, $period, $first_call, $params);
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Getting tasks which should be run
|
116 |
+
*
|
117 |
+
* @return bool|array
|
118 |
+
*/
|
119 |
+
public static function checkTasks()
|
120 |
+
{
|
121 |
+
$tasks = self::getTasks();
|
122 |
+
|
123 |
+
// No tasks to run
|
124 |
+
if( empty( $tasks ) ){
|
125 |
+
return false;
|
126 |
+
}
|
127 |
+
|
128 |
+
$tasks_to_run = array();
|
129 |
+
foreach($tasks as $task => &$task_data){
|
130 |
+
|
131 |
+
if(
|
132 |
+
! isset( $task_data['processing'], $task_data['last_call'] ) ||
|
133 |
+
( $task_data['processing'] === true && time() - $task_data['last_call'] > self::TASK_EXECUTION_MIN_INTERVAL )
|
134 |
+
){
|
135 |
+
$task_data['processing'] = false;
|
136 |
+
$task_data['last_call'] = 0;
|
137 |
+
}
|
138 |
+
|
139 |
+
if(
|
140 |
+
$task_data['processing'] === false &&
|
141 |
+
$task_data['next_call'] <= time() // default condition
|
142 |
+
){
|
143 |
+
|
144 |
+
$task_data['processing'] = true;
|
145 |
+
$task_data['last_call'] = time();
|
146 |
+
|
147 |
+
$tasks_to_run[] = $task;
|
148 |
+
}
|
149 |
+
|
150 |
+
}
|
151 |
+
|
152 |
+
self::saveTasks( $tasks );
|
153 |
+
|
154 |
+
return $tasks_to_run;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Run all tasks from $this->tasks_to_run.
|
159 |
+
* Saving all results to (array) $this->tasks_completed
|
160 |
+
*
|
161 |
+
* @return void
|
162 |
+
*/
|
163 |
+
public function runTasks()
|
164 |
+
{
|
165 |
+
global $apbct;
|
166 |
+
|
167 |
+
if( empty( $this->tasks_to_run ) ){
|
168 |
+
return;
|
169 |
+
}
|
170 |
+
|
171 |
+
foreach($this->tasks_to_run as $task){
|
172 |
+
|
173 |
+
$this->selectTask($task);
|
174 |
+
|
175 |
+
if(function_exists($this->handler)){
|
176 |
+
|
177 |
+
$result = call_user_func_array($this->handler, isset($this->params) ? $this->params : array());
|
178 |
+
|
179 |
+
if(empty($result['error'])){
|
180 |
+
$this->tasks_completed[$task] = true;
|
181 |
+
$apbct->error_delete($task, 'save_data', 'cron');
|
182 |
+
}else{
|
183 |
+
$this->tasks_completed[$task] = false;
|
184 |
+
$apbct->error_add($task, $result, 'cron');
|
185 |
+
}
|
186 |
+
|
187 |
+
}else{
|
188 |
+
$this->tasks_completed[$task] = false;
|
189 |
+
$apbct->error_add($task, $this->handler.'_IS_NOT_EXISTS', 'cron');
|
190 |
+
}
|
191 |
+
|
192 |
+
$this->saveTask($task);
|
193 |
+
|
194 |
+
}
|
195 |
+
|
196 |
+
//* Merging executed tasks with updated during execution
|
197 |
+
$tasks = self::getTasks();
|
198 |
+
|
199 |
+
foreach($tasks as $task => $task_data){
|
200 |
+
|
201 |
+
// Task where added during execution
|
202 |
+
if(!isset($this->tasks[$task])){
|
203 |
+
$this->tasks[$task] = $task_data;
|
204 |
+
continue;
|
205 |
+
}
|
206 |
+
|
207 |
+
// Task where updated during execution
|
208 |
+
if($task_data !== $this->tasks[$task]){
|
209 |
+
$this->tasks[$task] = $task_data;
|
210 |
+
continue;
|
211 |
+
}
|
212 |
+
|
213 |
+
// Setting next call depending on results
|
214 |
+
if(isset($this->tasks[$task], $this->tasks_completed[$task])){
|
215 |
+
$this->tasks[$task]['next_call'] = $this->tasks_completed[$task]
|
216 |
+
? time() + $this->tasks[$task]['period']
|
217 |
+
: time() + round($this->tasks[$task]['period']/4);
|
218 |
+
}
|
219 |
+
|
220 |
+
if(empty($this->tasks[$task]['next_call']) || $this->tasks[$task]['next_call'] < time()){
|
221 |
+
$this->tasks[$task]['next_call'] = time() + $this->tasks[$task]['period'];
|
222 |
+
}
|
223 |
+
|
224 |
+
}
|
225 |
+
|
226 |
+
// Task where deleted during execution
|
227 |
+
$tmp = $this->tasks;
|
228 |
+
foreach($tmp as $task => $task_data){
|
229 |
+
if( ! isset( $tasks[ $task ] ) ){
|
230 |
+
unset( $this->tasks[ $task ] );
|
231 |
+
}
|
232 |
+
}
|
233 |
+
|
234 |
+
//*/ End of merging
|
235 |
+
|
236 |
+
self::saveTasks( $this->tasks );
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Select task in private properties for comfortable use
|
241 |
+
*
|
242 |
+
* @param $task
|
243 |
+
*/
|
244 |
+
private function selectTask($task)
|
245 |
+
{
|
246 |
+
$this->task = $task;
|
247 |
+
$this->handler = $this->tasks[$task]['handler'];
|
248 |
+
$this->period = $this->tasks[$task]['period'];
|
249 |
+
$this->next_call = $this->tasks[$task]['next_call'];
|
250 |
+
$this->params = isset($this->tasks[$task]['params']) ? $this->tasks[$task]['params'] : array();
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Save task in private properties for comfortable use
|
255 |
+
*
|
256 |
+
* @param null $task
|
257 |
+
*/
|
258 |
+
private function saveTask( $task = null )
|
259 |
+
{
|
260 |
+
$task = $task ?: $this->task;
|
261 |
+
|
262 |
+
$this->tasks[$task]['handler'] = $this->handler;
|
263 |
+
$this->tasks[$task]['period'] = $this->period;
|
264 |
+
$this->tasks[$task]['next_call'] = $this->next_call;
|
265 |
+
$this->tasks[$task]['params'] = $this->params;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Save option with tasks
|
270 |
+
*
|
271 |
+
* @param array $tasks
|
272 |
+
*/
|
273 |
+
public static function saveTasks( $tasks = array() )
|
274 |
+
{
|
275 |
+
update_option( self::CRON_OPTION_NAME, $tasks );
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* @param array $tasks_to_run
|
280 |
+
*/
|
281 |
+
public function setTasksToRun( $tasks_to_run ){
|
282 |
+
$this->tasks_to_run = $tasks_to_run;
|
283 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
}
|
@@ -1,65 +1,67 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Cleantalk\ApbctWP\FindSpam\ListTable;
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
$
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
$this->
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
$
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
$
|
35 |
-
|
36 |
-
|
37 |
-
'
|
38 |
-
'
|
39 |
-
'
|
40 |
-
'
|
41 |
-
'
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
<
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
|
|
|
|
65 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Cleantalk\ApbctWP\FindSpam\ListTable;
|
4 |
+
|
5 |
+
use Cleantalk\Variables\Server;
|
6 |
+
|
7 |
+
class UsersScan extends Users
|
8 |
+
{
|
9 |
+
|
10 |
+
function prepare_items() {
|
11 |
+
|
12 |
+
$columns = $this->get_columns();
|
13 |
+
$this->_column_headers = array( $columns, array(), array() );
|
14 |
+
|
15 |
+
$per_page_option = get_current_screen()->get_option( 'per_page', 'option' );
|
16 |
+
$per_page = get_user_meta( get_current_user_id(), $per_page_option, true );
|
17 |
+
if( ! $per_page ) {
|
18 |
+
$per_page = 10;
|
19 |
+
}
|
20 |
+
|
21 |
+
$scanned_users = $this->getSpamNow();
|
22 |
+
|
23 |
+
$this->set_pagination_args( array(
|
24 |
+
'total_items' => $scanned_users->get_total(),
|
25 |
+
'per_page' => $per_page,
|
26 |
+
) );
|
27 |
+
|
28 |
+
$current_page = (int) $this->get_pagenum();
|
29 |
+
|
30 |
+
$scanned_users_to_show = array_slice( $scanned_users->get_results(), ( ( $current_page - 1 ) * $per_page ), $per_page );
|
31 |
+
|
32 |
+
foreach( $scanned_users_to_show as $user_id ) {
|
33 |
+
|
34 |
+
$user_obj = get_userdata( $user_id );
|
35 |
+
|
36 |
+
$this->items[] = array(
|
37 |
+
'ct_id' => $user_obj->ID,
|
38 |
+
'ct_username' => $user_obj,
|
39 |
+
'ct_name' => $user_obj->display_name,
|
40 |
+
'ct_email' => $user_obj->user_email,
|
41 |
+
'ct_signed_up' => $user_obj->user_registered,
|
42 |
+
'ct_role' => implode( ', ', $user_obj->roles ),
|
43 |
+
'ct_posts' => count_user_posts( $user_id ),
|
44 |
+
);
|
45 |
+
|
46 |
+
}
|
47 |
+
|
48 |
+
}
|
49 |
+
|
50 |
+
function extra_tablenav( $which ) {
|
51 |
+
if( isset( $_SERVER['SERVER_ADDR'] ) && $_SERVER['SERVER_ADDR'] === '127.0.0.1' && in_array( Server::get_domain(), array( 'lc', 'loc', 'lh' ) )){
|
52 |
+
?>
|
53 |
+
<button type="button" class="button action ct_insert_users">Insert users</button>
|
54 |
+
<button type="button" class="button action ct_insert_users__delete">Delete inserted</button>
|
55 |
+
<?php
|
56 |
+
}
|
57 |
+
if( ! $this->has_items() ) return;
|
58 |
+
?>
|
59 |
+
<div class="alignleft actions bulkactions">
|
60 |
+
<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>
|
61 |
+
<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>
|
62 |
+
<span class="spinner"></span>
|
63 |
+
</div>
|
64 |
+
<?php
|
65 |
+
}
|
66 |
+
|
67 |
}
|
@@ -15,7 +15,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
15 |
private $api_key = '';
|
16 |
private $apbct = false;
|
17 |
private $store_interval = 60;
|
18 |
-
private $
|
19 |
private $ua_id = 'null'; //User-Agent
|
20 |
|
21 |
private $ac_log_result = '';
|
@@ -36,8 +36,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
36 |
$this->db__table__logs = $log_table ?: null;
|
37 |
$this->db__table__ac_logs = $ac_logs_table ?: null;
|
38 |
$this->db__table__ac_ua_bl= defined('APBCT_TBL_AC_UA_BL') ? APBCT_TBL_AC_UA_BL : null;
|
39 |
-
$this->
|
40 |
-
|
41 |
|
42 |
foreach( $params as $param_name => $param ){
|
43 |
$this->$param_name = isset( $this->$param_name ) ? $param : false;
|
@@ -222,9 +221,8 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
222 |
"SELECT ip"
|
223 |
. ' FROM `' . $this->db__table__ac_logs . '`'
|
224 |
. " WHERE ip = '$current_ip'"
|
225 |
-
. " AND ua = '$this->
|
226 |
);
|
227 |
-
|
228 |
if( isset( $result['ip'] ) ){
|
229 |
|
230 |
if( Cookie::get('apbct_antibot') !== hash( 'sha256', $this->api_key . $this->apbct->data['salt'] ) ){
|
@@ -267,12 +265,12 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
267 |
// @todo Rename ip column to sign. Use IP + UserAgent for it.
|
268 |
|
269 |
foreach( $this->ip_array as $ip_origin => $current_ip ){
|
270 |
-
$id = md5( $current_ip . $this->
|
271 |
$this->db->execute(
|
272 |
"INSERT INTO " . $this->db__table__ac_logs . " SET
|
273 |
id = '$id',
|
274 |
ip = '$current_ip',
|
275 |
-
ua = '$this->
|
276 |
entries = 1,
|
277 |
interval_start = $interval_time
|
278 |
ON DUPLICATE KEY UPDATE
|
@@ -348,7 +346,7 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
348 |
'{CLEANTALK_TITLE}' => __( 'Antispam by CleanTalk', 'cleantalk-spam-protect' ),
|
349 |
'{REMOTE_ADDRESS}' => $result['ip'],
|
350 |
'{SERVICE_ID}' => $this->apbct->data['service_id'] . ', ' . $net_count,
|
351 |
-
'{HOST}' => Server::get( 'HTTP_HOST' ),
|
352 |
'{COOKIE_ANTICRAWLER}' => hash( 'sha256', $apbct->api_key . $apbct->data['salt'] ),
|
353 |
'{COOKIE_ANTICRAWLER_PASSED}' => '1',
|
354 |
'{GENERATED}' => '<p>The page was generated at ' . date( 'D, d M Y H:i:s' ) . "</p>",
|
15 |
private $api_key = '';
|
16 |
private $apbct = false;
|
17 |
private $store_interval = 60;
|
18 |
+
private $sign; //Signature - User-Agent + Protocol
|
19 |
private $ua_id = 'null'; //User-Agent
|
20 |
|
21 |
private $ac_log_result = '';
|
36 |
$this->db__table__logs = $log_table ?: null;
|
37 |
$this->db__table__ac_logs = $ac_logs_table ?: null;
|
38 |
$this->db__table__ac_ua_bl= defined('APBCT_TBL_AC_UA_BL') ? APBCT_TBL_AC_UA_BL : null;
|
39 |
+
$this->sign = md5( Server::get('HTTP_USER_AGENT') . Server::get('HTTPS') . Server::get('HTTP_HOST') );
|
|
|
40 |
|
41 |
foreach( $params as $param_name => $param ){
|
42 |
$this->$param_name = isset( $this->$param_name ) ? $param : false;
|
221 |
"SELECT ip"
|
222 |
. ' FROM `' . $this->db__table__ac_logs . '`'
|
223 |
. " WHERE ip = '$current_ip'"
|
224 |
+
. " AND ua = '$this->sign' AND " . random_int( 10000, 100000 ) . ";"
|
225 |
);
|
|
|
226 |
if( isset( $result['ip'] ) ){
|
227 |
|
228 |
if( Cookie::get('apbct_antibot') !== hash( 'sha256', $this->api_key . $this->apbct->data['salt'] ) ){
|
265 |
// @todo Rename ip column to sign. Use IP + UserAgent for it.
|
266 |
|
267 |
foreach( $this->ip_array as $ip_origin => $current_ip ){
|
268 |
+
$id = md5( $current_ip . $this->sign . $interval_time );
|
269 |
$this->db->execute(
|
270 |
"INSERT INTO " . $this->db__table__ac_logs . " SET
|
271 |
id = '$id',
|
272 |
ip = '$current_ip',
|
273 |
+
ua = '$this->sign',
|
274 |
entries = 1,
|
275 |
interval_start = $interval_time
|
276 |
ON DUPLICATE KEY UPDATE
|
346 |
'{CLEANTALK_TITLE}' => __( 'Antispam by CleanTalk', 'cleantalk-spam-protect' ),
|
347 |
'{REMOTE_ADDRESS}' => $result['ip'],
|
348 |
'{SERVICE_ID}' => $this->apbct->data['service_id'] . ', ' . $net_count,
|
349 |
+
'{HOST}' => Server::get( 'HTTP_HOST' ) . ', ' . APBCT_VERSION,
|
350 |
'{COOKIE_ANTICRAWLER}' => hash( 'sha256', $apbct->api_key . $apbct->data['salt'] ),
|
351 |
'{COOKIE_ANTICRAWLER_PASSED}' => '1',
|
352 |
'{GENERATED}' => '<p>The page was generated at ' . date( 'D, d M Y H:i:s' ) . "</p>",
|
@@ -75,7 +75,7 @@ class AntiFlood extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
75 |
$result = $this->db->fetch_all(
|
76 |
"SELECT SUM(entries) as total_count"
|
77 |
. ' FROM `' . $this->db__table__ac_logs . '`'
|
78 |
-
. " WHERE ip = '$current_ip' AND interval_start > '$time';"
|
79 |
);
|
80 |
|
81 |
if( ! empty( $result ) && isset( $result[0]['total_count'] ) && $result[0]['total_count'] >= $this->view_limit ){
|
@@ -186,7 +186,7 @@ class AntiFlood extends \Cleantalk\Common\Firewall\FirewallModule{
|
|
186 |
'{REMOTE_ADDRESS}' => $result['ip'],
|
187 |
'{REQUEST_URI}' => Server::get( 'REQUEST_URI' ),
|
188 |
'{SERVICE_ID}' => $this->apbct->data['service_id'] . ', ' . $net_count,
|
189 |
-
'{HOST}' => Server::get( 'HTTP_HOST' ),
|
190 |
'{GENERATED}' => '<p>The page was generated at ' . date( 'D, d M Y H:i:s' ) . "</p>",
|
191 |
'{COOKIE_ANTIFLOOD_PASSED}' => md5( $this->api_key . $result['ip'] ),
|
192 |
);
|
75 |
$result = $this->db->fetch_all(
|
76 |
"SELECT SUM(entries) as total_count"
|
77 |
. ' FROM `' . $this->db__table__ac_logs . '`'
|
78 |
+
. " WHERE ip = '$current_ip' AND interval_start > '$time' AND " . random_int( 10000, 100000 ) . ";"
|
79 |
);
|
80 |
|
81 |
if( ! empty( $result ) && isset( $result[0]['total_count'] ) && $result[0]['total_count'] >= $this->view_limit ){
|
186 |
'{REMOTE_ADDRESS}' => $result['ip'],
|
187 |
'{REQUEST_URI}' => Server::get( 'REQUEST_URI' ),
|
188 |
'{SERVICE_ID}' => $this->apbct->data['service_id'] . ', ' . $net_count,
|
189 |
+
'{HOST}' => Server::get( 'HTTP_HOST' ) . ', ' . APBCT_VERSION,
|
190 |
'{GENERATED}' => '<p>The page was generated at ' . date( 'D, d M Y H:i:s' ) . "</p>",
|
191 |
'{COOKIE_ANTIFLOOD_PASSED}' => md5( $this->api_key . $result['ip'] ),
|
192 |
);
|
@@ -127,7 +127,9 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
|
|
127 |
network, mask, status
|
128 |
FROM " . $this->db__table__data . "
|
129 |
WHERE network IN (". implode( ',', $needles ) .")
|
130 |
-
AND network = " . $current_ip_v4 . " & mask
|
|
|
|
|
131 |
|
132 |
if( ! empty( $db_results ) ){
|
133 |
|
@@ -240,7 +242,7 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule {
|
|
240 |
'{CLEANTALK_TITLE}' => ($this->test ? __('This is the testing page for SpamFireWall', 'cleantalk-spam-protect') : ''),
|
241 |
'{REMOTE_ADDRESS}' => $result['ip'],
|
242 |
'{SERVICE_ID}' => $this->apbct->data['service_id'] . ', ' . $net_count,
|
243 |
-
'{HOST}' => Server::get( 'HTTP_HOST' ),
|
244 |
'{GENERATED}' => '<p>The page was generated at ' . date( 'D, d M Y H:i:s' ) . "</p>",
|
245 |
'{REQUEST_URI}' => Server::get( 'REQUEST_URI' ),
|
246 |
|
127 |
network, mask, status
|
128 |
FROM " . $this->db__table__data . "
|
129 |
WHERE network IN (". implode( ',', $needles ) .")
|
130 |
+
AND network = " . $current_ip_v4 . " & mask
|
131 |
+
AND " . random_int( 10000, 100000 ) . "
|
132 |
+
ORDER BY status DESC");
|
133 |
|
134 |
if( ! empty( $db_results ) ){
|
135 |
|
242 |
'{CLEANTALK_TITLE}' => ($this->test ? __('This is the testing page for SpamFireWall', 'cleantalk-spam-protect') : ''),
|
243 |
'{REMOTE_ADDRESS}' => $result['ip'],
|
244 |
'{SERVICE_ID}' => $this->apbct->data['service_id'] . ', ' . $net_count,
|
245 |
+
'{HOST}' => Server::get( 'HTTP_HOST' ) . ', ' . APBCT_VERSION,
|
246 |
'{GENERATED}' => '<p>The page was generated at ' . date( 'D, d M Y H:i:s' ) . "</p>",
|
247 |
'{REQUEST_URI}' => Server::get( 'REQUEST_URI' ),
|
248 |
|
@@ -2,13 +2,15 @@
|
|
2 |
|
3 |
namespace Cleantalk\Common;
|
4 |
|
|
|
|
|
5 |
/**
|
6 |
* CleanTalk Helper class.
|
7 |
* Compatible with any CMS.
|
8 |
*
|
9 |
* @package PHP Antispam by CleanTalk
|
10 |
* @subpackage Helper
|
11 |
-
* @Version 3.
|
12 |
* @author Cleantalk team (welcome@cleantalk.org)
|
13 |
* @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
|
14 |
* @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
|
@@ -60,147 +62,212 @@ class Helper
|
|
60 |
'netserv2.cleantalk.org' => '178.63.60.214',
|
61 |
'netserv3.cleantalk.org' => '188.40.14.173',
|
62 |
);
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
|
205 |
/**
|
206 |
* Checks if the IP is in private range
|
@@ -229,6 +296,10 @@ class Helper
|
|
229 |
*/
|
230 |
static public function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = 0)
|
231 |
{
|
|
|
|
|
|
|
|
|
232 |
if(is_array($cidr)){
|
233 |
foreach($cidr as $curr_mask){
|
234 |
if(self::ip__mask_match($ip, $curr_mask, $ip_type)){
|
@@ -305,6 +376,18 @@ class Helper
|
|
305 |
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && self::ip__v6_reduce($ip) != '0::0') return 'v6'; // IPv6
|
306 |
return false; // Unknown
|
307 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
|
309 |
/**
|
310 |
* Expand IPv6
|
@@ -862,4 +945,32 @@ class Helper
|
|
862 |
}
|
863 |
return $param;
|
864 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
865 |
}
|
2 |
|
3 |
namespace Cleantalk\Common;
|
4 |
|
5 |
+
use Cleantalk\Variables\Server;
|
6 |
+
|
7 |
/**
|
8 |
* CleanTalk Helper class.
|
9 |
* Compatible with any CMS.
|
10 |
*
|
11 |
* @package PHP Antispam by CleanTalk
|
12 |
* @subpackage Helper
|
13 |
+
* @Version 3.5
|
14 |
* @author Cleantalk team (welcome@cleantalk.org)
|
15 |
* @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
|
16 |
* @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
|
62 |
'netserv2.cleantalk.org' => '178.63.60.214',
|
63 |
'netserv3.cleantalk.org' => '188.40.14.173',
|
64 |
);
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
|
68 |
+
*
|
69 |
+
* @param string $ip_type_to_get Type of IP you want to receive
|
70 |
+
* @param bool $v4_only
|
71 |
+
*
|
72 |
+
* @return string|null
|
73 |
+
*/
|
74 |
+
public static function ip__get( $ip_type_to_get = 'real', $v4_only = true, $headers = array() )
|
75 |
+
{
|
76 |
+
$out = null;
|
77 |
+
|
78 |
+
switch( $ip_type_to_get ){
|
79 |
+
|
80 |
+
// Cloud Flare
|
81 |
+
case 'cloud_flare':
|
82 |
+
$headers = $headers ?: self::http__get_headers();
|
83 |
+
if( isset( $headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'] ) ){
|
84 |
+
$tmp = strpos( $headers['Cf-Connecting-Ip'], ',' ) !== false
|
85 |
+
? explode( ',', $headers['Cf-Connecting-Ip'] )
|
86 |
+
: (array) $headers['Cf-Connecting-Ip'];
|
87 |
+
$ip_version = self::ip__validate( trim( $tmp[0] ) );
|
88 |
+
if( $ip_version ){
|
89 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( trim( $tmp[0] ) ) : trim( $tmp[0] );
|
90 |
+
}
|
91 |
+
}
|
92 |
+
break;
|
93 |
+
|
94 |
+
// GTranslate
|
95 |
+
case 'gtranslate':
|
96 |
+
$headers = $headers ?: self::http__get_headers();
|
97 |
+
if( isset( $headers['X-Gt-Clientip'], $headers['X-Gt-Viewer-Ip'] ) ){
|
98 |
+
$ip_version = self::ip__validate( $headers['X-Gt-Viewer-Ip'] );
|
99 |
+
if( $ip_version ){
|
100 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $headers['X-Gt-Viewer-Ip'] ) : $headers['X-Gt-Viewer-Ip'];
|
101 |
+
}
|
102 |
+
}
|
103 |
+
break;
|
104 |
+
|
105 |
+
// ezoic
|
106 |
+
case 'ezoic':
|
107 |
+
$headers = $headers ?: self::http__get_headers();
|
108 |
+
if( isset( $headers['X-Middleton'], $headers['X-Middleton-Ip'] ) ){
|
109 |
+
$ip_version = self::ip__validate( $headers['X-Middleton-Ip'] );
|
110 |
+
if( $ip_version ){
|
111 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $headers['X-Middleton-Ip'] ) : $headers['X-Middleton-Ip'];
|
112 |
+
}
|
113 |
+
}
|
114 |
+
break;
|
115 |
+
|
116 |
+
// Sucury
|
117 |
+
case 'sucury':
|
118 |
+
$headers = $headers ?: self::http__get_headers();
|
119 |
+
if( isset( $headers['X-Sucuri-Clientip'] ) ){
|
120 |
+
$ip_version = self::ip__validate( $headers['X-Sucuri-Clientip'] );
|
121 |
+
if( $ip_version ){
|
122 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $headers['X-Sucuri-Clientip'] ) : $headers['X-Sucuri-Clientip'];
|
123 |
+
}
|
124 |
+
}
|
125 |
+
break;
|
126 |
+
|
127 |
+
// X-Forwarded-By
|
128 |
+
case 'x_forwarded_by':
|
129 |
+
$headers = $headers ?: self::http__get_headers();
|
130 |
+
if( isset( $headers['X-Forwarded-By'], $headers['X-Client-Ip'] ) ){
|
131 |
+
$ip_version = self::ip__validate( $headers['X-Client-Ip'] );
|
132 |
+
if( $ip_version ){
|
133 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $headers['X-Client-Ip'] ) : $headers['X-Client-Ip'];
|
134 |
+
}
|
135 |
+
}
|
136 |
+
break;
|
137 |
+
|
138 |
+
// Stackpath
|
139 |
+
case 'stackpath':
|
140 |
+
$headers = $headers ?: self::http__get_headers();
|
141 |
+
if( isset( $headers['X-Sp-Edge-Host'], $headers['X-Sp-Forwarded-Ip'] ) ){
|
142 |
+
$ip_version = self::ip__validate( $headers['X-Sp-Forwarded-Ip'] );
|
143 |
+
if( $ip_version ){
|
144 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $headers['X-Sp-Forwarded-Ip'] ) : $headers['X-Sp-Forwarded-Ip'];
|
145 |
+
}
|
146 |
+
}
|
147 |
+
break;
|
148 |
+
|
149 |
+
// Ico-X-Forwarded-For
|
150 |
+
case 'ico_x_forwarded_for':
|
151 |
+
$headers = $headers ?: self::http__get_headers();
|
152 |
+
if( isset( $headers['Ico-X-Forwarded-For'], $headers['X-Forwarded-Host'] ) ){
|
153 |
+
$ip_version = self::ip__validate( $headers['Ico-X-Forwarded-For'] );
|
154 |
+
if( $ip_version ){
|
155 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $headers['Ico-X-Forwarded-For'] ) : $headers['Ico-X-Forwarded-For'];
|
156 |
+
}
|
157 |
+
}
|
158 |
+
break;
|
159 |
+
|
160 |
+
// OVH
|
161 |
+
case 'ovh':
|
162 |
+
$headers = $headers ?: self::http__get_headers();
|
163 |
+
if( isset( $headers['X-Cdn-Any-Ip'], $headers['Remote-Ip'] ) ){
|
164 |
+
$ip_version = self::ip__validate( $headers['Remote-Ip'] );
|
165 |
+
if( $ip_version ){
|
166 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $headers['Remote-Ip'] ) : $headers['Remote-Ip'];
|
167 |
+
}
|
168 |
+
}
|
169 |
+
break;
|
170 |
+
|
171 |
+
// Incapsula proxy
|
172 |
+
case 'incapsula':
|
173 |
+
$headers = $headers ?: self::http__get_headers();
|
174 |
+
if( isset( $headers['Incap-Client-Ip'], $headers['X-Forwarded-For'] ) ){
|
175 |
+
$ip_version = self::ip__validate( $headers['Incap-Client-Ip'] );
|
176 |
+
if( $ip_version ){
|
177 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $headers['Incap-Client-Ip'] ) : $headers['Incap-Client-Ip'];
|
178 |
+
}
|
179 |
+
}
|
180 |
+
break;
|
181 |
+
|
182 |
+
// Remote addr
|
183 |
+
case 'remote_addr':
|
184 |
+
$ip_version = self::ip__validate( Server::get( 'REMOTE_ADDR' ) );
|
185 |
+
if( $ip_version ){
|
186 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( Server::get( 'REMOTE_ADDR' ) ) : Server::get( 'REMOTE_ADDR' );
|
187 |
+
}
|
188 |
+
break;
|
189 |
+
|
190 |
+
// X-Forwarded-For
|
191 |
+
case 'x_forwarded_for':
|
192 |
+
$headers = $headers ?: self::http__get_headers();
|
193 |
+
if( isset( $headers['X-Forwarded-For'] ) ){
|
194 |
+
$tmp = explode( ',', trim( $headers['X-Forwarded-For'] ) );
|
195 |
+
$tmp = trim( $tmp[0] );
|
196 |
+
$ip_version = self::ip__validate( $tmp );
|
197 |
+
if( $ip_version ){
|
198 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize( $tmp ) : $tmp;
|
199 |
+
}
|
200 |
+
}
|
201 |
+
break;
|
202 |
+
|
203 |
+
// X-Real-Ip
|
204 |
+
case 'x_real_ip':
|
205 |
+
$headers = $headers ?: self::http__get_headers();
|
206 |
+
if(isset($headers['X-Real-Ip'])){
|
207 |
+
$tmp = explode(",", trim($headers['X-Real-Ip']));
|
208 |
+
$tmp = trim($tmp[0]);
|
209 |
+
$ip_version = self::ip__validate($tmp);
|
210 |
+
if($ip_version){
|
211 |
+
$out = $ip_version === 'v6' && ! $v4_only ? self::ip__v6_normalize($tmp) : $tmp;
|
212 |
+
}
|
213 |
+
}
|
214 |
+
break;
|
215 |
+
|
216 |
+
// Real
|
217 |
+
// Getting real IP from REMOTE_ADDR or Cf_Connecting_Ip if set or from (X-Forwarded-For, X-Real-Ip) if REMOTE_ADDR is local.
|
218 |
+
case 'real':
|
219 |
+
|
220 |
+
// Detect IP type
|
221 |
+
$out = self::ip__get( 'cloud_flare', $v4_only, $headers );
|
222 |
+
$out = $out ?: self::ip__get( 'sucury', $v4_only, $headers );
|
223 |
+
$out = $out ?: self::ip__get( 'gtranslate', $v4_only, $headers );
|
224 |
+
$out = $out ?: self::ip__get( 'ezoic', $v4_only, $headers );
|
225 |
+
$out = $out ?: self::ip__get( 'stackpath', $v4_only, $headers );
|
226 |
+
$out = $out ?: self::ip__get( 'x_forwarded_by', $v4_only, $headers );
|
227 |
+
$out = $out ?: self::ip__get( 'ico_x_forwarded_for', $v4_only, $headers );
|
228 |
+
$out = $out ?: self::ip__get( 'ovh', $v4_only, $headers );
|
229 |
+
$out = $out ?: self::ip__get( 'incapsula', $v4_only, $headers );
|
230 |
+
|
231 |
+
$ip_version = self::ip__validate( $out );
|
232 |
+
|
233 |
+
// Is private network
|
234 |
+
if(
|
235 |
+
$out &&
|
236 |
+
(
|
237 |
+
self::ip__is_private_network( $out, $ip_version ) ||
|
238 |
+
self::ip__mask_match(
|
239 |
+
$out,
|
240 |
+
Server::get( 'SERVER_ADDR' ) . '/24',
|
241 |
+
$ip_version
|
242 |
+
)
|
243 |
+
)
|
244 |
+
){
|
245 |
+
//@todo Remove local IP from x-forwarded-for and x-real-ip
|
246 |
+
$out = $out ?: self::ip__get( 'x_forwarded_for', $v4_only, $headers );
|
247 |
+
$out = $out ?: self::ip__get( 'x_real_ip', $v4_only, $headers );
|
248 |
+
}
|
249 |
+
|
250 |
+
$out = $out ?: self::ip__get( 'remote_addr', $v4_only, $headers );
|
251 |
+
|
252 |
+
break;
|
253 |
+
|
254 |
+
default:
|
255 |
+
$out = self::ip__get( 'real', $v4_only, $headers );
|
256 |
+
}
|
257 |
+
|
258 |
+
// Final validating IP
|
259 |
+
$ip_version = self::ip__validate( $out );
|
260 |
+
|
261 |
+
if( ! $ip_version ){
|
262 |
+
return null;
|
263 |
+
|
264 |
+
}elseif( $ip_version === 'v6' && $v4_only ){
|
265 |
+
return null;
|
266 |
+
|
267 |
+
}else{
|
268 |
+
return $out;
|
269 |
+
}
|
270 |
+
}
|
271 |
|
272 |
/**
|
273 |
* Checks if the IP is in private range
|
296 |
*/
|
297 |
static public function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = 0)
|
298 |
{
|
299 |
+
if( ! self::ip__validate( $ip ) || ! self::cidr__validate( $cidr ) ){
|
300 |
+
return false;
|
301 |
+
}
|
302 |
+
|
303 |
if(is_array($cidr)){
|
304 |
foreach($cidr as $curr_mask){
|
305 |
if(self::ip__mask_match($ip, $curr_mask, $ip_type)){
|
376 |
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && self::ip__v6_reduce($ip) != '0::0') return 'v6'; // IPv6
|
377 |
return false; // Unknown
|
378 |
}
|
379 |
+
|
380 |
+
/**
|
381 |
+
* Validate CIDR
|
382 |
+
*
|
383 |
+
* @param string $cidr expects string like 1.1.1.1/32
|
384 |
+
*
|
385 |
+
* @return bool
|
386 |
+
*/
|
387 |
+
public static function cidr__validate( $cidr ){
|
388 |
+
$cidr = explode( '/', $cidr );
|
389 |
+
return isset( $cidr[0], $cidr[1] ) && self::ip__validate( $cidr[0] ) && preg_match( '@\d{1,2}@', $cidr[1] );
|
390 |
+
}
|
391 |
|
392 |
/**
|
393 |
* Expand IPv6
|
945 |
}
|
946 |
return $param;
|
947 |
}
|
948 |
+
|
949 |
+
/**
|
950 |
+
* Gets every HTTP_ headers from $_SERVER
|
951 |
+
*
|
952 |
+
* If Apache web server is missing then making
|
953 |
+
* Patch for apache_request_headers()
|
954 |
+
*
|
955 |
+
* returns array
|
956 |
+
*/
|
957 |
+
public static function http__get_headers(){
|
958 |
+
|
959 |
+
$headers = array();
|
960 |
+
foreach($_SERVER as $key => $val){
|
961 |
+
if( 0 === stripos( $key, 'http_' ) ){
|
962 |
+
$server_key = preg_replace('/^http_/i', '', $key);
|
963 |
+
$key_parts = explode('_', $server_key);
|
964 |
+
if(count($key_parts) > 0 and strlen($server_key) > 2){
|
965 |
+
foreach($key_parts as $part_index => $part){
|
966 |
+
$key_parts[$part_index] = function_exists('mb_strtolower') ? mb_strtolower($part) : strtolower($part);
|
967 |
+
$key_parts[$part_index][0] = strtoupper($key_parts[$part_index][0]);
|
968 |
+
}
|
969 |
+
$server_key = implode('-', $key_parts);
|
970 |
+
}
|
971 |
+
$headers[$server_key] = $val;
|
972 |
+
}
|
973 |
+
}
|
974 |
+
return $headers;
|
975 |
+
}
|
976 |
}
|
@@ -62,7 +62,7 @@ class Schema
|
|
62 |
* @return array Array of schemas
|
63 |
* @throws \Exception Throws if calling un-existed schema
|
64 |
*/
|
65 |
-
public static function getSchema($table = null )
|
66 |
{
|
67 |
if( is_null( $table ) ) {
|
68 |
return self::$schemas;
|
62 |
* @return array Array of schemas
|
63 |
* @throws \Exception Throws if calling un-existed schema
|
64 |
*/
|
65 |
+
public static function getSchema( $table = null )
|
66 |
{
|
67 |
if( is_null( $table ) ) {
|
68 |
return self::$schemas;
|
@@ -1,35 +1,35 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Cleantalk\Templates;
|
4 |
-
|
5 |
-
if(!trait_exists('Cleantalk\Templates\Singleton')) {
|
6 |
-
|
7 |
-
trait Singleton{
|
8 |
-
|
9 |
-
static $instance;
|
10 |
-
|
11 |
-
public function __construct(){}
|
12 |
-
public function __wakeup(){}
|
13 |
-
public function __clone(){}
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Constructor
|
17 |
-
* @return $this
|
18 |
-
*/
|
19 |
-
public static function getInstance(){
|
20 |
-
if (!isset(static::$instance)) {
|
21 |
-
static::$instance = new static;
|
22 |
-
static::$instance->init();
|
23 |
-
}
|
24 |
-
return static::$instance;
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Alternative constructor
|
29 |
-
*/
|
30 |
-
|
31 |
-
|
32 |
-
}
|
33 |
-
|
34 |
-
}
|
35 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Cleantalk\Templates;
|
4 |
+
|
5 |
+
if(!trait_exists('Cleantalk\Templates\Singleton')) {
|
6 |
+
|
7 |
+
trait Singleton{
|
8 |
+
|
9 |
+
static $instance;
|
10 |
+
|
11 |
+
public function __construct(){}
|
12 |
+
public function __wakeup(){}
|
13 |
+
public function __clone(){}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Constructor
|
17 |
+
* @return $this
|
18 |
+
*/
|
19 |
+
public static function getInstance(){
|
20 |
+
if (!isset(static::$instance)) {
|
21 |
+
static::$instance = new static;
|
22 |
+
static::$instance->init();
|
23 |
+
}
|
24 |
+
return static::$instance;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Alternative constructor
|
29 |
+
*/
|
30 |
+
protected function init(){
|
31 |
+
|
32 |
+
}
|
33 |
+
|
34 |
+
}
|
35 |
+
}
|
@@ -45,7 +45,7 @@ class Cookie extends ServerVariables{
|
|
45 |
$value = isset( $_COOKIE[ $name ] ) ? $_COOKIE[ $name ] : '';
|
46 |
|
47 |
// Remember for thurther calls
|
48 |
-
static::getInstance()->
|
49 |
|
50 |
return $value;
|
51 |
}
|
45 |
$value = isset( $_COOKIE[ $name ] ) ? $_COOKIE[ $name ] : '';
|
46 |
|
47 |
// Remember for thurther calls
|
48 |
+
static::getInstance()->remember_variable( $name, $value );
|
49 |
|
50 |
return $value;
|
51 |
}
|
@@ -45,7 +45,7 @@ class Get extends ServerVariables{
|
|
45 |
$value = isset( $_GET[ $name ] ) ? $_GET[ $name ] : '';
|
46 |
|
47 |
// Remember for thurther calls
|
48 |
-
static::getInstance()->
|
49 |
|
50 |
return $value;
|
51 |
}
|
45 |
$value = isset( $_GET[ $name ] ) ? $_GET[ $name ] : '';
|
46 |
|
47 |
// Remember for thurther calls
|
48 |
+
static::getInstance()->remember_variable( $name, $value );
|
49 |
|
50 |
return $value;
|
51 |
}
|
@@ -46,7 +46,7 @@ class Post extends ServerVariables{
|
|
46 |
$value = isset( $_POST[ $name ] ) ? $_POST[ $name ] : '';
|
47 |
|
48 |
// Remember for thurther calls
|
49 |
-
static::getInstance()->
|
50 |
|
51 |
return $value;
|
52 |
}
|
46 |
$value = isset( $_POST[ $name ] ) ? $_POST[ $name ] : '';
|
47 |
|
48 |
// Remember for thurther calls
|
49 |
+
static::getInstance()->remember_variable( $name, $value );
|
50 |
|
51 |
return $value;
|
52 |
}
|
@@ -41,7 +41,7 @@ class Request extends ServerVariables{
|
|
41 |
$value = isset( $_REQUEST[ $name ] ) ? $_REQUEST[ $name ] : '';
|
42 |
|
43 |
// Remember for thurther calls
|
44 |
-
static::getInstance()->
|
45 |
|
46 |
return $value;
|
47 |
}
|
41 |
$value = isset( $_REQUEST[ $name ] ) ? $_REQUEST[ $name ] : '';
|
42 |
|
43 |
// Remember for thurther calls
|
44 |
+
static::getInstance()->remember_variable( $name, $value );
|
45 |
|
46 |
return $value;
|
47 |
}
|
@@ -6,78 +6,86 @@ namespace Cleantalk\Variables;
|
|
6 |
* Class Server
|
7 |
* Wrapper to safely get $_SERVER variables
|
8 |
*
|
9 |
-
* @
|
|
|
|
|
10 |
*/
|
11 |
-
class Server extends ServerVariables{
|
12 |
-
|
13 |
static $instance;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Constructor
|
17 |
-
* @return $this
|
18 |
-
*/
|
19 |
-
public static function getInstance(){
|
20 |
-
if (!isset(static::$instance)) {
|
21 |
-
static::$instance = new static;
|
22 |
-
static::$instance->init();
|
23 |
-
}
|
24 |
-
return static::$instance;
|
25 |
-
}
|
26 |
-
|
27 |
/**
|
28 |
-
* Gets given $_SERVER variable and
|
29 |
*
|
30 |
* @param string $name
|
31 |
*
|
32 |
* @return mixed|string
|
33 |
*/
|
34 |
protected function get_variable( $name ){
|
35 |
-
|
36 |
// Return from memory. From $this->server
|
37 |
if(isset(static::$instance->variables[$name]))
|
38 |
return static::$instance->variables[$name];
|
39 |
-
|
40 |
$name = strtoupper( $name );
|
41 |
-
|
42 |
if( function_exists( 'filter_input' ) )
|
43 |
$value = filter_input( INPUT_SERVER, $name );
|
44 |
-
|
45 |
if( empty( $value ) )
|
46 |
$value = isset( $_SERVER[ $name ] ) ? $_SERVER[ $name ] : '';
|
47 |
-
|
48 |
// Convert to upper case for REQUEST_METHOD
|
49 |
if( in_array( $name, array( 'REQUEST_METHOD' ) ) )
|
50 |
$value = strtoupper( $value );
|
51 |
-
|
52 |
// Convert HTML chars for HTTP_USER_AGENT, HTTP_USER_AGENT, SERVER_NAME
|
53 |
if( in_array( $name, array( 'HTTP_USER_AGENT', 'HTTP_USER_AGENT', 'SERVER_NAME' ) ) )
|
54 |
$value = htmlspecialchars( $value );
|
55 |
-
|
56 |
// Remember for thurther calls
|
57 |
-
static::getInstance()->
|
58 |
-
|
59 |
return $value;
|
60 |
}
|
61 |
-
|
62 |
/**
|
63 |
* Checks if $_SERVER['REQUEST_URI'] contains string
|
64 |
*
|
65 |
-
* @param string $
|
66 |
*
|
67 |
-
* @return bool
|
68 |
*/
|
69 |
-
public function in_uri( $
|
70 |
-
return self::has_string( 'REQUEST_URI', $
|
|
|
|
|
|
|
|
|
71 |
}
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
73 |
/**
|
74 |
* Checks if $_SERVER['REQUEST_URI'] contains string
|
75 |
*
|
76 |
-
* @param string $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
*
|
78 |
-
* @return bool
|
79 |
*/
|
80 |
-
public function
|
81 |
-
return self::
|
82 |
}
|
83 |
}
|
6 |
* Class Server
|
7 |
* Wrapper to safely get $_SERVER variables
|
8 |
*
|
9 |
+
* @usage \CleantalkSP\Variables\Server::get( $name );
|
10 |
+
*
|
11 |
+
* @package \CleantalkSP\Variables
|
12 |
*/
|
13 |
+
class Server extends ServerVariables {
|
14 |
+
|
15 |
static $instance;
|
16 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
/**
|
18 |
+
* Gets given $_SERVER variable and save it to memory
|
19 |
*
|
20 |
* @param string $name
|
21 |
*
|
22 |
* @return mixed|string
|
23 |
*/
|
24 |
protected function get_variable( $name ){
|
25 |
+
|
26 |
// Return from memory. From $this->server
|
27 |
if(isset(static::$instance->variables[$name]))
|
28 |
return static::$instance->variables[$name];
|
29 |
+
|
30 |
$name = strtoupper( $name );
|
31 |
+
|
32 |
if( function_exists( 'filter_input' ) )
|
33 |
$value = filter_input( INPUT_SERVER, $name );
|
34 |
+
|
35 |
if( empty( $value ) )
|
36 |
$value = isset( $_SERVER[ $name ] ) ? $_SERVER[ $name ] : '';
|
37 |
+
|
38 |
// Convert to upper case for REQUEST_METHOD
|
39 |
if( in_array( $name, array( 'REQUEST_METHOD' ) ) )
|
40 |
$value = strtoupper( $value );
|
41 |
+
|
42 |
// Convert HTML chars for HTTP_USER_AGENT, HTTP_USER_AGENT, SERVER_NAME
|
43 |
if( in_array( $name, array( 'HTTP_USER_AGENT', 'HTTP_USER_AGENT', 'SERVER_NAME' ) ) )
|
44 |
$value = htmlspecialchars( $value );
|
45 |
+
|
46 |
// Remember for thurther calls
|
47 |
+
static::getInstance()->remember_variable( $name, $value );
|
48 |
+
|
49 |
return $value;
|
50 |
}
|
51 |
+
|
52 |
/**
|
53 |
* Checks if $_SERVER['REQUEST_URI'] contains string
|
54 |
*
|
55 |
+
* @param string $needle
|
56 |
*
|
57 |
+
* @return bool
|
58 |
*/
|
59 |
+
public static function in_uri( $needle ){
|
60 |
+
return self::has_string( 'REQUEST_URI', $needle );
|
61 |
+
}
|
62 |
+
|
63 |
+
public static function in_host( $needle ){
|
64 |
+
return self::has_string( 'HTTP_HOST', $needle );
|
65 |
}
|
66 |
+
|
67 |
+
public static function get_domain(){
|
68 |
+
preg_match( '@\.(\S+)\/?$@', self::get( 'HTTP_HOST' ), $matches );
|
69 |
+
return isset( $matches[1] ) ? $matches[1] : false;
|
70 |
+
}
|
71 |
+
|
72 |
/**
|
73 |
* Checks if $_SERVER['REQUEST_URI'] contains string
|
74 |
*
|
75 |
+
* @param string $needle needle
|
76 |
+
*
|
77 |
+
* @return bool
|
78 |
+
*/
|
79 |
+
public static function in_referer( $needle ){
|
80 |
+
return self::has_string( 'HTTP_REFERER', $needle );
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Checks if $_SERVER['REQUEST_URI'] contains string
|
85 |
*
|
86 |
+
* @return bool
|
87 |
*/
|
88 |
+
public static function is_post(){
|
89 |
+
return self::get( 'REQUEST_METHOD' ) === 'POST';
|
90 |
}
|
91 |
}
|
@@ -1,85 +1,77 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Cleantalk\Variables;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Class ServerVariables
|
7 |
-
* Safety handler for ${_SOMETHING}
|
8 |
-
*
|
9 |
-
* @usage \Cleantalk\Variables\{SOMETHING}::get( $name );
|
10 |
-
*
|
11 |
-
* @package Cleantalk\Variables
|
12 |
-
*/
|
13 |
-
class ServerVariables{
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
public
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
*
|
25 |
-
* @
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
*
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
*
|
46 |
-
*
|
47 |
-
* @
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
*
|
56 |
-
*
|
57 |
-
*
|
58 |
-
* @
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
*
|
68 |
-
*
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
* @param string $var Haystack to search in
|
78 |
-
* @param string $string Needle to search
|
79 |
-
*
|
80 |
-
* @return bool|int
|
81 |
-
*/
|
82 |
-
static function has_string( $var, $string ){
|
83 |
-
return stripos( self::get( $var ), $string ) !== false;
|
84 |
-
}
|
85 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Cleantalk\Variables;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class ServerVariables
|
7 |
+
* Safety handler for ${_SOMETHING}
|
8 |
+
*
|
9 |
+
* @usage \Cleantalk\Variables\{SOMETHING}::get( $name );
|
10 |
+
*
|
11 |
+
* @package Cleantalk\Variables
|
12 |
+
*/
|
13 |
+
class ServerVariables{
|
14 |
+
|
15 |
+
use \Cleantalk\Templates\Singleton;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var array Contains saved variables
|
19 |
+
*/
|
20 |
+
public $variables = [];
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Gets variable from ${_SOMETHING}
|
24 |
+
*
|
25 |
+
* @param string $name Variable name
|
26 |
+
*
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
public static function get( $name ){
|
30 |
+
return static::getInstance()->get_variable( $name );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* BLUEPRINT
|
35 |
+
* Gets given ${_SOMETHING} variable and seva it to memory
|
36 |
+
* @param $name
|
37 |
+
*
|
38 |
+
* @return mixed|string
|
39 |
+
*/
|
40 |
+
protected function get_variable( $name ){
|
41 |
+
return true;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Save variable to $this->variables[]
|
46 |
+
*
|
47 |
+
* @param string $name
|
48 |
+
* @param string $value
|
49 |
+
*/
|
50 |
+
protected function remember_variable( $name, $value ){
|
51 |
+
static::$instance->variables[$name] = $value;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Checks if variable contains given string
|
56 |
+
*
|
57 |
+
* @param string $var Haystack to search in
|
58 |
+
* @param string $string Needle to search
|
59 |
+
*
|
60 |
+
* @return bool|int
|
61 |
+
*/
|
62 |
+
static function has_string( $var, $string ){
|
63 |
+
return stripos( self::get( $var ), $string ) !== false;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Checks if variable equal to $param
|
68 |
+
*
|
69 |
+
* @param string $var Variable to compare
|
70 |
+
* @param string $param Param to compare
|
71 |
+
*
|
72 |
+
* @return bool|int
|
73 |
+
*/
|
74 |
+
static function equal( $var, $param ){
|
75 |
+
return self::get( $var ) == $param;
|
76 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
@@ -4,7 +4,7 @@ Tags: spam, antispam, anti-spam, comments, firewall
|
|
4 |
Requires at least: 3.0
|
5 |
Tested up to: 5.6
|
6 |
Requires PHP: 5.4
|
7 |
-
Stable tag: 5.
|
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,35 @@ If your website has forms that send data to external sources, you can enable opt
|
|
580 |
|
581 |
== Changelog ==
|
582 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
583 |
= 5.151.4 Jan 18 2020 =
|
584 |
* Fix: Users checking performance fix.
|
585 |
* Fix: AC disabled if SFW contains less than 50 entries.
|
4 |
Requires at least: 3.0
|
5 |
Tested up to: 5.6
|
6 |
Requires PHP: 5.4
|
7 |
+
Stable tag: 5.152
|
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.152 Jan 29 2020 =
|
584 |
+
* Fix: Using server protocol for AC checking.
|
585 |
+
* Fix: Prevent caching db queries for SFW.
|
586 |
+
* Fix: mgm registration temp fix.
|
587 |
+
* Upd: Checking skipped request replaced.
|
588 |
+
* Fix: Bookly plugin service requests checking skipped.
|
589 |
+
* Fix: Youzier login form skipped.
|
590 |
+
* Fix: InJob theme lost password skipped.
|
591 |
+
* Upd: Showing plugin version on SFW block page.
|
592 |
+
* Fix: fix request id rotation.
|
593 |
+
* Mod: Show "Insert users" button only for local web servers.
|
594 |
+
* Upd: Checking skipped request replaced for non-ajax requests.
|
595 |
+
* Fix: BuddyPress edit profile checking skippped.
|
596 |
+
* Fix: Unused code removed.
|
597 |
+
* Upd: Helper::ip__get() method updated.
|
598 |
+
* Fix: UltimateMember password reset skipped.
|
599 |
+
* Del: Unused code removed.
|
600 |
+
* New: Server::get() now can accept 'URI' as an parameter. Returns full URI like 'http://domain.net/request/path?parameter=value#fragment
|
601 |
+
* Mod: apbct_exclusions_check__url__reversed() simplifed and PHPDoc'ed.
|
602 |
+
* Mod: apbct_base_call exclusions revised.
|
603 |
+
* Mod: $cleantalk_executed chaos simplified.
|
604 |
+
* Upd: Shedule sfw update once again if it failed.
|
605 |
+
* Fix: Delete cleantalk options via uninstalling.
|
606 |
+
* Fix: Deleting table for network sites fixed.
|
607 |
+
* Fix: Using host header for AC checking.
|
608 |
+
* Fix: Expression formatting fixed.
|
609 |
+
* Mod: Cron. Do not runs when it already runs.
|
610 |
+
* Mod: Cron class updated.
|
611 |
+
|
612 |
= 5.151.4 Jan 18 2020 =
|
613 |
* Fix: Users checking performance fix.
|
614 |
* Fix: AC disabled if SFW contains less than 50 entries.
|