File: //home/swifizcd/julnohub.com.ng/wp-content/plugins/cleantalk-spam-protect/cleantalk.php
<?php
/*
Plugin Name: Anti-Spam by CleanTalk
Plugin URI: https://cleantalk.org
Description: Max power, all-in-one, no Captcha, premium anti-spam plugin. No comment spam, no registration spam, no contact spam, protects any WordPress forms.
Version: 6.76
Author: CleanTalk - Anti-Spam Protection <welcome@cleantalk.org>
Author URI: https://cleantalk.org
Text Domain: cleantalk-spam-protect
Domain Path: /i18n
*/
use Cleantalk\Antispam\ProtectByShortcode;
use Cleantalk\ApbctWP\Activator;
use Cleantalk\ApbctWP\AdminNotices;
use Cleantalk\ApbctWP\ContactsEncoder\ContactsEncoder;
use Cleantalk\ApbctWP\Antispam\ForceProtection;
use Cleantalk\ApbctWP\API;
use Cleantalk\ApbctWP\CleantalkRealPerson;
use Cleantalk\ApbctWP\CleantalkUpgrader;
use Cleantalk\ApbctWP\CleantalkUpgraderSkin;
use Cleantalk\ApbctWP\CleantalkUpgraderSkinDeprecated;
use Cleantalk\ApbctWP\Cron;
use Cleantalk\ApbctWP\DB;
use Cleantalk\ApbctWP\Deactivator;
use Cleantalk\ApbctWP\Firewall\AntiCrawler;
use Cleantalk\ApbctWP\Firewall\AntiFlood;
use Cleantalk\ApbctWP\Firewall\SFW;
use Cleantalk\ApbctWP\Firewall\SFWUpdateHelper;
use Cleantalk\ApbctWP\Helper;
use Cleantalk\ApbctWP\RemoteCalls;
use Cleantalk\ApbctWP\RequestParameters\RequestParameters;
use Cleantalk\ApbctWP\RequestParameters\SubmitTimeHandler;
use Cleantalk\ApbctWP\RestController;
use Cleantalk\ApbctWP\Sanitize;
use Cleantalk\ApbctWP\State;
use Cleantalk\ApbctWP\Transaction;
use Cleantalk\ApbctWP\UpdatePlugin\DbTablesCreator;
use Cleantalk\ApbctWP\Variables\Cookie;
use Cleantalk\ApbctWP\Variables\Get;
use Cleantalk\ApbctWP\Variables\Post;
use Cleantalk\ApbctWP\Variables\Request;
use Cleantalk\ApbctWP\Variables\Server;
use Cleantalk\Common\ContactsEncoder\Dto\Params;
use Cleantalk\Common\DNS;
use Cleantalk\Common\Firewall;
use Cleantalk\Common\Schema;
use Cleantalk\Common\TT;
// Prevent direct call
if ( ! defined('ABSPATH') ) {
die('Not allowed!');
}
global $apbct, $wpdb, $pagenow;
$cleantalk_executed = false;
/**
* Define common const.
*/
$plugin_info = get_file_data(__FILE__, array('Version' => 'Version', 'Name' => 'Plugin Name',));
define('APBCT_NAME', isset($plugin_info['Name']) ? $plugin_info['Name'] : 'Anti-Spam by CleanTalk');
define('APBCT_VERSION', isset($plugin_info['Version']) ? $plugin_info['Version'] : '1.0.0');
define('APBCT_URL_PATH', plugins_url('', __FILE__)); //HTTP path. Plugin root folder without '/'.
define('APBCT_CSS_ASSETS_PATH', plugins_url('css', __FILE__)); //CSS assets path. Plugin root folder without '/'.
define('APBCT_JS_ASSETS_PATH', plugins_url('js', __FILE__)); //JS assets path. Plugin root folder without '/'.
define('APBCT_IMG_ASSETS_PATH', plugins_url('inc/images', __FILE__)); //IMAGES assets path. Plugin root folder without '/'.
define('APBCT_DIR_PATH', dirname(__FILE__) . '/'); //System path. Plugin root folder with '/'.
define('APBCT_PLUGIN_BASE_NAME', plugin_basename(__FILE__)); //Plugin base name.
define(
'APBCT_CASERT_PATH',
file_exists(ABSPATH . WPINC . '/certificates/ca-bundle.crt') ? ABSPATH . WPINC . '/certificates/ca-bundle.crt' : ''
); // SSL Serttificate path
/**
* Define options names const.
*/
define('APBCT_DATA', 'cleantalk_data'); // Option name with different plugin data.
define('APBCT_SETTINGS', 'cleantalk_settings'); // Option name with plugin settings.
define('APBCT_NETWORK_SETTINGS', 'cleantalk_network_settings'); // Option name with plugin network settings.
define('APBCT_JS_ERRORS', 'cleantalk_js_errors'); // Option name with js errors. Empty by default.
/**
* Define service const.
*/
define('APBCT_REMOTE_CALL_SLEEP', 5); // Minimum time between remote call
define('APBCT_WPMS', (is_multisite() ? true : false)); // WordPress Multisite - if WMPS is enabled
define('APBCT_LANG_REL_PATH', 'cleantalk-spam-protect/i18n');
if ( ! defined('CLEANTALK_PLUGIN_DIR') ) {
define('CLEANTALK_PLUGIN_DIR', dirname(__FILE__) . '/');
}
/**
* Require PHP patch.
*/
require_once(CLEANTALK_PLUGIN_DIR . 'lib/cleantalk-php-patch.php'); // Pathces fpr different functions which not exists
/**
* Require the Autoloader
*/
require_once(CLEANTALK_PLUGIN_DIR . 'lib/autoloader.php');
if (!defined('APBCT_IS_LOCALHOST')) {
define('APBCT_IS_LOCALHOST', in_array(Server::getDomain(), array('lc', 'loc', 'lh', 'test')));
}
/**
* Define API params const.
*/
$plugin_version__agent = APBCT_VERSION;
// Converts version to xxx.xxx.xx-dev to xxx.xxx.2xx and xxx.xxx.xx-fix to xxx.xxx.1xx
if ( preg_match('@^(\d+)\.(\d+)\.(\d{1,2})-(dev|fix)$@', $plugin_version__agent, $m) ) {
$major_version = TT::getArrayValueAsString($m, 1);
$minor_version = TT::getArrayValueAsString($m, 2);
$branch_sub = TT::getArrayValueAsString($m, 4) === 'dev' ? '2' : '1';
$padded = str_pad(
TT::getArrayValueAsString($m, 3),
2,
'0',
STR_PAD_LEFT
);
$plugin_version__agent = $major_version . '.' . $minor_version . '.' . $branch_sub . $padded;
}
define('APBCT_AGENT', 'wordpress-' . $plugin_version__agent); // Prepared agent
if ( defined('CLEANTALK_SERVER') ) {
define('APBCT_MODERATE_URL', 'https://moderate.' . CLEANTALK_SERVER);
if ( ! defined('CLEANTALK_API_URL') ) {
define('CLEANTALK_API_URL', 'https://api.' . CLEANTALK_SERVER);
}
} else {
define('APBCT_MODERATE_URL', 'https://moderate.cleantalk.org'); // Api URL
}
define('APBCT_BOT_DETECTOR_SCRIPT_URL', 'https://fd.cleantalk.org/ct-bot-detector-wrapper.js');
/**
* Require base classes.
*/
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-pluggable.php'); // Pluggable functions
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-common.php');
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-wpcli.php');
/**
* Global state handle.
*/
// Global ArrayObject with settings and other global variables
$apbct = new State('cleantalk', array('settings', 'data', 'errors', 'remote_calls', 'stats', 'fw_stats'));
// Init plugin basename.
$apbct->base_name = 'cleantalk-spam-protect/cleantalk.php';
// Identify plugin execution
$apbct->plugin_request_id = md5(microtime());
// Init logos.
$apbct->logo = plugin_dir_url(__FILE__) . 'inc/images/logo.png';
$apbct->logo__small = plugin_dir_url(__FILE__) . 'inc/images/logo_small.png';
$apbct->logo__small__colored = plugin_dir_url(__FILE__) . 'inc/images/logo_color.png';
// Init Account status
$apbct->white_label = $apbct->network_settings['multisite__white_label'];
$apbct->allow_custom_key = $apbct->network_settings['multisite__work_mode'] != 2;
$apbct->plugin_name = $apbct->network_settings['multisite__white_label__plugin_name'] ? $apbct->network_settings['multisite__white_label__plugin_name'] : APBCT_NAME;
$apbct->api_key = ! APBCT_WPMS || $apbct->allow_custom_key || $apbct->white_label ? $apbct->settings['apikey'] : $apbct->network_settings['apikey'];
$apbct->key_is_ok = ! APBCT_WPMS || $apbct->allow_custom_key || $apbct->white_label ? $apbct->data['key_is_ok'] : $apbct->network_data['key_is_ok'];
$apbct->moderate = ! APBCT_WPMS || $apbct->allow_custom_key || $apbct->white_label ? $apbct->data['moderate'] : $apbct->network_data['moderate'];
// Init counter
$apbct->data['user_counter']['since'] = isset($apbct->data['user_counter']['since'])
? $apbct->data['user_counter']['since']
: date('d M');
// Init SFW update data
$apbct->firewall_updating = (bool)$apbct->fw_stats['firewall_updating_id'];
$apbct->data['sfw_load_type'] = (!APBCT_WPMS || is_main_site() || $apbct->network_settings['multisite__work_mode'] === 2) ? 'all' : 'personal';
$apbct->saveData();
// Init settings link
$apbct->settings_link = is_network_admin() ? 'settings.php?page=cleantalk' : 'options-general.php?page=cleantalk';
// Connection reports
$apbct->setConnectionReports();
// SFW update sentinel
$apbct->setSFWUpdateSentinel();
// User IP Keeper - used for checkers
$apbct->setLoginIPKeeper();
add_action('wp_login', 'apbct_wp_login_actions', 10, 2);
/**
* Actions for hook 'wp-login'.
* @param $user_login
* @param $wp_user
*
* @return void
*/
function apbct_wp_login_actions($_user_login, $wp_user)
{
global $apbct;
$apbct->login_ip_keeper->addUserIP($wp_user);
apbct_add_admin_ip_to_swf_whitelist($wp_user);
}
// Disabling comments
if ( $apbct->settings['comments__disable_comments__all'] || $apbct->settings['comments__disable_comments__posts'] || $apbct->settings['comments__disable_comments__pages'] || $apbct->settings['comments__disable_comments__media'] ) {
\Cleantalk\Antispam\DisableComments::getInstance();
}
// Email encoder
if (
$apbct->key_is_ok &&
( ! is_admin() || apbct_is_ajax() ) &&
current_action() !== 'wp_ajax_delete-plugin'
) {
$skip_email_encode = false;
if (!empty($_POST)) {
foreach ( $_POST as $param => $_value ) {
if ( strpos((string)$param, 'et_pb_contactform_submit') === 0 ) {
$skip_email_encode = true;
break;
}
}
}
$contacts_encoder = apbctGetContactsEncoder();
if ($apbct->settings['data__email_decoder'] && !$skip_email_encode && !apbct_is_amp_request()) {
// Encode content
$contacts_encoder->runEncoding();
// Email Encoder ajax handlers for decoding
$contacts_encoder->registerAjaxRoute();
}
// Force protection to avoid spam from bots without javascript
if ($apbct->settings['forms__force_protection']) {
ForceProtection::getInstance();
}
}
// The Real Person
if ( $apbct->settings['comments__the_real_person'] ) {
new CleantalkRealPerson();
}
add_action('rest_api_init', 'apbct_register_my_rest_routes');
function apbct_register_my_rest_routes()
{
$controller = new RestController();
$controller->register_routes();
}
// Register hooks for AJAX requests
\Cleantalk\ApbctWP\HooksRegistrar::registerAjaxHooks($apbct->ajax_service);
// Database prefix
global $wpdb, $wp_version;
$apbct->db_prefix = ! APBCT_WPMS || $apbct->allow_custom_key || $apbct->white_label ? $wpdb->prefix : $wpdb->base_prefix;
$apbct->db_prefix = ! $apbct->white_label && defined('CLEANTALK_ACCESS_KEY') ? $wpdb->base_prefix : $wpdb->prefix;
/** @todo HARDCODE FIX */
if ( $apbct->plugin_version === '1.0.0' ) {
$apbct->plugin_version = '5.100';
}
/**
* Do update actions if version is changed
* ! we can`t place this function to the hook "upgrader_process_complete" !
*/
apbct_update_actions();
add_action('init', function () {
global $apbct;
// Self cron
$ct_cron = Cron::getInstance();
$tasks_to_run = $ct_cron->checkTasks(); // Check for current tasks. Drop tasks inner counters.
if (
$tasks_to_run && // There are tasks to run
! RemoteCalls::check() && // Do not do CRON in remote call action
(
! defined('DOING_CRON') ||
(defined('DOING_CRON') && DOING_CRON !== true)
)
) {
$cron_res = $ct_cron->runTasks($tasks_to_run);
if ( is_array($cron_res) ) {
foreach ( $cron_res as $_task => $res ) {
if ( $res === true ) {
$apbct->errorDelete('cron', true);
} else {
$apbct->errorAdd('cron', $res);
}
}
}
}
// Remote calls
if ( RemoteCalls::check() ) {
try {
/**
* Needs to include apbct_settings__validate() for run_service_template_get remote call.
* TODO:Probably we should refactor apbct_settings__validate() to a class feature to use it within autoloader
*/
if ( Get::get('spbc_remote_call_action') === 'run_service_template_get' ) {
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-settings.php');
}
RemoteCalls::perform();
} catch ( Exception $e ) {
die(json_encode(array('ERROR' => $e->getMessage())));
}
}
});
//Delete cookie for admin trial notice
add_action('wp_logout', 'apbct__hook__wp_logout__delete_trial_notice_cookie');
// Set cookie only for public pages and for non-AJAX requests
if ( ! is_admin() && ! apbct_is_ajax() && ! defined('DOING_CRON')
&& ! apbct__is_rest_api_request()
&& empty(Post::get('ct_checkjs_register_form')) // Buddy press registration fix
&& empty(Get::get('ct_checkjs_search_default')) // Search form fix
&& empty(Post::get('action')) //bbPress
&& ! \Cleantalk\Variables\Server::inUri('/favicon.ico') // /favicon request rewritten cookies fix
&& ! apbct__is_wp_rocket_preloader_request()
) {
if ( $apbct->data['cookies_type'] !== 'alternative' ) {
if ( !$apbct->settings['forms__search_test'] && !Get::get('s') ) { //skip cookie set for search form redirect page
add_action('template_redirect', 'apbct_cookie', 2);
}
add_action('template_redirect', 'apbct_store__urls', 2);
add_action('template_redirect', 'apbct_store__page_hits', 2);
}
if (
empty($_POST) &&
$apbct->data['key_is_ok']
) {
if ( (isset($_GET['q']) && $_GET['q'] !== '') || empty($_GET) ) {
apbct_cookie();
}
//store url and hits ignoring GET containment
apbct_store__page_hits();
apbct_store__urls();
}
}
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-public-validate-skip-functions.php');
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-public-validate.php');
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-public.php');
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-public-integrations.php');
// Early checks
if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'wpmlsubscribe') {
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-ajax.php');
ct_ajax_hook();
}
// Iphorm
if (
Post::get('iphorm_ajax') !== '' &&
Post::get('iphorm_id') !== '' &&
Post::get('iphorm_uid') !== ''
) {
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-ajax.php');
ct_ajax_hook();
}
// Facebook
if ( $apbct->settings['forms__general_contact_forms_test'] == 1
&& ( Post::get('action') === 'fb_intialize')
&& ! empty(Post::get('FB_userdata'))
) {
if ( apbct_is_user_enable() ) {
ct_registration_errors(null);
}
}
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-integrations-by-hook.php');
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-integrations-by-class.php');
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-integrations-by-route.php');
// Form protection by shortcode
new ProtectByShortcode();
// WP Delicious integration
add_filter('delicious_recipes_process_registration_errors', 'apbct_wp_delicious', 10, 4);
$js_errors_arr = apbct_check_post_for_no_cookie_data();
if ($js_errors_arr && isset($js_errors_arr['data'])) {
apbct_write_js_errors($js_errors_arr['data']);
}
/**
* @param string $data
* @psalm-suppress UnusedVariable
*/
function apbct_write_js_errors($data)
{
if (!is_string($data) || empty($data)) {
return false;
}
$tmp = substr($data, strlen('_ct_no_cookie_data_'));
$errors = json_decode(base64_decode($tmp), true);
if (!isset($errors['ct_js_errors'])) {
return false;
}
$errors = $errors['ct_js_errors'];
$exist_errors = get_option(APBCT_JS_ERRORS);
if (!$exist_errors) {
return update_option(APBCT_JS_ERRORS, $errors);
}
$errors_collection_msgs = [];
foreach ($exist_errors as $err_index => $err_value) {
array_push($errors_collection_msgs, $err_value['err']['msg']);
}
foreach ($errors as $err_index => $err_value) {
if (!in_array($err_value['err']['msg'], $errors_collection_msgs)) {
array_push($exist_errors, $err_value);
}
}
return update_option(APBCT_JS_ERRORS, $exist_errors);
}
// LearnPress
if (
apbct_is_plugin_active('learnpress/learnpress.php') &&
apbct_is_in_uri('lp-ajax=checkout') &&
sizeof($_POST) > 0
) {
apbct_form__learnpress__testSpam();
}
// Appointment Booking Calendar
if (
apbct_is_plugin_active('appointment-booking-calendar/cpabc_appointments.php') &&
Post::getString('cpabc_appointments_post')
) {
apbct_form__appointment_booking_calendar__testSpam();
}
// OptimizePress
if (
apbct_is_plugin_active('op-dashboard/op-dashboard.php') &&
!empty($_POST)
) {
$is_optin = apbct_is_in_uri('/optin/submit');
$is_reg = apbct_is_in_uri('/users/submit');
if ($is_reg || $is_optin) {
apbct_form__optimizepress__testSpam($is_reg);
}
}
// Mailoptin. Pass without action because url for ajax request is domain.com/any-page/?mailoptin-ajax=subscribe_to_email_list
if (
apbct_is_plugin_active('mailoptin/mailoptin.php') &&
sizeof($_POST) > 0 &&
Get::get('mailoptin-ajax') === 'subscribe_to_email_list'
) {
apbct_form__mo_subscribe_to_email_list__testSpam();
}
// Metform
if (
apbct_is_plugin_active('metform/metform.php') &&
sizeof($_POST) > 0 &&
(
apbct_is_in_uri('/wp-json/metform/') ||
(apbct_get_rest_url_only_path() !== 'index.php' && apbct_is_in_uri(apbct_get_rest_url_only_path() . 'metform/'))
)
) {
apbct_form__metform_subscribe__testSpam();
}
// Memberpress integration
// MemberPress sends mepr_process_signup_form='Y' or '1' — both must trigger the check
if (
!empty($_POST) &&
apbct_is_plugin_active('memberpress/memberpress.php') &&
Post::getString('mepr_process_signup_form') &&
(int)$apbct->settings['forms__registrations_test'] === 1
) {
apbct_memberpress_signup_request_test();
}
// Ninja Forms. Making GET action to POST action
if (
apbct_is_in_uri('admin-ajax.php') &&
sizeof($_POST) > 0 &&
Get::get('action') === 'ninja_forms_ajax_submit'
) {
$_POST['action'] = 'ninja_forms_ajax_submit';
}
// GiveWP without ajax
if (
!empty($_POST) &&
(int)$apbct->settings['forms__contact_forms_test'] === 1 &&
apbct_is_plugin_active('give/give.php') &&
!empty($_POST['give-form-hash']) &&
!empty($_POST['give-form-id'])
) {
apbct_givewp_donate_request_test();
}
// JetformBuilder
if (
!empty($_POST) &&
apbct_is_plugin_active('jetformbuilder/jet-form-builder.php') &&
Get::get('jet_form_builder_submit') === 'submit'
) {
apbct_jetformbuilder_request_test();
}
// DHVC Form
if (
!empty($_POST) &&
apbct_is_plugin_active('dhvc-form/dhvc-form.php') &&
Post::get('dhvc_form') && Post::get('_dhvc_form_nonce')
) {
apbct_dhvcform_request_test();
}
// SeedConfirmPro
if (!empty($_POST) &&
apbct_is_plugin_active('seed-confirm-pro/seed-confirm-pro.php') &&
Post::get('seed_confirm_nonce')
) {
apbct_seedConfirmPro_request_test();
}
// LeakyPaywall
if (!empty($_POST) &&
apbct_is_plugin_active('leaky-paywall/leaky-paywall.php') &&
apbct_is_in_uri('registration-form') &&
Post::get('level_id')
) {
apbct_leakyPaywall_request_test();
}
// SeedProd Coming Soon Page Pro integration
add_action('wp_ajax_seed_cspv5_subscribe_callback', 'apbct_form__seedprod_coming_soon__testSpam', 1);
add_action('wp_ajax_nopriv_seed_cspv5_subscribe_callback', 'apbct_form__seedprod_coming_soon__testSpam', 1);
add_action('wp_ajax_seed_cspv5_contactform_callback', 'apbct_form__seedprod_coming_soon__testSpam', 1);
add_action('wp_ajax_nopriv_seed_cspv5_contactform_callback', 'apbct_form__seedprod_coming_soon__testSpam', 1);
// The 7 theme contact form integration
add_action('wp_ajax_nopriv_dt_send_mail', 'apbct_form__the7_contact_form', 1);
add_action('wp_ajax_dt_send_mail', 'apbct_form__the7_contact_form', 1);
// Custom register form (ticket_id=13668)
add_action('website_neotrends_signup_fields_check', function ($username, $fields) {
$ip = Helper::ipGet('real', false);
$ct_result = ct_test_registration($username, $fields['email'], $ip);
if ( TT::getArrayValueAsInt($ct_result, 'allow') === 0 ) {
ct_die_extended(TT::getArrayValueAsString($ct_result, 'comment'));
}
}, 1, 2);
add_action('elementor/frontend/the_content', 'apbct_form__elementor_pro__addField', 10, 2);
// INEVIO theme integration
add_action('wp_ajax_contact_form_handler', 'apbct_form__inevio__testSpam', 1);
add_action('wp_ajax_nopriv_contact_form_handler', 'apbct_form__inevio__testSpam', 1);
// Enfold Theme contact form
add_filter('avf_form_send', 'apbct_form__enfold_contact_form__test_spam', 4, 10);
// Profile Builder integration
add_filter('wppb_output_field_errors_filter', 'apbct_form_profile_builder__check_register', 1, 3);
// Advanced Classifieds & Directory Pro
add_filter('acadp_is_spam', 'apbct_advanced_classifieds_directory_pro__check_register', 1, 2);
// WP Foro register system integration
add_filter('wpforo_create_profile', 'wpforo_create_profile__check_register', 1, 1);
// HappyForms integration
add_filter('happyforms_validate_submission', 'apbct_form_happyforms_test_spam', 1, 3);
add_filter('happyforms_use_hash_protection', '__return_false');
// Formidable
add_filter('frm_entries_before_create', 'apbct_form__formidable__testSpam', 999999, 2);
add_action('frm_entries_footer_scripts', 'apbct_form__formidable__footerScripts', 20, 2);
add_action('mec_booking_end_form_step_2', function () {
echo "<script>
if (typeof ctPublic.force_alt_cookies == 'undefined' || (ctPublic.force_alt_cookies !== 'undefined' && !ctPublic.force_alt_cookies)) {
ctNoCookieAttachHiddenFieldsToForms();
}
</script>";
});
// Public actions
if ( ! is_admin() && ! apbct_is_ajax() && ! apbct_is_customize_preview() ) {
if (
apbct_is_plugin_active('fluentformpro/fluentformpro.php') &&
(
apbct_is_in_uri('ff_landing=') ||
(
// Load scripts for logged in users if constant is defined
apbct_is_user_logged_in() &&
(defined('APBCT_FF_JS_SCRIPTS_LOAD') &&
APBCT_FF_JS_SCRIPTS_LOAD == true)
)
)
) {
add_action('wp_head', function () {
echo '<script data-pagespeed-no-defer="" src="'
. APBCT_URL_PATH
. '/js/apbct-public-bundle.min.js'
. '?ver=' . APBCT_VERSION . '" id="ct_public_functions-js"></script>';
echo '<script src="' . APBCT_BOT_DETECTOR_SCRIPT_URL . '?ver='
. APBCT_VERSION . '" async id="ct_bot_detector-js" data-wp-strategy="async"></script>';
}, 100);
}
SFWUpdateHelper::processSFWOutdatedError($apbct);
// SpamFireWall check
if ( $apbct->plugin_version == APBCT_VERSION && // Do not call with first start
$apbct->settings['sfw__enabled'] == 1 &&
$apbct->stats['sfw']['last_update_time'] &&
apbct_is_get() &&
! apbct_wp_doing_cron() &&
! Server::inUri('/favicon.ico') &&
! apbct_is_cli()
) {
add_action('init', 'apbct_sfw__init_wrapper', 1);
}
}
// Activation/deactivation functions must be in main plugin file.
// http://codex.wordpress.org/Function_Reference/register_activation_hook
register_activation_hook(__FILE__, 'apbct_activation');
function apbct_activation($network_wide)
{
Activator::activation($network_wide);
}
register_deactivation_hook(__FILE__, 'apbct_deactivation');
function apbct_deactivation($network_wide)
{
Deactivator::deactivation($network_wide);
}
register_uninstall_hook(__FILE__, 'apbct_uninstall');
function apbct_uninstall($network_wide)
{
global $apbct;
$apbct->settings['misc__complete_deactivation'] = 1;
$apbct->saveSettings();
Deactivator::deactivation($network_wide);
}
// Hook for newly added blog
if ( version_compare($wp_version, '5.1') >= 0 ) {
add_action('wp_initialize_site', 'apbct_activation__new_blog', 10, 2);
add_action('wp_uninitialize_site', 'apbct_wpms__delete_blog', 10, 1);
} else {
add_action('wpmu_new_blog', 'apbct_activation__new_blog__deprecated', 10, 6);
add_action('delete_blog', 'apbct_wpms__delete_blog__deprecated', 10, 2);
}
function apbct_activation__new_blog__deprecated($blog_id, $_user_id, $_domain, $_path, $_site_id, $_meta)
{
Activator::activation(false, $blog_id);
}
function apbct_activation__new_blog(WP_Site $new_site, $_args)
{
Activator::activation(false, $new_site->blog_id);
}
function apbct_wpms__delete_blog__deprecated($blog_id, $_drop)
{
apbct_sfw__delete_tables($blog_id);
}
function apbct_wpms__delete_blog(WP_Site $old_site)
{
apbct_sfw__delete_tables($old_site->blog_id);
}
// Async loading for JavaScript
add_filter('script_loader_tag', 'apbct_add_async_attribute', 10, 3);
// Redirect admin to plugin settings.
if ( ! defined('WP_ALLOW_MULTISITE') || (defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE == false) ) {
add_action('admin_init', 'apbct_plugin_redirect');
}
// After plugin loaded - to load locale as described in manual
add_action('init', 'apbct_plugin_loaded');
// SiteGround Speed Optimizer: skip cache for URLs with apbct_no_cache.
add_action('plugins_loaded', 'apbct_sgo_optimizer__register_bypass_query_params', 1);
if ( ! empty($apbct->settings['data__use_ajax']) &&
! apbct_is_in_uri('.xml') &&
! apbct_is_in_uri('.xsl')
) {
$apbct->ajax_service->addPublicAction('ct_get_cookie', 'ct_get_cookie');
}
// Admin panel actions
if ( is_admin() || is_network_admin() ) {
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-find-spam.php');
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-admin.php');
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-settings.php');
add_action('admin_init', 'apbct_admin__init', 1);
// Show notices
add_action('admin_init', array(AdminNotices::class, 'showAdminNotices'));
// Register AJAX hooks
add_action('admin_init', function () use ($apbct) {
\Cleantalk\ApbctWP\HooksRegistrar::registerAdminHooks($apbct->ajax_service);
});
if ( ! (defined('DOING_AJAX') && DOING_AJAX) ) {
add_action('admin_enqueue_scripts', 'apbct_admin__enqueue_scripts');
add_action('admin_menu', 'apbct_settings_add_page');
add_action('network_admin_menu', 'apbct_settings_add_page');
//Show widget only if enables and not IP license
if ( $apbct->settings['wp__dashboard_widget__show'] && ! $apbct->moderate_ip ) {
add_action('wp_dashboard_setup', 'ct_dashboard_statistics_widget');
}
}
if ( apbct_is_ajax() || Post::get('cma-action') !== '' ) {
$_cleantalk_hooked_actions = array();
$_cleantalk_ajax_actions_to_check = array();
global $apbct_active_integrations;
if (isset($apbct_active_integrations) && is_array($apbct_active_integrations)) {
$integrated_hooks = array_column($apbct_active_integrations, 'hook');
foreach ( $integrated_hooks as $hook ) {
if ( is_array($hook) ) {
foreach ( $hook as $_item ) {
$_cleantalk_hooked_actions[] = $_item;
}
} else {
$_cleantalk_hooked_actions[] = $hook;
}
}
}
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-ajax.php');
// Feedback for comments
if ( Post::get('action') === 'ct_feedback_comment' ) {
add_action('wp_ajax_nopriv_ct_feedback_comment', 'apbct_comment__send_feedback', 1);
add_action('wp_ajax_ct_feedback_comment', 'apbct_comment__send_feedback', 1);
}
if ( Post::get('action') === 'ct_feedback_user' ) {
add_action('wp_ajax_nopriv_ct_feedback_user', 'apbct_user__send_feedback', 1);
add_action('wp_ajax_ct_feedback_user', 'apbct_user__send_feedback', 1);
}
// Check AJAX requests
// if User is not logged in
// if Unknown action or Known action with mandatory check
if (
( ! apbct_is_user_logged_in() || $apbct->settings['data__protect_logged_in'] == 1) &&
Post::get('action') !== '' &&
(
! in_array(Post::get('action'), $_cleantalk_hooked_actions) ||
in_array(Post::get('action'), $_cleantalk_ajax_actions_to_check)
)
) {
add_action('plugins_loaded', 'ct_ajax_hook');
}
//QAEngine Theme answers
if ( intval($apbct->settings['forms__general_contact_forms_test']) ) {
add_filter('et_pre_insert_question', 'ct_ajax_hook', 1, 1);
} // Questions
add_filter('et_pre_insert_answer', 'ct_ajax_hook', 1, 1); // Answers
// Some of plugins to register a users use AJAX context.
add_filter('registration_errors', 'ct_registration_errors', 1, 3);
add_filter('registration_errors', 'ct_check_registration_errors', 999999, 3);
add_action('user_register', 'apbct_user_register');
}
//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'))
) {
ct_contact_form_validate();
}
// Sends feedback to the cloud about comments
// add_action('wp_set_comment_status', 'ct_comment_send_feedback', 10, 2);
// Sends feedback to the cloud about deleted users
if ( $pagenow === 'users.php' ) {
add_action('delete_user', 'apbct_user__delete__hook', 10, 2);
}
if ( $pagenow === 'plugins.php' || apbct_is_in_uri('plugins.php') ) {
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'apbct_admin__plugin_action_links', 10, 2);
add_filter(
'network_admin_plugin_action_links_' . plugin_basename(__FILE__),
'apbct_admin__plugin_action_links',
10,
2
);
add_filter('all_plugins', 'apbct_admin__change_plugin_description');
add_filter('plugin_row_meta', 'apbct_admin__register_plugin_links', 10, 3);
}
// Public pages actions
} else {
add_action('wp_enqueue_scripts', 'ct_enqueue_scripts_public');
add_action('wp_enqueue_scripts', 'ct_enqueue_styles_public');
add_action('login_enqueue_scripts', 'ct_enqueue_styles_public');
// Init action.
add_action('plugins_loaded', 'apbct_init', 1);
// Comments
add_filter('comment_text', 'ct_comment_text');
// Registrations
if ( ! Post::get('wp-submit') ) {
add_action('login_form_register', 'apbct_cookie');
add_action('login_form_register', 'apbct_store__urls');
add_action('login_form_register', 'apbct_store__page_hits');
}
add_action('login_enqueue_scripts', 'apbct_login__scripts');
add_action('register_form', 'ct_register_form');
add_filter('registration_errors', 'ct_registration_errors', 1, 3);
add_filter('registration_errors', 'ct_check_registration_errors', 999999, 3);
add_action('user_register', 'apbct_user_register');
// WordPress Multisite registrations
add_action('signup_extra_fields', 'ct_register_form');
add_filter('wpmu_validate_user_signup', 'ct_registration_errors_wpmu', 10, 3);
// Login form - for notifications only
add_filter('login_message', 'ct_login_message');
// Ait-Themes fix
if ( Get::get('ait-action') === 'register' ) {
$tmp = Post::get('redirect_to');
unset($_POST['redirect_to']);
ct_contact_form_validate();
$_POST['redirect_to'] = $tmp;
}
}
/**
* Wrapper for SpamFireWall check to make if fire on 'init' hook
* @return void
*/
function apbct_sfw__init_wrapper()
{
wp_suspend_cache_addition(true);
apbct_sfw__check();
wp_suspend_cache_addition(false);
}
/**
* Function for SpamFireWall check
*/
function apbct_sfw__check()
{
global $apbct, $spbc, $cleantalk_url_exclusions;
// Turn off the SpamFireWall if current url in the exceptions list and WordPress core pages
if ( ! empty($cleantalk_url_exclusions) && is_array($cleantalk_url_exclusions) ) {
$core_page_to_skip_check = array('/feed');
foreach ( array_merge($cleantalk_url_exclusions, $core_page_to_skip_check) as $v ) {
if ( apbct_is_in_uri($v) ) {
return;
}
}
}
// Skip the check
if ( ! empty(Get::get('access')) ) {
$spbc_settings = get_option('spbc_settings');
$spbc_key = ! empty($spbc_settings['spbc_key']) ? $spbc_settings['spbc_key'] : false;
if ( Get::get('access') === $apbct->api_key || ($spbc_key !== false && Get::get('access') === $spbc_key) ) {
Cookie::set(
'spbc_firewall_pass_key',
md5(Server::get('REMOTE_ADDR') . $spbc_key),
time() + 1200,
'/',
''
);
Cookie::set(
'ct_sfw_pass_key',
md5(Server::get('REMOTE_ADDR') . $apbct->api_key),
time() + 1200,
'/',
''
);
return;
}
unset($spbc_settings, $spbc_key);
}
// Turn off the SpamFireWall if Remote Call is in progress
if ( $apbct->rc_running || ( ! empty($spbc) && $spbc->rc_running) ) {
return;
}
// update mode - skip checking
if ( SFWUpdateHelper::SFWUpdateModeEnabled($apbct)) {
return;
}
// sfw is outdated - skip checking
if ( SFWUpdateHelper::SFWDataOutdated($apbct) ) {
return;
}
$firewall = new Firewall(
DB::getInstance()
);
$sfw_tables_names = SFW::getSFWTablesNames();
if (
!$sfw_tables_names ||
!isset($sfw_tables_names['sfw_personal_table_name'], $sfw_tables_names['sfw_common_table_name'])
) {
add_action('init', function () use ($apbct) {
$apbct->errorAdd(
'sfw',
esc_html__(
'Can not get SFW table names from main blog options',
'cleantalk-spam-protect'
)
);
});
return;
}
$firewall->loadFwModule(
new SFW(
APBCT_TBL_FIREWALL_LOG,
$sfw_tables_names['sfw_personal_table_name'],
array(
'sfw_counter' => $apbct->settings['admin_bar__sfw_counter'],
'api_key' => $apbct->api_key,
'apbct' => $apbct,
'cookie_domain' => parse_url(get_option('home'), PHP_URL_HOST),
'data__cookies_type' => $apbct->data['cookies_type'],
'sfw_common_table_name' => $sfw_tables_names['sfw_common_table_name'],
)
)
);
if ( $apbct->settings['sfw__anti_crawler'] && $apbct->stats['sfw']['entries'] > 50 ) {
$firewall->loadFwModule(
new \Cleantalk\ApbctWP\Firewall\AntiCrawler(
APBCT_TBL_FIREWALL_LOG,
APBCT_TBL_AC_LOG,
array(
'api_key' => $apbct->api_key,
'apbct' => $apbct,
)
)
);
}
if ( $apbct->settings['sfw__anti_flood'] && is_null(apbct_wp_get_current_user()) ) {
$firewall->loadFwModule(
new AntiFlood(
APBCT_TBL_FIREWALL_LOG,
APBCT_TBL_AC_LOG,
array(
'api_key' => $apbct->api_key,
'view_limit' => $apbct->settings['sfw__anti_flood__view_limit'],
'apbct' => $apbct,
)
)
);
}
$firewall->run();
}
/**
* Redirects admin to plugin settings after activation.
* @psalm-suppress UnusedVariable
*/
function apbct_plugin_redirect()
{
global $apbct;
wp_suspend_cache_addition(true);
if (
get_option('ct_plugin_do_activation_redirect', false) &&
delete_option('ct_plugin_do_activation_redirect') &&
! Get::get('activate-multi')
) {
ct_account_status_check(null, false);
apbct_sfw_update__init(3); // Updating SFW
wp_redirect($apbct->settings_link);
}
wp_suspend_cache_addition(false);
}
/**
* @param $event_type
*
* @psalm-suppress UnusedVariable
*/
function ct_add_event($event_type)
{
global $apbct, $cleantalk_executed;
//
// To migrate on the new version of ct_add_event().
//
switch ( $event_type ) {
case '0':
$event_type = 'no';
break;
case '1':
$event_type = 'yes';
break;
}
$current_hour = (int)date('G');
// Updating current hour
if ( $current_hour != $apbct->data['current_hour'] ) {
$apbct->data['current_hour'] = $current_hour;
$apbct->data['array_accepted'][$current_hour] = 0;
$apbct->data['array_blocked'][$current_hour] = 0;
}
//Add 1 to counters
if ( $event_type === 'yes' ) {
$apbct->data['array_accepted'][$current_hour]++;
$apbct->data['admin_bar__all_time_counter']['accepted']++;
$apbct->data['user_counter']['accepted']++;
}
if ( $event_type === 'no' ) {
$apbct->data['array_blocked'][$current_hour]++;
$apbct->data['admin_bar__all_time_counter']['blocked']++;
$apbct->data['user_counter']['blocked']++;
}
$apbct->saveData();
$cleantalk_executed = true;
}
/**
* return new cookie value
*/
function ct_get_cookie()
{
$ct_checkjs_key = ct_get_checkjs_value();
print $ct_checkjs_key;
die();
}
// This action triggered by wp_schedule_single_event( time() + 720, 'apbct_sfw_update__init' );
add_action('apbct_sfw_update__init', 'apbct_sfw_update__init');
/**
* * * * * * SFW UPDATE ACTIONS * * * * * *
*/
/**
* Called by sfw_update remote call
* Starts SFW update and could use a delay before start
*
* @param int $delay
*
* @return bool|string|string[]
*/
function apbct_sfw_update__init($delay = 0)
{
global $apbct;
//do not run sfw update on subsites if mutual key is set
if ($apbct->network_settings['multisite__work_mode'] === 2 && !is_main_site()) {
return false;
}
// Prevent start an update if update is already running and started less than 10 minutes ago
if (
$apbct->fw_stats['firewall_updating_id'] &&
time() - $apbct->fw_stats['firewall_updating_last_start'] < 600 &&
SFWUpdateHelper::updateIsInProgress() &&
! SFWUpdateHelper::updateIsFrozen()
) {
return false;
}
if ( ! $apbct->settings['sfw__enabled'] ) {
return false;
}
$requirements_check = apply_filters('apbct_sfw_update__check_requirements', apbct_sfw_update__check_requirements());
if (true !== $requirements_check) {
return array('error' => $requirements_check);
}
// Get update period for server
$update_period = DNS::getRecord('spamfirewall-ttl-txt.cleantalk.org', true, true);
$update_period = isset($update_period['txt']) ? $update_period['txt'] : 0;
$update_period = (int)$update_period > 14400 ? (int)$update_period : 14400;
if ( $apbct->stats['sfw']['update_period'] != $update_period ) {
$apbct->stats['sfw']['update_period'] = $update_period;
$apbct->save('stats');
}
$sfw_tables_names = SFW::getSFWTablesNames();
if ( !$sfw_tables_names ) {
//try to create tables
$sfw_tables_names = apbct_sfw_update__create_tables(false, true);
if (!$sfw_tables_names) {
return array('error' => 'Can not get SFW table names from main blog options');
}
}
$apbct->data['sfw_common_table_name'] = TT::getArrayValueAsString($sfw_tables_names, 'sfw_common_table_name');
$apbct->data['sfw_personal_table_name'] = TT::getArrayValueAsString($sfw_tables_names, 'sfw_personal_table_name');
$apbct->save('data');
$wp_upload_dir = wp_upload_dir();
$base_dir = TT::getArrayValueAsString($wp_upload_dir, 'basedir');
//update only common tables if moderate 0
if ( ! $apbct->moderate ) {
$apbct->data['sfw_load_type'] = 'common';
}
if ( $apbct->network_settings['multisite__work_mode'] !== 2) {
$apbct->data['sfw_load_type'] = 'all';
$apbct->save('data');
}
// Flush fw stats data
$apbct->fw_stats = $apbct->default_fw_stats;
$apbct->fw_stats['calls'] = 0;
$apbct->fw_stats['firewall_updating_id'] = md5((string)rand(0, 100000));
$apbct->fw_stats['firewall_updating_last_start'] = time();
$apbct->fw_stats['updating_folder'] = $base_dir . DIRECTORY_SEPARATOR . 'cleantalk_fw_files_for_blog_' . get_current_blog_id() . DIRECTORY_SEPARATOR;
$apbct->save('fw_stats');
if (apbct_sfw_update__switch_to_direct()) {
return SFWUpdateHelper::directUpdate();
}
$apbct->sfw_update_sentinel->seekId($apbct->fw_stats['firewall_updating_id']);
// Delete update errors
$apbct->errorDelete('sfw_update', 'save_data');
$apbct->errorDelete('sfw_update', 'save_data', 'cron');
\Cleantalk\ApbctWP\Queue::clearQueue();
$queue = new \Cleantalk\ApbctWP\Queue();
//this is the first stage, select what type of SFW load need
$load_type = isset($apbct->data['sfw_load_type']) ? TT::toString($apbct->data['sfw_load_type']) : 'all';
$get_multifiles_params = array();
if ( $load_type === 'all' ) {
$queue->addStage('apbct_sfw_update__get_multifiles_all');
} else {
$get_multifiles_params['type'] = $load_type;
$get_multifiles_params['do_return_urls'] = false;
$queue->addStage('apbct_sfw_update__get_multifiles_of_type', $get_multifiles_params);
}
$cron = new Cron();
$watch_dog_period = $apbct->sfw_update_sentinel->getWatchDogCronPeriod();
$cron->addTask('sfw_update_sentinel_watchdog', 'apbct_sfw_update_sentinel__run_watchdog', $watch_dog_period, time() + $watch_dog_period);
$cron->addTask('sfw_update_checker', 'apbct_sfw_update__checker', 15);
return Helper::httpRequestRcToHost(
'sfw_update__worker',
array(
'firewall_updating_id' => $apbct->fw_stats['firewall_updating_id'],
'delay' => $delay
),
array('async')
);
}
/**
* Precheck server requirements before SFW update started.
* @return string|true True if check passed, first error string otherwise.
*/
function apbct_sfw_update__check_requirements()
{
global $apbct;
$result = true;
try {
// The Access key is empty
if ( ! $apbct->api_key && ! $apbct->ip_license ) {
throw new \Exception('KEY_IS_EMPTY');
}
if ( ! $apbct->data['key_is_ok'] ) {
throw new \Exception('KEY_IS_NOT_VALID');
}
$requirements_checker = new Cleantalk\ApbctWP\ServerRequirementsChecker\ServerRequirementsChecker();
$curl_multi_ok = $requirements_checker->getRequiredParameterValue('curl_multi_funcs_array');
if (!$curl_multi_ok) {
throw new \Exception('CURL MULTI FUNCTIONS NOT AVAILABLE');
}
} catch (\Exception $e) {
$result = 'SFW UPDATE INIT: ' . $e->getMessage();
}
return $result;
}
/**
* Decide need to force direct update
*
* @return bool
* @psalm-suppress NullArgument
*/
function apbct_sfw_update__switch_to_direct()
{
global $apbct;
$apbct->fw_stats['reason_direct_update_log'] = null;
if (defined('APBCT_SFW_FORCE_DIRECT_UPDATE')) {
$apbct->fw_stats['reason_direct_update_log'] = 'const APBCT_SFW_FORCE_DIRECT_UPDATE exists';
return true;
}
$prepare_dir__result = SFWUpdateHelper::prepareUpdDir();
if (!empty($prepare_dir__result['error'])) {
$apbct->fw_stats['reason_direct_update_log'] = 'variable prepare_dir__result has error';
return true;
}
$test_rc_result = Helper::httpRequestRcToHostTest(
'sfw_update__worker',
array(
'spbc_remote_call_token' => md5($apbct->api_key),
'spbc_remote_call_action' => 'sfw_update__worker',
'plugin_name' => 'apbct'
)
);
if (!empty($test_rc_result['error'])) {
$apbct->fw_stats['reason_direct_update_log'] = 'test remote call has error';
return true;
}
if (isset($apbct->fw_stats['firewall_updating_last_start'], $apbct->stats['sfw']['update_period']) &&
((int)$apbct->fw_stats['firewall_updating_last_start'] + (int)$apbct->stats['sfw']['update_period'] + 3600) < time()) {
$apbct->fw_stats['reason_direct_update_log'] = 'general update is freezing';
return true;
}
return false;
}
/**
* Called by sfw_update__worker remote call
* gather all process about SFW updating
*
* @param null|string $updating_id
* @param null|string $multifile_url
* @param null|string|int $url_count
* @param null|string|int $current_url
* @param string $useragent_url
*
* @return array|bool|int|string|string[]
*/
function apbct_sfw_update__worker($checker_work = false)
{
global $apbct;
if ( ! $apbct->data['key_is_ok'] ) {
return array('error' => 'Worker: KEY_IS_NOT_VALID');
}
if ( ! $apbct->settings['sfw__enabled'] ) {
return false;
}
if ( ! $checker_work ) {
if (
Request::equal('firewall_updating_id', '') ||
! Request::equal('firewall_updating_id', $apbct->fw_stats['firewall_updating_id'])
) {
return array('error' => 'Worker: WRONG_UPDATE_ID');
}
}
if ( ! isset($apbct->fw_stats['calls']) ) {
$apbct->fw_stats['calls'] = 0;
}
$apbct->fw_stats['calls']++;
$apbct->save('fw_stats');
if ( $apbct->fw_stats['calls'] > 600 ) {
$apbct->errorAdd('sfw_update', 'WORKER_CALL_LIMIT_EXCEEDED');
$apbct->saveErrors();
return 'WORKER_CALL_LIMIT_EXCEEDED';
}
$queue = new \Cleantalk\ApbctWP\Queue();
if ( count($queue->queue['stages']) === 0 ) {
// Queue is already empty. Exit.
return true;
}
$result = $queue->executeStage();
if ( $result === null ) {
// The stage is in progress, will try to wait up to 5 seconds to its complete
for ( $i = 0; $i < 5; $i++ ) {
sleep(1);
$queue->refreshQueue();
if ( ! $queue->isQueueInProgress() ) {
// The stage executed, break waiting and continue sfw_update__worker process
break;
}
if ( $i >= 4 ) {
// The stage still not executed, exit from sfw_update__worker
return true;
}
}
}
if ( isset($result['error'], $result['status']) && $result['status'] === 'FINISHED' ) {
SFWUpdateHelper::fallback();
$direct_upd_res = SFWUpdateHelper::directUpdate();
if ( !empty($direct_upd_res['error']) ) {
$apbct->errorAdd('queue', $result['error'], 'sfw_update');
$apbct->errorAdd('direct', $direct_upd_res['error'], 'sfw_update');
$apbct->saveErrors();
return $direct_upd_res['error'];
}
//stop seeking updates on success direct update
$apbct->sfw_update_sentinel->clearSentinelData();
return true;
}
if ( $queue->isQueueFinished() ) {
$queue->queue['finished'] = time();
$queue->saveQueue($queue->queue);
foreach ( $queue->queue['stages'] as $stage ) {
if ( isset($stage['error'], $stage['status']) && $stage['status'] !== 'FINISHED' ) {
//there could be an array of errors of files processed
if ( is_array($stage['error']) ) {
$error = implode(" ", array_values($stage['error']));
} else {
$error = $result['error'];
}
$apbct->errorAdd('sfw_update', $error);
}
}
// Do logging the queue process here
return true;
}
// This is the repeat stage request, do not generate any new RC
if ( stripos(TT::toString(Request::get('stage')), 'Repeat') !== false ) {
return true;
}
return Helper::httpRequestRcToHost(
'sfw_update__worker',
array('firewall_updating_id' => $apbct->fw_stats['firewall_updating_id']),
array('async')
);
}
/**
* QUEUE STAGES *
*/
/**
* Queue stage. Get both types of multifiles (common/personal) url for next downloading.
* @return array|array[]|string[]
*/
function apbct_sfw_update__get_multifiles_all()
{
global $apbct;
if ( ! $apbct->data['key_is_ok'] ) {
return array('error' => 'Get multifiles: KEY_IS_NOT_VALID');
}
$get_multifiles_common_urls = apbct_sfw_update__get_multifiles_of_type(array('type' => 'common', 'do_return_urls' => true));
if ( !empty($get_multifiles_common_urls['error']) ) {
$output_error = $get_multifiles_common_urls['error'];
}
$get_multifiles_personal_urls = apbct_sfw_update__get_multifiles_of_type(array('type' => 'personal', 'do_return_urls' => true));
if ( !empty($get_multifiles_personal_urls['error']) ) {
$output_error = $get_multifiles_personal_urls['error'];
}
$file_urls = array_merge($get_multifiles_common_urls, $get_multifiles_personal_urls);
if ( empty($file_urls) ) {
$output_error = 'SFW_UPDATE_FILES_URLS_IS_EMPTY';
}
if ( empty($output_error) ) {
$apbct->fw_stats['firewall_update_percent'] = round(100 / count($file_urls), 2);
$apbct->save('fw_stats');
return array(
'next_stage' => array(
'name' => 'apbct_sfw_update__download_files',
'args' => $file_urls,
'is_last' => '0'
)
);
} else {
return array('error' => $output_error);
}
}
/**
* Queue stage. Get multifiles url for next downloading. Can return urls directly if flag is set instead of next stage call.
* @param array $params 'type' -> type of SFW load, 'do_return_urls' -> return urls if true, array call for next stage otherwise(default false)
* @return array|array[]|string[]
*/
function apbct_sfw_update__get_multifiles_of_type(array $params)
{
global $apbct;
//check key
if ( ! $apbct->data['key_is_ok'] ) {
return array('error' => 'Get multifiles: KEY_IS_NOT_VALID');
}
//chek type
if ( !isset($params['type']) || !in_array($params['type'], array('common', 'personal')) ) {
return array('error' => 'Get multifiles: bad params');
} else {
$type = $params['type'];
}
//check needs return urls instead of next stage
$do_return_urls = TT::getArrayValueAsBool($params, 'do_return_urls');
$output_error = array();
// getting urls
try {
$direction_files = SFWUpdateHelper::getDirectionUrlsOfType($type);
$direction_url_id = TT::getArrayValueAsString($direction_files, 'url_id');
if ( $type === 'personal' ) {
$apbct->fw_stats['personal_lists_url_id'] = $direction_url_id;
} else {
$apbct->fw_stats['common_lists_url_id'] = $direction_url_id;
}
} catch (\Exception $e) {
$output_error[] = $e->getMessage();
}
if ( empty($output_error) ) {
if ( !empty($direction_files['files_urls']) ) {
$urls = array();
foreach ( $direction_files['files_urls'] as $value ) {
$urls[] = $value[0];
}
$apbct->fw_stats['firewall_update_percent'] = round(100 / count($urls), 2);
$apbct->save('fw_stats');
// return urls directly on do load all multifiles, otherwise proceed to next queue stage
if ( !$do_return_urls) {
return array(
'next_stage' => array(
'name' => 'apbct_sfw_update__download_files',
'args' => $urls,
'is_last' => '0'
)
);
} else {
return $urls;
}
} else {
return array('error' => 'SFW_UPDATE_FILES_URLS_IS_EMPTY');
}
} else {
return array('error' => $output_error);
}
}
/**
* Queue stage. Do load multifiles with networks on their urls.
* @param $all_urls
* @return array|true
*/
function apbct_sfw_update__download_files($all_urls, $direct_update = false)
{
$downloader = new \Cleantalk\ApbctWP\Firewall\SFWFilesDownloader();
return $downloader->downloadFiles($all_urls, $direct_update);
}
/**
* Queue stage. Create SFW origin tables to make sure they are exists.
* @return array[]|bool|string[]
*/
function apbct_sfw_update__create_tables($direct_update = false, $return_new_tables_names = false)
{
global $apbct, $wpdb;
// Preparing database infrastructure
// Creating SFW tables to make sure that they are exists
$db_tables_creator = new DbTablesCreator();
//common table
$common_table_name = $wpdb->base_prefix . Schema::getSchemaTablePrefix() . 'sfw';
$db_tables_creator->createTable($common_table_name);
$apbct->data['sfw_common_table_name'] = $common_table_name;
//personal table
$table_name_personal = $wpdb->prefix . Schema::getSchemaTablePrefix() . 'sfw_personal';
$db_tables_creator->createTable($table_name_personal);
$apbct->data['sfw_personal_table_name'] = $table_name_personal;
//ua table
$personal_ua_bl_table_name = $wpdb->prefix . Schema::getSchemaTablePrefix() . 'ua_bl';
$db_tables_creator->createTable($personal_ua_bl_table_name);
$apbct->data['sfw_personal_ua_bl_table_name'] = $personal_ua_bl_table_name;
$apbct->saveData();
if ( $return_new_tables_names ) {
return array(
'sfw_common_table_name' => $common_table_name,
'sfw_personal_table_name' => $table_name_personal,
'sfw_personal_ua_bl_table_name' => $personal_ua_bl_table_name,
);
}
return $direct_update ? true : array(
'next_stage' => array(
'name' => 'apbct_sfw_update__create_temp_tables',
)
);
}
/**
* Queue stage. Create SFW temporary tables. They will replace origin tables after update.
* @return array[]|bool
*/
function apbct_sfw_update__create_temp_tables($direct_update = false)
{
global $apbct;
// Create common table
$result = SFW::createTempTables(DB::getInstance(), $apbct->data['sfw_common_table_name']);
if ( ! empty($result['error']) ) {
return $result;
}
// Create personal table
$result = SFW::createTempTables(DB::getInstance(), $apbct->data['sfw_personal_table_name']);
if ( ! empty($result['error']) ) {
return $result;
}
$result__clear_db = AntiCrawler::clearDataTable(
\Cleantalk\ApbctWP\DB::getInstance(),
APBCT_TBL_AC_UA_BL
);
if ( ! empty($result__clear_db['error']) ) {
return $result__clear_db['error'];
}
return $direct_update ? true : array(
'next_stage' => array(
'name' => 'apbct_sfw_update__process_files',
)
);
}
/**
* Queue stage. Process all of downloaded multifiles that collected to the update folder.
* @return array[]|int|string[]|null
*/
function apbct_sfw_update__process_files()
{
global $apbct;
// get list of files in the upd folder
$files = glob($apbct->fw_stats['updating_folder'] . '/*csv.gz');
$files = array_filter($files, static function ($element) {
return strpos($element, 'list') !== false;
});
if ( count($files) ) {
reset($files);
$concrete_file = current($files);
//get direction on how the file should be processed (common/personal)
if (
// we should have a personal list id (hash) to make sure the file belongs to private lists
!empty($apbct->fw_stats['personal_lists_url_id'])
&& strpos($concrete_file, $apbct->fw_stats['personal_lists_url_id']) !== false
) {
$direction = 'personal';
} elseif (
// we should have a common list id (hash) to make sure the file belongs to common lists
!empty($apbct->fw_stats['common_lists_url_id'])
&& strpos($concrete_file, $apbct->fw_stats['common_lists_url_id']) !== false ) {
$direction = 'common';
} else {
// no id found in fw_stats or file namse does not contain any of them
return array('error' => 'SFW_DIRECTION_FAILED');
}
// do proceed file with networks itself
if ( strpos($concrete_file, 'bl_list') !== false ) {
//$result = apbct_sfw_update__process_file($concrete_file, $direction);
$result = SFWUpdateHelper::processFile($concrete_file, $direction);
}
// do proceed ua file
if ( strpos($concrete_file, 'ua_list') !== false ) {
$result = SFWUpdateHelper::processUA($concrete_file);
}
// do proceed checking file
if ( strpos($concrete_file, 'ck_list') !== false ) {
$result = SFWUpdateHelper::processCK($concrete_file, $direction);
}
if ( ! empty($result['error']) ) {
return $result;
}
$apbct->fw_stats['firewall_update_percent'] = round(100 / count($files), 2);
$apbct->save('fw_stats');
return array(
'next_stage' => array(
'name' => 'apbct_sfw_update__process_files',
)
);
}
return array(
'next_stage' => array(
'name' => 'apbct_sfw_update__process_exclusions',
)
);
}
/**
* Queue stage. Process hardcoded exclusion to the SFW temp table.
* @return array[]|string[]|bool
*/
function apbct_sfw_update__process_exclusions($direct_update = false)
{
global $apbct;
$table_names = SFW::getSFWTablesNames();
$origin_personal_table_name = $table_names && isset($table_names['sfw_personal_table_name']) && is_string($table_names['sfw_personal_table_name'])
? $table_names['sfw_personal_table_name']
: null;
if ($origin_personal_table_name) {
$temp_table_name = $origin_personal_table_name . '_temp';
} else {
return array('error' => 'EXCLUSIONS: CAN NOT GET SFW TABLES NAMES');
}
if (!DB::getInstance()->isTableExists($temp_table_name)) {
SFW::createTempTables(DB::getInstance(), $origin_personal_table_name);
if (!DB::getInstance()->isTableExists($temp_table_name)) {
return array('error' => 'EXCLUSIONS: CAN NOT RECREATE TEMP PERSONAL TABLE ' . $temp_table_name);
}
}
$result = SFW::updateWriteToDbExclusions(
DB::getInstance(),
$temp_table_name
);
if ( ! empty($result['error']) ) {
return array('error' => 'EXCLUSIONS: ' . $result['error']);
}
if ( ! is_int($result) ) {
return array('error' => 'EXCLUSIONS: WRONG_RESPONSE update__write_to_db__exclusions');
}
/**
* Update expected_networks_count
*/
if ( $result > 0 ) {
$apbct->fw_stats['expected_networks_count_personal'] += $result;
$apbct->save('fw_stats');
}
return $direct_update ? true : array(
'next_stage' => array(
'name' => 'apbct_sfw_update__end_of_update__renaming_tables',
'accepted_tries' => 1
)
);
}
/**
* Queue stage. Delete origin tables and rename temporary tables.
* @return array|array[]|string[]|bool
*/
function apbct_sfw_update__end_of_update__renaming_tables($direct_update = false)
{
global $apbct;
$check = SFWUpdateHelper::checkTablesIntegrityBeforeRenaming($apbct->data['sfw_load_type']);
if ( !empty($check['error']) ) {
return array('error' => $check['error']);
}
$apbct->fw_stats['update_mode'] = 1;
$apbct->save('fw_stats');
usleep(10000);
// REMOVE AND RENAME
try {
SFWUpdateHelper::removeAndRenameSfwTables($apbct->data['sfw_load_type']);
} catch (\Exception $e) {
$apbct->fw_stats['update_mode'] = 0;
$apbct->save('fw_stats');
return array('error' => $e->getMessage());
}
$apbct->fw_stats['update_mode'] = 0;
$apbct->save('fw_stats');
return $direct_update ? true : array(
'next_stage' => array(
'name' => 'apbct_sfw_update__end_of_update__checking_data',
'accepted_tries' => 1
)
);
}
/**
* Queue stage. Check data after all the SFW update actions.
* @return array|array[]|string[]|bool
*/
function apbct_sfw_update__end_of_update__checking_data($direct_update = false)
{
global $apbct, $wpdb;
try {
SFWUpdateHelper::checkTablesIntegrityAfterRenaming($apbct->data['sfw_load_type']);
} catch (\Exception $e) {
return array('error' => $e->getMessage());
}
$apbct->stats['sfw']['entries'] = $wpdb->get_var('SELECT COUNT(*) FROM ' . $apbct->data['sfw_common_table_name']);
$apbct->stats['sfw']['entries_personal'] = $wpdb->get_var('SELECT COUNT(*) FROM ' . $apbct->data['sfw_personal_table_name']);
$apbct->save('stats');
/**
* Checking the integrity of the sfw database update
*/
if ( in_array($apbct->data['sfw_load_type'], array('all','common'))
&& isset($apbct->stats['sfw']['entries'])
&& ($apbct->stats['sfw']['entries'] != $apbct->fw_stats['expected_networks_count'] ) ) {
return array(
'error' =>
'The discrepancy between the amount of data received for the update and in the final table: '
. $apbct->data['sfw_common_table_name']
. '. RECEIVED: ' . $apbct->fw_stats['expected_networks_count']
. '. ADDED: ' . $apbct->stats['sfw']['entries']
);
}
if ( in_array($apbct->data['sfw_load_type'], array('all','personal'))
&& isset($apbct->stats['sfw']['entries_personal'])
&& ( $apbct->stats['sfw']['entries_personal'] != $apbct->fw_stats['expected_networks_count_personal'] ) ) {
return array(
'error' =>
'The discrepancy between the amount of data received for the update and in the final table: '
. $apbct->data['sfw_personal_table_name']
. '. RECEIVED: ' . $apbct->fw_stats['expected_networks_count_personal']
. '. ADDED: ' . $apbct->stats['sfw']['entries_personal']
);
}
return $direct_update ? true : array(
'next_stage' => array(
'name' => 'apbct_sfw_update__end_of_update__updating_stats',
'accepted_tries' => 1
)
);
}
/**
* Queue stage. Update stats.
* @param $direct_update
* @return array[]
*/
function apbct_sfw_update__end_of_update__updating_stats($direct_update = false)
{
global $apbct;
$is_first_updating = ! $apbct->stats['sfw']['last_update_time'];
$apbct->stats['sfw']['last_update_time'] = time();
$apbct->stats['sfw']['last_update_way'] = $direct_update ? 'Direct update' : 'Queue update';
$apbct->save('stats');
return array(
'next_stage' => array(
'name' => 'apbct_sfw_update__end_of_update',
'accepted_tries' => 1,
'args' => $is_first_updating
)
);
}
/**
* Final queue stage. Reset all misc data and set new cron.
* @param $is_first_updating
* @return true
*/
function apbct_sfw_update__end_of_update($is_first_updating = false)
{
global $apbct;
// Delete update errors
$apbct->errorDelete('sfw_update', true);
// Running sfw update once again in 12 min if entries is < 4000
if ( $is_first_updating &&
$apbct->stats['sfw']['entries'] < 4000
) {
wp_schedule_single_event(time() + 720, 'apbct_sfw_update__init');
}
$cron = new Cron();
$cron->updateTask('sfw_update', 'apbct_sfw_update__init', $apbct->stats['sfw']['update_period']);
$cron->removeTask('sfw_update_checker');
SFWUpdateHelper::removeUpdFolder($apbct->fw_stats['updating_folder']);
// Reset all FW stats
$apbct->sfw_update_sentinel->clearSentinelData();
$apbct->fw_stats['firewall_update_percent'] = 0;
$apbct->fw_stats['firewall_updating_id'] = null;
$apbct->fw_stats['expected_networks_count'] = false;
$apbct->fw_stats['expected_ua_count'] = false;
$apbct->save('fw_stats');
return true;
}
/**
* Cron task handler.
* @return array|bool|int|string|string[]
*/
function apbct_sfw_update__checker()
{
$queue = new \Cleantalk\ApbctWP\Queue();
if ( count($queue->queue['stages']) ) {
foreach ( $queue->queue['stages'] as $stage ) {
if ( $stage['status'] === 'NULL' ) {
return apbct_sfw_update__worker(true);
}
}
}
return true;
}
/**
* * * * * * SFW COMMON ACTIONS * * * * * *
*/
function apbct_sfw__clear()
{
global $apbct, $wpdb;
$wpdb->query('DELETE FROM ' . APBCT_TBL_FIREWALL_DATA . ';');
$apbct->stats['sfw']['entries'] = 0;
$apbct->save('stats');
}
/**
* Send SFW logs to the cloud.
* @param $api_key
* @return array|bool|int[]|string[]
*/
function ct_sfw_send_logs($api_key = '')
{
global $apbct;
$api_key = ! empty($apbct->api_key) ? $apbct->api_key : $api_key;
if (
time() - $apbct->stats['sfw']['sending_logs__timestamp'] < 180 ||
empty($api_key) ||
$apbct->settings['sfw__enabled'] != 1 ||
apbct__is_hosting_license()
) {
return true;
}
$apbct->stats['sfw']['sending_logs__timestamp'] = time();
$apbct->save('stats');
$result = SFW::sendLog(
DB::getInstance(),
APBCT_TBL_FIREWALL_LOG,
$api_key
);
if ( empty($result['error']) ) {
$apbct->stats['sfw']['last_send_time'] = time();
$apbct->stats['sfw']['last_send_amount'] = TT::getArrayValueAsInt($result, 'rows');
$apbct->errorDelete('sfw_send_logs', true);
$apbct->save('stats');
}
return $result;
}
/**
* Handle SFW private_records remote call.
* @param $action
* @param null|string $test_data
* @return string JSON string of results
* @throws Exception
*/
function apbct_sfw_private_records_handler($action, $test_data = null)
{
$error = 'sfw_private_records_handler: ';
if ( !empty($action) && (in_array($action, array('add', 'delete'))) ) {
$metadata = !empty($test_data) ? TT::toString($test_data) : TT::toString(Post::get('metadata'));
if ( !empty($metadata) ) {
$metadata = json_decode(stripslashes($metadata), true);
if ( $metadata === 'NULL' || $metadata === null ) {
throw new InvalidArgumentException($error . 'metadata JSON decoding failed');
}
} else {
throw new InvalidArgumentException($error . 'metadata is empty');
}
foreach ( $metadata as $_key => &$row ) {
$row = explode(',', $row);
//do this to get info more obvious
$metadata_assoc_array = array(
'network' => TT::getArrayValueAsInt($row, 0),
'mask' => TT::getArrayValueAsInt($row, 1),
'status' => isset($row[2]) ? TT::toInt($row[2]) : null
);
//validate
$validation_error = '';
if ( $metadata_assoc_array['network'] === 0
|| $metadata_assoc_array['network'] > 4294967295
) {
$validation_error = 'metadata validate failed on "network" value';
}
if ( $metadata_assoc_array['mask'] === 0
|| $metadata_assoc_array['mask'] > 4294967295
) {
$validation_error = 'metadata validate failed on "mask" value';
}
//only for adding
if ( $action === 'add' ) {
if ( $metadata_assoc_array['status'] !== 1 && $metadata_assoc_array['status'] !== 0 ) {
$validation_error = 'metadata validate failed on "status" value';
}
}
if ( !empty($validation_error) ) {
throw new InvalidArgumentException($error . $validation_error);
}
$row = $metadata_assoc_array;
}
unset($row);
$table_names = SFW::getSFWTablesNames();
$table_name = $table_names && isset($table_names['sfw_personal_table_name']) && is_string($table_names['sfw_personal_table_name'])
? $table_names['sfw_personal_table_name']
: false;
if (!$table_name || !DB::getInstance()->isTableExists($table_name)) {
throw new InvalidArgumentException('internal error: sfw table does not exist');
}
//method selection
if ( $action === 'add' ) {
$handler_output = SFW::privateRecordsAdd(
DB::getInstance(),
$table_name,
$metadata
);
} elseif ( $action === 'delete' ) {
$handler_output = SFW::privateRecordsDelete(
DB::getInstance(),
$table_name,
$metadata
);
} else {
$error .= 'unknown action name: ' . $action;
throw new InvalidArgumentException($error);
}
} else {
throw new InvalidArgumentException($error . 'empty action name');
}
return json_encode(array('OK' => $handler_output));
}
/**
* Cron task handler. Clear anti-flood table.
* @return void
*/
function apbct_antiflood__clear_table()
{
global $apbct;
if ( $apbct->settings['sfw__anti_flood'] || $apbct->settings['sfw__anti_crawler'] ) {
$anti_flood = new AntiFlood(
APBCT_TBL_FIREWALL_LOG,
APBCT_TBL_AC_LOG,
array(
'chance_to_clean' => 100,
)
);
$anti_flood->setDb(DB::getInstance());
$anti_flood->clearTable();
unset($anti_flood);
// Clear table APBCT_TBL_AC_LOG once a day
$anticrawler = new AntiCrawler(
APBCT_TBL_FIREWALL_LOG,
APBCT_TBL_AC_LOG
);
$anticrawler->setDb(DB::getInstance());
$anticrawler->clearTable();
unset($anticrawler);
}
}
/**
* * * * * * REMOTE CALL ACTIONS * * * * * *
*/
/**
* Install plugin from WordPress catalog
*
* @param null|WP $_wp
* @param null|string|array $plugin
*
* @psalm-suppress UndefinedClass
*/
function apbct_rc__install_plugin($_wp = null, $plugin = null)
{
global $wp_version;
if ( is_null($plugin) ) {
$plugin = Get::get('plugin') ? Get::get('plugin') : '';
}
$allowed_plugin = 'security-malware-firewall/security-malware-firewall.php';
if ( !empty($plugin) && TT::toString($plugin) !== $allowed_plugin ) {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_NOT_ALLOWED')));
}
if ( !empty($plugin) ) {
$plugin = TT::toString($plugin);
if ( preg_match('/[a-zA-Z-\d]+[\/\\][a-zA-Z-\d]+\.php/', $plugin) ) {
$plugin_slug = preg_replace('@([a-zA-Z-\d]+)[\\\/].*@', '$1', $plugin);
if ( $plugin_slug ) {
require_once(ABSPATH . 'wp-admin/includes/plugin-install.php');
$result = plugins_api(
'plugin_information',
array(
'slug' => $plugin_slug,
'fields' => array('version' => true, 'download_link' => true,),
)
);
if ( ! is_wp_error($result) ) {
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
include_once(ABSPATH . 'wp-admin/includes/file.php');
include_once(ABSPATH . 'wp-admin/includes/misc.php');
if ( version_compare(PHP_VERSION, '5.6.0') >= 0 && version_compare($wp_version, '5.3') >= 0 ) {
$installer = new CleantalkUpgrader(new CleantalkUpgraderSkin());
} else {
$installer = new CleantalkUpgrader(new CleantalkUpgraderSkinDeprecated());
}
$download_link = is_object($result) ? $result->download_link : false;
if ($download_link) {
$installer->install($download_link);
}
if ( $download_link && $installer->apbct_result === 'OK' ) {
die('OK');
} else {
die('FAIL ' . json_encode(array('error' => $installer->apbct_result)));
}
} else {
die(
'FAIL ' . json_encode(array(
'error' => 'FAIL_TO_GET_LATEST_VERSION',
'details' => $result instanceof WP_Error ? $result->get_error_message() : '',
))
);
}
} else {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_SLUG_INCORRECT')));
}
} else {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_NAME_IS_INCORRECT')));
}
} else {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_NAME_IS_UNSET')));
}
}
function apbct_rc__activate_plugin($plugin)
{
if ( ! $plugin ) {
$plugin = Get::get('plugin') ? TT::toString(Get::get('plugin')) : null;
}
// Only allow activation of Security by CleanTalk plugin via remote call
$allowed_plugin = 'security-malware-firewall/security-malware-firewall.php';
if ( $plugin && $plugin !== $allowed_plugin ) {
return array('error' => 'PLUGIN_NOT_ALLOWED');
}
if ( $plugin ) {
if ( preg_match('@[a-zA-Z-\d]+[\\\/][a-zA-Z-\d]+\.php@', $plugin) ) {
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
$result = activate_plugins($plugin);
$result_array = array('success' => true);
$error_msg = '';
if (!$result || is_wp_error($result)) {
if ($result instanceof WP_Error) {
$error_msg = ' ' . $result->get_error_message();
}
$result_array = array(
'error' => 'FAIL_TO_ACTIVATE',
'details' => $error_msg
);
}
return $result_array;
} else {
return array('error' => 'PLUGIN_NAME_IS_INCORRECT');
}
} else {
return array('error' => 'PLUGIN_NAME_IS_UNSET');
}
}
/**
* Uninstall plugin from WordPress catalog
*
* @param null $plugin
*/
function apbct_rc__deactivate_plugin($plugin = null)
{
global $apbct;
if ( is_null($plugin) ) {
$plugin = Get::get('plugin') ? TT::toString(Get::get('plugin')) : null;
}
// Only allow deactivation of CleanTalk plugins via remote call
$allowed_plugins = array(
'cleantalk-spam-protect/cleantalk.php',
'security-malware-firewall/security-malware-firewall.php',
);
if ( $plugin && !in_array($plugin, $allowed_plugins, true) ) {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_NOT_ALLOWED')));
}
if ( $plugin ) {
// Switching complete deactivation for security
if ( $plugin === 'security-malware-firewall/security-malware-firewall.php' && ! empty(Get::get('misc__complete_deactivation')) ) {
$spbc_settings = TT::toArray(get_option('spbc_settings'));
$spbc_settings['misc__complete_deactivation'] = TT::toInt(Get::get('misc__complete_deactivation'));
update_option('spbc_settings', $spbc_settings);
}
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
if ( is_plugin_active($plugin) ) {
// Hook to set flag if the plugin is deactivated
add_action('deactivate_' . $plugin, 'apbct_rc__uninstall_plugin__check_deactivate');
deactivate_plugins($plugin, false, is_multisite());
} else {
$apbct->plugin_deactivated = true;
}
// Hook to set flag if the plugin is deactivated
add_action('deactivate_' . $plugin, 'apbct_rc__uninstall_plugin__check_deactivate');
deactivate_plugins($plugin, false, is_multisite());
if ( $apbct->plugin_deactivated ) {
die('OK');
} else {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_STILL_ACTIVE')));
}
} else {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_NAME_IS_UNSET')));
}
}
/**
* Uninstall plugin from WordPress. Delete files.
*
* @param null $plugin
*/
function apbct_rc__uninstall_plugin($plugin = null)
{
global $apbct;
if ( is_null($plugin) ) {
$plugin = Get::get('plugin') ? TT::toString(Get::get('plugin')) : null;
}
// Only allow uninstallation of CleanTalk plugins via remote call
$allowed_plugins = array(
'cleantalk-spam-protect/cleantalk.php',
'security-malware-firewall/security-malware-firewall.php',
);
if ( $plugin && !in_array($plugin, $allowed_plugins, true) ) {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_NOT_ALLOWED')));
}
if ( $plugin ) {
// Switching complete deactivation for security
if ( $plugin === 'security-malware-firewall/security-malware-firewall.php' && ! empty(Get::get('misc__complete_deactivation')) ) {
$spbc_settings = TT::toArray(get_option('spbc_settings'));
$spbc_settings['misc__complete_deactivation'] = TT::toInt(Get::get('misc__complete_deactivation'));
update_option('spbc_settings', $spbc_settings);
}
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
if ( is_plugin_active($plugin) ) {
// Hook to set flag if the plugin is deactivated
add_action('deactivate_' . $plugin, 'apbct_rc__uninstall_plugin__check_deactivate');
deactivate_plugins($plugin, false, is_multisite());
} else {
$apbct->plugin_deactivated = true;
}
if ( $apbct->plugin_deactivated ) {
require_once(ABSPATH . '/wp-admin/includes/file.php');
$result = delete_plugins(array($plugin));
$die_string = 'OK';
$error_msg = '';
if (!$result || is_wp_error($result)) {
if ($result instanceof WP_Error) {
$error_msg = ' ' . $result->get_error_message();
}
$die_string = 'FAIL ' . json_encode(array(
'error' => 'PLUGIN_STILL_EXISTS',
'details' => $error_msg
));
}
die($die_string);
} else {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_STILL_ACTIVE')));
}
} else {
die('FAIL ' . json_encode(array('error' => 'PLUGIN_NAME_IS_UNSET')));
}
}
function apbct_rc__uninstall_plugin__check_deactivate()
{
global $apbct;
$apbct->plugin_deactivated = true;
}
/**
* @param $source
*
* @return bool
*/
function apbct_rc__update_settings($source)
{
global $apbct;
foreach ( $apbct->default_settings as $setting => $def_value ) {
if ( array_key_exists($setting, $source) ) {
$var = $source[$setting];
$type = gettype($def_value);
settype($var, $type);
if ( $type === 'string' ) {
$var = preg_replace(array('/=/', '/`/'), '', $var);
}
$apbct->settings[$setting] = $var;
}
}
$apbct->save('settings');
return true;
}
/**
* @param string $key
* @param string $plugin
*
* @return array|string
*/
function apbct_rc__insert_auth_key($key, $plugin)
{
if ( $plugin === 'security-malware-firewall/security-malware-firewall.php' ) {
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
if ( is_plugin_active($plugin) ) {
$key = trim($key);
if ( $key && preg_match('/^[a-z\d]{3,30}$/', $key) ) {
$result = API::methodNoticePaidTill(
$key,
preg_replace('/http[s]?:\/\//', '', get_option('home'), 1), // Site URL
'security'
);
if ( empty($result['error']) ) {
if ( TT::getArrayValueAsInt($result, 'valid') === 1 ) {
// Set account params
$data = get_option('spbc_data', array());
$data['user_token'] = TT::getArrayValueAsInt($result, 'user_token');
$data['notice_show'] = TT::getArrayValueAsInt($result, 'show_notice');
$data['notice_renew'] = TT::getArrayValueAsInt($result, 'renew');
$data['notice_trial'] = TT::getArrayValueAsInt($result, 'trial');
$data['service_id'] = TT::getArrayValueAsInt($result, 'service_id');
$data['user_id'] = TT::getArrayValueAsInt($result, 'user_id');
$data['moderate'] = TT::getArrayValueAsInt($result, 'moderate');
$data['license_trial'] = TT::getArrayValueAsInt($result, 'license_trial');
$data['account_name_ob'] = TT::getArrayValueAsString($result, 'account_name_ob');
$data['key_is_ok'] = true;
update_option('spbc_data', $data);
// Set Access key
$settings = TT::toArray(get_option('spbc_settings', array()));
$settings['spbc_key'] = $key;
update_option('spbc_settings', $settings);
return 'OK';
} else {
return array('error' => 'KEY_IS_NOT_VALID');
}
} else {
return array('error' => $result);
}
} else {
return array('error' => 'KEY_IS_NOT_CORRECT');
}
} else {
return array('error' => 'PLUGIN_IS_NOT_ACTIVE_OR_NOT_INSTALLED');
}
} else {
return array('error' => 'PLUGIN_SLUG_INCORRECT');
}
}
/**
* Putting WordPress to maintenance mode.
* For given duration in seconds
*
* @param $duration
*
* @return bool
*/
function apbct_maintenance_mode__enable($duration)
{
apbct_maintenance_mode__disable();
$content = "<?php\n\n"
. '$upgrading = ' . (time() - (60 * 10) + $duration) . ';';
return (bool)file_put_contents(ABSPATH . '.maintenance', $content);
}
/**
* Disabling maintenance mode by deleting .maintenance file.
*
* @return void
*/
function apbct_maintenance_mode__disable()
{
$maintenance_file = ABSPATH . '.maintenance';
if ( file_exists($maintenance_file) ) {
unlink($maintenance_file);
}
}
/**
* @param $stage
* @param $result
* @param array $response
*
* @return void
*/
function apbct_update__outputResult($stage, $result, $response = array())
{
$response['stage'] = $stage;
$response['error'] = isset($response['error']) ? $response['error'] : '';
if ( $result === true ) {
$result = 'OK';
}
if ( $result === false ) {
$result = 'FAIL';
}
$response['error'] = $response['error'] ?: '';
$response['error'] = $result !== 'OK' && empty($response['error']) ? $result : $response['error'];
$response['agent'] = APBCT_AGENT;
echo \Cleantalk\ApbctWP\Escape::escHtml($result . ' ' . json_encode($response));
if ( $result === 'FAIL' ) {
die();
}
echo '<br>';
}
/**
* Getting brief data
*
* @param null|string $api_key
*/
function cleantalk_get_brief_data($api_key = null)
{
global $apbct;
$api_key = is_null($api_key) ? $apbct->api_key : $api_key;
$apbct->data['brief_data'] = API::methodGetAntispamReportBreif($api_key);
# expanding data about the country
if ( isset($apbct->data['brief_data']['top5_spam_ip']) && ! empty($apbct->data['brief_data']['top5_spam_ip']) ) {
foreach ( $apbct->data['brief_data']['top5_spam_ip'] as $key => $ip_data ) {
$ip = $ip_data[0];
$ip_data[1] = array(
'country_name' => 'Unknown',
'country_code' => 'cleantalk'
);
if ( isset($ip) ) {
$country_data = TT::toArray(API::methodIpInfo($ip));
$country_data_clear = current($country_data);
if (
is_array($country_data_clear) &&
isset($country_data_clear['country_name']) &&
isset($country_data_clear['country_code'])
) {
$ip_data[1] = array(
'country_name' => $country_data_clear['country_name'],
'country_code' => ( ! preg_match(
'/[^A-Za-z0-9]/',
$country_data_clear['country_code']
)) ? $country_data_clear['country_code'] : 'cleantalk'
);
}
}
$apbct->data['brief_data']['top5_spam_ip'][$key] = $ip_data;
}
}
$apbct->saveData();
}
/**
* Delete cookie for admin trial notice
*/
function apbct__hook__wp_logout__delete_trial_notice_cookie()
{
if ( ! headers_sent() ) {
Cookie::setNativeCookie('ct_trial_banner_closed', '', time() - 3600);
}
}
/**
* Store URLs
*/
function apbct_store__urls()
{
global $apbct;
if (
! empty($apbct->headers_sent) // Headers sent
) {
return false;
}
if ( $apbct->settings['misc__store_urls'] && empty($apbct->flags__url_stored) && ! headers_sent() ) {
// URLs HISTORY
// Get current url
$current_url = TT::toString(Server::get('HTTP_HOST'))
. TT::toString(Server::get('REQUEST_URI'));
$current_url = $current_url ? substr($current_url, 0, 128) : 'UNKNOWN';
// Get already stored URLs
$urls_json = TT::toString(RequestParameters::getCommonStorage('apbct_urls'));
$urls = !empty($urls_json) ? json_decode($urls_json, true) : array();
$urls = ! is_array($urls) ? [] : $urls;
$urls[$current_url][] = time();
// Saving only latest 5 visit for each of 5 last urls
$urls_count_to_keep = 5;
$visits_to_keep = 5;
//Rotating.
$urls[$current_url] = count($urls[$current_url]) > $visits_to_keep
? array_slice(
$urls[$current_url],
1,
$visits_to_keep
)
: $urls[$current_url];
$urls = count($urls) > $urls_count_to_keep
? array_slice($urls, 1, $urls_count_to_keep)
: $urls;
// Saving
RequestParameters::setCommonStorage('apbct_urls', json_encode($urls, JSON_UNESCAPED_SLASHES));
// SITE-REFERER
// Get current site-referer
$new_site_referer = Server::getString('HTTP_REFERER');
if (empty($new_site_referer)) {
//do not overwrite existing param - this case is when the new url is entered via address bar
if (empty(RequestParameters::get('apbct_site_referer', true))) {
//we should keep existing param anyway to make sure the site referer is not lost
RequestParameters::set('apbct_site_referer', '0', true);
}
} else {
$is_valid_new_url = parse_url($new_site_referer, PHP_URL_HOST) !== null;
$is_not_like_host = $is_valid_new_url && parse_url($new_site_referer, PHP_URL_HOST) !== Server::getString('HTTP_HOST');
if ($is_not_like_host) {
RequestParameters::set('apbct_site_referer', $new_site_referer, true);
}
}
$apbct->flags__url_stored = true;
}
}
/**
* Set Cookies test for cookie test
* Sets cookies with params timestamp && landing_timestamp && previous_referer
* Sets test cookie with all other cookies
* @return bool
*/
function apbct_cookie()
{
global $apbct;
if (
! empty($apbct->flags__cookies_setuped) || // Cookies already set
! empty($apbct->headers_sent) || // Headers sent
Post::get('fusion_login_box') // Avada Fusion registration form exclusion
) {
return false;
}
// Prevent headers sent error
if ( headers_sent($file, $line) ) {
$apbct->headers_sent = true;
$apbct->headers_sent__hook = current_filter();
$apbct->headers_sent__where = $file . ':' . $line;
return false;
}
// Cookie names to validate
$cookie_test_value = array(
'cookies_names' => array(),
'check_value' => $apbct->api_key,
);
// We need to skip the domain attribute for prevent including the dot to the cookie's domain on the client.
$domain = '';
// Submit time
if ( empty($_POST) ) {
SubmitTimeHandler::setToRequest(time(), $cookie_test_value);
}
// Landing time
$site_landing_timestamp = RequestParameters::get('apbct_site_landing_ts', true);
if ( ! $site_landing_timestamp ) {
$site_landing_timestamp = time();
RequestParameters::set('apbct_site_landing_ts', TT::toString($site_landing_timestamp), true);
}
if ($apbct->data['cookies_type'] === 'native') {
$http_referrer = TT::toString(Server::get('HTTP_REFERER'));
// Previous referer
if ( $http_referrer ) {
Cookie::set('apbct_prev_referer', $http_referrer, 0, '/', $domain, null, true, 'Lax', true);
$cookie_test_value['cookies_names'][] = 'apbct_prev_referer';
$cookie_test_value['check_value'] = isset($cookie_test_value['check_value'])
? $cookie_test_value['check_value'] . $http_referrer
: $http_referrer;
}
}
// Cookies test
$cookie_test_value['check_value'] = md5(
isset($cookie_test_value['check_value'])
? $cookie_test_value['check_value']
: ''
);
if ( $apbct->data['cookies_type'] !== 'alternative' ) {
Cookie::set('apbct_cookies_test', urlencode(json_encode($cookie_test_value)), 0, '/', $domain, null, true);
}
$apbct->flags__cookies_setuped = true;
return $apbct->flags__cookies_setuped;
}
/**
* Store page hits. Only for native cookies mode.
* @return void
*/
function apbct_store__page_hits()
{
global $apbct;
if (
! empty($apbct->headers_sent) // Headers sent
) {
return;
}
if ( $apbct->data['cookies_type'] === 'native' && empty($apbct->page_hits_set) ) {
// Page hits
// Get
$page_hits = TT::toInt(RequestParameters::get('apbct_page_hits', true));
// Set / Increase
// todo if cookies disabled there is no way to keep this data without DB:( always will be 1
$page_hits = $page_hits ? $page_hits + 1 : 1;
RequestParameters::set('apbct_page_hits', TT::toString($page_hits), true);
$apbct->page_hits_set = true;
}
}
/**
* Cookies test for sender
* Also checks for valid timestamp in $_COOKIE['apbct_timestamp'] and other apbct_ COOKIES
* @return null|int null|0|1
* @throws JsonException
*/
function apbct_cookies_test()
{
global $apbct;
if ( $apbct->data['cookies_type'] !== 'native' || Cookie::$force_alt_cookies_global) {
return 1;
}
if ( Cookie::get('apbct_cookies_test') ) {
$apbct_cookies_test = TT::toString(Cookie::get('apbct_cookies_test'));
$cookie_test = json_decode(urldecode($apbct_cookies_test), true);
if ( ! is_array($cookie_test) ) {
return 0;
}
$check_string = $apbct->api_key;
// generate value
$cookie_names = TT::getArrayValueAsArray($cookie_test, 'cookies_names');
foreach ( $cookie_names as $cookie_name ) {
$check_string .= Cookie::get($cookie_name);
}
// check generated value with current cookie
$check_value = TT::getArrayValueAsString($cookie_test, 'check_value');
if ( $check_value === md5($check_string) ) {
return 1;
}
return 0;
}
return null;
}
/**
* Inner function - Account status check. Scheduled in 1800 seconds for default!
* @param $api_key
* @param $process_errors
* @return bool
*/
function ct_account_status_check($api_key = null, $process_errors = true)
{
global $apbct;
$api_key = $api_key ?: $apbct->api_key;
$result = API::methodNoticePaidTill(
$api_key,
preg_replace('/http[s]?:\/\//', '', get_option('home'), 1),
! is_main_site() && $apbct->white_label ? 'anti-spam-hosting' : 'antispam'
);
if ( empty($result['error']) || ! empty($result['valid']) ) {
// Notices
$apbct->data['notice_show'] = TT::getArrayValueAsInt($result, 'show_notice', 0);
$apbct->data['notice_renew'] = TT::getArrayValueAsInt($result, 'renew', 0);
$apbct->data['notice_trial'] = TT::getArrayValueAsInt($result, 'trial', 0);
$apbct->data['notice_review'] = TT::getArrayValueAsInt($result, 'show_review', 0);
if ($apbct->data['notice_show']) {
$notice_banners = API::getNoticeBanners($api_key);
if (isset($notice_banners['operation_status'], $notice_banners['banners']) && $notice_banners['operation_status'] === 'SUCCESS') {
if (isset($notice_banners['banners']['TRIAL']['level'])) {
$apbct->data['notice_trial_level'] = strtolower($notice_banners['banners']['TRIAL']['level']);
}
if (isset($notice_banners['banners']['RENEW']['level'])) {
$apbct->data['notice_renew_level'] = strtolower($notice_banners['banners']['RENEW']['level']);
}
if (isset($notice_banners['banners']['REVIEW']['level'])) {
$apbct->data['notice_review_level'] = strtolower($notice_banners['banners']['REVIEW']['level']);
}
}
}
// Other
$apbct->data['service_id'] = TT::getArrayValueAsInt($result, 'service_id', 0);
$apbct->data['user_id'] = TT::getArrayValueAsInt($result, 'user_id', 0);
$apbct->data['valid'] = TT::getArrayValueAsInt($result, 'valid', 0);
$apbct->data['moderate'] = TT::getArrayValueAsInt($result, 'moderate', 0);
$apbct->data['ip_license'] = TT::getArrayValueAsInt($result, 'ip_license', 0);
$apbct->data['spam_count'] = TT::getArrayValueAsInt($result, 'spam_count', 0);
$apbct->data['user_token'] = TT::getArrayValueAsString($result, 'user_token', '');
$apbct->data['license_trial'] = TT::getArrayValueAsInt($result, 'license_trial', 0);
$apbct->data['account_name_ob'] = TT::getArrayValueAsString($result, 'account_name_ob', '');
$apbct->data['moderate_ip'] = isset($result['moderate_ip'], $result['ip_license']) ?
TT::getArrayValueAsInt($result, 'moderate_ip', 0)
: 0;
//todo:temporary solution for description, until we found the way to transfer this from cloud
if (defined('APBCT_WHITELABEL_PLUGIN_DESCRIPTION')) {
/** @psalm-suppress PossiblyInvalidArrayAssignment */
$result['wl_antispam_description'] = APBCT_WHITELABEL_PLUGIN_DESCRIPTION;
}
//todo:temporary solution for FAQ
if (defined('APBCT_WHITELABEL_FAQ_LINK')) {
/** @psalm-suppress PossiblyInvalidArrayAssignment */
$result['wl_faq_url'] = APBCT_WHITELABEL_FAQ_LINK;
}
if ( isset($result['wl_status']) && $result['wl_status'] === 'ON' ) {
$apbct->data['wl_mode_enabled'] = true;
$apbct->data['wl_brandname'] = isset($result['wl_brandname'])
? Sanitize::cleanTextField($result['wl_brandname'])
: $apbct->default_data['wl_brandname'];
$apbct->data['wl_url'] = isset($result['wl_url'])
? Sanitize::cleanUrl($result['wl_url'])
: $apbct->default_data['wl_url'];
$apbct->data['wl_support_url'] = isset($result['wl_support_url'])
? Sanitize::cleanUrl($result['wl_support_url'])
: $apbct->default_data['wl_support_url'];
$apbct->data['wl_support_faq'] = isset($result['wl_faq_url'])
? Sanitize::cleanUrl($result['wl_faq_url'])
//important, if missed get this from already set wl_support_url for now
: $apbct->data['wl_support_url'];
$apbct->data['wl_support_email'] = isset($result['wl_support_email'])
? Sanitize::cleanEmail($result['wl_support_email'])
: $apbct->default_data['wl_support_email'];
$plugin_data_wl = get_file_data(__FILE__, array('Description' => 'Description'));
$plugin_data_wl = is_array($plugin_data_wl) && isset($plugin_data_wl['Description'])
? $plugin_data_wl['Description']
: 'No description provided';
$apbct->data['wl_antispam_description'] = isset($result['wl_antispam_description'])
? Sanitize::cleanTextField($result['wl_antispam_description'])
: $plugin_data_wl;
} else {
$apbct->data['wl_mode_enabled'] = false;
$apbct->data['wl_brandname'] = $apbct->default_data['wl_brandname'];
$apbct->data['wl_url'] = $apbct->default_data['wl_url'];
$apbct->data['wl_support_faq'] = $apbct->default_data['wl_support_url'];
$apbct->data['wl_support_url'] = $apbct->default_data['wl_support_url'];
$apbct->data['wl_support_email'] = $apbct->default_data['wl_support_email'];
}
$cron = new Cron();
$cron->updateTask('check_account_status', 'ct_account_status_check', 86400);
$apbct->errorDelete('account_check', true);
} elseif ( $process_errors ) {
$apbct->errorAdd('account_check', $result);
}
if ( ! empty($result['valid']) ) {
$apbct->data['key_is_ok'] = true;
$result = true;
} else {
$apbct->data['key_is_ok'] = false;
$result = false;
}
$apbct->saveData();
return $result;
}
/**
* Send connection reports cron wrapper.
* If setting misc__send_connection_reports is disabled there will no reports sen on cron.
*/
function ct_cron_send_connection_report_email()
{
global $apbct;
if (isset($apbct->settings['misc__send_connection_reports']) && $apbct->settings['misc__send_connection_reports'] == 1) {
$apbct->getConnectionReports()->sendUnsentReports(true);
}
}
/**
* Send js errors reports cron wrapper.
* If setting misc__send_connection_reports is disabled there will no reports sen on cron.
*/
function ct_cron_send_js_error_report_email()
{
global $apbct;
if (isset($apbct->settings['misc__send_connection_reports']) && $apbct->settings['misc__send_connection_reports'] == 1) {
$apbct->getJsErrorsReport()->sendEmail(true);
}
}
/**
* Cron job handler
* Clear old alt-cookies/no-cookies from the database
*
* @return void
*/
function apbct_cron_clear_old_session_data()
{
global $wpdb, $apbct;
$query = $wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like(APBCT_TBL_SESSIONS));
$session_table_exists = $wpdb->get_var($query);
if (empty($session_table_exists)) {
return;
}
$res = \Cleantalk\ApbctWP\Variables\AltSessions::cleanFromOld();
$session_clear_log = get_option('cleantalk_sessions_clear_log', []);
$session_clear_log[] = array(
'time' => time(),
'result' => $res,
);
$session_clear_log = array_slice((array)$session_clear_log, -4, 4, true);
update_option('cleantalk_sessions_clear_log', $session_clear_log);
$ct_cron = new Cron();
if (\Cleantalk\ApbctWP\Variables\AltSessions::checkHasUndeletedOldSessions()) {
$ct_cron->updateTask('clear_old_session_data', 'apbct_cron_clear_old_session_data', 60, time() + 60);
} else {
$ct_cron->updateTask('clear_old_session_data', 'apbct_cron_clear_old_session_data', 86400);
}
}
/**
* @param $blog_id
* @param $_drop
*
* @return void
* @psalm-suppress UnusedParam
*/
function apbct_sfw__delete_tables($blog_id)
{
global $wpdb;
$initial_blog = get_current_blog_id();
switch_to_blog($blog_id);
$wpdb->query('DROP TABLE IF EXISTS `' . $wpdb->prefix . 'cleantalk_sfw`;'); // Deleting SFW data
$wpdb->query('DROP TABLE IF EXISTS `' . $wpdb->prefix . 'cleantalk_sfw_logs`;'); // Deleting SFW logs
$wpdb->query('DROP TABLE IF EXISTS `' . $wpdb->prefix . 'cleantalk_ac_log`;'); // Deleting SFW logs
$wpdb->query('DROP TABLE IF EXISTS `' . $wpdb->prefix . 'cleantalk_ua_bl`;'); // Deleting AC UA black lists
switch_to_blog($initial_blog);
}
/**
* Is enable for user group
*
* @param WP_User $user
*
* @return boolean
*/
function apbct_is_user_enable($user = null)
{
global $current_user;
$user = $user !== null ? $user : $current_user;
return ! (apbct_is_user_role_in(array('administrator', 'editor', 'author'), $user) || apbct_is_super_admin());
}
/**
* Checks if the current user has role
*
* @param array $roles array of strings
* @param int|string|WP_User|mixed $user User ID to check|user_login|WP_User
*
* @return boolean Does the user has this role|roles
*/
function apbct_is_user_role_in($roles, $user = false)
{
if ( is_numeric($user) && function_exists('get_userdata') ) {
$user = get_userdata((int)$user);
}
if ( is_string($user) && function_exists('get_user_by') ) {
$user = get_user_by('login', $user);
}
if ( ! $user && function_exists('wp_get_current_user') ) {
$user = wp_get_current_user();
}
if ( ! $user ) {
$user = apbct_wp_get_current_user();
}
if ( !is_object($user) || empty($user->ID) ) {
return false;
}
foreach ( (array)$roles as $role ) {
if ( isset($user->caps[strtolower($role)]) || in_array(strtolower($role), $user->roles) ) {
return true;
}
}
return false;
}
/**
* Update and rotate statistics with requests execution time
*
* @param $exec_time
*/
function apbct_statistics_rotate($exec_time)
{
global $apbct;
$requests_counters = array_keys($apbct->stats['requests']);
if ( !empty($requests_counters) ) {
// Delete old stats
$min_request_count_key = min($requests_counters);
if ( $min_request_count_key < time() - (86400 * 7) ) {
unset($apbct->stats['requests'][$min_request_count_key]);
}
// Create new if newest older than 1 day
$max_request_count_key = max($requests_counters);
if ( $max_request_count_key < time() - (86400 * 1) ) {
$apbct->stats['requests'][time()] = array('amount' => 0, 'average_time' => 0);
}
}
// Update all existing stats
foreach ( $apbct->stats['requests'] as &$weak_stat ) {
$weak_stat['average_time'] = ($weak_stat['average_time'] * $weak_stat['amount'] + $exec_time) / ++$weak_stat['amount'];
}
unset($weak_stat);
$apbct->save('stats');
}
/**
* Runs update actions for new version.
*
* @global State $apbct
*/
function apbct_update_actions()
{
global $apbct;
// Update logic
if ( $apbct->plugin_version !== APBCT_VERSION ) {
// Perform a transaction and exit transaction ID isn't match
if ( ! Transaction::get('updater')->perform() ) {
return;
}
// Main blog
if ( is_main_site() ) {
require_once(CLEANTALK_PLUGIN_DIR . 'inc/cleantalk-updater.php');
$result = apbct_run_update_actions($apbct->plugin_version, APBCT_VERSION);
//If update is successful
if ( $result === true ) {
apbct_update__set_version__from_plugin('from_plugin');
}
ct_send_feedback('0:' . APBCT_AGENT); // Send feedback to let cloud know about updated version.
// Side blogs
} else {
apbct_update__set_version__from_plugin('from_plugin');
}
}
}
/**
* Set version of plugin in database
*
* @param string $ver
*
* @return bool
* @global State $apbct
*
*/
function apbct_update__set_version__from_plugin($ver)
{
global $apbct;
switch ( true ) {
case $ver === 'from_plugin':
$apbct->data['plugin_version'] = APBCT_VERSION;
break;
case preg_match('/^\d+\.\d+(\.\d+)?(-[a-zA-Z0-9-_]+)?$/', $ver) === 1:
$apbct->data['plugin_version'] = $ver;
break;
default:
return false;
}
$apbct->saveData();
return true;
}
function apbct_sfw_update_sentinel__run_watchdog()
{
global $apbct;
$apbct->sfw_update_sentinel->runWatchDog();
}
/**
* Cron wrapper. Remove support user.
* @return void
*/
function apbct_cron_remove_support_user()
{
$temp_user_service = new \Cleantalk\ApbctWP\SupportUser();
$temp_user_service->performCronDeleteUser();
}
/**
* This is a helper function to avoid code duplication on build ContactsEncoder object
* @return ContactsEncoder
*/
function apbctGetContactsEncoder()
{
global $apbct;
$contacts_encoder_params = new Params();
$contacts_encoder_params->api_key = $apbct->api_key;
$contacts_encoder_params->is_logged_in = apbct_is_user_logged_in();
$contacts_encoder_params->obfuscation_mode = $apbct->settings['data__email_decoder_obfuscation_mode'];
$contacts_encoder_params->obfuscation_text = $apbct->settings['data__email_decoder_obfuscation_custom_text'];
$contacts_encoder_params->do_encode_emails = (int)$apbct->settings['data__email_decoder_encode_email_addresses'];
$contacts_encoder_params->do_encode_phones = (int)$apbct->settings['data__email_decoder_encode_phone_numbers'];
return ContactsEncoder::getInstance($contacts_encoder_params);
}