Spam protection, AntiSpam, FireWall by CleanTalk - Version 5.124

Version Description

August 8 2019 = * Spam protection improved. * Fix: SpamFireWall local database counter on Multisite. * Fix: Caldera Forms integration. * Fix: Settings "Use AJAX for JS check" description. * Fix: Formidable integration. * New: External forms check now independed from JavaScript. * New: Setting Protect external - capture buffer. * New: QuForm integration.

Download this release

Release Info

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

Code changes from version 5.123 to 5.124

cleantalk.php CHANGED
@@ -3,12 +3,12 @@
3
  Plugin Name: Anti-Spam by CleanTalk
4
  Plugin URI: http://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.123
7
  Author: СleanTalk <welcome@cleantalk.org>
8
  Author URI: http://cleantalk.org
9
  Text Domain: cleantalk
10
  Domain Path: /i18n
11
- */+
12
 
13
  $cleantalk_executed = false;
14
 
@@ -21,11 +21,11 @@ define('APBCT_VERSION', $plugin_info['Version']);
21
  define('APBCT_URL_PATH', plugins_url('', __FILE__)); //HTTP path. Plugin root folder without '/'.
22
  define('APBCT_DIR_PATH', plugin_dir_path(__FILE__)); //System path. Plugin root folder with '/'.
23
  define('APBCT_PLUGIN_BASE_NAME', plugin_basename(__FILE__)); //Plugin base name.
24
- define('APBCT_CASERT_PATH', file_exists(ABSPATH.WPINC.'/certificates/ca-bundle.crt') ? ABSPATH.WPINC.'/certificates/ca-bundle.crt' : ''); // SSL Serttificate path
 
25
  // API params
26
- define('CLEANTALK_AGENT', 'wordpress-'.str_replace('.', '', $plugin_info['Version']));
27
- define('CLEANTALK_API_URL', 'https://api.cleantalk.org'); //Api URL
28
- define('CLEANTALK_MODERATE_URL', 'http://moderate.cleantalk.org'); //Api URL
29
 
30
  // Option names
31
  define('APBCT_DATA', 'cleantalk_data'); //Option name with different plugin data.
@@ -45,22 +45,32 @@ define('APBCT_REMOTE_CALL_SLEEP', 5); // Minimum time between remote call
45
 
