Spam protection, AntiSpam, FireWall by CleanTalk - Version 5.152

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.

Download this release

Release Info

Developer glomberg
Plugin Icon 128x128 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 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.151.4
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
- // Self cron
133
- if( ! apbct_is_remote_call() && // Do not doing CRON in remote call action
134
- ! defined('DOING_CRON') ||
135
- (defined('DOING_CRON') && DOING_CRON !== true)
 
 
 
 
 
136
  ){
137
-
138
- $ct_cron = new Cron();
139
- $ct_cron->checkTasks();
140
-
141
- if(!empty($ct_cron->tasks_to_run)){
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->prefix.'cleantalk_sfw_temp`;'); // Deleting temporary SFW data
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
 
inc/cleantalk-ajax.php CHANGED
@@ -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',
inc/cleantalk-common.php CHANGED
@@ -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( ! $cleantalk_executed && apbct_exclusions_check() ){
 
 
 
 
 
 
92
  do_action( 'apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST );
93
  return array( 'ct_result' => new CleantalkResponse() );
94
  }
 
 
 
 
 
 
 
 
 
95
  $cleantalk_executed = true;
96
 
97
- // Request id rotation
98
- $plugin_request_id__lifetime = 2;
99
- $tmp = array();
100
- foreach( $apbct->plugin_request_ids as $request_id => $request_time ){
101
- if( time() - $request_time < $plugin_request_id__lifetime )
102
- $tmp[ $request_id ] = $request_time;
 
 
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, $cleantalk_executed;
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' ) && ! \Cleantalk\Variables\Server::has_string( 'REQUEST_URI', APBCT_URL_EXCLUSIONS__REVERSED )
278
- ? false
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
  /**
inc/cleantalk-pluggable.php CHANGED
@@ -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
+ }
inc/cleantalk-public.php CHANGED
@@ -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'];
inc/cleantalk-settings.php CHANGED
@@ -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'] ) )
lib/Cleantalk/ApbctWP/Cron.php CHANGED
@@ -2,152 +2,283 @@
2
 
3
  namespace Cleantalk\ApbctWP;
4
 
5
- /*
6
- * CleanTalk cron class
7
- * Version 1.0
8
- */
 
 
 
 
 
 
 
9
 
10
  class Cron
11
  {
12
- public $tasks = array(); // Array with tasks
13
- public $tasks_to_run = array(); // Array with tasks which should be run now
14
- public $tasks_completed = array(); // Result of executed tasks
15
-
16
- // Currently selected task
17
- private $task;
18
- private $handler;
19
- private $period;
20
- private $next_call;
21
-
22
- // Option name with cron data
23
- const CRON_OPTION_NAME = 'cleantalk_cron';
24
-
25
- // Getting tasks option
26
- public function __construct()
27
- {
28
- $tasks = get_option(self::CRON_OPTION_NAME);
29
- $this->tasks = empty($tasks) ? array() : $tasks;
30
- }
31
-
32
- // Adding new cron task
33
- static public function addTask($task, $handler, $period, $first_call = null, $update = false)
34
- {
35
- // First call time() + preiod
36
- $first_call = !$first_call ? time()+$period : $first_call;
37
-
38
- $tasks = get_option(self::CRON_OPTION_NAME);
39
- $tasks = empty($tasks) ? array() : $tasks;
40
-
41
- if(isset($tasks[$task]) && !$update)
42
- return false;
43
-
44
- // Task entry
45
- $tasks[$task] = array(
46
- 'handler' => $handler,
47
- 'next_call' => $first_call,
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
- * Getting list of tasks
80
  *
81
- * @return array
 
 
 
 
 
 
82
  */
83
- public function getTasks()
84
  {
85
- return $this->tasks;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
  }
lib/Cleantalk/ApbctWP/FindSpam/ListTable/UsersScan.php CHANGED
@@ -1,65 +1,67 @@
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
  }
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
  }
lib/Cleantalk/ApbctWP/Firewall/AntiCrawler.php CHANGED
@@ -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 $ua; //User-Agent
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->ua = md5( Server::get('HTTP_USER_AGENT') );
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->ua';"
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->ua . $interval_time );
271
  $this->db->execute(
272
  "INSERT INTO " . $this->db__table__ac_logs . " SET
273
  id = '$id',
274
  ip = '$current_ip',
275
- ua = '$this->ua',
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&nbsp;' . 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&nbsp;' . date( 'D, d M Y H:i:s' ) . "</p>",
lib/Cleantalk/ApbctWP/Firewall/AntiFlood.php CHANGED
@@ -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&nbsp;' . 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&nbsp;' . date( 'D, d M Y H:i:s' ) . "</p>",
191
  '{COOKIE_ANTIFLOOD_PASSED}' => md5( $this->api_key . $result['ip'] ),
192
  );
lib/Cleantalk/ApbctWP/Firewall/SFW.php CHANGED
@@ -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 ORDER BY status DESC");
 
 
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&nbsp;' . 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&nbsp;' . date( 'D, d M Y H:i:s' ) . "</p>",
247
  '{REQUEST_URI}' => Server::get( 'REQUEST_URI' ),
248
 
lib/Cleantalk/Common/Helper.php CHANGED
@@ -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.4
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
- * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
66
- *
67
- * @param array $ip_types Type of IP you want to receive
68
- * @param bool $v4_only
69
- *
70
- * @return array|mixed|null
71
- */
72
- static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare'), $v4_only = true)
73
- {
74
- $ips = array_flip($ip_types); // Result array with IPs
75
- $headers = apache_request_headers();
76
-
77
- // REMOTE_ADDR
78
- if(isset($ips['remote_addr'])){
79
- $ip_type = self::ip__validate( isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '' );
80
- if($ip_type){
81
- $ips['remote_addr'] = ($ip_type == 'v6' ? self::ip__v6_normalize(isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '' ) : isset( $_SERVER['REMOTE_ADDR'] )) ? $_SERVER['REMOTE_ADDR'] : '';
82
- }
83
- }
84
-
85
- // X-Forwarded-For
86
- if(isset($ips['x_forwarded_for'])){
87
- if(isset($headers['X-Forwarded-For'])){
88
- $tmp = explode(",", trim($headers['X-Forwarded-For']));
89
- $tmp = trim($tmp[0]);
90
- $ip_type = self::ip__validate($tmp);
91
- if($ip_type){
92
- $ips['x_forwarded_for'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
93
- }
94
- }
95
- }
96
-
97
- // X-Real-Ip
98
- if(isset($ips['x_real_ip'])){
99
- if(isset($headers['X-Real-Ip'])){
100
- $tmp = explode(",", trim($headers['X-Real-Ip']));
101
- $tmp = trim($tmp[0]);
102
- $ip_type = self::ip__validate($tmp);
103
- if($ip_type){
104
- $ips['x_forwarded_for'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
105
- }
106
- }
107
- }
108
-
109
- // Cloud Flare
110
- if(isset($ips['cloud_flare'])){
111
- if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){
112
- $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip'];
113
- $tmp = strpos($tmp, ',') !== false ? explode(',', $tmp) : (array)$tmp;
114
- $ip_type = self::ip__validate(trim($tmp[0]));
115
- if($ip_type){
116
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize(trim($tmp[0])) : trim($tmp[0]);
117
- }
118
- }
119
- }
120
-
121
- // 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.
122
- if(isset($ips['real'])){
123
-
124
- // Detect IP type
125
- $ip_type = self::ip__validate(isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '');
126
- if($ip_type)
127
- $ips['real'] = ($ip_type == 'v6' ? self::ip__v6_normalize(isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '' ) : isset( $_SERVER['REMOTE_ADDR'] )) ? $_SERVER['REMOTE_ADDR'] : '';
128
-
129
- // Cloud Flare
130
- if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){
131
- $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip'];
132
- $tmp = strpos($tmp, ',') !== false ? explode(',', $tmp) : (array)$tmp;
133
- $ip_type = self::ip__validate(trim($tmp[0]));
134
- if($ip_type)
135
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize(trim($tmp[0])) : trim($tmp[0]);
136
-
137
- // Sucury
138
- }elseif(isset($headers['X-Sucuri-Clientip'], $headers['X-Sucuri-Country'])){
139
- $ip_type = self::ip__validate($headers['X-Sucuri-Clientip']);
140
- if($ip_type)
141
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['X-Sucuri-Clientip']) : $headers['X-Sucuri-Clientip'];
142
-
143
- // OVH
144
- }elseif(isset($headers['X-Cdn-Any-Ip'], $headers['Remote-Ip'])){
145
- $ip_type = self::ip__validate($headers['Remote-Ip']);
146
- if($ip_type)
147
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['Remote-Ip']) : $headers['Remote-Ip'];
148
-
149
- // Incapsula proxy
150
- }elseif(isset($headers['Incap-Client-Ip'])){
151
- $ip_type = self::ip__validate($headers['Incap-Client-Ip']);
152
- if($ip_type)
153
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['Incap-Client-Ip']) : $headers['Incap-Client-Ip'];
154
- }
155
-
156
- // Is private network
157
- if($ip_type === false ||
158
- ($ip_type &&
159
- (self::ip__is_private_network($ips['real'], $ip_type) ||
160
- self::ip__mask_match(
161
- $ips['real'],
162
- (isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] . '/24' : '127.0.0.1/24'),
163
- $ip_type
164
- )
165
- )
166
- )
167
- ){
168
-
169
- // X-Forwarded-For
170
- if(isset($headers['X-Forwarded-For'])){
171
- $tmp = explode(',', trim($headers['X-Forwarded-For']));
172
- $tmp = trim($tmp[0]);
173
- $ip_type = self::ip__validate($tmp);
174
- if($ip_type)
175
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
176
-
177
- // X-Real-Ip
178
- }elseif(isset($headers['X-Real-Ip'])){
179
- $tmp = explode(',', trim($headers['X-Real-Ip']));
180
- $tmp = trim($tmp[0]);
181
- $ip_type = self::ip__validate($tmp);
182
- if($ip_type)
183
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
184
- }
185
- }
186
- }
187
-
188
- // Validating IPs
189
- $result = array();
190
- foreach($ips as $key => $ip){
191
- $ip_version = self::ip__validate($ip);
192
- if($ip && (($v4_only && $ip_version == 'v4') || !$v4_only)){
193
- $result[$key] = $ip;
194
- }
195
- }
196
-
197
- $result = array_unique($result);
198
- return count($result) > 1
199
- ? $result
200
- : (reset($result) !== false
201
- ? reset($result)
202
- : null);
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
  }
