'', 'subscription' => 'basic', 'threshold_exceeded' => false, 'activation_datetime' => 0 ]; private $x_api_key = 'hudft60djisdusdjwek'; private $app_host_url = 'https://app.hu-manity.co'; private $app_login_url = 'https://app.hu-manity.co/#/login'; private $app_dashboard_url = 'https://app.hu-manity.co/#/'; private $account_api_url = 'https://account-api.hu-manity.co'; private $designer_api_url = 'https://designer-api.hu-manity.co'; private $transactional_api_url = 'https://transactional-api.hu-manity.co'; private $app_widget_url = '//cdn.hu-manity.co/hu-banner.min.js'; private $deactivaion_url = ''; private $network_admin = false; private $plugin_network_active = false; private static $_instance; private $notices = []; public $options = []; public $network_options = []; public $bot_detect; public $dashboard; public $frontend; public $settings; public $consent_logs; public $privacy_consent; public $privacy_consent_logs; public $welcome; public $welcome_api; public $welcome_frontend; public $db_version; /** * @var $defaults */ public $defaults = [ 'general' => [ 'global_override' => false, 'global_cookie' => false, 'app_id' => '', 'app_key' => '', 'app_blocking' => true, 'conditional_active' => false, 'conditional_display' => 'hide', 'conditional_rules' => [], 'amp_support' => false, 'bot_detection' => true, 'caching_compatibility' => true, 'debug_mode' => false, 'position' => 'bottom', 'message_text' => '', 'css_class' => '', 'accept_text' => '', 'refuse_text' => '', 'refuse_opt' => false, 'refuse_code' => '', 'refuse_code_head' => '', 'revoke_cookies' => false, 'revoke_cookies_opt' => 'automatic', 'revoke_message_text' => '', 'revoke_text' => '', 'redirection' => false, 'see_more' => false, 'link_target' => '_blank', 'link_position' => 'banner', 'time' => 'month', 'time_rejected' => 'month', 'hide_effect' => 'fade', 'on_scroll' => false, 'on_scroll_offset' => 100, 'on_click' => false, 'colors' => [ 'text' => '#fff', 'button' => '#00a99d', 'bar' => '#32323a', 'bar_opacity' => 100 ], 'see_more_opt' => [ 'text' => '', 'link_type' => 'page', 'id' => 0, 'link' => '', 'sync' => false ], 'script_placement' => 'header', 'translate' => true, 'deactivation_delete' => false, 'review_notice' => true, 'review_notice_delay' => 0, 'update_version' => 8, 'update_notice' => true, 'update_notice_diss' => false, 'update_delay_date' => 0, 'update_threshold_date' => 0, 'csp_notice' => false ], 'privacy_consent' => [ 'wordpress_active' => true, 'wordpress_active_type' => 'all', 'contactform7_active' => false, 'contactform7_active_type' => 'all', 'mailchimp_active' => false, 'mailchimp_active_type' => 'all', 'wpforms_active' => false, 'wpforms_active_type' => 'all', 'woocommerce_active' => false, 'woocommerce_active_type' => 'all', 'formidableforms_active' => false, 'formidableforms_active_type' => 'all', 'easydigitaldownloads_active' => false, 'easydigitaldownloads_active_type' => 'all' ], 'data' => [ 'status' => '', 'subscription' => 'basic', 'threshold_exceeded' => false, 'activation_datetime' => 0 ], 'version' => '2.5.13' ]; /** * Disable object cloning. * * @return void */ public function __clone() {} /** * Disable unserializing of the class. * * @return void */ public function __wakeup() {} /** * Main plugin instance. * * @return object */ public static function instance() { if ( self::$_instance === null ) { self::$_instance = new self(); add_action( 'init', [ self::$_instance, 'load_textdomain' ] ); self::$_instance->includes(); self::$_instance->bot_detect = new Cookie_Notice_Bot_Detect(); self::$_instance->dashboard = new Cookie_Notice_Dashboard(); self::$_instance->frontend = new Cookie_Notice_Frontend(); self::$_instance->settings = new Cookie_Notice_Settings(); self::$_instance->consent_logs = new Cookie_Notice_Consent_Logs(); self::$_instance->privacy_consent = new Cookie_Notice_Privacy_Consent(); self::$_instance->privacy_consent_logs = new Cookie_Notice_Privacy_Consent_Logs(); self::$_instance->welcome = new Cookie_Notice_Welcome(); self::$_instance->welcome_api = new Cookie_Notice_Welcome_API(); self::$_instance->welcome_frontend = new Cookie_Notice_Welcome_Frontend(); } return self::$_instance; } /** * Class constructor. * * @return void */ public function __construct() { // define plugin constants $this->define_constants(); // activation hooks register_activation_hook( __FILE__, [ $this, 'activation' ] ); register_deactivation_hook( __FILE__, [ $this, 'deactivation' ] ); // set network data $this->set_network_data(); $this->check_legacy_options(); // get options if ( is_multisite() ) { // get network options $this->network_options['general'] = get_site_option( 'cookie_notice_options', $this->defaults['general'] ); $this->network_options['privacy_consent'] = get_site_option( 'cookie_notice_privacy_consent', $this->defaults['privacy_consent'] ); if ( $this->is_network_admin() ) { $general_options = $this->network_options['general']; $privacy_consent_options = $this->network_options['privacy_consent']; } else { $page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : ''; // settings page? if ( is_admin() && $page === 'cookie-notice' ) { // get current url path $url_path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ); if ( is_string( $url_path ) && basename( $url_path ) === 'admin.php' ) { // get site options $general_options = get_option( 'cookie_notice_options', $this->defaults['general'] ); $privacy_consent_options = get_option( 'cookie_notice_privacy_consent', $this->defaults['privacy_consent'] ); } } else { if ( $this->is_plugin_network_active() && $this->network_options['general']['global_override'] ) { $general_options = $this->network_options['general']; $privacy_consent_options = $this->network_options['privacy_consent']; } else { $general_options = get_option( 'cookie_notice_options', $this->defaults['general'] ); $privacy_consent_options = get_option( 'cookie_notice_privacy_consent', $this->defaults['privacy_consent'] ); } } } } else { $general_options = get_option( 'cookie_notice_options', $this->defaults['general'] ); $privacy_consent_options = get_option( 'cookie_notice_privacy_consent', $this->defaults['privacy_consent'] ); } // merge old options with new ones $this->options['general'] = $this->multi_array_merge( $this->defaults['general'], $general_options ); $this->options['privacy_consent'] = $this->multi_array_merge( $this->defaults['privacy_consent'], $privacy_consent_options ); if ( ! isset( $this->options['general']['see_more_opt']['sync'] ) ) $this->options['general']['see_more_opt']['sync'] = $this->defaults['general']['see_more_opt']['sync']; // actions add_action( 'plugins_loaded', [ $this, 'set_database_version' ], 0 ); add_action( 'plugins_loaded', [ $this, 'set_status_data' ], 0 ); add_action( 'init', [ $this, 'register_shortcodes' ] ); add_action( 'init', [ $this, 'wpsc_add_cookie' ] ); add_action( 'init', [ $this, 'set_plugin_links' ] ); add_action( 'admin_init', [ $this, 'update_notice' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] ); add_action( 'admin_footer', [ $this, 'deactivate_plugin_template' ] ); add_action( 'wp_ajax_cn_dismiss_notice', [ $this, 'ajax_dismiss_admin_notice' ] ); add_action( 'wp_ajax_cn_review_notice', [ $this, 'ajax_review_notice' ] ); add_action( 'wp_ajax_cn-deactivate-plugin', [ $this, 'deactivate_plugin' ] ); } /** * Set current plugin version from database. * * @return void */ public function set_database_version() { // get current version if ( $this->is_network_admin() ) $this->db_version = get_site_option( 'cookie_notice_version', '1.0.0' ); else $this->db_version = get_option( 'cookie_notice_version', '1.0.0' ); } /** * Check legacy options. * * @return void */ public function check_legacy_options() { // multisite? if ( is_multisite() ) { // get network options $site_options = get_site_option( 'cookie_notice_options', $this->defaults['general'] ); // update legacy options $site_options = $this->update_legacy_options( $site_options ); // any changes? if ( $site_options !== false ) update_site_option( 'cookie_notice_options', $site_options ); } // get options $options = get_option( 'cookie_notice_options', $this->defaults['general'] ); // update legacy options $options = $this->update_legacy_options( $options ); // any changes? if ( $options !== false ) update_option( 'cookie_notice_options', $options ); } /** * Maybe change legacy options. * * @param array $options * @return false|array */ public function update_legacy_options( $options ) { // bail out if options are missing or invalid to avoid PHP 8 fatal on non-array values if ( ! is_array( $options ) ) return $this->defaults['general']; $options_changed = false; // check legacy parameters that were yes/no strings foreach ( [ 'refuse_opt', 'on_scroll', 'on_click', 'deactivation_delete', 'see_more' ] as $param ) { if ( array_key_exists( $param, $options ) && ! is_bool( $options[$param] ) ) { $options[$param] = $options[$param] === 'yes'; $options_changed = true; } } // check hide banner if ( isset( $options['hide_banner'] ) ) { if ( $options['hide_banner'] && ! isset( $options['conditional_active'] ) ) { $options['conditional_active'] = true; $options['conditional_display'] = 'hide'; $options['conditional_rules'] = [ 1 => [ 1 => [ 'param' => 'user_type', 'operator' => 'equal', 'value' => 'logged_in' ] ] ]; } unset( $options['hide_banner'] ); $options_changed = true; } if ( $options_changed ) return $options; else return false; } /** * Setup plugin constants. * * @return void */ private function define_constants() { define( 'COOKIE_NOTICE_URL', plugins_url( '', __FILE__ ) ); define( 'COOKIE_NOTICE_PATH', plugin_dir_path( __FILE__ ) ); define( 'COOKIE_NOTICE_BASENAME', plugin_basename( __FILE__ ) ); define( 'COOKIE_NOTICE_REL_PATH', dirname( COOKIE_NOTICE_BASENAME ) ); } /** * Set cookie compliance status data. * * @return void */ public function set_status_data() { $default_data = $this->defaults['data']; if ( is_multisite() ) { if ( $this->is_plugin_network_active() ) { // network if ( $this->is_network_admin() ) { if ( $this->network_options['general']['global_override'] ) $status_data = get_site_option( 'cookie_notice_status', $default_data ); else $status_data = $default_data; // site } else { if ( $this->network_options['general']['global_override'] ) $status_data = get_site_option( 'cookie_notice_status', $default_data ); else $status_data = get_option( 'cookie_notice_status', $default_data ); } } else { // network if ( $this->is_network_admin() ) $status_data = $default_data; // site else $status_data = get_option( 'cookie_notice_status', $default_data ); } } else $status_data = get_option( 'cookie_notice_status', $default_data ); // old status format? if ( ! is_array( $status_data ) ) { // update config data $status_data = $this->welcome_api->get_app_config( '', true ); } else { // merge database data with default data $status_data = array_merge( $default_data, $status_data ); } if ( $status_data['threshold_exceeded'] ) $this->options['general']['app_blocking'] = false; // check status $status = $this->check_status( $status_data['status'] ); // no activation timestamp? if ( empty( $status_data['activation_datetime'] ) ) { if ( $status === 'active' ) $activation = time(); else $activation = 0; } else $activation = (int) $status_data['activation_datetime']; // set status data $this->status_data = [ 'status' => $status, 'subscription' => $this->check_subscription( $status_data['subscription'] ), 'threshold_exceeded' => (bool) $status_data['threshold_exceeded'], 'activation_datetime' => $activation ]; } /** * Get cookie compliance status data. * * @return string */ public function get_status_data() { return $this->status_data; } /** * Get cookie compliance status. * * @return string */ public function get_status() { return $this->status_data['status']; } /** * Check cookie compliance status. * * @param string $status * @return string */ public function check_status( $status ) { $status = sanitize_key( $status ); return ! empty( $status ) && in_array( $status, [ 'active', 'pending' ], true ) ? $status : $this->defaults['data']['status']; } /** * Get cookie compliance subscription. * * @return string */ public function get_subscription() { return $this->status_data['subscription']; } /** * Check cookie compliance subscription. * * @param string $subscription * @return string */ public function check_subscription( $subscription ) { $subscription = sanitize_key( $subscription ); return ! empty( $subscription ) && in_array( $subscription, [ 'basic', 'pro' ], true ) ? $subscription : $this->defaults['data']['subscription']; } /** * Check whether the current threshold is exceeded. * * @return bool */ public function threshold_exceeded() { return $this->status_data['threshold_exceeded']; } /** * Get cookie compliance activation timestamp. * * @return int */ public function get_cc_activation_datetime() { return (int) $this->status_data['activation_datetime']; } /** * Get endpoint URL. * * @param string $type * @param string $query * @return string */ public function get_url( $type, $query = '' ) { if ( $type === 'login' ) $url = $this->app_login_url; elseif ( $type === 'dashboard' ) $url = $this->app_dashboard_url; elseif ( $type === 'widget' ) $url = $this->app_widget_url; elseif ( $type === 'host' ) $url = $this->app_host_url; elseif ( $type === 'account_api' ) $url = $this->account_api_url; elseif ( $type === 'designer_api' ) $url = $this->designer_api_url; elseif ( $type === 'transactional_api' ) $url = $this->transactional_api_url; return $url . ( $query !== '' ? $query : '' ); } /** * Get API key. * * @return string */ public function get_api_key() { return $this->x_api_key; } /** * Check whether the current request is for the network administrative interface. * * @return bool */ public function is_network_admin() { return $this->network_admin; } /** * Check whether the plugin is active for the entire network. * * @return bool */ public function is_plugin_network_active() { return $this->plugin_network_active; } /** * Set network data. * * @return void */ private function set_network_data() { // load plugin.php file if ( ! function_exists( 'is_plugin_active_for_network' ) ) require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); $cn_network = isset( $_POST['cn_network'] ) ? (int) $_POST['cn_network'] : false; // bypass is_network_admin() to handle AJAX requests properly. $this->network_admin = is_multisite() && ( is_network_admin() || ( wp_doing_ajax() && $cn_network === 1 ) ); // check whether the plugin is active for the entire network. $this->plugin_network_active = is_plugin_active_for_network( COOKIE_NOTICE_BASENAME ); } /** * Include required files. * * @return void */ private function includes() { include_once( COOKIE_NOTICE_PATH . 'includes/bot-detect.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/dashboard.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/frontend.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/functions.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/settings.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/consent-logs.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/privacy-consent.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/privacy-consent-logs.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/welcome.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/welcome-api.php' ); include_once( COOKIE_NOTICE_PATH . 'includes/welcome-frontend.php' ); } /** * Load textdomain. * * @return void */ public function load_textdomain() { load_plugin_textdomain( 'cookie-notice', false, dirname( COOKIE_NOTICE_BASENAME ) . '/languages/' ); } /** * Plugin activation. * * @global object $wpdb * * @param bool $network * @return void */ public function activation( $network ) { // network activation? if ( is_multisite() && $network ) { // add network options add_site_option( 'cookie_notice_options', $this->defaults['general'] ); add_site_option( 'cookie_notice_privacy_consent', $this->defaults['privacy_consent'] ); add_site_option( 'cookie_notice_status', $this->defaults['data'] ); add_site_option( 'cookie_notice_version', $this->defaults['version'] ); global $wpdb; // get all available sites $blogs_ids = $wpdb->get_col( 'SELECT blog_id FROM ' . $wpdb->blogs ); foreach ( $blogs_ids as $blog_id ) { // change to another site switch_to_blog( (int) $blog_id ); // run current site activation process $this->activate_site(); restore_current_blog(); } } else $this->activate_site(); } /** * Single site activation. * * @return void */ public function activate_site() { // add default options add_option( 'cookie_notice_options', $this->defaults['general'], null, false ); add_option( 'cookie_notice_privacy_consent', $this->defaults['privacy_consent'], null, false ); add_option( 'cookie_notice_status', $this->defaults['data'], null, false ); add_option( 'cookie_notice_version', $this->defaults['version'], null, false ); } /** * Plugin deactivation. * * @global object $wpdb * * @param bool $network * @return void */ public function deactivation( $network ) { // network deactivation? if ( is_multisite() && $network ) { $delete = $this->options['general']['global_override'] && $this->options['general']['deactivation_delete']; // delete network options? if ( $delete ) { delete_site_option( 'cookie_notice_options' ); delete_site_option( 'cookie_notice_privacy_consent' ); delete_site_option( 'cookie_notice_status' ); delete_site_option( 'cookie_notice_app_analytics' ); delete_site_option( 'cookie_notice_app_blocking' ); delete_site_option( 'cookie_notice_version' ); } global $wpdb; // get all available sites $blogs_ids = $wpdb->get_col( 'SELECT blog_id FROM ' . $wpdb->blogs ); foreach ( $blogs_ids as $blog_id ) { // change to another site switch_to_blog( (int) $blog_id ); // run current site deactivation process $this->deactivate_site( $delete ); restore_current_blog(); } } else $this->deactivate_site(); } /** * Single site deactivation. * * @param bool $force_deletion * @return void */ public function deactivate_site( $force_deletion = false ) { // delete settings? if ( $force_deletion || $this->options['general']['deactivation_delete'] ) { // delete options delete_option( 'cookie_notice_options' ); delete_option( 'cookie_notice_privacy_consent' ); delete_option( 'cookie_notice_status' ); delete_option( 'cookie_notice_app_analytics' ); delete_option( 'cookie_notice_app_blocking' ); delete_option( 'cookie_notice_version' ); // delete transients if any delete_transient( 'cookie_notice_app_token' ); delete_transient( 'cookie_notice_app_quick_config' ); delete_transient( 'cookie_notice_app_subscriptions' ); } // remove wp super cache cookie $this->wpsc_delete_cookie(); } /** * Update notice. * * @return void */ public function update_notice() { if ( ! current_user_can( 'install_plugins' ) ) return; // bail an ajax if ( wp_doing_ajax() ) return; $network = $this->is_network_admin(); // get cookie compliance status $status = $this->get_status(); // get subscription $subscription = $this->get_subscription(); // update number $current_update = 14; // new version? if ( version_compare( $this->db_version, $this->defaults['version'], '<' ) ) { if ( $this->options['general']['update_version'] < $current_update ) { // check version, if update version is lower than plugin version, set update notice to true $this->options['general']['update_version'] = $current_update; $this->options['general']['update_notice'] = true; // update options if ( $network ) { $this->options['general']['update_notice_diss'] = false; update_site_option( 'cookie_notice_options', $this->options['general'] ); } else update_option( 'cookie_notice_options', $this->options['general'] ); } // update 2.4.17+ if ( version_compare( $this->db_version, '2.4.17', '<' ) ) { // get cookie compliance activation timestamp $activation_date = $this->get_cc_activation_datetime(); // get status data $data = $this->status_data; // no activation timestamp? if ( empty( $activation_date ) ) { if ( $status === 'active' ) $activation = time(); else $activation = 0; } else $activation = (int) $data['activation_datetime']; // update activation timestamp $data['activation_datetime'] = $activation; if ( $network ) update_site_option( 'cookie_notice_status', $data ); else update_option( 'cookie_notice_status', $data, false ); } // update plugin version if ( $network ) update_site_option( 'cookie_notice_version', $this->defaults['version'] ); else update_option( 'cookie_notice_version', $this->defaults['version'], false ); } // check page $page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : ''; // if visiting settings, mark notice as read if ( $page === 'cookie-notice' && ! empty( $_GET['welcome'] ) ) { $this->options['general']['update_notice'] = false; if ( $network ) { $this->options['general']['update_notice_diss'] = true; update_site_option( 'cookie_notice_options', $this->options['general'] ); } else update_option( 'cookie_notice_options', $this->options['general'] ); } if ( is_multisite() && ( ( $this->is_plugin_network_active() && ! $network && $this->network_options['general']['global_override'] ) || ( $network && ! $this->is_plugin_network_active() ) ) ) $this->options['general']['update_notice'] = false; // show notice, if no compliance only if ( $this->options['general']['update_notice'] === true ) { if ( empty( $status ) ) { $this->add_notice( '
' . __( 'Microsoft will start enforcing Clarity Consent API v2 on October 31, 2025, for visitors from the EEA, UK, and Switzerland. Sites without valid consent signals may lose access to key analytics and advertising data. Cookie Compliance makes it effortless — automatically syncing user consent with Clarity, Microsoft Ads, and more.', 'cookie-notice' ) . ' ' . __( "Add compliance features today and upgrade later to unlock advanced integrations.", 'cookie-notice' ) . '
' . esc_html__( 'Add Compliance features', 'cookie-notice' ) . ' ' . esc_html__( 'Dismiss Notice', 'cookie-notice' ) . '
' . __( 'Cookie Compliance now supports Microsoft Clarity Consent API v2, ensuring consent is automatically synchronized between your site, Clarity analytics, and Microsoft Ads. Starting October 31, 2025, Microsoft will require valid consent signals for all visitors from the EEA, UK, and Switzerland. Sites without valid it may lose access to key analytics and advertising data.', 'cookie-notice' ) . ' ' . __( "Upgrade to Pro today to stay compliant and keep your analytics running smoothly — no code required.", 'cookie-notice' ) . '
' . esc_html__( 'Upgrade to Pro', 'cookie-notice' ) . ' ' . esc_html__( 'Dismiss Notice', 'cookie-notice' ) . '
' . sprintf( __( 'Your website has reached the %1$s visits usage limit for the Cookie Compliance Basic Plan. Compliance services such as Consent Record Storage, Autoblocking, and Consent Analytics have been deactivated until current usage cycle ends on %2$s.', 'cookie-notice' ), $threshold, $cycle_date ) . '
' . sprintf( __( 'To reactivate compliance services now, upgrade your domain to a Pro plan.', 'cookie-notice' ) . '
' . sprintf( __( "Hi, you've been using Cookie Notice & Compliance for GDPR / CCPA for more than %s. We hope it has been a valuable addition to your WordPress site. We would be grateful if you could take a few minutes to share your thoughts by leaving a review.", 'cookie-notice' ), human_time_diff( $activation_date, $current_time ) ) . '
' . esc_html__( 'Thank you for helping us improve and grow!', 'cookie-notice' ) . '
' . esc_html__( 'Review', 'cookie-notice' ) . '' . esc_html__( 'Delay', 'cookie-notice' ) . '' . esc_html__( 'Dismiss', 'cookie-notice' ) . '