FileMaster
Search
Toggle Dark Mode
Home
/
.
/
wp-content
/
plugins
/
cleantalk-spam-protect
/
inc
Edit File: 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::get('ct_checkjs')), true) ? 1 : apbct_js_test(TT::toString(Post::get('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() { global $apbct; $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 ( TT::toString($apbct->settings['data__bot_detector_enabled']) === '0') { 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; }
Save
Back