46
  if(!defined('CLEANTALK_PLUGIN_DIR')){
47
 
48
- define('CLEANTALK_PLUGIN_DIR', plugin_dir_path(__FILE__));
49
-
50
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkDB_Wordpress.php'); // Database class
51
-
52
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/cleantalk-php-patch.php'); // Pathces fpr different functions which not exists
53
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkHelper.php'); // Helper class. Different useful functions
54
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkAPI_base.php'); // API.
55
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkAPI.php'); // API extension for Wordpress
56
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/Cleantalk.php'); // Main class for request
57
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkRequest.php'); // Holds request data
58
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkResponse.php'); // Holds response data
59
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkCron.php'); // Cron handling
60
- require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkState.php'); // State class
 
 
 
 
 
 
 
 
 
 
61
  // require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkIntegration.php'); // Integrations
62
- require_once( CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-pluggable.php'); // Pluggable functions
63
- require_once( CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-common.php');
64
 
65
  // Global ArrayObject with settings and other global varables
66
  global $apbct;
@@ -88,14 +98,12 @@ if(!defined('CLEANTALK_PLUGIN_DIR')){
88
  if(!$apbct->white_label){
89
  require_once( CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-widget.php');
90
  $apbct->settings['apikey'] = defined('CLEANTALK_ACCESS_KEY') ? CLEANTALK_ACCESS_KEY : $apbct->settings['apikey'];
91
-
92
  }
93
 
94
  // Passing JS key to frontend
95
  add_action('wp_ajax_apbct_js_keys__get', 'apbct_js_keys__get__ajax');
96
  add_action('wp_ajax_nopriv_apbct_js_keys__get', 'apbct_js_keys__get__ajax');
97
 
98
-
99
  // Database prefix
100
  global $wpdb;
101
  $apbct->db_prefix = !$apbct->white_label && defined('CLEANTALK_ACCESS_KEY') ? $wpdb->base_prefix : $wpdb->prefix;
@@ -277,6 +285,10 @@ if(!defined('CLEANTALK_PLUGIN_DIR')){
277
  add_filter('et_pre_insert_question', 'ct_ajax_hook', 1, 1); // Questions
278
  add_filter('et_pre_insert_answer', 'ct_ajax_hook', 1, 1); // Answers
279
 
 
 
 
 
280
  // Some of plugins to register a users use AJAX context.
281
  add_filter('registration_errors', 'ct_registration_errors', 1, 3);
282
  add_filter('registration_errors', 'ct_check_registration_erros', 999999, 3);
@@ -408,15 +420,14 @@ function apbct_remote_call__perform()
408
  */
409
  if(is_string($result) && strpos($result, 'FAIL') !== false){
410
  $result = json_decode(substr($result, 5), true);
411
- $result['error_string'] = $result['error'];
412
  }
413
- die(empty($result['error']) ? 'OK' : 'FAIL '.json_encode(array('error' => $result['error_string'])));
414
  break;
415
 
416
  // SFW send logs
417
  case 'sfw_send_logs':
418
  $result = ct_sfw_send_logs();
419
- die(empty($result['error']) ? 'OK' : 'FAIL '.json_encode(array('error' => $result['error_string'])));
420
  break;
421
 
422
  // Update plugin
@@ -426,23 +437,41 @@ function apbct_remote_call__perform()
426
 
427
  // Install plugin
428
  case 'install_plugin':
429
- add_action('wp', 'apbct_install_plugin', 1);
430
  break;
431
-
432
- // Uninstall plugin
433
- case 'uninstall_plugin':
434
- add_action('plugins_loaded', 'apbct_uninstall_plugin', 1);
 
 
435
  break;
436
-
437
- // Update settins
 
 
 
 
 
 
 
 
438
  case 'update_settings':
439
  $result = apbct_rc__update_settings($_GET);
440
- die(empty($result['error'])
441
  ? 'OK'
442
- : 'FAIL '.json_encode(array('error' => $result['error_string'])));
 
 
 
 
443
  break;
444
 
445
- // No action found
 
 
 
 
446
  default:
447
  die('FAIL '.json_encode(array('error' => 'UNKNOWN_ACTION_2')));
448
  break;
@@ -477,9 +506,6 @@ function apbct_sfw__check()
477
  if($apbct->rc_running || (!empty($spbc) && $spbc->rc_running))
478
  return;
479
 
480
- include_once(CLEANTALK_PLUGIN_DIR . "lib/CleantalkSFW_Base.php");
481
- include_once(CLEANTALK_PLUGIN_DIR . "lib/CleantalkSFW.php");
482
-
483
  $is_sfw_check = true;
484
  $sfw = new CleantalkSFW();
485
  $sfw->ip_array = (array)$sfw->ip__get(array('real'), true);
@@ -775,9 +801,6 @@ function ct_sfw_update($immediate = false){
775
 
776
  if($apbct->settings['spam_firewall'] == 1){
777
 
778
- include_once(CLEANTALK_PLUGIN_DIR . "lib/CleantalkSFW_Base.php");
779
- include_once(CLEANTALK_PLUGIN_DIR . "lib/CleantalkSFW.php");
780
-
781
  $sfw = new CleantalkSFW();
782
 
783
  $file_url = isset($_GET['file_url']) ? $_GET['file_url'] : null;
@@ -792,7 +815,7 @@ function ct_sfw_update($immediate = false){
792
  return $result;
793
  }
794
 
795
- return array('error' => true, 'error_string' => 'SFW_DISABLED');
796
 
797
  }
798
 
@@ -801,9 +824,6 @@ function ct_sfw_send_logs()
801
  global $apbct;
802
 
803
  if($apbct->settings['spam_firewall'] == 1){
804
-
805
- include_once(CLEANTALK_PLUGIN_DIR . "lib/CleantalkSFW_Base.php");
806
- include_once(CLEANTALK_PLUGIN_DIR . "lib/CleantalkSFW.php");
807
 
808
  $sfw = new CleantalkSFW();
809
  $result = $sfw->logs__send($apbct->api_key);
@@ -818,83 +838,177 @@ function ct_sfw_send_logs()
818
 
819
  }
820
 
821
- return array('error' => true, 'error_string' => 'SFW_DISABLED');
822
  }
823
 
824
  /**
825
  * Install plugin from wordpress catalog
826
  *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
827
  * @param null $plugin_name
828
  */
829
- function apbct_install_plugin($plugin_name = null){
830
 
831
  global $apbct;
832
 
833
- $plugin_name = $plugin_name ? $plugin_name : (isset($_GET['plugin_name']) ? $_GET['plugin_name'] : null);
834
-
835
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
836
- include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
837
- include_once( ABSPATH . 'wp-admin/includes/file.php' );
838
- include_once( ABSPATH . 'wp-admin/includes/misc.php' );
839
- include_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkUpgrader.php' );
840
- include_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkUpgraderSkin.php' );
841
 
842
- if($plugin_name){
843
- $installer= new CleantalkUpgrader( new CleantalkUpgraderSkin() );
844
- $installer->install($plugin_name);
 
 
 
 
 
845
 
846
- if($installer->apbct_result === 'OK'){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
847
  die('OK');
848
  }else
849
- die('FAIL '. json_encode(array('error' => $installer->apbct_result)));
850
-
851
  }else
852
  die('FAIL '. json_encode(array('error' => 'PLUGIN_NAME_IS_UNSET')));
853
  }
854
 
 
855
  /**
856
- * Install plugin from wordpress catalog
857
  *
858
- * @param null $plugin_name
859
  */
860
- function apbct_uninstall_plugin($plugin_name = null){
861
 
862
  global $apbct;
863
 
864
- $plugin_name = $plugin_name ? $plugin_name : (isset($_GET['plugin_name']) ? $_GET['plugin_name'] : null);
865
 
866
- if($plugin_name){
867
 
868
- // Hook to set flag if the plugin is deactivated
869
- add_action( 'deactivate_'.$plugin_name, 'apbct_uninstall_plugin__check_deactivate' );
870
- deactivate_plugins($plugin_name, false, is_multisite() ? true : false);
 
 
 
 
 
 
 
 
 
 
 
 
 
871
 
872
  if($apbct->plugin_deactivated){
873
 
874
- // Hook to set flag if the plugin is uninstalled
875
- add_action( 'uninstall_'.$plugin_name, 'apbct_uninstall_plugin__check_uninstall' );
876
- uninstall_plugin($plugin_name);
877
 
878
- if($apbct->plugin_uninstalled){
 
 
879
  die('OK');
880
  }else
881
- die('FAIL '. json_encode(array('error' => 'PLUGIN_STILL_EXISTS')));
882
  }else
883
  die('FAIL '. json_encode(array('error' => 'PLUGIN_STILL_ACTIVE')));
884
  }else
885
  die('FAIL '. json_encode(array('error' => 'PLUGIN_NAME_IS_UNSET')));
886
  }
887
 
888
- function apbct_uninstall_plugin__check_deactivate(){
889
  global $apbct;
890
  $apbct->plugin_deactivated = true;
891
  }
892
- function apbct_uninstall_plugin__check_uninstall(){
893
- global $apbct;
894
- $apbct->plugin_uninstalled = true;
895
- }
896
 
897
- function apbct_update(){
898
 
899
  //Upgrade params
900
  $plugin = 'cleantalk-spam-protect/cleantalk.php';
@@ -978,6 +1092,62 @@ function apbct_rc__update_settings($source) {
978
  return true;
979
  }
980
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
981
  function cleantalk_get_brief_data(){
982
 
983
  global $apbct;
@@ -1270,8 +1440,10 @@ function ct_account_status_check($api_key = null, $process_errors = true){
1270
  global $apbct;
1271
 
1272
  $api_key = $api_key ? $api_key : $apbct->api_key;
1273
-
1274
- $result = CleantalkAPI::method__notice_paid_till($api_key, preg_replace('/http[s]?:\/\//', '', get_option('siteurl'), 1));
 
 
1275
 
1276
  if(empty($result['error']) || (isset($result['error_no']) && $result['error_no'] == 12)){
1277
 
@@ -1475,8 +1647,8 @@ function apbct_statistics__rotate($exec_time){
1475
 
1476
  /**
1477
  * Runs update actions for new version.
1478
- *
1479
- * @global type $apbct
1480
  */
1481
  function apbct_update_actions(){
1482
 
@@ -1496,7 +1668,7 @@ function apbct_update_actions(){
1496
  $apbct->data['plugin_version'] = APBCT_VERSION;
1497
  $apbct->saveData();
1498
  }
1499
- ct_send_feedback('0:' . CLEANTALK_AGENT ); // Send feedback to let cloud know about updated version.
1500
 
1501
  // Side blogs
1502
  }else{
3
  Plugin Name: Anti-Spam by CleanTalk
4
  Plugin URI: http://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.124
7
  Author: СleanTalk <welcome@cleantalk.org>
8
  Author URI: http://cleantalk.org
9
  Text Domain: cleantalk
10
  Domain Path: /i18n
11
+ */
12
 
13
  $cleantalk_executed = false;
14
 
21
  define('APBCT_URL_PATH', plugins_url('', __FILE__)); //HTTP path. Plugin root folder without '/'.
22
  define('APBCT_DIR_PATH', plugin_dir_path(__FILE__)); //System path. Plugin root folder with '/'.
23
  define('APBCT_PLUGIN_BASE_NAME', plugin_basename(__FILE__)); //Plugin base name.
24
+ define('APBCT_CASERT_PATH', file_exists(ABSPATH . WPINC . '/certificates/ca-bundle.crt') ? ABSPATH . WPINC . '/certificates/ca-bundle.crt' : ''); // SSL Serttificate path
25
+
26
  // API params
27
+ define('APBCT_AGENT', 'wordpress-'.str_replace('.', '', $plugin_info['Version']));
28
+ define('APBCT_MODERATE_URL', 'http://moderate.cleantalk.org'); //Api URL
 
29
 
30
  // Option names
31
  define('APBCT_DATA', 'cleantalk_data'); //Option name with different plugin data.
45
 
46
  if(!defined('CLEANTALK_PLUGIN_DIR')){
47
 
48
+ define('CLEANTALK_PLUGIN_DIR', dirname(__FILE__ ) . '/');
49
+
50
+ // PHP functions patches
51
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/cleantalk-php-patch.php'); // Pathces fpr different functions which not exists
52
+
53
+ // Base classes
54
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkBase/CleantalkAPI.php'); // Helper
55
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkBase/CleantalkDB.php'); // Database driver
56
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkBase/CleantalkHelper.php'); // Helper
57
+ include_once(CLEANTALK_PLUGIN_DIR . "lib/CleantalkBase/CleantalkSFW.php"); // SpamFireWall
58
+
59
+ // Child classes
60
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkAPI.php'); // API for Wordpress
61
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkDB.php'); // Database class for Wordpress
62
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkHelper.php'); // Helper for Worpdress
63
+ include_once(CLEANTALK_PLUGIN_DIR . "lib/CleantalkSFW.php"); // SpamFireWall for Wordpress
64
+
65
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/Cleantalk.php'); // Main class for request
66
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkRequest.php'); // Holds request data
67
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkResponse.php'); // Holds response data
68
+
69
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkCron.php'); // Cron handling
70
+ require_once(CLEANTALK_PLUGIN_DIR . 'lib/CleantalkState.php'); // State class
71
  // require_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkIntegration.php'); // Integrations
72
+ require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-pluggable.php'); // Pluggable functions
73
+ require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-common.php');
74
 
75
  // Global ArrayObject with settings and other global varables
76
  global $apbct;
98
  if(!$apbct->white_label){
99
  require_once( CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-widget.php');
100
  $apbct->settings['apikey'] = defined('CLEANTALK_ACCESS_KEY') ? CLEANTALK_ACCESS_KEY : $apbct->settings['apikey'];
 
101
  }
102
 
103
  // Passing JS key to frontend
104
  add_action('wp_ajax_apbct_js_keys__get', 'apbct_js_keys__get__ajax');
105
  add_action('wp_ajax_nopriv_apbct_js_keys__get', 'apbct_js_keys__get__ajax');
106
 
 
107
  // Database prefix
108
  global $wpdb;
109
  $apbct->db_prefix = !$apbct->white_label && defined('CLEANTALK_ACCESS_KEY') ? $wpdb->base_prefix : $wpdb->prefix;
285
  add_filter('et_pre_insert_question', 'ct_ajax_hook', 1, 1); // Questions
286
  add_filter('et_pre_insert_answer', 'ct_ajax_hook', 1, 1); // Answers
287
 
288
+ // Formidable
289
+ add_filter( 'frm_entries_before_create', 'ct_frm_validate_entry', 10, 2 );
290
+ add_action( 'frm_entries_footer_scripts', 'ct_frm_entries_footer_scripts', 20, 2 );
291
+
292
  // Some of plugins to register a users use AJAX context.
293
  add_filter('registration_errors', 'ct_registration_errors', 1, 3);
294
  add_filter('registration_errors', 'ct_check_registration_erros', 999999, 3);
420
  */
421
  if(is_string($result) && strpos($result, 'FAIL') !== false){
422
  $result = json_decode(substr($result, 5), true);
 
423
  }
424
+ die(empty($result['error']) ? 'OK' : 'FAIL '.json_encode(array('error' => $result['error'])));
425
  break;
426
 
427
  // SFW send logs
428
  case 'sfw_send_logs':
429
  $result = ct_sfw_send_logs();
430
+ die(empty($result['error']) ? 'OK' : 'FAIL '.json_encode(array('error' => $result['error'])));
431
  break;
432
 
433
  // Update plugin
437
 
438
  // Install plugin
439
  case 'install_plugin':
440
+ add_action('wp', 'apbct_rc__install_plugin', 1);
441
  break;
442
+ // Activate plugin
443
+ case 'activate_plugin':
444
+ $result = apbct_rc__activate_plugin($_GET['plugin']);
445
+ die(empty($result['error'])
446
+ ? 'OK'
447
+ : 'FAIL '.json_encode(array('error' => $result['error'])));
448
  break;
449
+
450
+ // Insert API key
451
+ case 'insert_auth_key':
452
+ $result = apbct_rc__insert_auth_key($_GET['auth_key'], $_GET['plugin']);
453
+ die(empty($result['error'])
454
+ ? 'OK'
455
+ : 'FAIL '.json_encode(array('error' => $result['error'])));
456
+ break;
457
+
458
+ // Update settins
459
  case 'update_settings':
460
  $result = apbct_rc__update_settings($_GET);
461
+ die(empty($result['error'])
462
  ? 'OK'
463
+ : 'FAIL '.json_encode(array('error' => $result['error'])));
464
+ break;
465
+ // Deactivate plugin
466
+ case 'deactivate_plugin':
467
+ add_action('plugins_loaded', 'apbct_rc__deactivate_plugin', 1);
468
  break;
469
 
470
+ // Uninstall plugin
471
+ case 'uninstall_plugin':
472
+ add_action('plugins_loaded', 'apbct_rc__uninstall_plugin', 1);
473
+ break;
474
+ // No action found
475
  default:
476
  die('FAIL '.json_encode(array('error' => 'UNKNOWN_ACTION_2')));
477
  break;
506
  if($apbct->rc_running || (!empty($spbc) && $spbc->rc_running))
507
  return;
508
 
 
 
 
509
  $is_sfw_check = true;
510
  $sfw = new CleantalkSFW();
511
  $sfw->ip_array = (array)$sfw->ip__get(array('real'), true);
801
 
802
  if($apbct->settings['spam_firewall'] == 1){
803
 
 
 
 
804
  $sfw = new CleantalkSFW();
805
 
806
  $file_url = isset($_GET['file_url']) ? $_GET['file_url'] : null;
815
  return $result;
816
  }
817
 
818
+ return array('error' => 'SFW_DISABLED');
819
 
820
  }
821
 
824
  global $apbct;
825
 
826
  if($apbct->settings['spam_firewall'] == 1){
 
 
 
827
 
828
  $sfw = new CleantalkSFW();
829
  $result = $sfw->logs__send($apbct->api_key);
838
 
839
  }
840
 
841
+ return array('error' => 'SFW_DISABLED');
842
  }
843
 
844
  /**
845
  * Install plugin from wordpress catalog
846
  *
847
+ * @param WP $wp
848
+ * @param string $plugin_slug
849
+ */
850
+ function apbct_rc__install_plugin($wp = null, $plugin = null){
851
+
852
+ $plugin = $plugin ? $plugin : (isset($_GET['plugin']) ? $_GET['plugin'] : null);
853
+
854
+ if($plugin){
855
+
856
+ if(preg_match('/[a-zA-Z-\d]+[\/\\][a-zA-Z-\d]+\.php/', $plugin)){
857
+
858
+ $plugin_slug = preg_replace('@([a-zA-Z-\d]+)[\\\/].*@', '$1', $plugin);
859
+
860
+ if($plugin_slug){
861
+
862
+ require_once(ABSPATH.'wp-admin/includes/plugin-install.php');
863
+ $result = plugins_api(
864
+ 'plugin_information',
865
+ array('slug' => $plugin_slug, 'fileds' => array('version' => true, 'download_link' => true,),)
866
+ );
867
+
868
+ if(!is_wp_error($result)){
869
+
870
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
871
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
872
+ include_once( ABSPATH . 'wp-admin/includes/file.php' );
873
+ include_once( ABSPATH . 'wp-admin/includes/misc.php' );
874
+ include_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkUpgrader.php' );
875
+ include_once( CLEANTALK_PLUGIN_DIR . 'lib/CleantalkUpgraderSkin.php' );
876
+
877
+ $installer= new CleantalkUpgrader( new CleantalkUpgraderSkin() );
878
+ $installer->install($result->download_link);
879
+
880
+ if($installer->apbct_result === 'OK'){
881
+ die('OK');
882
+
883
+ }else
884
+ die('FAIL '. json_encode(array('error' => $installer->apbct_result)));
885
+ }else
886
+ die('FAIL '. json_encode(array('error' => 'FAIL_TO_GET_LATEST_VERSION '.$result->get_error_message())));
887
+ }else
888
+ die('FAIL '. json_encode(array('error' => 'PLUGIN_SLUG_INCORRECT')));
889
+ }else
890
+ die('FAIL '. json_encode(array('error' => 'PLUGIN_NAME_IS_INCORRECT')));
891
+ }else
892
+ die('FAIL '. json_encode(array('error' => 'PLUGIN_NAME_IS_UNSET')));
893
+ }
894
+
895
+ function apbct_rc__activate_plugin($plugin){
896
+
897
+ $plugin = $plugin ? $plugin : (isset($_GET['plugin']) ? $_GET['plugin'] : null);
898
+
899
+ if($plugin){
900
+
901
+ if(preg_match('@[a-zA-Z-\d]+[\\\/][a-zA-Z-\d]+\.php@', $plugin)){
902
+
903
+ require_once (ABSPATH .'/wp-admin/includes/plugin.php');
904
+
905
+ $result = activate_plugins($plugin);
906
+
907
+ if($result && !is_wp_error($result)){
908
+ return array('success' => true);
909
+ }else
910
+ return array('error' => 'FAIL_TO_ACTIVATE'.(is_wp_error($result) ? ' '.$result->get_error_message() : ''));
911
+ }else
912
+ return array('error' => 'PLUGIN_NAME_IS_INCORRECT');
913
+ }else
914
+ return array('error' => 'PLUGIN_NAME_IS_UNSET');
915
+ }
916
+
917
+ /**
918
+ * Uninstall plugin from wordpress catalog
919
+ *
920
  * @param null $plugin_name
921
  */
922
+ function apbct_rc__deactivate_plugin($plugin = null){
923
 
924
  global $apbct;
925
 
926
+ $plugin = $plugin ? $plugin : (isset($_GET['plugin']) ? $_GET['plugin'] : null);
 
 
 
 
 
 
 
927
 
928
+ if($plugin){
929
+
930
+ // Switching complete deactivation for security
931
+ if($plugin == 'security-malware-firewall/security-malware-firewall.php' && !empty($_GET['complete_deactivation'])){
932
+ $spbc_settings = get_option('spbc_settings');
933
+ $spbc_settings['complete_deactivation'] = intval($_GET['complete_deactivation']);
934
+ update_option('spbc_settings', $spbc_settings);
935
+ }
936
 
937
+ require_once (ABSPATH .'/wp-admin/includes/plugin.php');
938
+
939
+ if(is_plugin_active( $plugin )){
940
+ // Hook to set flag if the plugin is deactivated
941
+ add_action( 'deactivate_'.$plugin, 'apbct_rc__uninstall_plugin__check_deactivate' );
942
+ deactivate_plugins($plugin, false, is_multisite() ? true : false);
943
+ }else{
944
+ $apbct->plugin_deactivated = true;
945
+ }
946
+
947
+ // Hook to set flag if the plugin is deactivated
948
+ add_action( 'deactivate_'.$plugin, 'apbct_rc__uninstall_plugin__check_deactivate' );
949
+ deactivate_plugins($plugin, false, is_multisite() ? true : false);
950
+
951
+ if($apbct->plugin_deactivated){
952
  die('OK');
953
  }else
954
+ die('FAIL '. json_encode(array('error' => 'PLUGIN_STILL_ACTIVE')));
 
955
  }else
956
  die('FAIL '. json_encode(array('error' => 'PLUGIN_NAME_IS_UNSET')));
957
  }
958
 
959
+
960
  /**
961
+ * Uninstall plugin from wordpress catalog
962
  *
963
+ * @param null $plugin
964
  */
965
+ function apbct_rc__uninstall_plugin($plugin = null){
966
 
967
  global $apbct;
968
 
969
+ $plugin = $plugin ? $plugin : (isset($_GET['plugin']) ? $_GET['plugin'] : null);
970
 
971
+ if($plugin){
972
 
973
+ // Switching complete deactivation for security
974
+ if($plugin == 'security-malware-firewall/security-malware-firewall.php' && !empty($_GET['complete_deactivation'])){
975
+ $spbc_settings = get_option('spbc_settings');
976
+ $spbc_settings['complete_deactivation'] = intval($_GET['complete_deactivation']);
977
+ update_option('spbc_settings', $spbc_settings);
978
+ }
979
+
980
+ require_once (ABSPATH .'/wp-admin/includes/plugin.php');
981
+
982
+ if(is_plugin_active( $plugin )){
983
+ // Hook to set flag if the plugin is deactivated
984
+ add_action( 'deactivate_'.$plugin, 'apbct_rc__uninstall_plugin__check_deactivate' );
985
+ deactivate_plugins($plugin, false, is_multisite() ? true : false);
986
+ }else{
987
+ $apbct->plugin_deactivated = true;
988
+ }
989
 
990
  if($apbct->plugin_deactivated){
991
 
992
+ require_once (ABSPATH .'/wp-admin/includes/file.php');
 
 
993
 
994
+ $result = delete_plugins(array($plugin));
995
+
996
+ if($result && !is_wp_error($result)){
997
  die('OK');
998
  }else
999
+ die('FAIL '. json_encode(array('error' => 'PLUGIN_STILL_EXISTS'.($is_wp_error($result) ? ' '.$result->get_error_message() : ''))));
1000
  }else
1001
  die('FAIL '. json_encode(array('error' => 'PLUGIN_STILL_ACTIVE')));
1002
  }else
1003
  die('FAIL '. json_encode(array('error' => 'PLUGIN_NAME_IS_UNSET')));
1004
  }
1005
 
1006
+ function apbct_rc__uninstall_plugin__check_deactivate(){
1007
  global $apbct;
1008
  $apbct->plugin_deactivated = true;
1009
  }
 
 
 
 
1010
 
1011
+ function apbct_rc__update(){
1012
 
1013
  //Upgrade params
1014
  $plugin = 'cleantalk-spam-protect/cleantalk.php';
1092
  return true;
1093
  }
1094
 
1095
+ function apbct_rc__insert_auth_key($key, $plugin){
1096
+
1097
+ global $apbct;
1098
+
1099
+ if($plugin === 'security-malware-firewall/security-malware-firewall.php'){
1100
+
1101
+ require_once (ABSPATH .'/wp-admin/includes/plugin.php');
1102
+
1103
+ if(is_plugin_active( $plugin )){
1104
+
1105
+ $key = trim($key);
1106
+
1107
+ if($key && preg_match('/^[a-z\d]{3,15}$/', $key)){
1108
+
1109
+ $result = CleantalkAPI::method__notice_paid_till(
1110
+ $key,
1111
+ preg_replace('/http[s]?:\/\//', '', get_option('siteurl'), 1) // Site URL
1112
+ );
1113
+
1114
+ if( empty( $result['error'] ) ) {
1115
+
1116
+ if( $result['valid'] ){
1117
+
1118
+ // Set account params
1119
+ $data = get_option('spbc_data', array());
1120
+ $data['user_token'] = $result['user_token'];
1121
+ $data['notice_show'] = $result['show_notice'];
1122
+ $data['notice_renew'] = $result['renew'];
1123
+ $data['notice_trial'] = $result['trial'];
1124
+ $data['auto_update_app'] = isset($result['show_auto_update_notice']) ? $result['show_auto_update_notice'] : 0;
1125
+ $data['service_id'] = $result['service_id'];
1126
+ $data['moderate'] = $result['moderate'];
1127
+ $data['auto_update_app '] = isset($result['auto_update_app']) ? $result['auto_update_app'] : 0;
1128
+ $data['license_trial'] = isset($result['license_trial']) ? $result['license_trial'] : 0;
1129
+ $data['account_name_ob'] = isset($result['account_name_ob']) ? $result['account_name_ob'] : '';
1130
+ $data['key_is_ok'] = true;
1131
+ update_option('spbc_data', $data);
1132
+
1133
+ // Set key
1134
+ $settings = get_option('spbc_settings', array());
1135
+ $settings['spbc_key'] = $key;
1136
+ update_option('spbc_settings', $settings);
1137
+
1138
+ return 'OK';
1139
+ }else
1140
+ return array('error' => array('KEY_IS_NOT_VALID'));
1141
+ }else
1142
+ return array('error' => $result);
1143
+ }else
1144
+ return array('error' => 'KEY_IS_NOT_CORRECT');
1145
+ }else
1146
+ return array('error' => 'PLUGIN_IS_NOT_ACTIVE_OR_NOT_INSTALLED');
1147
+ }else
1148
+ return array('error' => 'PLUGIN_SLUG_INCORRECT');
1149
+ }
1150
+
1151
  function cleantalk_get_brief_data(){
1152
 
1153
  global $apbct;
1440
  global $apbct;
1441
 
1442
  $api_key = $api_key ? $api_key : $apbct->api_key;
1443
+ $result = CleantalkAPI::method__notice_paid_till(
1444
+ $api_key,
1445
+ preg_replace('/http[s]?:\/\//', '', get_option('siteurl'), 1)
1446
+ );
1447
 
1448
  if(empty($result['error']) || (isset($result['error_no']) && $result['error_no'] == 12)){
1449
 
1647
 
1648
  /**
1649
  * Runs update actions for new version.
1650
+ *
1651
+ * @global CleantalkState $apbct
1652
  */
1653
  function apbct_update_actions(){
1654
 
1668
  $apbct->data['plugin_version'] = APBCT_VERSION;
1669
  $apbct->saveData();
1670
  }
1671
+ ct_send_feedback('0:' . APBCT_AGENT ); // Send feedback to let cloud know about updated version.
1672
 
1673
  // Side blogs
1674
  }else{
inc/cleantalk-admin.php CHANGED
@@ -51,7 +51,7 @@ function ct_dashboard_statistics_widget_output( $post, $callback_args ) {
51
  }elseif(!empty($apbct->data['brief_data']['error'])){
52
  echo '<div class="ct_widget_block">'
53
  .'<h2 class="ct_widget_activate_header">'
54
- .sprintf(__('Something went wrong! Error: "%s".', 'cleantalk'), "<u>{$apbct->brief_data['error_string']}</u>")
55
  .'</h2>';
56
  if($apbct->user_token && !$apbct->white_label){
57
  echo '<h2 class="ct_widget_activate_header">'
51
  }elseif(!empty($apbct->data['brief_data']['error'])){
52
  echo '<div class="ct_widget_block">'
53
  .'<h2 class="ct_widget_activate_header">'
54
+ .sprintf(__('Something went wrong! Error: "%s".', 'cleantalk'), "<u>{$apbct->brief_data['error']}</u>")
55
  .'</h2>';
56
  if($apbct->user_token && !$apbct->white_label){
57
  echo '<h2 class="ct_widget_activate_header">'
inc/cleantalk-ajax.php CHANGED
@@ -295,6 +295,7 @@ function ct_ajax_hook($message_obj = false, $additional = false)
295
  check_url_exclusions() || // url exclusions
296
  (isset($_POST['action']) && in_array($_POST['action'], $skip_post)) || // Special params
297
  (isset($_GET['action']) && in_array($_GET['action'], $skip_post)) || // Special params
 
298
  // QAEngine Theme fix
299
  ( strval(current_action()) != 'et_pre_insert_answer' &&
300
  (
295
  check_url_exclusions() || // url exclusions
296
  (isset($_POST['action']) && in_array($_POST['action'], $skip_post)) || // Special params
297
  (isset($_GET['action']) && in_array($_GET['action'], $skip_post)) || // Special params
298
+ isset($_POST['quform_submit']) || //QForms multi-paged form skip
299
  // QAEngine Theme fix
300
  ( strval(current_action()) != 'et_pre_insert_answer' &&
301
  (
inc/cleantalk-comments.php CHANGED
@@ -432,7 +432,7 @@ function ct_ajax_check_comments(){
432
 
433
  }else{
434
  $check_result['error'] = 1;
435
- $check_result['error_message'] = $result['error_string'];
436
  echo json_encode($check_result);
437
  }
438
  }else{
432
 
433
  }else{
434
  $check_result['error'] = 1;
435
+ $check_result['error_message'] = $result['error'];
436
  echo json_encode($check_result);
437
  }
438
  }else{
inc/cleantalk-common.php CHANGED
@@ -97,7 +97,7 @@ function apbct_base_call($params = array(), $reg_flag = false){
97
  'auth_key' => $apbct->api_key,
98
  'js_on' => apbct_js_test('ct_checkjs', $_COOKIE) ? 1 : apbct_js_test('ct_checkjs', $_POST),
99
 
100
- 'agent' => CLEANTALK_AGENT,
101
  'sender_info' => $sender_info,
102
  'submit_time' => apbct_get_submit_time(),
103
  );
@@ -114,7 +114,7 @@ function apbct_base_call($params = array(), $reg_flag = false){
114
 
115
  // Options store url without shceme because of DB error with ''://'
116
  $config = ct_get_server();
117
- $ct->server_url = CLEANTALK_MODERATE_URL;
118
  $ct->work_url = preg_match('/http:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
119
  $ct->server_ttl = $config['ct_server_ttl'];
120
  $ct->server_changed = $config['ct_server_changed'];
@@ -470,7 +470,7 @@ function ct_send_feedback($feedback_request = null) {
470
 
471
  // Server URL handling
472
  $config = ct_get_server();
473
- $ct->server_url = CLEANTALK_MODERATE_URL;
474
  $ct->work_url = preg_match('/http:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
475
  $ct->server_ttl = $config['ct_server_ttl'];
476
  $ct->server_changed = $config['ct_server_changed'];
97
  'auth_key' => $apbct->api_key,
98
  'js_on' => apbct_js_test('ct_checkjs', $_COOKIE) ? 1 : apbct_js_test('ct_checkjs', $_POST),
99
 
100
+ 'agent' => APBCT_AGENT,
101
  'sender_info' => $sender_info,
102
  'submit_time' => apbct_get_submit_time(),
103
  );
114
 
115
  // Options store url without shceme because of DB error with ''://'
116
  $config = ct_get_server();
117
+ $ct->server_url = APBCT_MODERATE_URL;
118
  $ct->work_url = preg_match('/http:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
119
  $ct->server_ttl = $config['ct_server_ttl'];
120
  $ct->server_changed = $config['ct_server_changed'];
470
 
471
  // Server URL handling
472
  $config = ct_get_server();
473
+ $ct->server_url = APBCT_MODERATE_URL;
474
  $ct->work_url = preg_match('/http:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
475
  $ct->server_ttl = $config['ct_server_ttl'];
476
  $ct->server_changed = $config['ct_server_changed'];
inc/cleantalk-public.php CHANGED
@@ -33,32 +33,42 @@ function apbct_init() {
33
  add_shortcode( 'et_pb_contact_form', 'ct_contact_form_validate' );
34
  }
35
 
36
- if($apbct->settings['check_external']
37
- && isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST'
38
- && isset($_POST['cleantalk_hidden_method'])
39
- && isset($_POST['cleantalk_hidden_action'])
40
- ){
41
- $action=htmlspecialchars($_POST['cleantalk_hidden_action']);
42
- $method=htmlspecialchars($_POST['cleantalk_hidden_method']);
43
- unset($_POST['cleantalk_hidden_action']);
44
- unset($_POST['cleantalk_hidden_method']);
45
- ct_contact_form_validate();
46
- if(empty($_POST['cleantalk_hidden_ajax'])){
47
- print "<html><body><form method='$method' action='$action'>";
48
- ct_print_form($_POST,'');
49
- print "</form><center>Redirecting to ".$action."... Anti-spam by CleanTalk.</center></body></html>";
50
- print "<script>
51
- if(document.forms[0].submit != 'undefined'){
52
- var objects = document.getElementsByName('submit');
53
- if(objects.length > 0)
54
- document.forms[0].removeChild(objects[0]);
55
- }
56
- document.forms[0].submit();
57
- </script>";
58
- die();
59
  }
60
- }
61
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  if(isset($_POST['quform_ajax'], $_POST['quform_csrf_token'], $_POST['quform_form_id'])){
63
  require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-ajax.php');
64
  ct_ajax_hook();
@@ -75,7 +85,8 @@ function apbct_init() {
75
 
76
  if($apbct->settings['general_contact_forms_test'] == 1 && empty($_POST['ct_checkjs_cf7'])){
77
  add_action('CMA_custom_post_type_nav','ct_contact_form_validate_postdata',1);
78
- add_action('wp','ct_contact_form_validate',1);
 
79
  if(isset($_POST['reg_redirect_link'])&&isset($_POST['tmpl_registration_nonce_field']))
80
  {
81
  unset($_POST['ct_checkjs_register_form']);
@@ -230,6 +241,10 @@ function apbct_init() {
230
  add_filter('wpforms_process_before_filter', 'apbct_from__WPForms__gatherData', 100, 2);
231
  // Do spam check
232
  add_filter('wpforms_process_initial_errors', 'apbct_form__WPForms__showResponse', 100, 2);
 
 
 
 
233
 
234
  //
235
  // Load JS code to website footer
@@ -248,7 +263,7 @@ function apbct_init() {
248
 
249
  if ($apbct->settings['general_contact_forms_test'] == 1 && !isset($_POST['comment_post_ID']) && !isset($_GET['for'])){
250
  $ct_check_post_result=false;
251
- add_action( 'wp', 'ct_contact_form_validate', 999 );
252
  }
253
  if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST' &&
254
  $apbct->settings['general_postdata_test'] == 1 &&
@@ -262,6 +277,79 @@ function apbct_init() {
262
  }
263
  }
264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  // MailChimp Premium for Wordpress
266
  function ct_add_mc4wp_error_message($messages){
267
 
@@ -2325,6 +2413,44 @@ function apbct_form__WPForms__changeMailNotification($message, $wpforms_email){
2325
 
2326
  }
2327
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2328
  /**
2329
  * Inserts anti-spam hidden to Fast Secure contact form
2330
  */
@@ -2660,7 +2786,8 @@ function ct_contact_form_validate() {
2660
  (strpos($_SERVER['REQUEST_URI'],'admin_aspcms/_system/AspCms_SiteSetting.asp?action=saves')!==false ) || // Skip admin save callback
2661
  (strpos($_SERVER['REQUEST_URI'],'?profile_tab=postjobs')!==false ) || // Skip post vacancies
2662
  (isset($_POST['btn_insert_post_type_hotel']) && $_POST['btn_insert_post_type_hotel'] == 'SUBMIT HOTEL') || // Skip adding hotel
2663
- (isset($_POST['action']) && $_POST['action'] == 'updraft_savesettings') // Updraft save settings
 
2664
  ) {
2665
  return null;
2666
  }
@@ -2966,30 +3093,20 @@ function ct_send_error_notice ($comment = '') {
2966
  return null;
2967
  }
2968
 
2969
- function ct_print_form($arr,$k)
2970
  {
2971
- foreach($arr as $key=>$value)
2972
- {
2973
- if(!is_array($value))
2974
- {
2975
- if($k=='')
2976
- {
2977
- print '<textarea name="'.$key.'" style="display:none;">'.htmlspecialchars($value).'</textarea>';
2978
- }
2979
- else
2980
- {
2981
- print '<textarea name="'.$k.'['.$key.']" style="display:none;">'.htmlspecialchars($value).'</textarea>';
2982
- }
2983
- }
2984
- else
2985
- {
2986
- if($k=='')
2987
- {
2988
- ct_print_form($value,$key);
2989
  }
2990
- else
2991
- {
2992
- ct_print_form($value,$k.'['.$key.']');
 
 
2993
  }
2994
  }
2995
  }
33
  add_shortcode( 'et_pb_contact_form', 'ct_contact_form_validate' );
34
  }
35
 
36
+ if($apbct->settings['check_external']){
37
+
38
+ // Fixing form and directs it this site
39
+ if($apbct->settings['check_external__capture_buffer'] && !is_admin() && !apbct_is_ajax() && apbct_is_user_enable() && !(defined('DOING_CRON') && DOING_CRON)){
40
+ add_action('wp', 'apbct_buffer__start');
41
+ add_action('shutdown', 'apbct_buffer__end', 0);
42
+ add_action('shutdown', 'apbct_buffer__output', 2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
+
45
+ // Check and redirecct
46
+ if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST'
47
+ && isset($_POST['cleantalk_hidden_method'])
48
+ && isset($_POST['cleantalk_hidden_action'])
49
+ ){
50
+ $action = htmlspecialchars($_POST['cleantalk_hidden_action']);
51
+ $method = htmlspecialchars($_POST['cleantalk_hidden_method']);
52
+ unset($_POST['cleantalk_hidden_action']);
53
+ unset($_POST['cleantalk_hidden_method']);
54
+ ct_contact_form_validate();
55
+ if(!apbct_is_ajax()){
56
+ print "<html><body><form method='$method' action='$action'>";
57
+ ct_print_form($_POST, '');
58
+ print "</form>Redirecting to " . $action . "... Anti-spam by CleanTalk.</body></html>";
59
+ print "<script>
60
+ if(document.forms[0].submit !== 'undefined'){
61
+ var objects = document.getElementsByName('submit');
62
+ if(objects.length > 0)
63
+ document.forms[0].removeChild(objects[0]);
64
+ }
65
+ document.forms[0].submit();
66
+ </script>";
67
+ die();
68
+ }
69
+ }
70
+ }
71
+
72
  if(isset($_POST['quform_ajax'], $_POST['quform_csrf_token'], $_POST['quform_form_id'])){
73
  require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-ajax.php');
74
  ct_ajax_hook();
85
 
86
  if($apbct->settings['general_contact_forms_test'] == 1 && empty($_POST['ct_checkjs_cf7'])){
87
  add_action('CMA_custom_post_type_nav','ct_contact_form_validate_postdata',1);
88
+ //add_action('init','ct_contact_form_validate',1);
89
+ ct_contact_form_validate();
90
  if(isset($_POST['reg_redirect_link'])&&isset($_POST['tmpl_registration_nonce_field']))
91
  {
92
  unset($_POST['ct_checkjs_register_form']);
241
  add_filter('wpforms_process_before_filter', 'apbct_from__WPForms__gatherData', 100, 2);
242
  // Do spam check
243
  add_filter('wpforms_process_initial_errors', 'apbct_form__WPForms__showResponse', 100, 2);
244
+
245
+ // QForms integration
246
+ add_filter( 'quform_post_validate', 'ct_quform_post_validate', 10, 2 );
247
+
248
 
249
  //
250
  // Load JS code to website footer
263
 
264
  if ($apbct->settings['general_contact_forms_test'] == 1 && !isset($_POST['comment_post_ID']) && !isset($_GET['for'])){
265
  $ct_check_post_result=false;
266
+ add_action( 'init', 'ct_contact_form_validate', 999 );
267
  }
268
  if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST' &&
269
  $apbct->settings['general_postdata_test'] == 1 &&
277
  }
278
  }
279
 
280
+ function apbct_buffer__start(){
281
+ ob_start();
282
+ }
283
+
284
+ function apbct_buffer__end(){
285
+
286
+ if(!ob_get_level())
287
+ return;
288
+
289
+ global $apbct;
290
+ $apbct->buffer = ob_get_contents();
291
+ ob_end_clean();
292
+ }
293
+
294
+ /**
295
+ * Outputs changed buffer
296
+ *
297
+ * @global $apbct
298
+ */
299
+ function apbct_buffer__output(){
300
+
301
+ global $apbct;
302
+
303
+ if(empty($apbct->buffer))
304
+ return;
305
+
306
+ $site_url = get_option('siteurl');
307
+ $site__host = parse_url($site_url, PHP_URL_HOST);
308
+
309
+ $dom = new DOMDocument();
310
+ @$dom->loadHTML($apbct->buffer);
311
+
312
+ $forms = $dom->getElementsByTagName('form');
313
+
314
+ foreach($forms as $form){
315
+
316
+ $action = $form->getAttribute('action');
317
+ $action = $action ? $action : $site_url;
318
+ $action__host = parse_url($action, PHP_URL_HOST);
319
+
320
+ // Check if the form directed to the third party site
321
+ if($site__host != $action__host){
322
+
323
+ $method = $form->getAttribute('method');
324
+ $method = $method ? $method : 'get';
325
+ // Directs form to our site
326
+ $form->setAttribute('method', 'POST');
327
+ $form->setAttribute('action', $site_url);
328
+
329
+ // Add cleantalk_hidden_action
330
+ $new_input = $dom->createElement('input');
331
+ $new_input->setAttribute('type', 'hidden');
332
+ $new_input->setAttribute('name', 'cleantalk_hidden_action');
333
+ $new_input->setAttribute('value', $action);
334
+ $form->appendChild($new_input);
335
+
336
+ // Add cleantalk_hidden_method
337
+ $new_input = $dom->createElement('input');
338
+ $new_input->setAttribute('type', 'hidden');
339
+ $new_input->setAttribute('name', 'cleantalk_hidden_method');
340
+ $new_input->setAttribute('value', $method);
341
+ $form->appendChild($new_input);
342
+
343
+ }
344
+ } unset($form);
345
+
346
+ $html = $dom->getElementsByTagName('html');
347
+
348
+ echo gettype($html) == 'object'
349
+ ? $html[0]->childNodes[0]->ownerDocument->saveHTML()
350
+ : $apbct->buffer;
351
+ }
352
+
353
  // MailChimp Premium for Wordpress
354
  function ct_add_mc4wp_error_message($messages){
355
 
2413
 
2414
  }
2415
 
2416
+ /*
2417
+ * QuForms check spam
2418
+ * works with singl-paged forms
2419
+ * and with multi-paged forms - check only last step of the forms
2420
+ */
2421
+ function ct_quform_post_validate($result, $form) {
2422
+
2423
+ if ( $form->hasPages() ) {
2424
+ $comment_type = 'contact_form_wordpress_quforms_multipage';
2425
+ } else {
2426
+ $comment_type = 'contact_form_wordpress_quforms_singlepage';
2427
+ }
2428
+
2429
+ $ct_temp_msg_data = ct_get_fields_any( $form->getValues() );
2430
+ // @ToDo If we have several emails at the form - will be used only the first detected!
2431
+ $sender_email = ($ct_temp_msg_data['email'] ? $ct_temp_msg_data['email'] : '');
2432
+
2433
+ $checkjs = apbct_js_test('ct_checkjs', $_COOKIE);
2434
+ $base_call_result = apbct_base_call(
2435
+ array(
2436
+ 'message' => $form->getValues(),
2437
+ 'sender_email' => $sender_email,
2438
+ 'post_info' => array('comment_type' => $comment_type),
2439
+ 'js_on' => $checkjs,
2440
+ )
2441
+ );
2442
+
2443
+ $ct_result = $base_call_result['ct_result'];
2444
+ if ($ct_result->allow == 0) {
2445
+ die(json_encode(array('type' => 'error', 'apbct' => array('blocked' => true, 'comment' => $ct_result->comment))));
2446
+ } else {
2447
+ return $result;
2448
+ }
2449
+
2450
+ return $result;
2451
+
2452
+ }
2453
+
2454
  /**
2455
  * Inserts anti-spam hidden to Fast Secure contact form
2456
  */
2786
  (strpos($_SERVER['REQUEST_URI'],'admin_aspcms/_system/AspCms_SiteSetting.asp?action=saves')!==false ) || // Skip admin save callback
2787
  (strpos($_SERVER['REQUEST_URI'],'?profile_tab=postjobs')!==false ) || // Skip post vacancies
2788
  (isset($_POST['btn_insert_post_type_hotel']) && $_POST['btn_insert_post_type_hotel'] == 'SUBMIT HOTEL') || // Skip adding hotel
2789
+ (isset($_POST['action']) && $_POST['action'] == 'updraft_savesettings') || // Updraft save settings
2790
+ isset($_POST['quform_submit']) //QForms multi-paged form skip
2791
  ) {
2792
  return null;
2793
  }
3093
  return null;
3094
  }
3095
 
3096
+ function ct_print_form($arr, $k)
3097
  {
3098
+ foreach($arr as $key => $value){
3099
+ if(!is_array($value)){
3100
+ if($k == ''){
3101
+ print '<textarea name="' . $key . '" style="display:none;">' . htmlspecialchars($value) . '</textarea>';
3102
+ }else{
3103
+ print '<textarea name="' . $k . '[' . $key . ']" style="display:none;">' . htmlspecialchars($value) . '</textarea>';
 
 
 
 
 
 
 
 
 
 
 
 
3104
  }
3105
+ }else{
3106
+ if($k == ''){
3107
+ ct_print_form($value, $key);
3108
+ }else{
3109
+ ct_print_form($value, $k . '[' . $key . ']');
3110
  }
3111
  }
3112
  }
inc/cleantalk-settings.php CHANGED
@@ -163,15 +163,18 @@ function apbct_settings__add_page() {
163
  'check_external' => array(
164
  'title' => __('Protect external forms', 'cleantalk'),
165
  'description' => __('Turn this option on to protect forms on your WordPress that send data to third-part servers (like MailChimp).', 'cleantalk'),
 
 
 
 
 
 
 
166
  ),
167
  'check_internal' => array(
168
  'title' => __('Protect internal forms', 'cleantalk'),
169
  'description' => __('This option will enable protection for custom (hand-made) AJAX forms with PHP scripts handlers on your WordPress.', 'cleantalk'),
170
  ),
171
- // 'validate_email_existence' => array(
172
- // 'title' => __('Validate e-mail for existence', 'cleantalk'),
173
- // 'description' => __('Using additional filter for e-mails. Block subscription/comment/registration if e-mail not exists.', 'cleantalk'),
174
- // ),
175
  ),
176
  ),
177
 
@@ -213,7 +216,7 @@ function apbct_settings__add_page() {
213
  ),
214
  'use_ajax' => array(
215
  'title' => __('Use AJAX for JavaScript check', 'cleantalk'),
216
- 'description' => __('Options helps protect WordPress against spam with any caching plugins. Turn this option on to avoid issues with caching plugins.', 'cleantalk')."<strong> ".__('Attention! Incompatible with AMP plugins!', 'cleantalk')."</strong>",
217
  ),
218
  'use_static_js_key' => array(
219
  'title' => __('Use static keys for JS check.', 'cleantalk'),
@@ -528,7 +531,7 @@ function apbct_settings__error__output($return = false){
528
  if(isset($sub_error['error_time']))
529
  $errors_out[$sub_type] .= date('Y-m-d H:i:s', $sub_error['error_time']) . ': ';
530
  $errors_out[$sub_type] .= ucfirst($type).': ';
531
- $errors_out[$sub_type] .= (isset($error_texts[$sub_type]) ? $error_texts[$sub_type] : $error_texts['unknown']) . $sub_error['error_string'];
532
  }
533
  continue;
534
  }
@@ -536,7 +539,7 @@ function apbct_settings__error__output($return = false){
536
  $errors_out[$type] = '';
537
  if(isset($error['error_time']))
538
  $errors_out[$type] .= date('Y-m-d H:i:s', $error['error_time']) . ': ';
539
- $errors_out[$type] .= (isset($error_texts[$type]) ? $error_texts[$type] : $error_texts['unknown']) . ' ' . (isset($error['error_string']) ? $error['error_string'] : '');
540
 
541
  }
542
  }
@@ -806,7 +809,7 @@ function apbct_settings__field__statistics() {
806
  echo '<br>';
807
 
808
  // SFW last update
809
- $sfw_netwoks_amount = $wpdb->get_results("SELECT count(*) AS cnt FROM `".$wpdb->base_prefix."cleantalk_sfw`", ARRAY_A);
810
  printf(
811
  __('SpamFireWall was updated %s. Now contains %s entries.', 'cleantalk'),
812
  $apbct->stats['sfw']['last_update_time'] ? date('M d Y H:i:s', $apbct->stats['sfw']['last_update_time']) : __('unknown', 'cleantalk'),
@@ -1000,7 +1003,7 @@ function apbct_settings__validate($settings) {
1000
  }
1001
  } unset($setting, $value);
1002
 
1003
- // validating API key
1004
  $settings['apikey'] = isset($settings['apikey']) ? trim($settings['apikey']) : '';
1005
  $settings['apikey'] = defined('CLEANTALK_ACCESS_KEY') ? CLEANTALK_ACCESS_KEY : $settings['apikey'];
1006
  $settings['apikey'] = $apbct->white_label ? $apbct->settings['apikey'] : $settings['apikey'];
@@ -1023,7 +1026,7 @@ function apbct_settings__validate($settings) {
1023
 
1024
  $website = parse_url(get_option('siteurl'), PHP_URL_HOST).parse_url(get_option('siteurl'), PHP_URL_PATH);
1025
  $platform = 'wordpress';
1026
- $user_ip = CleantalkHelper::ip__get(array('real'), false);
1027
  $timezone = filter_input(INPUT_POST, 'ct_admin_timezone');
1028
  $language = filter_input(INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE');
1029
  $wpms = APBCT_WPMS && defined('SUBDOMAIN_INSTALL') && !SUBDOMAIN_INSTALL ? true : false;
@@ -1031,6 +1034,7 @@ function apbct_settings__validate($settings) {
1031
  $hoster_api_key = $apbct->white_label&& defined('APBCT_HOSTER_API_KEY') ? APBCT_HOSTER_API_KEY : '';
1032
 
1033
  $result = CleantalkAPI::method__get_api_key(
 
1034
  ct_get_admin_email(),
1035
  $website,
1036
  $platform,
@@ -1056,13 +1060,13 @@ function apbct_settings__validate($settings) {
1056
  if(!$apbct->white_label)
1057
  $apbct->error_add('key_get', $result);
1058
  else
1059
- $apbct->error_add('key_get', $result['error_string'] . ' <button id="apbct_setting_get_key_auto" name="submit" type="submit" class="cleantalk_manual_link" value="get_key_auto">'.__('Get access key automatically', 'cleantalk').'</button>'.'<input type="hidden" id="ct_admin_timezone" name="ct_admin_timezone" value="null" />');
1060
  return $settings;
1061
  }
1062
  }
1063
 
1064
  // Feedback with app_agent
1065
- ct_send_feedback('0:' . CLEANTALK_AGENT); // 0 - request_id, agent version.
1066
 
1067
  // Key is good by default
1068
  $apbct->data['key_is_ok'] = true;
@@ -1092,6 +1096,7 @@ function apbct_settings__validate($settings) {
1092
 
1093
  // Key is not valid
1094
  }else{
 
1095
  $apbct->error_add('key_invalid', __('Testing is failed. Please check the Access key.', 'cleantalk'));
1096
  }
1097
 
163
  'check_external' => array(
164
  'title' => __('Protect external forms', 'cleantalk'),
165
  'description' => __('Turn this option on to protect forms on your WordPress that send data to third-part servers (like MailChimp).', 'cleantalk'),
166
+ 'childrens' => array('check_external__capture_buffer'),
167
+ ),
168
+ 'check_external__capture_buffer' => array(
169
+ 'title' => __('Capture buffer', 'cleantalk'),
170
+ 'description' => __('This setting gives you more sophisticated and strengthened protection for external forms. But it could break plugins which use a buffer like Ninja Forms.', 'cleantalk'),
171
+ 'class' => 'apbct_settings-field_wrapper--sub',
172
+ 'parent' => 'check_external',
173
  ),
174
  'check_internal' => array(
175
  'title' => __('Protect internal forms', 'cleantalk'),
176
  'description' => __('This option will enable protection for custom (hand-made) AJAX forms with PHP scripts handlers on your WordPress.', 'cleantalk'),
177
  ),
 
 
 
 
178
  ),
179
  ),
180
 
216
  ),
217
  'use_ajax' => array(
218
  'title' => __('Use AJAX for JavaScript check', 'cleantalk'),
219
+ 'description' => __('Options helps protect WordPress against spam with any caching plugins. Turn this option on to avoid issues with caching plugins.', 'cleantalk'),
220
  ),
221
  'use_static_js_key' => array(
222
  'title' => __('Use static keys for JS check.', 'cleantalk'),
531
  if(isset($sub_error['error_time']))
532
  $errors_out[$sub_type] .= date('Y-m-d H:i:s', $sub_error['error_time']) . ': ';
533
  $errors_out[$sub_type] .= ucfirst($type).': ';
534
+ $errors_out[$sub_type] .= (isset($error_texts[$sub_type]) ? $error_texts[$sub_type] : $error_texts['unknown']) . $sub_error['error'];
535
  }
536
  continue;
537
  }
539
  $errors_out[$type] = '';
540
  if(isset($error['error_time']))
541
  $errors_out[$type] .= date('Y-m-d H:i:s', $error['error_time']) . ': ';
542
+ $errors_out[$type] .= (isset($error_texts[$type]) ? $error_texts[$type] : $error_texts['unknown']) . ' ' . (isset($error['error']) ? $error['error'] : '');
543
 
544
  }
545
  }
809
  echo '<br>';
810
 
811
  // SFW last update
812
+ $sfw_netwoks_amount = $wpdb->get_results("SELECT count(*) AS cnt FROM `".$wpdb->prefix."cleantalk_sfw`", ARRAY_A);
813
  printf(
814
  __('SpamFireWall was updated %s. Now contains %s entries.', 'cleantalk'),
815
  $apbct->stats['sfw']['last_update_time'] ? date('M d Y H:i:s', $apbct->stats['sfw']['last_update_time']) : __('unknown', 'cleantalk'),
1003
  }
1004
  } unset($setting, $value);
1005
 
1006
+ // Validating API key
1007
  $settings['apikey'] = isset($settings['apikey']) ? trim($settings['apikey']) : '';
1008
  $settings['apikey'] = defined('CLEANTALK_ACCESS_KEY') ? CLEANTALK_ACCESS_KEY : $settings['apikey'];
1009
  $settings['apikey'] = $apbct->white_label ? $apbct->settings['apikey'] : $settings['apikey'];
1026
 
1027
  $website = parse_url(get_option('siteurl'), PHP_URL_HOST).parse_url(get_option('siteurl'), PHP_URL_PATH);
1028
  $platform = 'wordpress';
1029
+ $user_ip = CleantalkHelper::ip__get(array('real'), false);
1030
  $timezone = filter_input(INPUT_POST, 'ct_admin_timezone');
1031
  $language = filter_input(INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE');
1032
  $wpms = APBCT_WPMS && defined('SUBDOMAIN_INSTALL') && !SUBDOMAIN_INSTALL ? true : false;
1034
  $hoster_api_key = $apbct->white_label&& defined('APBCT_HOSTER_API_KEY') ? APBCT_HOSTER_API_KEY : '';
1035
 
1036
  $result = CleantalkAPI::method__get_api_key(
1037
+ 'antispam',
1038
  ct_get_admin_email(),
1039
  $website,
1040
  $platform,
1060
  if(!$apbct->white_label)
1061
  $apbct->error_add('key_get', $result);
1062
  else
1063
+ $apbct->error_add('key_get', $result['error'] . ' <button id="apbct_setting_get_key_auto" name="submit" type="submit" class="cleantalk_manual_link" value="get_key_auto">'.__('Get access key automatically', 'cleantalk').'</button>'.'<input type="hidden" id="ct_admin_timezone" name="ct_admin_timezone" value="null" />');
1064
  return $settings;
1065
  }
1066
  }
1067
 
1068
  // Feedback with app_agent
1069
+ ct_send_feedback('0:' . APBCT_AGENT); // 0 - request_id, agent version.
1070
 
1071
  // Key is good by default
1072
  $apbct->data['key_is_ok'] = true;
1096
 
1097
  // Key is not valid
1098
  }else{
1099
+ $apbct->data['key_is_ok'] = false;
1100
  $apbct->error_add('key_invalid', __('Testing is failed. Please check the Access key.', 'cleantalk'));
1101
  }
1102
 
inc/cleantalk-updater.php CHANGED
@@ -223,7 +223,7 @@ function apbct_update_to_5_118_2(){
223
  $apbct->saveData();
224
  }
225
 
226
- function apbct_update_to_5_119(){
227
 
228
  global $wpdb;
229
 
@@ -278,4 +278,11 @@ function apbct_update_to_5_119(){
278
  'ct_server_changed' => 0,
279
  )
280
  );
 
 
 
 
 
 
 
281
  }
223
  $apbct->saveData();
224
  }
225
 
226
+ function apbct_update_to_5_119_0(){
227
 
228
  global $wpdb;
229
 
278
  'ct_server_changed' => 0,
279
  )
280
  );
281
+ }
282
+
283
+ function apbct_update_to_5_124_0(){
284
+ global $apbct;
285
+ // Deleting error in database because format were changed
286
+ $apbct->errors = array();
287
+ $apbct->saveErrors();
288
  }
inc/cleantalk-users.php CHANGED
@@ -453,7 +453,7 @@ function ct_ajax_check_users(){
453
  print json_encode($check_result);
454
  }else{
455
  $check_result['error'] = 1;
456
- $check_result['error_message'] = $result['error_string'];
457
  echo json_encode($check_result);
458
  }
459
  }else{
453
  print json_encode($check_result);
454
  }else{
455
  $check_result['error'] = 1;
456
+ $check_result['error_message'] = $result['error'];
457
  echo json_encode($check_result);
458
  }
459
  }else{
js/cleantalk_external.min.js CHANGED
@@ -1,2 +1,2 @@
1
- function ct_protect_external(){for(i=0;i<document.forms.length;i++)if("string"==typeof document.forms[i].action&&(action=document.forms[i].action,(-1!=action.indexOf("http://")||-1!=action.indexOf("https://"))&&(tmp=action.split("//"),tmp=tmp[1].split("/"),host=tmp[0].toLowerCase(),host!=location.hostname.toLowerCase()))){var t=document.createElement("input");t.name="cleantalk_hidden_action",t.value=action,t.type="hidden",document.forms[i].appendChild(t);var e=document.createElement("input");e.name="cleantalk_hidden_method",e.value=document.forms[i].method,e.type="hidden",document.forms[i].method="POST",document.forms[i].appendChild(e),document.forms[i].action=ctNocache.blog_home}}jQuery(document).ready(function(){"object"==typeof _agile?window.onload=function(){setTimeout(function(){ct_protect_external()},1500)}:ct_protect_external()});
2
  //# sourceMappingURL=cleantalk_external.min.js.map
1
+ function ct_protect_external(){for(i=0;i<document.forms.length;i++)if("string"==typeof document.forms[i].action&&(action=document.forms[i].action,(-1!=action.indexOf("http://")||-1!=action.indexOf("https://"))&&(tmp=action.split("//"),tmp=tmp[1].split("/"),host=tmp[0].toLowerCase(),host!=location.hostname.toLowerCase()))){var t=document.createElement("input");t.name="cleantalk_hidden_action",t.value=action,t.type="hidden",document.forms[i].appendChild(t);var e=document.createElement("input");e.name="cleantalk_hidden_method",e.value=document.forms[i].method,e.type="hidden",document.forms[i].method="POST",document.forms[i].appendChild(e),document.forms[i].action=ctNocache.blog_home}}window.onload=function(){setTimeout(function(){ct_protect_external()},1500)};
2
  //# sourceMappingURL=cleantalk_external.min.js.map
js/cleantalk_external.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["cleantalk_external.js"],"names":["ct_protect_external","i","document","forms","length","action","indexOf","tmp","split","host","toLowerCase","location","hostname","ct_action","createElement","name","value","type","appendChild","ct_method","method","ctNocache","blog_home","jQuery","ready","_agile","window","onload","setTimeout"],"mappings":"AAAA,SAASA,sBAER,IAAIC,EAAE,EAAEA,EAAEC,SAASC,MAAMC,OAAOH,IAE/B,GAAqC,iBAA3BC,SAASC,MAAMF,GAAS,SAEjCI,OAAOH,SAASC,MAAMF,GAAGI,SACM,GAA5BA,OAAOC,QAAQ,aAA6C,GAA7BD,OAAOC,QAAQ,eAEhDC,IAAIF,OAAOG,MAAM,MACjBD,IAAIA,IAAI,GAAGC,MAAM,KACjBC,KAAKF,IAAI,GAAGG,cACTD,MAAME,SAASC,SAASF,gBAAc,CAExC,IAAIG,EAAYX,SAASY,cAAc,SACvCD,EAAUE,KAAK,0BACfF,EAAUG,MAAMX,OAChBQ,EAAUI,KAAK,SACff,SAASC,MAAMF,GAAGiB,YAAYL,GAE9B,IAAIM,EAAYjB,SAASY,cAAc,SACvCK,EAAUJ,KAAK,0BACfI,EAAUH,MAAMd,SAASC,MAAMF,GAAGmB,OAClCD,EAAUF,KAAK,SAEff,SAASC,MAAMF,GAAGmB,OAAO,OACzBlB,SAASC,MAAMF,GAAGiB,YAAYC,GAE9BjB,SAASC,MAAMF,GAAGI,OAAOgB,UAAUC,WAOxCC,OAAOrB,UAAUsB,MAAM,WAGF,iBAAVC,OACTC,OAAOC,OAAS,WAAYC,WAAW,WAAY5B,uBAAyB,OAE5EA","file":"cleantalk_external.min.js","sourcesContent":["function ct_protect_external(){\n\t\t\t\n\tfor(i=0;i<document.forms.length;i++){\n\t\t\n\t\tif(typeof(document.forms[i].action)=='string'){\n\t\t\t\n\t\t\taction=document.forms[i].action;\n\t\t\tif(action.indexOf('http://')!=-1||action.indexOf('https://')!=-1){\n\t\t\t\t\n\t\t\t\ttmp=action.split('//');\n\t\t\t\ttmp=tmp[1].split('/');\n\t\t\t\thost=tmp[0].toLowerCase();\n\t\t\t\tif(host!=location.hostname.toLowerCase()){\n\t\t\t\t\t\n\t\t\t\t\tvar ct_action = document.createElement(\"input\");\n\t\t\t\t\tct_action.name='cleantalk_hidden_action';\n\t\t\t\t\tct_action.value=action;\n\t\t\t\t\tct_action.type='hidden';\n\t\t\t\t\tdocument.forms[i].appendChild(ct_action);\n\t\t\t\t\t\n\t\t\t\t\tvar ct_method = document.createElement(\"input\");\n\t\t\t\t\tct_method.name='cleantalk_hidden_method';\n\t\t\t\t\tct_method.value=document.forms[i].method;\n\t\t\t\t\tct_method.type='hidden';\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\tdocument.forms[i].method='POST';\n\t\t\t\t\tdocument.forms[i].appendChild(ct_method);\n\t\t\t\t\t\n\t\t\t\t\tdocument.forms[i].action=ctNocache.blog_home;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\njQuery(document).ready(function(){\n\t\t\t\n\t// Aigle CRM subscription form\n\tif(typeof _agile == 'object'){\n\t\twindow.onload = function(){ setTimeout(function(){ ct_protect_external() }, 1500); };\n\t}else{\n\t\tct_protect_external();\n\t}\n});"]}
1
+ {"version":3,"sources":["cleantalk_external.js"],"names":["ct_protect_external","i","document","forms","length","action","indexOf","tmp","split","host","toLowerCase","location","hostname","ct_action","createElement","name","value","type","appendChild","ct_method","method","ctNocache","blog_home","window","onload","setTimeout"],"mappings":"AAAA,SAASA,sBAER,IAAIC,EAAE,EAAEA,EAAEC,SAASC,MAAMC,OAAOH,IAE/B,GAAqC,iBAA3BC,SAASC,MAAMF,GAAS,SAEjCI,OAAOH,SAASC,MAAMF,GAAGI,SACM,GAA5BA,OAAOC,QAAQ,aAA6C,GAA7BD,OAAOC,QAAQ,eAEhDC,IAAIF,OAAOG,MAAM,MACjBD,IAAIA,IAAI,GAAGC,MAAM,KACjBC,KAAKF,IAAI,GAAGG,cACTD,MAAME,SAASC,SAASF,gBAAc,CAExC,IAAIG,EAAYX,SAASY,cAAc,SACvCD,EAAUE,KAAK,0BACfF,EAAUG,MAAMX,OAChBQ,EAAUI,KAAK,SACff,SAASC,MAAMF,GAAGiB,YAAYL,GAE9B,IAAIM,EAAYjB,SAASY,cAAc,SACvCK,EAAUJ,KAAK,0BACfI,EAAUH,MAAMd,SAASC,MAAMF,GAAGmB,OAClCD,EAAUF,KAAK,SAEff,SAASC,MAAMF,GAAGmB,OAAO,OACzBlB,SAASC,MAAMF,GAAGiB,YAAYC,GAE9BjB,SAASC,MAAMF,GAAGI,OAAOgB,UAAUC,WAOxCC,OAAOC,OAAS,WACZC,WAAW,WACPzB,uBACD","file":"cleantalk_external.min.js","sourcesContent":["function ct_protect_external(){\n\t\t\t\n\tfor(i=0;i<document.forms.length;i++){\n\t\t\n\t\tif(typeof(document.forms[i].action)=='string'){\n\t\t\t\n\t\t\taction=document.forms[i].action;\n\t\t\tif(action.indexOf('http://')!=-1||action.indexOf('https://')!=-1){\n\t\t\t\t\n\t\t\t\ttmp=action.split('//');\n\t\t\t\ttmp=tmp[1].split('/');\n\t\t\t\thost=tmp[0].toLowerCase();\n\t\t\t\tif(host!=location.hostname.toLowerCase()){\n\t\t\t\t\t\n\t\t\t\t\tvar ct_action = document.createElement(\"input\");\n\t\t\t\t\tct_action.name='cleantalk_hidden_action';\n\t\t\t\t\tct_action.value=action;\n\t\t\t\t\tct_action.type='hidden';\n\t\t\t\t\tdocument.forms[i].appendChild(ct_action);\n\t\t\t\t\t\n\t\t\t\t\tvar ct_method = document.createElement(\"input\");\n\t\t\t\t\tct_method.name='cleantalk_hidden_method';\n\t\t\t\t\tct_method.value=document.forms[i].method;\n\t\t\t\t\tct_method.type='hidden';\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\tdocument.forms[i].method='POST';\n\t\t\t\t\tdocument.forms[i].appendChild(ct_method);\n\t\t\t\t\t\n\t\t\t\t\tdocument.forms[i].action=ctNocache.blog_home;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nwindow.onload = function () {\n setTimeout(function () {\n ct_protect_external()\n }, 1500);\n};"]}
lib/Cleantalk.php CHANGED
@@ -424,7 +424,7 @@ class Cleantalk {
424
  $args = array(
425
  'body' => $data,
426
  'timeout' => $server_timeout,
427
- 'user-agent' => CLEANTALK_AGENT.' '.get_bloginfo( 'url' ),
428
  );
429
 
430
  $result = wp_remote_post($url, $args);
424
  $args = array(
425
  'body' => $data,
426
  'timeout' => $server_timeout,
427
+ 'user-agent' => APBCT_AGENT.' '.get_bloginfo( 'url' ),
428
  );
429
 
430
  $result = wp_remote_post($url, $args);
lib/CleantalkAPI.php CHANGED
@@ -1,17 +1,31 @@
1
  <?php
2
 
3
- class CleantalkAPI extends CleantalkAPI_base
4
- {
 
 
 
 
 
 
 
 
 
 
 
 
5
  /**
6
- * Function sends raw request to API server
 
7
  *
8
- * @param string url of API server
9
- * @param array data to send
10
- * @param boolean is data have to be JSON encoded or not
11
- * @param integer connect timeout
12
- * @return type
 
13
  */
14
- static public function send_request($data, $url = self::URL, $timeout = 5, $ssl = false)
15
  {
16
  global $apbct;
17
 
@@ -19,14 +33,14 @@ class CleantalkAPI extends CleantalkAPI_base
19
  $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $url;
20
 
21
  // Adding agent version to data
22
- $data['agent'] = defined('CLEANTALK_AGENT') ? CLEANTALK_AGENT : self::AGENT;
23
 
24
  if($apbct->settings['use_buitin_http_api']){
25
 
26
  $args = array(
27
  'body' => $data,
28
  'timeout' => $timeout,
29
- 'user-agent' => CLEANTALK_AGENT.' '.get_bloginfo( 'url' ),
30
  );
31
 
32
  $result = wp_remote_post($url, $args);
@@ -39,12 +53,15 @@ class CleantalkAPI extends CleantalkAPI_base
39
  }
40
 
41
  // Call CURL version if disabled
42
- }else
43
- $result = parent::send_request($data, $url, $timeout, $ssl);
44
-
45
- if(empty($result) || !empty($errors))
46
- return array('error' => true, 'error_string' => $errors);
47
- else
48
- return $result;
 
 
 
49
  }
50
  }
1
  <?php
2
 
3
+ /**
4
+ * Class CleantalkAPI.
5
+ * Compatible only with Wordpress.
6
+ *
7
+ * @depends CleantalkBase\CleantalkAPI
8
+ *
9
+ * @version 1.0
10
+ * @author Cleantalk team (welcome@cleantalk.org)
11
+ * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
12
+ * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
13
+ * @see https://github.com/CleanTalk/wordpress-antispam
14
+ */
15
+ class CleantalkAPI extends CleantalkBase\CleantalkAPI
16
+ {
17
  /**
18
+ * Function sends raw request to API server.
19
+ * May use built in Wordpress HTTP-API
20
  *
21
+ * @param array Data to send
22
+ * @param string API server URL
23
+ * @param int $timeout
24
+ * @param bool Do we need to use SSL
25
+ *
26
+ * @return array|bool
27
  */
28
+ static public function send_request($data, $url = self::URL, $timeout = 5, $ssl = false, $ssl_path = '')
29
  {
30
  global $apbct;
31
 
33
  $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $url;
34
 
35
  // Adding agent version to data
36
+ $data['agent'] = APBCT_AGENT;
37
 
38
  if($apbct->settings['use_buitin_http_api']){
39
 
40
  $args = array(
41
  'body' => $data,
42
  'timeout' => $timeout,
43
+ 'user-agent' => APBCT_AGENT.' '.get_bloginfo( 'url' ),
44
  );
45
 
46
  $result = wp_remote_post($url, $args);
53
  }
54
 
55
  // Call CURL version if disabled
56
+ }else{
57
+ $ssl_path = $ssl_path
58
+ ? $ssl_path
59
+ : (defined('APBCT_CASERT_PATH') ? APBCT_CASERT_PATH : '');
60
+ $result = parent::send_request($data, $url, $timeout, $ssl, $ssl_path);
61
+ }
62
+
63
+ return empty($result) || !empty($errors)
64
+ ? array('error' => true, 'error' => $errors)
65
+ : $result;
66
  }
67
  }
lib/CleantalkAPI_base.php DELETED
@@ -1,595 +0,0 @@
1
- <?php
2
-
3
- class CleantalkAPI_base
4
- {
5
- const URL = 'https://api.cleantalk.org';
6
- const AGENT = 'apbct-api-2.0';
7
-
8
- /**
9
- * Wrapper for 2s_blacklists_db API method
10
- *
11
- * @param string $api_key
12
- * @param type $out Data output type (JSON or file URL)
13
- * @param boolean $do_check
14
- * @return mixed|string|array('error' => true, 'error_string' => STRING)
15
- * @returns mixed STRING ||
16
- */
17
- static public function method__get_2s_blacklists_db($api_key, $out = null, $do_check = true){
18
-
19
- $request = array(
20
- 'method_name' => '2s_blacklists_db',
21
- 'auth_key' => $api_key,
22
- 'out' => $out,
23
- );
24
-
25
- $result = self::send_request($request);
26
- $result = $do_check ? self::check_response($result, '2s_blacklists_db') : $result;
27
-
28
- return $result;
29
- }
30
-
31
- /**
32
- * Function gets access key automatically
33
- *
34
- * @param string website admin email
35
- * @param string website host
36
- * @param string website platform
37
- * @return type
38
- */
39
- static public function method__get_api_key($email, $website, $platform, $timezone = null, $language = null, $user_ip = null, $wpms = false, $white_label = 0, $hoster_api_key = '', $do_check = true)
40
- {
41
- $request = array(
42
- 'method_name' => 'get_api_key',
43
- 'product_name' => 'antispam',
44
- 'email' => $email,
45
- 'website' => $website,
46
- 'platform' => $platform,
47
- 'timezone' => $timezone,
48
- 'http_accept_language' => $language,
49
- 'user_ip' => $user_ip,
50
- 'wpms_setup' => $wpms,
51
- 'hoster_whitelabel' => $white_label,
52
- 'hoster_api_key' => $hoster_api_key,
53
- );
54
-
55
- $result = self::send_request($request);
56
- $result = $do_check ? self::check_response($result, 'get_api_key') : $result;
57
-
58
- return $result;
59
- }
60
-
61
- /**
62
- * Function gets spam report
63
- *
64
- * @param string website host
65
- * @param integer report days
66
- * @param boolean do_check
67
- * @return type
68
- */
69
- static public function method__get_antispam_report($host, $period = 1, $do_check = true)
70
- {
71
- $request=Array(
72
- 'method_name' => 'get_antispam_report',
73
- 'hostname' => $host,
74
- 'period' => $period
75
- );
76
-
77
- $result = self::send_request($request);
78
- $result = $do_check ? self::check_response($result, 'get_antispam_report') : $result;
79
-
80
- return $result;
81
- }
82
-
83
- /**
84
- * Function gets spam statistics
85
- *
86
- * @param string website host
87
- * @param integer report days
88
- * @return type
89
- */
90
- static public function method__get_antispam_report_breif($api_key, $do_check = true)
91
- {
92
- $request = array(
93
- 'method_name' => 'get_antispam_report_breif',
94
- 'auth_key' => $api_key,
95
- );
96
-
97
- $result = self::send_request($request);
98
- $result = $do_check ? self::check_response($result, 'get_antispam_report_breif') : $result;
99
-
100
- return $result;
101
- }
102
-
103
- /**
104
- * Function gets information about renew notice
105
- *
106
- * @param string api_key API key
107
- * @param string $path_to_cms Path to website
108
- *
109
- * @return type
110
- */
111
- static public function method__notice_paid_till($api_key, $path_to_cms, $do_check = true)
112
- {
113
- $request = array(
114
- 'method_name' => 'notice_paid_till',
115
- 'path_to_cms' => $path_to_cms,
116
- 'auth_key' => $api_key
117
- );
118
-
119
- $result = self::send_request($request);
120
- $result = $do_check ? self::check_response($result, 'notice_paid_till') : $result;
121
-
122
- return $result;
123
- }
124
-
125
- static public function method__ip_info($data, $do_check = true)
126
- {
127
- $request = array(
128
- 'method_name' => 'ip_info',
129
- 'data' => $data
130
- );
131
-
132
- $result = self::send_request($request);
133
- $result = $do_check ? self::check_response($result, 'ip_info') : $result;
134
- return $result;
135
- }
136
-
137
- /**
138
- * Function gets spam report
139
- *
140
- * @param string website host
141
- * @param integer report days
142
- * @return type
143
- */
144
- static public function method__spam_check_cms($api_key, $data, $date = null, $do_check = true)
145
- {
146
- $request=Array(
147
- 'method_name' => 'spam_check_cms',
148
- 'auth_key' => $api_key,
149
- 'data' => is_array($data) ? implode(',',$data) : $data,
150
- );
151
-
152
- if($date) $request['date'] = $date;
153
-
154
- $result = self::send_request($request, self::URL, 10);
155
- $result = $do_check ? self::check_response($result, 'spam_check_cms') : $result;
156
-
157
- return $result;
158
- }
159
-
160
- /**
161
- * Function gets spam report
162
- *
163
- * @param string website host
164
- * @param integer report days
165
- * @return type
166
- */
167
- static public function method__spam_check($api_key, $data, $date = null, $do_check = true)
168
- {
169
- $request=Array(
170
- 'method_name' => 'spam_check',
171
- 'auth_key' => $api_key,
172
- 'data' => is_array($data) ? implode(',',$data) : $data,
173
- );
174
-
175
- if($date) $request['date'] = $date;
176
-
177
- $result = self::send_request($request, self::URL, 10);
178
- $result = $do_check ? self::check_response($result, 'spam_check') : $result;
179
-
180
- return $result;
181
- }
182
-
183
- /**
184
- * Wrapper for sfw_logs API method
185
- * @param integer connect timeout
186
- * @return type
187
- * returns mixed STRING || array('error' => true, 'error_string' => STRING)
188
- */
189
- static public function method__sfw_logs($api_key, $data, $do_check = true){
190
-
191
- $request = array(
192
- 'auth_key' => $api_key,
193
- 'method_name' => 'sfw_logs',
194
- 'data' => json_encode($data),
195
- 'rows' => count($data),
196
- 'timestamp' => time()
197
- );
198
-
199
- $result = self::send_request($request);
200
- $result = $do_check ? self::check_response($result, 'sfw_logs') : $result;
201
-
202
- return $result;
203
- }
204
-
205
- static public function method__security_logs($api_key, $data, $do_check = true)
206
- {
207
- $request = array(
208
- 'auth_key' => $api_key,
209
- 'method_name' => 'security_logs',
210
- 'timestamp' => current_time('timestamp'),
211
- 'data' => json_encode($data),
212
- 'rows' => count($data),
213
- );
214
-
215
- $result = self::send_request($request);
216
- $result = $do_check ? self::check_response($result, 'security_logs') : $result;
217
-
218
- return $result;
219
- }
220
-
221
- static public function method__security_logs__sendFWData($api_key, $data, $do_check = true){
222
-
223
- $request = array(
224
- 'auth_key' => $api_key,
225
- 'method_name' => 'security_logs',
226
- 'timestamp' => current_time('timestamp'),
227
- 'data_fw' => json_encode($data),
228
- 'rows_fw' => count($data),
229
- );
230
-
231
- $result = self::send_request($request);
232
- $result = $do_check ? self::check_response($result, 'security_logs') : $result;
233
-
234
- return $result;
235
- }
236
-
237
- static public function method__security_logs__feedback($api_key, $do_check = true)
238
- {
239
- $request = array(
240
- 'auth_key' => $api_key,
241
- 'method_name' => 'security_logs',
242
- 'data' => '0',
243
- );
244
-
245
- $result = self::send_request($request);
246
- $result = $do_check ? self::check_response($result, 'security_logs') : $result;
247
-
248
- return $result;
249
- }
250
-
251
- static public function method__security_firewall_data($api_key, $do_check = true){
252
-
253
- $request = array(
254
- 'auth_key' => $api_key,
255
- 'method_name' => 'security_firewall_data',
256
- );
257
-
258
- $result = self::send_request($request);
259
- $result = $do_check ? self::check_response($result, 'security_firewall_data') : $result;
260
-
261
- return $result;
262
- }
263
-
264
- static public function method__security_firewall_data_file($api_key, $do_check = true){
265
-
266
- $request = array(
267
- 'auth_key' => $api_key,
268
- 'method_name' => 'security_firewall_data_file',
269
- );
270
-
271
- $result = self::send_request($request);
272
- $result = $do_check ? self::check_response($result, 'security_firewall_data_file') : $result;
273
-
274
- return $result;
275
- }
276
-
277
- static public function method__security_linksscan_logs($api_key, $scan_time, $scan_result, $links_total, $links_list, $do_check = true)
278
- {
279
- $request = array(
280
- 'auth_key' => $api_key,
281
- 'method_name' => 'security_linksscan_logs',
282
- 'started' => $scan_time,
283
- 'result' => $scan_result,
284
- 'total_links_found' => $links_total,
285
- 'links_list' => $links_list,
286
- );
287
-
288
- $result = self::send_request($request);
289
- $result = $do_check ? self::check_response($result, 'security_linksscan_logs') : $result;
290
-
291
- return $result;
292
- }
293
-
294
- static public function method__security_mscan_logs($api_key, $service_id, $scan_time, $scan_result, $scanned_total, $modified, $unknown, $do_check = true)
295
- {
296
- $request = array(
297
- 'method_name' => 'security_mscan_logs',
298
- 'auth_key' => $api_key,
299
- 'service_id' => $service_id,
300
- 'started' => $scan_time,
301
- 'result' => $scan_result,
302
- 'total_core_files' => $scanned_total,
303
- );
304
-
305
- if(!empty($modified)){
306
- $request['failed_files'] = json_encode($modified);
307
- $request['failed_files_rows'] = count($modified);
308
- }
309
- if(!empty($unknown)){
310
- $request['unknown_files'] = json_encode($unknown);
311
- $request['unknown_files_rows'] = count($unknown);
312
- }
313
-
314
- $result = self::send_request($request);
315
- $result = $do_check ? self::check_response($result, 'security_mscan_logs') : $result;
316
-
317
- return $result;
318
- }
319
-
320
- static public function method__security_mscan_files($api_key, $file_path, $file, $file_md5, $weak_spots, $do_check = true)
321
- {
322
- $request = array(
323
- 'method_name' => 'security_mscan_files',
324
- 'auth_key' => $api_key,
325
- 'path_to_sfile' => $file_path,
326
- 'attached_sfile' => $file,
327
- 'md5sum_sfile' => $file_md5,
328
- 'dangerous_code' => $weak_spots,
329
- );
330
-
331
- $result = self::send_request($request);
332
- $result = $do_check ? self::check_response($result, 'security_mscan_files') : $result;
333
-
334
- return $result;
335
- }
336
-
337
- /**
338
- * Function gets spam domains report
339
- *
340
- * @param string $api_key
341
- * @param array|string|mixed $data
342
- * @param string $date
343
- * @param bool do_check
344
- *
345
- * @return array|bool|mixed
346
- */
347
- static public function method__backlinks_check_cms($api_key, $data, $date = null, $do_check = true)
348
- {
349
- $request = array(
350
- 'method_name' => 'backlinks_check_cms',
351
- 'auth_key' => $api_key,
352
- 'data' => is_array($data) ? implode(',',$data) : $data,
353
- );
354
-
355
- if($date) $request['date'] = $date;
356
-
357
- $result = self::send_request($request);
358
- $result = $do_check ? self::check_response($result, 'backlinks_check_cms') : $result;
359
-
360
- return $result;
361
- }
362
-
363
- /**
364
- * Function gets spam domains report
365
- *
366
- * @param string api_key
367
- * @param array logs
368
- * @param bool do_check
369
- * @return array|bool|mixed
370
- */
371
- static public function method__security_backend_logs($api_key, $logs, $do_check = true)
372
- {
373
- $request = array(
374
- 'method_name' => 'security_backend_logs',
375
- 'auth_key' => $api_key,
376
- 'logs' => json_encode($logs),
377
- 'total_logs' => count($logs),
378
- );
379
-
380
- $result = self::send_request($request);
381
- $result = $do_check ? self::check_response($result, 'security_backend_logs') : $result;
382
-
383
- return $result;
384
- }
385
-
386
- /**
387
- * Sends data about auto repairs
388
- *
389
- * @param string $api_key
390
- * @param $repair_result
391
- * @param $repair_comment
392
- * @param $repaired_processed_files
393
- * @param $repaired_total_files_proccessed
394
- * @param $backup_id
395
- * @param bool $do_check
396
- *
397
- * @return array|bool|mixed
398
- */
399
- static public function method__security_mscan_repairs($api_key, $repair_result, $repair_comment, $repaired_processed_files, $repaired_total_files_proccessed, $backup_id, $do_check = true)
400
- {
401
- $request = array(
402
- 'method_name' => 'security_mscan_repairs',
403
- 'auth_key' => $api_key,
404
- 'repair_result' => $repair_result,
405
- 'repair_comment' => $repair_comment,
406
- 'repair_proccessed_files' => json_encode($repaired_processed_files),
407
- 'repair_total_files_proccessed' => $repaired_total_files_proccessed,
408
- 'backup_id' => $backup_id
409
- );
410
-
411
- $result = self::send_request($request);
412
- $result = $do_check ? self::check_response($result, 'security_mscan_repairs') : $result;
413
-
414
- return $result;
415
- }
416
-
417
- /**
418
- * Force server to update checksums for specific plugin\theme
419
- *
420
- * @param string $api_key
421
- * @param string $plugins_and_themes_to_refresh
422
- * @param bool $do_check
423
- *
424
- * @return array|bool|mixed
425
- */
426
- static public function method__request_checksums($api_key, $plugins_and_themes_to_refresh, $do_check = true)
427
- {
428
- $request = array(
429
- 'method_name' => 'request_checksums',
430
- 'auth_key' => $api_key,
431
- 'data' => $plugins_and_themes_to_refresh
432
- );
433
-
434
- $result = self::send_request($request);
435
- $result = $do_check ? self::check_response($result, 'request_checksums') : $result;
436
-
437
- return $result;
438
- }
439
-
440
- /**
441
- * Function sends raw request to API server
442
- *
443
- * @param array $data to send
444
- * @param string $url of API server
445
- * @param integer $timeout timeout in seconds
446
- * @param boolean $ssl use ssl on not
447
- * @return array|bool
448
- */
449
- static public function send_request($data, $url = self::URL, $timeout = 5, $ssl = false)
450
- {
451
- // Possibility to switch API url
452
- $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $url;
453
-
454
- // Adding agent version to data
455
- $data['agent'] = defined('CLEANTALK_AGENT') ? CLEANTALK_AGENT : self::AGENT;
456
-
457
- // Make URL string
458
- $data_string = http_build_query($data);
459
- $data_string = str_replace("&amp;", "&", $data_string);
460
-
461
- // For debug purposes
462
- if(defined('CLEANTALK_DEBUG') && CLEANTALK_DEBUG){
463
- global $apbct_debug;
464
- $apbct_debug['sent_data'] = $data;
465
- $apbct_debug['request_string'] = $data_string;
466
- }
467
-
468
- if (function_exists('curl_init')){
469
-
470
- $ch = curl_init();
471
-
472
- // Set diff options
473
- curl_setopt($ch, CURLOPT_URL, $url);
474
- curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
475
- curl_setopt($ch, CURLOPT_POST, true);
476
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
477
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
478
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
479
-
480
- // Switch on/off SSL
481
- if ($ssl === true) {
482
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
483
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
484
- curl_setopt($ch, CURLOPT_CAINFO, APBCT_CASERT_PATH);
485
- }else{
486
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
487
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
488
- }
489
-
490
- // Make a request
491
- $result = curl_exec($ch);
492
- $errors = curl_error($ch);
493
- curl_close($ch);
494
-
495
- // Retry with SSL enabled if failed
496
- if($result === false)
497
- if($ssl === false)
498
- return self::send_request($data, $url, $timeout, true);
499
-
500
- }else
501
- $errors = 'CURL_NOT_INSTALLED';
502
-
503
- // Trying to use file_get_contents() to make a API call
504
- if(!empty($errors)){
505
- if(ini_get('allow_url_fopen')){
506
- $opts = array(
507
- 'http'=>array(
508
- 'method' => "POST",
509
- 'timeout' => $timeout,
510
- 'content' => $data_string,
511
- )
512
- );
513
- $context = stream_context_create($opts);
514
- $result = @file_get_contents($url, 0, $context);
515
-
516
- $errors = $result === false
517
- ? $errors . '_FAILED_TO_USE_FILE_GET_CONTENTS'
518
- : false;
519
-
520
- }else
521
- $errors .= '_AND_ALLOW_URL_FOPEN_IS_DISABLED';
522
- }
523
-
524
- if(empty($result) || !empty($errors))
525
- return array('error' => true, 'error_string' => $errors);
526
- else
527
- return $result;
528
- }
529
-
530
- /**
531
- * Function checks server response
532
- *
533
- * @param string $result
534
- * @param string $method_name
535
- * @return mixed (array || array('error' => true))
536
- */
537
- static public function check_response($result, $method_name = null)
538
- {
539
- // Errors handling
540
- // Bad connection
541
- if(is_array($result) && isset($result['error'])){
542
- return array(
543
- 'error' => true,
544
- 'error_string' => 'CONNECTION_ERROR: ' . (isset($result['error_string']) ? ' '.$result['error_string'] : ''),
545
- );
546
- }
547
-
548
- // JSON decode errors
549
- $result = json_decode($result, true);
550
- if(empty($result)){
551
- return array(
552
- 'error' => true,
553
- 'error_string' => 'JSON_DECODE_ERROR'
554
- );
555
- }
556
-
557
- // Server errors
558
- if($result && (isset($result['error_no']) || isset($result['error_message']))){
559
- return array(
560
- 'error' => true,
561
- 'error_string' => "SERVER_ERROR NO: {$result['error_no']} MSG: {$result['error_message']}",
562
- 'error_no' => $result['error_no'],
563
- 'error_message' => $result['error_message']
564
- );
565
- }
566
-
567
- // Pathces for different methods
568
- switch ($method_name) {
569
-
570
- // get_antispam_report_breif
571
- case 'get_antispam_report_breif':
572
-
573
- $out = isset($result['data']) && is_array($result['data'])
574
- ? $result['data']
575
- : array('error' => true, 'error_string' => 'NO_DATA');
576
-
577
- for($tmp = array(), $i = 0; $i < 7; $i++){
578
- $tmp[date('Y-m-d', time() - 86400 * 7 + 86400 * $i)] = 0;
579
- }
580
- $out['spam_stat'] = (array) array_merge( $tmp, isset($out['spam_stat']) ? $out['spam_stat'] : array() );
581
- $out['top5_spam_ip'] = isset($out['top5_spam_ip']) ? $out['top5_spam_ip'] : array();
582
-
583
- break;
584
-
585
- default:
586
- $out = isset($result['data']) && is_array($result['data'])
587
- ? $result['data']
588
- : array('error' => true, 'error_string' => 'NO_DATA');
589
- break;
590
- }
591
-
592
- return $out;
593
-
594
- }
595
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/CleantalkBase/CleantalkAPI.php ADDED
@@ -0,0 +1,777 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CleantalkBase;
4
+
5
+ if(!class_exists('CleantalkBase\CleantalkAPI'))
6
+ {
7
+ /**
8
+ * CleanTalk API class.
9
+ * Mostly contains wrappers for API methods. Check and send mehods.
10
+ * Compatible with any CMS.
11
+ *
12
+ * @version 3.2
13
+ * @author Cleantalk team (welcome@cleantalk.org)
14
+ * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
15
+ * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
16
+ * @see https://github.com/CleanTalk/php-antispam
17
+ */
18
+ class CleantalkAPI
19
+ {
20
+ /* Default params */
21
+ const URL = 'https://api.cleantalk.org';
22
+ const AGENT = 'ct-api-3.2';
23
+
24
+ /**
25
+ * Wrapper for 2s_blacklists_db API method.
26
+ * Gets data for SpamFireWall.
27
+ *
28
+ * @param string $api_key
29
+ * @param null|string $out Data output type (JSON or file URL)
30
+ * @param boolean $do_check
31
+ *
32
+ * @return mixed|string|array('error' => STRING)
33
+ */
34
+ static public function method__get_2s_blacklists_db($api_key, $out = null, $do_check = true)
35
+ {
36
+ $request = array(
37
+ 'method_name' => '2s_blacklists_db',
38
+ 'auth_key' => $api_key,
39
+ 'out' => $out,
40
+ );
41
+
42
+ $result = static::send_request($request);
43
+ $result = $do_check ? static::check_response($result, '2s_blacklists_db') : $result;
44
+
45
+ return $result;
46
+ }
47
+
48
+ /**
49
+ * Wrapper for get_api_key API method.
50
+ * Gets access key automatically.
51
+ *
52
+ * @param string $product_name Type of product
53
+ * @param string $email Website admin email
54
+ * @param string $website Website host
55
+ * @param string $platform Website platform
56
+ * @param string|null $timezone
57
+ * @param string|null $language
58
+ * @param string|null $user_ip
59
+ * @param bool $wpms
60
+ * @param bool $white_label
61
+ * @param string $hoster_api_key
62
+ * @param bool $do_check
63
+ *
64
+ * @return array|bool|mixed
65
+ */
66
+ static public function method__get_api_key($product_name, $email, $website, $platform, $timezone = null, $language = null, $user_ip = null, $wpms = false, $white_label = false, $hoster_api_key = '', $do_check = true)
67
+ {
68
+ $request = array(
69
+ 'method_name' => 'get_api_key',
70
+ 'product_name' => $product_name,
71
+ 'email' => $email,
72
+ 'website' => $website,
73
+ 'platform' => $platform,
74
+ 'timezone' => $timezone,
75
+ 'http_accept_language' => $language,
76
+ 'user_ip' => $user_ip,
77
+ 'wpms_setup' => $wpms,
78
+ 'hoster_whitelabel' => $white_label,
79
+ 'hoster_api_key' => $hoster_api_key,
80
+ );
81
+
82
+ $result = static::send_request($request);
83
+ $result = $do_check ? static::check_response($result, 'get_api_key') : $result;
84
+
85
+ return $result;
86
+ }
87
+
88
+ /**
89
+ * Wrapper for get_antispam_report API method.
90
+ * Gets spam report.
91
+ *
92
+ * @param string $host website host
93
+ * @param integer $period report days
94
+ * @param boolean $do_check
95
+ *
96
+ * @return array|bool|mixed
97
+ */
98
+ static public function method__get_antispam_report($host, $period = 1, $do_check = true)
99
+ {
100
+ $request = Array(
101
+ 'method_name' => 'get_antispam_report',
102
+ 'hostname' => $host,
103
+ 'period' => $period
104
+ );
105
+
106
+ $result = static::send_request($request);
107
+ $result = $do_check ? static::check_response($result, 'get_antispam_report') : $result;
108
+
109
+ return $result;
110
+ }
111
+
112
+ /**
113
+ * Wrapper for get_antispam_report_breif API method.
114
+ * Ggets spam statistics.
115
+ *
116
+ * @param string $api_key
117
+ * @param bool $do_check
118
+ *
119
+ * @return array|bool|mixed
120
+ */
121
+ static public function method__get_antispam_report_breif($api_key, $do_check = true)
122
+ {
123
+ $request = array(
124
+ 'method_name' => 'get_antispam_report_breif',
125
+ 'auth_key' => $api_key,
126
+ );
127
+
128
+ $result = static::send_request($request);
129
+ $result = $do_check ? static::check_response($result, 'get_antispam_report_breif') : $result;
130
+
131
+ return $result;
132
+ }
133
+
134
+ /**
135
+ * Wrapper for notice_paid_till API method.
136
+ * Gets information about renew notice.
137
+ *
138
+ * @param string $api_key API key
139
+ * @param string $path_to_cms Website URL
140
+ * @param bool $do_check
141
+ *
142
+ * @return array|bool|mixed
143
+ */
144
+ static public function method__notice_paid_till($api_key, $path_to_cms, $do_check = true)
145
+ {
146
+ $request = array(
147
+ 'method_name' => 'notice_paid_till',
148
+ 'path_to_cms' => $path_to_cms,
149
+ 'auth_key' => $api_key
150
+ );
151
+
152
+ $result = static::send_request($request);
153
+ $result = $do_check ? static::check_response($result, 'notice_paid_till') : $result;
154
+
155
+ return $result;
156
+ }
157
+
158
+ /**
159
+ * Wrapper for ip_info API method.
160
+ * Gets IP country.
161
+ *
162
+ * @param string $data
163
+ * @param bool $do_check
164
+ *
165
+ * @return array|bool|mixed
166
+ */
167
+ static public function method__ip_info($data, $do_check = true)
168
+ {
169
+ $request = array(
170
+ 'method_name' => 'ip_info',
171
+ 'data' => $data
172
+ );
173
+
174
+ $result = static::send_request($request);
175
+ $result = $do_check ? static::check_response($result, 'ip_info') : $result;
176
+ return $result;
177
+ }
178
+
179
+ /**
180
+ * Wrapper for spam_check_cms API method.
181
+ * Checks IP|email via CleanTalk's database.
182
+ *
183
+ * @param string $api_key
184
+ * @param array $data
185
+ * @param null|string $date
186
+ * @param bool $do_check
187
+ *
188
+ * @return array|bool|mixed
189
+ */
190
+ static public function method__spam_check_cms($api_key, $data, $date = null, $do_check = true)
191
+ {
192
+ $request = Array(
193
+ 'method_name' => 'spam_check_cms',
194
+ 'auth_key' => $api_key,
195
+ 'data' => is_array($data) ? implode(',', $data) : $data,
196
+ );
197
+
198
+ if($date) $request['date'] = $date;
199
+
200
+ $result = static::send_request($request, self::URL, 10);
201
+ $result = $do_check ? static::check_response($result, 'spam_check_cms') : $result;
202
+
203
+ return $result;
204
+ }
205
+
206
+ /**
207
+ * Wrapper for spam_check API method.
208
+ * Checks IP|email via CleanTalk's database.
209
+ *
210
+ * @param string $api_key
211
+ * @param array $data
212
+ * @param null|string $date
213
+ * @param bool $do_check
214
+ *
215
+ * @return array|bool|mixed
216
+ */
217
+ static public function method__spam_check($api_key, $data, $date = null, $do_check = true)
218
+ {
219
+ $request = Array(
220
+ 'method_name' => 'spam_check',
221
+ 'auth_key' => $api_key,
222
+ 'data' => is_array($data) ? implode(',', $data) : $data,
223
+ );
224
+
225
+ if($date) $request['date'] = $date;
226
+
227
+ $result = static::send_request($request, self::URL, 10);
228
+ $result = $do_check ? static::check_response($result, 'spam_check') : $result;
229
+
230
+ return $result;
231
+ }
232
+
233
+ /**
234
+ * Wrapper for sfw_logs API method.
235
+ * Sends SpamFireWall logs to the cloud.
236
+ *
237
+ * @param string $api_key
238
+ * @param array $data
239
+ * @param bool $do_check
240
+ *
241
+ * @return array|bool|mixed
242
+ */
243
+ static public function method__sfw_logs($api_key, $data, $do_check = true)
244
+ {
245
+
246
+ $request = array(
247
+ 'auth_key' => $api_key,
248
+ 'method_name' => 'sfw_logs',
249
+ 'data' => json_encode($data),
250
+ 'rows' => count($data),
251
+ 'timestamp' => time()
252
+ );
253
+
254
+ $result = static::send_request($request);
255
+ $result = $do_check ? static::check_response($result, 'sfw_logs') : $result;
256
+
257
+ return $result;
258
+ }
259
+
260
+ /**
261
+ * Wrapper for security_logs API method.
262
+ * Sends security logs to the cloud.
263
+ *
264
+ * @param string $api_key
265
+ * @param array $data
266
+ * @param bool $do_check
267
+ *
268
+ * @return array|bool|mixed
269
+ */
270
+ static public function method__security_logs($api_key, $data, $do_check = true)
271
+ {
272
+ $request = array(
273
+ 'auth_key' => $api_key,
274
+ 'method_name' => 'security_logs',
275
+ 'timestamp' => current_time('timestamp'),
276
+ 'data' => json_encode($data),
277
+ 'rows' => count($data),
278
+ );
279
+
280
+ $result = static::send_request($request);
281
+ $result = $do_check ? static::check_response($result, 'security_logs') : $result;
282
+
283
+ return $result;
284
+ }
285
+
286
+ /**
287
+ * Wrapper for security_logs API method.
288
+ * Sends Securitty Firewall logs to the cloud.
289
+ *
290
+ * @param string $api_key
291
+ * @param array $data
292
+ * @param bool $do_check
293
+ *
294
+ * @return array|bool|mixed
295
+ */
296
+ static public function method__security_logs__sendFWData($api_key, $data, $do_check = true)
297
+ {
298
+
299
+ $request = array(
300
+ 'auth_key' => $api_key,
301
+ 'method_name' => 'security_logs',
302
+ 'timestamp' => current_time('timestamp'),
303
+ 'data_fw' => json_encode($data),
304
+ 'rows_fw' => count($data),
305
+ );
306
+
307
+ $result = static::send_request($request);
308
+ $result = $do_check ? static::check_response($result, 'security_logs') : $result;
309
+
310
+ return $result;
311
+ }
312
+
313
+ /**
314
+ * Wrapper for security_logs API method.
315
+ * Sends empty data to the cloud to syncronize version.
316
+ *
317
+ * @param string $api_key
318
+ * @param bool $do_check
319
+ *
320
+ * @return array|bool|mixed
321
+ */
322
+ static public function method__security_logs__feedback($api_key, $do_check = true)
323
+ {
324
+ $request = array(
325
+ 'auth_key' => $api_key,
326
+ 'method_name' => 'security_logs',
327
+ 'data' => '0',
328
+ );
329
+
330
+ $result = static::send_request($request);
331
+ $result = $do_check ? static::check_response($result, 'security_logs') : $result;
332
+
333
+ return $result;
334
+ }
335
+
336
+ /**
337
+ * Wrapper for security_firewall_data API method.
338
+ * Gets Securitty Firewall data to write to the local database.
339
+ *
340
+ * @param string $api_key
341
+ * @param bool $do_check
342
+ *
343
+ * @return array|bool|mixed
344
+ */
345
+ static public function method__security_firewall_data($api_key, $do_check = true)
346
+ {
347
+
348
+ $request = array(
349
+ 'auth_key' => $api_key,
350
+ 'method_name' => 'security_firewall_data',
351
+ );
352
+
353
+ $result = static::send_request($request);
354
+ $result = $do_check ? static::check_response($result, 'security_firewall_data') : $result;
355
+
356
+ return $result;
357
+ }
358
+
359
+ /**
360
+ * Wrapper for security_firewall_data_file API method.
361
+ * Gets URI with security firewall data in .csv.gz file to write to the local database.
362
+ *
363
+ * @param string $api_key
364
+ * @param bool $do_check
365
+ *
366
+ * @return array|bool|mixed
367
+ */
368
+ static public function method__security_firewall_data_file($api_key, $do_check = true)
369
+ {
370
+
371
+ $request = array(
372
+ 'auth_key' => $api_key,
373
+ 'method_name' => 'security_firewall_data_file',
374
+ );
375
+
376
+ $result = static::send_request($request);
377
+ $result = $do_check ? static::check_response($result, 'security_firewall_data_file') : $result;
378
+
379
+ return $result;
380
+ }
381
+
382
+ /**
383
+ * Wrapper for security_linksscan_logs API method.
384
+ * Send data to the cloud about scanned links.
385
+ *
386
+ * @param string $api_key
387
+ * @param string $scan_time Datetime of scan
388
+ * @param bool $scan_result
389
+ * @param int $links_total
390
+ * @param array $links_list
391
+ * @param bool $do_check
392
+ *
393
+ * @return array|bool|mixed
394
+ */
395
+ static public function method__security_linksscan_logs($api_key, $scan_time, $scan_result, $links_total, $links_list, $do_check = true)
396
+ {
397
+ $request = array(
398
+ 'auth_key' => $api_key,
399
+ 'method_name' => 'security_linksscan_logs',
400
+ 'started' => $scan_time,
401
+ 'result' => $scan_result,
402
+ 'total_links_found' => $links_total,
403
+ 'links_list' => $links_list,
404
+ );
405
+
406
+ $result = static::send_request($request);
407
+ $result = $do_check ? static::check_response($result, 'security_linksscan_logs') : $result;
408
+
409
+ return $result;
410
+ }
411
+
412
+ /**
413
+ * Wrapper for security_mscan_logs API method.
414
+ * Sends result of file scan to the cloud.
415
+ *
416
+ * @param string $api_key
417
+ * @param int $service_id
418
+ * @param string $scan_time Datetime of scan
419
+ * @param bool $scan_result
420
+ * @param int $scanned_total
421
+ * @param array $modified List of modified files with details
422
+ * @param array $unknown List of modified files with details
423
+ * @param bool $do_check
424
+ *
425
+ * @return array|bool|mixed
426
+ */
427
+ static public function method__security_mscan_logs($api_key, $service_id, $scan_time, $scan_result, $scanned_total, $modified, $unknown, $do_check = true)
428
+ {
429
+ $request = array(
430
+ 'method_name' => 'security_mscan_logs',
431
+ 'auth_key' => $api_key,
432
+ 'service_id' => $service_id,
433
+ 'started' => $scan_time,
434
+ 'result' => $scan_result,
435
+ 'total_core_files' => $scanned_total,
436
+ );
437
+
438
+ if(!empty($modified)){
439
+ $request['failed_files'] = json_encode($modified);
440
+ $request['failed_files_rows'] = count($modified);
441
+ }
442
+ if(!empty($unknown)){
443
+ $request['unknown_files'] = json_encode($unknown);
444
+ $request['unknown_files_rows'] = count($unknown);
445
+ }
446
+
447
+ $result = static::send_request($request);
448
+ $result = $do_check ? static::check_response($result, 'security_mscan_logs') : $result;
449
+
450
+ return $result;
451
+ }
452
+
453
+ /**
454
+ * Wrapper for security_mscan_files API method.
455
+ * Sends file to the cloud for analysis.
456
+ *
457
+ * @param string $api_key
458
+ * @param string $file_path Path to the file
459
+ * @param array $file File itself
460
+ * @param string $file_md5 MD5 hash of file
461
+ * @param array $weak_spots List of weak spots found in file
462
+ * @param bool $do_check
463
+ *
464
+ * @return array|bool|mixed
465
+ */
466
+ static public function method__security_mscan_files($api_key, $file_path, $file, $file_md5, $weak_spots, $do_check = true)
467
+ {
468
+ $request = array(
469
+ 'method_name' => 'security_mscan_files',
470
+ 'auth_key' => $api_key,
471
+ 'path_to_sfile' => $file_path,
472
+ 'attached_sfile' => $file,
473
+ 'md5sum_sfile' => $file_md5,
474
+ 'dangerous_code' => $weak_spots,
475
+ );
476
+
477
+ $result = static::send_request($request);
478
+ $result = $do_check ? static::check_response($result, 'security_mscan_files') : $result;
479
+
480
+ return $result;
481
+ }
482
+
483
+ /**
484
+ * Wrapper for get_antispam_report API method.
485
+ * Function gets spam domains report.
486
+ *
487
+ * @param string $api_key
488
+ * @param array|string|mixed $data
489
+ * @param string $date
490
+ * @param bool $do_check
491
+ *
492
+ * @return array|bool|mixed
493
+ */
494
+ static public function method__backlinks_check_cms($api_key, $data, $date = null, $do_check = true)
495
+ {
496
+ $request = array(
497
+ 'method_name' => 'backlinks_check_cms',
498
+ 'auth_key' => $api_key,
499
+ 'data' => is_array($data) ? implode(',', $data) : $data,
500
+ );
501
+
502
+ if($date) $request['date'] = $date;
503
+
504
+ $result = static::send_request($request);
505
+ $result = $do_check ? static::check_response($result, 'backlinks_check_cms') : $result;
506
+
507
+ return $result;
508
+ }
509
+
510
+ /**
511
+ * Wrapper for get_antispam_report API method.
512
+ * Function gets spam domains report
513
+ *
514
+ * @param string $api_key
515
+ * @param array $logs
516
+ * @param bool $do_check
517
+ *
518
+ * @return array|bool|mixed
519
+ */
520
+ static public function method__security_backend_logs($api_key, $logs, $do_check = true)
521
+ {
522
+ $request = array(
523
+ 'method_name' => 'security_backend_logs',
524
+ 'auth_key' => $api_key,
525
+ 'logs' => json_encode($logs),
526
+ 'total_logs' => count($logs),
527
+ );
528
+
529
+ $result = static::send_request($request);
530
+ $result = $do_check ? static::check_response($result, 'security_backend_logs') : $result;
531
+
532
+ return $result;
533
+ }
534
+
535
+ /**
536
+ * Wrapper for get_antispam_report API method.
537
+ * Sends data about auto repairs
538
+ *
539
+ * @param string $api_key
540
+ * @param bool $repair_result
541
+ * @param string $repair_comment
542
+ * @param $repaired_processed_files
543
+ * @param $repaired_total_files_proccessed
544
+ * @param $backup_id
545
+ * @param bool $do_check
546
+ *
547
+ * @return array|bool|mixed
548
+ */
549
+ static public function method__security_mscan_repairs($api_key, $repair_result, $repair_comment, $repaired_processed_files, $repaired_total_files_proccessed, $backup_id, $do_check = true)
550
+ {
551
+ $request = array(
552
+ 'method_name' => 'security_mscan_repairs',
553
+ 'auth_key' => $api_key,
554
+ 'repair_result' => $repair_result,
555
+ 'repair_comment' => $repair_comment,
556
+ 'repair_processed_files' => json_encode($repaired_processed_files),
557
+ 'repair_total_files_processed' => $repaired_total_files_proccessed,
558
+ 'backup_id' => $backup_id,
559
+ 'mscan_log_id' => 1,
560
+ );
561
+
562
+ $result = static::send_request($request);
563
+ $result = $do_check ? static::check_response($result, 'security_mscan_repairs') : $result;
564
+
565
+ return $result;
566
+ }
567
+
568
+ /**
569
+ * Wrapper for get_antispam_report API method.
570
+ * Force server to update checksums for specific plugin\theme
571
+ *
572
+ * @param string $api_key
573
+ * @param string $plugins_and_themes_to_refresh
574
+ * @param bool $do_check
575
+ *
576
+ * @return array|bool|mixed
577
+ */
578
+ static public function method__request_checksums($api_key, $plugins_and_themes_to_refresh, $do_check = true)
579
+ {
580
+ $request = array(
581
+ 'method_name' => 'request_checksums',
582
+ 'auth_key' => $api_key,
583
+ 'data' => $plugins_and_themes_to_refresh
584
+ );
585
+
586
+ $result = static::send_request($request);
587
+ $result = $do_check ? static::check_response($result, 'request_checksums') : $result;
588
+
589
+ return $result;
590
+ }
591
+
592
+ /**
593
+ * Function sends raw request to API server
594
+ *
595
+ * @param array $data to send
596
+ * @param string $url of API server
597
+ * @param integer $timeout timeout in seconds
598
+ * @param boolean $ssl use ssl on not
599
+ *
600
+ * @return array|bool
601
+ */
602
+ static public function send_request($data, $url = self::URL, $timeout = 5, $ssl = false, $ssl_path = '')
603
+ {
604
+ // Possibility to switch agent vaersion
605
+ $data['agent'] = !empty($data['agent'])
606
+ ? $data['agent']
607
+ : (defined('CLEANTALK_AGENT') ? CLEANTALK_AGENT : self::AGENT);
608
+
609
+ // Make URL string
610
+ $data_string = http_build_query($data);
611
+ $data_string = str_replace("&amp;", "&", $data_string);
612
+
613
+ // For debug purposes
614
+ if(defined('CLEANTALK_DEBUG') && CLEANTALK_DEBUG){
615
+ global $apbct_debug;
616
+ $apbct_debug['sent_data'] = $data;
617
+ $apbct_debug['request_string'] = $data_string;
618
+ }
619
+
620
+ // Possibility to switch API url
621
+ $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $url;
622
+
623
+ if(function_exists('curl_init')){
624
+
625
+ $ch = curl_init();
626
+
627
+ // Set diff options
628
+ curl_setopt($ch, CURLOPT_URL, $url);
629
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
630
+ curl_setopt($ch, CURLOPT_POST, true);
631
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
632
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
633
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
634
+
635
+ $ssl_path = $ssl_path
636
+ ? $ssl_path
637
+ : (defined('CLEANTALK_CASERT_PATH') ? CLEANTALK_CASERT_PATH : '');
638
+
639
+ // Switch on/off SSL
640
+ if($ssl && $ssl_path){
641
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
642
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
643
+ curl_setopt($ch, CURLOPT_CAINFO, $ssl_path);
644
+ }else{
645
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
646
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
647
+ }
648
+
649
+ // Make a request
650
+ $result = curl_exec($ch);
651
+ $errors = curl_error($ch);
652
+ curl_close($ch);
653
+
654
+ // Retry with SSL enabled if failed
655
+ if($result === false){
656
+ if($ssl === false){
657
+ return self::send_request($data, $url, $timeout, true, $ssl_path);
658
+ }
659
+ }
660
+
661
+ }else{
662
+ $errors = 'CURL_NOT_INSTALLED';
663
+ }
664
+
665
+ // Trying to use file_get_contents() to make a API call
666
+ if(!empty($errors)){
667
+ if(ini_get('allow_url_fopen')){
668
+ $opts = array(
669
+ 'http' => array(
670
+ 'method' => "POST",
671
+ 'timeout' => $timeout,
672
+ 'content' => $data_string,
673
+ ),
674
+ );
675
+ $context = stream_context_create($opts);
676
+ $result = @file_get_contents($url, 0, $context);
677
+
678
+ $errors = $result === false
679
+ ? $errors . '_FAILED_TO_USE_FILE_GET_CONTENTS'
680
+ : false;
681
+
682
+ }else{
683
+ $errors .= '_AND_ALLOW_URL_FOPEN_IS_DISABLED';
684
+ }
685
+ }
686
+
687
+ return empty($result) || !empty($errors)
688
+ ? array('error' => $errors)
689
+ : $result;
690
+ }
691
+
692
+ /**
693
+ * Function checks server response
694
+ *
695
+ * @param string $result
696
+ * @param string $method_name
697
+ *
698
+ * @return mixed (array || array('error' => true))
699
+ */
700
+ static public function check_response($result, $method_name = null)
701
+ {
702
+ // Errors handling
703
+ // Bad connection
704
+ if(is_array($result) && isset($result['error'])){
705
+ return array(
706
+ 'error' => 'CONNECTION_ERROR: ' . (isset($result['error']) ? ' ' . $result['error'] : ''),
707
+ );
708
+ }
709
+
710
+ // JSON decode errors
711
+ $result = json_decode($result, true);
712
+ if(empty($result)){
713
+ return array(
714
+ 'error' => 'JSON_DECODE_ERROR',
715
+ );
716
+ }
717
+
718
+ // Server errors
719
+ if($result &&
720
+ (isset($result['error_no']) || isset($result['error_message'])) &&
721
+ (isset($result['error_no']) && $result['error_no'] != 12)
722
+ ){
723
+ return array(
724
+ 'error' => "SERVER_ERROR NO: {$result['error_no']} MSG: {$result['error_message']}",
725
+ 'error_no' => $result['error_no'],
726
+ 'error_message' => $result['error_message'],
727
+ );
728
+ }
729
+
730
+ // Pathces for different methods
731
+ switch($method_name){
732
+
733
+ // notice_paid_till
734
+ case 'notice_paid_till':
735
+ if(
736
+ (isset($result['error_no']) && $result['error_no'] == 12) ||
737
+ (empty($result['error']) && empty($result['data']['service_id'])) ||
738
+ (empty($result['error']) && isset($result['data']['service_id']) && !is_int($result['data']['service_id']))
739
+ ){
740
+ $out = array(
741
+ 'valid' => 0,
742
+ );
743
+ }else{
744
+ $out = $result['data'];
745
+ $out['valid'] = 1;
746
+ }
747
+
748
+ return $out;
749
+
750
+ break;
751
+
752
+ // get_antispam_report_breif
753
+ case 'get_antispam_report_breif':
754
+
755
+ $out = isset($result['data']) && is_array($result['data'])
756
+ ? $result['data']
757
+ : array('error' => 'NO_DATA');
758
+
759
+ for($tmp = array(), $i = 0; $i < 7; $i++){
760
+ $tmp[date('Y-m-d', time() - 86400 * 7 + 86400 * $i)] = 0;
761
+ }
762
+ $out['spam_stat'] = (array)array_merge($tmp, isset($out['spam_stat']) ? $out['spam_stat'] : array());
763
+ $out['top5_spam_ip'] = isset($out['top5_spam_ip']) ? $out['top5_spam_ip'] : array();
764
+
765
+ return $out;
766
+
767
+ break;
768
+
769
+ default:
770
+ return isset($result['data']) && is_array($result['data'])
771
+ ? $result['data']
772
+ : array('error' => 'NO_DATA');
773
+ break;
774
+ }
775
+ }
776
+ }
777
+ }
lib/CleantalkBase/CleantalkDB.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CleantalkBase;
4
+
5
+ /**
6
+ * CleanTalk abstract Data Base driver.
7
+ * Shows what should be inside.
8
+ * Uses singleton pattern.
9
+ *
10
+ * @version 1.0
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
+ * @see https://github.com/CleanTalk/php-antispam
15
+ */
16
+
17
+ class CleantalkDB
18
+ {
19
+
20
+ private static $instances = [];
21
+
22
+ /**
23
+ * @var string Query string
24
+ */
25
+ private $query;
26
+
27
+ /**
28
+ * @var wpdb result
29
+ */
30
+ private $db_result;
31
+
32
+ /**
33
+ * @var array Processed result
34
+ */
35
+ public $result = array();
36
+
37
+ /**
38
+ * @var string Database prefix
39
+ */
40
+ public $prefix = '';
41
+
42
+ public function __construct() { }
43
+ public function __clone() { }
44
+ public function __wakeup() { }
45
+
46
+ public static function getInstance()
47
+ {
48
+ $cls = static::class;
49
+ if (!isset(static::$instances[$cls])) {
50
+ $instance = new static;
51
+ static::$instances[$cls] = $instance;
52
+ $instance->init();
53
+ }
54
+
55
+ return static::$instances[$cls];
56
+ }
57
+
58
+ /**
59
+ * Alternative constructor.
60
+ * Initilize Database object and write it to property.
61
+ * Set tables prefix.
62
+ */
63
+ private function init(){ }
64
+
65
+ /**
66
+ * Set $this->query string for next uses
67
+ *
68
+ * @param $query
69
+ * @return $this
70
+ */
71
+ public function set_query($query){ }
72
+
73
+ /**
74
+ * Safely replace place holders
75
+ *
76
+ * @param string $query
77
+ * @param array $vars
78
+ *
79
+ * @return $this
80
+ */
81
+ public function prepare($query, $vars = array()){ }
82
+
83
+ /**
84
+ * Run any raw request
85
+ *
86
+ * @param $query
87
+ *
88
+ * @return bool|int Raw result
89
+ */
90
+ public function execute($query){ }
91
+
92
+ /**
93
+ * Fetchs first column from query.
94
+ * May receive raw or prepared query.
95
+ *
96
+ * @param bool $query
97
+ * @param bool $response_type
98
+ *
99
+ * @return array|object|void|null
100
+ */
101
+ public function fetch($query = false, $response_type = false){ }
102
+
103
+ /**
104
+ * Fetchs all result from query.
105
+ * May receive raw or prepared query.
106
+ *
107
+ * @param bool $query
108
+ * @param bool $response_type
109
+ *
110
+ * @return array|object|null
111
+ */
112
+ public function fetch_all($query = false, $response_type = false){ }
113
+ }
lib/CleantalkBase/CleantalkHelper.php ADDED
@@ -0,0 +1,671 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CleantalkBase;
4
+
5
+ if(!class_exists('CleantalkBase\CleantalkHelper'))
6
+ {
7
+ /**
8
+ * CleanTalk Helper class.
9
+ * Compatible with any CMS.
10
+ *
11
+ * @package PHP Antispam by CleanTalk
12
+ * @subpackage Helper
13
+ * @Version 3.2
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
17
+ * @see https://github.com/CleanTalk/php-antispam
18
+ */
19
+ class CleantalkHelper
20
+ {
21
+ /**
22
+ * Default user agent for HTTP requests
23
+ */
24
+ const AGENT = 'Cleatalk-Helper/3.2';
25
+
26
+ /**
27
+ * @var array Set of private networks IPv4 and IPv6
28
+ */
29
+ public static $private_networks = array(
30
+ 'v4' => array(
31
+ '10.0.0.0/8',
32
+ '100.64.0.0/10',
33
+ '172.16.0.0/12',
34
+ '192.168.0.0/16',
35
+ '127.0.0.1/32',
36
+ ),
37
+ 'v6' => array(
38
+ '0:0:0:0:0:0:0:1/128', // localhost
39
+ '0:0:0:0:0:0:a:1/128', // ::ffff:127.0.0.1
40
+ ),
41
+ );
42
+
43
+ /**
44
+ * @var array Set of CleanTalk servers
45
+ */
46
+ public static $cleantalks_servers = array(
47
+ // MODERATE
48
+ 'moderate1.cleantalk.org' => '162.243.144.175',
49
+ 'moderate2.cleantalk.org' => '159.203.121.181',
50
+ 'moderate3.cleantalk.org' => '88.198.153.60',
51
+ 'moderate4.cleantalk.org' => '159.69.51.30',
52
+ 'moderate5.cleantalk.org' => '95.216.200.119',
53
+ 'moderate6.cleantalk.org' => '138.68.234.8',
54
+ // APIX
55
+ 'apix1.cleantalk.org' => '35.158.52.161',
56
+ 'apix2.cleantalk.org' => '18.206.49.217',
57
+ 'apix3.cleantalk.org' => '3.18.23.246',
58
+ );
59
+
60
+ /**
61
+ * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
62
+ *
63
+ * @param array $ip_types Type of IP you want to receive
64
+ * @param bool $v4_only
65
+ *
66
+ * @return array|mixed|null
67
+ */
68
+ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare'), $v4_only = true)
69
+ {
70
+ $ips = array_flip($ip_types); // Result array with IPs
71
+ $headers = apache_request_headers();
72
+
73
+ // REMOTE_ADDR
74
+ if(isset($ips['remote_addr'])){
75
+ $ip_type = self::ip__validate($_SERVER['REMOTE_ADDR']);
76
+ if($ip_type){
77
+ $ips['remote_addr'] = $ip_type == 'v6' ? self::ip__v6_normalize($_SERVER['REMOTE_ADDR']) : $_SERVER['REMOTE_ADDR'];
78
+ }
79
+ }
80
+
81
+ // X-Forwarded-For
82
+ if(isset($ips['x_forwarded_for'])){
83
+ if(isset($headers['X-Forwarded-For'])){
84
+ $tmp = explode(",", trim($headers['X-Forwarded-For']));
85
+ $tmp = trim($tmp[0]);
86
+ $ip_type = self::ip__validate($tmp);
87
+ if($ip_type){
88
+ $ips['x_forwarded_for'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
89
+ }
90
+ }
91
+ }
92
+
93
+ // X-Real-Ip
94
+ if(isset($ips['x_real_ip'])){
95
+ if(isset($headers['X-Real-Ip'])){
96
+ $tmp = explode(",", trim($headers['X-Real-Ip']));
97
+ $tmp = trim($tmp[0]);
98
+ $ip_type = self::ip__validate($tmp);
99
+ if($ip_type){
100
+ $ips['x_forwarded_for'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
101
+ }
102
+ }
103
+ }
104
+
105
+ // Cloud Flare
106
+ if(isset($ips['cloud_flare'])){
107
+ if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){
108
+ $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip'];
109
+ $tmp = strpos($tmp, ',') !== false ? explode(',', $tmp) : (array)$tmp;
110
+ $ip_type = self::ip__validate(trim($tmp[0]));
111
+ if($ip_type){
112
+ $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize(trim($tmp[0])) : trim($tmp[0]);
113
+ }
114
+ }
115
+ }
116
+
117
+ // 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.
118
+ if(isset($ips['real'])){
119
+
120
+ // Detect IP type
121
+ $ip_type = self::ip__validate($_SERVER['REMOTE_ADDR']);
122
+ if($ip_type)
123
+ $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($_SERVER['REMOTE_ADDR']) : $_SERVER['REMOTE_ADDR'];
124
+
125
+ // Cloud Flare
126
+ if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){
127
+ $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip'];
128
+ $tmp = strpos($tmp, ',') !== false ? explode(',', $tmp) : (array)$tmp;
129
+ $ip_type = self::ip__validate(trim($tmp[0]));
130
+ if($ip_type)
131
+ $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize(trim($tmp[0])) : trim($tmp[0]);
132
+
133
+ // Sucury
134
+ }elseif(isset($headers['X-Sucuri-Clientip'], $headers['X-Sucuri-Country'])){
135
+ $ip_type = self::ip__validate($headers['X-Sucuri-Clientip']);
136
+ if($ip_type)
137
+ $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['X-Sucuri-Clientip']) : $headers['X-Sucuri-Clientip'];
138
+
139
+ // OVH
140
+ }elseif(isset($headers['X-Cdn-Any-Ip'], $headers['Remote-Ip'])){
141
+ $ip_type = self::ip__validate($headers['X-Cdn-Any-Ip']);
142
+ if($ip_type)
143
+ $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['X-Cdn-Any-Ip']) : $headers['X-Cdn-Any-Ip'];
144
+
145
+ // Incapsula proxy
146
+ }elseif(isset($headers['Incap-Client-Ip'])){
147
+ $ip_type = self::ip__validate($headers['Incap-Client-Ip']);
148
+ if($ip_type)
149
+ $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['Incap-Client-Ip']) : $headers['Incap-Client-Ip'];
150
+ }
151
+
152
+ // Is private network
153
+ if($ip_type === false || ($ip_type && (self::ip__is_private_network($ips['real'], $ip_type) || self::ip__mask_match($ips['real'], filter_input(INPUT_SERVER, 'SERVER_ADDR') . '/24', $ip_type)))){
154
+
155
+ // X-Forwarded-For
156
+ if(isset($headers['X-Forwarded-For'])){
157
+ $tmp = explode(',', trim($headers['X-Forwarded-For']));
158
+ $tmp = trim($tmp[0]);
159
+ $ip_type = self::ip__validate($tmp);
160
+ if($ip_type)
161
+ $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
162
+
163
+ // X-Real-Ip
164
+ }elseif(isset($headers['X-Real-Ip'])){
165
+ $tmp = explode(',', trim($headers['X-Real-Ip']));
166
+ $tmp = trim($tmp[0]);
167
+ $ip_type = self::ip__validate($tmp);
168
+ if($ip_type)
169
+ $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
170
+ }
171
+ }
172
+ }
173
+
174
+ // Validating IPs
175
+ $result = array();
176
+ foreach($ips as $key => $ip){
177
+ $ip_version = self::ip__validate($ip);
178
+ if($ip && (($v4_only && $ip_version == 'v4') || !$v4_only)){
179
+ $result[$key] = $ip;
180
+ }
181
+ }
182
+
183
+ $result = array_unique($result);
184
+ return count($result) > 1
185
+ ? $result
186
+ : (reset($result) !== false
187
+ ? reset($result)
188
+ : null);
189
+ }
190
+
191
+ /**
192
+ * Checks if the IP is in private range
193
+ *
194
+ * @param string $ip
195
+ * @param string $ip_type
196
+ *
197
+ * @return bool
198
+ */
199
+ static function ip__is_private_network($ip, $ip_type = 'v4')
200
+ {
201
+ return self::ip__mask_match($ip, self::$private_networks[$ip_type], $ip_type);
202
+ }
203
+
204
+ /**
205
+ * Check if the IP belong to mask. Recursive.
206
+ * Octet by octet for IPv4
207
+ * Hextet by hextet for IPv6
208
+ *
209
+ * @param string $ip
210
+ * @param string $cidr work to compare with
211
+ * @param string $ip_type IPv6 or IPv4
212
+ * @param int $xtet_count Recursive counter. Determs current part of address to check.
213
+ *
214
+ * @return bool
215
+ */
216
+ static public function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = 0)
217
+ {
218
+ if(is_array($cidr)){
219
+ foreach($cidr as $curr_mask){
220
+ if(self::ip__mask_match($ip, $curr_mask, $ip_type)){
221
+ return true;
222
+ }
223
+ }
224
+ unset($curr_mask);
225
+ return false;
226
+ }
227
+
228
+ $xtet_base = ($ip_type == 'v4') ? 8 : 16;
229
+
230
+ // Calculate mask
231
+ $exploded = explode('/', $cidr);
232
+ $net_ip = $exploded[0];
233
+ $mask = $exploded[1];
234
+
235
+ // Exit condition
236
+ $xtet_end = ceil($mask / $xtet_base);
237
+ if($xtet_count == $xtet_end)
238
+ return true;
239
+
240
+ // Lenght of bits for comparsion
241
+ $mask = $mask - $xtet_base * $xtet_count >= $xtet_base ? $xtet_base : $mask - $xtet_base * $xtet_count;
242
+
243
+ // Explode by octets/hextets from IP and Net
244
+ $net_ip_xtets = explode($ip_type == 'v4' ? '.' : ':', $net_ip);
245
+ $ip_xtets = explode($ip_type == 'v4' ? '.' : ':', $ip);
246
+
247
+ // Standartizing. Getting current octets/hextets. Adding leading zeros.
248
+ $net_xtet = str_pad(decbin($ip_type == 'v4' ? $net_ip_xtets[$xtet_count] : hexdec($net_ip_xtets[$xtet_count])), $xtet_base, 0, STR_PAD_LEFT);
249
+ $ip_xtet = str_pad(decbin($ip_type == 'v4' ? $ip_xtets[$xtet_count] : hexdec($ip_xtets[$xtet_count])), $xtet_base, 0, STR_PAD_LEFT);
250
+
251
+ // Comparing bit by bit
252
+ for($i = 0, $result = true; $mask != 0; $mask--, $i++){
253
+ if($ip_xtet[$i] != $net_xtet[$i]){
254
+ $result = false;
255
+ break;
256
+ }
257
+ }
258
+
259
+ // Recursing. Moving to next octet/hextet.
260
+ if($result)
261
+ $result = self::ip__mask_match($ip, $cidr, $ip_type, $xtet_count + 1);
262
+
263
+ return $result;
264
+
265
+ }
266
+
267
+ /**
268
+ * Converts long mask like 4294967295 to number like 32
269
+ *
270
+ * @param int $long_mask
271
+ *
272
+ * @return int
273
+ */
274
+ static function ip__mask__long_to_number($long_mask)
275
+ {
276
+ $num_mask = strpos((string)decbin($long_mask), '0');
277
+ return $num_mask === false ? 32 : $num_mask;
278
+ }
279
+
280
+ /**
281
+ * Validating IPv4, IPv6
282
+ *
283
+ * @param string $ip
284
+ *
285
+ * @return string|bool
286
+ */
287
+ static public function ip__validate($ip)
288
+ {
289
+ if(!$ip) return false; // NULL || FALSE || '' || so on...
290
+ if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && $ip != '0.0.0.0') return 'v4'; // IPv4
291
+ if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && self::ip__v6_reduce($ip) != '0::0') return 'v6'; // IPv6
292
+ return false; // Unknown
293
+ }
294
+
295
+ /**
296
+ * Expand IPv6
297
+ *
298
+ * @param string $ip
299
+ *
300
+ * @return string IPv6
301
+ */
302
+ static public function ip__v6_normalize($ip)
303
+ {
304
+ $ip = trim($ip);
305
+ // Searching for ::ffff:xx.xx.xx.xx patterns and turn it to IPv6
306
+ if(preg_match('/^::ffff:([0-9]{1,3}\.?){4}$/', $ip)){
307
+ $ip = dechex(sprintf("%u", ip2long(substr($ip, 7))));
308
+ $ip = '0:0:0:0:0:0:' . (strlen($ip) > 4 ? substr('abcde', 0, -4) : '0') . ':' . substr($ip, -4, 4);
309
+ // Normalizing hextets number
310
+ }elseif(strpos($ip, '::') !== false){
311
+ $ip = str_replace('::', str_repeat(':0', 8 - substr_count($ip, ':')) . ':', $ip);
312
+ $ip = strpos($ip, ':') === 0 ? '0' . $ip : $ip;
313
+ $ip = strpos(strrev($ip), ':') === 0 ? $ip . '0' : $ip;
314
+ }
315
+ // Simplifyng hextets
316
+ if(preg_match('/:0(?=[a-z0-9]+)/', $ip)){
317
+ $ip = preg_replace('/:0(?=[a-z0-9]+)/', ':', strtolower($ip));
318
+ $ip = self::ip__v6_normalize($ip);
319
+ }
320
+ return $ip;
321
+ }
322
+
323
+ /**
324
+ * Reduce IPv6
325
+ *
326
+ * @param string $ip
327
+ *
328
+ * @return string IPv6
329
+ */
330
+ static public function ip__v6_reduce($ip)
331
+ {
332
+ if(strpos($ip, ':') !== false){
333
+ $ip = preg_replace('/:0{1,4}/', ':', $ip);
334
+ $ip = preg_replace('/:{2,}/', '::', $ip);
335
+ $ip = strpos($ip, '0') === 0 ? substr($ip, 1) : $ip;
336
+ }
337
+ return $ip;
338
+ }
339
+
340
+ /**
341
+ * Get URL form IP. Check if it's belong to cleantalk.
342
+ *
343
+ * @param $ip
344
+ *
345
+ * @return false|int|string
346
+ */
347
+ static public function ip__resolve__cleantalks($ip)
348
+ {
349
+ if(self::ip__validate($ip)){
350
+ $url = array_search($ip, self::$cleantalks_servers);
351
+ return $url
352
+ ? $url
353
+ : self::ip__resolve($ip);
354
+ }else
355
+ return $ip;
356
+ }
357
+
358
+ /**
359
+ * Get URL form IP
360
+ *
361
+ * @param $ip
362
+ *
363
+ * @return string
364
+ */
365
+ static public function ip__resolve($ip)
366
+ {
367
+ if(self::ip__validate($ip)){
368
+ $url = gethostbyaddr($ip);
369
+ if($url)
370
+ return $url;
371
+ }
372
+ return $ip;
373
+ }
374
+
375
+ /**
376
+ * Resolve DNS to IP
377
+ *
378
+ * @param $host
379
+ * @param bool $out
380
+ *
381
+ * @return bool
382
+ */
383
+ static public function dns__resolve($host, $out = false)
384
+ {
385
+
386
+ // Get DNS records about URL
387
+ if(function_exists('dns_get_record')){
388
+ $records = dns_get_record($host, DNS_A);
389
+ if($records !== false){
390
+ $out = $records[0]['ip'];
391
+ }
392
+ }
393
+
394
+ // Another try if first failed
395
+ if(!$out && function_exists('gethostbynamel')){
396
+ $records = gethostbynamel($host);
397
+ if($records !== false){
398
+ $out = $records[0];
399
+ }
400
+ }
401
+
402
+ return $out;
403
+
404
+ }
405
+
406
+ /**
407
+ * Function sends raw http request
408
+ *
409
+ * May use 4 presets(combining possible):
410
+ * get_code - getting only HTTP response code
411
+ * async - async requests
412
+ * get - GET-request
413
+ * ssl - use SSL
414
+ *
415
+ * @param string $url URL
416
+ * @param array $data POST|GET indexed array with data to send
417
+ * @param string|array $presets String or Array with presets: get_code, async, get, ssl, dont_split_to_array
418
+ * @param array $opts Optional option for CURL connection
419
+ *
420
+ * @return array|bool (array || array('error' => true))
421
+ */
422
+ static public function http__request($url, $data = array(), $presets = null, $opts = array())
423
+ {
424
+ if(function_exists('curl_init')){
425
+
426
+ $ch = curl_init();
427
+
428
+ if(!empty($data)){
429
+ // If $data scalar converting it to array
430
+ $data = is_string($data) || is_int($data) ? array($data => 1) : $data;
431
+ // Build query
432
+ $opts[CURLOPT_POSTFIELDS] = $data;
433
+ }
434
+
435
+ // Merging OBLIGATORY options with GIVEN options
436
+ $opts = self::array_merge__save_numeric_keys(
437
+ array(
438
+ CURLOPT_URL => $url,
439
+ CURLOPT_RETURNTRANSFER => true,
440
+ CURLOPT_CONNECTTIMEOUT_MS => 3000,
441
+ CURLOPT_FORBID_REUSE => true,
442
+ CURLOPT_USERAGENT => self::AGENT . '; ' . (!empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'UNKNOWN_HOST'),
443
+ CURLOPT_POST => true,
444
+ CURLOPT_SSL_VERIFYPEER => false,
445
+ CURLOPT_SSL_VERIFYHOST => 0,
446
+ CURLOPT_HTTPHEADER => array('Expect:'), // Fix for large data and old servers http://php.net/manual/ru/function.curl-setopt.php#82418
447
+ CURLOPT_FOLLOWLOCATION => true,
448
+ CURLOPT_MAXREDIRS => 5,
449
+ ),
450
+ $opts
451
+ );
452
+
453
+ // Use presets
454
+ $presets = is_array($presets) ? $presets : explode(' ', $presets);
455
+ foreach($presets as $preset){
456
+
457
+ switch($preset){
458
+
459
+ // Do not follow redirects
460
+ case 'dont_follow_redirects':
461
+ $opts[CURLOPT_FOLLOWLOCATION] = false;
462
+ $opts[CURLOPT_MAXREDIRS] = 0;
463
+ break;
464
+
465
+ // Get headers only
466
+ case 'get_code':
467
+ $opts[CURLOPT_HEADER] = true;
468
+ $opts[CURLOPT_NOBODY] = true;
469
+ break;
470
+
471
+ // Make a request, don't wait for an answer
472
+ case 'async':
473
+ $opts[CURLOPT_CONNECTTIMEOUT_MS] = 1000;
474
+ $opts[CURLOPT_TIMEOUT_MS] = 500;
475
+ break;
476
+
477
+ case 'get':
478
+ $opts[CURLOPT_URL] .= $data ? '?' . str_replace("&amp;", "&", http_build_query($data)) : '';
479
+ $opts[CURLOPT_POST] = false;
480
+ $opts[CURLOPT_POSTFIELDS] = null;
481
+ break;
482
+
483
+ case 'ssl':
484
+ $opts[CURLOPT_SSL_VERIFYPEER] = true;
485
+ $opts[CURLOPT_SSL_VERIFYHOST] = 2;
486
+ if(defined('CLEANTALK_CASERT_PATH') && CLEANTALK_CASERT_PATH)
487
+ $opts[CURLOPT_CAINFO] = CLEANTALK_CASERT_PATH;
488
+ break;
489
+
490
+ default:
491
+
492
+ break;
493
+ }
494
+
495
+ }
496
+ unset($preset);
497
+
498
+ curl_setopt_array($ch, $opts);
499
+ $result = curl_exec($ch);
500
+
501
+ // RETURN if async request
502
+ if(in_array('async', $presets))
503
+ return true;
504
+
505
+ if($result){
506
+
507
+ if(strpos($result, PHP_EOL) !== false && !in_array('dont_split_to_array', $presets))
508
+ $result = explode(PHP_EOL, $result);
509
+
510
+ // Get code crossPHP method
511
+ if(in_array('get_code', $presets)){
512
+ $curl_info = curl_getinfo($ch);
513
+ $result = $curl_info['http_code'];
514
+ }
515
+ curl_close($ch);
516
+ $out = $result;
517
+ }else
518
+ $out = array('error' => curl_error($ch));
519
+ }else
520
+ $out = array('error' => 'CURL_NOT_INSTALLED');
521
+
522
+ /**
523
+ * Getting HTTP-response code without cURL
524
+ */
525
+ if($presets && ($presets == 'get_code' || (is_array($presets) && in_array('get_code', $presets)))
526
+ && isset($out['error']) && $out['error'] == 'CURL_NOT_INSTALLED'
527
+ ){
528
+ $headers = get_headers($url);
529
+ $out = (int)preg_replace('/.*(\d{3}).*/', '$1', $headers[0]);
530
+ }
531
+
532
+ return $out;
533
+ }
534
+
535
+ /**
536
+ * Merging arrays without reseting numeric keys
537
+ *
538
+ * @param array $arr1 One-dimentional array
539
+ * @param array $arr2 One-dimentional array
540
+ *
541
+ * @return array Merged array
542
+ */
543
+ public static function array_merge__save_numeric_keys($arr1, $arr2)
544
+ {
545
+ foreach($arr2 as $key => $val){
546
+ $arr1[$key] = $val;
547
+ }
548
+ return $arr1;
549
+ }
550
+
551
+ /**
552
+ * Merging arrays without reseting numeric keys recursive
553
+ *
554
+ * @param array $arr1 One-dimentional array
555
+ * @param array $arr2 One-dimentional array
556
+ *
557
+ * @return array Merged array
558
+ */
559
+ public static function array_merge__save_numeric_keys__recursive($arr1, $arr2)
560
+ {
561
+ foreach($arr2 as $key => $val){
562
+ // Array | array => array
563
+ if(isset($arr1[$key]) && is_array($arr1[$key]) && is_array($val)){
564
+ $arr1[$key] = self::array_merge__save_numeric_keys__recursive($arr1[$key], $val);
565
+ // Scalar | array => array
566
+ }elseif(isset($arr1[$key]) && !is_array($arr1[$key]) && is_array($val)){
567
+ $tmp = $arr1[$key] =
568
+ $arr1[$key] = $val;
569
+ $arr1[$key][] = $tmp;
570
+ // array | scalar => array
571
+ }elseif(isset($arr1[$key]) && is_array($arr1[$key]) && !is_array($val)){
572
+ $arr1[$key][] = $val;
573
+ // scalar | scalar => scalar
574
+ }else{
575
+ $arr1[$key] = $val;
576
+ }
577
+ }
578
+ return $arr1;
579
+ }
580
+
581
+ /**
582
+ * Function removing non UTF8 characters from array|string|object
583
+ *
584
+ * @param array|object|string $data
585
+ *
586
+ * @return array|object|string
587
+ */
588
+ public static function removeNonUTF8($data)
589
+ {
590
+ // Array || object
591
+ if(is_array($data) || is_object($data)){
592
+ foreach($data as $key => &$val){
593
+ $val = self::removeNonUTF8($val);
594
+ }
595
+ unset($key, $val);
596
+
597
+ //String
598
+ }else{
599
+ if(!preg_match('//u', $data))
600
+ $data = 'Nulled. Not UTF8 encoded or malformed.';
601
+ }
602
+ return $data;
603
+ }
604
+
605
+ /**
606
+ * Function convert anything to UTF8 and removes non UTF8 characters
607
+ *
608
+ * @param array|object|string $obj
609
+ * @param string $data_codepage
610
+ *
611
+ * @return mixed(array|object|string)
612
+ */
613
+ public static function toUTF8($obj, $data_codepage = null)
614
+ {
615
+ // Array || object
616
+ if(is_array($obj) || is_object($obj)){
617
+ foreach($obj as $key => &$val){
618
+ $val = self::toUTF8($val, $data_codepage);
619
+ }
620
+ unset($key, $val);
621
+
622
+ //String
623
+ }else{
624
+ if(!preg_match('//u', $obj) && function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')){
625
+ $encoding = mb_detect_encoding($obj);
626
+ $encoding = $encoding ? $encoding : $data_codepage;
627
+ if($encoding)
628
+ $obj = mb_convert_encoding($obj, 'UTF-8', $encoding);
629
+ }
630
+ }
631
+ return $obj;
632
+ }
633
+
634
+ /**
635
+ * Function convert from UTF8
636
+ *
637
+ * @param array|object|string $obj
638
+ * @param string $data_codepage
639
+ *
640
+ * @return mixed (array|object|string)
641
+ */
642
+ public static function fromUTF8($obj, $data_codepage = null)
643
+ {
644
+ // Array || object
645
+ if(is_array($obj) || is_object($obj)){
646
+ foreach($obj as $key => &$val){
647
+ $val = self::fromUTF8($val, $data_codepage);
648
+ }
649
+ unset($key, $val);
650
+
651
+ //String
652
+ }else{
653
+ if(preg_match('u', $obj) && function_exists('mb_convert_encoding') && $data_codepage !== null)
654
+ $obj = mb_convert_encoding($obj, $data_codepage, 'UTF-8');
655
+ }
656
+ return $obj;
657
+ }
658
+
659
+ /**
660
+ * Checks if the string is JSON type
661
+ *
662
+ * @param string
663
+ *
664
+ * @return bool
665
+ */
666
+ static public function is_json($string)
667
+ {
668
+ return is_string($string) && is_array(json_decode($string, true)) ? true : false;
669
+ }
670
+ }
671
+ }
lib/{CleantalkSFW_Base.php → CleantalkBase/CleantalkSFW.php} RENAMED
@@ -1,27 +1,29 @@
1
  <?php
2
 
3
- /*
4
- * CleanTalk SpamFireWall base class
5
- * Compatible only with Wordpress.
6
- * @depends on CleantalkHelper class
7
- * @depends on CleantalkAPI class
8
- * @depends on CleantalkDB class
9
- * Version 3.0-base
10
- * author Cleantalk team (welcome@cleantalk.org)
11
- * copyright (C) 2014 CleanTalk team (http://cleantalk.org)
12
- * license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
13
- * see https://github.com/CleanTalk/php-antispam
14
- */
15
 
16
- class CleantalkSFW_Base
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  {
18
  public $ip = 0;
19
- public $ip_str = '';
20
  public $ip_array = Array();
21
- public $ip_str_array = Array();
22
  public $results = array();
23
  public $blocked_ip = '';
24
- public $passed_ip = '';
25
  public $result = false;
26
  public $pass = true;
27
 
@@ -39,27 +41,33 @@ class CleantalkSFW_Base
39
  //Debug
40
  public $debug;
41
  public $debug_data = '';
42
- public $debug_networks = array();
43
 
44
  /**
45
- * Creates connection to database
46
- *
47
- * @param array $params
48
- * array((string)'hostname', (string)'db_name', (string)'charset', (array)PDO options)
49
- * @param string $username
50
- * @param string $password
51
- *
52
- * @return void
53
- */
54
  public function __construct()
55
  {
 
 
 
 
 
 
 
 
 
56
  $this->debug = isset($_GET['debug']) && intval($_GET['debug']) === 1 ? true : false;
57
  }
58
 
59
- /*
60
- * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
61
- * reutrns array('remote_addr' => 'val', ['x_forwarded_for' => 'val', ['x_real_ip' => 'val', ['cloud_flare' => 'val']]])
62
- */
 
 
 
 
63
  public function ip__get($ips_input = array('real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare'), $v4_only = true){
64
 
65
  $result = CleantalkHelper::ip__get($ips_input, $v4_only);
@@ -77,9 +85,9 @@ class CleantalkSFW_Base
77
 
78
  }
79
 
80
- /*
81
- * Checks IP via Database
82
- */
83
  public function ip_check()
84
  {
85
  foreach($this->ip_array as $origin => $current_ip){
@@ -115,10 +123,14 @@ class CleantalkSFW_Base
115
  }
116
  }
117
  }
118
-
119
- /*
120
- * Add entry to SFW log
121
- */
 
 
 
 
122
  public function logs__update($ip, $result){
123
 
124
  if($ip === NULL || $result === NULL){
@@ -143,16 +155,18 @@ class CleantalkSFW_Base
143
  $this->db->execute($query);
144
  }
145
 
146
- /*
147
- * Sends and wipe SFW log
148
- *
149
- * returns mixed true || array('error' => true, 'error_string' => STRING)
150
- */
 
 
151
  public function logs__send($ct_key){
152
 
153
  //Getting logs
154
  $query = "SELECT * FROM ".$this->log_table.";";
155
- $this->db->set_query($query)->fetch_all();
156
 
157
  if(count($this->db->result)){
158
 
@@ -172,20 +186,25 @@ class CleantalkSFW_Base
172
  $this->db->execute("DELETE FROM ".$this->log_table.";");
173
  return $result;
174
  }
 
175
  }else{
176
  return $result;
177
  }
178
 
179
  }else{
180
- return array('error' => true, 'error_string' => 'NO_LOGS_TO_SEND');
181
  }
182
  }
183
 
184
- /*
185
- * Updates SFW local base
186
- *
187
- * return mixed true || array('error' => true, 'error_string' => STRING)
188
- */
 
 
 
 
189
  public function sfw_update($ct_key, $file_url = null, $immediate = false){
190
 
191
  // Getting remote file name
@@ -201,7 +220,7 @@ class CleantalkSFW_Base
201
 
202
  $pattenrs = array();
203
  $pattenrs[] = 'get';
204
- if(!$immediate) $pattenrs[] = 'dont_wait_for_answer';
205
 
206
  return CleantalkHelper::http__request(
207
  get_option('siteurl'),
@@ -215,7 +234,7 @@ class CleantalkSFW_Base
215
  );
216
 
217
  }else
218
- return array('error' => true, 'error_string' => 'BAD_RESPONSE');
219
  }else
220
  return $result;
221
  }else{
@@ -265,22 +284,26 @@ class CleantalkSFW_Base
265
  return $count_result;
266
 
267
  }else
268
- return array('error' => true, 'error_string' => 'ERROR_GZ_EMPTY');
269
  }else
270
- return array('error' => true, 'error_string' => 'ERROR_OPEN_GZ_FILE');
271
  }else
272
- return array('error' => true, 'error_string' => 'ERROR_ALLOW_URL_FOPEN_DISABLED');
273
  }else
274
- return array('error' => true, 'error_string' => 'NO_REMOTE_FILE_FOUND');
275
  }
276
  }
277
 
278
- /*
279
- * Shows DIE page
280
- *
281
- * Stops script executing
282
- */
283
- public function sfw_die($api_key, $cookie_prefix = '', $cookie_domain = '')
 
 
 
 
284
  {
285
  die("IP {$this->blocked_ip} BLACKLISTED");
286
  }
1
  <?php
2
 
3
+ namespace CleantalkBase;
 
 
 
 
 
 
 
 
 
 
 
4
 
5
+ /**
6
+ * CleanTalk SpamFireWall base class.
7
+ * Compatible with any CMS.
8
+ *
9
+ * @depends CleantalkHelper class
10
+ * @depends CleantalkAPI class
11
+ * @depends CleantalkDB class
12
+ *
13
+ * @version 3.3
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
17
+ * @see https://github.com/CleanTalk/php-antispam
18
+ */
19
+ class CleantalkSFW
20
  {
21
  public $ip = 0;
22
+
23
  public $ip_array = Array();
24
+
25
  public $results = array();
26
  public $blocked_ip = '';
 
27
  public $result = false;
28
  public $pass = true;
29
 
41
  //Debug
42
  public $debug;
43
  public $debug_data = '';
 
44
 
45
  /**
46
+ * CleantalkSFW_Base constructor.
47
+ * Creates Database driver instance.
48
+ */
 
 
 
 
 
 
49
  public function __construct()
50
  {
51
+ if(empty($this->db)){
52
+ // Creating database object. Depends on current CMS.
53
+ $this->db = CleantalkDB::getInstance();
54
+
55
+ // Use default tables if not specified
56
+ $this->data_table = defined('CLEANTALK_TBL_FIREWALL_DATA') ? CLEANTALK_TBL_FIREWALL_DATA : $this->db->prefix . 'cleantalk_sfw';
57
+ $this->log_table = defined('CLEANTALK_TBL_FIREWALL_LOG') ? CLEANTALK_TBL_FIREWALL_LOG : $this->db->prefix . 'cleantalk_sfw_logs';
58
+ }
59
+
60
  $this->debug = isset($_GET['debug']) && intval($_GET['debug']) === 1 ? true : false;
61
  }
62
 
63
+ /**
64
+ * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
65
+ *
66
+ * @param array $ips_input type of IP you want to receive
67
+ * @param bool $v4_only
68
+ *
69
+ * @return array|mixed|null
70
+ */
71
  public function ip__get($ips_input = array('real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare'), $v4_only = true){
72
 
73
  $result = CleantalkHelper::ip__get($ips_input, $v4_only);
85
 
86
  }
87
 
88
+ /**
89
+ * Checks IP via Database
90
+ */
91
  public function ip_check()
92
  {
93
  foreach($this->ip_array as $origin => $current_ip){
123
  }
124
  }
125
  }
126
+
127
+ /**
128
+ * Add entry to SFW log.
129
+ * Writes to database.
130
+ *
131
+ * @param string $ip
132
+ * @param string $result "blocked" or "passed"
133
+ */
134
  public function logs__update($ip, $result){
135
 
136
  if($ip === NULL || $result === NULL){
155
  $this->db->execute($query);
156
  }
157
 
158
+ /**
159
+ * Sends and wipe SFW log
160
+ *
161
+ * @param string $ct_key API key
162
+ *
163
+ * @return array|bool array('error' => STRING)
164
+ */
165
  public function logs__send($ct_key){
166
 
167
  //Getting logs
168
  $query = "SELECT * FROM ".$this->log_table.";";
169
+ $this->db->fetch_all($query);
170
 
171
  if(count($this->db->result)){
172
 
186
  $this->db->execute("DELETE FROM ".$this->log_table.";");
187
  return $result;
188
  }
189
+ return array('error' => 'SENT_AND_RECEIVED_LOGS_COUNT_DOESNT_MACH');
190
  }else{
191
  return $result;
192
  }
193
 
194
  }else{
195
+ return array('error' => 'NO_LOGS_TO_SEND');
196
  }
197
  }
198
 
199
+ /**
200
+ * Updates SFW local base
201
+ *
202
+ * @param string $ct_key API key
203
+ * @param null|string $file_url File URL with SFW data.
204
+ * @param bool $immediate Requires immmediate update. Without remote call
205
+ *
206
+ * @return array|bool array('error' => STRING)
207
+ */
208
  public function sfw_update($ct_key, $file_url = null, $immediate = false){
209
 
210
  // Getting remote file name
220
 
221
  $pattenrs = array();
222
  $pattenrs[] = 'get';
223
+ if(!$immediate) $pattenrs[] = 'async';
224
 
225
  return CleantalkHelper::http__request(
226
  get_option('siteurl'),
234
  );
235
 
236
  }else
237
+ return array('error' => 'BAD_RESPONSE');
238
  }else
239
  return $result;
240
  }else{
284
  return $count_result;
285
 
286
  }else
287
+ return array('error' => 'ERROR_GZ_EMPTY');
288
  }else
289
+ return array('error' => 'ERROR_OPEN_GZ_FILE');
290
  }else
291
+ return array('error' => 'ERROR_ALLOW_URL_FOPEN_DISABLED');
292
  }else
