array( 'name' => 'Identity Data', 'description' => 'Name, username, title, date of birth', 'legal_basis' => 'consent', 'retention_period' => '2 years', 'sensitivity' => 'medium' ), 'contact' => array( 'name' => 'Contact Data', 'description' => 'Email, phone number, postal address', 'legal_basis' => 'legitimate_interest', 'retention_period' => '3 years', 'sensitivity' => 'medium' ), 'technical' => array( 'name' => 'Technical Data', 'description' => 'IP address, browser type, device info', 'legal_basis' => 'legitimate_interest', 'retention_period' => '13 months', 'sensitivity' => 'low' ), 'usage' => array( 'name' => 'Usage Data', 'description' => 'Pages visited, time spent, interactions', 'legal_basis' => 'consent', 'retention_period' => '25 months', 'sensitivity' => 'low' ), 'marketing' => array( 'name' => 'Marketing Data', 'description' => 'Preferences, communication history', 'legal_basis' => 'consent', 'retention_period' => '2 years', 'sensitivity' => 'medium' ), 'financial' => array( 'name' => 'Financial Data', 'description' => 'Payment info, transaction history', 'legal_basis' => 'contract', 'retention_period' => '7 years', 'sensitivity' => 'high' ) ); /** * Legal basis options */ private $legal_basis_options = array( 'consent' => 'User has given explicit consent', 'contract' => 'Processing is necessary for contract performance', 'legal_obligation' => 'Processing is necessary for legal compliance', 'vital_interests' => 'Processing is necessary to protect vital interests', 'public_task' => 'Processing is necessary for public interest', 'legitimate_interest' => 'Processing is necessary for legitimate interests' ); /** * Get instance */ public static function instance() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } /** * Constructor */ private function __construct() { $this->init_data_mapping(); } /** * Initialize data mapping whisker */ private function init_data_mapping() { // Hook into WordPress to detect data processing add_action('init', array($this, 'scan_data_processing_activities')); add_action('user_register', array($this, 'map_user_registration_data')); add_action('wp_login', array($this, 'map_login_data'), 10, 2); add_action('comment_post', array($this, 'map_comment_data')); // WooCommerce hooks if available if (class_exists('WooCommerce')) { add_action('woocommerce_checkout_order_processed', array($this, 'map_order_data')); add_action('woocommerce_new_customer_data', array($this, 'map_customer_data')); } // Contact form hooks add_action('wpcf7_mail_sent', array($this, 'map_contact_form_data')); add_action('gform_after_submission', array($this, 'map_gravity_form_data'), 10, 2); // Analytics integration add_action('wp_head', array($this, 'track_analytics_data_collection')); // Admin hooks if (is_admin()) { add_action('admin_post_export_data_map', array($this, 'export_data_map')); } if (defined('WP_DEBUG') && WP_DEBUG) { error_log('TigerStyle Whiskers: Data mapper whisker is tracking with precision!'); } } /** * Scan for data processing activities */ public function scan_data_processing_activities() { $activities = array(); // Core WordPress activities $activities = array_merge($activities, $this->scan_wordpress_core_processing()); // Plugin-based activities $activities = array_merge($activities, $this->scan_plugin_processing()); // Theme-based activities $activities = array_merge($activities, $this->scan_theme_processing()); // Third-party service activities $activities = array_merge($activities, $this->scan_third_party_processing()); // Store the complete map $this->processing_activities = $activities; update_option('tigerstyle_whiskers_data_processing_map', $activities); return $activities; } /** * Scan WordPress core data processing */ private function scan_wordpress_core_processing() { $activities = array(); // User registration if (get_option('users_can_register')) { $activities['user_registration'] = array( 'purpose' => 'User account creation and management', 'data_categories' => array('identity', 'contact'), 'legal_basis' => 'consent', 'recipients' => array('website_administrators'), 'retention_period' => 'Until account deletion', 'processing_location' => 'EU/US', 'automated_decision_making' => false, 'data_source' => 'User input during registration', 'security_measures' => array('password_hashing', 'access_controls') ); } // Comments if (comments_open()) { $activities['comments'] = array( 'purpose' => 'Comment moderation and display', 'data_categories' => array('identity', 'contact', 'technical'), 'legal_basis' => 'legitimate_interest', 'recipients' => array('website_visitors', 'administrators'), 'retention_period' => 'Until comment deletion', 'processing_location' => 'EU/US', 'automated_decision_making' => true, 'decision_logic' => 'Spam detection and moderation', 'data_source' => 'User input in comment forms', 'security_measures' => array('spam_filtering', 'moderation_queue') ); } // Admin activities $activities['admin_access'] = array( 'purpose' => 'Website administration and security', 'data_categories' => array('technical', 'usage'), 'legal_basis' => 'legitimate_interest', 'recipients' => array('administrators'), 'retention_period' => '13 months', 'processing_location' => 'EU/US', 'automated_decision_making' => false, 'data_source' => 'Server logs and user interactions', 'security_measures' => array('access_logs', 'login_protection') ); return $activities; } /** * Scan plugin-based data processing */ private function scan_plugin_processing() { $activities = array(); // TigerStyle Heat Analytics if (class_exists('TigerStyleSEO_Google_setup')) { $analytics_id = get_option('google_analytics_id', ''); if (!empty($analytics_id)) { $activities['analytics'] = array( 'purpose' => 'Website traffic analysis and optimization', 'data_categories' => array('technical', 'usage'), 'legal_basis' => 'consent', 'recipients' => array('Google Analytics', 'website_administrators'), 'retention_period' => '26 months (Google Analytics default)', 'processing_location' => 'US (Google servers)', 'automated_decision_making' => true, 'decision_logic' => 'Audience segmentation and behavior analysis', 'data_source' => 'Website visitor interactions', 'security_measures' => array('data_anonymization', 'secure_transmission'), 'third_party_processor' => 'Google Ireland Limited' ); } } // WooCommerce if (class_exists('WooCommerce')) { $activities['ecommerce'] = array( 'purpose' => 'Order processing and customer management', 'data_categories' => array('identity', 'contact', 'financial'), 'legal_basis' => 'contract', 'recipients' => array('payment_processors', 'shipping_companies'), 'retention_period' => '7 years (accounting requirements)', 'processing_location' => 'EU/US', 'automated_decision_making' => false, 'data_source' => 'Customer checkout and account creation', 'security_measures' => array('payment_encryption', 'ssl_transmission') ); } // Contact Form 7 if (is_plugin_active('contact-form-7/wp-contact-form-7.php')) { $activities['contact_forms'] = array( 'purpose' => 'Customer inquiries and support', 'data_categories' => array('identity', 'contact'), 'legal_basis' => 'legitimate_interest', 'recipients' => array('support_team', 'administrators'), 'retention_period' => '2 years', 'processing_location' => 'EU/US', 'automated_decision_making' => false, 'data_source' => 'Contact form submissions', 'security_measures' => array('spam_protection', 'secure_transmission') ); } // MailChimp if (is_plugin_active('mailchimp-for-wp/mailchimp-for-wp.php')) { $activities['email_marketing'] = array( 'purpose' => 'Email marketing and newsletters', 'data_categories' => array('identity', 'contact', 'marketing'), 'legal_basis' => 'consent', 'recipients' => array('Mailchimp', 'marketing_team'), 'retention_period' => 'Until unsubscribe', 'processing_location' => 'US (Mailchimp servers)', 'automated_decision_making' => true, 'decision_logic' => 'Email campaign optimization and segmentation', 'data_source' => 'Newsletter signup forms', 'security_measures' => array('double_opt_in', 'secure_api'), 'third_party_processor' => 'The Rocket Science Group LLC (Mailchimp)' ); } return $activities; } /** * Scan theme-based data processing */ private function scan_theme_processing() { $activities = array(); // Check for theme customizations that might process data $theme = wp_get_theme(); // Custom theme analytics or tracking if ($this->theme_has_custom_tracking()) { $activities['theme_tracking'] = array( 'purpose' => 'Theme-specific user experience tracking', 'data_categories' => array('technical', 'usage'), 'legal_basis' => 'legitimate_interest', 'recipients' => array('theme_developers', 'administrators'), 'retention_period' => '13 months', 'processing_location' => 'EU/US', 'automated_decision_making' => false, 'data_source' => 'Theme interaction events', 'security_measures' => array('anonymized_tracking') ); } return $activities; } /** * Scan third-party service data processing */ private function scan_third_party_processing() { $activities = array(); // Check for external services $external_services = $this->detect_external_services(); foreach ($external_services as $service => $details) { $activities["third_party_{$service}"] = array( 'purpose' => $details['purpose'], 'data_categories' => $details['data_categories'], 'legal_basis' => $details['legal_basis'], 'recipients' => array($details['provider']), 'retention_period' => $details['retention_period'], 'processing_location' => $details['location'], 'automated_decision_making' => $details['automated_decisions'], 'data_source' => 'Website visitor interactions', 'security_measures' => $details['security_measures'], 'third_party_processor' => $details['processor_name'] ); } return $activities; } /** * Detect external services */ private function detect_external_services() { $services = array(); // Google Fonts if ($this->uses_google_fonts()) { $services['google_fonts'] = array( 'purpose' => 'Font delivery and display optimization', 'data_categories' => array('technical'), 'legal_basis' => 'legitimate_interest', 'retention_period' => 'Up to 1 year', 'location' => 'US (Google servers)', 'automated_decisions' => false, 'security_measures' => array('https_delivery'), 'provider' => 'Google Fonts API', 'processor_name' => 'Google Ireland Limited' ); } // YouTube embeds if ($this->has_youtube_embeds()) { $services['youtube'] = array( 'purpose' => 'Video content delivery and analytics', 'data_categories' => array('technical', 'usage'), 'legal_basis' => 'consent', 'retention_period' => 'Various (see YouTube privacy policy)', 'location' => 'US (Google servers)', 'automated_decisions' => true, 'security_measures' => array('privacy_enhanced_mode'), 'provider' => 'YouTube', 'processor_name' => 'Google Ireland Limited' ); } // CDN services $cdn_service = $this->detect_cdn_service(); if ($cdn_service) { $services['cdn'] = array( 'purpose' => 'Content delivery and performance optimization', 'data_categories' => array('technical'), 'legal_basis' => 'legitimate_interest', 'retention_period' => '30-90 days', 'location' => 'Global CDN network', 'automated_decisions' => false, 'security_measures' => array('https_delivery', 'ddos_protection'), 'provider' => $cdn_service['name'], 'processor_name' => $cdn_service['processor'] ); } return $services; } /** * Map user registration data */ public function map_user_registration_data($user_id) { $user = get_user_by('id', $user_id); $this->log_data_processing_event(array( 'event_type' => 'user_registration', 'user_id' => $user_id, 'data_collected' => array( 'username' => $user->user_login, 'email' => $user->user_email, 'registration_date' => $user->user_registered, 'ip_address' => $this->get_user_ip(), 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '' ), 'legal_basis' => 'consent', 'purpose' => 'User account creation', 'retention_period' => 'Until account deletion' )); } /** * Map login data */ public function map_login_data($user_login, $user) { $this->log_data_processing_event(array( 'event_type' => 'user_login', 'user_id' => $user->ID, 'data_collected' => array( 'login_time' => current_time('mysql'), 'ip_address' => $this->get_user_ip(), 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'login_method' => 'standard' ), 'legal_basis' => 'legitimate_interest', 'purpose' => 'Security and access control', 'retention_period' => '13 months' )); } /** * Map comment data */ public function map_comment_data($comment_id) { $comment = get_comment($comment_id); $this->log_data_processing_event(array( 'event_type' => 'comment_submission', 'comment_id' => $comment_id, 'data_collected' => array( 'author_name' => $comment->comment_author, 'author_email' => $comment->comment_author_email, 'author_url' => $comment->comment_author_url, 'ip_address' => $comment->comment_author_IP, 'user_agent' => $comment->comment_agent, 'comment_date' => $comment->comment_date ), 'legal_basis' => 'legitimate_interest', 'purpose' => 'Comment display and moderation', 'retention_period' => 'Until comment deletion' )); } /** * Map WooCommerce order data */ public function map_order_data($order_id) { if (!class_exists('WooCommerce')) { return; } $order = wc_get_order($order_id); $this->log_data_processing_event(array( 'event_type' => 'order_processing', 'order_id' => $order_id, 'data_collected' => array( 'billing_details' => $order->get_billing_address(), 'shipping_details' => $order->get_shipping_address(), 'payment_method' => $order->get_payment_method(), 'order_total' => $order->get_total(), 'customer_id' => $order->get_customer_id(), 'order_date' => $order->get_date_created() ), 'legal_basis' => 'contract', 'purpose' => 'Order fulfillment and customer service', 'retention_period' => '7 years (accounting requirements)' )); } /** * Track analytics data collection */ public function track_analytics_data_collection() { if (!TigerStyleWhiskers_CookieConsent::instance()->has_analytics_consent()) { return; } // Only track if analytics is active if (class_exists('TigerStyleSEO_Google_setup')) { $analytics_id = get_option('google_analytics_id', ''); if (!empty($analytics_id)) { $this->log_data_processing_event(array( 'event_type' => 'analytics_tracking', 'data_collected' => array( 'page_url' => $_SERVER['REQUEST_URI'] ?? '', 'referrer' => $_SERVER['HTTP_REFERER'] ?? '', 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'ip_address' => $this->get_user_ip(), 'timestamp' => current_time('mysql') ), 'legal_basis' => 'consent', 'purpose' => 'Website analytics and optimization', 'retention_period' => '26 months', 'third_party_processor' => 'Google Analytics' )); } } } /** * Log data processing event */ private function log_data_processing_event($event_data) { // Add common fields $event_data['timestamp'] = current_time('timestamp'); $event_data['site_url'] = home_url(); $event_data['gdpr_applies'] = TigerStyleWhiskers_BoundaryDetector::is_gdpr_territory(); // Hash sensitive data if (isset($event_data['data_collected']['ip_address'])) { $event_data['data_collected']['ip_address_hash'] = hash('sha256', $event_data['data_collected']['ip_address']); unset($event_data['data_collected']['ip_address']); // Remove raw IP } if (isset($event_data['data_collected']['user_agent'])) { $event_data['data_collected']['user_agent_hash'] = hash('sha256', $event_data['data_collected']['user_agent']); unset($event_data['data_collected']['user_agent']); // Remove raw user agent } // Store in database (consider using a custom table for better performance) $existing_log = get_option('tigerstyle_whiskers_processing_log', array()); $existing_log[] = $event_data; // Keep only last 1000 events to prevent database bloat if (count($existing_log) > 1000) { $existing_log = array_slice($existing_log, -1000); } update_option('tigerstyle_whiskers_processing_log', $existing_log); // Also log to audit trail if available if (class_exists('TigerStyleWhiskers_AuditTrail') && isset($event_data['event_type'])) { $audit_trail = TigerStyleWhiskers_AuditTrail::instance(); $audit_trail->log_event($event_data['event_type'], $event_data); } } /** * Get user IP address (anonymized) */ private function get_user_ip() { $ip = ''; if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; } elseif (!empty($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } // Anonymize IP for privacy (remove last octet for IPv4) if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $ip_parts = explode('.', $ip); $ip_parts[3] = '0'; $ip = implode('.', $ip_parts); } return $ip; } /** * Helper methods for detection */ private function theme_has_custom_tracking() { // Check theme files for tracking code return false; // Simplified for now } private function uses_google_fonts() { // Check if Google Fonts are loaded return strpos(file_get_contents(get_template_directory() . '/style.css'), 'fonts.googleapis.com') !== false; } private function has_youtube_embeds() { // Check for YouTube embeds in content return false; // Simplified for now } private function detect_cdn_service() { // Detect CDN services return false; // Simplified for now } /** * Export data processing map */ public function export_data_map() { if (!current_user_can('manage_options')) { wp_die('You do not have sufficient permissions'); } $data_map = array( 'site_info' => array( 'site_url' => home_url(), 'site_name' => get_bloginfo('name'), 'export_date' => current_time('mysql'), 'wordpress_version' => get_bloginfo('version'), 'whiskers_version' => TIGERSTYLE_WHISKERS_VERSION ), 'processing_activities' => $this->processing_activities, 'data_categories' => $this->data_categories, 'legal_basis_explanations' => $this->legal_basis_options, 'compliance_status' => TigerStyleWhiskers_ComplianceScanner::get_status() ); // Set headers for download header('Content-Type: application/json'); header('Content-Disposition: attachment; filename="data-processing-map-' . date('Y-m-d') . '.json"'); header('Cache-Control: no-cache, must-revalidate'); echo json_encode($data_map, JSON_PRETTY_PRINT); exit; } /** * Get processing activities for admin display */ public function get_processing_activities() { return $this->processing_activities; } /** * Get data categories */ public function get_data_categories() { return $this->data_categories; } /** * Render admin page */ public function render_admin_page() { $activities = $this->get_processing_activities(); ?>

$activity): ?>