Spam protection, AntiSpam, FireWall by CleanTalk - Version 5.177

Version Description

May 12 2022 =

WP 6.0 compatibility, Email Encoder added, Common HTTP API implemented, Honeypot fields improved and some minor issues fixed.

  • New. Email Encode functionality added.
  • New. cleantalk-common.php. Honeypot field value and source now sends in sender_info.
  • New. ct_preprocess_comment(). Honeypot field source now sends in sender_info.
  • New. HTTP API. Common CleanTalk http library added.
  • New. Public integrations. Honeypot field for search form.
  • New. WP 6.0 compatibility.
  • Fix: EZ Form Calculator - clearing the message
  • Fix. Common. Checking all post data fixed.
  • Imp. Settings. "Hide website" field moved to "different" section.
  • Imp. Settings. "Hide website" type changed to checkbox from radio.
  • Imp. Settings. "Honeypot field" state changed to enabled by defaults.
  • Mod: Integration for Advanced Classifieds & Directory Pro - registration form
  • Fix. Custom ajax. Custom ajax handler usage removed completely.
  • Fix: Excluded the addition of visible fields in filter of The Events Calendar
  • Fix. cleantalk-common.php. Added search honeypot field signature to potential honeypot fields post values
  • Fix: MultiStep Checkout for WooCommerce - skipped step validation
  • Ref. cleantalk-public-integrations.php. Empty string converts to false - comparison removed.
  • fix: apbct_get_rest_url - returns the result of a get_rest_url() function if it exists
  • Mod: modified getting pixel_url.
  • Fix. apbct_init. Reduce multiple direct calls of apbct_get_pixel_url__ajax.
  • Fix: Cleantalk\Common\HTTP\Request. Timeout error while async request.
  • Fix. HTTP API. Process exception passed from WordPress \Requests class.
  • Fix. Cleantalk. Antispam class fixed.
  • Fix. API. Common API class fixed.
  • Fix. Comments checker. Pagination fixed.
  • Fix. Common. CleanTalk service request excluded.
Download this release

Release Info

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

Code changes from version 5.176 to 5.177

cleantalk.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: Anti-Spam by CleanTalk
5
  Plugin URI: https://cleantalk.org
6
  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.
7
- Version: 5.176
8
  Author: СleanTalk <welcome@cleantalk.org>
9
  Author URI: https://cleantalk.org
10
  Text Domain: cleantalk-spam-protect
@@ -141,6 +141,14 @@ if ( $apbct->settings['comments__disable_comments__all'] || $apbct->settings['co
141
  \Cleantalk\Antispam\DisableComments::getInstance();
142
  }
143
 
 
 
 
 
 
 
 
 
144
  add_action('rest_api_init', 'apbct_register_my_rest_routes');
145
  function apbct_register_my_rest_routes()
146
  {
@@ -398,6 +406,9 @@ add_filter('avf_form_send', 'apbct_form__enfold_contact_form__test_spam', 4, 10)
398
  // Profile Builder integration
399
  add_filter('wppb_output_field_errors_filter', 'apbct_form_profile_builder__check_register', 1, 3);
400
 
 
 
 
401
  // WP Foro register system integration
402
  add_filter('wpforo_create_profile', 'wpforo_create_profile__check_register', 1, 1);
403
 
@@ -1087,6 +1098,7 @@ function apbct_sfw_update__download_files($urls)
1087
 
1088
  if ( empty($results['error']) && ($count_urls === $count_results) ) {
1089
  $download_again = array();
 
1090
  for ( $i = 0; $i < $count_results; $i++ ) {
1091
  if ( $results[$i] === 'error' ) {
1092
  $download_again[] = $urls[$i];
@@ -2777,7 +2789,7 @@ function apbct_test_connection()
2777
 
2778
  foreach ( $url_to_test as $url ) {
2779
  $start = microtime(true);
2780
- $result = \Cleantalk\ApbctWP\Helper::httpRequestGetContent($url);
2781
 
2782
  $out[$url] = array(
2783
  'result' => ! empty($result['error']) ? $result['error'] : 'OK',
4
  Plugin Name: Anti-Spam by CleanTalk
5
  Plugin URI: https://cleantalk.org
6
  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.
7
+ Version: 5.177
8
  Author: СleanTalk <welcome@cleantalk.org>
9
  Author URI: https://cleantalk.org
10
  Text Domain: cleantalk-spam-protect
141
  \Cleantalk\Antispam\DisableComments::getInstance();
142
  }
143
 
144
+ // Email encoder
145
+ if (
146
+ $apbct->key_is_ok &&
147
+ ( ! is_admin() || apbct_is_ajax() ) &&
148
+ $apbct->settings['data__email_decoder'] ) {
149
+ \Cleantalk\Antispam\EmailEncoder::getInstance();
150
+ }
151
+
152
  add_action('rest_api_init', 'apbct_register_my_rest_routes');
153
  function apbct_register_my_rest_routes()
154
  {
406
  // Profile Builder integration
407
  add_filter('wppb_output_field_errors_filter', 'apbct_form_profile_builder__check_register', 1, 3);
408
 
409
+ // Advanced Classifieds & Directory Pro
410
+ add_filter('acadp_is_spam', 'apbct_advanced_classifieds_directory_pro__check_register', 1, 2);
411
+
412
  // WP Foro register system integration
413
  add_filter('wpforo_create_profile', 'wpforo_create_profile__check_register', 1, 1);
414
 
1098
 
1099
  if ( empty($results['error']) && ($count_urls === $count_results) ) {
1100
  $download_again = array();
1101
+ $results = array_values($results);
1102
  for ( $i = 0; $i < $count_results; $i++ ) {
1103
  if ( $results[$i] === 'error' ) {
1104
  $download_again[] = $urls[$i];
2789
 
2790
  foreach ( $url_to_test as $url ) {
2791
  $start = microtime(true);
2792
+ $result = \Cleantalk\ApbctWP\Helper::httpRequestGetResponseCode($url);
2793
 
2794
  $out[$url] = array(
2795
  'result' => ! empty($result['error']) ? $result['error'] : 'OK',
inc/cleantalk-ajax.php CHANGED
@@ -661,6 +661,28 @@ function ct_ajax_hook($message_obj = null)
661
  $base_call_params['sender_info']['exception_description'] = apbct_is_exception_arg_request();
662
  }
663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
664
  $base_call_result = apbct_base_call($base_call_params);
665
  $ct_result = $base_call_result['ct_result'];
666
 
661
  $base_call_params['sender_info']['exception_description'] = apbct_is_exception_arg_request();
662
  }
663
 
664
+ // EZ Form Calculator - clearing the message
665
+ if (
666
+ apbct_is_plugin_active('ez-form-calculator-premium/ezfc.php') &&
667
+ Post::equal('action', 'ezfc_frontend')
668
+ ) {
669
+ if (!is_array($message)) {
670
+ $message = preg_split('/\r\n|\r|\n/', $message);
671
+ }
672
+
673
+ foreach ($message as $key => $string) {
674
+ if (
675
+ $string === '__HIDDEN__' ||
676
+ $string === '0' ||
677
+ (int)$string !== 0
678
+ ) {
679
+ unset($message[$key]);
680
+ }
681
+ }
682
+
683
+ $base_call_params['message'] = implode('\n', $message);
684
+ }
685
+
686
  $base_call_result = apbct_base_call($base_call_params);
687
  $ct_result = $base_call_result['ct_result'];
688
 
inc/cleantalk-common.php CHANGED
@@ -18,8 +18,8 @@ function apbct_array($array)
18
  return new \Cleantalk\Common\Arr($array);
19
  }
20
 
21
- $ct_checkjs_frm = 'ct_checkjs_frm';
22
- $ct_checkjs_register_form = 'ct_checkjs_register_form';
23
 
24
  $apbct_cookie_request_id_label = 'request_id';
25
  $apbct_cookie_register_ok_label = 'register_ok';
@@ -211,14 +211,22 @@ function apbct_base_call($params = array(), $reg_flag = false)
211
  */
212
  if ( $apbct->settings['data__honeypot_field'] && ! isset($params['honeypot_field']) ) {
213
  $honeypot_field = 1;
214
-
215
- if (
216
- Post::get('wc_apbct_email_id') ||
217
- Post::get('apbct__email_id__wp_register') ||
218
- Post::get('apbct__email_id__wp_contact_form_7') ||
219
- Post::get('apbct__email_id__wp_wpforms')
220
- ) {
221
- $honeypot_field = 0;
 
 
 
 
 
 
 
 
222
  }
223
 
224
  $params['honeypot_field'] = $honeypot_field;
@@ -235,11 +243,7 @@ function apbct_base_call($params = array(), $reg_flag = false)
235
 
236
  $ct = new Cleantalk();
237
 
238
- $ct->use_bultin_api = $apbct->settings['wp__use_builtin_http_api'] ? true : false;
239
- $ct->ssl_on = $apbct->settings['data__ssl_on'];
240
- $ct->ssl_path = APBCT_CASERT_PATH;
241
-
242
- // Options store url without shceme because of DB error with ''://'
243
  $config = ct_get_server();
244
  $ct->server_url = APBCT_MODERATE_URL;
245
  $ct->work_url = preg_match('/https:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
@@ -651,6 +655,7 @@ function apbct_js_keys__get__ajax()
651
  function apbct_get_pixel_url__ajax($direct_call = false)
652
  {
653
  global $apbct;
 
654
  $pixel_hash = md5(
655
  Helper::ipGet()
656
  . $apbct->api_key
18
  return new \Cleantalk\Common\Arr($array);
19
  }
20
 
21
+ $ct_checkjs_frm = 'ct_checkjs_frm';
22
+ $ct_checkjs_register_form = 'ct_checkjs_register_form';
23
 
24
  $apbct_cookie_request_id_label = 'request_id';
25
  $apbct_cookie_register_ok_label = 'register_ok';
211
  */
212
  if ( $apbct->settings['data__honeypot_field'] && ! isset($params['honeypot_field']) ) {
213
  $honeypot_field = 1;
214
+ // collect probable sources
215
+ $honeypot_potential_values = array(
216
+ 'wc_apbct_email_id' => Post::get('wc_apbct_email_id'),
217
+ 'apbct__email_id__wp_register' => Post::get('apbct__email_id__wp_register'),
218
+ 'apbct__email_id__wp_contact_form_7' => Post::get('apbct__email_id__wp_contact_form_7'),
219
+ 'apbct__email_id__wp_wpforms' => Post::get('apbct__email_id__wp_wpforms'),
220
+ 'apbct__email_id__search_form' => Post::get('apbct__email_id__search_form')
221
+ );
222
+ // if source is filled then pass them to params as additional fields
223
+ foreach ($honeypot_potential_values as $source_name => $source_value) {
224
+ if ( $source_value ) {
225
+ $honeypot_field = 0;
226
+ $params['sender_info']['honeypot_field_value'] = $source_value;
227
+ $params['sender_info']['honeypot_field_source'] = $source_name;
228
+ break;
229
+ }
230
  }
231
 
232
  $params['honeypot_field'] = $honeypot_field;
243
 
244
  $ct = new Cleantalk();
245
 
246
+ // Options store url without scheme because of DB error with ''://'
 
 
 
 
247
  $config = ct_get_server();
248
  $ct->server_url = APBCT_MODERATE_URL;
249
  $ct->work_url = preg_match('/https:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
655
  function apbct_get_pixel_url__ajax($direct_call = false)
656
  {
657
  global $apbct;
658
+
659
  $pixel_hash = md5(
660
  Helper::ipGet()
661
  . $apbct->api_key
inc/cleantalk-pluggable.php CHANGED
@@ -156,6 +156,13 @@ function apbct_get_rest_url($blog_id = null, $path = '/', $scheme = 'rest')
156
  {
157
  global $wp_rewrite;
158
 
 
 
 
 
 
 
 
159
  if ( empty($path) ) {
160
  $path = '/';
161
  }
@@ -801,6 +808,14 @@ function apbct_is_skip_request($ajax = false)
801
  ) {
802
  return 'GiveWP';
803
  }
 
 
 
 
 
 
 
 
804
  } else {
805
  /*****************************************/
806
  /* Here is non-ajax requests skipping */
@@ -914,6 +929,13 @@ function apbct_is_skip_request($ajax = false)
914
  ) {
915
  return 'Restrict Content Pro Login Form skip';
916
  }
 
 
 
 
 
 
 
917
  }
918
 
919
  // Event Manager - there is the direct integration
156
  {
157
  global $wp_rewrite;
158
 
159
+ /**
160
+ * If exists get_rest_url() - return it
161
+ */
162
+ if ( function_exists('get_rest_url') ) {
163
+ return get_rest_url();
164
+ }
165
+
166
  if ( empty($path) ) {
167
  $path = '/';
168
  }
808
  ) {
809
  return 'GiveWP';
810
  }
811
+
812
+ // MultiStep Checkout for WooCommerce
813
+ if (
814
+ apbct_is_plugin_active('woo-multistep-checkout/woo-multistep-checkout.php') &&
815
+ Post::get('action') === 'thwmsc_step_validation'
816
+ ) {
817
+ return 'MultiStep Checkout for WooCommerce - step validation';
818
+ }
819
  } else {
820
  /*****************************************/
821
  /* Here is non-ajax requests skipping */
929
  ) {
930
  return 'Restrict Content Pro Login Form skip';
931
  }
932
+ // APBCT service actions
933
+ if (
934
+ apbct_is_plugin_active('cleantalk-spam-protect/cleantalk.php') &&
935
+ apbct_is_in_uri('wp-json/cleantalk-antispam/v1/check_email_before_post')
936
+ ) {
937
+ return 'APBCT service actions';
938
+ }
939
  }
940
 
941
  // Event Manager - there is the direct integration
inc/cleantalk-public-integrations.php CHANGED
@@ -1083,8 +1083,15 @@ function ct_preprocess_comment($comment)
1083
  if ( isset($apbct->settings['comments__hide_website_field']) && $apbct->settings['comments__hide_website_field'] ) {
1084
  $honeypot_field = 1;
1085
 
1086
- if ( isset($_POST['url']) && ! empty($_POST['url']) && $post_info['comment_type'] === 'comment' && isset($_POST['comment_post_ID']) ) {
 
 
 
 
1087
  $honeypot_field = 0;
 
 
 
1088
  }
1089
 
1090
  $base_call_data['honeypot_field'] = $honeypot_field;
@@ -3330,3 +3337,56 @@ function apbct_form_happyforms_test_spam($is_valid, $request, $_form)
3330
 
3331
  return $is_valid;
3332
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1083
  if ( isset($apbct->settings['comments__hide_website_field']) && $apbct->settings['comments__hide_website_field'] ) {
1084
  $honeypot_field = 1;
1085
 
1086
+ if (
1087
+ $post_info['comment_type'] === 'comment' &&
1088
+ Post::get('url') &&
1089
+ Post::get('comment_post_ID')
1090
+ ) {
1091
  $honeypot_field = 0;
1092
+ // if url is filled then pass them to $base_call_data as additional fields
1093
+ $base_call_data['sender_info']['honeypot_field_value'] = Post::get('url');
1094
+ $base_call_data['sender_info']['honeypot_field_source'] = 'url';
1095
  }
1096
 
1097
  $base_call_data['honeypot_field'] = $honeypot_field;
3337
 
3338
  return $is_valid;
3339
  }
3340
+
3341
+ function apbct_form_search__add_fields($form_html)
3342
+ {
3343
+ global $apbct;
3344
+ if ( is_string($form_html) && $apbct->settings['forms__search_test'] == 1 ) {
3345
+ return str_replace('</form>', ct_add_honeypot_field('search_form') . '</form>', $form_html);
3346
+ }
3347
+ return $form_html;
3348
+ }
3349
+
3350
+ /**
3351
+ * Advanced Classifieds & Directory Pro
3352
+ *
3353
+ * @param $response
3354
+ * @param $form_name
3355
+ *
3356
+ * @return mixed
3357
+ * @psalm-suppress UnusedVariable
3358
+ */
3359
+ function apbct_advanced_classifieds_directory_pro__check_register($response, $_form_name)
3360
+ {
3361
+ global $cleantalk_executed, $ct_comment;
3362
+
3363
+ if (
3364
+ Post::get('username') &&
3365
+ Post::get('email')
3366
+ ) {
3367
+ $data = ct_get_fields_any($_POST, Post::get('email'));
3368
+
3369
+ $base_call_result = apbct_base_call(
3370
+ array(
3371
+ 'message' => ! empty($data['message']) ? json_encode($data['message']) : '',
3372
+ 'sender_email' => ! empty($data['email']) ? $data['email'] : '',
3373
+ 'sender_nickname' => ! empty($data['nickname']) ? $data['nickname'] : '',
3374
+ 'post_info' => array(
3375
+ 'comment_type' => 'register_advanced_classifieds_directory_pro'
3376
+ ),
3377
+ ),
3378
+ true
3379
+ );
3380
+
3381
+ $ct_result = $base_call_result['ct_result'];
3382
+
3383
+ $cleantalk_executed = true;
3384
+
3385
+ if ( $ct_result->allow == 0 ) {
3386
+ $ct_comment = $ct_result->comment;
3387
+ ct_die(null, null);
3388
+ }
3389
+ }
3390
+
3391
+ return $response;
3392
+ }
inc/cleantalk-public.php CHANGED
@@ -19,7 +19,7 @@ function apbct_init()
19
  global $ct_jp_comments, $apbct;
20
 
21
  // Pixel
22
- if ( $apbct->settings['data__pixel'] ) {
23
  $apbct->pixel_url = apbct_get_pixel_url__ajax(true);
24
  }
25
 
@@ -37,6 +37,11 @@ function apbct_init()
37
  }
38
  }
39
 
 
 
 
 
 
40
  //fix for EPM registration form
41
  if ( Post::get('reg_email') && shortcode_exists('epm_registration_form') ) {
42
  unset($_POST['ct_checkjs_register_form']);
@@ -133,7 +138,7 @@ function apbct_init()
133
 
134
  //hook for Anonymous Post
135
  if ( $apbct->settings['data__general_postdata_test'] == 1 && empty(Post::get('ct_checkjs_cf7')) ) {
136
- add_action('wp', 'ct_contact_form_validate_postdata', 1);
137
  }
138
 
139
  if ( $apbct->settings['forms__general_contact_forms_test'] == 1 && empty(Post::get('ct_checkjs_cf7')) && ! apbct_is_direct_trackback() ) {
@@ -354,7 +359,7 @@ function apbct_init()
354
  ! is_admin() &&
355
  ! apbct_is_user_role_in(array('administrator', 'moderator'))
356
  ) {
357
- ct_contact_form_validate_postdata();
358
  }
359
  }
360
 
@@ -1311,9 +1316,9 @@ function apbct_enqueue_and_localize_public_scripts()
1311
  '_rest_nonce' => wp_create_nonce('wp_rest'),
1312
  '_ajax_url' => admin_url('admin-ajax.php', 'relative'),
1313
  '_rest_url' => esc_url(apbct_get_rest_url()),
1314
- '_apbct_ajax_url' => APBCT_URL_PATH . '/lib/Cleantalk/ApbctWP/Ajax.php',
1315
  'data__cookies_type' => $apbct->data['cookies_type'],
1316
  'data__ajax_type' => $apbct->data['ajax_type'],
 
1317
  ));
1318
 
1319
  wp_localize_script('ct_public', 'ctPublic', array(
19
  global $ct_jp_comments, $apbct;
20
 
21
  // Pixel
22
+ if ( $apbct->settings['data__pixel'] && empty($apbct->pixel_url) ) {
23
  $apbct->pixel_url = apbct_get_pixel_url__ajax(true);
24
  }
25
 
37
  }
38
  }
39
 
40
+ //Search form hook init
41
+ if ( $apbct->settings['forms__search_test'] ) {
42
+ add_filter('get_search_form', 'apbct_form_search__add_fields', 999);
43
+ }
44
+
45
  //fix for EPM registration form
46
  if ( Post::get('reg_email') && shortcode_exists('epm_registration_form') ) {
47
  unset($_POST['ct_checkjs_register_form']);
138
 
139
  //hook for Anonymous Post
140
  if ( $apbct->settings['data__general_postdata_test'] == 1 && empty(Post::get('ct_checkjs_cf7')) ) {
141
+ add_action('init', 'ct_contact_form_validate_postdata', 1000);
142
  }
143
 
144
  if ( $apbct->settings['forms__general_contact_forms_test'] == 1 && empty(Post::get('ct_checkjs_cf7')) && ! apbct_is_direct_trackback() ) {
359
  ! is_admin() &&
360
  ! apbct_is_user_role_in(array('administrator', 'moderator'))
361
  ) {
362
+ add_action('init', 'ct_contact_form_validate_postdata', 1000);
363
  }
364
  }
365
 
1316
  '_rest_nonce' => wp_create_nonce('wp_rest'),
1317
  '_ajax_url' => admin_url('admin-ajax.php', 'relative'),
1318
  '_rest_url' => esc_url(apbct_get_rest_url()),
 
1319
  'data__cookies_type' => $apbct->data['cookies_type'],
1320
  'data__ajax_type' => $apbct->data['ajax_type'],
1321
+ 'text__wait_for_decoding' => esc_html__('Wait for decoding...', 'cleantalk-spam-protect'),
1322
  ));
1323
 
1324
  wp_localize_script('ct_public', 'ctPublic', array(
inc/cleantalk-settings.php CHANGED
@@ -147,6 +147,16 @@ function apbct_settings__set_fileds()
147
  'childrens' => array('sfw__anti_flood', 'sfw__anti_crawler', 'sfw__use_delete_to_clear_table'),
148
  'long_description' => true,
149
  ),
 
 
 
 
 
 
 
 
 
 
150
  ),
151
  ),
152
 
@@ -341,15 +351,6 @@ function apbct_settings__set_fileds()
341
  ),
342
  'display' => ! $apbct->white_label,
343
  ),
344
- 'comments__hide_website_field' => array(
345
- 'title' => __('Hide the "Website" field', 'cleantalk-spam-protect'),
346
- 'description' => __(
347
- 'This option hides the "Website" field on the comment form.',
348
- 'cleantalk-spam-protect'
349
- ),
350
- 'long_description' => true,
351
- 'display' => ! $apbct->white_label,
352
- ),
353
  ),
354
  ),
355
 
@@ -518,6 +519,10 @@ function apbct_settings__set_fileds()
518
  ),
519
  'long_description' => true,
520
  ),
 
 
 
 
521
  ),
522
  ),
523
 
@@ -2784,5 +2789,5 @@ function apbct__send_local_settings_to_api($settings)
2784
  // Hostname
2785
  $hostname = preg_replace('/^(https?:)?(\/\/)?(www\.)?/', '', get_site_url());
2786
 
2787
- \Cleantalk\Common\API::methodSendLocalSettings($api_key, $hostname, $settings);
2788
  }
147
  'childrens' => array('sfw__anti_flood', 'sfw__anti_crawler', 'sfw__use_delete_to_clear_table'),
148
  'long_description' => true,
149
  ),
150
+ 'comments__hide_website_field' => array(
151
+ 'type' => 'checkbox',
152
+ 'title' => __('Hide the "Website" field', 'cleantalk-spam-protect'),
153
+ 'description' => __(
154
+ 'This option hides the "Website" field on the comment form.',
155
+ 'cleantalk-spam-protect'
156
+ ),
157
+ 'long_description' => true,
158
+ 'display' => ! $apbct->white_label,
159
+ ),
160
  ),
161
  ),
162
 
351
  ),
352
  'display' => ! $apbct->white_label,
353
  ),
 
 
 
 
 
 
 
 
 
354
  ),
355
  ),
356
 
519
  ),
520
  'long_description' => true,
521
  ),
522
+ 'data__email_decoder' => array(
523
+ 'title' => __('Encode contact data', 'cleantalk-spam-protect'),
524
+ 'description' => __('Turn on this option to prevent crawlers grab contact data (emails) from website content.', 'cleantalk-spam-protect'),
525
+ ),
526
  ),
527
  ),
528
 
2789
  // Hostname
2790
  $hostname = preg_replace('/^(https?:)?(\/\/)?(www\.)?/', '', get_site_url());
2791
 
2792
+ \Cleantalk\ApbctWP\API::methodSendLocalSettings($api_key, $hostname, $settings);
2793
  }
inc/cleantalk-updater.php CHANGED
@@ -1107,3 +1107,15 @@ function apbct_update_to_5_176()
1107
  $apbct->data['ajax_type'] = apbct_settings__get_ajax_type() ?: 'admin_ajax';
1108
  $apbct->saveData();
1109
  }
 
 
 
 
 
 
 
 
 
 
 
 
1107
  $apbct->data['ajax_type'] = apbct_settings__get_ajax_type() ?: 'admin_ajax';
1108
  $apbct->saveData();
1109
  }