lib/Cleantalk/Common/Schema.php CHANGED
@@ -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;
lib/Cleantalk/Templates/Singleton.php CHANGED
@@ -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
- private function init(){
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
+ }
lib/Cleantalk/Variables/Cookie.php CHANGED
@@ -45,7 +45,7 @@ class Cookie extends ServerVariables{
45
  $value = isset( $_COOKIE[ $name ] ) ? $_COOKIE[ $name ] : '';
46
 
47
  // Remember for thurther calls
48
- static::getInstance()->remebmer_variable( $name, $value );
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
  }
lib/Cleantalk/Variables/Get.php CHANGED
@@ -45,7 +45,7 @@ class Get extends ServerVariables{
45
  $value = isset( $_GET[ $name ] ) ? $_GET[ $name ] : '';
46
 
47
  // Remember for thurther calls
48
- static::getInstance()->remebmer_variable( $name, $value );
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
  }
lib/Cleantalk/Variables/Post.php CHANGED
@@ -46,7 +46,7 @@ class Post extends ServerVariables{
46
  $value = isset( $_POST[ $name ] ) ? $_POST[ $name ] : '';
47
 
48
  // Remember for thurther calls
49
- static::getInstance()->remebmer_variable( $name, $value );
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
  }
lib/Cleantalk/Variables/Request.php CHANGED
@@ -41,7 +41,7 @@ class Request extends ServerVariables{
41
  $value = isset( $_REQUEST[ $name ] ) ? $_REQUEST[ $name ] : '';
42
 
43
  // Remember for thurther calls
44
- static::getInstance()->remebmer_variable( $name, $value );
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
  }