293
+ return array('error' => 'NO_REMOTE_FILE_FOUND');
294
  }
295
  }
296
 
297
+ /**
298
+ * Shows DIE page.
299
+ * Stops script executing.
300
+ *
301
+ * @param string $api_key
302
+ * @param string $cookie_prefix
303
+ * @param string $cookie_domain
304
+ * @param bool $test
305
+ */
306
+ public function sfw_die($api_key, $cookie_prefix = '', $cookie_domain = '', $test = false)
307
  {
308
  die("IP {$this->blocked_ip} BLACKLISTED");
309
  }
lib/{CleantalkDB_Wordpress.php → CleantalkDB.php} RENAMED
@@ -1,26 +1,23 @@
1
  <?php
2
 
3
- /*
4
  * CleanTalk Wordpress Data Base driver
5
  * Compatible only with Wordpress.
6
- * Version 2.0
7
- * author Cleantalk team (welcome@cleantalk.org)
8
- * copyright (C) 2014 CleanTalk team (http://cleantalk.org)
9
- * license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
10
- * see https://github.com/CleanTalk/php-antispam
 
 
 
 
11
  */
12
 
13
- class CleantalkDB_Wordpress
14
  {
15
- /**
16
- * @var string tables prefix
17
- */
18
- public $prefix;
19
 
20
- /**
21
- * @var wpdb instance of WPDB
22
- */
23
- private $db;
24
 
25
  /**
26
  * @var string Query string
@@ -28,7 +25,7 @@ class CleantalkDB_Wordpress
28
  private $query;
29
 
30
  /**
31
- * @var Raw DB result
32
  */
33
  private $db_result;
34
 
@@ -38,15 +35,30 @@ class CleantalkDB_Wordpress
38
  public $result = array();
39
 
40
  /**
41
- * CleantalkDB_Wordpress constructor.
42
  */
43
- public function __construct()
 
 
 
 
 
 
44
  {
45
- global $wpdb, $apbct;
46
- $this->db = $wpdb;
47
- $this->prefix = $apbct->db_prefix;
 
 
 
 
 
48
  }
49
 
 
 
 
 
50
  /**
51
  * Set $this->query string for next uses
52
  *
@@ -60,7 +72,6 @@ class CleantalkDB_Wordpress
60
  }
61
 
62
  /**
63
- * @todo finish in two weaks! (09.07.2019)
64
  * Safely replace place holders
65
  *
66
  * @param string $query
@@ -68,13 +79,15 @@ class CleantalkDB_Wordpress
68
  *
69
  * @return $this
70
  */
71
- public function prepare__incomplete__($query, $vars = array())
72
  {
 
 
73
  $query = $query ? $query : $this->query;
74
  $vars = $vars ? $vars : array();
75
  array_unshift($vars, $query);
76
 
77
- $this->query = call_user_func_array('$this->db->prepare', $vars);
78
 
79
  return $this;
80
  }
@@ -84,11 +97,14 @@ class CleantalkDB_Wordpress
84
  *
85
  * @param $query
86
  *
87
- * @return bool|int|Raw
88
  */
89
  public function execute($query)
90
  {
91
- $this->db_result = $this->db->query($query);
 
 
 
92
  return $this->db_result;
93
  }
94
 
@@ -103,10 +119,13 @@ class CleantalkDB_Wordpress
103
  */
104
  public function fetch($query = false, $response_type = false)
105
  {
106
- $query = $query ? $query : $this->query;
 
 
107
  $response_type = $response_type ? $response_type : ARRAY_A;
108
 
109
- $this->result = $this->db->get_row($query, $response_type);
 
110
  return $this->result;
111
  }
112
 
@@ -121,10 +140,13 @@ class CleantalkDB_Wordpress
121
  */
122
  public function fetch_all($query = false, $response_type = false)
123
  {
124
- $query = $query ? $query : $this->query;
 
 
125
  $response_type = $response_type ? $response_type : ARRAY_A;
126
 
127
- $this->result = $this->db->get_results($query, $response_type);
 
128
  return $this->result;
129
  }
130
  }