1110
+
1111
+ /**
1112
+ * 5.172.1
1113
+ */
1114
+ function apbct_update_to_5_176_1()
1115
+ {
1116
+ global $apbct;
1117
+ if ( ! isset($apbct->settings['data__email_decoder']) ) {
1118
+ $apbct->settings['data__email_decoder'] = 0;
1119
+ $apbct->saveSettings();
1120
+ }
1121
+ }
js/apbct-public--functions.min.js CHANGED
@@ -1,2 +1,2 @@
1
- function ctSetCookie(t,o,n){var e;("string"==typeof t&&"string"==typeof o||"number"==typeof o)&&(e="ct_pointer_data"===t,t=[[t,o,n]]),"none"!==ctPublicFunctions.data__cookies_type&&("native"===ctPublicFunctions.data__cookies_type?t.forEach(function(t,o,n){var e=void 0!==t[2]?"expires="+e+"; ":"",c="https:"===location.protocol?"; secure":"";document.cookie=t[0]+"="+encodeURIComponent(t[1])+"; "+e+"path=/; samesite=lax"+c}):"alternative"!==ctPublicFunctions.data__cookies_type||e||("rest"===ctPublicFunctions.data__ajax_type?apbct_public_sendREST("alt_sessions",{method:"POST",data:{cookies:t}}):"admin_ajax"===ctPublicFunctions.data__ajax_type&&apbct_public_sendAJAX({action:"apbct_alt_session__save__AJAX",cookies:t},{notJson:1})))}function ctDeleteCookie(t){var o;"none"!==ctPublicFunctions.data__cookies_type&&("native"===ctPublicFunctions.data__cookies_type?(o="https:"===location.protocol?"; secure":"",document.cookie=t+'=""; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax'+o):ctPublicFunctions.data__cookies_type)}function apbct_public_sendAJAX(o,n,e){var c=n.callback||null,a=n.callback_context||null,l=n.callback_params||null,t=n.async||!0,s=n.notJson||null,i=n.timeout||15e3,e=e||null,r=n.button||null,u=n.spinner||null,p=n.progressbar||null,_=n.silent||null,d=n.no_nonce||null;"string"==typeof o?o=(o=d?o:o+"&_ajax_nonce="+ctPublicFunctions._ajax_nonce)+"&no_cache="+Math.random():(d||(o._ajax_nonce=ctPublicFunctions._ajax_nonce),o.no_cache=Math.random()),r&&(r.setAttribute("disabled","disabled"),r.style.cursor="not-allowed"),u&&jQuery(u).css("display","inline"),jQuery.ajax({type:"POST",url:apbct_ajax?ctPublicFunctions._apbct_ajax_url:ctPublicFunctions._ajax_url,data:o,async:t,success:function(t){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),(t=s?t:JSON.parse(t)).error?(setTimeout(function(){p&&p.fadeOut("slow")},1e3),console.log("Error happens: "+(t.error||"Unkown"))):c&&(l?c.apply(a,l.concat(t,o,n,e)):c(t,o,n,e))},error:function(t,o,n){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),n&&!_&&(console.log("APBCT_AJAX_ERROR"),console.log(t),console.log(o),console.log("Anti-spam by Cleantalk plugin error: "+n+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"))},timeout:i})}function apbct_public_sendREST(o,n){var e=n.callback||null,t=n.data||[],c=n.method||"POST";jQuery.ajax({type:c,url:ctPublicFunctions._rest_url+"cleantalk-antispam/v1/"+o,data:t,beforeSend:function(t){t.setRequestHeader("X-WP-Nonce",ctPublicFunctions._rest_nonce)},success:function(t){t.error?console.log("Error happens: "+(t.error||"Unknown")):e&&e(t,o,n,null)},error:function(t,o,n){n&&(console.log("APBCT_REST_ERROR"),console.log(t),console.log(o),console.log("Anti-spam by Cleantalk plugin REST API error: "+n+" Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"))}})}
2
  //# sourceMappingURL=apbct-public--functions.min.js.map
1
+ function ctSetCookie(t,o,e){var n;("string"==typeof t&&"string"==typeof o||"number"==typeof o)&&(n="ct_pointer_data"===t,t=[[t,o,e]]),"none"!==ctPublicFunctions.data__cookies_type&&("native"===ctPublicFunctions.data__cookies_type?t.forEach(function(t,o,e){var n=void 0!==t[2]?"expires="+n+"; ":"",c="https:"===location.protocol?"; secure":"";document.cookie=t[0]+"="+encodeURIComponent(t[1])+"; "+n+"path=/; samesite=lax"+c}):"alternative"!==ctPublicFunctions.data__cookies_type||n||("rest"===ctPublicFunctions.data__ajax_type?apbct_public_sendREST("alt_sessions",{method:"POST",data:{cookies:t}}):"admin_ajax"===ctPublicFunctions.data__ajax_type&&apbct_public_sendAJAX({action:"apbct_alt_session__save__AJAX",cookies:t},{notJson:1})))}function ctDeleteCookie(t){var o;"none"!==ctPublicFunctions.data__cookies_type&&("native"===ctPublicFunctions.data__cookies_type?(o="https:"===location.protocol?"; secure":"",document.cookie=t+'=""; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax'+o):ctPublicFunctions.data__cookies_type)}function apbct_public_sendAJAX(o,e,n){var c=e.callback||null,a=e.callback_context||null,l=e.callback_params||null,t=e.async||!0,s=e.notJson||null,i=e.timeout||15e3,n=n||null,r=e.button||null,u=e.spinner||null,p=e.progressbar||null,_=e.silent||null,d=e.no_nonce||null;"string"==typeof o?o=(o=d?o:o+"&_ajax_nonce="+ctPublicFunctions._ajax_nonce)+"&no_cache="+Math.random():(d||(o._ajax_nonce=ctPublicFunctions._ajax_nonce),o.no_cache=Math.random()),r&&(r.setAttribute("disabled","disabled"),r.style.cursor="not-allowed"),u&&jQuery(u).css("display","inline"),jQuery.ajax({type:"POST",url:ctPublicFunctions._ajax_url,data:o,async:t,success:function(t){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),(t=s?t:JSON.parse(t)).error?(setTimeout(function(){p&&p.fadeOut("slow")},1e3),console.log("Error happens: "+(t.error||"Unkown"))):c&&(l?c.apply(a,l.concat(t,o,e,n)):c(t,o,e,n))},error:function(t,o,e){r&&(r.removeAttribute("disabled"),r.style.cursor="pointer"),u&&jQuery(u).css("display","none"),e&&!_&&(console.log("APBCT_AJAX_ERROR"),console.log(t),console.log(o),console.log("Anti-spam by Cleantalk plugin error: "+e+"Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"))},timeout:i})}function apbct_public_sendREST(o,e){var n=e.callback||null,t=e.data||[],c=e.method||"POST";jQuery.ajax({type:c,url:ctPublicFunctions._rest_url+"cleantalk-antispam/v1/"+o,data:t,beforeSend:function(t){t.setRequestHeader("X-WP-Nonce",ctPublicFunctions._rest_nonce)},success:function(t){t.error?console.log("Error happens: "+(t.error||"Unknown")):n&&n(t,o,e,null)},error:function(t,o,e){e&&(console.log("APBCT_REST_ERROR"),console.log(t),console.log(o),console.log("Anti-spam by Cleantalk plugin REST API error: "+e+" Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/"))}})}
2
  //# sourceMappingURL=apbct-public--functions.min.js.map
js/apbct-public--functions.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"apbct-public--functions.min.js","sources":["apbct-public--functions.js"],"sourcesContent":["function ctSetCookie( cookies, value, expires ){\n\n if( typeof cookies === 'string' && typeof value === 'string' || typeof value === 'number'){\n var skip_alt = cookies === 'ct_pointer_data';\n cookies = [ [ cookies, value, expires ] ];\n }\n\n // Cookies disabled\n if( ctPublicFunctions.data__cookies_type === 'none' ){\n return;\n\n // Using traditional cookies\n }else if( ctPublicFunctions.data__cookies_type === 'native' ){\n cookies.forEach( function (item, i, arr\t) {\n var expires = typeof item[2] !== 'undefined' ? \"expires=\" + expires + '; ' : '';\n var ctSecure = location.protocol === 'https:' ? '; secure' : '';\n document.cookie = item[0] + \"=\" + encodeURIComponent(item[1]) + \"; \" + expires + \"path=/; samesite=lax\" + ctSecure;\n });\n\n // Using alternative cookies\n }else if( ctPublicFunctions.data__cookies_type === 'alternative' && ! skip_alt ){\n\n // Using REST API handler\n if( ctPublicFunctions.data__ajax_type === 'rest' ){\n apbct_public_sendREST(\n 'alt_sessions',\n {\n method: 'POST',\n data: { cookies: cookies }\n }\n );\n\n // Using AJAX request and handler\n } else if( ctPublicFunctions.data__ajax_type === 'admin_ajax' ) {\n apbct_public_sendAJAX(\n {\n action: 'apbct_alt_session__save__AJAX',\n cookies: cookies,\n },\n {\n notJson: 1,\n }\n );\n }\n }\n}\n\nfunction ctDeleteCookie(cookieName) {\n // Cookies disabled\n if( ctPublicFunctions.data__cookies_type === 'none' ){\n return;\n\n // Using traditional cookies\n }else if( ctPublicFunctions.data__cookies_type === 'native' ){\n\n var ctSecure = location.protocol === 'https:' ? '; secure' : '';\n document.cookie = cookieName + \"=\\\"\\\"; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax\" + ctSecure;\n\n // Using alternative cookies\n }else if( ctPublicFunctions.data__cookies_type === 'alternative' ){\n // @ToDo implement this logic\n }\n}\n\nfunction apbct_public_sendAJAX(data, params, obj){\n\n // Default params\n var callback = params.callback || null;\n var callback_context = params.callback_context || null;\n var callback_params = params.callback_params || null;\n var async = params.async || true;\n var notJson = params.notJson || null;\n var timeout = params.timeout || 15000;\n var obj = obj || null;\n var button = params.button || null;\n var spinner = params.spinner || null;\n var progressbar = params.progressbar || null;\n var silent = params.silent || null;\n var no_nonce = params.no_nonce || null;\n\n if(typeof (data) === 'string') {\n if( ! no_nonce )\n data = data + '&_ajax_nonce=' + ctPublicFunctions._ajax_nonce;\n data = data + '&no_cache=' + Math.random()\n } else {\n if( ! no_nonce )\n data._ajax_nonce = ctPublicFunctions._ajax_nonce;\n data.no_cache = Math.random();\n }\n // Button and spinner\n if(button) {button.setAttribute('disabled', 'disabled'); button.style.cursor = 'not-allowed'; }\n if(spinner) jQuery(spinner).css('display', 'inline');\n\n jQuery.ajax({\n type: \"POST\",\n url: apbct_ajax ? ctPublicFunctions._apbct_ajax_url : ctPublicFunctions._ajax_url,\n data: data,\n async: async,\n success: function(result){\n if(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\n if(spinner) jQuery(spinner).css('display', 'none');\n if(!notJson) result = JSON.parse(result);\n if(result.error){\n setTimeout(function(){ if(progressbar) progressbar.fadeOut('slow'); }, 1000);\n console.log('Error happens: ' + (result.error || 'Unkown'));\n }else{\n if(callback) {\n if (callback_params)\n callback.apply( callback_context, callback_params.concat( result, data, params, obj ) );\n else\n callback(result, data, params, obj);\n }\n }\n },\n error: function(jqXHR, textStatus, errorThrown){\n if(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\n if(spinner) jQuery(spinner).css('display', 'none');\n if( errorThrown && ! silent ) {\n console.log('APBCT_AJAX_ERROR');\n console.log(jqXHR);\n console.log(textStatus);\n console.log('Anti-spam by Cleantalk plugin error: ' + errorThrown + 'Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\n }\n },\n timeout: timeout,\n });\n}\n\nfunction apbct_public_sendREST( route, params ) {\n\n var callback = params.callback || null;\n var data = params.data || [];\n var method = params.method || 'POST';\n\n jQuery.ajax({\n type: method,\n url: ctPublicFunctions._rest_url + 'cleantalk-antispam/v1/' + route,\n data: data,\n beforeSend : function ( xhr ) {\n xhr.setRequestHeader( 'X-WP-Nonce', ctPublicFunctions._rest_nonce );\n },\n success: function(result){\n if(result.error){\n console.log('Error happens: ' + (result.error || 'Unknown'));\n }else{\n if(callback) {\n var obj = null;\n callback(result, route, params, obj);\n }\n }\n },\n error: function(jqXHR, textStatus, errorThrown){\n if( errorThrown ) {\n console.log('APBCT_REST_ERROR');\n console.log(jqXHR);\n console.log(textStatus);\n console.log('Anti-spam by Cleantalk plugin REST API error: ' + errorThrown + ' Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\n }\n },\n });\n\n}\n"],"names":["ctSetCookie","cookies","value","expires","skip_alt","ctPublicFunctions","data__cookies_type","forEach","item","i","arr","ctSecure","location","protocol","document","cookie","encodeURIComponent","data__ajax_type","apbct_public_sendREST","method","data","apbct_public_sendAJAX","action","notJson","ctDeleteCookie","cookieName","params","obj","callback","callback_context","callback_params","async","timeout","button","spinner","progressbar","silent","no_nonce","_ajax_nonce","Math","random","no_cache","setAttribute","style","cursor","jQuery","css","ajax","type","url","apbct_ajax","_apbct_ajax_url","_ajax_url","success","result","removeAttribute","JSON","parse","error","setTimeout","fadeOut","console","log","apply","concat","jqXHR","textStatus","errorThrown","route","_rest_url","beforeSend","xhr","setRequestHeader","_rest_nonce"],"mappings":"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"}
1
+ {"version":3,"file":"apbct-public--functions.min.js","sources":["apbct-public--functions.js"],"sourcesContent":["function ctSetCookie( cookies, value, expires ){\n\n if( typeof cookies === 'string' && typeof value === 'string' || typeof value === 'number'){\n var skip_alt = cookies === 'ct_pointer_data';\n cookies = [ [ cookies, value, expires ] ];\n }\n\n // Cookies disabled\n if( ctPublicFunctions.data__cookies_type === 'none' ){\n return;\n\n // Using traditional cookies\n }else if( ctPublicFunctions.data__cookies_type === 'native' ){\n cookies.forEach( function (item, i, arr\t) {\n var expires = typeof item[2] !== 'undefined' ? \"expires=\" + expires + '; ' : '';\n var ctSecure = location.protocol === 'https:' ? '; secure' : '';\n document.cookie = item[0] + \"=\" + encodeURIComponent(item[1]) + \"; \" + expires + \"path=/; samesite=lax\" + ctSecure;\n });\n\n // Using alternative cookies\n }else if( ctPublicFunctions.data__cookies_type === 'alternative' && ! skip_alt ){\n\n // Using REST API handler\n if( ctPublicFunctions.data__ajax_type === 'rest' ){\n apbct_public_sendREST(\n 'alt_sessions',\n {\n method: 'POST',\n data: { cookies: cookies }\n }\n );\n\n // Using AJAX request and handler\n } else if( ctPublicFunctions.data__ajax_type === 'admin_ajax' ) {\n apbct_public_sendAJAX(\n {\n action: 'apbct_alt_session__save__AJAX',\n cookies: cookies,\n },\n {\n notJson: 1,\n }\n );\n }\n }\n}\n\nfunction ctDeleteCookie(cookieName) {\n // Cookies disabled\n if( ctPublicFunctions.data__cookies_type === 'none' ){\n return;\n\n // Using traditional cookies\n }else if( ctPublicFunctions.data__cookies_type === 'native' ){\n\n var ctSecure = location.protocol === 'https:' ? '; secure' : '';\n document.cookie = cookieName + \"=\\\"\\\"; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax\" + ctSecure;\n\n // Using alternative cookies\n }else if( ctPublicFunctions.data__cookies_type === 'alternative' ){\n // @ToDo implement this logic\n }\n}\n\nfunction apbct_public_sendAJAX(data, params, obj){\n\n // Default params\n var callback = params.callback || null;\n var callback_context = params.callback_context || null;\n var callback_params = params.callback_params || null;\n var async = params.async || true;\n var notJson = params.notJson || null;\n var timeout = params.timeout || 15000;\n var obj = obj || null;\n var button = params.button || null;\n var spinner = params.spinner || null;\n var progressbar = params.progressbar || null;\n var silent = params.silent || null;\n var no_nonce = params.no_nonce || null;\n\n if(typeof (data) === 'string') {\n if( ! no_nonce )\n data = data + '&_ajax_nonce=' + ctPublicFunctions._ajax_nonce;\n data = data + '&no_cache=' + Math.random()\n } else {\n if( ! no_nonce )\n data._ajax_nonce = ctPublicFunctions._ajax_nonce;\n data.no_cache = Math.random();\n }\n // Button and spinner\n if(button) {button.setAttribute('disabled', 'disabled'); button.style.cursor = 'not-allowed'; }\n if(spinner) jQuery(spinner).css('display', 'inline');\n\n jQuery.ajax({\n type: \"POST\",\n url: ctPublicFunctions._ajax_url,\n data: data,\n async: async,\n success: function(result){\n if(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\n if(spinner) jQuery(spinner).css('display', 'none');\n if(!notJson) result = JSON.parse(result);\n if(result.error){\n setTimeout(function(){ if(progressbar) progressbar.fadeOut('slow'); }, 1000);\n console.log('Error happens: ' + (result.error || 'Unkown'));\n }else{\n if(callback) {\n if (callback_params)\n callback.apply( callback_context, callback_params.concat( result, data, params, obj ) );\n else\n callback(result, data, params, obj);\n }\n }\n },\n error: function(jqXHR, textStatus, errorThrown){\n if(button){ button.removeAttribute('disabled'); button.style.cursor = 'pointer'; }\n if(spinner) jQuery(spinner).css('display', 'none');\n if( errorThrown && ! silent ) {\n console.log('APBCT_AJAX_ERROR');\n console.log(jqXHR);\n console.log(textStatus);\n console.log('Anti-spam by Cleantalk plugin error: ' + errorThrown + 'Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\n }\n },\n timeout: timeout,\n });\n}\n\nfunction apbct_public_sendREST( route, params ) {\n\n var callback = params.callback || null;\n var data = params.data || [];\n var method = params.method || 'POST';\n\n jQuery.ajax({\n type: method,\n url: ctPublicFunctions._rest_url + 'cleantalk-antispam/v1/' + route,\n data: data,\n beforeSend : function ( xhr ) {\n xhr.setRequestHeader( 'X-WP-Nonce', ctPublicFunctions._rest_nonce );\n },\n success: function(result){\n if(result.error){\n console.log('Error happens: ' + (result.error || 'Unknown'));\n }else{\n if(callback) {\n var obj = null;\n callback(result, route, params, obj);\n }\n }\n },\n error: function(jqXHR, textStatus, errorThrown){\n if( errorThrown ) {\n console.log('APBCT_REST_ERROR');\n console.log(jqXHR);\n console.log(textStatus);\n console.log('Anti-spam by Cleantalk plugin REST API error: ' + errorThrown + ' Please, contact Cleantalk tech support https://wordpress.org/support/plugin/cleantalk-spam-protect/');\n }\n },\n });\n\n}\n"],"names":["ctSetCookie","cookies","value","expires","skip_alt","ctPublicFunctions","data__cookies_type","forEach","item","i","arr","ctSecure","location","protocol","document","cookie","encodeURIComponent","data__ajax_type","apbct_public_sendREST","method","data","apbct_public_sendAJAX","action","notJson","ctDeleteCookie","cookieName","params","obj","callback","callback_context","callback_params","async","timeout","button","spinner","progressbar","silent","no_nonce","_ajax_nonce","Math","random","no_cache","setAttribute","style","cursor","jQuery","css","ajax","type","url","_ajax_url","success","result","removeAttribute","JSON","parse","error","setTimeout","fadeOut","console","log","apply","concat","jqXHR","textStatus","errorThrown","route","_rest_url","beforeSend","xhr","setRequestHeader","_rest_nonce"],"mappings":"AAAA,SAASA,YAAaC,EAASC,EAAOC,GAElC,IACQC,GADe,iBAAZH,GAAyC,iBAAVC,GAAuC,iBAAVA,KAC/DE,EAAuB,oBAAZH,EACfA,EAAU,CAAE,CAAEA,EAASC,EAAOC,KAIW,SAAzCE,kBAAkBC,qBAI6B,WAAzCD,kBAAkBC,mBACxBL,EAAQM,QAAS,SAAUC,EAAMC,EAAGC,GAChC,IAAIP,OAA6B,IAAZK,EAAK,GAAqB,WAAaL,EAAU,KAAO,GACzEQ,EAAiC,WAAtBC,SAASC,SAAwB,WAAa,GAC7DC,SAASC,OAASP,EAAK,GAAK,IAAMQ,mBAAmBR,EAAK,IAAM,KAAOL,EAAU,uBAAyBQ,IAI/D,gBAAzCN,kBAAkBC,oBAA0CF,IAGxB,SAAtCC,kBAAkBY,gBAClBC,sBACI,eACA,CACIC,OAAQ,OACRC,KAAM,CAAEnB,QAASA,KAKoB,eAAtCI,kBAAkBY,iBACzBI,sBACI,CACIC,OAAQ,gCACRrB,QAASA,GAEb,CACIsB,QAAS,MAO7B,SAASC,eAAeC,GAEpB,IAMQd,EANqC,SAAzCN,kBAAkBC,qBAI6B,WAAzCD,kBAAkBC,oBAEpBK,EAAiC,WAAtBC,SAASC,SAAwB,WAAa,GAC7DC,SAASC,OAASU,EAAa,mEAAuEd,GAGhGN,kBAAkBC,oBAKhC,SAASe,sBAAsBD,EAAMM,EAAQC,GAGzC,IAAIC,EAAcF,EAAOE,UAAe,KACpCC,EAAmBH,EAAOG,kBAAoB,KAC9CC,EAAkBJ,EAAOI,iBAAmB,KAC5CC,EAAQL,EAAOK,QAAS,EACxBR,EAAcG,EAAOH,SAAe,KACpCS,EAAcN,EAAOM,SAAe,KACpCL,EAAcA,GAAsB,KACpCM,EAAcP,EAAOO,QAAe,KACpCC,EAAcR,EAAOQ,SAAe,KACpCC,EAAcT,EAAOS,aAAe,KACpCC,EAAcV,EAAOU,QAAe,KACpCC,EAAcX,EAAOW,UAAe,KAEnB,iBAAX,EAGNjB,GADIA,EADEiB,EAECjB,EADIA,EAAO,gBAAkBf,kBAAkBiC,aACxC,aAAeC,KAAKC,UAE5BH,IACFjB,EAAKkB,YAAcjC,kBAAkBiC,aACzClB,EAAKqB,SAAWF,KAAKC,UAGtBP,IAAUA,EAAOS,aAAa,WAAY,YAAaT,EAAOU,MAAMC,OAAS,eAC7EV,GAASW,OAAOX,GAASY,IAAI,UAAW,UAE3CD,OAAOE,KAAK,CACRC,KAAM,OACNC,IAAK5C,kBAAkB6C,UACvB9B,KAAMA,EACNW,MAAOA,EACPoB,QAAS,SAASC,GACXnB,IAAUA,EAAOoB,gBAAgB,YAAapB,EAAOU,MAAMC,OAAS,WACpEV,GAAUW,OAAOX,GAASY,IAAI,UAAW,SAC/BM,EAAT7B,EACD6B,EADmBE,KAAKC,MAAMH,IACvBI,OACNC,WAAW,WAAetB,GAAaA,EAAYuB,QAAQ,SAAY,KACvEC,QAAQC,IAAI,mBAAqBR,EAAOI,OAAS,YAE9C5B,IACKE,EACAF,EAASiC,MAAOhC,EAAkBC,EAAgBgC,OAAQV,EAAQhC,EAAMM,EAAQC,IAEhFC,EAASwB,EAAQhC,EAAMM,EAAQC,KAI/C6B,MAAO,SAASO,EAAOC,EAAYC,GAC5BhC,IAAUA,EAAOoB,gBAAgB,YAAapB,EAAOU,MAAMC,OAAS,WACpEV,GAASW,OAAOX,GAASY,IAAI,UAAW,QACvCmB,IAAiB7B,IACjBuB,QAAQC,IAAI,oBACZD,QAAQC,IAAIG,GACZJ,QAAQC,IAAII,GACZL,QAAQC,IAAI,wCAA0CK,EAAc,yGAG5EjC,QAASA,IAIjB,SAASd,sBAAuBgD,EAAOxC,GAEnC,IAAIE,EAAWF,EAAOE,UAAY,KAC9BR,EAAWM,EAAON,MAAQ,GAC1BD,EAAWO,EAAOP,QAAU,OAEhC0B,OAAOE,KAAK,CACRC,KAAM7B,EACN8B,IAAK5C,kBAAkB8D,UAAY,yBAA2BD,EAC9D9C,KAAMA,EACNgD,WAAa,SAAWC,GACpBA,EAAIC,iBAAkB,aAAcjE,kBAAkBkE,cAE1DpB,QAAS,SAASC,GACXA,EAAOI,MACNG,QAAQC,IAAI,mBAAqBR,EAAOI,OAAS,YAE9C5B,GAECA,EAASwB,EAAQc,EAAOxC,EADd,OAKtB8B,MAAO,SAASO,EAAOC,EAAYC,GAC3BA,IACAN,QAAQC,IAAI,oBACZD,QAAQC,IAAIG,GACZJ,QAAQC,IAAII,GACZL,QAAQC,IAAI,iDAAmDK,EAAc"}
js/apbct-public.min.js CHANGED
@@ -1,2 +1,2 @@
1
- function apbct_collect_visible_fields(e){var t,i=[],n="",o=0,c="",a=0,l=[];for(t in e.elements)isNaN(+t)||(i[t]=e.elements[t]);return(i=i.filter(function(e){return-1===l.indexOf(e.getAttribute("name"))&&(-1===["radio","checkbox"].indexOf(e.getAttribute("type"))||(l.push(e.getAttribute("name")),!1))})).forEach(function(e,t,i){"submit"!==e.getAttribute("type")&&null!==e.getAttribute("name")&&"ct_checkjs"!==e.getAttribute("name")&&("none"!==getComputedStyle(e).display&&"hidden"!==getComputedStyle(e).visibility&&"0"!==getComputedStyle(e).opacity&&"hidden"!==e.getAttribute("type")||e.classList.contains("wp-editor-area")?(n+=" "+e.getAttribute("name"),o++):(c+=" "+e.getAttribute("name"),a++))}),c=c.trim(),{visible_fields:n=n.trim(),visible_fields_count:o,invisible_fields:c,invisible_fields_count:a}}function apbct_visible_fields_set_cookie(e,t){var i="object"==typeof e&&null!==e?e:{};if("native"===ctPublic.data__cookies_type)for(var n in i){if(10<n)return;ctSetCookie("apbct_visible_fields_"+(void 0!==t?t:n),JSON.stringify(i[n]))}else ctSetCookie("apbct_visible_fields",JSON.stringify(i))}function apbct_js_keys__set_input_value(e,t,i,n){if(0<document.querySelectorAll("[name^=ct_checkjs]").length)for(var o=document.querySelectorAll("[name^=ct_checkjs]"),c=0;c<o.length;c++)o[c].value=e.js_key}function apbctGetScreenInfo(){return JSON.stringify({fullWidth:document.documentElement.scrollWidth,fullHeight:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight),visibleWidth:document.documentElement.clientWidth,visibleHeight:document.documentElement.clientHeight})}!function(){var o=new Date,t=(new Date).getTime(),i=!0,n=[],c=0,a={},e=!1,l=!1;function s(e,t,i){"function"==typeof window.addEventListener?e.addEventListener(t,i):e.attachEvent(t,i)}function d(e,t,i){"function"==typeof window.removeEventListener?e.removeEventListener(t,i):e.detachEvent(t,i)}var r=function(e){var t=Math.floor((new Date).getTime()/1e3);ctSetCookie("ct_fkp_timestamp",t),d(window,"mousedown",r),d(window,"keydown",r)},u=setInterval(function(){i=!0},150),_=setInterval(function(){ctSetCookie("ct_pointer_data",JSON.stringify(n))},1200),m=function(e){l||(ctSetCookie("ct_mouse_moved","true"),l=!0),!0===i&&(n.push([Math.round(e.clientY),Math.round(e.clientX),Math.round((new Date).getTime()-t)]),i=!1,50<=++c&&(d(window,"mousemove",m),clearInterval(u),clearInterval(_)))};function p(e){var t=e.target.value;!t||t in a||("rest"===ctPublicFunctions.data__ajax_type?apbct_public_sendREST("check_email_before_post",{method:"POST",data:{email:t},callback:function(e){e.result&&(a[t]={result:e.result,timestamp:Date.now()/1e3|0},ctSetCookie("ct_checked_emails",JSON.stringify(a)))}}):"admin_ajax"===ctPublicFunctions.data__ajax_type&&apbct_public_sendAJAX({action:"apbct_email_check_before_post",email:t},{callback:function(e){e.result&&(a[t]={result:e.result,timestamp:Date.now()/1e3|0},ctSetCookie("ct_checked_emails",JSON.stringify(a)))}}))}function f(e){ctSetCookie("apbct_pixel_url",e),+ctPublic.pixel__enabled&&!document.getElementById("apbct_pixel")&&jQuery("body").append('<img alt="Cleantalk Pixel" id="apbct_pixel" style="display: none; left: 99999px;" src="'+e+'">')}s(window,"mousemove",m),s(window,"mousedown",r),s(window,"keydown",r),s(window,"scroll",function(){e||(ctSetCookie("ct_has_scrolled","true"),e=!0)}),s(window,"DOMContentLoaded",function(){var e=[["ct_ps_timestamp",Math.floor((new Date).getTime()/1e3)],["ct_fkp_timestamp","0"],["ct_pointer_data","0"],["ct_timezone",o.getTimezoneOffset()/60*-1],["ct_screen_info",apbctGetScreenInfo()],["ct_has_scrolled","false"],["ct_mouse_moved","false"],["apbct_headless",navigator.webdriver]];if("native"!==ctPublic.data__cookies_type)e.push(["apbct_visible_fields","0"]);else{var t=document.cookie.split(";");if(0!==t.length)for(var i=0;i<t.length;i++){var n=t[i].trim().split("=")[0];0===n.indexOf("apbct_visible_fields_")&&ctDeleteCookie(n)}}+ctPublic.pixel__setting&&(+ctPublic.pixel__enabled?"rest"===ctPublicFunctions.data__ajax_type?apbct_public_sendREST("apbct_get_pixel_url",{method:"POST",callback:function(e){e&&f(e)}}):apbct_public_sendAJAX({action:"apbct_get_pixel_url"},{notJson:!0,callback:function(e){e&&f(e)}}):e.push(["apbct_pixel_url",ctPublic.pixel__url])),+ctPublic.data__email_check_before_post&&(e.push(["ct_checked_emails","0"]),jQuery("input[type = 'email'], #email").blur(p)),ctSetCookie(e),setTimeout(function(){for(var e=0;e<document.forms.length;e++){var t,i,n=document.forms[e];0==+ctPublic.data__visible_fields_required||"get"===n.method.toString().toLowerCase()||n.classList.contains("slp_search_form")||n.parentElement.classList.contains("mec-booking")||-1!==n.action.toString().indexOf("activehosted.com")||n.id&&"caspioform"===n.id||n.classList&&n.classList.contains("tinkoffPayRow")||n.classList&&n.classList.contains("give-form")||n.id&&"ult-forgot-password-form"===n.id||n.id&&-1!==n.id.toString().indexOf("calculatedfields")||n.id&&-1!==n.id.toString().indexOf("sac-form")||n.id&&-1!==n.id.toString().indexOf("cp_tslotsbooking_pform")||n.name&&-1!==n.name.toString().indexOf("cp_tslotsbooking_pform")||"https://epayment.epymtservice.com/epay.jhtml"===n.action.toString()||((t=document.createElement("input")).setAttribute("type","hidden"),t.setAttribute("id","apbct_visible_fields_"+e),t.setAttribute("name","apbct_visible_fields"),(i={})[0]=apbct_collect_visible_fields(n),t.value=JSON.stringify(i),n.append(t),n.onsubmit_prev=n.onsubmit,n.ctFormIndex=e,n.onsubmit=function(e){var t;"native"!==ctPublic.data__cookies_type&&void 0!==e.target.ctFormIndex&&((t={})[0]=apbct_collect_visible_fields(this),apbct_visible_fields_set_cookie(t,e.target.ctFormIndex)),e.target.onsubmit_prev instanceof Function&&setTimeout(function(){e.target.onsubmit_prev.call(e.target,e)},500)})}},1e3)})}(),"undefined"!=typeof jQuery&&jQuery(document).ajaxComplete(function(e,t,i){t.responseText&&-1!==t.responseText.indexOf('"apbct')&&void 0!==(t=JSON.parse(t.responseText)).apbct&&(t=t.apbct).blocked&&(document.dispatchEvent(new CustomEvent("apbctAjaxBockAlert",{bubbles:!0,detail:{message:t.comment}})),cleantalkModal.loaded=t.comment,cleantalkModal.open(),1==+t.stop_script&&window.stop())});
2
  //# sourceMappingURL=apbct-public.min.js.map
1
+ function apbctAjaxEmailDecode(t){const i=t.target;i.setAttribute("title",ctPublicFunctions.text__wait_for_decoding),i.style.cursor="progress","rest"===ctPublicFunctions.data__ajax_type?apbct_public_sendREST("apbct_decode_email",{data:{encodedEmail:t.target.dataset.originalString},method:"POST",callback:function(e){e.success&&(ctFillDecodedEmail(e.data,t.target),i.setAttribute("title",""),i.removeAttribute("style"))}}):apbct_public_sendAJAX({action:"apbct_decode_email",encodedEmail:t.target.dataset.originalString},{notJson:!0,callback:function(e){e.success&&(ctFillDecodedEmail(e.data,t.target),i.setAttribute("title",""),i.removeAttribute("style"))}})}function ctFillDecodedEmail(e,t){t.innerText=e}function apbct_collect_visible_fields(e){var t,i=[],o="",n=0,c="",a=0,l=[];for(t in e.elements)isNaN(+t)||(i[t]=e.elements[t]);return(i=i.filter(function(e){return-1===l.indexOf(e.getAttribute("name"))&&(-1===["radio","checkbox"].indexOf(e.getAttribute("type"))||(l.push(e.getAttribute("name")),!1))})).forEach(function(e,t,i){"submit"!==e.getAttribute("type")&&null!==e.getAttribute("name")&&"ct_checkjs"!==e.getAttribute("name")&&("none"!==getComputedStyle(e).display&&"hidden"!==getComputedStyle(e).visibility&&"0"!==getComputedStyle(e).opacity&&"hidden"!==e.getAttribute("type")||e.classList.contains("wp-editor-area")?(o+=" "+e.getAttribute("name"),n++):(c+=" "+e.getAttribute("name"),a++))}),c=c.trim(),{visible_fields:o=o.trim(),visible_fields_count:n,invisible_fields:c,invisible_fields_count:a}}function apbct_visible_fields_set_cookie(e,t){var i="object"==typeof e&&null!==e?e:{};if("native"===ctPublic.data__cookies_type)for(var o in i){if(10<o)return;ctSetCookie("apbct_visible_fields_"+(void 0!==t?t:o),JSON.stringify(i[o]))}else ctSetCookie("apbct_visible_fields",JSON.stringify(i))}function apbct_js_keys__set_input_value(e,t,i,o){if(0<document.querySelectorAll("[name^=ct_checkjs]").length)for(var n=document.querySelectorAll("[name^=ct_checkjs]"),c=0;c<n.length;c++)n[c].value=e.js_key}function apbctGetScreenInfo(){return JSON.stringify({fullWidth:document.documentElement.scrollWidth,fullHeight:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight),visibleWidth:document.documentElement.clientWidth,visibleHeight:document.documentElement.clientHeight})}function ctSetPixelUrlLocalstorage(e){localStorage.setItem("session_pixel_url",e),localStorage.setItem(e,Math.floor(Date.now()/1e3).toString())}function ctGetPixelUrlLocalstorage(){var e=localStorage.getItem("session_pixel_url");return null!==e&&e}function ctIsOutdatedPixelUrlLocalstorage(e){e=Number(localStorage.getItem(e));return 10800<Math.floor(Date.now()/1e3).toString()-e}function ctCleaPixelUrlLocalstorage(e){localStorage.removeItem(e),localStorage.removeItem("session_pixel_url")}!function(){var c=new Date,t=(new Date).getTime(),i=!0,o=[],n=0,a={},e=!1,l=!1;function s(e,t,i){"function"==typeof window.addEventListener?e.addEventListener(t,i):e.attachEvent(t,i)}function r(e,t,i){"function"==typeof window.removeEventListener?e.removeEventListener(t,i):e.detachEvent(t,i)}var d=function(e){var t=Math.floor((new Date).getTime()/1e3);ctSetCookie("ct_fkp_timestamp",t),r(window,"mousedown",d),r(window,"keydown",d)},u=setInterval(function(){i=!0},150),_=setInterval(function(){ctSetCookie("ct_pointer_data",JSON.stringify(o))},1200),m=function(e){l||(ctSetCookie("ct_mouse_moved","true"),l=!0),!0===i&&(o.push([Math.round(e.clientY),Math.round(e.clientX),Math.round((new Date).getTime()-t)]),i=!1,50<=++n&&(r(window,"mousemove",m),clearInterval(u),clearInterval(_)))};function p(e){var t=e.target.value;!t||t in a||("rest"===ctPublicFunctions.data__ajax_type?apbct_public_sendREST("check_email_before_post",{method:"POST",data:{email:t},callback:function(e){e.result&&(a[t]={result:e.result,timestamp:Date.now()/1e3|0},ctSetCookie("ct_checked_emails",JSON.stringify(a)))}}):"admin_ajax"===ctPublicFunctions.data__ajax_type&&apbct_public_sendAJAX({action:"apbct_email_check_before_post",email:t},{callback:function(e){e.result&&(a[t]={result:e.result,timestamp:Date.now()/1e3|0},ctSetCookie("ct_checked_emails",JSON.stringify(a)))}}))}function f(e){ctSetCookie("apbct_pixel_url",e),+ctPublic.pixel__enabled&&!document.getElementById("apbct_pixel")&&jQuery("body").append('<img alt="Cleantalk Pixel" id="apbct_pixel" style="display: none; left: 99999px;" src="'+e+'">')}s(window,"mousemove",m),s(window,"mousedown",d),s(window,"keydown",d),s(window,"scroll",function(){e||(ctSetCookie("ct_has_scrolled","true"),e=!0)}),s(window,"DOMContentLoaded",function(){var e=[["ct_ps_timestamp",Math.floor((new Date).getTime()/1e3)],["ct_fkp_timestamp","0"],["ct_pointer_data","0"],["ct_timezone",c.getTimezoneOffset()/60*-1],["ct_screen_info",apbctGetScreenInfo()],["ct_has_scrolled","false"],["ct_mouse_moved","false"],["apbct_headless",navigator.webdriver]];if("native"!==ctPublic.data__cookies_type)e.push(["apbct_visible_fields","0"]);else{var t=document.cookie.split(";");if(0!==t.length)for(var i=0;i<t.length;i++){var o=t[i].trim().split("=")[0];0===o.indexOf("apbct_visible_fields_")&&ctDeleteCookie(o)}}+ctPublic.pixel__setting&&(+ctPublic.pixel__enabled?function(){var e=ctGetPixelUrlLocalstorage();if(!1!==e){if(!ctIsOutdatedPixelUrlLocalstorage(e))return f(e);ctCleaPixelUrlLocalstorage(e)}"rest"===ctPublicFunctions.data__ajax_type?apbct_public_sendREST("apbct_get_pixel_url",{method:"POST",callback:function(e){e&&(ctGetPixelUrlLocalstorage()||ctSetPixelUrlLocalstorage(e),f(e))}}):apbct_public_sendAJAX({action:"apbct_get_pixel_url"},{notJson:!0,callback:function(e){e&&(ctGetPixelUrlLocalstorage()||ctSetPixelUrlLocalstorage(e),f(e))}})}():e.push(["apbct_pixel_url",ctPublic.pixel__url])),+ctPublic.data__email_check_before_post&&(e.push(["ct_checked_emails","0"]),jQuery("input[type = 'email'], #email").blur(p)),ctSetCookie(e),setTimeout(function(){for(var e=0;e<document.forms.length;e++){var t,i,o=document.forms[e];0==+ctPublic.data__visible_fields_required||"get"===o.method.toString().toLowerCase()||o.classList.contains("slp_search_form")||o.parentElement.classList.contains("mec-booking")||-1!==o.action.toString().indexOf("activehosted.com")||o.id&&"caspioform"===o.id||o.classList&&o.classList.contains("tinkoffPayRow")||o.classList&&o.classList.contains("give-form")||o.id&&"ult-forgot-password-form"===o.id||o.id&&-1!==o.id.toString().indexOf("calculatedfields")||o.id&&-1!==o.id.toString().indexOf("sac-form")||o.id&&-1!==o.id.toString().indexOf("cp_tslotsbooking_pform")||o.name&&-1!==o.name.toString().indexOf("cp_tslotsbooking_pform")||"https://epayment.epymtservice.com/epay.jhtml"===o.action.toString()||o.name&&-1!==o.name.toString().indexOf("tribe-bar-form")||((t=document.createElement("input")).setAttribute("type","hidden"),t.setAttribute("id","apbct_visible_fields_"+e),t.setAttribute("name","apbct_visible_fields"),(i={})[0]=apbct_collect_visible_fields(o),t.value=JSON.stringify(i),o.append(t),o.onsubmit_prev=o.onsubmit,o.ctFormIndex=e,o.onsubmit=function(e){var t;"native"!==ctPublic.data__cookies_type&&void 0!==e.target.ctFormIndex&&((t={})[0]=apbct_collect_visible_fields(this),apbct_visible_fields_set_cookie(t,e.target.ctFormIndex)),e.target.onsubmit_prev instanceof Function&&setTimeout(function(){e.target.onsubmit_prev.call(e.target,e)},500)})}},1e3);let n=document.querySelectorAll("[data-original-string]");if(n.length)for(let e=0;e<n.length;++e)n[e].parentElement.href||n[e].parentElement.parentElement.href||n[e].addEventListener("click",function e(t){this.removeEventListener("click",e),apbctAjaxEmailDecode(t)})})}(),"undefined"!=typeof jQuery&&jQuery(document).ajaxComplete(function(e,t,i){t.responseText&&-1!==t.responseText.indexOf('"apbct')&&void 0!==(t=JSON.parse(t.responseText)).apbct&&(t=t.apbct).blocked&&(document.dispatchEvent(new CustomEvent("apbctAjaxBockAlert",{bubbles:!0,detail:{message:t.comment}})),cleantalkModal.loaded=t.comment,cleantalkModal.open(),1==+t.stop_script&&window.stop())});
2
  //# sourceMappingURL=apbct-public.min.js.map