lib/Cleantalk/Variables/Server.php CHANGED
@@ -6,78 +6,86 @@ namespace Cleantalk\Variables;
6
  * Class Server
7
  * Wrapper to safely get $_SERVER variables
8
  *
9
- * @package Cleantalk\Variables
 
 
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 seva it to memory
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()->remebmer_variable( $name, $value );
58
-
59
  return $value;
60
  }
61
-
62
  /**
63
  * Checks if $_SERVER['REQUEST_URI'] contains string
64
  *
65
- * @param string $string needle
66
  *
67
- * @return bool|int
68
  */
69
- public function in_uri( $string ){
70
- return self::has_string( 'REQUEST_URI', $string );
 
 
 
 
71
  }
72
-
 
 
 
 
 
73
  /**
74
  * Checks if $_SERVER['REQUEST_URI'] contains string
75
  *
76
- * @param string $string needle
 
 
 
 
 
 
 
 
 
77
  *
78
- * @return bool|int
79
  */
80
- public function in_referer( $string ){
81
- return self::has_string( 'HTTP_REFERER', $string );
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
  }
lib/Cleantalk/Variables/ServerVariables.php CHANGED
@@ -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
- static $instance;
16
-
17
- public $variables = array();
18
-
19
- public function __construct(){}
20
- public function __wakeup(){}
21
- public function __clone(){}
22
-
23
- /**
24
- * Constructor
25
- * @return $this
26
- */
27
- public static function getInstance(){
28
- if (!isset(static::$instance)) {
29
- static::$instance = new static;
30
- static::$instance->init();
31
- }
32
- return static::$instance;
33
- }
34
-
35
- /**
36
- * Alternative constructor
37
- */
38
- protected function init(){
39
-
40
- }
41
-
42
- /**
43
- * Gets variable from ${_SOMETHING}
44
- *
45
- * @param $name
46
- *
47
- * @return string ${_SOMETHING}[ $name ]
48
- */
49
- public static function get( $name ){
50
- return static::getInstance()->get_variable( $name );
51
- }
52
-
53
- /**
54
- * BLUEPRINT
55
- * Gets given ${_SOMETHING} variable and seva it to memory
56
- * @param $name
57
- *
58
- * @return mixed|string
59
- */
60
- protected function get_variable( $name ){
61
- return true;
62
- }
63
-
64
- /**
65
- * Save variable to $this->variables[]
66
- *
67
- * @param string $name
68
- * @param string $value
69
- */
70
- protected function remebmer_variable( $name, $value ){
71
- static::$instance->variables[$name] = $value;
72
- }
73
-
74
- /**
75
- * Checks if variable contains given string
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
  }
readme.txt CHANGED
@@ -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.151.4
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.