File: //home/swifizcd/julnohub.com.ng/wp-content/plugins/cleantalk-spam-protect/inc/cleantalk-common.php
<?php
use Cleantalk\Antispam\Cleantalk;
use Cleantalk\Antispam\CleantalkRequest;
use Cleantalk\Antispam\CleantalkResponse;
use Cleantalk\ApbctWP\API;
use Cleantalk\ApbctWP\CleantalkSettingsTemplates;
use Cleantalk\ApbctWP\Cron;
use Cleantalk\ApbctWP\DB;
use Cleantalk\ApbctWP\DTO\GetFieldsAnyDTO;
use Cleantalk\ApbctWP\Firewall\SFW;
use Cleantalk\ApbctWP\GetFieldsAny;
use Cleantalk\ApbctWP\Helper;
use Cleantalk\ApbctWP\Honeypot;
use Cleantalk\ApbctWP\Sanitize;
use Cleantalk\ApbctWP\Variables\AltSessions;
use Cleantalk\ApbctWP\Variables\Cookie;
use Cleantalk\ApbctWP\Variables\Get;
use Cleantalk\ApbctWP\Variables\Post;
use Cleantalk\ApbctWP\Variables\Server;
use Cleantalk\ApbctWP\RequestParameters\RequestParameters;
use Cleantalk\ApbctWP\RequestParameters\SubmitTimeHandler;
use Cleantalk\Common\TT;
// Prevent direct call
if ( ! defined('ABSPATH') ) {
die('Not allowed!');
}
function apbct_array($array)
{
return new \Cleantalk\Common\Arr($array);
}
$ct_checkjs_frm = 'ct_checkjs_frm';
$ct_checkjs_register_form = 'ct_checkjs_register_form';
$apbct_cookie_request_id_label = 'request_id';
$apbct_cookie_register_ok_label = 'register_ok';
$ct_checkjs_cf7 = 'ct_checkjs_cf7';
$ct_cf7_comment = '';
$ct_checkjs_jpcf = 'ct_checkjs_jpcf';
$ct_jpcf_patched = false;
$ct_jpcf_fields = array('name', 'email');
// Comment already proccessed
$ct_comment_done = false;
// Comment already proccessed
$ct_signup_done = false;
//Contains registration error
$ct_registration_error_comment = false;
// Default value for JS test
$ct_checkjs_def = 0;
// COOKIE label to store request id for last approved
$ct_approved_request_id_label = 'ct_approved_request_id';
// Last request id approved for publication
$ct_approved_request_id = null;
// Trial notice show time in minutes
$trial_notice_showtime = 10;
// Renew notice show time in minutes
$renew_notice_showtime = 10;
// COOKIE label for WP Landing Page proccessing result
$ct_wplp_result_label = 'ct_wplp_result';
// Flag indicates active JetPack comments
$ct_jp_comments = false;
// WP admin email notice interval in seconds
$ct_admin_notoice_period = 21600;
// Sevice negative comment to visitor.
// It uses for BuddyPress registrations to avoid double checks
$ct_negative_comment = null;
/**
* Public action 'plugins_loaded' - Loads locale, see http://codex.wordpress.org/Function_Reference/load_plugin_textdomain
*/
function apbct_plugin_loaded()
{
load_plugin_textdomain('cleantalk-spam-protect', false, APBCT_LANG_REL_PATH);
}
/**
* Inner function - Request's wrapper for anything
*
* @param array Array of parameters:
* 'message' - string
* 'example' - string
* 'checkjs' - int
* 'sender_email' - string
* 'sender_nickname' - string
* 'sender_info' - array
* 'post_info' - string
*
* @return array array('ct'=> Cleantalk, 'ct_result' => CleantalkResponse)
*/
function apbct_base_call($params = array(), $reg_flag = false)
{
global $cleantalk_executed;
if ( isset($params['post_info']['comment_type']) && (
($params['post_info']['comment_type'] === 'site_search_wordpress') ||
($params['post_info']['comment_type'] === 'jetpack_comment')
)) {
Cookie::$force_alt_cookies_global = true;
}
/* Exclusions */
if ( $cleantalk_executed ) {
do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST);
return array('ct_result' => new CleantalkResponse());
}
// URL, IP, Role, Form signs exclusions
if ( apbct_exclusions_check() ) {
do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST);
return array('ct_result' => new CleantalkResponse());
}
// Reversed url exclusions. Pass everything except one.
if ( apbct_exclusions_check__url__reversed() ) {
do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST);
return array('ct_result' => new CleantalkResponse());
}
global $apbct;
$cleantalk_executed = true;
/* Request ID rotation */
$tmp = array();
if ( $apbct->plugin_request_ids && ! empty($apbct->plugin_request_ids) ) {
$plugin_request_id__lifetime = 2;
foreach ( $apbct->plugin_request_ids as $request_id => $request_time ) {
if ( time() - $request_time < $plugin_request_id__lifetime ) {
$tmp[$request_id] = $request_time;
}
}
}
$apbct->plugin_request_ids = $tmp;
$apbct->save('plugin_request_ids');
// Skip duplicate requests
if (
isset($apbct->plugin_request_ids[ $apbct->plugin_request_id ]) &&
current_filter() !== 'woocommerce_registration_errors' && // Prevent skip checking woocommerce registration during checkout
current_filter() !== 'woocommerce_store_api_checkout_order_processed' && // Prevent skip checking woocommerce registration during checkout
current_filter() !== 'um_submit_form_register' // Prevent skip checking UltimateMember register
) {
do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST);
return array('ct_result' => new CleantalkResponse());
}
$apbct->plugin_request_ids[ $apbct->plugin_request_id ] = time();
$apbct->save('plugin_request_ids');
/* End of Request ID rotation */
if ( ! $apbct->stats['no_cookie_data_taken'] ) {
apbct_form__get_no_cookie_data();
}
$sender_info = apbct_get_sender_info();
if (isset($params['sender_info']) && !empty($params['sender_info'])) {
$sender_info = \Cleantalk\ApbctWP\Helper::arrayMergeSaveNumericKeysRecursive(
$sender_info,
(array)$params['sender_info']
);
}
$default_params = array(
// IPs
'sender_ip' => defined('CT_TEST_IP')
? CT_TEST_IP
: \Cleantalk\ApbctWP\Helper::ipGet('remote_addr', false),
'x_forwarded_for' => \Cleantalk\ApbctWP\Helper::ipGet('x_forwarded_for', false),
'x_real_ip' => \Cleantalk\ApbctWP\Helper::ipGet('x_real_ip', false),
// Misc
'auth_key' => $apbct->api_key,
'js_on' => apbct_js_test(Sanitize::cleanTextField(Cookie::getString('ct_checkjs')), true)
? 1
: apbct_js_test(Post::getString('ct_checkjs')),
'agent' => APBCT_AGENT,
'sender_info' => $sender_info,
'submit_time' => SubmitTimeHandler::getFromRequest(),
);
if (!isset($params['post_info']['post_url'])) {
$params['post_info']['post_url'] = Server::get('HTTP_REFERER');
}
// Event Token
$params['event_token'] = apbct_get_event_token($params);
if (Cookie::get('typo')) {
$default_params['sender_info']['typo'] = Cookie::get('typo');
}
/**
* Add exception_action sender email is empty
*/
if (
empty($params['sender_email']) &&
! isset($params['exception_action']) &&
// No need to log excluded requests on the direct integrations
! empty($params['post_info']['comment_type']) &&
strpos($params['post_info']['comment_type'], 'contact_form_wordpress_') === false &&
! preg_match('/comment$/', $params['post_info']['comment_type']) &&
! apbct_is_trackback() &&
! defined('XMLRPC_REQUEST')
) {
/**
* If the constant APBCT_SERVICE__DISABLE_EMPTY_EMAIL_EXCEPTION is defined,
* it means that the exception action should be disabled for empty email checks.
*
* Check all post data option ignore this constant.
* @since 6.58.99
*/
if (
$apbct->service_constants->disable_empty_email_exception->isDefined() &&
!$apbct->settings['data__general_postdata_test']
) {
$params['exception_action'] = 0;
} else {
$params['exception_action'] = 1;
}
}
/**
* Skip checking excepted requests if the "Log excluded requests" option is disabled.
*/
if ( isset($params['exception_action']) && $params['exception_action'] == 1 && ! $apbct->settings['exclusions__log_excluded_requests'] ) {
do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST);
return array('ct_result' => new CleantalkResponse());
}
// Honeypot
if ( isset($params['honeypot_field']) ) {
$default_params['honeypot_field'] = $params['honeypot_field'];
} else if ( $apbct->settings['data__honeypot_field'] ) {
$honeypot = Honeypot::check();
$params['honeypot_field'] = isset($honeypot['status']) ? $honeypot['status'] : null;
if ( isset($honeypot['value'], $honeypot['source'], $params['sender_info']) ) {
$params['sender_info']['honeypot_field_value'] = $honeypot['value'];
$params['sender_info']['honeypot_field_source'] = $honeypot['source'];
}
}
// Send $_SERVER if couldn't find IP
if ( empty($default_params['sender_ip']) ) {
$default_params['sender_info']['server_info'] = $_SERVER;
}
$ct = new Cleantalk();
$ct_request = new CleantalkRequest(
\Cleantalk\ApbctWP\Helper::arrayMergeSaveNumericKeysRecursive($default_params, $params)
);
// Options store url without scheme because of DB error with ''://'
$config = ct_get_server();
$ct->server_url = APBCT_MODERATE_URL;
$ct->work_url = isset($config['ct_work_url']) && preg_match('/https:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
$ct->server_ttl = isset($config['ct_server_ttl']) ? $config['ct_server_ttl'] : null;
$ct->server_changed = isset($config['ct_server_changed']) ? $config['ct_server_changed'] : null;
$start = microtime(true);
$ct_result = $reg_flag
? @$ct->isAllowUser($ct_request)
: @$ct->isAllowMessage($ct_request);
$exec_time = microtime(true) - $start;
// Statistics
// Average request time
apbct_statistics_rotate($exec_time);
// Last request
$apbct->stats['last_request']['time'] = time();
$apbct->stats['last_request']['server'] = $ct->work_url;
$apbct->save('stats');
if ( $ct->server_change ) {
update_option(
'cleantalk_server',
array(
'ct_work_url' => $ct->work_url,
'ct_server_ttl' => $ct->server_ttl,
'ct_server_changed' => time(),
)
);
$cron = new Cron();
$cron->updateTask('rotate_moderate', 'apbct_rotate_moderate', 86400); // Rotate moderate server
}
//alternative checks and connection report handler
if ($ct_result instanceof \Cleantalk\Antispam\CleantalkResponse) {
$ct_result = ct_checks_on_cleantalk_errors($ct_request, $ct_result);
}
// Restart submit form counter for failed requests
if ( is_object($ct_result) && $ct_result->allow == 0 ) {
apbct_cookie(); // Setting page timer and cookies
ct_add_event('no');
} else {
ct_add_event('yes');
}
// Set cookies if it's not.
if ( empty($apbct->flags__cookies_setuped) ) {
Cookie::$force_alt_cookies_global = false;
apbct_cookie();
}
//clear POST and REQUEST superglobal from service data
$_POST = apbct_clear_superglobal_service_data($_POST, 'post');
$_REQUEST = apbct_clear_superglobal_service_data($_REQUEST, 'request');
return array('ct' => $ct, 'ct_result' => $ct_result);
}
function apbct_rotate_moderate()
{
$ct = new Cleantalk();
$ct->server_url = APBCT_MODERATE_URL;
$ct->rotateModerate();
if ( $ct->server_change ) {
update_option(
'cleantalk_server',
array(
'ct_work_url' => $ct->work_url,
'ct_server_ttl' => $ct->server_ttl,
'ct_server_changed' => time(),
)
);
}
}
function apbct_exclusions_check($func = null)
{
global $apbct;
if ( Post::get('apbct_do_not_exclude') ) {
return false;
}
// Common exclusions
if (
apbct_exclusions_check__form_signs($_POST) ||
apbct_exclusions_check__url() ||
apbct_is_user_role_in($apbct->settings['exclusions__roles'])
) {
return true;
}
// Personal exclusions
switch ( $func ) {
case 'ct_contact_form_validate_postdata':
if (
(defined('DOING_AJAX') && DOING_AJAX) ||
apbct_array($_POST)->getKeys('members_search_submit')->result()
) {
return true;
}
break;
case 'ct_contact_form_validate':
if (
apbct_array($_POST)->getKeys('members_search_submit')->result()
|| (
(int)$apbct->settings['data__protect_logged_in'] === 1
&& (
Post::equal('wpfaction', 'topic_add')
|| Post::equal('wpfaction', 'post_add')
)
&& apbct_is_plugin_active('wpforo/wpforo.php')
)
) {
return true;
}
break;
default:
return false;
}
return false;
}
/**
* Check if the reversed exclusions is set and doesn't match.
*
* @return bool
*/
function apbct_exclusions_check__url__reversed()
{
return defined('APBCT_URL_EXCLUSIONS__REVERSED') &&
! Server::hasString('REQUEST_URI', APBCT_URL_EXCLUSIONS__REVERSED);
}
/**
* Checks if reuqest URI is in exclusion list
*
* @return bool
*/
function apbct_exclusions_check__url()
{
global $apbct;
if ( ! empty($apbct->settings['exclusions__urls']) ) {
if ( strpos($apbct->settings['exclusions__urls'], "\r\n") !== false ) {
$exclusions = explode("\r\n", $apbct->settings['exclusions__urls']);
} elseif ( strpos($apbct->settings['exclusions__urls'], "\n") !== false ) {
$exclusions = explode("\n", $apbct->settings['exclusions__urls']);
} else {
$exclusions = explode(',', $apbct->settings['exclusions__urls']);
}
//default haystack is request_uri
$url_haystack = Server::getString('REQUEST_URI');
/**
* Fix for AJAX and WP REST API forms
*/
// case for admin-ajax routes, may contain get params(!)
$is_admin_ajax_like = stripos(Server::getString('REQUEST_URI'), '/wp-admin/admin-ajax.php') === 0;
// case for woocommerce-ajax routes, may contain get params(!)
$is_wc_ajax_like = stripos(Server::getString('REQUEST_URI'), '/?wc-ajax=') === 0;
// case for wp-json paths
$is_wp_json_like = stripos(Server::getString('REQUEST_URI'), '/wp-json/') === 0;
// case for rest paths
$rest_url_only_path = apbct_get_rest_url_only_path();
$is_rest_only_path = $rest_url_only_path !== 'index.php' && stripos(Server::getString('REQUEST_URI'), $rest_url_only_path) === 0;
// if need to use http referrer as haystack
$do_use_http_referrer = (
Server::getString('HTTP_REFERER') &&
(
$is_admin_ajax_like ||
$is_wc_ajax_like ||
$is_wp_json_like ||
$is_rest_only_path
)
);
// do combine actions from referrer if so
if ($do_use_http_referrer) {
$url_haystack = str_ireplace(
array('http://', 'https://', strval(TT::toString(Server::get('HTTP_HOST')))),
'',
Server::getString('HTTP_REFERER')
);
}
// if exclusions is full-url like, modify haystack to being full-url also
if ( $apbct->data['check_exclusion_as_url'] ) {
$protocol = ! in_array(Server::get('HTTPS'), ['off', '']) || Server::get('SERVER_PORT') == 443 ? 'https://' : 'http://';
$url_haystack = $protocol . TT::toString(Server::get('SERVER_NAME')) . TT::toString($url_haystack);
}
$url_haystack = TT::toString($url_haystack);
foreach ( $exclusions as $exclusion ) {
if (
(
$apbct->settings['exclusions__urls__use_regexp'] &&
preg_match('@' . $exclusion . '@', $url_haystack) === 1
) ||
stripos($url_haystack, $exclusion) !== false
) {
return true;
}
}
return false;
}
return false;
}
/**
* Check POST array for the exclusion form signs. Listen for array keys or for value in case if key is "action".
* @param array $form_data The POST array or another filtered array of form data.
* @return bool True if exclusion found in the keys of array, false otherwise.
*/
function apbct_exclusions_check__form_signs($form_data)
{
global $apbct;
if ( ! empty($apbct->settings['exclusions__form_signs']) ) {
if ( strpos($apbct->settings['exclusions__form_signs'], "\r\n") !== false ) {
$exclusions = explode("\r\n", $apbct->settings['exclusions__form_signs']);
} elseif ( strpos($apbct->settings['exclusions__form_signs'], "\n") !== false ) {
$exclusions = explode("\n", $apbct->settings['exclusions__form_signs']);
} else {
$exclusions = explode(',', $apbct->settings['exclusions__form_signs']);
}
foreach ( $exclusions as $exclusion ) {
foreach ($form_data as $key => $value) {
$haystack = ($key === 'action' || $key === 'data') ? $value : $key;
if (
$haystack === $exclusion ||
(is_string($haystack) && stripos($haystack, $exclusion) !== false) ||
(is_string($haystack) && preg_match('@' . $exclusion . '@', $haystack) === 1)
) {
return true;
}
}
}
return false;
}
return false;
}
/**
* Inner function - Default data array for senders
* @return array
*/
function apbct_get_sender_info()
{
global $apbct;
// Validate cookie from the backend
$cookie_is_ok = apbct_cookies_test();
if ( count($_POST) > 0 ) {
foreach ( $_POST as $k => $v ) {
if ( preg_match("/^(ct_check|checkjs).+/", (string)$k) ) {
$checkjs_data_post = $v;
}
}
}
// Visible fields processing
$visible_fields = GetFieldsAny::getVisibleFieldsData();
// preparation of some parameters when cookies are disabled and data is received from localStorage
if ($apbct->data['cookies_type'] === 'native') {
$param_email_check = Cookie::getNativeCookieValue('ct_checked_emails');
$param_screen_info = Cookie::getNativeCookieValue('ct_screen_info');
} else {
$param_email_check = Cookie::get('ct_checked_emails') ? json_encode(
Cookie::get('ct_checked_emails')
) : null;
$param_screen_info = Cookie::get('ct_screen_info')
? json_encode(Cookie::get('ct_screen_info'))
: null;
}
$param_mouse_cursor_positions = Cookie::get('ct_pointer_data');
$param_pixel_url = Cookie::get('apbct_pixel_url');
if ($apbct->data['cookies_type'] === 'none') {
$param_email_check = Cookie::get('ct_checked_emails') ? urldecode(
TT::toString(Cookie::get('ct_checked_emails'))
) : null;
$param_mouse_cursor_positions = urldecode(TT::toString(Cookie::get('ct_pointer_data')));
$param_pixel_url = Cookie::get('apbct_pixel_url');
$param_pixel_url = urldecode(is_string($param_pixel_url) ? $param_pixel_url : '');
$param_screen_info = Cookie::get('ct_screen_info')
? urldecode(TT::toString(Cookie::get('ct_screen_info')))
: null;
}
//cache plugins detection
$cache_plugins_detected = apbct_is_cache_plugins_exists(true);
$cache_plugins_detected = empty($cache_plugins_detected) ? false : $cache_plugins_detected;
$cache_plugins_detected = json_encode($cache_plugins_detected);
$apbct_urls = RequestParameters::getCommonStorage('apbct_urls');
if (!empty($apbct_urls)) {
if (is_string($apbct_urls)) {
$apbct_urls = json_encode(json_decode($apbct_urls, true));
} else {
$apbct_urls = json_encode($apbct_urls);
}
}
$apbct_urls = !empty($apbct_urls) ? $apbct_urls : null;
$site_landing_ts = RequestParameters::get('apbct_site_landing_ts', true);
$site_landing_ts = !empty($site_landing_ts) ? TT::toString($site_landing_ts) : null;
$site_referer = RequestParameters::get('apbct_site_referer', true);
$site_referer = !empty($site_referer) ? TT::toString($site_referer) : 'UNKNOWN';
/**
* Important! Do not use just HTTP only flag here. Page hits are handled on JS side
* and could be provided via NoCookie hidden field.
* Also, forms with forced alt cookies does not provide it via hidden field and in the same time other forms do,
* so we need a flag to know the source.
* A.G.
*/
$page_hits = RequestParameters::get('apbct_page_hits', Cookie::$force_alt_cookies_global);
$page_hits = !empty($page_hits) ? TT::toString($page_hits) : null;
//Let's keep $data_array for debugging
$data_array = array(
'plugin_request_id' => $apbct->plugin_request_id,
'wpms' => is_multisite() ? 'yes' : 'no',
'remote_addr' => \Cleantalk\ApbctWP\Helper::ipGet('remote_addr', false),
'USER_AGENT' => Server::get('HTTP_USER_AGENT'),
'page_url' => apbct_sender_info___get_page_url(),
'cms_lang' => substr(get_locale(), 0, 2),
'ct_options' => json_encode($apbct->settings, JSON_UNESCAPED_SLASHES),
'fields_number' => sizeof($_POST),
'direct_post' => $cookie_is_ok === null && apbct_is_post() ? 1 : 0,
// Raw data to validated JavaScript test in the cloud
'checkjs_data_cookies' => Cookie::get('ct_checkjs') ?: null,
'checkjs_data_post' => !empty($checkjs_data_post) ? $checkjs_data_post : null,
// PHP cookies
'cookies_enabled' => $cookie_is_ok,
'data__set_cookies' => $apbct->settings['data__set_cookies'],
'data__cookies_type' => $apbct->data['cookies_type'],
'REFFERRER' => Server::getString('HTTP_REFERER'),
'REFFERRER_PREVIOUS' => !empty(Cookie::getString('apbct_prev_referer')) && $cookie_is_ok
? Cookie::getString('apbct_prev_referer')
: null,
'site_landing_ts' => $site_landing_ts,
'page_hits' => $page_hits,
'mouse_cursor_positions' => $param_mouse_cursor_positions,
'js_timezone' => Cookie::get('ct_timezone') ?: null,
'key_press_timestamp' => Cookie::get('ct_fkp_timestamp') ?: null,
'page_set_timestamp' => Cookie::get('ct_ps_timestamp') ?: null,
'form_visible_inputs' => !empty($visible_fields['visible_fields_count'])
? $visible_fields['visible_fields_count']
: null,
'apbct_visible_fields' => !empty($visible_fields['visible_fields'])
? $visible_fields['visible_fields']
: null,
'form_invisible_inputs' => !empty($visible_fields['invisible_fields_count'])
? $visible_fields['invisible_fields_count']
: null,
'apbct_invisible_fields' => !empty($visible_fields['invisible_fields'])
? $visible_fields['invisible_fields']
: null,
// Misc
'site_referer' => $site_referer,
'source_url' => $apbct_urls,
'pixel_url' => $param_pixel_url,
'pixel_setting' => $apbct->settings['data__pixel'],
// Debug stuff
'amp_detected' => apbct_is_amp_request(),
'hook' => current_filter() ? current_filter() : 'no_hook',
'headers_sent' => !empty($apbct->headers_sent) ? $apbct->headers_sent : false,
'headers_sent__hook' => !empty($apbct->headers_sent__hook) ? $apbct->headers_sent__hook : 'no_hook',
'headers_sent__where' => !empty($apbct->headers_sent__where) ? $apbct->headers_sent__where : false,
'request_type' => Server::get('REQUEST_METHOD') ?: 'UNKNOWN',
'email_check' => $param_email_check,
'screen_info' => $param_screen_info,
'has_scrolled' => Cookie::get('ct_has_scrolled') !== ''
? json_encode(Cookie::get('ct_has_scrolled'))
: null,
'mouse_moved' => Cookie::get('ct_mouse_moved') !== ''
? json_encode(Cookie::get('ct_mouse_moved'))
: null,
'emulations_headless_mode' => Cookie::get('apbct_headless') !== ''
? json_encode(Cookie::get('apbct_headless'))
: null,
'no_cookie_data_taken' => isset($apbct->stats['no_cookie_data_taken']) ? $apbct->stats['no_cookie_data_taken'] : null,
'no_cookie_data_post_source' => isset($apbct->stats['no_cookie_data_post_source'])
? $apbct->stats['no_cookie_data_post_source']
: null,
'has_key_up' => Cookie::get('ct_has_key_up') !== ''
? json_encode(Cookie::get('ct_has_key_up'))
: null,
'has_input_focused' => Cookie::get('ct_has_input_focused') !== ''
? json_encode(Cookie::get('ct_has_input_focused'))
: null,
'cache_plugins_detected' => $cache_plugins_detected,
//bot detector data
'bot_detector_fired_form_exclusions' => apbct__bot_detector_get_fired_exclusions(),
'bot_detector_prepared_form_exclusions' => apbct__bot_detector_get_prepared_exclusion(),
'bot_detector_frontend_data_log' => apbct__bot_detector_get_fd_log(),
'submit_time_calculation_enabled' => SubmitTimeHandler::isCalculationDisabled() ? 0 : 1,
'ct_gathering_loaded' => Cookie::getBool('ct_gathering_loaded'),
);
// Unset cookies_enabled from sender_info if cookies_type === none
if ($apbct->data['cookies_type'] === 'none') {
unset($data_array['cookies_enabled']);
}
return $data_array;
}
function apbct_sender_info___get_page_url()
{
if (
( apbct_is_ajax() || apbct_is_rest() )
&& Server::get('HTTP_REFERER')
) {
return TT::toString(Server::get('HTTP_REFERER'));
}
$protocol = ! empty($_SERVER['HTTPS']) && 'off' !== strtolower($_SERVER['HTTPS']) ? "https://" : "http://";
return $protocol . TT::toString(Server::get('SERVER_NAME')) . TT::toString(Server::get('REQUEST_URI'));
}
function apbct_get_pixel_url($direct_call = false)
{
global $apbct;
$ip = Helper::ipGet();
$ip_version = Helper::ipValidate(TT::toString($ip));
$pixel_hash = md5(
$ip
. $apbct->api_key
. Helper::timeGetIntervalStart(3600 * 3) // Unique for every 3 hours
);
//get params for cache plugins exclusion detection
$cache_plugins_detected = apbct_is_cache_plugins_exists(true);
$cache_exclusion_snippet = '';
if ( !empty($cache_plugins_detected) ) {
//NitroPack
if ( in_array('NitroPack', $cache_plugins_detected) ) {
$cache_exclusion_snippet = '?gclid=' . $pixel_hash;
}
}
//construct URL
$server = get_option('cleantalk_server');
$server_url = isset($server['ct_work_url']) ? $apbct->server['ct_work_url'] : APBCT_MODERATE_URL;
$server_url_with_version = $ip_version === 'v4' ? str_replace('.cleantalk.org', '-v4.cleantalk.org', $server_url) : $server_url;
$pixel = '/pixel/' . $pixel_hash . '.gif' . $cache_exclusion_snippet;
$pixel_url = str_replace('http://', 'https://', $server_url_with_version) . $pixel;
if ( $direct_call ) {
return $pixel_url ;
}
die($pixel_url);
}
/**
* Checking email before POST
*/
function apbct_email_check_before_post()
{
$email = trim(TT::toString(Post::get('email')));
if ( $email ) {
$result = \Cleantalk\ApbctWP\API::methodEmailCheck($email);
if ( isset($result['data']) ) {
die(json_encode(array('result' => $result['data'])));
}
die(json_encode(array('error' => 'ERROR_CHECKING_EMAIL')));
}
die(json_encode(array('error' => 'EMPTY_DATA')));
}
/**
* Checking email exist before POST
*/
function apbct_email_check_exist_post()
{
global $apbct;
$email = trim(TT::toString(Post::get('email')));
$api_key = $apbct->api_key;
$brandname = $apbct->data['wl_mode_enabled'] ? $apbct->data['wl_brandname'] : 'Anti-Spam by CleanTalk';
if ( $email && $api_key ) {
$result = \Cleantalk\ApbctWP\API::methodEmailCheckExist($email, $api_key);
if ( isset($result['result']) ) {
$text_result = '';
if ( $result['result'] != 'EXISTS' ) {
$text_result = __('The email doesn`t exist, double check the address.', 'cleantalk-spam-protect') . ' ' . $brandname . '.';
} else {
$text_result = __('The email exists and is good to use!', 'cleantalk-spam-protect') . ' ' . $brandname . '.';
}
$result['text_result'] = $text_result;
die(json_encode(array('result' => $result)));
}
die(json_encode(array('error' => 'ERROR_CHECKING_EMAIL')));
}
die(json_encode(array('error' => 'EMPTY_DATA')));
}
/**
* Force protection check bot
*/
function apbct_force_protection_check_bot()
{
die(\Cleantalk\ApbctWP\Antispam\ForceProtection::getInstance()->checkBot());
}
/**
* Get ct_get_checkjs_value
*
* @return int|string|null
*/
function ct_get_checkjs_value()
{
global $apbct;
// Use static JS keys
if ( $apbct->settings['data__use_static_js_key'] == 1 ) {
$key = hash('sha256', $apbct->api_key . ct_get_admin_email() . $apbct->salt);
// Auto detecting. Detected.
} elseif (
$apbct->settings['data__use_static_js_key'] == -1 &&
(apbct_is_cache_plugins_exists() ||
(apbct_is_post() && isset($apbct->data['cache_detected']) && $apbct->data['cache_detected'] == 1)
)
) {
$key = hash('sha256', $apbct->api_key . ct_get_admin_email() . $apbct->salt);
if ( apbct_is_cache_plugins_exists() ) {
$apbct->data['cache_detected'] = 1;
}
$apbct->saveData();
// Using dynamic JS keys
} else {
$keys = $apbct->data['js_keys'];
$keys_checksum = md5(json_encode($keys));
$key = null;
$latest_key_time = 0;
foreach ( $keys as $k => $t ) {
if (!is_object($t)) {
// Removing key if it's to old
if ( time() - $t > $apbct->data['js_keys_store_days'] * 86400 * 7 ) {
unset($keys[$k]);
continue;
}
if ( $t > $latest_key_time ) {
$latest_key_time = $t;
$key = $k;
}
} else {
$keys = array();
}
}
// Set new key if the latest key is too old
if ( time() - $latest_key_time > $apbct->data['js_key_lifetime'] ) {
$key = rand();
$keys[$key] = time();
}
// Save keys if they were changed
if ( md5(json_encode($keys)) != $keys_checksum ) {
$apbct->data['js_keys'] = $keys;
// $apbct->saveData();
}
$apbct->data['cache_detected'] = 0;
$apbct->saveData();
}
return $key;
}
function apbct_is_cache_plugins_exists($return_names = false)
{
$out = array();
$constants_of_cache_plugins = array(
'WP_ROCKET_VERSION' => 'WPRocket',
'LSCWP_DIR' => 'LiteSpeed Cache',
'WPFC_WP_CONTENT_BASENAME' => 'WP Fastest Cache',
'W3TC' => 'W3 Total Cache',
'WPO_VERSION' => 'WP-Optimize – Clean, Compress, Cache',
'AUTOPTIMIZE_PLUGIN_VERSION' => 'Autoptimize',
'WPCACHEHOME' => 'WP Super Cache',
'WPHB_VERSION' => 'Hummingbird – Speed up, Cache, Optimize Your CSS and JS',
'CE_FILE' => 'Cache Enabler – WordPress Cache',
'SiteGround_Optimizer\VERSION' => 'SG Optimizer',
'NITROPACK_VERSION' => 'NitroPack',
'TWO_PLUGIN_FILE' => '10Web Booster',
'FLYING_PRESS_VERSION' => 'Flying Press',
'BREEZE_VERSION' => 'Breeze',
'SPEEDYCACHE_VERSION' => 'SpeedyCache',
);
$classes_of_cache_plugins = array (
'\RedisObjectCache' => 'Redis',
'\WP_Rest_Cache_Plugin\Includes\Plugin' => 'Rest Cache'
);
$headers = array(
'HTTP_X_VARNISH' => 'Varnish',
);
foreach ($constants_of_cache_plugins as $const => $_text) {
if ( defined($const) ) {
$out[] = $_text;
}
}
foreach ($classes_of_cache_plugins as $class => $_text) {
/**
* @psalm-suppress DocblockTypeContradiction
* @psalm-suppress TypeDoesNotContainType
*/
if ( class_exists($class) ) {
$out[] = $_text;
}
}
foreach ($headers as $header => $_text) {
if ( isset($_SERVER[$header]) ) {
$out[] = $_text;
}
}
return $return_names ? $out : !empty($out);
}
function apbct_is_varnish_cache_exists()
{
return isset($_SERVER['HTTP_X_VARNISH']);
}
function apbct_is_advanced_cache_exists()
{
return apbct_is_cache_plugins_exists() && file_exists(untrailingslashit(WP_CONTENT_DIR) . '/advanced-cache.php');
}
function apbct_is_10web_booster_exists()
{
return apbct_is_cache_plugins_exists() && apbct_is_plugin_active('tenweb-speed-optimizer/tenweb_speed_optimizer.php');
}
/**
* Inner function - Current site admin e-mail
* @return string Admin e-mail
*/
function ct_get_admin_email()
{
global $apbct;
if ( ! is_multisite() ) {
// Not WPMS
$admin_email = get_option('admin_email');
} elseif ( is_main_site() || $apbct->network_settings['multisite__work_mode'] != 3) {
// WPMS - Main site, common account
$admin_email = get_site_option('admin_email');
} else {
// WPMS - Individual account, individual Access key
$admin_email = get_blog_option(get_current_blog_id(), 'admin_email');
}
if ( $apbct->data['account_email'] ) {
add_filter('apbct_get_api_key_email', function () {
global $apbct;
return $apbct->data['account_email'];
});
}
return $admin_email;
}
/**
* Inner function - Current CleanTalk working server info
* @return array Array of server data
*/
function ct_get_server()
{
$ct_server = get_option('cleantalk_server');
if ( ! is_array($ct_server) ) {
$ct_server = array(
'ct_work_url' => null,
'ct_server_ttl' => null,
'ct_server_changed' => null
);
}
$ct_server['ct_work_url'] = Sanitize::sanitizeCleantalkServerUrl(TT::getArrayValueAsString($ct_server, 'ct_work_url'));
return $ct_server;
}
/**
* @param $url
*
* @return string|null
*/
function sanitize_cleantalk_server_url($url)
{
if (!is_string($url)) {
return null;
}
return preg_match('/^.*(moderate|api).*\.cleantalk.org(?!\.)[\/\\\\]{0,1}/m', $url)
? $url
: null;
}
/**
* Inner function - Stores ang returns cleantalk hash of current comment
*
* @param string New hash or NULL
*
* @return string New hash or current hash depending on parameter
*/
function ct_hash($new_hash = '')
{
/**
* Current hash
*/
static $hash;
if ( ! empty($new_hash) ) {
$hash = $new_hash;
}
return $hash;
}
/**
* Inner function - Write manual moderation results to PHP sessions
*
* @param string $hash CleanTalk comment hash
* @param string $message comment_content
* @param int $allow flag good comment (1) or bad (0)
*
* @return string comment_content w\o cleantalk resume
*/
function ct_feedback($hash, $allow)
{
global $apbct;
$ct_feedback = $hash . ':' . $allow . ';';
if ( ! $apbct->data['feedback_request'] ) {
$apbct->data['feedback_request'] = $ct_feedback;
} else {
$apbct->data['feedback_request'] .= $ct_feedback;
}
$apbct->saveData();
return $ct_feedback;
}
/**
* Inner function - Sends the results of moderation
* Scheduled in 3600 seconds!
*
* @param string $feedback_request
*
* @return bool
*/
function ct_send_feedback($feedback_request = null)
{
global $apbct;
if (
empty($feedback_request) &&
isset($apbct->data['feedback_request']) &&
preg_match("/^[a-z0-9\;\:]+$/", $apbct->data['feedback_request'])
) {
$feedback_request = $apbct->data['feedback_request'];
$apbct->data['feedback_request'] = '';
$apbct->saveData();
}
if ( $feedback_request !== null ) {
$ct_request = new CleantalkRequest(array(
// General
'auth_key' => $apbct->api_key,
// Additional
'feedback' => $feedback_request,
));
$ct = new Cleantalk();
// Server URL handling
$config = ct_get_server();
$ct->server_url = APBCT_MODERATE_URL;
$ct->work_url = isset($config['ct_work_url']) && preg_match('/http:\/\/.+/', $config['ct_work_url']) ? $config['ct_work_url'] : null;
$ct->server_ttl = isset($config['ct_server_ttl']) ? $config['ct_server_ttl'] : null;
$ct->server_changed = isset($config['ct_server_changed']) ? $config['ct_server_changed'] : null;
//method use api3.0 since 6.35(6.36?)
$ct->api_version = '/api3.0';
$ct->method_uri = 'send_feedback';
$ct_result = $ct->sendFeedback($ct_request);
if ( $ct->server_change ) {
update_option(
'cleantalk_server',
array(
'ct_work_url' => $ct->work_url,
'ct_server_ttl' => $ct->server_ttl,
'ct_server_changed' => time(),
)
);
$cron = new Cron();
$cron->updateTask('rotate_moderate', 'apbct_rotate_moderate', 86400); // Rotate moderate server
}
if ( $ct_result ) {
return true;
}
}
return false;
}
/**
* Delete old spam comments
* Scheduled in 3600 seconds!
* @return null
*/
function ct_delete_spam_comments()
{
global $apbct;
if ( $apbct->settings['comments__remove_old_spam'] == 1 ) {
$last_comments = get_comments(array('status' => 'spam', 'number' => 1000, 'order' => 'ASC'));
if ( is_array($last_comments) ) {
foreach ( $last_comments as $c ) {
if ( is_object($c) ) {
$comment_date_gmt = strtotime($c->comment_date_gmt);
if ( $comment_date_gmt ) {
if ( time() - $comment_date_gmt > 86400 * $apbct->data['spam_store_days'] ) {
// Force deletion old spam comments
wp_delete_comment(TT::toInt($c->comment_ID), true);
}
}
}
}
}
}
return null;
}
/**
* Get data from an ARRAY recursively
*
* @param array $arr
* @param string $email
* @param string|array $nickname
*
* @return array
* @deprecated Use ct_gfa_dto() to work with DTO object
*/
function ct_get_fields_any($arr, $email = '', $nickname = '')
{
if ( is_array($nickname) ) {
$nickname_str = '';
foreach ( $nickname as $value ) {
$nickname_str .= ($value ? $value . " " : "");
}
$nickname = trim($nickname_str);
}
return ct_gfa($arr, TT::toString($email), TT::toString($nickname));
}
/**
* Get data as assoc array from an ARRAY recursively
*
* @see getFieldsAnyDTO to understand the structure of the result
* @param array $input_array maybe raw POST array or other preprocessed POST data.
* @param string $email email, rewriting result of process $input_array data
* @param string $nickname nickname, rewriting result of process $input_array data
* @param array $emails_array additional emails array, rewriting result of process $input_array data
* @deprecated since 6.48, use ct_gfa_dto() instead
* @return array
*/
function ct_gfa($input_array, $email = '', $nickname = '', $emails_array = array())
{
$gfa = new GetFieldsAny($input_array);
return $gfa->getFields($email, $nickname, $emails_array);
}
/**
* Get data as GetFieldsAnyDTO object from an ARRAY recursively
*
* @see getFieldsAnyDTO to understand the structure of the result
* @param array $input_array maybe raw POST array or other preprocessed POST data.
* @param string $email email, rewriting result of process $input_array data
* @param string $nickname nickname, rewriting result of process $input_array data
* @param array $emails_array array of additional emails, rewriting result of process $input_array data
*
* @return GetFieldsAnyDTO
*/
function ct_gfa_dto($input_array, $email = '', $nickname = '', $emails_array = array())
{
$gfa = new GetFieldsAny($input_array);
return $gfa->getFieldsDTO($email, $nickname, $emails_array);
}
/**
* Function changes CleanTalk result object if an error occurred.
* @return object
*/
function ct_checks_on_cleantalk_errors(CleantalkRequest $ct_request, CleantalkResponse $ct_result)
{
global $apbct;
$post_blocked_via_js_check = false;
if ( (int)($ct_result->errno) != 0 ) {
if ( $ct_request->js_on === null || $ct_request->js_on != 1 ) {
$ct_result->allow = 0;
$ct_result->spam = '1';
$ct_result->comment = sprintf(
'We\'ve got an issue: %s. Forbidden. Please, enable Javascript. %s.',
isset($ct_result->comment) ? $ct_result->comment : '',
$apbct->plugin_name
);
$post_blocked_via_js_check = true;
} else {
$ct_result->allow = 1;
$ct_result->comment = 'Allow';
}
}
// Add a connection report
$apbct->getConnectionReports()->handleRequest($ct_request, $ct_result, $post_blocked_via_js_check);
return $ct_result;
}
/**
* Does ey has correct symbols? Checks against regexp ^[a-z\d]{3,30}$
*
* @param string api_key
*
* @return bool
*/
function apbct_api_key__is_correct($api_key = null)
{
global $apbct;
$api_key = $api_key !== null ? $api_key : $apbct->api_key;
return $api_key && preg_match('/^[a-z\d]{3,30}$/', $api_key) ? true : false;
}
function apbct__is_hosting_license()
{
global $apbct;
return $apbct->data['moderate_ip'] && $apbct->data['ip_license'];
}
function apbct_add_async_attribute($tag, $handle)
{
global $apbct;
$scripts_handles_names = array(
'ct_public',
'ct_public_functions',
'ct_public_admin_js',
'ct_internal',
'ct_external',
'ct_nocache',
'ct_collect_details',
'cleantalk-modal',
);
if ( in_array($handle, $scripts_handles_names, true) ) {
if ( $apbct->settings['misc__async_js'] ) {
$tag = str_replace(' src', ' async="async" src', $tag);
}
// Prevent script deferred loading by various CDN
$tag = str_replace(' src', ' data-pagespeed-no-defer src', $tag);
if ( class_exists('Cookiebot_WP') ) {
$tag = str_replace(' src', ' data-cookieconsent="ignore" src', $tag);
}
}
return $tag;
}
function apbct_add_admin_ip_to_swf_whitelist($user)
{
global $apbct;
$user = ! $user instanceof WP_User ? apbct_wp_get_current_user() : $user;
$ip = Helper::ipGet('real', true);
if (
$apbct->settings['sfw__enabled'] && // Break if the SpamFireWall is inactive
Server::isGet() &&
! apbct_wp_doing_cron() &&
is_object($user) &&
in_array('administrator', (array)$user->roles, true) &&
Cookie::get('ct_sfw_ip_wl') !== md5($ip . $apbct->api_key) &&
SFW::updateWriteToDbExclusions(DB::getInstance(), APBCT_TBL_FIREWALL_DATA_PERSONAL, array($ip)) &&
apbct_private_list_add($ip) &&
! headers_sent()
) {
Cookie::set(
'ct_sfw_ip_wl',
md5($ip . $apbct->api_key),
time() + 86400 * 30,
'/',
'',
null,
true,
'Lax'
);
}
}
function apbct_private_list_add($ip)
{
global $apbct;
if ( Helper::ipValidate($ip) ) {
$result = API::methodPrivateListAddSfwWl($apbct->data['user_token'], $ip, $apbct->data['service_id']);
return empty($result['error']);
}
return false;
}
/**
* Hide website field from standard comments form
*/
add_filter('comment_form_default_fields', 'apbct__change_type_website_field', 999, 1);
function apbct__change_type_website_field($fields)
{
global $apbct;
if ( isset($apbct->settings['comments__hide_website_field']) && $apbct->settings['comments__hide_website_field'] ) {
if (
!empty($fields['url']) &&
strpos($fields['url'], 'input id=') !== false
) {
$fields['url'] = '<input id="honeypot-field-url" style="display: none;" autocomplete="off" name="url" type="text" value="" size="30" maxlength="200" />';
}
$theme = wp_get_theme();
if ( isset($theme->template) && $theme->template === 'dt-the7' ) {
$fields['url'] = '<input id="honeypot-field-url" autocomplete="off" name="url" type="text" value="" size="30" maxlength="200" /></div>';
}
}
return $fields;
}
/**
* The function determines whether it is necessary
* to conduct a general check of the post request
*
* @return boolean
*/
function apbct_need_to_process_unknown_post_request()
{
global $apbct;
/** Exclude Ajax requests */
if ( apbct_is_ajax() ) {
return false;
}
/** Bitrix24 contact form */
if ( $apbct->settings['forms__general_contact_forms_test'] == 1 &&
! empty(Post::get('your-phone')) &&
! empty(Post::get('your-email')) &&
! empty(Post::get('your-message'))
) {
return true;
}
/** VFB_Pro integration */
if (
! empty($_POST) &&
$apbct->settings['forms__contact_forms_test'] == 1 &&
empty(Post::get('ct_checkjs_cf7')) &&
apbct_is_plugin_active('vfb-pro/vfb-pro.php') &&
! empty(Post::get('_vfb-form-id'))
) {
return true;
}
/** Integration with custom forms */
if (
! empty($_POST) &&
apbct_custom_forms_trappings()
) {
return true;
}
if (
$apbct->settings['forms__general_contact_forms_test'] == 1 &&
empty(Post::get('ct_checkjs_cf7')) &&
! apbct_is_direct_trackback()
) {
return true;
}
if ( apbct_is_user_enable() ) {
if (
$apbct->settings['forms__general_contact_forms_test'] == 1 &&
! Post::get('comment_post_ID') &&
! Get::get('for') &&
! apbct_is_direct_trackback()
) {
return true;
}
}
return false;
}
/**
* Recursive. Check all post data for ct_no_cookie_hidden_field data.
*
* @param array $data
* @param int $level Current recursion level
* @param array $array_mapping
*
* @return array|false
*/
function apbct_check_post_for_no_cookie_data($data = array(), $level = 0, $array_mapping = array())
{
//top level check
if ( Post::get('ct_no_cookie_hidden_field') ) {
return array('data' => Post::get('ct_no_cookie_hidden_field'), 'mapping' => array('ct_no_cookie_hidden_field'));
}
$array = empty($data) ? $_POST : $data;
//recursion limit
if ( $level > 5 ) {
return false;
}
foreach ( $array as $key => $value ) {
if ( is_array($value) ) {
$array_mapping[] = $key;
$level++;
return apbct_check_post_for_no_cookie_data($value, $level, $array_mapping);
}
if ( strpos((string)$key, 'ct_no_cookie_hidden_field') !== false || strpos($value, '_ct_no_cookie_data_') !== false ) {
$array_mapping[] = $key;
return array('data' => $value, 'mapping' => $array_mapping);
}
}
return array('data' => false, 'mapping' => null);
}
/**
* Filter POST for no_cookie_data for cases if POST mapping detected in apbct_check_post_for_no_cookie_data
* @param array $map a POST mapping where no cookie data has been found, mapping level limit is 5 (important)
* @psalm-suppress PossiblyUndefinedIntArrayOffset
*/
function apbct_filter_post_no_cookie_data($map)
{
//todo if we need to increase recursion limit , there is no other way except of eval constructor usage
$cleared_post = $_POST;
if ( !is_array($map) || empty($map) || count($map) > 5 ) {
return;
}
try {
switch ( count($map) ) {
case 1:
$query_cleared = apbct_clear_query_from_service_fields(
$cleared_post [$map[0]],
'ct_no_cookie_hidden_field'
);
if (false === $query_cleared) {
unset($cleared_post [$map[0]]);
} else {
$cleared_post [$map[0]] = $query_cleared;
}
break;
case 2:
$query_cleared = apbct_clear_query_from_service_fields(
$cleared_post [$map[0]] [$map[1]],
'ct_no_cookie_hidden_field'
);
if (false === $query_cleared) {
unset($cleared_post [$map[0]] [$map[1]]);
} else {
$cleared_post [$map[0]] [$map[1]] = $query_cleared;
}
break;
case 3:
$query_cleared = apbct_clear_query_from_service_fields(
$cleared_post [$map[0]] [$map[1]] [$map[2]],
'ct_no_cookie_hidden_field'
);
if (false === $query_cleared) {
unset($cleared_post [$map[0]] [$map[1]] [$map[2]]);
} else {
$cleared_post [$map[0]] [$map[1]] [$map[2]] = $query_cleared;
}
break;
case 4:
$query_cleared = apbct_clear_query_from_service_fields(
$cleared_post [$map[0]] [$map[1]] [$map[2]] [$map[3]],
'ct_no_cookie_hidden_field'
);
if (false === $query_cleared) {
unset($cleared_post [$map[0]] [$map[1]] [$map[2]] [$map[3]]);
} else {
$cleared_post [$map[0]] [$map[1]] [$map[2]] [$map[3]] = $query_cleared;
}
break;
case 5:
$query_cleared = apbct_clear_query_from_service_fields(
$cleared_post [$map[0]] [$map[1]] [$map[2]] [$map[3]] [$map[4]],
'ct_no_cookie_hidden_field'
);
if (false === $query_cleared) {
unset($cleared_post [$map[0]] [$map[1]] [$map[2]] [$map[3]] [$map[4]]);
} else {
$cleared_post [$map[0]] [$map[1]] [$map[2]] [$map[3]] [$map[4]] = $query_cleared;
}
break;
}
$_POST = $cleared_post;
} catch ( Exception $e ) {
return;
}
}
/**
* Try to clear POST key from service records if they are persist in query encoded string.
* <p>For example, function will return <b>"some_field=some_value"</b> if $query_string = <b>"some_field=some_value&ct_no_cookie_hidden_field=some_value"</b>
* @param $query_string
* @param $service_field_name string Service record name. If empty, any known records types will be cleared:
* <ul>
* <li>ct_bot_detector_event_token</li>
* <li>apbct_visible_fields</li>
* <li>ct_no_cookie_hidden_field</li>
* </ul>
* @return false|string
*/
function apbct_clear_query_from_service_fields($query_string, $service_field_name = '')
{
$pattern = empty($service_field_name)
? '/(&?ct_bot_detector_event_token=|&?apbct_visible_fields=|&?ct_no_cookie_hidden_field=)/'
: '/&?' . $service_field_name . '=/';
if (preg_match($pattern, $query_string)) {
parse_str($query_string, $query);
if ( empty($service_field_name) ) {
//clear all known service fields
unset($query['ct_bot_detector_event_token']);
unset($query['apbct_visible_fields']);
unset($query['ct_no_cookie_hidden_field']);
} else {
unset($query[$service_field_name]);
}
return http_build_query($query);
}
return false;
}
/**
* Main entry function to collect no cookie data.
*/
function apbct_form__get_no_cookie_data($preprocessed_data = null, $need_filter = true)
{
global $apbct;
$flag = null;
$no_cookie_data = apbct_check_post_for_no_cookie_data($preprocessed_data);
if ( $need_filter && !empty($no_cookie_data['mapping']) ) {
apbct_filter_post_no_cookie_data($no_cookie_data['mapping']);
}
if ( $no_cookie_data && !empty($no_cookie_data['data']) && $apbct->data['cookies_type'] === 'none' ) {
$flag = \Cleantalk\ApbctWP\Variables\NoCookie::setDataFromHiddenField($no_cookie_data['data']);
}
//set a flag of success
$apbct->stats['no_cookie_data_taken'] = $flag;
//set a source if available
if ( !empty($no_cookie_data['mapping']) && is_array($no_cookie_data['mapping']) ) {
$apbct->stats['no_cookie_data_post_source'] = '[' . implode('][', $no_cookie_data['mapping']) . ']';
}
$apbct->save('stats');
}
/**
* API method "service_template_get" response validator.
* @param string $template_id
* @param array $template_get_result
* @return array template_name - name from response, options_site - site options from response
*/
function apbct_validate_api_response__service_template_get($template_id, $template_get_result)
{
$services_templates_get_error = '';
$options_site = null;
$template_name = '';
if ( empty($template_get_result) || !is_array($template_get_result) ) {
throw new InvalidArgumentException('Parse services_templates_get API error: wrong services_templates_get response');
}
if ( array_key_exists('error', $template_get_result) ) {
throw new InvalidArgumentException('Parse services_templates_get API error: ' . $template_get_result['error']);
}
foreach ( $template_get_result as $_key => $template ) {
if ( empty($template['template_id']) ) {
$services_templates_get_error = 'Parse services_templates_get API error: template_id is empty';
break;
}
if ( $template['template_id'] === (int)$template_id ) {
if ( empty($template['options_site']) ) {
$services_templates_get_error = 'Parse services_templates_get API error: options_site is empty';
break;
}
if ( !is_string($template['options_site']) ) {
$services_templates_get_error = 'Parse services_templates_get API error: options_site is not a string';
break;
}
$options_site = json_decode($template['options_site'], true);
$template_name = !empty($template['name']) ? htmlspecialchars($template['name']) : 'N\A';
if ( $options_site === false || !is_array($options_site)) {
$services_templates_get_error = 'Parse services_templates_get API error: options_site JSON decode error';
break;
}
}
}
if ( !empty($services_templates_get_error) ) {
throw new InvalidArgumentException($services_templates_get_error);
}
if ( empty($options_site) ) {
throw new InvalidArgumentException('Parse services_templates_get API error: no such template_id found in APi response ' . $template_id);
}
return array(
'template_name' => $template_name,
'options_site' => $options_site
);
}
/**
* Set new settings template called by remote call.
* @param string $template_id - template id that setting up
* @param array $options_template_data - validated plugin options from cloud
* @param string $api_key - current site api key
* @return string - JSON string of result
*/
function apbct_rc__service_template_set($template_id, array $options_template_data, $api_key)
{
$templates_object = new CleantalkSettingsTemplates($api_key);
$settings_set_result = $templates_object->setPluginOptions(
$template_id,
isset($options_template_data['template_name']) ? $options_template_data['template_name'] : '',
isset($options_template_data['options_site']) ? $options_template_data['options_site'] : ''
);
$result = $settings_set_result
? json_encode(array('OK' => 'Settings updated'))
: json_encode(array('ERROR' => 'Internal settings updating error'));
return $result !== false ? $result : '{"ERROR":"Internal JSON encoding error"}';
}
/**
* Remove CleanTalk service data from super global variables.
* Attention! This function should be called after(!) CleanTalk request processing.
* @param array $superglobal $_POST | $_REQUEST
* @param string $type post|request
* @return array cleared array of super global
*/
function apbct_clear_superglobal_service_data($superglobal, $type)
{
$fields_to_clear = array(
'apbct_visible_fields',
);
$cleared_superglobal = $superglobal;
switch ($type) {
case 'post':
// Magnesium Quiz special $_request clearance || Uni CPO
if (
(apbct_is_plugin_active('magnesium-quiz/magnesium-quiz.php')) ||
(apbct_is_plugin_active('uni-woo-custom-product-options/uni-cpo.php')) ||
(apbct_is_plugin_active('nex-forms/main.php'))
) {
$fields_to_clear[] = 'ct_bot_detector_event_token';
$fields_to_clear[] = 'ct_no_cookie_hidden_field';
$fields_to_clear[] = 'apbct_event_id';
$fields_to_clear[] = 'apbct__email_id';
}
// It is a service field. Need to be deleted before the processing.
break;
case 'request':
//Optima Express special $_request clearance
if ( (apbct_is_plugin_active('optima-express/iHomefinder.php')) ) {
$fields_to_clear[] = 'ct_no_cookie_hidden_field';
}
if ( (apbct_is_plugin_active('uni-woo-custom-product-options/uni-cpo.php')) ) {
$fields_to_clear[] = 'ct_bot_detector_event_token';
$fields_to_clear[] = 'ct_no_cookie_hidden_field';
$fields_to_clear[] = 'apbct_event_id';
$fields_to_clear[] = 'apbct__email_id';
}
break;
}
$cleared_superglobal = apbct_clear_array_fields_recursive($cleared_superglobal, $fields_to_clear);
return $cleared_superglobal;
}
/**
* Clear array from fields by preset
* @param array $array
* @param string[] $preset_of_fields_to_clear - array of fields to clear, look for strpos in the key of array
*
* @return array
*/
function apbct_clear_array_fields_recursive($array, $preset_of_fields_to_clear = array())
{
$cleared = is_array($array) ? $array : array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$cleared[$key] = apbct_clear_array_fields_recursive($value, $preset_of_fields_to_clear);
} else if (is_string($key) ) {
foreach ($preset_of_fields_to_clear as $field) {
if (strpos($key, $field) !== false) {
unset($cleared[$key]);
}
}
}
}
return $cleared;
}
/**
* Check whether the request is AMP
*
* @return bool
*/
function apbct_is_amp_request()
{
$result = false;
$amp_options = get_option('amp-options');
if (apbct_is_plugin_active('amp/amp.php') &&
$amp_options &&
isset($amp_options['paired_url_structure'])
) {
$amp_paired_type = $amp_options['paired_url_structure'];
switch ($amp_paired_type) {
case 'query_var':
$result = apbct_is_in_uri('?amp=1') ? true : false;
break;
case 'path_suffix':
$result = apbct_is_in_uri('/amp/') ? true : false;
break;
case 'legacy_transitional':
$result = apbct_is_in_uri('?amp') ? true : false;
break;
case 'legacy_reader':
$result = apbct_is_in_uri('/amp/') || apbct_is_in_uri('?amp') ? true : false;
}
}
return $result;
}
/**
* Try to get event token from params->post->alt.cookies
*
* @return string
*/
function apbct_get_event_token($params)
{
global $ct_rest_middleware_event_token;
if (!empty($params['event_token'])) {
return TT::toString($params['event_token']);
}
if (isset($ct_rest_middleware_event_token) && !empty($ct_rest_middleware_event_token)) {
return TT::toString($ct_rest_middleware_event_token);
}
return !empty(Post::getString('ct_bot_detector_event_token'))
? Post::getString('ct_bot_detector_event_token')
: Cookie::getString('ct_bot_detector_event_token');
}
/**
* Do prepare exclusions for skippping bot-detector event token field.
* @return string JSOn
*/
function apbct__bot_detector_get_prepared_exclusion()
{
global $apbct;
$bot_detector_exclusions = array();
//start exclusion there
//todo if do need to add a built-ib exclusion, use $exlusion_format
//set regexp to chek within attributes
// $exlusion_format = array(
// 'exclusion_id' => '',
// 'signs_to_check' => array(
// 'form_attributes' => '',
// 'form_children_attributes' => '',
// 'form_parent_attributes' => ''
// )
// );
if ($apbct->settings['exclusions__bot_detector']) {
$bot_detector_exclusions = array_merge(
$bot_detector_exclusions,
apbct__bot_detector_get_custom_exclusion_from_settings()
);
}
//start validate
$bot_detector_exclusions_valid = array();
foreach ($bot_detector_exclusions as $exclusion) {
if (
empty($exclusion['exclusion_id']) ||
(
empty($exclusion['signs_to_check']['form_attributes']) &&
empty($exclusion['signs_to_check']['form_children_attributes']) &&
empty($exclusion['signs_to_check']['form_parent_attributes'])
)
) {
continue;
}
$bot_detector_exclusions_valid[] = $exclusion;
}
//prepare for early localize
$bot_detector_exclusions_valid = json_encode($bot_detector_exclusions_valid);
return $bot_detector_exclusions_valid !== false ? $bot_detector_exclusions_valid : '{}';
}
function apbct__bot_detector_get_fired_exclusions()
{
return Cookie::get('ct_bot_detector_form_exclusion');
}
/**
* Return bot detector frontend data log from Alt Sessions if data found.
* Format: JSON.
*
* @return string JSON encoded bot detector frontend data log.
*/
function apbct__bot_detector_get_fd_log()
{
$result = array(
'plugin_status' => 'OK',
'error_msg' => '',
'frontend_data_log' => ''
);
// Initialize result array with default values
if (defined('APBCT_DO_NOT_COLLECT_FRONTEND_DATA_LOGS')) {
$result['plugin_status'] = 'OK';
$result['error_msg'] = 'bot detector logs collection is disabled via constant definition';
return json_encode($result);
}
try {
if ( ! apbct__is_bot_detector_enabled() ) {
throw new \Exception('bot detector library usage is disabled');
}
// Retrieve bot detector frontend data log from Alt Sessions
$alt_sessions_fd_log = AltSessions::get('ct_bot_detector_frontend_data_log');
// Check if the retrieved data is a string
if ( !is_string($alt_sessions_fd_log) || '' === $alt_sessions_fd_log ) {
throw new \Exception('no log found in alt sessions');
}
// Encode the retrieved data to JSON format
$param_bot_detector_fd_log = json_decode($alt_sessions_fd_log, true);
// Check if the JSON encoding was successful
if ( empty($param_bot_detector_fd_log) ) {
throw new \Exception('can not decode data from alt sessions');
}
} catch (Exception $e) {
$result['plugin_status'] = 'ERROR';
$result['error_msg'] = $e->getMessage();
return json_encode($result);
}
$result['frontend_data_log'] = $param_bot_detector_fd_log;
// Return the result as a JSON encoded string
return json_encode($result);
}
function apbct__bot_detector_get_custom_exclusion_from_settings()
{
global $apbct;
$exlusion_format = array(
'exclusion_id' => '',
'signs_to_check' => array(
'form_attributes' => '',
'form_children_attributes' => '',
'form_parent_attributes' => ''
)
);
$exclusions = array();
if (!$apbct->settings['exclusions__bot_detector']) {
return $exclusions;
}
foreach ($exlusion_format['signs_to_check'] as $sign => $_val) {
$setting_name = 'exclusions__bot_detector__' . $sign;
if (!empty($apbct->settings[$setting_name])) {
$regexps = explode(',', $apbct->settings[$setting_name]);
for ( $i = 0; $i < count($regexps); $i++ ) {
$form_exclusion = $exlusion_format;
$form_exclusion['exclusion_id'] = 'exclusion_' . $i;
$form_exclusion['signs_to_check'][$sign] = $regexps[$i];
$exclusions[] = $form_exclusion;
}
}
}
return $exclusions;
}
/**
* Check if Bot-Detector is enabled/disabled
*
* @return bool
*/
function apbct__is_bot_detector_enabled()
{
global $apbct;
// Constant is preferred
if ( isset($apbct->service_constants->bot_detector_enabled) && $apbct->service_constants->bot_detector_enabled->isDefined() ) {
return (bool) $apbct->service_constants->bot_detector_enabled->getValue();
}
// Check by $apbct->data
if ( isset($apbct->data['bot_detector_enabled']) ) {
return (bool) $apbct->data['bot_detector_enabled'];
}
// By default - enabled
return true;
}