js/apbct-public.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"apbct-public.min.js","sources":["apbct-public.js"],"sourcesContent":["(function() {\n\n\tvar ct_date = new Date(),\n\t\tctTimeMs = new Date().getTime(),\n\t\tctMouseEventTimerFlag = true, //Reading interval flag\n\t\tctMouseData = [],\n\t\tctMouseDataCounter = 0,\n\t\tctCheckedEmails = {},\n\t\tctScrollCollected = false,\n\t\tctMouseMovedCollected = false;\n\n\tfunction apbct_attach_event_handler(elem, event, callback){\n\t\tif(typeof window.addEventListener === \"function\") elem.addEventListener(event, callback);\n\t\telse elem.attachEvent(event, callback);\n\t}\n\n\tfunction apbct_remove_event_handler(elem, event, callback){\n\t\tif(typeof window.removeEventListener === \"function\") elem.removeEventListener(event, callback);\n\t\telse elem.detachEvent(event, callback);\n\t}\n\n\t//Writing first key press timestamp\n\tvar ctFunctionFirstKey = function output(event){\n\t\tvar KeyTimestamp = Math.floor(new Date().getTime()/1000);\n\t\tctSetCookie(\"ct_fkp_timestamp\", KeyTimestamp);\n\t\tctKeyStopStopListening();\n\t};\n\n\t//Reading interval\n\tvar ctMouseReadInterval = setInterval(function(){\n\t\tctMouseEventTimerFlag = true;\n\t}, 150);\n\n\t//Writting interval\n\tvar ctMouseWriteDataInterval = setInterval(function(){\n\t\tctSetCookie(\"ct_pointer_data\", JSON.stringify(ctMouseData));\n\t}, 1200);\n\n\t//Logging mouse position each 150 ms\n\tvar ctFunctionMouseMove = function output(event){\n\t\tctSetMouseMoved();\n\t\tif(ctMouseEventTimerFlag === true){\n\n\t\t\tctMouseData.push([\n\t\t\t\tMath.round(event.clientY),\n\t\t\t\tMath.round(event.clientX),\n\t\t\t\tMath.round(new Date().getTime() - ctTimeMs)\n\t\t\t]);\n\n\t\t\tctMouseDataCounter++;\n\t\t\tctMouseEventTimerFlag = false;\n\t\t\tif(ctMouseDataCounter >= 50){\n\t\t\t\tctMouseStopData();\n\t\t\t}\n\t\t}\n\t};\n\n\t//Stop mouse observing function\n\tfunction ctMouseStopData(){\n\t\tapbct_remove_event_handler(window, \"mousemove\", ctFunctionMouseMove);\n\t\tclearInterval(ctMouseReadInterval);\n\t\tclearInterval(ctMouseWriteDataInterval);\n\t}\n\n\t//Stop key listening function\n\tfunction ctKeyStopStopListening(){\n\t\tapbct_remove_event_handler(window, \"mousedown\", ctFunctionFirstKey);\n\t\tapbct_remove_event_handler(window, \"keydown\", ctFunctionFirstKey);\n\t}\n\n\tfunction checkEmail(e) {\n\t\tvar current_email = e.target.value;\n\t\tif (current_email && !(current_email in ctCheckedEmails)) {\n\t\t\t// Using REST API handler\n\t\t\tif( ctPublicFunctions.data__ajax_type === 'rest' ){\n\t\t\t\tapbct_public_sendREST(\n\t\t\t\t\t'check_email_before_post',\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\tdata: {'email' : current_email},\n\t\t\t\t\t\tcallback: function (result) {\n\t\t\t\t\t\t\tif (result.result) {\n\t\t\t\t\t\t\t\tctCheckedEmails[current_email] = {'result' : result.result, 'timestamp': Date.now() / 1000 |0};\n\t\t\t\t\t\t\t\tctSetCookie('ct_checked_emails', JSON.stringify(ctCheckedEmails));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t// Using AJAX request and handler\n\t\t\t} else if( ctPublicFunctions.data__ajax_type === 'admin_ajax' ) {\n\t\t\t\tapbct_public_sendAJAX(\n\t\t\t\t\t{\n\t\t\t\t\t\taction: 'apbct_email_check_before_post',\n\t\t\t\t\t\temail : current_email,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcallback: function (result) {\n\t\t\t\t\t\t\tif (result.result) {\n\t\t\t\t\t\t\t\tctCheckedEmails[current_email] = {'result' : result.result, 'timestamp': Date.now() / 1000 |0};\n\t\t\t\t\t\t\t\tctSetCookie('ct_checked_emails', JSON.stringify(ctCheckedEmails));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction ctSetPixelImg(pixelUrl) {\n\t\tctSetCookie('apbct_pixel_url', pixelUrl);\n\t\tif( +ctPublic.pixel__enabled ){\n\t\t\tif( ! document.getElementById('apbct_pixel') ) {\n\t\t\t\tjQuery('body').append( '<img alt=\"Cleantalk Pixel\" id=\"apbct_pixel\" style=\"display: none; left: 99999px;\" src=\"' + pixelUrl + '\">' );\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction ctGetPixelUrl() {\n\t\t// Using REST API handler\n\t\tif( ctPublicFunctions.data__ajax_type === 'rest' ){\n\t\t\tapbct_public_sendREST(\n\t\t\t\t'apbct_get_pixel_url',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\tcallback: function (result) {\n\t\t\t\t\t\tif (result) {\n\t\t\t\t\t\t\tctSetPixelImg(result);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\t\t// Using AJAX request and handler\n\t\t}else{\n\t\t\tapbct_public_sendAJAX(\n\t\t\t\t{\n\t\t\t\t\taction: 'apbct_get_pixel_url',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tnotJson: true,\n\t\t\t\t\tcallback: function (result) {\n\t\t\t\t\t\tif (result) {\n\t\t\t\t\t\t\tctSetPixelImg(result);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction ctSetHasScrolled() {\n\t\tif( ! ctScrollCollected ) {\n\t\t\tctSetCookie(\"ct_has_scrolled\", 'true');\n\t\t\tctScrollCollected = true;\n\t\t}\n\t}\n\n\tfunction ctSetMouseMoved() {\n\t\tif( ! ctMouseMovedCollected ) {\n\t\t\tctSetCookie(\"ct_mouse_moved\", 'true');\n\t\t\tctMouseMovedCollected = true;\n\t\t}\n\t}\n\n\tapbct_attach_event_handler(window, \"mousemove\", ctFunctionMouseMove);\n\tapbct_attach_event_handler(window, \"mousedown\", ctFunctionFirstKey);\n\tapbct_attach_event_handler(window, \"keydown\", ctFunctionFirstKey);\n\tapbct_attach_event_handler(window, \"scroll\", ctSetHasScrolled);\n\n\t// Ready function\n\tfunction apbct_ready(){\n\n\t\t// Collect scrolling info\n\t\tvar initCookies = [\n\t\t\t[\"ct_ps_timestamp\", Math.floor(new Date().getTime() / 1000)],\n\t\t\t[\"ct_fkp_timestamp\", \"0\"],\n\t\t\t[\"ct_pointer_data\", \"0\"],\n\t\t\t[\"ct_timezone\", ct_date.getTimezoneOffset()/60*(-1) ],\n\t\t\t[\"ct_screen_info\", apbctGetScreenInfo()],\n\t\t\t[\"ct_has_scrolled\", 'false'],\n\t\t\t[\"ct_mouse_moved\", 'false'],\n\t\t\t[\"apbct_headless\", navigator.webdriver],\n\t\t];\n\n\t\tif( ctPublic.data__cookies_type !== 'native' ) {\n\t\t\tinitCookies.push(['apbct_visible_fields', '0']);\n\t\t} else {\n\t\t\t// Delete all visible fields cookies on load the page\n\t\t\tvar cookiesArray = document.cookie.split(\";\");\n\t\t\tif( cookiesArray.length !== 0 ) {\n\t\t\t\tfor ( var i = 0; i < cookiesArray.length; i++ ) {\n\t\t\t\t\tvar currentCookie = cookiesArray[i].trim();\n\t\t\t\t\tvar cookieName = currentCookie.split(\"=\")[0];\n\t\t\t\t\tif( cookieName.indexOf(\"apbct_visible_fields_\") === 0 ) {\n\t\t\t\t\t\tctDeleteCookie(cookieName);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif( +ctPublic.pixel__setting ){\n\t\t\tif( +ctPublic.pixel__enabled ){\n\t\t\t\tctGetPixelUrl();\n\t\t\t} else {\n\t\t\t\tinitCookies.push(['apbct_pixel_url', ctPublic.pixel__url]);\n\t\t\t}\n\t\t}\n\n\t\tif ( +ctPublic.data__email_check_before_post) {\n\t\t\tinitCookies.push(['ct_checked_emails', '0']);\n\t\t\tjQuery(\"input[type = 'email'], #email\").blur(checkEmail);\n\t\t}\n\n\t\tctSetCookie(initCookies);\n\n\t\tsetTimeout(function(){\n\n\t\t\tfor(var i = 0; i < document.forms.length; i++){\n\t\t\t\tvar form = document.forms[i];\n\n\t\t\t\t//Exclusion for forms\n\t\t\t\tif (\n\t\t\t\t\t+ctPublic.data__visible_fields_required === 0 ||\n\t\t\t\t\tform.method.toString().toLowerCase() === 'get' ||\n\t\t\t\t\tform.classList.contains('slp_search_form') || //StoreLocatorPlus form\n\t\t\t\t\tform.parentElement.classList.contains('mec-booking') ||\n\t\t\t\t\tform.action.toString().indexOf('activehosted.com') !== -1 || // Active Campaign\n\t\t\t\t\t(form.id && form.id === 'caspioform') || //Caspio Form\n\t\t\t\t\t(form.classList && form.classList.contains('tinkoffPayRow')) || // TinkoffPayForm\n\t\t\t\t\t(form.classList && form.classList.contains('give-form')) || // GiveWP\n\t\t\t\t\t(form.id && form.id === 'ult-forgot-password-form') || //ult forgot password\n\t\t\t\t\t(form.id && form.id.toString().indexOf('calculatedfields') !== -1) || // CalculatedFieldsForm\n\t\t\t\t\t(form.id && form.id.toString().indexOf('sac-form') !== -1) || // Simple Ajax Chat\n\t\t\t\t\t(form.id && form.id.toString().indexOf('cp_tslotsbooking_pform') !== -1) || // WP Time Slots Booking Form\n\t\t\t\t\t(form.name && form.name.toString().indexOf('cp_tslotsbooking_pform') !== -1) || // WP Time Slots Booking Form\n\t\t\t\t\tform.action.toString() === 'https://epayment.epymtservice.com/epay.jhtml' // Custom form\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar hiddenInput = document.createElement( 'input' );\n\t\t\t\thiddenInput.setAttribute( 'type', 'hidden' );\n\t\t\t\thiddenInput.setAttribute( 'id', 'apbct_visible_fields_' + i );\n\t\t\t\thiddenInput.setAttribute( 'name', 'apbct_visible_fields');\n\t\t\t\tvar visibleFieldsToInput = {};\n\t\t\t\tvisibleFieldsToInput[0] = apbct_collect_visible_fields(form);\n\t\t\t\thiddenInput.value = JSON.stringify(visibleFieldsToInput);\n\t\t\t\tform.append( hiddenInput );\n\n\t\t\t\tform.onsubmit_prev = form.onsubmit;\n\n\t\t\t\tform.ctFormIndex = i;\n\t\t\t\tform.onsubmit = function (event) {\n\n\t\t\t\t\tif ( ctPublic.data__cookies_type !== 'native' && typeof event.target.ctFormIndex !== 'undefined' ) {\n\n\t\t\t\t\t\tvar visible_fields = {};\n\t\t\t\t\t\tvisible_fields[0] = apbct_collect_visible_fields(this);\n\t\t\t\t\t\tapbct_visible_fields_set_cookie( visible_fields, event.target.ctFormIndex );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Call previous submit action\n\t\t\t\t\tif (event.target.onsubmit_prev instanceof Function) {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\tevent.target.onsubmit_prev.call(event.target, event);\n\t\t\t\t\t\t}, 500);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\n\t\t}, 1000);\n\t}\n\tapbct_attach_event_handler(window, \"DOMContentLoaded\", apbct_ready);\n\n}());\n\nfunction apbct_collect_visible_fields( form ) {\n\n\t// Get only fields\n\tvar inputs = [],\n\t\tinputs_visible = '',\n\t\tinputs_visible_count = 0,\n\t\tinputs_invisible = '',\n\t\tinputs_invisible_count = 0,\n\t\tinputs_with_duplicate_names = [];\n\n\tfor(var key in form.elements){\n\t\tif(!isNaN(+key))\n\t\t\tinputs[key] = form.elements[key];\n\t}\n\n\t// Filter fields\n\tinputs = inputs.filter(function(elem){\n\n\t\t// Filter already added fields\n\t\tif( inputs_with_duplicate_names.indexOf( elem.getAttribute('name') ) !== -1 ){\n\t\t\treturn false;\n\t\t}\n\t\t// Filter inputs with same names for type == radio\n\t\tif( -1 !== ['radio', 'checkbox'].indexOf( elem.getAttribute(\"type\") )){\n\t\t\tinputs_with_duplicate_names.push( elem.getAttribute('name') );\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\n\t// Visible fields\n\tinputs.forEach(function(elem, i, elements){\n\t\t// Unnecessary fields\n\t\tif(\n\t\t\telem.getAttribute(\"type\") === \"submit\" || // type == submit\n\t\t\telem.getAttribute('name') === null ||\n\t\t\telem.getAttribute('name') === 'ct_checkjs'\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\t// Invisible fields\n\t\tif(\n\t\t\tgetComputedStyle(elem).display === \"none\" || // hidden\n\t\t\tgetComputedStyle(elem).visibility === \"hidden\" || // hidden\n\t\t\tgetComputedStyle(elem).opacity === \"0\" || // hidden\n\t\t\telem.getAttribute(\"type\") === \"hidden\" // type == hidden\n\t\t) {\n\t\t\tif( elem.classList.contains(\"wp-editor-area\") ) {\n\t\t\t\tinputs_visible += \" \" + elem.getAttribute(\"name\");\n\t\t\t\tinputs_visible_count++;\n\t\t\t} else {\n\t\t\t\tinputs_invisible += \" \" + elem.getAttribute(\"name\");\n\t\t\t\tinputs_invisible_count++;\n\t\t\t}\n\t\t}\n\t\t// Visible fields\n\t\telse {\n\t\t\tinputs_visible += \" \" + elem.getAttribute(\"name\");\n\t\t\tinputs_visible_count++;\n\t\t}\n\n\t});\n\n\tinputs_invisible = inputs_invisible.trim();\n\tinputs_visible = inputs_visible.trim();\n\n\treturn {\n\t\tvisible_fields : inputs_visible,\n\t\tvisible_fields_count : inputs_visible_count,\n\t\tinvisible_fields : inputs_invisible,\n\t\tinvisible_fields_count : inputs_invisible_count,\n\t}\n\n}\n\nfunction apbct_visible_fields_set_cookie( visible_fields_collection, form_id ) {\n\n\tvar collection = typeof visible_fields_collection === 'object' && visible_fields_collection !== null ? visible_fields_collection : {};\n\n\tif( ctPublic.data__cookies_type === 'native' ) {\n\t\tfor ( var i in collection ) {\n\t\t\tif ( i > 10 ) {\n\t\t\t\t// Do not generate more than 10 cookies\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar collectionIndex = form_id !== undefined ? form_id : i;\n\t\t\tctSetCookie(\"apbct_visible_fields_\" + collectionIndex, JSON.stringify( collection[i] ) );\n\t\t}\n\t} else {\n\t\tctSetCookie(\"apbct_visible_fields\", JSON.stringify( collection ) );\n\t}\n}\n\nfunction apbct_js_keys__set_input_value(result, data, params, obj){\n\tif( document.querySelectorAll('[name^=ct_checkjs]').length > 0 ) {\n\t\tvar elements = document.querySelectorAll('[name^=ct_checkjs]');\n\t\tfor ( var i = 0; i < elements.length; i++ ) {\n\t\t\telements[i].value = result.js_key;\n\t\t}\n\t}\n}\n\nfunction apbctGetScreenInfo() {\n\treturn JSON.stringify({\n\t\tfullWidth : document.documentElement.scrollWidth,\n\t\tfullHeight : Math.max(\n\t\t\tdocument.body.scrollHeight, document.documentElement.scrollHeight,\n\t\t\tdocument.body.offsetHeight, document.documentElement.offsetHeight,\n\t\t\tdocument.body.clientHeight, document.documentElement.clientHeight\n\t\t),\n\t\tvisibleWidth : document.documentElement.clientWidth,\n\t\tvisibleHeight : document.documentElement.clientHeight,\n\t});\n}\n\nif(typeof jQuery !== 'undefined') {\n\n\t// Capturing responses and output block message for unknown AJAX forms\n\tjQuery(document).ajaxComplete(function (event, xhr, settings) {\n\t\tif (xhr.responseText && xhr.responseText.indexOf('\"apbct') !== -1) {\n\t\t\tvar response = JSON.parse(xhr.responseText);\n\t\t\tif (typeof response.apbct !== 'undefined') {\n\t\t\t\tresponse = response.apbct;\n\t\t\t\tif (response.blocked) {\n\t\t\t\t\tdocument.dispatchEvent(\n\t\t\t\t\t\tnew CustomEvent( \"apbctAjaxBockAlert\", {\n\t\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\t\tdetail: { message: response.comment }\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t\t// Show the result by modal\n\t\t\t\t\tcleantalkModal.loaded = response.comment;\n\t\t\t\t\tcleantalkModal.open();\n\n\t\t\t\t\tif(+response.stop_script == 1)\n\t\t\t\t\t\twindow.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n}"],"names":["apbct_collect_visible_fields","form","key","inputs","inputs_visible","inputs_visible_count","inputs_invisible","inputs_invisible_count","inputs_with_duplicate_names","elements","isNaN","filter","elem","indexOf","getAttribute","push","forEach","i","getComputedStyle","display","visibility","opacity","classList","contains","trim","visible_fields","visible_fields_count","invisible_fields","invisible_fields_count","apbct_visible_fields_set_cookie","visible_fields_collection","form_id","collection","ctPublic","data__cookies_type","ctSetCookie","undefined","JSON","stringify","apbct_js_keys__set_input_value","result","data","params","obj","document","querySelectorAll","length","value","js_key","apbctGetScreenInfo","fullWidth","documentElement","scrollWidth","fullHeight","Math","max","body","scrollHeight","offsetHeight","clientHeight","visibleWidth","clientWidth","visibleHeight","ct_date","Date","ctTimeMs","getTime","ctMouseEventTimerFlag","ctMouseData","ctMouseDataCounter","ctCheckedEmails","ctScrollCollected","ctMouseMovedCollected","apbct_attach_event_handler","event","callback","window","addEventListener","attachEvent","apbct_remove_event_handler","removeEventListener","detachEvent","ctFunctionFirstKey","KeyTimestamp","floor","ctMouseReadInterval","setInterval","ctMouseWriteDataInterval","ctFunctionMouseMove","round","clientY","clientX","clearInterval","checkEmail","e","current_email","target","ctPublicFunctions","data__ajax_type","apbct_public_sendREST","method","email","timestamp","now","apbct_public_sendAJAX","action","ctSetPixelImg","pixelUrl","pixel__enabled","getElementById","jQuery","append","initCookies","getTimezoneOffset","navigator","webdriver","cookiesArray","cookie","split","cookieName","ctDeleteCookie","pixel__setting","notJson","pixel__url","data__email_check_before_post","blur","setTimeout","forms","hiddenInput","visibleFieldsToInput","data__visible_fields_required","toString","toLowerCase","parentElement","id","name","createElement","setAttribute","onsubmit_prev","onsubmit","ctFormIndex","this","Function","call","ajaxComplete","xhr","settings","responseText","response","parse","apbct","blocked","dispatchEvent","CustomEvent","bubbles","detail","message","comment","cleantalkModal","loaded","open","stop_script","stop"],"mappings":"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"}
1
+ {"version":3,"file":"apbct-public.min.js","sources":["apbct-public.js"],"sourcesContent":["(function() {\n\n\tvar ct_date = new Date(),\n\t\tctTimeMs = new Date().getTime(),\n\t\tctMouseEventTimerFlag = true, //Reading interval flag\n\t\tctMouseData = [],\n\t\tctMouseDataCounter = 0,\n\t\tctCheckedEmails = {},\n\t\tctScrollCollected = false,\n\t\tctMouseMovedCollected = false;\n\n\tfunction apbct_attach_event_handler(elem, event, callback){\n\t\tif(typeof window.addEventListener === \"function\") elem.addEventListener(event, callback);\n\t\telse elem.attachEvent(event, callback);\n\t}\n\n\tfunction apbct_remove_event_handler(elem, event, callback){\n\t\tif(typeof window.removeEventListener === \"function\") elem.removeEventListener(event, callback);\n\t\telse elem.detachEvent(event, callback);\n\t}\n\n\t//Writing first key press timestamp\n\tvar ctFunctionFirstKey = function output(event){\n\t\tvar KeyTimestamp = Math.floor(new Date().getTime()/1000);\n\t\tctSetCookie(\"ct_fkp_timestamp\", KeyTimestamp);\n\t\tctKeyStopStopListening();\n\t};\n\n\t//Reading interval\n\tvar ctMouseReadInterval = setInterval(function(){\n\t\tctMouseEventTimerFlag = true;\n\t}, 150);\n\n\t//Writting interval\n\tvar ctMouseWriteDataInterval = setInterval(function(){\n\t\tctSetCookie(\"ct_pointer_data\", JSON.stringify(ctMouseData));\n\t}, 1200);\n\n\t//Logging mouse position each 150 ms\n\tvar ctFunctionMouseMove = function output(event){\n\t\tctSetMouseMoved();\n\t\tif(ctMouseEventTimerFlag === true){\n\n\t\t\tctMouseData.push([\n\t\t\t\tMath.round(event.clientY),\n\t\t\t\tMath.round(event.clientX),\n\t\t\t\tMath.round(new Date().getTime() - ctTimeMs)\n\t\t\t]);\n\n\t\t\tctMouseDataCounter++;\n\t\t\tctMouseEventTimerFlag = false;\n\t\t\tif(ctMouseDataCounter >= 50){\n\t\t\t\tctMouseStopData();\n\t\t\t}\n\t\t}\n\t};\n\n\t//Stop mouse observing function\n\tfunction ctMouseStopData(){\n\t\tapbct_remove_event_handler(window, \"mousemove\", ctFunctionMouseMove);\n\t\tclearInterval(ctMouseReadInterval);\n\t\tclearInterval(ctMouseWriteDataInterval);\n\t}\n\n\t//Stop key listening function\n\tfunction ctKeyStopStopListening(){\n\t\tapbct_remove_event_handler(window, \"mousedown\", ctFunctionFirstKey);\n\t\tapbct_remove_event_handler(window, \"keydown\", ctFunctionFirstKey);\n\t}\n\n\tfunction checkEmail(e) {\n\t\tvar current_email = e.target.value;\n\t\tif (current_email && !(current_email in ctCheckedEmails)) {\n\t\t\t// Using REST API handler\n\t\t\tif( ctPublicFunctions.data__ajax_type === 'rest' ){\n\t\t\t\tapbct_public_sendREST(\n\t\t\t\t\t'check_email_before_post',\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\tdata: {'email' : current_email},\n\t\t\t\t\t\tcallback: function (result) {\n\t\t\t\t\t\t\tif (result.result) {\n\t\t\t\t\t\t\t\tctCheckedEmails[current_email] = {'result' : result.result, 'timestamp': Date.now() / 1000 |0};\n\t\t\t\t\t\t\t\tctSetCookie('ct_checked_emails', JSON.stringify(ctCheckedEmails));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t// Using AJAX request and handler\n\t\t\t} else if( ctPublicFunctions.data__ajax_type === 'admin_ajax' ) {\n\t\t\t\tapbct_public_sendAJAX(\n\t\t\t\t\t{\n\t\t\t\t\t\taction: 'apbct_email_check_before_post',\n\t\t\t\t\t\temail : current_email,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcallback: function (result) {\n\t\t\t\t\t\t\tif (result.result) {\n\t\t\t\t\t\t\t\tctCheckedEmails[current_email] = {'result' : result.result, 'timestamp': Date.now() / 1000 |0};\n\t\t\t\t\t\t\t\tctSetCookie('ct_checked_emails', JSON.stringify(ctCheckedEmails));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction ctSetPixelImg(pixelUrl) {\n\t\tctSetCookie('apbct_pixel_url', pixelUrl);\n\t\tif( +ctPublic.pixel__enabled ){\n\t\t\tif( ! document.getElementById('apbct_pixel') ) {\n\t\t\t\tjQuery('body').append( '<img alt=\"Cleantalk Pixel\" id=\"apbct_pixel\" style=\"display: none; left: 99999px;\" src=\"' + pixelUrl + '\">' );\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction ctGetPixelUrl() {\n\t\t// Check if pixel is already in localstorage and is not outdated\n\t\tlet local_storage_pixel_url = ctGetPixelUrlLocalstorage();\n\t\tif ( local_storage_pixel_url !== false ) {\n\t\t\tif ( ctIsOutdatedPixelUrlLocalstorage(local_storage_pixel_url) ) {\n\t\t\t\tctCleaPixelUrlLocalstorage(local_storage_pixel_url)\n\t\t\t} else {\n\t\t\t\t//if so - load pixel from localstorage and draw it skipping AJAX\n\t\t\t\tctSetPixelImg(local_storage_pixel_url);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// Using REST API handler\n\t\tif( ctPublicFunctions.data__ajax_type === 'rest' ){\n\t\t\tapbct_public_sendREST(\n\t\t\t\t'apbct_get_pixel_url',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\tcallback: function (result) {\n\t\t\t\t\t\tif (result) {\n\t\t\t\t\t\t\t//set pixel url to localstorage\n\t\t\t\t\t\t\tif ( ! ctGetPixelUrlLocalstorage() ){\n\t\t\t\t\t\t\t\tctSetPixelUrlLocalstorage(result);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t//then run pixel drawing\n\t\t\t\t\t\t\tctSetPixelImg(result);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\t\t// Using AJAX request and handler\n\t\t}else{\n\t\t\tapbct_public_sendAJAX(\n\t\t\t\t{\n\t\t\t\t\taction: 'apbct_get_pixel_url',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tnotJson: true,\n\t\t\t\t\tcallback: function (result) {\n\t\t\t\t\t\tif (result) {\n\t\t\t\t\t\t\t//set pixel url to localstorage\n\t\t\t\t\t\t\tif ( ! ctGetPixelUrlLocalstorage() ){\n\t\t\t\t\t\t\t\tctSetPixelUrlLocalstorage(result);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t//then run pixel drawing\n\t\t\t\t\t\t\tctSetPixelImg(result);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction ctSetHasScrolled() {\n\t\tif( ! ctScrollCollected ) {\n\t\t\tctSetCookie(\"ct_has_scrolled\", 'true');\n\t\t\tctScrollCollected = true;\n\t\t}\n\t}\n\n\tfunction ctSetMouseMoved() {\n\t\tif( ! ctMouseMovedCollected ) {\n\t\t\tctSetCookie(\"ct_mouse_moved\", 'true');\n\t\t\tctMouseMovedCollected = true;\n\t\t}\n\t}\n\n\tapbct_attach_event_handler(window, \"mousemove\", ctFunctionMouseMove);\n\tapbct_attach_event_handler(window, \"mousedown\", ctFunctionFirstKey);\n\tapbct_attach_event_handler(window, \"keydown\", ctFunctionFirstKey);\n\tapbct_attach_event_handler(window, \"scroll\", ctSetHasScrolled);\n\n\t// Ready function\n\tfunction apbct_ready(){\n\n\t\t// Collect scrolling info\n\t\tvar initCookies = [\n\t\t\t[\"ct_ps_timestamp\", Math.floor(new Date().getTime() / 1000)],\n\t\t\t[\"ct_fkp_timestamp\", \"0\"],\n\t\t\t[\"ct_pointer_data\", \"0\"],\n\t\t\t[\"ct_timezone\", ct_date.getTimezoneOffset()/60*(-1) ],\n\t\t\t[\"ct_screen_info\", apbctGetScreenInfo()],\n\t\t\t[\"ct_has_scrolled\", 'false'],\n\t\t\t[\"ct_mouse_moved\", 'false'],\n\t\t\t[\"apbct_headless\", navigator.webdriver],\n\t\t];\n\n\t\tif( ctPublic.data__cookies_type !== 'native' ) {\n\t\t\tinitCookies.push(['apbct_visible_fields', '0']);\n\t\t} else {\n\t\t\t// Delete all visible fields cookies on load the page\n\t\t\tvar cookiesArray = document.cookie.split(\";\");\n\t\t\tif( cookiesArray.length !== 0 ) {\n\t\t\t\tfor ( var i = 0; i < cookiesArray.length; i++ ) {\n\t\t\t\t\tvar currentCookie = cookiesArray[i].trim();\n\t\t\t\t\tvar cookieName = currentCookie.split(\"=\")[0];\n\t\t\t\t\tif( cookieName.indexOf(\"apbct_visible_fields_\") === 0 ) {\n\t\t\t\t\t\tctDeleteCookie(cookieName);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif( +ctPublic.pixel__setting ){\n\t\t\tif( +ctPublic.pixel__enabled ){\n\t\t\t\tctGetPixelUrl()\n\t\t\t} else {\n\t\t\t\tinitCookies.push(['apbct_pixel_url', ctPublic.pixel__url]);\n\t\t\t}\n\t\t}\n\n\t\tif ( +ctPublic.data__email_check_before_post) {\n\t\t\tinitCookies.push(['ct_checked_emails', '0']);\n\t\t\tjQuery(\"input[type = 'email'], #email\").blur(checkEmail);\n\t\t}\n\n\t\tctSetCookie(initCookies);\n\n\t\tsetTimeout(function(){\n\n\t\t\tfor(var i = 0; i < document.forms.length; i++){\n\t\t\t\tvar form = document.forms[i];\n\n\t\t\t\t//Exclusion for forms\n\t\t\t\tif (\n\t\t\t\t\t+ctPublic.data__visible_fields_required === 0 ||\n\t\t\t\t\tform.method.toString().toLowerCase() === 'get' ||\n\t\t\t\t\tform.classList.contains('slp_search_form') || //StoreLocatorPlus form\n\t\t\t\t\tform.parentElement.classList.contains('mec-booking') ||\n\t\t\t\t\tform.action.toString().indexOf('activehosted.com') !== -1 || // Active Campaign\n\t\t\t\t\t(form.id && form.id === 'caspioform') || //Caspio Form\n\t\t\t\t\t(form.classList && form.classList.contains('tinkoffPayRow')) || // TinkoffPayForm\n\t\t\t\t\t(form.classList && form.classList.contains('give-form')) || // GiveWP\n\t\t\t\t\t(form.id && form.id === 'ult-forgot-password-form') || //ult forgot password\n\t\t\t\t\t(form.id && form.id.toString().indexOf('calculatedfields') !== -1) || // CalculatedFieldsForm\n\t\t\t\t\t(form.id && form.id.toString().indexOf('sac-form') !== -1) || // Simple Ajax Chat\n\t\t\t\t\t(form.id && form.id.toString().indexOf('cp_tslotsbooking_pform') !== -1) || // WP Time Slots Booking Form\n\t\t\t\t\t(form.name && form.name.toString().indexOf('cp_tslotsbooking_pform') !== -1) || // WP Time Slots Booking Form\n\t\t\t\t\tform.action.toString() === 'https://epayment.epymtservice.com/epay.jhtml' || // Custom form\n\t\t\t\t\t(form.name && form.name.toString().indexOf('tribe-bar-form') !== -1) // The Events Calendar\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar hiddenInput = document.createElement( 'input' );\n\t\t\t\thiddenInput.setAttribute( 'type', 'hidden' );\n\t\t\t\thiddenInput.setAttribute( 'id', 'apbct_visible_fields_' + i );\n\t\t\t\thiddenInput.setAttribute( 'name', 'apbct_visible_fields');\n\t\t\t\tvar visibleFieldsToInput = {};\n\t\t\t\tvisibleFieldsToInput[0] = apbct_collect_visible_fields(form);\n\t\t\t\thiddenInput.value = JSON.stringify(visibleFieldsToInput);\n\t\t\t\tform.append( hiddenInput );\n\n\t\t\t\tform.onsubmit_prev = form.onsubmit;\n\n\t\t\t\tform.ctFormIndex = i;\n\t\t\t\tform.onsubmit = function (event) {\n\n\t\t\t\t\tif ( ctPublic.data__cookies_type !== 'native' && typeof event.target.ctFormIndex !== 'undefined' ) {\n\n\t\t\t\t\t\tvar visible_fields = {};\n\t\t\t\t\t\tvisible_fields[0] = apbct_collect_visible_fields(this);\n\t\t\t\t\t\tapbct_visible_fields_set_cookie( visible_fields, event.target.ctFormIndex );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Call previous submit action\n\t\t\t\t\tif (event.target.onsubmit_prev instanceof Function) {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\tevent.target.onsubmit_prev.call(event.target, event);\n\t\t\t\t\t\t}, 500);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\n\t\t}, 1000);\n\n\t\t// Listen clicks on encoded emails\n\t\tlet decodedEmailNodes = document.querySelectorAll(\"[data-original-string]\");\n\t\tif (decodedEmailNodes.length) {\n\t\t\tfor (let i = 0; i < decodedEmailNodes.length; ++i) {\n\t\t\t\tif (\n\t\t\t\t\tdecodedEmailNodes[i].parentElement.href ||\n\t\t\t\t\tdecodedEmailNodes[i].parentElement.parentElement.href\n\t\t\t\t) {\n\t\t\t\t\t// Skip listening click on hyperlinks\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdecodedEmailNodes[i].addEventListener('click', function ctFillDecodedEmailHandler(event) {\n\t\t\t\t\tthis.removeEventListener('click', ctFillDecodedEmailHandler);\n\t\t\t\t\tapbctAjaxEmailDecode(event);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\tapbct_attach_event_handler(window, \"DOMContentLoaded\", apbct_ready);\n\n}());\n\nfunction apbctAjaxEmailDecode(event){\n\tconst element = event.target;\n\telement.setAttribute('title', ctPublicFunctions.text__wait_for_decoding);\n\telement.style.cursor = 'progress';\n\t// Using REST API handler\n\tif( ctPublicFunctions.data__ajax_type === 'rest' ){\n\t\tapbct_public_sendREST(\n\t\t\t'apbct_decode_email',\n\t\t\t{\n\t\t\t\tdata: {encodedEmail: event.target.dataset.originalString},\n\t\t\t\tmethod: 'POST',\n\t\t\t\tcallback: function (result) {\n\t\t\t\t\tif (result.success) {\n\t\t\t\t\t\tctFillDecodedEmail(result.data, event.target);\n\t\t\t\t\t\telement.setAttribute('title', '');\n\t\t\t\t\t\telement.removeAttribute('style');\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\t\t// Using AJAX request and handler\n\t}else{\n\t\tapbct_public_sendAJAX(\n\t\t\t{\n\t\t\t\taction: 'apbct_decode_email',\n\t\t\t\tencodedEmail: event.target.dataset.originalString\n\t\t\t},\n\t\t\t{\n\t\t\t\tnotJson: true,\n\t\t\t\tcallback: function (result) {\n\t\t\t\t\tif (result.success) {\n\t\t\t\t\t\tctFillDecodedEmail(result.data, event.target);\n\t\t\t\t\t\telement.setAttribute('title', '');\n\t\t\t\t\t\telement.removeAttribute('style');\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\t}\n}\n\nfunction ctFillDecodedEmail(result, targetElement){\n\ttargetElement.innerText = result;\n}\n\nfunction apbct_collect_visible_fields( form ) {\n\n\t// Get only fields\n\tvar inputs = [],\n\t\tinputs_visible = '',\n\t\tinputs_visible_count = 0,\n\t\tinputs_invisible = '',\n\t\tinputs_invisible_count = 0,\n\t\tinputs_with_duplicate_names = [];\n\n\tfor(var key in form.elements){\n\t\tif(!isNaN(+key))\n\t\t\tinputs[key] = form.elements[key];\n\t}\n\n\t// Filter fields\n\tinputs = inputs.filter(function(elem){\n\n\t\t// Filter already added fields\n\t\tif( inputs_with_duplicate_names.indexOf( elem.getAttribute('name') ) !== -1 ){\n\t\t\treturn false;\n\t\t}\n\t\t// Filter inputs with same names for type == radio\n\t\tif( -1 !== ['radio', 'checkbox'].indexOf( elem.getAttribute(\"type\") )){\n\t\t\tinputs_with_duplicate_names.push( elem.getAttribute('name') );\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\n\t// Visible fields\n\tinputs.forEach(function(elem, i, elements){\n\t\t// Unnecessary fields\n\t\tif(\n\t\t\telem.getAttribute(\"type\") === \"submit\" || // type == submit\n\t\t\telem.getAttribute('name') === null ||\n\t\t\telem.getAttribute('name') === 'ct_checkjs'\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\t// Invisible fields\n\t\tif(\n\t\t\tgetComputedStyle(elem).display === \"none\" || // hidden\n\t\t\tgetComputedStyle(elem).visibility === \"hidden\" || // hidden\n\t\t\tgetComputedStyle(elem).opacity === \"0\" || // hidden\n\t\t\telem.getAttribute(\"type\") === \"hidden\" // type == hidden\n\t\t) {\n\t\t\tif( elem.classList.contains(\"wp-editor-area\") ) {\n\t\t\t\tinputs_visible += \" \" + elem.getAttribute(\"name\");\n\t\t\t\tinputs_visible_count++;\n\t\t\t} else {\n\t\t\t\tinputs_invisible += \" \" + elem.getAttribute(\"name\");\n\t\t\t\tinputs_invisible_count++;\n\t\t\t}\n\t\t}\n\t\t// Visible fields\n\t\telse {\n\t\t\tinputs_visible += \" \" + elem.getAttribute(\"name\");\n\t\t\tinputs_visible_count++;\n\t\t}\n\n\t});\n\n\tinputs_invisible = inputs_invisible.trim();\n\tinputs_visible = inputs_visible.trim();\n\n\treturn {\n\t\tvisible_fields : inputs_visible,\n\t\tvisible_fields_count : inputs_visible_count,\n\t\tinvisible_fields : inputs_invisible,\n\t\tinvisible_fields_count : inputs_invisible_count,\n\t}\n\n}\n\nfunction apbct_visible_fields_set_cookie( visible_fields_collection, form_id ) {\n\n\tvar collection = typeof visible_fields_collection === 'object' && visible_fields_collection !== null ? visible_fields_collection : {};\n\n\tif( ctPublic.data__cookies_type === 'native' ) {\n\t\tfor ( var i in collection ) {\n\t\t\tif ( i > 10 ) {\n\t\t\t\t// Do not generate more than 10 cookies\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar collectionIndex = form_id !== undefined ? form_id : i;\n\t\t\tctSetCookie(\"apbct_visible_fields_\" + collectionIndex, JSON.stringify( collection[i] ) );\n\t\t}\n\t} else {\n\t\tctSetCookie(\"apbct_visible_fields\", JSON.stringify( collection ) );\n\t}\n}\n\nfunction apbct_js_keys__set_input_value(result, data, params, obj){\n\tif( document.querySelectorAll('[name^=ct_checkjs]').length > 0 ) {\n\t\tvar elements = document.querySelectorAll('[name^=ct_checkjs]');\n\t\tfor ( var i = 0; i < elements.length; i++ ) {\n\t\t\telements[i].value = result.js_key;\n\t\t}\n\t}\n}\n\nfunction apbctGetScreenInfo() {\n\treturn JSON.stringify({\n\t\tfullWidth : document.documentElement.scrollWidth,\n\t\tfullHeight : Math.max(\n\t\t\tdocument.body.scrollHeight, document.documentElement.scrollHeight,\n\t\t\tdocument.body.offsetHeight, document.documentElement.offsetHeight,\n\t\t\tdocument.body.clientHeight, document.documentElement.clientHeight\n\t\t),\n\t\tvisibleWidth : document.documentElement.clientWidth,\n\t\tvisibleHeight : document.documentElement.clientHeight,\n\t});\n}\n\nif(typeof jQuery !== 'undefined') {\n\n\t// Capturing responses and output block message for unknown AJAX forms\n\tjQuery(document).ajaxComplete(function (event, xhr, settings) {\n\t\tif (xhr.responseText && xhr.responseText.indexOf('\"apbct') !== -1) {\n\t\t\tvar response = JSON.parse(xhr.responseText);\n\t\t\tif (typeof response.apbct !== 'undefined') {\n\t\t\t\tresponse = response.apbct;\n\t\t\t\tif (response.blocked) {\n\t\t\t\t\tdocument.dispatchEvent(\n\t\t\t\t\t\tnew CustomEvent( \"apbctAjaxBockAlert\", {\n\t\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\t\tdetail: { message: response.comment }\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t\t// Show the result by modal\n\t\t\t\t\tcleantalkModal.loaded = response.comment;\n\t\t\t\t\tcleantalkModal.open();\n\n\t\t\t\t\tif(+response.stop_script == 1)\n\t\t\t\t\t\twindow.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction ctSetPixelUrlLocalstorage(ajax_pixel_url) {\n\t//set pixel to the storage\n\tlocalStorage.setItem('session_pixel_url', ajax_pixel_url)\n\t//set pixel timestamp to the storage\n\tlocalStorage.setItem(ajax_pixel_url, Math.floor(Date.now() / 1000).toString())\n}\n\nfunction ctGetPixelUrlLocalstorage() {\n\tlet local_storage_pixel = localStorage.getItem('session_pixel_url');\n\tif ( local_storage_pixel !== null ) {\n\t\treturn local_storage_pixel;\n\t} else {\n\t\treturn false;\n\t}\n}\n\nfunction ctIsOutdatedPixelUrlLocalstorage(local_storage_pixel_url) {\n\tlet local_storage_pixel_timestamp = Number(localStorage.getItem(local_storage_pixel_url));\n\tlet current_timestamp = Math.floor(Date.now() / 1000).toString()\n\tlet timestamp_difference = current_timestamp - local_storage_pixel_timestamp;\n\treturn timestamp_difference > 3600 * 3;\n}\n\nfunction ctCleaPixelUrlLocalstorage(local_storage_pixel_url) {\n\t//remove timestamp\n\tlocalStorage.removeItem(local_storage_pixel_url)\n\t//remove pixel itself\n\tlocalStorage.removeItem('session_pixel_url')\n}"],"names":["apbctAjaxEmailDecode","event","element","target","setAttribute","ctPublicFunctions","text__wait_for_decoding","style","cursor","data__ajax_type","apbct_public_sendREST","data","encodedEmail","dataset","originalString","method","callback","result","success","ctFillDecodedEmail","removeAttribute","apbct_public_sendAJAX","action","notJson","targetElement","innerText","apbct_collect_visible_fields","form","key","inputs","inputs_visible","inputs_visible_count","inputs_invisible","inputs_invisible_count","inputs_with_duplicate_names","elements","isNaN","filter","elem","indexOf","getAttribute","push","forEach","i","getComputedStyle","display","visibility","opacity","classList","contains","trim","visible_fields","visible_fields_count","invisible_fields","invisible_fields_count","apbct_visible_fields_set_cookie","visible_fields_collection","form_id","collection","ctPublic","data__cookies_type","ctSetCookie","undefined","JSON","stringify","apbct_js_keys__set_input_value","params","obj","document","querySelectorAll","length","value","js_key","apbctGetScreenInfo","fullWidth","documentElement","scrollWidth","fullHeight","Math","max","body","scrollHeight","offsetHeight","clientHeight","visibleWidth","clientWidth","visibleHeight","ctSetPixelUrlLocalstorage","ajax_pixel_url","localStorage","setItem","floor","Date","now","toString","ctGetPixelUrlLocalstorage","let","local_storage_pixel","getItem","ctIsOutdatedPixelUrlLocalstorage","local_storage_pixel_url","local_storage_pixel_timestamp","Number","ctCleaPixelUrlLocalstorage","removeItem","ct_date","ctTimeMs","getTime","ctMouseEventTimerFlag","ctMouseData","ctMouseDataCounter","ctCheckedEmails","ctScrollCollected","ctMouseMovedCollected","apbct_attach_event_handler","window","addEventListener","attachEvent","apbct_remove_event_handler","removeEventListener","detachEvent","ctFunctionFirstKey","KeyTimestamp","ctMouseReadInterval","setInterval","ctMouseWriteDataInterval","ctFunctionMouseMove","round","clientY","clientX","clearInterval","checkEmail","e","current_email","email","timestamp","ctSetPixelImg","pixelUrl","pixel__enabled","getElementById","jQuery","append","initCookies","getTimezoneOffset","navigator","webdriver","cookiesArray","cookie","split","cookieName","ctDeleteCookie","pixel__setting","ctGetPixelUrl","pixel__url","data__email_check_before_post","blur","setTimeout","forms","hiddenInput","visibleFieldsToInput","data__visible_fields_required","toLowerCase","parentElement","id","name","createElement","onsubmit_prev","onsubmit","ctFormIndex","this","Function","call","decodedEmailNodes","href","ctFillDecodedEmailHandler","ajaxComplete","xhr","settings","responseText","response","parse","apbct","blocked","dispatchEvent","CustomEvent","bubbles","detail","message","comment","cleantalkModal","loaded","open","stop_script","stop"],"mappings":"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"}
lib/Cleantalk/Antispam/Cleantalk.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace Cleantalk\Antispam;
4
 