1
  <?php
2
 
3
+ /**
4
  * CleanTalk Wordpress Data Base driver
5
  * Compatible only with Wordpress.
6
+ * Uses singleton pattern.
7
+ *
8
+ * @depends CleantalkBase\CleantalkDB
9
+ *
10
+ * @version 3.2
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
+ * @see https://github.com/CleanTalk/wordpress-antispam
15
  */
16
 
17
+ class CleantalkDB extends CleantalkBase\CleantalkDB
18
  {
 
 
 
 
19
 
20
+ private static $instances = [];
 
 
 
21
 
22
  /**
23
  * @var string Query string
25
  private $query;
26
 
27
  /**
28
+ * @var wpdb result
29
  */
30
  private $db_result;
31
 
35
  public $result = array();
36
 
37
  /**
38
+ * @var string Database prefix
39
  */
40
+ public $prefix = '';
41
+
42
+ public function __construct() { }
43
+ public function __clone() { }
44
+ public function __wakeup() { }
45
+
46
+ public static function getInstance()
47
  {
48
+ $cls = static::class;
49
+ if (!isset(static::$instances[$cls])) {
50
+ $instance = new static;
51
+ static::$instances[$cls] = $instance;
52
+ $instance->init();
53
+ }
54
+
55
+ return static::$instances[$cls];
56
  }
57
 
58
+ private function init(){
59
+ global $apbct;
60
+ $this->prefix = $apbct->db_prefix;
61
+ }
62
  /**
63
  * Set $this->query string for next uses
64
  *
72
  }
73
 
74
  /**
 
75
  * Safely replace place holders
76
  *
77
  * @param string $query
79
  *
80
  * @return $this
81
  */
82
+ public function prepare($query, $vars = array())
83
  {
84
+ global $wpdb;
85
+
86
  $query = $query ? $query : $this->query;
87
  $vars = $vars ? $vars : array();
88
  array_unshift($vars, $query);
89
 
90
+ $this->query = call_user_func_array(array($wpdb, 'prepare'), $vars);
91
 
92
  return $this;
93
  }
97
  *
98
  * @param $query
99
  *
100
+ * @return bool|int Raw result
101
  */
102
  public function execute($query)
103
  {
104
+ global $wpdb;
105
+
106
+ $this->db_result = $wpdb->query($query);
107
+
108
  return $this->db_result;
109
  }
110
 
119
  */
120
  public function fetch($query = false, $response_type = false)
121
  {
122
+ global $wpdb;
123
+
124
+ $query = $query ? $query : $this->query;
125
  $response_type = $response_type ? $response_type : ARRAY_A;
126
 
127
+ $this->result = $wpdb->get_row($query, $response_type);
128
+
129
  return $this->result;
130
  }
131
 
140
  */
141
  public function fetch_all($query = false, $response_type = false)
142
  {
143
+ global $wpdb;
144
+
145
+ $query = $query ? $query : $this->query;
146
  $response_type = $response_type ? $response_type : ARRAY_A;
147
 
148
+ $this->result = $wpdb->get_results($query, $response_type);
149
+
150
  return $this->result;
151
  }
152
  }
