tigerstyle-whiskers/includes/whiskers/class-analytics-integration.php
Ryan Malloy adbdae19c8 Initial commit: TigerStyle Whiskers v1.0.0
Navigate privacy laws with feline precision — detect every boundary,
respect every territory! GDPR compliance and privacy protection for
WordPress.

- Cookie consent management
- Privacy boundary detection
- GDPR-compliant analytics gating
- Cross-plugin consent coordination (integrates with TigerStyle Heat)
- Visitor preference tracking
- Configurable cookie categories

Includes build.sh and .distignore for WordPress-installable release ZIPs.
2026-05-27 14:31:51 -06:00

421 lines
14 KiB
PHP

<?php
/**
* TigerStyle Whiskers Analytics Integration
*
* Bridge privacy consent with analytics - let Heat know when the coast is clear!
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
class TigerStyleWhiskers_AnalyticsIntegration {
/**
* Single instance
*/
private static $instance = null;
/**
* Analytics providers
*/
private $providers = array();
/**
* Get instance
*/
public static function instance() {
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
private function __construct() {
$this->init_analytics_integration();
}
/**
* Initialize analytics integration
*/
private function init_analytics_integration() {
$this->define_providers();
// Hook into consent events
add_action('tigerstyle_whiskers_consent_granted', array($this, 'handle_consent_granted'), 10, 2);
add_action('tigerstyle_whiskers_consent_withdrawn', array($this, 'handle_consent_withdrawn'), 10, 2);
// Integration with TigerStyle Heat
add_action('wp_head', array($this, 'inject_consent_bridge'), 1);
// Admin hooks
if (is_admin()) {
add_action('wp_ajax_whiskers_test_analytics_integration', array($this, 'ajax_test_integration'));
}
}
/**
* Define analytics providers
*/
private function define_providers() {
$this->providers = array(
'google_analytics' => array(
'name' => __('Google Analytics', 'tigerstyle-whiskers'),
'consent_category' => 'analytics',
'script_pattern' => '/gtag|analytics\.js|ga\.js/',
'cookie_patterns' => array('_ga', '_gid', '_gat'),
'integration_class' => 'TigerStyleSEO' // Heat integration
),
'google_tag_manager' => array(
'name' => __('Google Tag Manager', 'tigerstyle-whiskers'),
'consent_category' => 'analytics',
'script_pattern' => '/googletagmanager\.com/',
'cookie_patterns' => array('_ga', '_gid', '_gat'),
'integration_class' => 'TigerStyleSEO'
),
'facebook_pixel' => array(
'name' => __('Facebook Pixel', 'tigerstyle-whiskers'),
'consent_category' => 'marketing',
'script_pattern' => '/connect\.facebook\.net/',
'cookie_patterns' => array('_fbp', '_fbc', 'fr'),
'integration_class' => null
),
'hotjar' => array(
'name' => __('Hotjar', 'tigerstyle-whiskers'),
'consent_category' => 'analytics',
'script_pattern' => '/static\.hotjar\.com/',
'cookie_patterns' => array('_hjid', '_hjSession'),
'integration_class' => null
)
);
}
/**
* Handle consent granted
*/
public function handle_consent_granted($consent_data, $user_info) {
foreach ($this->providers as $provider_id => $provider) {
$category = $provider['consent_category'];
if (isset($consent_data[$category]) && $consent_data[$category]) {
$this->enable_provider($provider_id, $provider);
}
}
// Trigger Heat integration if analytics consent granted
if (isset($consent_data['analytics']) && $consent_data['analytics']) {
$this->trigger_heat_integration(true);
}
}
/**
* Handle consent withdrawn
*/
public function handle_consent_withdrawn($consent_categories, $user_info) {
foreach ($consent_categories as $category) {
foreach ($this->providers as $provider_id => $provider) {
if ($provider['consent_category'] === $category) {
$this->disable_provider($provider_id, $provider);
}
}
}
// Disable Heat integration if analytics consent withdrawn
if (in_array('analytics', $consent_categories)) {
$this->trigger_heat_integration(false);
}
}
/**
* Enable analytics provider
*/
private function enable_provider($provider_id, $provider) {
// Log the enabling
do_action('tigerstyle_whiskers_analytics_enabled', $provider_id, $provider);
// Provider-specific enabling logic
switch ($provider_id) {
case 'google_analytics':
$this->enable_google_analytics();
break;
case 'google_tag_manager':
$this->enable_google_tag_manager();
break;
case 'facebook_pixel':
$this->enable_facebook_pixel();
break;
}
}
/**
* Disable analytics provider
*/
private function disable_provider($provider_id, $provider) {
// Clear provider cookies
$this->clear_provider_cookies($provider['cookie_patterns']);
// Log the disabling
do_action('tigerstyle_whiskers_analytics_disabled', $provider_id, $provider);
// Provider-specific disabling logic
switch ($provider_id) {
case 'google_analytics':
$this->disable_google_analytics();
break;
case 'google_tag_manager':
$this->disable_google_tag_manager();
break;
case 'facebook_pixel':
$this->disable_facebook_pixel();
break;
}
}
/**
* Clear provider cookies
*/
private function clear_provider_cookies($cookie_patterns) {
foreach ($cookie_patterns as $pattern) {
// Use JavaScript to clear cookies client-side
$this->add_cookie_clear_script($pattern);
}
}
/**
* Add cookie clearing script
*/
private function add_cookie_clear_script($cookie_pattern) {
add_action('wp_footer', function() use ($cookie_pattern) {
echo "<script>
(function() {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
var name = cookie.split('=')[0];
if (name.indexOf('{$cookie_pattern}') === 0) {
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=' + window.location.hostname;
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/';
}
}
})();
</script>";
});
}
/**
* Enable Google Analytics
*/
private function enable_google_analytics() {
// Trigger Heat to enable GA if it's managing it
if (class_exists('TigerStyleSEO')) {
do_action('tigerstyle_heat_enable_analytics');
}
}
/**
* Disable Google Analytics
*/
private function disable_google_analytics() {
// Trigger Heat to disable GA
if (class_exists('TigerStyleSEO')) {
do_action('tigerstyle_heat_disable_analytics');
}
// Disable GA tracking
add_action('wp_footer', function() {
echo "<script>
if (typeof gtag !== 'undefined') {
gtag('consent', 'update', {
'analytics_storage': 'denied'
});
}
if (typeof ga !== 'undefined') {
ga('set', 'anonymizeIp', true);
ga('set', 'allowAdFeatures', false);
}
</script>";
});
}
/**
* Enable Google Tag Manager
*/
private function enable_google_tag_manager() {
add_action('wp_footer', function() {
echo "<script>
if (typeof dataLayer !== 'undefined') {
dataLayer.push({
'event': 'consent_granted',
'consent_analytics': true
});
}
</script>";
});
}
/**
* Disable Google Tag Manager
*/
private function disable_google_tag_manager() {
add_action('wp_footer', function() {
echo "<script>
if (typeof dataLayer !== 'undefined') {
dataLayer.push({
'event': 'consent_withdrawn',
'consent_analytics': false
});
}
</script>";
});
}
/**
* Enable Facebook Pixel
*/
private function enable_facebook_pixel() {
add_action('wp_footer', function() {
echo "<script>
if (typeof fbq !== 'undefined') {
fbq('consent', 'grant');
}
</script>";
});
}
/**
* Disable Facebook Pixel
*/
private function disable_facebook_pixel() {
add_action('wp_footer', function() {
echo "<script>
if (typeof fbq !== 'undefined') {
fbq('consent', 'revoke');
}
</script>";
});
}
/**
* Trigger Heat integration
*/
private function trigger_heat_integration($enable) {
if (class_exists('TigerStyleSEO')) {
if ($enable) {
do_action('tigerstyle_whiskers_heat_consent_granted');
} else {
do_action('tigerstyle_whiskers_heat_consent_withdrawn');
}
}
}
/**
* Inject consent bridge script
*/
public function inject_consent_bridge() {
$consent_state = $this->get_current_consent_state();
echo "<script>
window.tigerstyleWhiskersConsent = {
hasAnalyticsConsent: function() {
return " . ($consent_state['analytics'] ? 'true' : 'false') . ";
},
hasMarketingConsent: function() {
return " . ($consent_state['marketing'] ? 'true' : 'false') . ";
},
getConsentState: function() {
return " . wp_json_encode($consent_state) . ";
}
};
// Fire consent state event for other scripts
document.addEventListener('DOMContentLoaded', function() {
var event = new CustomEvent('tigerstyleWhiskersConsentReady', {
detail: window.tigerstyleWhiskersConsent.getConsentState()
});
document.dispatchEvent(event);
});
</script>";
}
/**
* Get current consent state
*/
private function get_current_consent_state() {
$cookie_consent = tigerstyle_whiskers()->get_whisker('cookie_consent');
if ($cookie_consent && method_exists($cookie_consent, 'get_consent_state')) {
return $cookie_consent->get_consent_state();
}
// Default state
return array(
'necessary' => true,
'analytics' => false,
'marketing' => false,
'preferences' => false
);
}
/**
* Get integration status
*/
public function get_integration_status() {
$status = array();
foreach ($this->providers as $provider_id => $provider) {
$status[$provider_id] = array(
'name' => $provider['name'],
'category' => $provider['consent_category'],
'detected' => $this->is_provider_detected($provider),
'consent_required' => true,
'current_consent' => $this->has_consent_for_category($provider['consent_category']),
'integration_class' => $provider['integration_class'],
'heat_integrated' => ($provider['integration_class'] === 'TigerStyleSEO' && class_exists('TigerStyleSEO'))
);
}
return $status;
}
/**
* Check if provider is detected on the site
*/
private function is_provider_detected($provider) {
// This would need actual detection logic
// For now, return true for Heat integration
return $provider['integration_class'] === 'TigerStyleSEO' && class_exists('TigerStyleSEO');
}
/**
* Check if user has consent for category
*/
private function has_consent_for_category($category) {
$consent_state = $this->get_current_consent_state();
return isset($consent_state[$category]) ? $consent_state[$category] : false;
}
/**
* AJAX: Test analytics integration
*/
public function ajax_test_integration() {
check_ajax_referer('whiskers_admin_nonce', 'nonce');
if (!current_user_can('manage_options')) {
wp_die(__('Insufficient permissions', 'tigerstyle-whiskers'));
}
$integration_status = $this->get_integration_status();
$heat_active = class_exists('TigerStyleSEO');
wp_send_json_success(array(
'message' => __('Analytics integration test completed!', 'tigerstyle-whiskers'),
'heat_active' => $heat_active,
'providers' => $integration_status,
'consent_bridge_active' => true
));
}
}