5
  use Cleantalk\ApbctWP\Helper;
 
6
 
7
  /**
8
  * Cleantalk base class
@@ -18,12 +19,6 @@ use Cleantalk\ApbctWP\Helper;
18
  */
19
  class Cleantalk
20
  {
21
- /**
22
- * Use WordPress built-in API
23
- * @var bool
24
- */
25
- public $use_bultin_api = false;
26
-
27
  /**
28
  * Maximum data size in bytes
29
  * @var int
@@ -84,18 +79,6 @@ class Cleantalk
84
  */
85
  public $api_version = '/api2.0';
86
 
87
- /**
88
- * Use https connection to servers
89
- * @var bool
90
- */
91
- public $ssl_on = false;
92
-
93
- /**
94
- * Path to SSL certificate
95
- * @var string
96
- */
97
- public $ssl_path = '';
98
-
99
  /**
100
  * Minimal server response in milliseconds to catch the server
101
  * @var int
@@ -283,7 +266,7 @@ class Cleantalk
283
  $this->downServers[] = $this->work_url;
284
  }
285
  $this->rotateModerate();
286
- $result = $this->sendRequest($msg, $this->work_url);
287
  if ( $result !== false && $result->errno === 0 ) {
288
  $this->server_change = true;
289
  }
@@ -459,10 +442,6 @@ class Cleantalk
459
  */
460
  private function sendRequest($data, $url, $server_timeout = 3)
461
  {
462
- $original_args = func_get_args();
463
- // Convert to array
464
- $data = (array)json_decode(json_encode($data), true);
465
-
466
  //Cleaning from 'null' values
467
  $tmp_data = array();
468
  foreach ( $data as $key => $value ) {
@@ -480,93 +459,12 @@ class Cleantalk
480
  $url .= $this->api_version;
481
  }
482
 
483
- $result = false;
484
- $curl_error = null;
485
-
486
- // Switching to secure connection
487
- if ( $this->ssl_on && ! preg_match("/^https:/", $url) ) {
488
- $url = preg_replace("/^(http)/i", "$1s", $url);
489
- }
490
-
491
- if ( $this->use_bultin_api ) {
492
- $args = array(
493
- 'body' => $data,
494
- 'timeout' => $server_timeout,
495
- 'user-agent' => APBCT_AGENT . ' ' . get_bloginfo('url'),
496
- );
497
-
498
- $result = wp_remote_post($url, $args);
499
-
500
- if ( is_wp_error($result) ) {
501
- $result = false;
502
- } else {
503
- $result = wp_remote_retrieve_body($result);
504
- }
505
- } else {
506
- if ( function_exists('curl_init') ) {
507
- $ch = curl_init();
508
-
509
- curl_setopt($ch, CURLOPT_URL, $url);
510
- curl_setopt($ch, CURLOPT_TIMEOUT, $server_timeout);
511
- curl_setopt($ch, CURLOPT_POST, 1);
512
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
513
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // receive server response ...
514
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); // resolve 'Expect: 100-continue' issue
515
- curl_setopt(
516
- $ch,
517
- CURLOPT_HTTP_VERSION,
518
- CURL_HTTP_VERSION_1_0
519
- ); // see http://stackoverflow.com/a/23322368
520
-
521
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disabling CA cert verification and
522
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // Disabling common name verification
523
-
524
- if ( $this->ssl_on && $this->ssl_path != '' ) {
525
- curl_setopt($ch, CURLOPT_CAINFO, $this->ssl_path);
526
- }
527
-
528
- $result = curl_exec($ch);
529
- if ( ! $result ) {
530
- $curl_error = curl_error($ch);
531
- // Use SSL next time, if error occurs.
532
- if ( ! $this->ssl_on ) {
533
- $this->ssl_on = true;
534
-
535
- return $this->sendRequest($original_args[0], $original_args[1], $server_timeout);
536
- }
537
- }
538
-
539
- curl_close($ch);
540
- }
541
- }
542
-
543
- if ( ! $result ) {
544
- $allow_url_fopen = ini_get('allow_url_fopen');
545
- if ( function_exists('file_get_contents') && $allow_url_fopen ) {
546
- $opts = array(
547
- 'http' =>
548
- array(
549
- 'method' => 'POST',
550
- 'header' => "Content-Type: text/html\r\n",
551
- 'content' => $data,
552
- 'timeout' => $server_timeout
553
- )
554
- );
555
-
556
- $context = stream_context_create($opts);
557
- $result = @file_get_contents($url, false, $context);
558
- }
559
- }
560
 
561
- if ( ! $result ) {
562
- $response['errno'] = 2;
563
- $response['errstr'] = $curl_error
564
- ? sprintf("CURL error: '%s'", $curl_error)
565
- : 'No CURL support compiled in';
566
- $response['errstr'] .= ' or disabled allow_url_fopen in php.ini.';
567
-
568
- return json_decode(json_encode($response));
569
- }
570
 
571
  $errstr = null;
572
  $response = is_string($result) ? json_decode($result) : false;
@@ -574,7 +472,7 @@ class Cleantalk
574
  $response->errno = 0;
575
  $response->errstr = $errstr;
576
  } else {
577
- $errstr = 'Unknown response from ' . $url . '.' . ' ' . $result;
578
 
579
  $response = null;
580
  $response['errno'] = 1;
3
  namespace Cleantalk\Antispam;
4
 
5
  use Cleantalk\ApbctWP\Helper;
6
+ use Cleantalk\ApbctWP\HTTP\Request;
7
 
8
  /**
9
  * Cleantalk base class
19
  */
20
  class Cleantalk
21
  {
 
 
 
 
 
 
22
  /**
23
  * Maximum data size in bytes
24
  * @var int
79
  */
80
  public $api_version = '/api2.0';
81
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  /**
83
  * Minimal server response in milliseconds to catch the server
84
  * @var int
266
  $this->downServers[] = $this->work_url;
267
  }
268
  $this->rotateModerate();
269
+ $result = $this->sendRequest($msg, $this->work_url, $this->server_timeout);
270
  if ( $result !== false && $result->errno === 0 ) {
271
  $this->server_change = true;
272
  }
442
  */
443
  private function sendRequest($data, $url, $server_timeout = 3)
444
  {
 
 
 
 
445
  //Cleaning from 'null' values
446
  $tmp_data = array();
447
  foreach ( $data as $key => $value ) {
459
  $url .= $this->api_version;
460
  }
461
 
462
+ $http = new Request();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
 
464
+ $result = $http->setUrl($url)
465
+ ->setData($data)
466
+ ->setOptions(['timeout' => $server_timeout])
467
+ ->request();
 
 
 
 
 
468
 
469
  $errstr = null;
470
  $response = is_string($result) ? json_decode($result) : false;
472
  $response->errno = 0;
473
  $response->errstr = $errstr;
474
  } else {
475
+ $errstr = 'Unknown response from ' . $url . '.' . ' ' . isset($result['error']) ? $result['error'] : $result;
476
 
477
  $response = null;
478
  $response['errno'] = 1;
lib/Cleantalk/Antispam/EmailEncoder.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Cleantalk\Antispam;
4
+
5
+ use Cleantalk\ApbctWP\Escape;
6
+ use Cleantalk\Templates\Singleton;
7
+ use Cleantalk\Variables\Post;
8
+
9
+ class EmailEncoder
10
+ {
11
+ use Singleton;
12
+
13
+ private $secret_key;
14
+
15
+ private $encription;
16
+
17
+ protected function init()
18
+ {
19
+ global $apbct;
20
+
21
+ $this->secret_key = md5($apbct->api_key);
22
+
23
+ $this->encription = function_exists('openssl_encrypt') && function_exists('openssl_decrypt');
24
+
25
+ $hooks_to_encode = array(
26
+ 'the_title',
27
+ 'the_content',
28
+ 'the_excerpt',
29
+ 'get_footer',
30
+ 'get_the_excerpt',
31
+ 'comment_text',
32
+ 'comment_excerpt',
33
+ 'comment_url',
34
+ 'get_comment_author_url',
35
+ 'get_comment_author_url_link',
36
+ 'widget_title',
37
+ 'widget_text',
38
+ 'widget_content',
39
+ 'widget_output',
40
+ );
41
+ foreach ( $hooks_to_encode as $hook ) {
42
+ add_filter($hook, array($this, 'modifyContent'));
43
+ }
44
+
45
+ add_action('wp_ajax_nopriv_apbct_decode_email', array($this, 'ajaxDecodeEmailHandler'));
46
+ add_action('wp_ajax_apbct_decode_email', array($this, 'ajaxDecodeEmailHandler'));
47
+ }
48
+
49
+ public function modifyContent($content)
50
+ {
51
+ return preg_replace_callback('/([_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,}))/', function ($matches) {
52
+ if ( in_array(strtolower($matches[4]), ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp']) ) {
53
+ return $matches[0];
54
+ }
55
+
56
+ $obfuscated = $this->obfuscateEmail($matches[0]);
57
+
58
+ $encoded = $this->encodeEmail($matches[0], $this->secret_key);
59
+
60
+ $tooltip = esc_html__('This contact was encoded by CleanTalk. Click to decode.', 'cleantalk-spam-protect');
61
+
62
+ return '<span
63
+ data-original-string="' . $encoded . '"
64
+ class="apbct-email-encoder"
65
+ title="' . esc_attr($tooltip) . '">' . $obfuscated . '</span>';
66
+ }, $content);
67
+ }
68
+
69
+ public function ajaxDecodeEmailHandler()
70
+ {
71
+ check_ajax_referer('ct_secret_stuff');
72
+ $this->ajaxDecodeEmail();
73
+ }
74
+
75
+ public function ajaxDecodeEmail()
76
+ {
77
+ // @ToDo implement bot checking via API. the method not implemented yet.
78
+
79
+ $encoded_email = trim(Post::get('encodedEmail'));
80
+ $email = $this->decodeEmail($encoded_email, $this->secret_key);
81
+ wp_send_json_success(Escape::escHtml($email));
82
+ }
83
+
84
+ private function encodeEmail($plain_email, $key)
85
+ {
86
+ if ( $this->encription ) {
87
+ $encoded_email = htmlspecialchars(@openssl_encrypt($plain_email, 'aes-128-cbc', $key));
88
+ } else {
89
+ $encoded_email = htmlspecialchars(base64_encode(str_rot13($plain_email)));
90
+ }
91
+ return $encoded_email;
92
+ }
93
+
94
+ private function decodeEmail($encoded_email, $key)
95
+ {
96
+ if ( $this->encription ) {
97
+ $decoded_email = htmlspecialchars_decode(@openssl_decrypt($encoded_email, 'aes-128-cbc', $key));
98
+ } else {
99
+ $decoded_email = htmlspecialchars_decode(base64_decode($encoded_email));
100
+ $decoded_email = str_rot13($decoded_email);
101
+ }
102
+ return $decoded_email;
103
+ }
104
+
105
+ private function obfuscateEmail($email)
106
+ {
107
+ $first_part = strpos($email, '@') > 2
108
+ ? substr($email, 0, 2) . str_pad('', strpos($email, '@') - 2, '*')
109
+ : str_pad('', strpos($email, '@'), '*');
110
+ $second_part = substr($email, strpos($email, '@') + 1, 2)
111
+ . str_pad('', strpos($email, '.', strpos($email, '@')) - 3 - strpos($email, '@'), '*');
112
+ $last_part = substr($email, (int) strrpos($email, '.', -1) - strlen($email));
113
+ return $first_part . '@' . $second_part . $last_part;
114
+ }
115
+ }
lib/Cleantalk/ApbctWP/API.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace Cleantalk\ApbctWP;
4
 
 
 
5
  /**
6
  * Class API.
7
  * Compatible only with WordPress.
@@ -53,45 +55,25 @@ class API extends \Cleantalk\Common\API
53
  * @param int $timeout
54
  * @param bool Do we need to use SSL
55
  *
56
- * @return array|string
57
  */
58
  public static function sendRequest($data, $url = self::URL, $timeout = 10, $ssl = false, $ssl_path = '')
59
  {
60
- global $apbct;
61
-
62
  // Possibility to switch API url
63
  $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $url;
64
 
65
  // Adding agent version to data
66
  $data['agent'] = defined('APBCT_AGENT') ? APBCT_AGENT : '';
67
 
68
- if (
69
- $apbct->settings['wp__use_builtin_http_api'] &&
70
- ( ! defined('SHORTINIT') || (defined('SHORTINIT') && SHORTINIT === false))
71
- ) {
72
- $args = array(
73
- 'body' => $data,
74
- 'timeout' => $timeout,
75
- 'user-agent' => APBCT_AGENT . ' ' . get_bloginfo('url'),
76
- );
77
-
78
- $result = wp_remote_post($url, $args);
79
-
80
- if ( is_wp_error($result) ) {
81
- $errors = $result->get_error_message();
82
- $result = false;
83
- } else {
84
- $result = wp_remote_retrieve_body($result);
85
- }
86
- // Call CURL version if disabled
87
- } else {
88
- $ssl_path = $ssl_path
89
- ?: (defined('APBCT_CASERT_PATH') ? APBCT_CASERT_PATH : '');
90
- $result = parent::sendRequest($data, $url, $timeout, $ssl, $ssl_path);
91
- }
92
 
93
- return empty($result) || ! empty($errors)
94
- ? array('error' => $errors)
95
- : $result;
 
 
 
 
 
96
  }
97
  }
2
 
3
  namespace Cleantalk\ApbctWP;
4
 
5
+ use Cleantalk\ApbctWP\HTTP\Request;
6
+
7
  /**
8
  * Class API.
9
  * Compatible only with WordPress.
55
  * @param int $timeout
56
  * @param bool Do we need to use SSL
57
  *
58
+ * @return array|bool
59
  */
60
  public static function sendRequest($data, $url = self::URL, $timeout = 10, $ssl = false, $ssl_path = '')
61
  {
 
 
62
  // Possibility to switch API url
63
  $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $url;
64
 
65
  // Adding agent version to data
66
  $data['agent'] = defined('APBCT_AGENT') ? APBCT_AGENT : '';
67
 
68
+ $http = new Request();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
+ return $http->setUrl($url)
71
+ ->setData($data)
72
+ ->setPresets(['retry_with_socket'])
73
+ ->addCallback(
74
+ __CLASS__ . '::checkResponse',
75
+ [$data['method_name']]
76
+ )
77
+ ->request();
78
  }
79
  }
lib/Cleantalk/ApbctWP/CleantalkSettingsTemplates.php CHANGED
@@ -54,7 +54,7 @@ class CleantalkSettingsTemplates
54
  $template_info = Post::get('data');
55
  if ( isset($template_info['template_id']) ) {
56
  $template_id = sanitize_text_field($template_info['template_id']);
57
- $res = \Cleantalk\Common\API::methodServicesTemplatesUpdate(
58
  $this->api_key,
59
  (int)$template_id,
60
  $this->getPluginOptions()
@@ -71,7 +71,7 @@ class CleantalkSettingsTemplates
71
  }
72
  if ( isset($template_info['template_name']) ) {
73
  $template_name = sanitize_text_field($template_info['template_name']);
74
- $res = \Cleantalk\Common\API::methodServicesTemplatesAdd(
75
  $this->api_key,
76
  $template_name,
77
  $this->getPluginOptions()
@@ -125,7 +125,7 @@ class CleantalkSettingsTemplates
125
  public static function getOptionsTemplate($api_key)
126
  {
127
  if ( ! self::$templates ) {
128
- $res = \Cleantalk\Common\API::methodServicesTemplatesGet($api_key);
129
  if ( is_array($res) ) {
130
  if ( array_key_exists('error', $res) ) {
131
  $templates = array();
54
  $template_info = Post::get('data');
55
  if ( isset($template_info['template_id']) ) {
56
  $template_id = sanitize_text_field($template_info['template_id']);
57
+ $res = \Cleantalk\ApbctWP\API::methodServicesTemplatesUpdate(
58
  $this->api_key,
59
  (int)$template_id,
60
  $this->getPluginOptions()
71
  }
72
  if ( isset($template_info['template_name']) ) {
73
  $template_name = sanitize_text_field($template_info['template_name']);
74
+ $res = \Cleantalk\ApbctWP\API::methodServicesTemplatesAdd(
75
  $this->api_key,
76
  $template_name,
77
  $this->getPluginOptions()
125
  public static function getOptionsTemplate($api_key)
126
  {
127
  if ( ! self::$templates ) {
128
+ $res = \Cleantalk\ApbctWP\API::methodServicesTemplatesGet($api_key);
129
  if ( is_array($res) ) {
130
  if ( array_key_exists('error', $res) ) {
131
  $templates = array();
lib/Cleantalk/ApbctWP/FindSpam/ListTable/Comments.php CHANGED
@@ -334,6 +334,20 @@ class Comments extends \Cleantalk\ApbctWP\CleantalkListTable
334
  return new \WP_Comment_Query($params_spam);
335
  }
336
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
  /**
338
  * Without IP and EMAIL
339
  *
334
  return new \WP_Comment_Query($params_spam);
335
  }
336
 
337
+ /**
338
+ * Spam comments
339
+ *
340
+ * @return \WP_Comment_Query
341
+ */
342
+ public function getScannedTotal()
343
+ {
344
+ $params_spam = array(
345
+ 'meta_key' => 'ct_marked_as_spam',
346
+ );
347
+
348
+ return new \WP_Comment_Query($params_spam);
349
+ }
350
+
351
  /**
352
  * Without IP and EMAIL
353
  *
lib/Cleantalk/ApbctWP/FindSpam/ListTable/CommentsScan.php CHANGED
@@ -20,7 +20,7 @@ class CommentsScan extends Comments
20
  $scanned_comments = $this->getSpamNow($per_page, $current_page);
21
 
22
  $this->set_pagination_args(array(
23
- 'total_items' => $this->getTotal(),
24
  'per_page' => $per_page,
25
  ));
26
 
20
  $scanned_comments = $this->getSpamNow($per_page, $current_page);
21
 
22
  $this->set_pagination_args(array(
23
+ 'total_items' => count($this->getScannedTotal()->get_comments()),
24
  'per_page' => $per_page,
25
  ));
26
 
lib/Cleantalk/ApbctWP/Firewall/AntiCrawler.php CHANGED
@@ -498,7 +498,6 @@ class AntiCrawler extends \Cleantalk\Common\Firewall\FirewallModule
498
  '_rest_nonce' => wp_create_nonce('wp_rest'),
499
  '_ajax_url' => admin_url('admin-ajax.php', 'relative'),
500
  '_rest_url' => esc_url(get_rest_url()),
501
- '_apbct_ajax_url' => APBCT_URL_PATH . '/lib/Cleantalk/ApbctWP/Ajax.php',
502
  'data__cookies_type' => $apbct->data['cookies_type'],
503
  'data__ajax_type' => $apbct->data['ajax_type'],
504
  'sfw__random_get' => $apbct->settings['sfw__random_get'] === '1' ||
498
  '_rest_nonce' => wp_create_nonce('wp_rest'),
499
  '_ajax_url' => admin_url('admin-ajax.php', 'relative'),
500
  '_rest_url' => esc_url(get_rest_url()),
 
501
  'data__cookies_type' => $apbct->data['cookies_type'],
502
  'data__ajax_type' => $apbct->data['ajax_type'],
503
  'sfw__random_get' => $apbct->settings['sfw__random_get'] === '1' ||
lib/Cleantalk/ApbctWP/Firewall/AntiFlood.php CHANGED
@@ -260,7 +260,6 @@ class AntiFlood extends \Cleantalk\Common\Firewall\FirewallModule
260
  '_rest_nonce' => wp_create_nonce('wp_rest'),
261
  '_ajax_url' => admin_url('admin-ajax.php', 'relative'),
262
  '_rest_url' => esc_url(get_rest_url()),
263
- '_apbct_ajax_url' => APBCT_URL_PATH . '/lib/Cleantalk/ApbctWP/Ajax.php',
264
  'data__cookies_type' => $apbct->data['cookies_type'],
265
  'data__ajax_type' => $apbct->data['ajax_type'],
266
  'sfw__random_get' => $apbct->settings['sfw__random_get'] === '1' ||
260
  '_rest_nonce' => wp_create_nonce('wp_rest'),
261
  '_ajax_url' => admin_url('admin-ajax.php', 'relative'),
262
  '_rest_url' => esc_url(get_rest_url()),
 
263
  'data__cookies_type' => $apbct->data['cookies_type'],
264
  'data__ajax_type' => $apbct->data['ajax_type'],
265
  'sfw__random_get' => $apbct->settings['sfw__random_get'] === '1' ||
lib/Cleantalk/ApbctWP/Firewall/SFW.php CHANGED
@@ -408,7 +408,6 @@ class SFW extends \Cleantalk\Common\Firewall\FirewallModule
408
  '_rest_nonce' => wp_create_nonce('wp_rest'),
409
  '_ajax_url' => admin_url('admin-ajax.php', 'relative'),
410
  '_rest_url' => esc_url(get_rest_url()),
411
- '_apbct_ajax_url' => APBCT_URL_PATH . '/lib/Cleantalk/ApbctWP/Ajax.php',
412
  'data__cookies_type' => $apbct->data['cookies_type'],
413
  'data__ajax_type' => $apbct->data['ajax_type'],
414
  'sfw__random_get' => $apbct->settings['sfw__random_get'] === '1' ||
408
  '_rest_nonce' => wp_create_nonce('wp_rest'),
409
  '_ajax_url' => admin_url('admin-ajax.php', 'relative'),
410
  '_rest_url' => esc_url(get_rest_url()),
 
411
  'data__cookies_type' => $apbct->data['cookies_type'],
412
  'data__ajax_type' => $apbct->data['ajax_type'],
413
  'sfw__random_get' => $apbct->settings['sfw__random_get'] === '1' ||
lib/Cleantalk/ApbctWP/HTTP/Request.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Cleantalk\ApbctWP\HTTP;
4
+
5
+ use Cleantalk\Common\HTTP\Response;
6
+ use Requests;
7
+
8
+ class Request extends \Cleantalk\Common\HTTP\Request
9
+ {
10
+ public function request()
11
+ {
12
+ global $apbct;
13
+
14
+ // Make a request via builtin WordPress HTTP API
15
+ if ( $apbct->settings['wp__use_builtin_http_api'] ) {
16
+ $this->appendOptionsObligatory();
17
+ $this->processPresets();
18
+
19
+ // Call cURL multi request if many URLs passed
20
+ $this->response = is_array($this->url)
21
+ ? $this->requestMulti()
22
+ : $this->requestSingle();
23
+
24
+ return $this->runCallbacks();
25
+ }
26
+
27
+ return parent::request();
28
+ }
29
+
30
+ protected function requestSingle()
31
+ {
32
+ global $apbct;
33
+
34
+ if ( ! $apbct->settings['wp__use_builtin_http_api'] ) {
35
+ return parent::requestSingle();
36
+ }
37
+
38
+ $type = in_array('get', $this->presets, true) ? 'GET' : 'POST';
39
+
40
+ try {
41
+ $response = Requests::request(
42
+ $this->url,
43
+ $this->options[CURLOPT_HTTPHEADER],
44
+ $this->data,
45
+ $type,
46
+ $this->options
47
+ );
48
+ } catch ( \Requests_Exception $e ) {
49
+ return new Response(['error' => $e->getMessage()], []);
50
+ }
51
+
52
+ if ( $response instanceof \Requests_Response ) {
53
+ return new Response($response->body, ['http_code' => $response->status_code]);
54
+ }
55
+
56
+ // String passed
57
+ return new Response($response, []);
58
+ }
59
+
60
+ protected function requestMulti()
61
+ {
62
+ global $apbct;
63
+
64
+ if ( ! $apbct->settings['wp__use_builtin_http_api'] ) {
65
+ return parent::requestMulti();
66
+ }
67
+
68
+ $responses = [];
69
+ $requests = [];
70
+ $options = [];
71
+
72
+ // Prepare options
73
+ foreach ( $this->url as $url ) {
74
+ $requests[] = [
75
+ 'url' => $url,
76
+ 'headers' => $this->options[CURLOPT_HTTPHEADER],
77
+ 'data' => $this->data,
78
+ 'type' => $type = in_array('get', $this->presets, true) ? 'GET' : 'POST',
79
+ 'cookies' => [],
80
+ ];
81
+ $options[] = [
82
+
83
+ ];
84
+ }
85
+
86
+ $responses_raw = \Requests::request_multiple($requests, $options);
87
+
88
+ foreach ( $responses_raw as $response ) {
89
+ if ( $response instanceof \Requests_Exception ) {
90
+ /**
91
+ * @psalm-suppress UndefinedPropertyFetch
92
+ */
93
+ $responses[$response->url] = new Response(['error' => $response->getMessage()], []);
94
+ continue;
95
+ }
96
+ if ( $response instanceof \Requests_Response ) {
97
+ $responses[$response->url] = new Response($response->body, ['http_code' => $response->status_code]);
98
+ continue;
99
+ }
100
+
101
+ // String passed
102
+ $responses[$response->url] = new Response($response, []);
103
+ }
104
+
105
+ return $responses;
106
+ }
107
+
108
+ /**
109
+ * Append options considering passed presets
110
+ */
111
+ protected function processPresets()
112
+ {
113
+ parent::processPresets();
114
+
115
+ global $apbct;
116
+
117
+ if ( $apbct->settings['wp__use_builtin_http_api'] ) {
118
+ foreach ( $this->presets as $preset ) {
119
+ switch ( $preset ) {
120
+ // Do not follow redirects
121
+ case 'dont_follow_redirects':
122
+ $this->options['follow_redirects'] = false;
123
+ $this->options['redirects'] = 0;
124
+ break;
125
+
126
+ // Make a request, don't wait for an answer
127
+ case 'async':
128
+ $this->options['timeout'] = 3;
129
+ $this->options['connect_timeout'] = 3;
130
+ $this->options['blocking'] = false;
131
+ break;
132
+
133
+ case 'ssl':
134
+ $this->options['verifyname'] = true;
135
+ if ( defined('CLEANTALK_CASERT_PATH') && CLEANTALK_CASERT_PATH ) {
136
+ $this->options['verify'] = CLEANTALK_CASERT_PATH;
137
+ }
138
+ break;
139
+
140
+ // Get headers only
141
+ case 'get_code':
142
+ $this->options['header'] = true;
143
+ $this->options['nobody'] = true;
144
+ break;
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
lib/Cleantalk/ApbctWP/Helper.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace Cleantalk\ApbctWP;
4
 
 
 
5
  /**
6
  * CleanTalk Anti-Spam Helper class.
7
  * Compatible only with WordPress.
@@ -27,7 +29,7 @@ class Helper extends \Cleantalk\Common\Helper
27
  * get - GET-request
28
  * ssl - use SSL
29
  *
30
- * @param string $url URL
31
  * @param array|string|int $data POST|GET indexed array with data to send
32
  * @param string|array $presets String or Array with presets: get_code, async, get, ssl, dont_split_to_array
33
  * @param array $opts Optional option for CURL connection
@@ -46,7 +48,13 @@ class Helper extends \Cleantalk\Common\Helper
46
  $opts
47
  );
48
 
49
- return parent::httpRequest($url, $data, $presets, $opts);
 
 
 
 
 
 
50
  }
51
 
52
  /**
@@ -59,7 +67,7 @@ class Helper extends \Cleantalk\Common\Helper
59
  */
60
  public static function httpRequestGetResponseCode($url)
61
  {
62
- return static::httpRequest($url, array(), 'get_code');
63
  }
64
 
65
  /**
2
 
3
  namespace Cleantalk\ApbctWP;
4
 
5
+ use Cleantalk\ApbctWP\HTTP\Request;
6
+
7
  /**
8
  * CleanTalk Anti-Spam Helper class.
9
  * Compatible only with WordPress.
29
  * get - GET-request
30
  * ssl - use SSL
31
  *
32
+ * @param string|array<string> $url URL
33
  * @param array|string|int $data POST|GET indexed array with data to send
34
  * @param string|array $presets String or Array with presets: get_code, async, get, ssl, dont_split_to_array
35
  * @param array $opts Optional option for CURL connection
48
  $opts
49
  );
50
 
51
+ $http = new Request();
52
+
53
+ return $http->setUrl($url)
54
+ ->setData($data)
55
+ ->setPresets($presets)
56
+ ->setOptions($opts)
57
+ ->request();
58
  }
59
 
60
  /**
67
  */
68
  public static function httpRequestGetResponseCode($url)
69
  {
70
+ return static::httpRequest($url, array(), 'get_code get');
71
  }
72
 
73
  /**
lib/Cleantalk/ApbctWP/RestController.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace Cleantalk\ApbctWP;
4
 
 
 
5
  class RestController extends \WP_REST_Controller
6
  {
7
  public function __construct()
@@ -66,5 +68,22 @@ class RestController extends \WP_REST_Controller
66
  'permission_callback' => '__return_true',
67
  )
68
  ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
  }
2
 
3
  namespace Cleantalk\ApbctWP;
4
 
5
+ use WP_REST_Request;
6
+
7
  class RestController extends \WP_REST_Controller
8
  {
9
  public function __construct()
68
  'permission_callback' => '__return_true',
69
  )
70
  ));
71
+
72
+ // REST route for decoding email
73
+ register_rest_route($this->namespace, "/apbct_decode_email", array(
74
+ array(
75
+ 'methods' => 'POST',
76
+ 'callback' => array(\Cleantalk\Antispam\EmailEncoder::getInstance(), 'ajaxDecodeEmail'),
77
+ 'permission_callback' => function (WP_REST_Request $request) {
78
+ return wp_verify_nonce($request->get_header('x_wp_nonce'), 'wp_rest');
79
+ },
80
+ 'args' => array(
81
+ 'encodedEmail' => array(
82
+ 'type' => 'string',
83
+ 'required' => true,
84
+ ),
85
+ ),
86
+ )
87
+ ));
88
  }
89
  }
lib/Cleantalk/ApbctWP/State.php CHANGED
@@ -90,7 +90,8 @@ class State extends \Cleantalk\Common\State
90
  // Secure connection to servers
91
  'data__pixel' => '3',
92
  'data__email_check_before_post' => 1,
93
- 'data__honeypot_field' => 0,
 
94
 
95
  // Exclusions
96
  // Send to the cloud some excepted requests
90
  // Secure connection to servers
91
  'data__pixel' => '3',
92
  'data__email_check_before_post' => 1,
93
+ 'data__honeypot_field' => 1,
94
+ 'data__email_decoder' => 0,
95
 
96
  // Exclusions
97
  // Send to the cloud some excepted requests
lib/Cleantalk/Common/API.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace Cleantalk\Common;
4
 
 
 
5
  /**
6
  * CleanTalk API class.
7
  * Mostly contains wrappers for API methods. Check and send methods.
@@ -26,13 +28,12 @@ class API
26
  * @param string $api_key
27
  * @param null|string $out Data output type (JSON or file URL)
28
  * @param string $version API method version
29
- * @param boolean $do_check
30
  *
31
- * @return string|array ('error' => STRING)
32
  *
33
  * @psalm-suppress PossiblyUnusedMethod
34
  */
35
- public static function methodGet2sBlacklistsDb($api_key, $out = null, $version = '1_0', $do_check = true)
36
  {
37
  $request = array(
38
  'method_name' => '2s_blacklists_db',
@@ -41,10 +42,7 @@ class API
41
  'version' => $version,
42
  );
43
 
44
- $result = static::sendRequest($request);
45
- $result = $do_check ? static::checkResponse($result, '2s_blacklists_db') : $result;
46
-
47
- return $result;
48
  }
49
 
50
  /**
@@ -61,7 +59,6 @@ class API
61
  * @param bool $wpms
62
  * @param bool $white_label
63
  * @param string $hoster_api_key
64
- * @param bool $do_check
65
  *
66
  * @return array|bool|mixed
67
  */
@@ -76,8 +73,7 @@ class API
76
  $wpms = false,
77
  $white_label = false,
78
  $hoster_api_key = '',
79
- $email_filtered = false,
80
- $do_check = true
81
  ) {
82
  $request = array(
83
  'method_name' => 'get_api_key',
@@ -94,10 +90,7 @@ class API
94
  'email_filtered' => $email_filtered
95
  );
96
 
97
- $result = static::sendRequest($request);
98
- $result = $do_check ? static::checkResponse($result, 'get_api_key') : $result;
99
-
100
- return $result;
101
  }
102
 
103
  /**
@@ -106,13 +99,12 @@ class API
106
  *
107
  * @param string $host website host
108
  * @param integer $period report days
109
- * @param boolean $do_check
110
  *
111
  * @return array|bool|mixed
112
  *
113
  * @psalm-suppress PossiblyUnusedMethod
114
  */
115
- public static function methodGetAntispamReport($host, $period = 1, $do_check = true)
116
  {
117
  $request = array(
118
  'method_name' => 'get_antispam_report',
@@ -120,10 +112,7 @@ class API
120
  'period' => $period
121
  );
122
 
123
- $result = static::sendRequest($request);
124
- $result = $do_check ? static::checkResponse($result, 'get_antispam_report') : $result;
125
-
126
- return $result;
127
  }
128
 
129
  /**
@@ -131,23 +120,19 @@ class API
131
  * Ggets spam statistics.
132
  *
133
  * @param string $api_key
134
- * @param bool $do_check
135
  *
136
  * @return array|bool|mixed
137
  *
138
  * @psalm-suppress PossiblyUnusedMethod
139
  */
140
- public static function methodGetAntispamReportBreif($api_key, $do_check = true)
141
  {
142
  $request = array(
143
  'method_name' => 'get_antispam_report_breif',
144
  'auth_key' => $api_key,
145
  );
146
 
147
- $result = static::sendRequest($request);
148
- $result = $do_check ? static::checkResponse($result, 'get_antispam_report_breif') : $result;
149
-
150
- return $result;
151
  }
152
 
153
  /**
@@ -157,7 +142,6 @@ class API
157
  * @param string $api_key Access key
158
  * @param string $path_to_cms Website URL
159
  * @param string $product_name
160
- * @param bool $do_check
161
  *
162
  * @return array|bool|mixed
163
  *
@@ -166,8 +150,7 @@ class API
166
  public static function methodNoticePaidTill(
167
  $api_key,
168
  $path_to_cms,
169
- $product_name = 'antispam',
170
- $do_check = true
171
  ) {
172
  $request = array(
173
  'method_name' => 'notice_paid_till',
@@ -179,10 +162,7 @@ class API
179
  $request['product_id'] = self::getProductId($product_name);
180
  }
181
 
182
- $result = static::sendRequest($request);
183
- $result = $do_check ? static::checkResponse($result, 'notice_paid_till') : $result;
184
-
185
- return $result;
186
  }
187
 
188
  /**
@@ -190,23 +170,19 @@ class API
190
  * Gets IP country.
191
  *
192
  * @param string $data
193
- * @param bool $do_check
194
  *
195
  * @return array|bool|mixed
196
  *
197
  * @psalm-suppress PossiblyUnusedMethod
198
  */
199
- public static function methodIpInfo($data, $do_check = true)
200
  {
201
  $request = array(
202
  'method_name' => 'ip_info',
203
  'data' => $data
204
  );
205
 
206
- $result = static::sendRequest($request);
207
- $result = $do_check ? static::checkResponse($result, 'ip_info') : $result;
208
-
209
- return $result;
210
  }
211
 
212
  /**
@@ -216,13 +192,12 @@ class API
216
  * @param string $api_key
217
  * @param array $data
218
  * @param null|string $date
219
- * @param bool $do_check
220
  *
221
  * @return array|bool|mixed
222
  *
223
  * @psalm-suppress PossiblyUnusedMethod
224
  */
225
- public static function methodSpamCheckCms($api_key, $data, $date = null, $do_check = true)
226
  {
227
  $request = array(
228
  'method_name' => 'spam_check_cms',
@@ -234,10 +209,7 @@ class API
234
  $request['date'] = $date;
235
  }
236
 
237
- $result = static::sendRequest($request, self::URL, 20);
238
- $result = $do_check ? static::checkResponse($result, 'spam_check_cms') : $result;
239
-
240
- return $result;
241
  }
242
 
243
  /**
@@ -247,13 +219,12 @@ class API
247
  * @param string $api_key Access key
248
  * @param string $path_to_cms Website URL
249
  * @param string $product_name
250
- * @param bool $do_check
251
  *
252
  * @return array|bool|mixed
253
  *
254
  * @psalm-suppress PossiblyUnusedMethod
255
  */
256
- public static function methodEmailCheck($email, $cache_only = true, $do_check = true)
257
  {
258
  $request = array(
259
  'method_name' => 'email_check',
@@ -261,10 +232,7 @@ class API
261
  'email' => $email,
262
  );
263
 
264
- $result = static::sendRequest($request);
265
- $result = $do_check ? static::checkResponse($result, 'email_check') : $result;
266
-
267
- return $result;
268
  }
269
 
270
  /**
@@ -274,13 +242,12 @@ class API
274
  * @param string $api_key
275
  * @param array $data
276
  * @param null|string $date
277
- * @param bool $do_check
278
  *
279
  * @return array|bool|mixed
280
  *
281
  * @psalm-suppress PossiblyUnusedMethod
282
  */
283
- public static function methodSpamCheck($api_key, $data, $date = null, $do_check = true)
284
  {
285
  $request = array(
286
  'method_name' => 'spam_check',
@@ -292,10 +259,7 @@ class API
292
  $request['date'] = $date;
293
  }
294
 
295
- $result = static::sendRequest($request, self::URL, 10);
296
- $result = $do_check ? static::checkResponse($result, 'spam_check') : $result;
297
-
298
- return $result;
299
  }
300
 
301
  /**
@@ -304,13 +268,12 @@ class API
304
  *
305
  * @param string $api_key
306
  * @param array $data
307
- * @param bool $do_check
308
  *
309
  * @return array|bool
310
  *
311
  * @psalm-suppress PossiblyUnusedMethod
312
  */
313
- public static function methodSfwLogs($api_key, $data, $do_check = true)
314
  {
315
  $request = array(
316
  'auth_key' => $api_key,
@@ -322,10 +285,7 @@ class API
322
 
323
  $request['data'] = str_replace('"EMPTY_ASSOCIATIVE_ARRAY"', '{}', $request['data']);
324
 
325
- $result = static::sendRequest($request);
326
- $result = $do_check ? static::checkResponse($result, 'sfw_logs') : $result;
327
-
328
- return $result;
329
  }
330
 
331
  /**
@@ -334,13 +294,12 @@ class API
334
  *
335
  * @param string $api_key
336
  * @param array $data
337
- * @param bool $do_check
338
  *
339
  * @return array|bool|mixed
340
  *
341
  * @psalm-suppress PossiblyUnusedMethod
342
  */
343
- public static function methodSecurityLogs($api_key, $data, $do_check = true)
344
  {
345
  $request = array(
346
  'auth_key' => $api_key,
@@ -350,10 +309,7 @@ class API
350
  'rows' => count($data),
351
  );
352
 
353
- $result = static::sendRequest($request);
354
- $result = $do_check ? static::checkResponse($result, 'security_logs') : $result;
355
-
356
- return $result;
357
  }
358
 
359
  /**
@@ -362,13 +318,12 @@ class API
362
  *
363
  * @param string $api_key
364
  * @param array $data
365
- * @param bool $do_check
366
  *
367
  * @return array|bool|mixed
368
  *
369
  * @psalm-suppress PossiblyUnusedMethod
370
  */
371
- public static function methodSecurityLogsSendFWData($api_key, $data, $do_check = true)
372
  {
373
  $request = array(
374
  'auth_key' => $api_key,
@@ -378,10 +333,7 @@ class API
378
  'rows_fw' => count($data),
379
  );
380
 
381
- $result = static::sendRequest($request);
382
- $result = $do_check ? static::checkResponse($result, 'security_logs') : $result;
383
-
384
- return $result;
385
  }
386
 
387
  /**
@@ -389,13 +341,12 @@ class API
389
  * Sends empty data to the cloud to syncronize version.
390
  *
391
  * @param string $api_key
392
- * @param bool $do_check
393
  *
394
  * @return array|bool|mixed
395
  *
396
  * @psalm-suppress PossiblyUnusedMethod
397
  */
398
- public static function methodSecurityLogsFeedback($api_key, $do_check = true)
399
  {
400
  $request = array(
401
  'auth_key' => $api_key,
@@ -403,10 +354,7 @@ class API
403
  'data' => '0',
404
  );
405
 
406
- $result = static::sendRequest($request);
407
- $result = $do_check ? static::checkResponse($result, 'security_logs') : $result;
408
-
409
- return $result;
410
  }
411
 
412
  /**
@@ -414,23 +362,19 @@ class API
414
  * Gets Securitty Firewall data to write to the local database.
415
  *
416
  * @param string $api_key
417
- * @param bool $do_check
418
  *
419
  * @return array|bool|mixed
420
  *
421
  * @psalm-suppress PossiblyUnusedMethod
422
  */
423
- public static function methodSecurityFirewallData($api_key, $do_check = true)
424
  {
425
  $request = array(
426
  'auth_key' => $api_key,
427
  'method_name' => 'security_firewall_data',
428
  );
429
 
430
- $result = static::sendRequest($request);
431
- $result = $do_check ? static::checkResponse($result, 'security_firewall_data') : $result;
432
-
433
- return $result;
434
  }
435
 
436
  /**
@@ -438,23 +382,19 @@ class API
438
  * Gets URI with security firewall data in .csv.gz file to write to the local database.
439
  *
440
  * @param string $api_key
441
- * @param bool $do_check
442
  *
443
  * @return array|bool|mixed
444
  *
445
  * @psalm-suppress PossiblyUnusedMethod
446
  */
447
- public static function methodSecurityFirewallDataFile($api_key, $do_check = true)
448
  {
449
  $request = array(
450
  'auth_key' => $api_key,
451
  'method_name' => 'security_firewall_data_file',
452
  );
453
 
454
- $result = static::sendRequest($request);
455
- $result = $do_check ? static::checkResponse($result, 'security_firewall_data_file') : $result;
456
-
457
- return $result;
458
  }
459
 
460
  /**
@@ -466,7 +406,6 @@ class API
466
  * @param bool $scan_result
467
  * @param int $links_total
468
  * @param array $links_list
469
- * @param bool $do_check
470
  *
471
  * @return array|bool|mixed
472
  *
@@ -477,8 +416,7 @@ class API
477
  $scan_time,
478
  $scan_result,
479
  $links_total,
480
- $links_list,
481
- $do_check = true
482
  ) {
483
  $request = array(
484
  'auth_key' => $api_key,
@@ -489,10 +427,7 @@ class API
489
  'links_list' => $links_list,
490
  );
491
 
492
- $result = static::sendRequest($request);
493
- $result = $do_check ? static::checkResponse($result, 'security_linksscan_logs') : $result;
494
-
495
- return $result;
496
  }
497
 
498
  /**
@@ -506,7 +441,6 @@ class API
506
  * @param int $scanned_total
507
  * @param array $modified List of modified files with details
508
  * @param array $unknown List of modified files with details
509
- * @param bool $do_check
510
  *
511
  * @return array|bool|mixed
512
  *
@@ -519,8 +453,7 @@ class API
519
  $scan_result,
520
  $scanned_total,
521
  $modified,
522
- $unknown,
523
- $do_check = true
524
  ) {
525
  $request = array(
526
  'method_name' => 'security_mscan_logs',
@@ -540,10 +473,7 @@ class API
540
  $request['unknown_files_rows'] = count($unknown);
541
  }
542
 
543
- $result = static::sendRequest($request);
544
- $result = $do_check ? static::checkResponse($result, 'security_mscan_logs') : $result;
545
-
546
- return $result;
547
  }
548
 
549
  /**
@@ -555,7 +485,6 @@ class API
555
  * @param array $file File itself
556
  * @param string $file_md5 MD5 hash of file
557
  * @param array $weak_spots List of weak spots found in file
558
- * @param bool $do_check
559
  *
560
  * @return array|bool|mixed
561
  *
@@ -566,8 +495,7 @@ class API
566
  $file_path,
567
  $file,
568
  $file_md5,
569
- $weak_spots,
570
- $do_check = true
571
  ) {
572
  $request = array(
573
  'method_name' => 'security_mscan_files',
@@ -578,10 +506,7 @@ class API
578
  'dangerous_code' => $weak_spots,
579
  );
580
 
581
- $result = static::sendRequest($request);
582
- $result = $do_check ? static::checkResponse($result, 'security_mscan_files') : $result;
583
-
584
- return $result;
585
  }
586
 
587
  /**
@@ -591,13 +516,12 @@ class API
591
  * @param string $api_key
592
  * @param array|string|mixed $data
593
  * @param string $date
594
- * @param bool $do_check
595
  *
596
  * @return array|bool|mixed
597
  *
598
  * @psalm-suppress PossiblyUnusedMethod
599
  */
600
- public static function methodBacklinksCheckCms($api_key, $data, $date = null, $do_check = true)
601
  {
602
  $request = array(
603
  'method_name' => 'backlinks_check_cms',
@@ -609,10 +533,7 @@ class API
609
  $request['date'] = $date;
610
  }
611
 
612
- $result = static::sendRequest($request);
613
- $result = $do_check ? static::checkResponse($result, 'backlinks_check_cms') : $result;
614
-
615
- return $result;
616
  }
617
 
618
  /**
@@ -621,13 +542,12 @@ class API
621
  *
622
  * @param string $api_key
623
  * @param array $logs
624
- * @param bool $do_check
625
  *
626
  * @return array|bool|mixed
627
  *
628
  * @psalm-suppress PossiblyUnusedMethod
629
  */
630
- public static function methodSecurityBackendLogs($api_key, $logs, $do_check = true)
631
  {
632
  $request = array(
633
  'method_name' => 'security_backend_logs',
@@ -636,10 +556,7 @@ class API
636
  'total_logs' => count($logs),
637
  );
638
 
639
- $result = static::sendRequest($request);
640
- $result = $do_check ? static::checkResponse($result, 'security_backend_logs') : $result;
641
-
642
- return $result;
643
  }
644
 
645
  /**
@@ -652,7 +569,6 @@ class API
652
  * @param $repaired_processed_files
653
  * @param $repaired_total_files_proccessed
654
  * @param $backup_id
655
- * @param bool $do_check
656
  *
657
  * @return array|bool|mixed
658
  *
@@ -664,8 +580,7 @@ class API
664
  $repair_comment,
665
  $repaired_processed_files,
666
  $repaired_total_files_proccessed,
667
- $backup_id,
668
- $do_check = true
669
  ) {
670
  $request = array(
671
  'method_name' => 'security_mscan_repairs',
@@ -678,10 +593,7 @@ class API
678
  'mscan_log_id' => 1,
679
  );
680
 
681
- $result = static::sendRequest($request);
682
- $result = $do_check ? static::checkResponse($result, 'security_mscan_repairs') : $result;
683
-
684
- return $result;
685
  }
686
 
687
  /**
@@ -690,13 +602,12 @@ class API
690
  *
691
  * @param string $api_key
692
  * @param string $plugins_and_themes_to_refresh
693
- * @param bool $do_check
694
  *
695
  * @return array|bool|mixed
696
  *
697
  * @psalm-suppress PossiblyUnusedMethod
698
  */
699
- public static function methodRequestChecksums($api_key, $plugins_and_themes_to_refresh, $do_check = true)
700
  {
701
  $request = array(
702
  'method_name' => 'request_checksums',
@@ -704,23 +615,19 @@ class API
704
  'data' => $plugins_and_themes_to_refresh
705
  );
706
 
707
- $result = static::sendRequest($request);
708
- $result = $do_check ? static::checkResponse($result, 'request_checksums') : $result;
709
-
710
- return $result;
711
  }
712
 
713
  /**
714
  * Settings templates get API method wrapper
715
  *
716
  * @param string $api_key
717
- * @param bool $do_check
718
  *
719
  * @return array|bool|mixed
720
  *
721
  * @psalm-suppress PossiblyUnusedMethod
722
  */
723
- public static function methodServicesTemplatesGet($api_key, $product_name = 'antispam', $do_check = true)
724
  {
725
  $request = array(
726
  'method_name' => 'services_templates_get',
@@ -728,10 +635,7 @@ class API
728
  'search[product_id]' => self::getProductId($product_name),
729
  );
730
 
731
- $result = static::sendRequest($request);
732
- $result = $do_check ? static::checkResponse($result, 'services_templates_get') : $result;
733
-
734
- return $result;
735
  }
736
 
737
  /**
@@ -739,7 +643,6 @@ class API
739
  *
740
  * @param string $api_key
741
  * @param null|string $template_name
742
- * @param bool $do_check
743
  *
744
  * @return array|bool|mixed
745
  *
@@ -749,8 +652,7 @@ class API
749
  $api_key,
750
  $template_name = null,
751
  $options = '',
752
- $product_name = 'antispam',
753
- $do_check = true
754
  ) {
755
  $request = array(
756
  'method_name' => 'services_templates_add',
@@ -760,10 +662,7 @@ class API
760
  'search[product_id]' => self::getProductId($product_name),
761
  );
762
 
763
- $result = static::sendRequest($request);
764
- $result = $do_check ? static::checkResponse($result, 'services_templates_add') : $result;
765
-
766
- return $result;
767
  }
768
 
769
  /**
@@ -773,7 +672,6 @@ class API
773
  * @param int $template_id
774
  * @param string $options
775
  * @param string $product_name
776
- * @param bool $do_check
777
  *
778
  * @return array|bool|mixed
779
  *
@@ -783,8 +681,7 @@ class API
783
  $api_key,
784
  $template_id,
785
  $options = '',
786
- $product_name = 'antispam',
787
- $do_check = true
788
  ) {
789
  $request = array(
790
  'method_name' => 'services_templates_update',
@@ -795,10 +692,7 @@ class API
795
  'search[product_id]' => self::getProductId($product_name),
796
  );
797
 
798
- $result = static::sendRequest($request);
799
- $result = $do_check ? static::checkResponse($result, 'services_templates_update') : $result;
800
-
801
- return $result;
802
  }
803
 
804
  /**
@@ -813,7 +707,6 @@ class API
813
  * @param string $note Description text
814
  * @param string $status allow|deny
815
  * @param string $expired Date Y-m-d H:i:s
816
- * @param bool $do_check
817
  *
818
  * @return array|bool|bool[]|mixed|string[]
819
  *
@@ -828,8 +721,7 @@ class API
828
  $record_type,
829
  $note,
830
  $status,
831
- $expired,
832
- $do_check = true
833
  ) {
834
  $request = array(
835
  'method_name' => 'private_list_add',
@@ -844,10 +736,7 @@ class API
844
  'expired' => $expired,
845
  );
846
 
847
- $result = static::sendRequest($request);
848
- $result = $do_check ? static::checkResponse($result, 'private_list_add') : $result;
849
-
850
- return $result;
851
  }
852
 
853
  /**
@@ -895,107 +784,40 @@ class API
895
  * @param boolean $ssl use ssl on not
896
  * @param string $ssl_path
897
  *
898
- * @return array|string
899
  */
900
  public static function sendRequest($data, $_url = self::URL, $timeout = 10, $ssl = false, $ssl_path = '')
901
  {
902
- global $apbct_debug;
903
-
904
  // Possibility to switch agent version
905
  $data['agent'] = ! empty($data['agent'])
906
  ? $data['agent']
907
  : (defined('CLEANTALK_AGENT') ? CLEANTALK_AGENT : self::AGENT);
908
 
909
- // Make URL string
910
- $data_string = http_build_query($data);
911
- $data_string = str_replace("&amp;", "&", $data_string);
912
-
913
- // For debug purposes
914
- if (defined('CLEANTALK_DEBUG') && CLEANTALK_DEBUG) {
915
- $apbct_debug['sent_data'] = $data;
916
- $apbct_debug['request_string'] = $data_string;
917
- }
918
-
919
  // Possibility to switch API url
920
  $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $_url;
921
 
922
- if (function_exists('curl_init')) {
923
- $ch = curl_init();
924
-
925
- // Set diff options
926
- curl_setopt($ch, CURLOPT_URL, $url);
927
- curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
928
- curl_setopt($ch, CURLOPT_POST, true);
929
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
930
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
931
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
932
-
933
- $ssl_path = $ssl_path ?: (defined('CLEANTALK_CASERT_PATH') ? CLEANTALK_CASERT_PATH : '');
934
-
935
- // Switch on/off SSL
936
- if ($ssl && $ssl_path) {
937
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
938
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
939
- curl_setopt($ch, CURLOPT_CAINFO, $ssl_path);
940
- } else {
941
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
942
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
943
- }
944
-
945
- // Make an asynchronous request, don't wait for an answer
946
- if ( $timeout == 0 ) {
947
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 2000);
948
- curl_setopt($ch, CURLOPT_TIMEOUT_MS, 2000);
949
- }
950
-
951
- // Make a request
952
- $result = curl_exec($ch);
953
- $errors = curl_error($ch);
954
- curl_close($ch);
955
-
956
- // RETURN if async request
957
- if ( $timeout == 0 ) {
958
- return array('data' => 'Async request was sent.');
959
- }
960
- } else {
961
- $errors = 'CURL_NOT_INSTALLED';
962
- }
963
 
964
- // Trying to use file_get_contents() to make a API call
965
- if ( ! empty($errors)) {
966
- if (ini_get('allow_url_fopen')) {
967
- $opts = array(
968
- 'http' => array(
969
- 'method' => "POST",
970
- 'timeout' => $timeout,
971
- 'content' => $data_string,
972
- ),
973
- );
974
- $context = stream_context_create($opts);
975
- $result = @file_get_contents($url, false, $context);
976
-
977
- $errors = $result === false
978
- ? $errors . '_FAILED_TO_USE_FILE_GET_CONTENTS'
979
- : false;
980
- } else {
981
- $errors .= '_AND_ALLOW_URL_FOPEN_IS_DISABLED';
982
- }
983
- }
984
-
985
- return empty($result) || ! empty($errors)
986
- ? array('error' => $errors)
987
- : $result;
988
  }
989
 
990
  /**
991
  * Function checks server response
992
  *
993
  * @param array|string $result
 
994
  * @param string $method_name
995
  *
996
  * @return mixed (array || array('error' => true))
997
  */
998
- public static function checkResponse($result, $method_name = null)
999
  {
1000
  // Errors handling
1001
  // Bad connection
2
 
3
  namespace Cleantalk\Common;
4
 
5
+ use Cleantalk\Common\HTTP\Request;
6
+
7
  /**
8
  * CleanTalk API class.
9
  * Mostly contains wrappers for API methods. Check and send methods.
28
  * @param string $api_key
29
  * @param null|string $out Data output type (JSON or file URL)
30
  * @param string $version API method version
 
31
  *
32
+ * @return array|bool|mixed
33
  *
34
  * @psalm-suppress PossiblyUnusedMethod
35
  */
36
+ public static function methodGet2sBlacklistsDb($api_key, $out = null, $version = '1_0')
37
  {
38
  $request = array(
39
  'method_name' => '2s_blacklists_db',
42
  'version' => $version,
43
  );
44
 
45
+ return static::sendRequest($request);
 
 
 
46
  }
47
 
48
  /**
59
  * @param bool $wpms
60
  * @param bool $white_label
61
  * @param string $hoster_api_key
 
62
  *
63
  * @return array|bool|mixed
64
  */
73
  $wpms = false,
74
  $white_label = false,
75
  $hoster_api_key = '',
76
+ $email_filtered = false
 
77
  ) {
78
  $request = array(
79
  'method_name' => 'get_api_key',
90
  'email_filtered' => $email_filtered
91
  );
92
 
93
+ return static::sendRequest($request);
 
 
 
94
  }
95
 
96
  /**
99
  *
100
  * @param string $host website host
101
  * @param integer $period report days
 
102
  *
103
  * @return array|bool|mixed
104
  *
105
  * @psalm-suppress PossiblyUnusedMethod
106
  */
107
+ public static function methodGetAntispamReport($host, $period = 1)
108
  {
109
  $request = array(
110
  'method_name' => 'get_antispam_report',
112
  'period' => $period
113
  );
114
 
115
+ return static::sendRequest($request);
 
 
 
116
  }
117
 
118
  /**
120
  * Ggets spam statistics.
121
  *
122
  * @param string $api_key
 
123
  *
124
  * @return array|bool|mixed
125
  *
126
  * @psalm-suppress PossiblyUnusedMethod
127
  */
128
+ public static function methodGetAntispamReportBreif($api_key)
129
  {
130
  $request = array(
131
  'method_name' => 'get_antispam_report_breif',
132
  'auth_key' => $api_key,
133
  );
134
 
135
+ return static::sendRequest($request);
 
 
 
136
  }
137
 
138
  /**
142
  * @param string $api_key Access key
143
  * @param string $path_to_cms Website URL
144
  * @param string $product_name
 
145
  *
146
  * @return array|bool|mixed
147
  *
150
  public static function methodNoticePaidTill(
151
  $api_key,
152
  $path_to_cms,
153
+ $product_name = 'antispam'
 
154
  ) {
155
  $request = array(
156
  'method_name' => 'notice_paid_till',
162
  $request['product_id'] = self::getProductId($product_name);
163
  }
164
 
165
+ return static::sendRequest($request);
 
 
 
166
  }
167
 
168
  /**
170
  * Gets IP country.
171
  *
172
  * @param string $data
 
173
  *
174
  * @return array|bool|mixed
175
  *
176
  * @psalm-suppress PossiblyUnusedMethod
177
  */
178
+ public static function methodIpInfo($data)
179
  {
180
  $request = array(
181
  'method_name' => 'ip_info',
182
  'data' => $data
183
  );
184
 
185
+ return static::sendRequest($request);
 
 
 
186
  }
187
 
188
  /**
192
  * @param string $api_key
193
  * @param array $data
194
  * @param null|string $date
 
195
  *
196
  * @return array|bool|mixed
197
  *
198
  * @psalm-suppress PossiblyUnusedMethod
199
  */
200
+ public static function methodSpamCheckCms($api_key, $data, $date = null)
201
  {
202
  $request = array(
203
  'method_name' => 'spam_check_cms',
209
  $request['date'] = $date;
210
  }
211
 
212
+ return static::sendRequest($request, self::URL, 20);
 
 
 
213
  }
214
 
215
  /**
219
  * @param string $api_key Access key
220
  * @param string $path_to_cms Website URL
221
  * @param string $product_name
 
222
  *
223
  * @return array|bool|mixed
224
  *
225
  * @psalm-suppress PossiblyUnusedMethod
226
  */
227
+ public static function methodEmailCheck($email, $cache_only = true)
228
  {
229
  $request = array(
230
  'method_name' => 'email_check',
232
  'email' => $email,
233
  );
234
 
235
+ return static::sendRequest($request);
 
 
 
236
  }
237
 
238
  /**
242
  * @param string $api_key
243
  * @param array $data
244
  * @param null|string $date
 
245
  *
246
  * @return array|bool|mixed
247
  *
248
  * @psalm-suppress PossiblyUnusedMethod
249
  */
250
+ public static function methodSpamCheck($api_key, $data, $date = null)
251
  {
252
  $request = array(
253
  'method_name' => 'spam_check',
259
  $request['date'] = $date;
260
  }
261
 
262
+ return static::sendRequest($request);
 
 
 
263
  }
264
 
265
  /**
268
  *
269
  * @param string $api_key
270
  * @param array $data
 
271
  *
272
  * @return array|bool
273
  *
274
  * @psalm-suppress PossiblyUnusedMethod
275
  */
276
+ public static function methodSfwLogs($api_key, $data)
277
  {
278
  $request = array(
279
  'auth_key' => $api_key,
285
 
286
  $request['data'] = str_replace('"EMPTY_ASSOCIATIVE_ARRAY"', '{}', $request['data']);
287
 
288
+ return static::sendRequest($request);
 
 
 
289
  }
290
 
291
  /**
294
  *
295
  * @param string $api_key
296
  * @param array $data
 
297
  *
298
  * @return array|bool|mixed
299
  *
300
  * @psalm-suppress PossiblyUnusedMethod
301
  */
302
+ public static function methodSecurityLogs($api_key, $data)
303
  {
304
  $request = array(
305
  'auth_key' => $api_key,
309
  'rows' => count($data),
310
  );
311
 
312
+ return static::sendRequest($request);
 
 
 
313
  }
314
 
315
  /**
318
  *
319
  * @param string $api_key
320
  * @param array $data
 
321
  *
322
  * @return array|bool|mixed
323
  *
324
  * @psalm-suppress PossiblyUnusedMethod
325
  */
326
+ public static function methodSecurityLogsSendFWData($api_key, $data)
327
  {
328
  $request = array(
329
  'auth_key' => $api_key,
333
  'rows_fw' => count($data),
334
  );
335
 
336
+ return static::sendRequest($request);
 
 
 
337
  }
338
 
339
  /**
341
  * Sends empty data to the cloud to syncronize version.
342
  *
343
  * @param string $api_key
 
344
  *
345
  * @return array|bool|mixed
346
  *
347
  * @psalm-suppress PossiblyUnusedMethod
348
  */
349
+ public static function methodSecurityLogsFeedback($api_key)
350
  {
351
  $request = array(
352
  'auth_key' => $api_key,
354
  'data' => '0',
355
  );
356
 
357
+ return static::sendRequest($request);
 
 
 
358
  }
359
 
360
  /**
362
  * Gets Securitty Firewall data to write to the local database.
363
  *
364
  * @param string $api_key
 
365
  *
366
  * @return array|bool|mixed
367
  *
368
  * @psalm-suppress PossiblyUnusedMethod
369
  */
370
+ public static function methodSecurityFirewallData($api_key)
371
  {
372
  $request = array(
373
  'auth_key' => $api_key,
374
  'method_name' => 'security_firewall_data',
375
  );
376
 
377
+ return static::sendRequest($request);
 
 
 
378
  }
379
 
380
  /**
382
  * Gets URI with security firewall data in .csv.gz file to write to the local database.
383
  *
384
  * @param string $api_key
 
385
  *
386
  * @return array|bool|mixed
387
  *
388
  * @psalm-suppress PossiblyUnusedMethod
389
  */
390
+ public static function methodSecurityFirewallDataFile($api_key)
391
  {
392
  $request = array(
393
  'auth_key' => $api_key,
394
  'method_name' => 'security_firewall_data_file',
395
  );
396
 
397
+ return static::sendRequest($request);
 
 
 
398
  }
399
 
400
  /**
406
  * @param bool $scan_result
407
  * @param int $links_total
408
  * @param array $links_list
 
409
  *
410
  * @return array|bool|mixed
411
  *
416
  $scan_time,
417
  $scan_result,
418
  $links_total,
419
+ $links_list
 
420
  ) {
421
  $request = array(
422
  'auth_key' => $api_key,
427
  'links_list' => $links_list,
428
  );
429
 
430
+ return static::sendRequest($request);
 
 
 
431
  }
432
 
433
  /**
441
  * @param int $scanned_total
442
  * @param array $modified List of modified files with details
443
  * @param array $unknown List of modified files with details
 
444
  *
445
  * @return array|bool|mixed
446
  *
453
  $scan_result,
454
  $scanned_total,
455
  $modified,
456
+ $unknown
 
457
  ) {
458
  $request = array(
459
  'method_name' => 'security_mscan_logs',
473
  $request['unknown_files_rows'] = count($unknown);
474
  }
475
 
476
+ return static::sendRequest($request);
 
 
 
477
  }
478
 
479
  /**
485
  * @param array $file File itself
486
  * @param string $file_md5 MD5 hash of file
487
  * @param array $weak_spots List of weak spots found in file
 
488
  *
489
  * @return array|bool|mixed
490
  *
495
  $file_path,
496
  $file,
497
  $file_md5,
498
+ $weak_spots
 
499
  ) {
500
  $request = array(
501
  'method_name' => 'security_mscan_files',
506
  'dangerous_code' => $weak_spots,
507
  );
508
 
509
+ return static::sendRequest($request);
 
 
 
510
  }
511
 
512
  /**
516
  * @param string $api_key
517
  * @param array|string|mixed $data
518
  * @param string $date
 
519
  *
520
  * @return array|bool|mixed
521
  *
522
  * @psalm-suppress PossiblyUnusedMethod
523
  */
524
+ public static function methodBacklinksCheckCms($api_key, $data, $date = null)
525
  {
526
  $request = array(
527
  'method_name' => 'backlinks_check_cms',
533
  $request['date'] = $date;
534
  }
535
 
536
+ return static::sendRequest($request);
 
 
 
537
  }
538
 
539
  /**
542
  *
543
  * @param string $api_key
544
  * @param array $logs
 
545
  *
546
  * @return array|bool|mixed
547
  *
548
  * @psalm-suppress PossiblyUnusedMethod
549
  */
550
+ public static function methodSecurityBackendLogs($api_key, $logs)
551
  {
552
  $request = array(
553
  'method_name' => 'security_backend_logs',
556
  'total_logs' => count($logs),
557
  );
558
 
559
+ return static::sendRequest($request);
 
 
 
560
  }
561
 
562
  /**
569
  * @param $repaired_processed_files
570
  * @param $repaired_total_files_proccessed
571
  * @param $backup_id
 
572
  *
573
  * @return array|bool|mixed
574
  *
580
  $repair_comment,
581
  $repaired_processed_files,
582
  $repaired_total_files_proccessed,
583
+ $backup_id
 
584
  ) {
585
  $request = array(
586
  'method_name' => 'security_mscan_repairs',
593
  'mscan_log_id' => 1,
594
  );
595
 
596
+ return static::sendRequest($request);
 
 
 
597
  }
598
 
599
  /**
602
  *
603
  * @param string $api_key
604
  * @param string $plugins_and_themes_to_refresh
 
605
  *
606
  * @return array|bool|mixed
607
  *
608
  * @psalm-suppress PossiblyUnusedMethod
609
  */
610
+ public static function methodRequestChecksums($api_key, $plugins_and_themes_to_refresh)
611
  {
612
  $request = array(
613
  'method_name' => 'request_checksums',
615
  'data' => $plugins_and_themes_to_refresh
616
  );
617
 
618
+ return static::sendRequest($request);
 
 
 
619
  }
620
 
621
  /**
622
  * Settings templates get API method wrapper
623
  *
624
  * @param string $api_key
 
625
  *
626
  * @return array|bool|mixed
627
  *
628
  * @psalm-suppress PossiblyUnusedMethod
629
  */
630
+ public static function methodServicesTemplatesGet($api_key, $product_name = 'antispam')
631
  {
632
  $request = array(
633
  'method_name' => 'services_templates_get',
635
  'search[product_id]' => self::getProductId($product_name),
636
  );
637
 
638
+ return static::sendRequest($request);
 
 
 
639
  }
640
 
641
  /**
643
  *
644
  * @param string $api_key
645
  * @param null|string $template_name
 
646
  *
647
  * @return array|bool|mixed
648
  *
652
  $api_key,
653
  $template_name = null,
654
  $options = '',
655
+ $product_name = 'antispam'
 
656
  ) {
657
  $request = array(
658
  'method_name' => 'services_templates_add',
662
  'search[product_id]' => self::getProductId($product_name),
663
  );
664
 
665
+ return static::sendRequest($request);
 
 
 
666
  }
667
 
668
  /**
672
  * @param int $template_id
673
  * @param string $options
674
  * @param string $product_name
 
675
  *
676
  * @return array|bool|mixed
677
  *
681
  $api_key,
682
  $template_id,
683
  $options = '',
684
+ $product_name = 'antispam'
 
685
  ) {
686
  $request = array(
687
  'method_name' => 'services_templates_update',
692
  'search[product_id]' => self::getProductId($product_name),
693
  );
694
 
695
+ return static::sendRequest($request);
 
 
 
696
  }
697
 
698
  /**
707
  * @param string $note Description text
708
  * @param string $status allow|deny
709
  * @param string $expired Date Y-m-d H:i:s
 
710
  *
711
  * @return array|bool|bool[]|mixed|string[]
712
  *
721
  $record_type,
722
  $note,
723
  $status,
724
+ $expired
 
725
  ) {
726
  $request = array(
727
  'method_name' => 'private_list_add',
736
  'expired' => $expired,
737
  );
738
 
739
+ return static::sendRequest($request);
 
 
 
740
  }
741
 
742
  /**
784
  * @param boolean $ssl use ssl on not
785
  * @param string $ssl_path
786
  *
787
+ * @return array|bool
788
  */
789
  public static function sendRequest($data, $_url = self::URL, $timeout = 10, $ssl = false, $ssl_path = '')
790
  {
 
 
791
  // Possibility to switch agent version
792
  $data['agent'] = ! empty($data['agent'])
793
  ? $data['agent']
794
  : (defined('CLEANTALK_AGENT') ? CLEANTALK_AGENT : self::AGENT);
795
 
 
 
 
 
 
 
 
 
 
 
796
  // Possibility to switch API url
797
  $url = defined('CLEANTALK_API_URL') ? CLEANTALK_API_URL : $_url;
798
 
799
+ $http = new Request();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
800
 
801
+ return $http->setUrl($url)
802
+ ->setData($data)
803
+ ->setPresets(['retry_with_socket'])
804
+ ->addCallback(
805
+ __CLASS__ . '::checkResponse',
806
+ [$data['method_name']]
807
+ )
808
+ ->request();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
809
  }
810
 
811
  /**
812
  * Function checks server response
813
  *
814
  * @param array|string $result
815
+ * @params null|string $_url
816
  * @param string $method_name
817
  *
818
  * @return mixed (array || array('error' => true))
819
  */
820
+ public static function checkResponse($result, $_url = null, $method_name = null)
821
  {
822
  // Errors handling
823
  // Bad connection
lib/Cleantalk/Common/HTTP/Request.php ADDED
@@ -0,0 +1,568 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Cleantalk\Common\HTTP;
4
+
5
+ /**
6
+ * Class Request
7
+ *
8
+ * @version 1.0.0
9
+ * @package Cleantalk\Common\Helpers
10
+ * @author Cleantalk team (welcome@cleantalk.org)
11
+ * @copyright (C) CleanTalk team (http://cleantalk.org)
12
+ * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
13
+ * @see https://github.com/CleanTalk/security-malware-firewall
14
+ */
15
+ class Request
16
+ {
17
+ /**
18
+ * Default user agent for HTTP requests
19
+ */
20
+ const AGENT = 'Cleantalk-Helper/1.0.0';
21
+
22
+ /**
23
+ * @var string|string[] Single URL string or array of URLs for multi request
24
+ */
25
+ protected $url;
26
+
27
+ /**
28
+ * @var array POST|GET indexed array with data to send
29
+ */
30
+ protected $data = [];
31
+
32
+ /**
33
+ * @var string|string[] Array with presets
34
+ * Example: array('get_code', 'async')
35
+ * Or space separated string with presets
36
+ * Example: 'get_code async get'
37
+ *
38
+ * May use the following presets(combining is possible):
39
+ * dont_follow_redirects - ignore 300-family response code and don't follow redirects
40
+ * get_code - getting only HTTP response code
41
+ * async - async requests. Sends request and return 'true' value. Doesn't wait for response.
42
+ * get - makes GET-type request instead of default POST-type
43
+ * ssl - uses SSL
44
+ * cache - allow caching for this request
45
+ * retry_with_socket - make another request with socket if cURL failed to retrieve data
46
+ */
47
+ protected $presets = [];
48
+
49
+ /**
50
+ * @var array Optional options for CURL connection
51
+ * Example: array(
52
+ * CURLOPT_URL => $url,
53
+ * CURLOPT_TIMEOUT => 15,
54
+ * CURLOPT_LOW_SPEED_TIME => 10,
55
+ * CURLOPT_RETURNTRANSFER => true,
56
+ * )
57
+ */
58
+ protected $options = [];
59
+
60
+ /**
61
+ * @var array [callable] Callback function to process after the request is performed without error to process received data
62
+ * If passed will be fired for both single and multi requests
63
+ */
64
+ protected $callbacks = [];
65
+
66
+ /**
67
+ * @var Response|array<Response>
68
+ */
69
+ public $response;
70
+
71
+ /**
72
+ * @param mixed $url
73
+ *
74
+ * @return Request
75
+ */
76
+ public function setUrl($url)
77
+ {
78
+ $this->url = $url;
79
+
80
+ return $this;
81
+ }
82
+
83
+ /**
84
+ * @param mixed $data
85
+ *
86
+ * @return Request
87
+ */
88
+ public function setData($data)
89
+ {
90
+ // If $data scalar converting it to array
91
+ $this->data = ! empty($data) && ! self::isJson($data) && is_scalar($data)
92
+ ? array((string)$data => 1)
93
+ : $data;
94
+
95
+ return $this;
96
+ }
97
+
98
+ /**
99
+ * Set one or more presets which change the way of the processing Request::request
100
+ *
101
+ * @param mixed $presets Array with presets
102
+ * Example: array('get_code', 'async')
103
+ * Or space separated string with presets
104
+ * Example: 'get_code async get'
105
+ *
106
+ * May use the following presets(combining is possible):
107
+ * dont_follow_redirects - ignore 300-family response code and don't follow redirects
108
+ * get_code - getting only HTTP response code
109
+ * async - async requests. Sends request and return 'true' value. Doesn't wait for response.
110
+ * get - makes GET-type request instead of default POST-type
111
+ * ssl - uses SSL
112
+ * cache - allow caching for this request
113
+ * retry_with_socket - make another request with socket if cURL failed to retrieve data
114
+ *
115
+ * @return Request
116
+ */
117
+ public function setPresets($presets)
118
+ {
119
+ // Prepare $presets to process
120
+ $this->presets = ! is_array($presets)
121
+ ? explode(' ', $presets)
122
+ : $presets;
123
+
124
+ return $this;
125
+ }
126
+
127
+ /**
128
+ * @param mixed $options
129
+ *
130
+ * @return Request
131
+ */
132
+ public function setOptions($options)
133
+ {
134
+ $this->options = $options;
135
+
136
+ return $this;
137
+ }
138
+
139
+ /**
140
+ * Set callback and additional arguments which will be passed to callback function
141
+ *
142
+ * @param callable $callback
143
+ * @param array $arguments
144
+ * @param int $priority
145
+ * @param bool $pass_response
146
+ *
147
+ * @return Request
148
+ * @psalm-suppress UnusedVariable
149
+ */
150
+ public function addCallback($callback, $arguments = array(), $priority = null, $pass_response = false)
151
+ {
152
+ $priority = $priority ?: 100;
153
+ if ( isset($this->callbacks[$priority]) ) {
154
+ return $this->addCallback($callback, $arguments, ++$priority);
155
+ }
156
+
157
+ $this->callbacks[$priority] = [
158
+ 'function' => $callback,
159
+ 'arguments' => $arguments,
160
+ 'pass_response' => $pass_response,
161
+ ];
162
+
163
+ return $this;
164
+ }
165
+
166
+ /**
167
+ * Function sends raw http request
168
+ *
169
+ * @return array|bool (array || array('error' => true))
170
+ */
171
+ public function request()
172
+ {
173
+ // Return the error if cURL is not installed
174
+ if ( ! function_exists('curl_init') ) {
175
+ return array('error' => 'CURL_NOT_INSTALLED');
176
+ }
177
+
178
+ if ( empty($this->url) ) {
179
+ return array('error' => 'URL_IS_NOT_SET');
180
+ }
181
+
182
+ $this->convertOptionsTocURLFormat();
183
+ $this->appendOptionsObligatory();
184
+ $this->processPresets();
185
+
186
+ // Call cURL multi request if many URLs passed
187
+ $this->response = is_array($this->url)
188
+ ? $this->requestMulti()
189
+ : $this->requestSingle();
190
+
191
+ // Process the error. Unavailable for multiple URLs.
192
+ if (
193
+ ! is_array($this->url) &&
194
+ $this->response->getError() &&
195
+ in_array('retry_with_socket', $this->presets, true)
196
+ ) {
197
+ $this->response = $this->requestWithSocket();
198
+ if ( $this->response->getError() ) {
199
+ return $this->response->getError();
200
+ }
201
+ }
202
+
203
+ return $this->runCallbacks();
204
+ }
205
+
206
+ /**
207
+ * @return Response
208
+ */
209
+ protected function requestSingle()
210
+ {
211
+ // Make a request
212
+ $ch = curl_init();
213
+
214
+ curl_setopt_array($ch, $this->options);
215
+
216
+ $request_result = curl_exec($ch); // Gather request result
217
+ $curl_info = curl_getinfo($ch); // Gather HTTP response information
218
+
219
+ // Do not catch timeout error for async requests.
220
+ if ( in_array('async', $this->presets, true) ) {
221
+ $request_result = true;
222
+ }
223
+
224
+ if ( $request_result === false ) {
225
+ $request_result = array('error' => curl_error($ch));
226
+ }
227
+
228
+ curl_close($ch);
229
+
230
+
231
+ return new Response($request_result, $curl_info);
232
+ }
233
+
234
+
235
+ /**
236
+ * Do multi curl requests without processing it.
237
+ *
238
+ * @return array<Response>
239
+ */
240
+ protected function requestMulti()
241
+ {
242
+ $urls_count = count($this->url);
243
+ $curl_arr = array();
244
+ $mh = curl_multi_init();
245
+ $this->response = [];
246
+
247
+ for ( $i = 0; $i < $urls_count; $i++ ) {
248
+ $this->options[CURLOPT_URL] = $this->url[$i];
249
+ $curl_arr[$i] = curl_init($this->url[$i]);
250
+
251
+ curl_setopt_array($curl_arr[$i], $this->options);
252
+ curl_multi_add_handle($mh, $curl_arr[$i]);
253
+ }
254
+
255
+ do {
256
+ curl_multi_exec($mh, $running);
257
+ usleep(1000);
258
+ } while ( $running > 0 );
259
+
260
+ for ( $i = 0; $i < $urls_count; $i++ ) {
261
+ $curl_info = curl_getinfo($curl_arr[$i]); // Gather HTTP response information
262
+ $received_data = curl_multi_getcontent($curl_arr[$i]);
263
+
264
+ // Do not catch timeout error for async requests.
265
+ if ( in_array('async', $this->presets, true) ) {
266
+ $received_data = true;
267
+ }
268
+
269
+ if ( $received_data === '' ) {
270
+ $received_data = array('error' => curl_error($curl_arr[$i]));
271
+ }
272
+
273
+ $this->response[$this->url[$i]] = new Response($received_data, $curl_info);
274
+ }
275
+
276
+ return $this->response;
277
+ }
278
+
279
+ /**
280
+ * Make a request with socket, exactly with file_get_contents()
281
+ *
282
+ * @return Response
283
+ */
284
+ private function requestWithSocket()
285
+ {
286
+ if ( ! ini_get('allow_url_fopen') ) {
287
+ return new Response(['error' => 'ALLOW_URL_FOPEN_IS_DISABLED'], []);
288
+ }
289
+
290
+ $context = stream_context_create(
291
+ [
292
+ 'http' => [
293
+ 'method' => 'GET', //in_array('get', $this->presets, true) ? 'GET' : 'POST',
294
+ 'timeout' => $this->options[CURLOPT_TIMEOUT],
295
+ 'content' => $this->data,
296
+ ],
297
+ ]
298
+ );
299
+
300
+ $response_content = @file_get_contents($this->url, false, $context)
301
+ ?: ['error' => 'FAILED_TO_USE_FILE_GET_CONTENTS'];
302
+
303
+ return new Response($response_content, []);
304
+ }
305
+
306
+ // Process with callback if passed. Save the processed result.
307
+ protected function runCallbacks()
308
+ {
309
+ $return_value = [];
310
+
311
+ // Cast to array to precess result from $this->requestSingle as $this->requestMulti results
312
+ $responses = is_object($this->response)
313
+ ? [$this->response]
314
+ : $this->response;
315
+
316
+ // Sort callback to keep the priority order
317
+ ksort($this->callbacks);
318
+
319
+ foreach ( $responses as $url => &$response ) {
320
+ // Skip the processing if the error occurred in this specific result
321
+ if ( $response->getError() ) {
322
+ $return_value[] = $response->getError();
323
+ continue;
324
+ }
325
+
326
+ // Get content to process
327
+ $content = $response->getContentProcessed();
328
+
329
+ // Perform all provided callback functions to each request result
330
+ if ( ! empty($this->callbacks) ) {
331
+ foreach ( $this->callbacks as $callback ) {
332
+ if ( is_callable($callback['function']) ) {
333
+ // Run callback
334
+ $content = call_user_func_array(
335
+ $callback['function'],
336
+ array_merge(
337
+ array(
338
+ $callback['pass_response'] ? $response : $content, // Pass Response or content
339
+ $url
340
+ ),
341
+ $callback['arguments']
342
+ )
343
+ );
344
+
345
+ // Foolproof
346
+ if ( ! $content instanceof Response ) {
347
+ $response->setProcessed($content);
348
+ }
349
+ }
350
+ }
351
+ }
352
+
353
+ $return_value[$url] = $content instanceof Response ? $content->getContentProcessed() : $content;
354
+ }
355
+ unset($response);
356
+
357
+ // Return a single content if it was a single request
358
+ return is_array($this->response) && count($this->response) > 1
359
+ ? $return_value
360
+ : reset($return_value);
361
+ }
362
+
363
+ /**
364
+ * Convert given options from simple naming like 'timeout' or 'ssl'
365
+ * to sophisticated and standardized cURL defined constants
366
+ *
367
+ * !! Called only after we make sure that cURL is exists !!
368
+ */
369
+ private function convertOptionsTocURLFormat()
370
+ {
371
+ $temp_options = [];
372
+ foreach ( $this->options as $option_name => &$option_value ) {
373
+ switch ( $option_name ) {
374
+ case 'timeout':
375
+ $temp_options[CURLOPT_TIMEOUT] = $option_value; // String
376
+ unset($this->options[$option_name]);
377
+ break;
378
+ case 'sslverify':
379
+ if ( $option_value ) {
380
+ $temp_options[CURLOPT_SSL_VERIFYPEER] = (bool)$option_value; // Boolean
381
+ $temp_options[CURLOPT_SSL_VERIFYHOST] = (int)(bool)$option_value; // Int 0|1
382
+ unset($this->options[$option_name]);
383
+ }
384
+ break;
385
+ case 'sslcertificates':
386
+ $temp_options[CURLOPT_CAINFO] = $option_name; // String
387
+ unset($this->options[$option_name]);
388
+ break;
389
+ case 'headers':
390
+ $temp_options[CURLOPT_HTTPHEADER] = $option_name; // String[]
391
+ unset($this->options[$option_name]);
392
+ break;
393
+ case 'user-agent':
394
+ $temp_options[CURLOPT_USERAGENT] = $option_name; // String
395
+ unset($this->options[$option_name]);
396
+ break;
397
+
398
+ // Unset unsupported string names in options
399
+ default:
400
+ if ( ! is_int($option_name) ) {
401
+ unset($this->options[$option_name]);
402
+ }
403
+ break;
404
+ }
405
+ }
406
+ unset($option_value);
407
+
408
+ $this->options = array_replace($this->options, $temp_options);
409
+ }
410
+
411
+ /**
412
+ * Set default options to make a request
413
+ */
414
+ protected function appendOptionsObligatory()
415
+ {
416
+ // Merging OBLIGATORY options with GIVEN options
417
+ $this->options = array_replace(
418
+ array(
419
+ CURLOPT_URL => ! is_array($this->url) ? $this->url : null,
420
+ CURLOPT_TIMEOUT => 10,
421
+ CURLOPT_LOW_SPEED_TIME => 7,
422
+ CURLOPT_RETURNTRANSFER => true,
423
+ CURLOPT_CONNECTTIMEOUT => 5000,
424
+ CURLOPT_FORBID_REUSE => true,
425
+ CURLOPT_USERAGENT => self::AGENT,
426
+ CURLOPT_POST => true,
427
+ CURLOPT_POSTFIELDS => $this->data,
428
+ CURLOPT_SSL_VERIFYPEER => false,
429
+ CURLOPT_SSL_VERIFYHOST => 0,
430
+ CURLOPT_HTTPHEADER => array(
431
+ 'Expect:',
432
+ // Fix for large data and old servers http://php.net/manual/ru/function.curl-setopt.php#82418
433
+ 'Expires: ' . date(DATE_RFC822, mktime(0, 0, 0, 1, 1, 1971)),
434
+ 'Cache-Control: no-store, no-cache, must-revalidate',
435
+ 'Cache-Control: post-check=0, pre-check=0',
436
+ 'Pragma: no-cache',
437
+ ),
438
+ CURLOPT_FOLLOWLOCATION => true,
439
+ CURLOPT_MAXREDIRS => 5,
440
+ ),
441
+ $this->options
442
+ );
443
+ }
444
+
445
+ /**
446
+ * Append options considering passed presets
447
+ */
448
+ protected function processPresets()
449
+ {
450
+ foreach ( $this->presets as $preset ) {
451
+ switch ( $preset ) {
452
+ // Do not follow redirects
453
+ case 'dont_follow_redirects':
454
+ $this->options[CURLOPT_FOLLOWLOCATION] = false;
455
+ $this->options[CURLOPT_MAXREDIRS] = 0;
456
+ break;
457
+
458
+ // Get headers only
459
+ case 'get_code':
460
+ $this->options[CURLOPT_HEADER] = true;
461
+ $this->options[CURLOPT_NOBODY] = true;
462
+ $this->addCallback(
463
+ static function (Response $response, $_url) {
464
+ return $response->getResponseCode();
465
+ },
466
+ array(),
467
+ 60,
468
+ true
469
+ );
470
+ break;
471
+
472
+ // Get headers only
473
+ case 'split_to_array':
474
+ $this->addCallback(
475
+ static function ($response_content, $_url) {
476
+ return explode(PHP_EOL, $response_content);
477
+ },
478
+ array(),
479
+ 50
480
+ );
481
+ break;
482
+
483
+ // Make a request, don't wait for an answer
484
+ case 'async':
485
+ $this->options[CURLOPT_CONNECTTIMEOUT] = 3;
486
+ $this->options[CURLOPT_TIMEOUT] = 3;
487
+ break;
488
+
489
+ case 'get':
490
+ $this->options[CURLOPT_CUSTOMREQUEST] = 'GET';
491
+ $this->options[CURLOPT_POST] = false;
492
+ $this->options[CURLOPT_POSTFIELDS] = null;
493
+ // Append parameter in a different way for single and multiple requests
494
+ if ( is_array($this->url) ) {
495
+ $this->url = array_map(function ($elem) {
496
+ return self::appendParametersToURL($elem, $this->data);
497
+ }, $this->url);
498
+ } else {
499
+ $this->options[CURLOPT_URL] = self::appendParametersToURL(
500
+ $this->options[CURLOPT_URL],
501
+ $this->data
502
+ );
503
+ }
504
+ break;
505
+
506
+ case 'ssl':
507
+ $this->options[CURLOPT_SSL_VERIFYPEER] = true;
508
+ $this->options[CURLOPT_SSL_VERIFYHOST] = 2;
509
+ if ( defined('CLEANTALK_CASERT_PATH') && CLEANTALK_CASERT_PATH ) {
510
+ $this->options[CURLOPT_CAINFO] = CLEANTALK_CASERT_PATH;
511
+ }
512
+ break;
513
+
514
+ case 'no_cache':
515
+ // Append parameter in a different way for single and multiple requests
516
+ if ( is_array($this->url) ) {
517
+ $this->url = array_map(static function ($elem) {
518
+ return self::appendParametersToURL($elem, ['no_cache' => mt_rand()]);
519
+ }, $this->url);
520
+ } else {
521
+ $this->options[CURLOPT_URL] = self::appendParametersToURL(
522
+ $this->options[CURLOPT_URL],
523
+ ['no_cache' => mt_rand()]
524
+ );
525
+ }
526
+ break;
527
+ }
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Appends given parameter(s) to URL considering other parameters
533
+ * Adds ? or & before the append
534
+ *
535
+ * @param string $url
536
+ * @param string|array $parameters
537
+ *
538
+ * @return string
539
+ */
540
+ public static function appendParametersToURL($url, $parameters)
541
+ {
542
+ if ( empty($parameters) ) {
543
+ return $url;
544
+ }
545
+
546
+ $parameters = is_array($parameters)
547
+ ? http_build_query($parameters)
548
+ : $parameters;
549
+
550
+ $url .= strpos($url, '?') === false
551
+ ? ('?' . $parameters)
552
+ : ('&' . $parameters);
553
+
554
+ return $url;
555
+ }
556
+
557
+ /**
558
+ * Checks if the string is JSON type
559
+ *
560
+ * @param string $string
561
+ *
562
+ * @return bool
563
+ */
564
+ public static function isJson($string)
565
+ {
566
+ return is_string($string) && is_array(json_decode($string, true));
567
+ }
568
+ }
lib/Cleantalk/Common/HTTP/Response.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Cleantalk\Common\HTTP;
4
+
5
+ class Response
6
+ {
7
+ private $raw;
8
+ private $processed;
9
+ private $error;
10
+ private $info;
11
+ private $response_code;
12
+
13
+ /**
14
+ * HTTPResponse constructor.
15
+ *
16
+ * @param $raw
17
+ * @param $info
18
+ */
19
+ public function __construct($raw, $info)
20
+ {
21
+ $this->raw = $raw;
22
+ $this->processed = $raw;
23
+ $this->info = $info;
24
+ $this->error = ! empty($raw['error'])
25
+ ? $raw
26
+ : null;
27
+ if ( isset($this->info['http_code']) ) {
28
+ $this->response_code = (int)$this->info['http_code'];
29
+ }
30
+ }
31
+
32
+ /**
33
+ * @return mixed
34
+ */
35
+ public function getError()
36
+ {
37
+ return $this->error;
38
+ }
39
+
40
+ /**
41
+ * @return mixed
42
+ */
43
+ public function getResponseCode()
44
+ {
45
+ return $this->response_code;
46
+ }
47
+
48
+ /**
49
+ * @return mixed
50
+ */
51
+ public function getContentRaw()
52
+ {
53
+ return $this->raw;
54
+ }
55
+
56
+ /**
57
+ * @return mixed
58
+ */
59
+ public function getContentProcessed()
60
+ {
61
+ return $this->processed;
62
+ }
63
+
64
+ /**
65
+ * @param mixed $processed
66
+ */
67
+ public function setProcessed($processed)
68
+ {
69
+ $this->processed = $processed;
70
+ }
71
+
72
+ /**
73
+ * @return mixed
74
+ */
75
+ public function getInfo()
76
+ {
77
+ return $this->info;
78
+ }
79
+ }
lib/Cleantalk/Common/Helper.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  namespace Cleantalk\Common;
4
 
 
5
  use Cleantalk\Templates\Singleton;
6
  use Cleantalk\Variables\Server;
7
 
@@ -48,25 +49,25 @@ class Helper
48
  */
49
  public static $cleantalks_servers = array(
50
  // MODERATE
51
- 'moderate1.cleantalk.org' => '162.243.144.175',
52
- 'moderate2.cleantalk.org' => '159.203.121.181',
53
- 'moderate3.cleantalk.org' => '88.198.153.60',
54
- 'moderate4.cleantalk.org' => '159.69.51.30',
55
- 'moderate5.cleantalk.org' => '95.216.200.119',
56
- 'moderate6.cleantalk.org' => '138.68.234.8',
57
- 'moderate8.cleantalk.org' => '188.34.154.26',
58
- 'moderate9.cleantalk.org' => '51.81.55.251',
59
 
60
  // APIX
61
- 'apix1.cleantalk.org' => '35.158.52.161',
62
- 'apix2.cleantalk.org' => '18.206.49.217',
63
- 'apix3.cleantalk.org' => '3.18.23.246',
64
- 'apix4.cleantalk.org' => '44.227.90.42',
65
- 'apix5.cleantalk.org' => '15.188.198.212',
66
- 'apix6.cleantalk.org' => '54.219.94.72',
67
  //ns
68
- 'netserv2.cleantalk.org' => '178.63.60.214',
69
- 'netserv3.cleantalk.org' => '188.40.14.173',
70
  );
71
 
72
  /**
@@ -575,7 +576,8 @@ class Helper
575
  $url = array_search($ip, self::$cleantalks_servers);
576
 
577
  return $url
578
- ?: self::ipResolve($ip);
 
579
  }
580
 
581
  return $ip;
@@ -639,7 +641,7 @@ class Helper
639
  * get - GET-request
640
  * ssl - use SSL
641
  *
642
- * @param string $url URL
643
  * @param array|string|int $data POST|GET indexed array with data to send
644
  * @param string|array $presets String or Array with presets: get_code, async, get, ssl, dont_split_to_array
645
  * @param array $opts Optional option for CURL connection
@@ -648,146 +650,21 @@ class Helper
648
  */
649
  public static function httpRequest($url, $data = array(), $presets = array(), $opts = array())
650
  {
651
- $url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'cleantalk_no_cache=' . rand(0, getrandmax());
652
 
653
- if ( method_exists(Server::class, 'isSSL') && Server::isSSL() ) {
654
- $url = str_replace('http:', 'https:', $url);
655
- }
656
-
657
- if (function_exists('curl_init')) {
658
- $ch = curl_init();
659
-
660
- if ( ! empty($data)) {
661
- // If $data scalar converting it to array
662
- $data = is_string($data) || is_int($data) ? array($data => 1) : $data;
663
- // Build query
664
- $opts[CURLOPT_POSTFIELDS] = $data;
665
- }
666
-
667
- // Merging OBLIGATORY options with GIVEN options
668
- $opts = self::arrayMergeSaveNumericKeys(
669
- array(
670
- CURLOPT_URL => $url,
671
- CURLOPT_TIMEOUT => 15,
672
- CURLOPT_LOW_SPEED_TIME => 10,
673
- CURLOPT_RETURNTRANSFER => true,
674
- CURLOPT_CONNECTTIMEOUT_MS => 10000,
675
- CURLOPT_FORBID_REUSE => true,
676
- CURLOPT_USERAGENT => self::AGENT . '; ' . (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'UNKNOWN_HOST'),
677
- CURLOPT_POST => true,
678
- CURLOPT_SSL_VERIFYPEER => false,
679
- CURLOPT_SSL_VERIFYHOST => 0,
680
- CURLOPT_HTTPHEADER => array(
681
- 'Expect:',
682
- // Fix for large data and old servers http://php.net/manual/ru/function.curl-setopt.php#82418
683
- 'Expires: ' . date(DATE_RFC822, mktime(0, 0, 0, 1, 1, 1971)),
684
- 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0',
685
- 'Cache-Control: post-check=0, pre-check=0',
686
- 'Pragma: no-cache',
687
- ),
688
- CURLOPT_FOLLOWLOCATION => true,
689
- CURLOPT_MAXREDIRS => 5,
690
- ),
691
- $opts
692
- );
693
-
694
- // Use presets
695
- $presets = is_array($presets) ? $presets : explode(' ', $presets);
696
- foreach ($presets as $preset) {
697
- switch ($preset) {
698
- // Do not follow redirects
699
- case 'dont_follow_redirects':
700
- $opts[CURLOPT_FOLLOWLOCATION] = false;
701
- $opts[CURLOPT_MAXREDIRS] = 0;
702
- break;
703
-
704
- // Get headers only
705
- case 'get_code':
706
- $opts[CURLOPT_HEADER] = true; // Header is output
707
- $opts[CURLOPT_NOBODY] = true; // No body in output method set to HEAD
708
- $opts[CURLOPT_HTTPGET] = true; // Method set to GET
709
- break;
710
-
711
- // Make a request, don't wait for an answer
712
- case 'async':
713
- $opts[CURLOPT_CONNECTTIMEOUT_MS] = 2000;
714
- $opts[CURLOPT_TIMEOUT_MS] = 2000;
715
- break;
716
-
717
- case 'get':
718
- $opts[CURLOPT_URL] .= $data ? '&' . str_replace("&amp;", "&", http_build_query($data)) : '';
719
- $opts[CURLOPT_CUSTOMREQUEST] = 'GET';
720
- $opts[CURLOPT_POST] = false;
721
- $opts[CURLOPT_POSTFIELDS] = null;
722
- break;
723
-
724
- case 'ssl':
725
- $opts[CURLOPT_SSL_VERIFYPEER] = true;
726
- $opts[CURLOPT_SSL_VERIFYHOST] = 2;
727
- if (defined('CLEANTALK_CASERT_PATH') && CLEANTALK_CASERT_PATH) {
728
- $opts[CURLOPT_CAINFO] = CLEANTALK_CASERT_PATH;
729
- }
730
- break;
731
-
732
- default:
733
- break;
734
- }
735
- }
736
-
737
- curl_setopt_array($ch, $opts);
738
- $result = curl_exec($ch);
739
-
740
- // RETURN if async request
741
- if (in_array('async', $presets, true)) {
742
- return true;
743
- }
744
-
745
- if ($result !== false) {
746
- if (
747
- is_string($result)
748
- && strpos($result, PHP_EOL) !== false
749
- && ! in_array('dont_split_to_array', $presets)
750
- ) {
751
- $result = explode(PHP_EOL, $result);
752
- }
753
-
754
- // Get code crossPHP method
755
- if (in_array('get_code', $presets)) {
756
- $curl_info = curl_getinfo($ch);
757
- $result = $curl_info['http_code'];
758
- }
759
- curl_close($ch);
760
- $out = $result;
761
- } else {
762
- $out = array('error' => curl_error($ch));
763
- }
764
- } else {
765
- $out = array('error' => 'CURL_NOT_INSTALLED');
766
- }
767
-
768
- /**
769
- * Getting HTTP-response code without cURL
770
- */
771
- if ( in_array('get_code', $presets, true) &&
772
- isset($out['error']) && $out['error'] === 'CURL_NOT_INSTALLED'
773
- ) {
774
- $headers = get_headers($url);
775
- $out = $headers !== false
776
- ? (int)preg_replace('/.*(\d{3}).*/', '$1', $headers[0])
777
- : array('error' => 'Couldnt get headers');
778
- }
779
-
780
- return $out;
781
  }
782
 
783
  /**
784
  * Do multi curl requests.
785
  *
786
  * @param array $urls Array of URLs to requests
787
- * @param string $write_to Path to the writing files dir
788
  *
789
- * @return array
790
- * @psalm-suppress PossiblyUnusedMethod
791
  */
792
  public static function httpMultiRequest($urls, $write_to = '')
793
  {
@@ -801,55 +678,26 @@ class Helper
801
  }
802
  }
803
 
804
- $urls_count = count($urls);
805
- $curl_arr = array();
806
- $master = curl_multi_init();
807
-
808
- for ($i = 0; $i < $urls_count; $i++) {
809
- $url = $urls[$i];
810
- $curl_arr[$i] = curl_init($url);
811
- $opts = array(
812
- CURLOPT_RETURNTRANSFER => true,
813
- CURLOPT_TIMEOUT => 15,
814
- CURLOPT_LOW_SPEED_TIME => 10,
815
- CURLOPT_CONNECTTIMEOUT_MS => 10000,
816
- CURLOPT_FORBID_REUSE => true,
817
- CURLOPT_USERAGENT => self::AGENT . '; ' . (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'UNKNOWN_HOST'),
818
- CURLOPT_HTTPHEADER => array('Expect:'),
819
- // Fix for large data and old servers http://php.net/manual/ru/function.curl-setopt.php#82418
820
- CURLOPT_FOLLOWLOCATION => true,
821
- CURLOPT_MAXREDIRS => 5,
822
- );
823
- curl_setopt_array($curl_arr[$i], $opts);
824
- curl_multi_add_handle($master, $curl_arr[$i]);
825
- }
826
 
827
- do {
828
- curl_multi_exec($master, $running);
829
- // @ToDo place here sleep(500) to avoid possible CPU overusing
830
- } while ($running > 0);
831
 
832
- $results = array();
 
 
 
 
 
 
 
833
 
834
- for ($i = 0; $i < $urls_count; $i++) {
835
- $info = curl_getinfo($curl_arr[$i], CURLINFO_HTTP_CODE);
836
- if (200 == $info) {
837
- if ( ! empty($write_to) && is_dir($write_to) && is_writable($write_to)) {
838
- $results[] = file_put_contents(
839
- $write_to . self::getFilenameFromUrl($urls[$i]),
840
- curl_multi_getcontent($curl_arr[$i])
841
- )
842
- ? 'success'
843
- : 'error';
844
- } else {
845
- $results[] = curl_multi_getcontent($curl_arr[$i]);
846
  }
847
- } else {
848
- $results[] = 'error';
849
- }
850
  }
851
 
852
- return $results;
853
  }
854
 
855
  /**
2
 
3
  namespace Cleantalk\Common;
4
 
5
+ use Cleantalk\Common\HTTP\Request;
6
  use Cleantalk\Templates\Singleton;
7
  use Cleantalk\Variables\Server;
8
 
49
  */
50
  public static $cleantalks_servers = array(
51
  // MODERATE
52
+ 'https://moderate1.cleantalk.org' => '162.243.144.175',
53
+ 'https://moderate2.cleantalk.org' => '159.203.121.181',
54
+ 'https://moderate3.cleantalk.org' => '88.198.153.60',
55
+ 'https://moderate4.cleantalk.org' => '159.69.51.30',
56
+ 'https://moderate5.cleantalk.org' => '95.216.200.119',
57
+ 'https://moderate6.cleantalk.org' => '138.68.234.8',
58
+ 'https://moderate8.cleantalk.org' => '188.34.154.26',
59
+ 'https://moderate9.cleantalk.org' => '51.81.55.251',
60
 
61
  // APIX
62
+ 'https://apix1.cleantalk.org' => '35.158.52.161',
63
+ 'https://apix2.cleantalk.org' => '18.206.49.217',
64
+ 'https://apix3.cleantalk.org' => '3.18.23.246',
65
+ 'https://apix4.cleantalk.org' => '44.227.90.42',
66
+ 'https://apix5.cleantalk.org' => '15.188.198.212',
67
+ 'https://apix6.cleantalk.org' => '54.219.94.72',
68
  //ns
69
+ 'http://netserv2.cleantalk.org' => '178.63.60.214',
70
+ 'http://netserv3.cleantalk.org' => '188.40.14.173',
71
  );
72
 
73
  /**
576
  $url = array_search($ip, self::$cleantalks_servers);
577
 
578
  return $url
579
+ ? parse_url($url, PHP_URL_HOST)
580
+ : self::ipResolve($ip);
581
  }
582
 
583
  return $ip;
641
  * get - GET-request
642
  * ssl - use SSL
643
  *
644
+ * @param string|array<string> $url URL
645
  * @param array|string|int $data POST|GET indexed array with data to send
646
  * @param string|array $presets String or Array with presets: get_code, async, get, ssl, dont_split_to_array
647
  * @param array $opts Optional option for CURL connection
650
  */
651
  public static function httpRequest($url, $data = array(), $presets = array(), $opts = array())
652
  {
653
+ $http = new Request();
654
 
655
+ return $http->setUrl($url)
656
+ ->setData($data)
657
+ ->setPresets($presets)
658
+ ->setOptions($opts)
659
+ ->request();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
660
  }
661
 
662
  /**
663
  * Do multi curl requests.
664
  *
665
  * @param array $urls Array of URLs to requests
 
666
  *
667
+ * @return array|bool|string
 
668
  */
669
  public static function httpMultiRequest($urls, $write_to = '')
670
  {
678
  }
679
  }
680
 
681
+ $http = new Request();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
682
 
683
+ $http->setUrl($urls)
684
+ ->setPresets('get');
 
 
685
 
686
+ if ( $write_to ) {
687
+ $http->addCallback(
688
+ static function ($content, $url) use ($write_to) {
689
+ if ( is_dir($write_to) && is_writable($write_to) ) {
690
+ return file_put_contents($write_to . self::getFilenameFromUrl($url), $content)
691
+ ? 'success'
692
+ : 'error';
693
+ }
694
 
695
+ return $content;
 
 
 
 
 
 
 
 
 
 
 
696
  }
697
+ );
 
 
698
  }
699
 
700
+ return $http->request();
701
  }
702
 
703
  /**
lib/Cleantalk/Variables/Server.php CHANGED
@@ -132,6 +132,7 @@ class Server extends ServerVariables
132
  * Determines if SSL is used.
133
  *
134
  * @return bool True if SSL, otherwise false.
 
135
  */
136
  public static function isSSL()
137
  {
132
  * Determines if SSL is used.
133
  *
134
  * @return bool True if SSL, otherwise false.
135
+ * @psalm-suppress PossiblyUnusedMethod
136
  */
137
  public static function isSSL()
138
  {
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: glomberg, safronik
3
  Tags: spam, antispam, anti-spam, comments, firewall
4
  Requires at least: 3.0
5
- Tested up to: 5.9
6
  Requires PHP: 5.6
7
  Stable tag: 5.176
8
  License: GPLv2
@@ -596,8 +596,37 @@ If your website has forms that send data to external sources, you can enable opt
596
 
597
  == Changelog ==
598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
  = 5.176 Apr 28 2022 =
600
- * New. integration added, honeypot fields added and some minor issues fixed.
601
  * New. Integration. NextendSocialLogin integration implemented.
602
  * New: Exclusions validation in apbct_settings__sanitize__exclusions().
603
  * New. WPDiscuz integration. Now sends sender_url. Integrations.php now ready to process sender_url.
2
  Contributors: glomberg, safronik
3
  Tags: spam, antispam, anti-spam, comments, firewall
4
  Requires at least: 3.0
5
+ Tested up to: 6.0
6
  Requires PHP: 5.6
7
  Stable tag: 5.176
8
  License: GPLv2
596
 
597
  == Changelog ==
598
 
599
+ = 5.177 May 12 2022 =
600
+ #### WP 6.0 compatibility, Email Encoder added, Common HTTP API implemented, Honeypot fields improved and some minor issues fixed.
601
+ * New. Email Encode functionality added.
602
+ * New. cleantalk-common.php. Honeypot field value and source now sends in sender_info.
603
+ * New. ct_preprocess_comment(). Honeypot field source now sends in sender_info.
604
+ * New. HTTP API. Common CleanTalk http library added.
605
+ * New. Public integrations. Honeypot field for search form.
606
+ * New. WP 6.0 compatibility.
607
+ * Fix: EZ Form Calculator - clearing the message
608
+ * Fix. Common. Checking all post data fixed.
609
+ * Imp. Settings. "Hide website" field moved to "different" section.
610
+ * Imp. Settings. "Hide website" type changed to checkbox from radio.
611
+ * Imp. Settings. "Honeypot field" state changed to enabled by defaults.
612
+ * Mod: Integration for Advanced Classifieds & Directory Pro - registration form
613
+ * Fix. Custom ajax. Custom ajax handler usage removed completely.
614
+ * Fix: Excluded the addition of visible fields in filter of The Events Calendar
615
+ * Fix. cleantalk-common.php. Added search honeypot field signature to potential honeypot fields post values
616
+ * Fix: MultiStep Checkout for WooCommerce - skipped step validation
617
+ * Ref. cleantalk-public-integrations.php. Empty string converts to false - comparison removed.
618
+ * fix: apbct_get_rest_url - returns the result of a get_rest_url() function if it exists
619
+ * Mod: modified getting pixel_url.
620
+ * Fix. apbct_init. Reduce multiple direct calls of apbct_get_pixel_url__ajax.
621
+ * Fix: Cleantalk\Common\HTTP\Request. Timeout error while async request.
622
+ * Fix. HTTP API. Process exception passed from WordPress \Requests class.
623
+ * Fix. Cleantalk. Antispam class fixed.
624
+ * Fix. API. Common API class fixed.
625
+ * Fix. Comments checker. Pagination fixed.
626
+ * Fix. Common. CleanTalk service request excluded.
627
+
628
  = 5.176 Apr 28 2022 =
629
+ #### New integration added, honeypot fields added and some minor issues fixed.
630
  * New. Integration. NextendSocialLogin integration implemented.
631
  * New: Exclusions validation in apbct_settings__sanitize__exclusions().
632
  * New. WPDiscuz integration. Now sends sender_url. Integrations.php now ready to process sender_url.