array(
'name' => 'Necessary',
'description' => 'Essential for website functionality',
'required' => true,
'color' => '#2c3e50'
),
'analytics' => array(
'name' => 'Analytics',
'description' => 'Help us understand how visitors use our site',
'required' => false,
'color' => '#ff6b35'
),
'marketing' => array(
'name' => 'Marketing',
'description' => 'Used to track visitors and display relevant ads',
'required' => false,
'color' => '#f7931e'
),
'preferences' => array(
'name' => 'Preferences',
'description' => 'Remember your settings and preferences',
'required' => false,
'color' => '#3498db'
)
);
/**
* Get instance
*/
public static function instance() {
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
private function __construct() {
$this->init_consent_whisker();
}
/**
* Initialize cookie consent whisker
*/
private function init_consent_whisker() {
// Frontend hooks
add_action('wp_footer', array($this, 'render_consent_banner'), 999);
add_action('wp_enqueue_scripts', array($this, 'enqueue_consent_assets'));
// AJAX handlers
add_action('wp_ajax_tigerstyle_whiskers_update_consent', array($this, 'handle_consent_update'));
add_action('wp_ajax_nopriv_tigerstyle_whiskers_update_consent', array($this, 'handle_consent_update'));
// Admin hooks
if (is_admin()) {
add_action('admin_post_update_cookie_consent_settings', array($this, 'handle_settings_update'));
}
// Check consent status on init
add_action('init', array($this, 'check_consent_status'));
// Integrate with TigerStyle Heat Analytics
add_action('init', array($this, 'integrate_with_analytics'));
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('TigerStyle Whiskers: Cookie consent whisker is alert and ready!');
}
}
/**
* Check current consent status
*/
public function check_consent_status() {
$this->consent_status = $this->get_visitor_consent();
// If no consent recorded and GDPR applies, show banner
if (TigerStyleWhiskers_BoundaryDetector::is_gdpr_territory() && !$this->has_consent_choice()) {
$this->consent_status['show_banner'] = true;
}
}
/**
* Get visitor consent from cookies
*/
private function get_visitor_consent() {
$default_consent = array(
'necessary' => true, // Always true
'analytics' => false,
'marketing' => false,
'preferences' => false,
'timestamp' => null,
'version' => null,
'show_banner' => false
);
// Check for consent cookie
$consent_cookie = isset($_COOKIE['tigerstyle_whiskers_consent']) ?
json_decode(stripslashes($_COOKIE['tigerstyle_whiskers_consent']), true) :
array();
return array_merge($default_consent, $consent_cookie ?: array());
}
/**
* Check if visitor has made a consent choice
*/
private function has_consent_choice() {
return !empty($this->consent_status['timestamp']);
}
/**
* Enqueue consent assets
*/
public function enqueue_consent_assets() {
// Only enqueue if we need to show consent UI
if (!$this->should_show_consent_ui()) {
return;
}
wp_enqueue_style(
'tigerstyle-whiskers-consent',
TIGERSTYLE_WHISKERS_PLUGIN_URL . 'assets/css/consent.css',
array(),
TIGERSTYLE_WHISKERS_VERSION
);
wp_enqueue_script(
'tigerstyle-whiskers-consent',
TIGERSTYLE_WHISKERS_PLUGIN_URL . 'assets/js/consent.js',
array('jquery'),
TIGERSTYLE_WHISKERS_VERSION,
true
);
// Localize script
wp_localize_script('tigerstyle-whiskers-consent', 'tigerstyleWhiskersConsent', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('tigerstyle_whiskers_consent'),
'categories' => $this->cookie_categories,
'current_consent' => $this->consent_status,
'strings' => array(
'accept_all' => __('Accept All Cookies', 'tigerstyle-whiskers'),
'accept_necessary' => __('Accept Necessary Only', 'tigerstyle-whiskers'),
'customize' => __('Customize Settings', 'tigerstyle-whiskers'),
'save_preferences' => __('Save My Preferences', 'tigerstyle-whiskers'),
'privacy_policy' => __('Privacy Policy', 'tigerstyle-whiskers'),
'learn_more' => __('Learn More', 'tigerstyle-whiskers'),
)
));
}
/**
* Should we show consent UI?
*/
private function should_show_consent_ui() {
// Show if GDPR applies and no consent recorded
return TigerStyleWhiskers_BoundaryDetector::is_gdpr_territory() && !$this->has_consent_choice();
}
/**
* Render consent banner
*/
public function render_consent_banner() {
if (!$this->should_show_consent_ui()) {
return;
}
$settings = $this->get_consent_settings();
?>
get_whiskers_icon(); ?>
get_default_banner_message()); ?>
cookie_categories as $key => $category): ?>
has_consent_choice()): ?>
';
}
/**
* Get default banner message
*/
private function get_default_banner_message() {
return sprintf(
__('We use cookies to enhance your browsing experience and analyze our traffic. Some cookies are essential for our website to function properly. %s', 'tigerstyle-whiskers'),
'' . __('Your choice matters to us - just like a cat choosing where to sit!', 'tigerstyle-whiskers') . ''
);
}
/**
* Handle consent update via AJAX
*/
public function handle_consent_update() {
// Verify nonce
if (!wp_verify_nonce($_POST['nonce'], 'tigerstyle_whiskers_consent')) {
wp_die(__('Security check failed', 'tigerstyle-whiskers'));
}
$consent_data = array(
'necessary' => true, // Always true
'analytics' => isset($_POST['analytics']) && $_POST['analytics'] === 'true',
'marketing' => isset($_POST['marketing']) && $_POST['marketing'] === 'true',
'preferences' => isset($_POST['preferences']) && $_POST['preferences'] === 'true',
'timestamp' => current_time('timestamp'),
'version' => TIGERSTYLE_WHISKERS_VERSION,
'ip_hash' => hash('sha256', TigerStyleWhiskers_BoundaryDetector::instance()->get_visitor_ip()),
'user_agent_hash' => hash('sha256', $_SERVER['HTTP_USER_AGENT'] ?? ''),
);
// Set consent cookie (365 days)
setcookie(
'tigerstyle_whiskers_consent',
json_encode($consent_data),
time() + (365 * 24 * 60 * 60),
'/',
'',
is_ssl(),
false // Not HTTP-only so JavaScript can read it
);
// Log consent (for audit trail)
$this->log_consent_change($consent_data, 'user_choice');
// Trigger analytics integration if consent given
if ($consent_data['analytics']) {
$this->trigger_analytics_activation();
}
wp_send_json_success(array(
'message' => __('Your preferences have been saved with feline precision!', 'tigerstyle-whiskers'),
'consent' => $consent_data
));
}
/**
* Log consent change for audit trail
*/
private function log_consent_change($consent_data, $trigger) {
if (class_exists('TigerStyleWhiskers_AuditTrail')) {
TigerStyleWhiskers_AuditTrail::log_event(array(
'event_type' => 'consent_change',
'trigger' => $trigger,
'consent_data' => $consent_data,
'ip_hash' => $consent_data['ip_hash'],
'user_agent_hash' => $consent_data['user_agent_hash'],
'timestamp' => $consent_data['timestamp']
));
}
}
/**
* Trigger analytics activation
*/
private function trigger_analytics_activation() {
// Integrate with TigerStyle Heat if available
if (class_exists('TigerStyleSEO_Google_setup')) {
// Analytics can now be activated
do_action('tigerstyle_whiskers_analytics_consent_granted');
}
}
/**
* Integrate with analytics
*/
public function integrate_with_analytics() {
// Check if analytics consent is given
if ($this->has_analytics_consent()) {
// Allow analytics to run
add_filter('tigerstyle_heat_analytics_allowed', '__return_true');
} else {
// Block analytics
add_filter('tigerstyle_heat_analytics_allowed', '__return_false');
// Remove analytics hooks if GDPR applies
if (TigerStyleWhiskers_BoundaryDetector::is_gdpr_territory()) {
$this->block_analytics_until_consent();
}
}
}
/**
* Check if analytics consent is given
*/
public function has_analytics_consent() {
return isset($this->consent_status['analytics']) && $this->consent_status['analytics'] === true;
}
/**
* Block analytics until consent
*/
private function block_analytics_until_consent() {
// Remove Google Analytics injection
if (class_exists('TigerStyleSEO_Google_setup')) {
$google_setup = TigerStyleSEO_Google_setup::instance();
remove_action('wp_head', array($google_setup, 'inject_google_analytics'), 2);
}
// Add placeholder script that activates after consent
add_action('wp_head', array($this, 'inject_consent_conditional_analytics'), 2);
}
/**
* Inject consent-conditional analytics
*/
public function inject_consent_conditional_analytics() {
if (!class_exists('TigerStyleSEO_Google_setup')) {
return;
}
$analytics_id = get_option('google_analytics_id', '');
if (empty($analytics_id)) {
return;
}
?>
'',
'banner_message' => '',
'privacy_policy_url' => '',
'cookie_policy_url' => '',
'banner_position' => 'bottom',
'banner_style' => 'modern',
'auto_hide_delay' => 0,
), get_option('tigerstyle_whiskers_consent_settings', array()));
}
/**
* Handle settings update from admin
*/
public function handle_settings_update() {
// Verify nonce and permissions
if (!wp_verify_nonce($_POST['consent_settings_nonce'], 'update_consent_settings') ||
!current_user_can('manage_options')) {
wp_die(__('Security check failed', 'tigerstyle-whiskers'));
}
$settings = array(
'banner_title' => sanitize_text_field($_POST['banner_title'] ?? ''),
'banner_message' => wp_kses_post($_POST['banner_message'] ?? ''),
'privacy_policy_url' => esc_url_raw($_POST['privacy_policy_url'] ?? ''),
'cookie_policy_url' => esc_url_raw($_POST['cookie_policy_url'] ?? ''),
'banner_position' => sanitize_text_field($_POST['banner_position'] ?? 'bottom'),
'banner_style' => sanitize_text_field($_POST['banner_style'] ?? 'modern'),
'auto_hide_delay' => intval($_POST['auto_hide_delay'] ?? 0),
);
update_option('tigerstyle_whiskers_consent_settings', $settings);
wp_redirect(admin_url('admin.php?page=tigerstyle-whiskers&tab=consent&message=settings_updated'));
exit;
}
/**
* Render admin settings page
*/
public function render_admin_page() {
$settings = $this->get_consent_settings();
?>
consent_status;
}
/**
* Check if specific consent is given
*/
public function has_consent_for($category) {
return isset($this->consent_status[$category]) && $this->consent_status[$category] === true;
}
}