lib/CleantalkHelper.php CHANGED
@@ -1,597 +1,48 @@
1
  <?php
2
 
3
- /*
 
 
4
  *
5
- * CleanTalk Cleantalk Antispam Helper class
6
  *
7
  * @package Antispam Plugin by CleanTalk
8
  * @subpackage Helper
9
- * @Version 2.0
10
  * @author Cleantalk team (welcome@cleantalk.org)
11
  * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
12
  * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
13
- *
14
  */
15
 
16
- class CleantalkHelper
17
  {
18
- public static $private_networks = array(
19
- 'v4' => array(
20
- '10.0.0.0/8',
21
- '100.64.0.0/10',
22
- '172.16.0.0/12',
23
- '192.168.0.0/16',
24
- '127.0.0.1/32',
25
- ),
26
- 'v6' => array(
27
- '0:0:0:0:0:0:0:1/128', // localhost
28
- '0:0:0:0:0:0:a:1/128', // ::ffff:127.0.0.1
29
- ),
30
- );
31
-
32
- public static $cleantalks_servers = array(
33
- // MODERATE
34
- 'moderate1.cleantalk.org' => '162.243.144.175',
35
- 'moderate2.cleantalk.org' => '159.203.121.181',
36
- 'moderate3.cleantalk.org' => '88.198.153.60',
37
- 'moderate4.cleantalk.org' => '159.69.51.30',
38
- 'moderate5.cleantalk.org' => '95.216.200.119',
39
- 'moderate6.cleantalk.org' => '138.68.234.8',
40
- // APIX
41
- 'apix1.cleantalk.org' => '35.158.52.161',
42
- 'apix2.cleantalk.org' => '18.206.49.217',
43
- 'apix3.cleantalk.org' => '3.18.23.246',
44
- );
45
-
46
- /*
47
- * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
48
- * reutrns array('remote_addr' => 'val', ['x_forwarded_for' => 'val', ['x_real_ip' => 'val', ['cloud_flare' => 'val']]])
49
- */
50
- static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwarded_for', 'x_real_ip', 'cloud_flare'), $v4_only = true)
51
- {
52
- $ips = array_flip($ip_types); // Result array with IPs
53
- $headers = apache_request_headers();
54
-
55
- // REMOTE_ADDR
56
- if(isset($ips['remote_addr'])){
57
- $ip_type = self::ip__validate($_SERVER['REMOTE_ADDR']);
58
- if($ip_type){
59
- $ips['remote_addr'] = $ip_type == 'v6' ? self::ip__v6_normalize($_SERVER['REMOTE_ADDR']) : $_SERVER['REMOTE_ADDR'];
60
- }
61
- }
62
-
63
- // X-Forwarded-For
64
- if(isset($ips['x_forwarded_for'])){
65
- if(isset($headers['X-Forwarded-For'])){
66
- $tmp = explode(",", trim($headers['X-Forwarded-For']));
67
- $tmp = trim($tmp[0]);
68
- $ip_type = self::ip__validate($tmp);
69
- if($ip_type){
70
- $ips['x_forwarded_for'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
71
- }
72
- }
73
- }
74
-
75
- // X-Real-Ip
76
- if(isset($ips['x_real_ip'])){
77
- if(isset($headers['X-Real-Ip'])){
78
- $tmp = explode(",", trim($headers['X-Real-Ip']));
79
- $tmp = trim($tmp[0]);
80
- $ip_type = self::ip__validate($tmp);
81
- if($ip_type){
82
- $ips['x_forwarded_for'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
83
- }
84
- }
85
- }
86
-
87
- // Cloud Flare
88
- if(isset($ips['cloud_flare'])){
89
- if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){
90
- $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip'];
91
- $tmp = strpos($tmp, ',') !== false ? explode(',', $tmp) : (array)$tmp;
92
- $ip_type = self::ip__validate(trim($tmp[0]));
93
- if($ip_type){
94
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize(trim($tmp[0])) : trim($tmp[0]);
95
- }
96
- }
97
- }
98
-
99
- // 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.
100
- if(isset($ips['real'])){
101
-
102
- // Detect IP type
103
- $ip_type = self::ip__validate($_SERVER['REMOTE_ADDR']);
104
- if($ip_type)
105
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($_SERVER['REMOTE_ADDR']) : $_SERVER['REMOTE_ADDR'];
106
-
107
- // Cloud Flare
108
- if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){
109
- $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip'];
110
- $tmp = strpos($tmp, ',') !== false ? explode(',', $tmp) : (array)$tmp;
111
- $ip_type = self::ip__validate(trim($tmp[0]));
112
- if($ip_type)
113
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize(trim($tmp[0])) : trim($tmp[0]);
114
-
115
- // Sucury
116
- }elseif(isset($headers['X-Sucuri-Clientip'], $headers['X-Sucuri-Country'])){
117
- $ip_type = self::ip__validate($headers['X-Sucuri-Clientip']);
118
- if($ip_type)
119
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['X-Sucuri-Clientip']) : $headers['X-Sucuri-Clientip'];
120
-
121
- // OVH
122
- }elseif(isset($headers['X-Cdn-Any-Ip'], $headers['Remote-Ip'])){
123
- $ip_type = self::ip__validate($headers['X-Cdn-Any-Ip']);
124
- if($ip_type)
125
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['X-Cdn-Any-Ip']) : $headers['X-Cdn-Any-Ip'];
126
-
127
- // Incapsula proxy
128
- }elseif(isset($headers['Incap-Client-Ip'])){
129
- $ip_type = self::ip__validate($headers['Incap-Client-Ip']);
130
- if($ip_type)
131
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['Incap-Client-Ip']) : $headers['Incap-Client-Ip'];
132
- }
133
-
134
- // Is private network
135
- if($ip_type === false || ($ip_type && (self::ip__is_private_network($ips['real'], $ip_type) || self::ip__mask_match($ips['real'], filter_input(INPUT_SERVER, 'SERVER_ADDR').'/24', $ip_type)))){
136
-
137
- // X-Forwarded-For
138
- if(isset($headers['X-Forwarded-For'])){
139
- $tmp = explode(',', trim($headers['X-Forwarded-For']));
140
- $tmp = trim($tmp[0]);
141
- $ip_type = self::ip__validate($tmp);
142
- if($ip_type)
143
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
144
-
145
- // X-Real-Ip
146
- }elseif(isset($headers['X-Real-Ip'])){
147
- $tmp = explode(',', trim($headers['X-Real-Ip']));
148
- $tmp = trim($tmp[0]);
149
- $ip_type = self::ip__validate($tmp);
150
- if($ip_type)
151
- $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp;
152
- }
153
- }
154
- }
155
-
156
- // Validating IPs
157
- $result = array();
158
- foreach($ips as $key => $ip){
159
- $ip_version = self::ip__validate($ip);
160
- if($ip && (($v4_only && $ip_version == 'v4') || !$v4_only)){
161
- $result[$key] = $ip;
162
- }
163
- }
164
-
165
- $result = array_unique($result);
166
- return count($result) > 1
167
- ? $result
168
- : (reset($result) !== false
169
- ? reset($result)
170
- : null);
171
- }
172
-
173
- static function ip__is_private_network($ip, $ip_type = 'v4'){
174
- return self::ip__mask_match($ip, self::$private_networks[$ip_type], $ip_type);
175
- }
176
-
177
- /*
178
- * Check if the IP belong to mask. Recursive.
179
- * Octet by octet for IPv4
180
- * Hextet by hextet for IPv6
181
- * @param ip string
182
- * @param cird mixed (string|array of strings)
183
- * @param ip_type string
184
- * @param cird mixed (string|array of strings)
185
- */
186
- static public function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = 0)
187
- {
188
- if(is_array($cidr)){
189
- foreach($cidr as $curr_mask){
190
- if(self::ip__mask_match($ip, $curr_mask, $ip_type)){
191
- return true;
192
- }
193
- } unset($curr_mask);
194
- return false;
195
- }
196
-
197
- if($ip_type == 'v4') $xtet_base = 8;
198
- if($ip_type == 'v6') $xtet_base = 16;
199
-
200
- // Calculate mask
201
- $exploded = explode('/', $cidr);
202
- $net_ip = $exploded[0];
203
- $mask = $exploded[1];
204
-
205
- // Exit condition
206
- $xtet_end = ceil($mask / $xtet_base);
207
- if($xtet_count == $xtet_end)
208
- return true;
209
-
210
- // Lenght of bits for comparsion
211
- $mask = $mask - $xtet_base * $xtet_count >= $xtet_base ? $xtet_base : $mask - $xtet_base * $xtet_count;
212
-
213
- // Explode by octets/hextets from IP and Net
214
- $net_ip_xtets = explode($ip_type == 'v4' ? '.' : ':', $net_ip);
215
- $ip_xtets = explode($ip_type == 'v4' ? '.' : ':', $ip);
216
-
217
- // Standartizing. Getting current octets/hextets. Adding leading zeros.
218
- $net_xtet = str_pad(decbin($ip_type == 'v4' ? $net_ip_xtets[$xtet_count] : hexdec($net_ip_xtets[$xtet_count])), $xtet_base, 0, STR_PAD_LEFT);
219
- $ip_xtet = str_pad(decbin($ip_type == 'v4' ? $ip_xtets[$xtet_count] : hexdec($ip_xtets[$xtet_count])), $xtet_base, 0, STR_PAD_LEFT);
220
-
221
- // Comparing bit by bit
222
- for($i = 0, $result = true; $mask != 0; $mask--, $i++ ){
223
- if($ip_xtet[$i] != $net_xtet[$i]){
224
- $result = false;
225
- break;
226
- }
227
- }
228
-
229
- // Recursing. Moving to next octet/hextet.
230
- if($result)
231
- $result = self::ip__mask_match($ip, $cidr, $ip_type, $xtet_count + 1);
232
-
233
- return $result;
234
-
235
- }
236
-
237
- /**
238
- * Converts long mask like 4294967295 to number like 32
239
- *
240
- * @param type $long_mask
241
- */
242
- static function ip__mask__long_to_number($long_mask){
243
- $num_mask = strpos((string)decbin($long_mask), '0');
244
- return $num_mask === false ? 32 : $num_mask;
245
- }
246
-
247
- /*
248
- * Validating IPv4, IPv6
249
- * param (string) $ip
250
- * returns (string) 'v4' || (string) 'v6' || (bool) false
251
- */
252
- static public function ip__validate($ip)
253
- {
254
- if(!$ip) return false; // NULL || FALSE || '' || so on...
255
- if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && $ip != '0.0.0.0') return 'v4'; // IPv4
256
- if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && self::ip__v6_reduce($ip) != '0::0') return 'v6'; // IPv6
257
- return false; // Unknown
258
- }
259
-
260
- /**
261
- * Expand IPv6
262
- * param (string) $ip
263
- * returns (string) IPv6
264
- */
265
- static public function ip__v6_normalize($ip)
266
- {
267
- $ip = trim($ip);
268
- // Searching for ::ffff:xx.xx.xx.xx patterns and turn it to IPv6
269
- if(preg_match('/^::ffff:([0-9]{1,3}\.?){4}$/', $ip)){
270
- $ip = dechex(sprintf("%u", ip2long(substr($ip, 7))));
271
- $ip = '0:0:0:0:0:0:'.(strlen($ip) > 4 ? substr('abcde', 0, -4) : '0').':'.substr($ip, -4, 4);
272
- // Normalizing hextets number
273
- }elseif(strpos($ip, '::') !== false){
274
- $ip = str_replace('::', str_repeat(':0', 8 - substr_count($ip, ':')).':', $ip);
275
- $ip = strpos($ip, ':') === 0 ? '0'.$ip : $ip;
276
- $ip = strpos(strrev($ip), ':') === 0 ? $ip.'0' : $ip;
277
- }
278
- // Simplifyng hextets
279
- if(preg_match('/:0(?=[a-z0-9]+)/', $ip)){
280
- $ip = preg_replace('/:0(?=[a-z0-9]+)/', ':', strtolower($ip));
281
- $ip = self::ip__v6_normalize($ip);
282
- }
283
- return $ip;
284
- }
285
-
286
- /**
287
- * Reduce IPv6
288
- * param (string) $ip
289
- * returns (string) IPv6
290
- */
291
- static public function ip__v6_reduce($ip){
292
- if(strpos($ip, ':') !== false){
293
- $ip = preg_replace('/:0{1,4}/', ':', $ip);
294
- $ip = preg_replace('/:{2,}/', '::', $ip);
295
- $ip = strpos($ip, '0') === 0 ? substr($ip, 1) : $ip;
296
- }
297
- return $ip;
298
- }
299
-
300
- static public function ip__resolve__cleantalks($ip){
301
- if(CleantalkHelper::ip__validate($ip)){
302
- $url = array_search($ip, self::$cleantalks_servers);
303
- return $url
304
- ? $url
305
- : self::ip__resolve($ip);
306
- }else
307
- return $ip;
308
- }
309
-
310
- static public function ip__resolve($ip){
311
- if(CleantalkHelper::ip__validate($ip)){
312
- $url = gethostbyaddr($ip);
313
- if($url)
314
- return $url;
315
- }
316
- return $ip;
317
- }
318
-
319
- static public function dns__resolve($host, $out = false){
320
-
321
- // Get DNS records about URL
322
- if(function_exists('dns_get_record')){
323
- $records = dns_get_record($host, DNS_A);
324
- if($records !== false) {
325
- $out = $records[0]['ip'];
326
- }
327
- }
328
-
329
- // Another try if first failed
330
- if(!$out && function_exists('gethostbynamel')){
331
- $records = gethostbynamel($host);
332
- if($records !== false){
333
- $out = $records[0];
334
- }
335
- }
336
-
337
- return $out;
338
-
339
- }
340
-
341
  /**
342
  * Function sends raw http request
343
  *
344
  * May use 4 presets(combining possible):
345
- * get_code - getting only HTTP response code
346
- * dont_wait_for_answer - async requests
347
- * get - GET-request
348
- * ssl - use SSL
349
- *
350
- * @param string $url URL
351
- * @param array $data POST|GET indexed array with data to send
352
- * @param string|array $presets String or Array with presets: get_code, dont_wait_for_answer, get, ssl, dont_split_to_array
353
- * @param array $opts Optional option for CURL connection
354
- *
355
- * @return array (array || array('error' => true))
356
  */
357
  static public function http__request($url, $data = array(), $presets = null, $opts = array())
358
  {
359
- if(function_exists('curl_init')){
360
-
361
- $ch = curl_init();
362
-
363
- // Merging OBLIGATORY options with GIVEN options
364
- $opts = self::array_merge__save_numeric_keys(
365
- array(
366
- CURLOPT_URL => $url,
367
- CURLOPT_RETURNTRANSFER => true,
368
- CURLOPT_CONNECTTIMEOUT_MS => 3000,
369
- CURLOPT_FORBID_REUSE => true,
370
- CURLOPT_USERAGENT => 'APBCT-wordpress/'.(defined('APBCT_VERSION') ? APBCT_VERSION : 'unknown').'; '.get_bloginfo('url'),
371
- CURLOPT_POST => true,
372
- CURLOPT_POSTFIELDS => str_replace("&amp;", "&", http_build_query($data)),
373
- CURLOPT_SSL_VERIFYPEER => false,
374
- CURLOPT_SSL_VERIFYHOST => 0,
375
- CURLOPT_HTTPHEADER => array('Expect:'), // Fix for large data and old servers http://php.net/manual/ru/function.curl-setopt.php#82418
376
- CURLOPT_FOLLOWLOCATION => true,
377
- CURLOPT_MAXREDIRS => 5,
378
- ),
379
- $opts
380
- );
381
-
382
- // Use presets
383
- $presets = is_array($presets) ? $presets : explode(' ', $presets);
384
- foreach($presets as $preset){
385
-
386
- switch($preset){
387
-
388
- // Do not follow redirects
389
- case 'dont_follow_redirects':
390
- $opts[CURLOPT_FOLLOWLOCATION] = false;
391
- $opts[CURLOPT_MAXREDIRS] = 0;
392
- break;
393
-
394
- // Get headers only
395
- case 'get_code':
396
- $opts[CURLOPT_HEADER] = true;
397
- $opts[CURLOPT_NOBODY] = true;
398
- break;
399
-
400
- // Make a request, don't wait for an answer
401
- case 'dont_wait_for_answer':
402
- $opts[CURLOPT_CONNECTTIMEOUT_MS] = 1000;
403
- $opts[CURLOPT_TIMEOUT_MS] = 500;
404
- break;
405
-
406
- case 'get':
407
- $opts[CURLOPT_URL] .= '?'.str_replace("&amp;", "&", http_build_query($data));
408
- $opts[CURLOPT_POST] = false;
409
- $opts[CURLOPT_POSTFIELDS] = null;
410
- break;
411
-
412
- case 'ssl':
413
- $opts[CURLOPT_SSL_VERIFYPEER] = true;
414
- $opts[CURLOPT_SSL_VERIFYHOST] = 2;
415
- $opts[CURLOPT_CAINFO] = APBCT_CASERT_PATH;
416
- break;
417
-
418
- default:
419
-
420
- break;
421
- }
422
-
423
- } unset($preset);
424
-
425
- curl_setopt_array($ch, $opts);
426
- $result = curl_exec($ch);
427
-
428
- // RETURN if async request
429
- if(in_array('dont_wait_for_answer', $presets))
430
- return true;
431
-
432
- if($result){
433
-
434
- if(strpos($result, PHP_EOL) !== false && !in_array('dont_split_to_array', $presets))
435
- $result = explode(PHP_EOL, $result);
436
-
437
- // Get code crossPHP method
438
- if(in_array('get_code', $presets)){
439
- $curl_info = curl_getinfo($ch);
440
- $result = $curl_info['http_code'];
441
- }
442
- curl_close($ch);
443
- $out = $result;
444
- }else
445
- $out = array('error' => true, 'error_string' => curl_error($ch));
446
- }else
447
- $out = array('error' => true, 'error_string' => 'CURL_NOT_INSTALLED');
448
-
449
- /** Fix for get_code preset */
450
- if($presets && ($presets == 'get_code' || (is_array($presets) && in_array('get_code', $presets) ) )
451
- && isset($out['error_string']) && $out['error_string'] == 'CURL_NOT_INSTALLED'
452
- ){
453
- $headers = get_headers($url);
454
- $out = (int)preg_replace('/.*(\d{3}).*/', '$1', $headers[0]);
455
- }
456
-
457
- return $out;
458
- }
459
-
460
- /**
461
- * Merging arrays without reseting numeric keys
462
- *
463
- * @param array $arr1 One-dimentional array
464
- * @param array $arr2 One-dimentional array
465
- * @return array Merged array
466
- */
467
- public static function array_merge__save_numeric_keys($arr1, $arr2){
468
- foreach ($arr2 as $key => $val){
469
- $arr1[$key] = $val;
470
- }
471
- return $arr1;
472
- }
473
-
474
- /**
475
- * Merging arrays without reseting numeric keys recursive
476
- *
477
- * @param array $arr1 One-dimentional array
478
- * @param array $arr2 One-dimentional array
479
- * @return array Merged array
480
- */
481
- public static function array_merge__save_numeric_keys__recursive($arr1, $arr2){
482
- foreach ($arr2 as $key => $val){
483
- // Array | array => array
484
- if(isset($arr1[$key]) && is_array($arr1[$key]) && is_array($val)){
485
- $arr1[$key] = self::array_merge__save_numeric_keys__recursive($arr1[$key], $val);
486
- // Scalar | array => array
487
- }elseif(isset($arr1[$key]) && !is_array($arr1[$key]) && is_array($val)){
488
- $tmp = $arr1[$key] =
489
- $arr1[$key] = $val;
490
- $arr1[$key][] = $tmp;
491
- // array | scalar => array
492
- }elseif(isset($arr1[$key]) && is_array($arr1[$key]) && !is_array($val)){
493
- $arr1[$key][] = $val;
494
- // scalar | scalar => scalar
495
- }else{
496
- $arr1[$key] = $val;
497
- }
498
- }
499
- return $arr1;
500
- }
501
-
502
- /**
503
- * Function removing non UTF8 characters from array|string|object
504
- *
505
- * @param mixed(array|object|string) $data
506
- * @param type $data_codepage
507
- * @return mixed(array|object|string)
508
- */
509
- public static function removeNonUTF8($data, $data_codepage = null)
510
- {
511
- // Array || object
512
- if(is_array($data) || is_object($data)){
513
- foreach ($data as $key => &$val) {
514
- $val = self::removeNonUTF8($val, $data_codepage);
515
- }unset($key, $val);
516
-
517
- //String
518
- }else{
519
- if(!preg_match('//u', $data))
520
- $data = 'Nulled. Not UTF8 encoded or malformed.';
521
- }
522
- return $data;
523
- }
524
 
525
- /**
526
- * Function convert anything to UTF8 and removes non UTF8 characters
527
- *
528
- * @param mixed(array|object|string) $obj
529
- * @param type $data_codepage
530
- * @return mixed(array|object|string)
531
- */
532
- public static function toUTF8($obj, $data_codepage = null)
533
- {
534
- // Array || object
535
- if(is_array($obj) || is_object($obj)){
536
- foreach ($obj as $key => &$val) {
537
- $val = self::toUTF8($val, $data_codepage);
538
- }unset($key, $val);
539
-
540
- //String
541
- }else{
542
- if (!preg_match('//u', $obj) && function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')){
543
- $encoding = mb_detect_encoding($obj);
544
- $encoding = $encoding ? $encoding : $data_codepage;
545
- if ($encoding)
546
- $obj = mb_convert_encoding($obj, 'UTF-8', $encoding);
547
- }
548
- }
549
- return $obj;
550
- }
551
-
552
- /**
553
- * Function convert from UTF8
554
- *
555
- * @param mixed (array|object|string)
556
- * @param string
557
- * @return mixed (array|object|string)
558
- */
559
- public static function fromUTF8($obj, $data_codepage = null)
560
- {
561
- // Array || object
562
- if(is_array($obj) || is_object($obj)){
563
- foreach ($obj as $key => &$val) {
564
- $val = self::fromUTF8($val, $data_codepage);
565
- }unset($key, $val);
566
-
567
- //String
568
- }else{
569
- if(preg_match('u', $obj) && function_exists('mb_convert_encoding') && $data_codepage !== null)
570
- $obj = mb_convert_encoding($obj, $data_codepage, 'UTF-8');
571
- }
572
- return $obj;
573
- }
574
-
575
- /**
576
- * Checks if the string is JSON type
577
- * @param string
578
- * @return bool
579
- */
580
- static public function is_json($string)
581
- {
582
- return is_string($string) && is_array(json_decode($string, true)) ? true : false;
583
- }
584
-
585
- // Escapes MySQL params
586
- public static function db__prepare_param($param, $quotes = '\''){
587
- if(is_array($param)){
588
- foreach($param as &$par){
589
- $par = self::db__prepare_param($par);
590
- }
591
- }
592
- global $wpdb;
593
- if(is_numeric($param)) $param = intval($param);
594
- if(is_string($param)) $param = $quotes.$wpdb->_real_escape($param).$quotes;
595
- return $param;
596
  }
597
  }
1
  <?php
2
 
3
+ /**
4
+ * CleanTalk Cleantalk Antispam Helper class.
5
+ * Compatible only with Wordpress.
6
  *
7
+ * @depends CleantalkBase\CleantalkHelper
8
  *
9
  * @package Antispam Plugin by CleanTalk
10
  * @subpackage Helper
11
+ * @Version 1.0
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
15
+ * @see https://github.com/CleanTalk/wordpress-antispam
16
  */
17
 
18
+ class CleantalkHelper extends CleantalkBase\CleantalkHelper
19
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  /**
21
  * Function sends raw http request
22
  *
23
  * May use 4 presets(combining possible):
24
+ * get_code - getting only HTTP response code
25
+ * async - async requests
26
+ * get - GET-request
27
+ * ssl - use SSL
28
+ *
29
+ * @param string $url URL
30
+ * @param array $data POST|GET indexed array with data to send
31
+ * @param string|array $presets String or Array with presets: get_code, async, get, ssl, dont_split_to_array
32
+ * @param array $opts Optional option for CURL connection
33
+ *
34
+ * @return array|bool (array || array('error' => true))
35
  */
36
  static public function http__request($url, $data = array(), $presets = null, $opts = array())
37
  {
38
+ // Set APBCT User-Agent and passing data to parent method
39
+ $opts = self::array_merge__save_numeric_keys(
40
+ array(
41
+ CURLOPT_USERAGENT => 'APBCT-wordpress/' . (defined('APBCT_VERSION') ? APBCT_VERSION : 'unknown') . '; ' . get_bloginfo('url'),
42
+ ),
43
+ $opts
44
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
+ return parent::http__request($url, $data, $presets, $opts);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
  }
lib/CleantalkSFW.php CHANGED
@@ -1,112 +1,57 @@
1
  <?php
2
 
3
- /*
4
  * CleanTalk SpamFireWall Wordpress class
5
  * Compatible only with Wordpress.
6
- * Version 3.0-wp
7
- * author Cleantalk team (welcome@cleantalk.org)
8
- * copyright (C) 2014 CleanTalk team (http://cleantalk.org)
9
- * license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
10
- * see https://github.com/CleanTalk/php-antispam
 
 
 
11
  */
12
 
13
- class CleantalkSFW extends CleantalkSFW_Base
14
  {
15
 
 
 
 
 
16
  public function __construct()
17
  {
 
18
  // Creating database object. Depends on current CMS.
19
- $this->db = new CleantalkDB_Wordpress();
20
-
21
  // Use default tables if not specified
22
  $this->data_table = defined('APBCT_TBL_FIREWALL_DATA') ? APBCT_TBL_FIREWALL_DATA : $this->db->prefix . 'cleantalk_sfw';
23
  $this->log_table = defined('APBCT_TBL_FIREWALL_LOG') ? APBCT_TBL_FIREWALL_LOG : $this->db->prefix . 'cleantalk_sfw_logs';
24
-
25
- parent::__construct();
26
 
 
27
  }
28
 
29
- /*
30
- * Shows DIE page
31
- *
32
- * Stops script executing
33
- */
 
 
 
 
34
  public function sfw_die($api_key, $cookie_prefix = '', $cookie_domain = '', $test = false){
35
 
36
  global $apbct;
37
-
38
  // Statistics
39
  if(!empty($this->blocked_ips)){
40
  $apbct->stats['last_sfw_block']['time'] = time();
41
  $apbct->stats['last_sfw_block']['ip'] = $this->blocked_ips[key($this->blocked_ips)]['ip'];
42
  $apbct->save('stats');
43
  }
44
-
45
- // File exists?
46
- if(file_exists(CLEANTALK_PLUGIN_DIR . "inc/sfw_die_page.html")){
47
- $sfw_die_page = file_get_contents(CLEANTALK_PLUGIN_DIR . "inc/sfw_die_page.html");
48
- }else{
49
- wp_die("IP BLACKLISTED", "Blacklisted", Array('response'=>403), true);
50
- }
51
-
52
- // Translation
53
- $request_uri = $_SERVER['REQUEST_URI'];
54
- $sfw_die_page = str_replace('{SFW_DIE_NOTICE_IP}', __('SpamFireWall is activated for your IP ', 'cleantalk'), $sfw_die_page);
55
- $sfw_die_page = str_replace('{SFW_DIE_MAKE_SURE_JS_ENABLED}', __('To continue working with web site, please make sure that you have enabled JavaScript.', 'cleantalk'), $sfw_die_page);
56
- $sfw_die_page = str_replace('{SFW_DIE_CLICK_TO_PASS}', __('Please click below to pass protection,', 'cleantalk'), $sfw_die_page);
57
- $sfw_die_page = str_replace('{SFW_DIE_YOU_WILL_BE_REDIRECTED}', sprintf(__('Or you will be automatically redirected to the requested page after %d seconds.', 'cleantalk'), 1), $sfw_die_page);
58
- $sfw_die_page = str_replace('{CLEANTALK_TITLE}', __('Antispam by CleanTalk', 'cleantalk'), $sfw_die_page);
59
- $sfw_die_page = str_replace('{TEST_TITLE}', ($this->test ? __('This is the testing page for SpamFireWall', 'cleantalk') : ''), $sfw_die_page);
60
-
61
- if($this->test){
62
- $sfw_die_page = str_replace('{REAL_IP__HEADER}', 'Real IP:', $sfw_die_page);
63
- $sfw_die_page = str_replace('{TEST_IP__HEADER}', 'Test IP:', $sfw_die_page);
64
- $sfw_die_page = str_replace('{TEST_IP}', $this->all_ips['sfw_test']['ip'], $sfw_die_page);
65
- $sfw_die_page = str_replace('{REAL_IP}', $this->all_ips['real']['ip'], $sfw_die_page);
66
- $sfw_die_page = str_replace('{TEST_IP_BLOCKED}', $this->all_ips['sfw_test']['status'] == 1 ? 'Passed' : 'Blocked', $sfw_die_page);
67
- $sfw_die_page = str_replace('{REAL_IP_BLOCKED}', $this->all_ips['real']['status'] == 1 ? 'Passed' : 'Blocked', $sfw_die_page);
68
- }else{
69
- $sfw_die_page = str_replace('{REAL_IP__HEADER}', '', $sfw_die_page);
70
- $sfw_die_page = str_replace('{TEST_IP__HEADER}', '', $sfw_die_page);
71
- $sfw_die_page = str_replace('{TEST_IP}', '', $sfw_die_page);
72
- $sfw_die_page = str_replace('{REAL_IP}', '', $sfw_die_page);
73
- $sfw_die_page = str_replace('{TEST_IP_BLOCKED}', '', $sfw_die_page);
74
- $sfw_die_page = str_replace('{REAL_IP_BLOCKED}', '', $sfw_die_page);
75
- }
76
-
77
- $sfw_die_page = str_replace('{REMOTE_ADDRESS}', $this->blocked_ips ? $this->blocked_ips[key($this->blocked_ips)]['ip'] : '', $sfw_die_page);
78
-
79
- // Service info
80
- $sfw_die_page = str_replace('{REQUEST_URI}', $request_uri, $sfw_die_page);
81
- $sfw_die_page = str_replace('{COOKIE_PREFIX}', $cookie_prefix, $sfw_die_page);
82
- $sfw_die_page = str_replace('{COOKIE_DOMAIN}', $cookie_domain, $sfw_die_page);
83
- $sfw_die_page = str_replace('{SERVICE_ID}', $apbct->data['service_id'], $sfw_die_page);
84
- $sfw_die_page = str_replace('{HOST}', $_SERVER['HTTP_HOST'], $sfw_die_page);
85
-
86
- $sfw_die_page = str_replace(
87
- '{SFW_COOKIE}',
88
- $this->test
89
- ? $this->all_ips['sfw_test']['ip']
90
- : md5(current(end($this->blocked_ips)).$api_key), $sfw_die_page
91
- );
92
-
93
- if($this->debug){
94
- $debug = '<h1>IP and Networks</h1>'
95
- . var_export($this->all_ips, true)
96
- . '<h1>Headers</h1>'
97
- . var_export(apache_request_headers(), true)
98
- . '<h1>REMOTE_ADDR</h1>'
99
- . var_export($_SERVER['REMOTE_ADDR'], true)
100
- . '<h1>SERVER_ADDR</h1>'
101
- . var_export($_SERVER['SERVER_ADDR'], true)
102
- . '<h1>IP_ARRAY</h1>'
103
- . var_export($this->ip_array, true)
104
- . '<h1>ADDITIONAL</h1>'
105
- . var_export($this->debug_data, true);
106
- }else
107
- $debug = '';
108
-
109
- $sfw_die_page = str_replace( "{DEBUG}", $debug, $sfw_die_page );
110
 
111
  // Headers
112
  if(headers_sent() === false){
@@ -116,9 +61,77 @@ class CleantalkSFW extends CleantalkSFW_Base
116
  header('Pragma: no-cache');
117
  header("HTTP/1.0 403 Forbidden");
118
  }
119
- $sfw_die_page = str_replace('{GENERATED}', "<p>The page was generated at&nbsp;".date("D, d M Y H:i:s")."</p>",$sfw_die_page);
120
 
121
- wp_die($sfw_die_page, "Blacklisted", Array('response'=>403));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  }
124
  }
1
  <?php
2
 
3
+ /**
4
  * CleanTalk SpamFireWall Wordpress class
5
  * Compatible only with Wordpress.
6
+ *
7
+ * @depends CleantalkBase\CleantalkSFW
8
+ *
9
+ * @version 3.3
10
+ * @author Cleantalk team (welcome@cleantalk.org)
11
+ * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
12
+ * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
13
+ * @see https://github.com/CleanTalk/wordpress-antispam
14
  */
15
 
16
+ class CleantalkSFW extends CleantalkBase\CleantalkSFW
17
  {
18
 
19
+ /**
20
+ * CleantalkSFW_Base constructor.
21
+ * Creates Database driver instance.
22
+ */
23
  public function __construct()
24
  {
25
+
26
  // Creating database object. Depends on current CMS.
27
+ $this->db = CleantalkDB::getInstance();
28
+
29
  // Use default tables if not specified
30
  $this->data_table = defined('APBCT_TBL_FIREWALL_DATA') ? APBCT_TBL_FIREWALL_DATA : $this->db->prefix . 'cleantalk_sfw';
31
  $this->log_table = defined('APBCT_TBL_FIREWALL_LOG') ? APBCT_TBL_FIREWALL_LOG : $this->db->prefix . 'cleantalk_sfw_logs';
 
 
32
 
33
+ parent::__construct();
34
  }
35
 
36
+ /**
37
+ * Shows DIE page.
38
+ * Stops script executing.
39
+ *
40
+ * @param string $api_key
41
+ * @param string $cookie_prefix
42
+ * @param string $cookie_domain
43
+ * @param bool $test
44
+ */
45
  public function sfw_die($api_key, $cookie_prefix = '', $cookie_domain = '', $test = false){
46
 
47
  global $apbct;
48
+
49
  // Statistics
50
  if(!empty($this->blocked_ips)){
51
  $apbct->stats['last_sfw_block']['time'] = time();
52
  $apbct->stats['last_sfw_block']['ip'] = $this->blocked_ips[key($this->blocked_ips)]['ip'];
53
  $apbct->save('stats');
54
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  // Headers
57
  if(headers_sent() === false){
61
  header('Pragma: no-cache');
62
  header("HTTP/1.0 403 Forbidden");
63
  }
 
64
 
65
+ // File exists?
66
+ if(file_exists(CLEANTALK_PLUGIN_DIR . "inc/sfw_die_page.html")){
67
+
68
+ $sfw_die_page = file_get_contents(CLEANTALK_PLUGIN_DIR . "inc/sfw_die_page.html");
69
+
70
+ // Translation
71
+ $request_uri = $_SERVER['REQUEST_URI'];
72
+ $sfw_die_page = str_replace('{SFW_DIE_NOTICE_IP}', __('SpamFireWall is activated for your IP ', 'cleantalk'), $sfw_die_page);
73
+ $sfw_die_page = str_replace('{SFW_DIE_MAKE_SURE_JS_ENABLED}', __('To continue working with web site, please make sure that you have enabled JavaScript.', 'cleantalk'), $sfw_die_page);
74
+ $sfw_die_page = str_replace('{SFW_DIE_CLICK_TO_PASS}', __('Please click below to pass protection,', 'cleantalk'), $sfw_die_page);
75
+ $sfw_die_page = str_replace('{SFW_DIE_YOU_WILL_BE_REDIRECTED}', sprintf(__('Or you will be automatically redirected to the requested page after %d seconds.', 'cleantalk'), 1), $sfw_die_page);
76
+ $sfw_die_page = str_replace('{CLEANTALK_TITLE}', __('Antispam by CleanTalk', 'cleantalk'), $sfw_die_page);
77
+ $sfw_die_page = str_replace('{TEST_TITLE}', ($this->test ? __('This is the testing page for SpamFireWall', 'cleantalk') : ''), $sfw_die_page);
78
+
79
+ if($this->test){
80
+ $sfw_die_page = str_replace('{REAL_IP__HEADER}', 'Real IP:', $sfw_die_page);
81
+ $sfw_die_page = str_replace('{TEST_IP__HEADER}', 'Test IP:', $sfw_die_page);
82
+ $sfw_die_page = str_replace('{TEST_IP}', $this->all_ips['sfw_test']['ip'], $sfw_die_page);
83
+ $sfw_die_page = str_replace('{REAL_IP}', $this->all_ips['real']['ip'], $sfw_die_page);
84
+ $sfw_die_page = str_replace('{TEST_IP_BLOCKED}', $this->all_ips['sfw_test']['status'] == 1 ? 'Passed' : 'Blocked', $sfw_die_page);
85
+ $sfw_die_page = str_replace('{REAL_IP_BLOCKED}', $this->all_ips['real']['status'] == 1 ? 'Passed' : 'Blocked', $sfw_die_page);
86
+ }else{
87
+ $sfw_die_page = str_replace('{REAL_IP__HEADER}', '', $sfw_die_page);
88
+ $sfw_die_page = str_replace('{TEST_IP__HEADER}', '', $sfw_die_page);
89
+ $sfw_die_page = str_replace('{TEST_IP}', '', $sfw_die_page);
90
+ $sfw_die_page = str_replace('{REAL_IP}', '', $sfw_die_page);
91
+ $sfw_die_page = str_replace('{TEST_IP_BLOCKED}', '', $sfw_die_page);
92
+ $sfw_die_page = str_replace('{REAL_IP_BLOCKED}', '', $sfw_die_page);
93
+ }
94
+
95
+ $sfw_die_page = str_replace('{REMOTE_ADDRESS}', $this->blocked_ips ? $this->blocked_ips[key($this->blocked_ips)]['ip'] : '', $sfw_die_page);
96
+
97
+ // Service info
98
+ $sfw_die_page = str_replace('{REQUEST_URI}', $request_uri, $sfw_die_page);
99
+ $sfw_die_page = str_replace('{COOKIE_PREFIX}', $cookie_prefix, $sfw_die_page);
100
+ $sfw_die_page = str_replace('{COOKIE_DOMAIN}', $cookie_domain, $sfw_die_page);
101
+ $sfw_die_page = str_replace('{SERVICE_ID}', $apbct->data['service_id'], $sfw_die_page);
102
+ $sfw_die_page = str_replace('{HOST}', $_SERVER['HTTP_HOST'], $sfw_die_page);
103
+
104
+ $sfw_die_page = str_replace(
105
+ '{SFW_COOKIE}',
106
+ $this->test
107
+ ? $this->all_ips['sfw_test']['ip']
108
+ : md5(current(end($this->blocked_ips)).$api_key), $sfw_die_page
109
+ );
110
+
111
+ if($this->debug){
112
+ $debug = '<h1>IP and Networks</h1>'
113
+ . var_export($this->all_ips, true)
114
+ . '<h1>Headers</h1>'
115
+ . var_export(apache_request_headers(), true)
116
+ . '<h1>REMOTE_ADDR</h1>'
117
+ . var_export($_SERVER['REMOTE_ADDR'], true)
118
+ . '<h1>SERVER_ADDR</h1>'
119
+ . var_export($_SERVER['SERVER_ADDR'], true)
120
+ . '<h1>IP_ARRAY</h1>'
121
+ . var_export($this->ip_array, true)
122
+ . '<h1>ADDITIONAL</h1>'
123
+ . var_export($this->debug_data, true);
124
+ }else
125
+ $debug = '';
126
+
127
+ $sfw_die_page = str_replace( "{DEBUG}", $debug, $sfw_die_page );
128
+ $sfw_die_page = str_replace('{GENERATED}', "<p>The page was generated at&nbsp;".date("D, d M Y H:i:s")."</p>",$sfw_die_page);
129
+
130
+ wp_die($sfw_die_page, "Blacklisted", Array('response'=>403));
131
+
132
+ }else{
133
+ wp_die("IP BLACKLISTED", "Blacklisted", Array('response'=>403));
134
+ }
135
 
136
  }
137
  }
lib/CleantalkState.php CHANGED
@@ -1,18 +1,33 @@
1
  <?php
2
 
3
- /*
4
- *
5
  * CleanTalk Antispam State class
6
  *
7
  * @package Antiospam Plugin by CleanTalk
8
  * @subpackage State
9
- * @Version 1.0
10
  * @author Cleantalk team (welcome@cleantalk.org)
11
  * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
12
  * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
13
- *
14
  */
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  class CleantalkState
17
  {
18
  public $user = null;
@@ -27,16 +42,16 @@ class CleantalkState
27
  'autoPubRevelantMess' => 0,
28
 
29
  /* Forms for protection */
30
- 'registrations_test' => 1,
31
- 'comments_test' => 1,
32
- 'contact_forms_test' => 1,
33
- 'general_contact_forms_test' => 1, // Antispam test for unsupported and untested contact forms
34
- 'wc_checkout_test' => 0, // WooCommerce checkout default test => OFF
35
- 'wc_register_from_order' => 1, // Woocommerce registration during checkout => ON
36
- 'search_test' => 1, // Test deafult Wordpress form
37
- 'check_external' => 0,
38
- 'check_internal' => 0,
39
- // 'validate_email_existence' => 1,
40
 
41
  /* Comments and messages */
42
  'bp_private_messages' => 1, //buddyPress private messages test => ON
@@ -86,11 +101,10 @@ class CleantalkState
86
 
87
  // Plugin data
88
  'plugin_version' => APBCT_VERSION,
89
- 'user_token' => '', // User token
90
- 'js_keys' => array(), // Keys to do JavaScript antispam test
91
- 'js_keys_store_days' => 14, // JavaScript keys store days - 8 days now
92
- 'js_key_lifetime' => 86400, // JavaScript key life time in seconds - 1 day now
93
- 'last_remote_call' => 0, //Timestam of last remote call
94
 
95
  // Account data
96
  'service_id' => 0,
@@ -131,12 +145,12 @@ class CleantalkState
131
  'blocked' => 0,
132
  // 'since' => date('d M'),
133
  ),
134
- 'connection_reports' => array(
135
- 'success' => 0,
136
- 'negative' => 0,
137
- 'negative_report' => array(),
138
- // 'since' => date('d M'),
139
- ),
140
 
141
  // A-B tests
142
  'ab_test' => array(
@@ -152,7 +166,7 @@ class CleantalkState
152
  'feedback_request' => '',
153
  'key_is_ok' => 0,
154
  'salt' => '',
155
- );
156
 
157
  public $def_network_data = array(
158
  'allow_custom_key' => 0,
@@ -178,6 +192,15 @@ class CleantalkState
178
  'install_plugin' => array(
179
  'last_call' => 0,
180
  ),
 
 
 
 
 
 
 
 
 
181
  'uninstall_plugin' => array(
182
  'last_call' => 0,
183
  ),
@@ -185,7 +208,7 @@ class CleantalkState
185
  'last_call' => 0,
186
  ),
187
  );
188
-
189
  public $def_stats = array(
190
  'sfw' => array(
191
  'last_send_time' => 0,
@@ -208,9 +231,14 @@ class CleantalkState
208
  ),
209
  )
210
  );
211
-
212
-
213
-
 
 
 
 
 
214
  public function __construct($option_prefix, $options = array('settings'), $wpms = false)
215
  {
216
  $this->option_prefix = $option_prefix;
@@ -258,6 +286,11 @@ class CleantalkState
258
  }
259
  }
260
 
 
 
 
 
 
261
  private function getOption($option_name)
262
  {
263
  $option = get_option('cleantalk_'.$option_name, null);
@@ -266,8 +299,15 @@ class CleantalkState
266
  : $option;
267
  }
268
 
 
 
 
 
 
 
 
269
  public function save($option_name, $use_perfix = true, $autoload = true)
270
- {
271
  $option_name_to_save = $use_perfix ? $this->option_prefix.'_'.$option_name : $option_name;
272
  $arr = array();
273
  foreach($this->$option_name as $key => $value){
@@ -276,56 +316,84 @@ class CleantalkState
276
  update_option($option_name_to_save, $arr, $autoload);
277
  }
278
 
 
 
 
279
  public function saveSettings()
280
  {
281
  update_option($this->option_prefix.'_settings', (array)$this->settings);
282
  }
283
 
 
 
 
284
  public function saveData()
285
  {
286
  update_option($this->option_prefix.'_data', (array)$this->data);
287
  }
288
 
 
 
 
289
  public function saveErrors()
290
  {
291
  update_option($this->option_prefix.'_errors', (array)$this->errors);
292
  }
293
 
 
 
 
294
  public function saveNetworkData()
295
- {
296
  update_site_option($this->option_prefix.'_network_data', $this->network_data);
297
  }
298
 
 
 
 
 
 
 
299
  public function deleteOption($option_name, $use_prefix = false)
300
  {
301
  if($this->__isset($option_name)){
302
  $this->__unset($option_name);
303
  delete_option( ($use_prefix ? $this->option_prefix.'_' : '') . $option_name);
304
- }
305
  }
306
 
307
  /**
308
  * Prepares an adds an error to the plugin's data
309
  *
310
- * @param string type
311
- * @param mixed array || string
 
 
 
312
  * @returns null
313
  */
314
  public function error_add($type, $error, $major_type = null, $set_time = true)
315
  {
316
  $error = is_array($error)
317
- ? $error['error_string']
318
  : $error;
319
 
 
 
 
 
 
 
 
320
  $error = array(
321
- 'error_string' => $error,
322
- 'error_time' => $set_time ? current_time('timestamp') : null,
323
  );
324
 
325
  if(!empty($major_type)){
326
  $this->errors[$major_type][$type] = $error;
327
  }else{
328
- $this->errors[$type] = $error;
329
  }
330
 
331
  $this->saveErrors();
@@ -334,12 +402,15 @@ class CleantalkState
334
  /**
335
  * Deletes an error from the plugin's data
336
  *
337
- * @param mixed (array of strings || string 'elem1 elem2...' || string 'elem') type
338
- * @param delay saving
 
 
339
  * @returns null
340
  */
341
  public function error_delete($type, $save_flag = false, $major_type = null)
342
  {
 
343
  if(is_string($type))
344
  $type = explode(' ', $type);
345
 
@@ -361,7 +432,8 @@ class CleantalkState
361
  /**
362
  * Deletes all errors from the plugin's data
363
  *
364
- * @param delay saving
 
365
  * @returns null
366
  */
367
  public function error_delete_all($save_flag = false)
@@ -371,7 +443,15 @@ class CleantalkState
371
  $this->saveErrors();
372
  }
373
 
374
- public function __set($name, $value)
 
 
 
 
 
 
 
 
375
  {
376
  $this->storage[$name] = $value;
377
  if(isset($this->storage['data']) && array_key_exists($name, $this->storage['data'])){
@@ -379,7 +459,15 @@ class CleantalkState
379
  }
380
  }
381
 
382
- public function __get($name)
 
 
 
 
 
 
 
 
383
  {
384
  // First check in storage
385
  if (array_key_exists($name, $this->storage)){
@@ -402,25 +490,15 @@ class CleantalkState
402
  return $this->storage[$name];
403
  }
404
 
405
- }
406
-
407
- public function __isset($name)
408
- {
409
- return isset($this->storage[$name]);
410
- }
411
-
412
- public function __unset($name)
413
- {
414
- unset($this->storage[$name]);
415
- }
416
 
417
- public function __call($name, $arguments)
418
  {
419
- error_log ("Calling method '$name' with arguments: " . implode(', ', $arguments). "\n");
420
- }
421
 
422
- public static function __callStatic($name, $arguments)
423
  {
424
- error_log("Calling static method '$name' with arguments: " . implode(', ', $arguments). "\n");
425
- }
426
  }
1
  <?php
2
 
3
+ /**
 
4
  * CleanTalk Antispam State class
5
  *
6
  * @package Antiospam Plugin by CleanTalk
7
  * @subpackage State
8
+ * @Version 2.0
9
  * @author Cleantalk team (welcome@cleantalk.org)
10
  * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
11
  * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
 
12
  */
13
 
14
+ /**
15
+ * @property mixed settings
16
+ * @property mixed moderate_ip
17
+ * @property mixed|string plugin_version
18
+ * @property mixed|string db_prefix
19
+ * @property bool|mixed white_label
20
+ * @property string settings_link
21
+ * @property mixed data
22
+ * @property int key_is_ok
23
+ * @property string logo__small__colored
24
+ * @property string logo__small
25
+ * @property string logo
26
+ * @property string plugin_name
27
+ * @property string base_name
28
+ * @property array|mixed errors
29
+ * @property ArrayObject network_data
30
+ */
31
  class CleantalkState
32
  {
33
  public $user = null;
42
  'autoPubRevelantMess' => 0,
43
 
44
  /* Forms for protection */
45
+ 'registrations_test' => 1,
46
+ 'comments_test' => 1,
47
+ 'contact_forms_test' => 1,
48
+ 'general_contact_forms_test' => 1, // Antispam test for unsupported and untested contact forms
49
+ 'wc_checkout_test' => 0, // WooCommerce checkout default test => OFF
50
+ 'wc_register_from_order' => 1, // Woocommerce registration during checkout => ON
51
+ 'search_test' => 1, // Test deafult Wordpress form
52
+ 'check_external' => 0,
53
+ 'check_external__capture_buffer' => 0,
54
+ 'check_internal' => 0,
55
 
56
  /* Comments and messages */
57
  'bp_private_messages' => 1, //buddyPress private messages test => ON
101
 
102
  // Plugin data
103
  'plugin_version' => APBCT_VERSION,
104
+ 'js_keys' => array(), // Keys to do JavaScript antispam test
105
+ 'js_keys_store_days' => 14, // JavaScript keys store days - 8 days now
106
+ 'js_key_lifetime' => 86400, // JavaScript key life time in seconds - 1 day now
107
+ 'last_remote_call' => 0, //Timestam of last remote call
 
108
 
109
  // Account data
110
  'service_id' => 0,
145
  'blocked' => 0,
146
  // 'since' => date('d M'),
147
  ),
148
+ 'connection_reports' => array(
149
+ 'success' => 0,
150
+ 'negative' => 0,
151
+ 'negative_report' => array(),
152
+ // 'since' => date('d M'),
153
+ ),
154
 
155
  // A-B tests
156
  'ab_test' => array(
166
  'feedback_request' => '',
167
  'key_is_ok' => 0,
168
  'salt' => '',
169
+ );
170
 
171
  public $def_network_data = array(
172
  'allow_custom_key' => 0,
192
  'install_plugin' => array(
193
  'last_call' => 0,
194
  ),
195
+ 'activate_plugin' => array(
196
+ 'last_call' => 0,
197
+ ),
198
+ 'insert_auth_key' => array(
199
+ 'last_call' => 0,
200
+ ),
201
+ 'deactivate_plugin' => array(
202
+ 'last_call' => 0,
203
+ ),
204
  'uninstall_plugin' => array(
205
  'last_call' => 0,
206
  ),
208
  'last_call' => 0,
209
  ),
210
  );
211
+
212
  public $def_stats = array(
213
  'sfw' => array(
214
  'last_send_time' => 0,
231
  ),
232
  )
233
  );
234
+
235
+ /**
236
+ * CleantalkState constructor.
237
+ *
238
+ * @param string $option_prefix Database settings prefix
239
+ * @param array $options Array of strings. Types of settings you want to get.
240
+ * @param bool $wpms Is multisite?
241
+ */
242
  public function __construct($option_prefix, $options = array('settings'), $wpms = false)
243
  {
244
  $this->option_prefix = $option_prefix;
286
  }
287
  }
288
 
289
+ /**
290
+ * Get specified option from database
291
+ *
292
+ * @param string $option_name
293
+ */
294
  private function getOption($option_name)
295
  {
296
  $option = get_option('cleantalk_'.$option_name, null);
299
  : $option;
300
  }
301
 
302
+ /**
303
+ * Save option to database
304
+ *
305
+ * @param string $option_name
306
+ * @param bool $use_perfix
307
+ * @param bool $autoload Use autoload flag?
308
+ */
309
  public function save($option_name, $use_perfix = true, $autoload = true)
310
+ {
311
  $option_name_to_save = $use_perfix ? $this->option_prefix.'_'.$option_name : $option_name;
312
  $arr = array();
313
  foreach($this->$option_name as $key => $value){
316
  update_option($option_name_to_save, $arr, $autoload);
317
  }
318
 
319
+ /**
320
+ * Save PREFIX_setting to DB.
321
+ */
322
  public function saveSettings()
323
  {
324
  update_option($this->option_prefix.'_settings', (array)$this->settings);
325
  }
326
 
327
+ /**
328
+ * Save PREFIX_data to DB.
329
+ */
330
  public function saveData()
331
  {
332
  update_option($this->option_prefix.'_data', (array)$this->data);
333
  }
334
 
335
+ /**
336
+ * Save PREFIX_error to DB.
337
+ */
338
  public function saveErrors()
339
  {
340
  update_option($this->option_prefix.'_errors', (array)$this->errors);
341
  }
342
 
343
+ /**
344
+ * Save PREFIX_network_data to DB.
345
+ */
346
  public function saveNetworkData()
347
+ {
348
  update_site_option($this->option_prefix.'_network_data', $this->network_data);
349
  }
350
 
351
+ /**
352
+ * Unset and delete option from DB.
353
+ *
354
+ * @param string $option_name
355
+ * @param bool $use_prefix
356
+ */
357
  public function deleteOption($option_name, $use_prefix = false)
358
  {
359
  if($this->__isset($option_name)){
360
  $this->__unset($option_name);
361
  delete_option( ($use_prefix ? $this->option_prefix.'_' : '') . $option_name);
362
+ }
363
  }
364
 
365
  /**
366
  * Prepares an adds an error to the plugin's data
367
  *
368
+ * @param string $type Error type/subtype
369
+ * @param string|array $error Error
370
+ * @param string $major_type Error major type
371
+ * @param bool $set_time Do we need to set time of this error
372
+ *
373
  * @returns null
374
  */
375
  public function error_add($type, $error, $major_type = null, $set_time = true)
376
  {
377
  $error = is_array($error)
378
+ ? $error['error']
379
  : $error;
380
 
381
+ // Exceptions
382
+ if( ($type == 'send_logs' && $error == 'NO_LOGS_TO_SEND') ||
383
+ ($type == 'send_firewall_logs' && $error == 'NO_LOGS_TO_SEND') ||
384
+ $error == 'LOG_FILE_NOT_EXISTS'
385
+ )
386
+ return;
387
+
388
  $error = array(
389
+ 'error' => $error,
390
+ 'error_time' => $set_time ? current_time('timestamp') : null,
391
  );
392
 
393
  if(!empty($major_type)){
394
  $this->errors[$major_type][$type] = $error;
395
  }else{
396
+ $this->errors[$type] = $error;
397
  }
398
 
399
  $this->saveErrors();
402
  /**
403
  * Deletes an error from the plugin's data
404
  *
405
+ * @param array|string $type Error type to delete
406
+ * @param bool $save_flag Do we need to save data after error was deleted
407
+ * @param string $major_type Error major type to delete
408
+ *
409
  * @returns null
410
  */
411
  public function error_delete($type, $save_flag = false, $major_type = null)
412
  {
413
+ /** @noinspection DuplicatedCode */
414
  if(is_string($type))
415
  $type = explode(' ', $type);
416
 
432
  /**
433
  * Deletes all errors from the plugin's data
434
  *
435
+ * @param bool $save_flag Do we need to save data after all errors was deleted
436
+ *
437
  * @returns null
438
  */
439
  public function error_delete_all($save_flag = false)
443
  $this->saveErrors();
444
  }
445
 
446
+ /**
447
+ * Magic.
448
+ * Add new variables to storage[NEW_VARIABLE]
449
+ * And duplicates it in storage['data'][NEW_VARIABLE]
450
+ *
451
+ * @param string $name
452
+ * @param mixed $value
453
+ */
454
+ public function __set($name, $value)
455
  {
456
  $this->storage[$name] = $value;
457
  if(isset($this->storage['data']) && array_key_exists($name, $this->storage['data'])){
459
  }
460
  }
461
 
462
+ /**
463
+ * Magic.
464
+ * Search and get param from: storage, data, api_key, database
465
+ *
466
+ * @param $name
467
+ *
468
+ * @return mixed
469
+ */
470
+ public function __get($name)
471
  {
472
  // First check in storage
473
  if (array_key_exists($name, $this->storage)){
490
  return $this->storage[$name];
491
  }
492
 
493
+ }
 
 
 
 
 
 
 
 
 
 
494
 
495
+ public function __isset($name)
496
  {
497
+ return isset($this->storage[$name]);
498
+ }
499
 
500
+ public function __unset($name)
501
  {
502
+ unset($this->storage[$name]);
503
+ }
504
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: safronik
3
  Tags: spam, antispam, protection, comments, firewall
4
  Requires at least: 3.0
5
  Tested up to: 5.3
6
- Stable tag: 5.123
7
  License: GPLv2
8
 
9
  Spam protection, antispam, all-in-one, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
@@ -575,6 +575,16 @@ If your website has forms that send data to external sources, you can enable opt
575
  10. Website's options.
576
 
577
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
578
  = 5.123 July 25 2019 =
579
  * Fix: Plenty of minor fixes.
580
  * Fix: wpDiscuz integration.
@@ -1956,6 +1966,16 @@ If your website has forms that send data to external sources, you can enable opt
1956
  * First version
1957
 
1958
  == Upgrade Notice ==
 
 
 
 
 
 
 
 
 
 
1959
  = 5.123 July 25 2019 =
1960
  * Fix: Plenty of minor fixes.
1961
  * Fix: wpDiscuz integration.
3
  Tags: spam, antispam, protection, comments, firewall
4
  Requires at least: 3.0
5
  Tested up to: 5.3
6
+ Stable tag: 5.124
7
  License: GPLv2
8
 
9
  Spam protection, antispam, all-in-one, premium plugin. No spam comments & users, no spam contact form & WooCommerce anti-spam.
575
  10. Website's options.
576
 
577
  == Changelog ==
578
+ = 5.124 August 8 2019 =
579
+ * Spam protection improved.
580
+ * Fix: SpamFireWall local database counter on Multisite.
581
+ * Fix: Caldera Forms integration.
582
+ * Fix: Settings "Use AJAX for JS check" description.
583
+ * Fix: Formidable integration.
584
+ * New: External forms check now independed from JavaScript.
585
+ * New: Setting Protect external - capture buffer.
586
+ * New: QuForm integration.
587
+
588
  = 5.123 July 25 2019 =
589
  * Fix: Plenty of minor fixes.
590
  * Fix: wpDiscuz integration.
1966
  * First version
1967
 
1968
  == Upgrade Notice ==
1969
+ = 5.124 August 8 2019 =
1970
+ * Spam protection improved.
1971
+ * Fix: SpamFireWall local database counter on Multisite.
1972
+ * Fix: Caldera Forms integration.
1973
+ * Fix: Settings "Use AJAX for JS check" description.
1974
+ * Fix: Formidable integration.
1975
+ * New: External forms check now independed from JavaScript.
1976
+ * New: Setting Protect external - capture buffer.
1977
+ * New: QuForm integration.
1978
+
1979
  = 5.123 July 25 2019 =
1980
  * Fix: Plenty of minor fixes.
1981
  * Fix: wpDiscuz integration.