Git Code Viewer Plugin
When you visit pages that display code repositories using the Git Code Viewer plugin:
If Privacy Mode is enabled, no IP addresses or user agents are collected.
'; wp_add_privacy_policy_content( 'Git Code Viewer', wp_kses_post($content) ); } /** * Register data exporter for GDPR requests */ public static function register_data_exporter($exporters) { $exporters['git-code-viewer'] = array( 'exporter_friendly_name' => __('Git Code Viewer Plugin'), 'callback' => array(__CLASS__, 'data_exporter') ); return $exporters; } /** * Export user data for GDPR requests */ public static function data_exporter($email_address, $page = 1) { $export_items = array(); // Get security logs that might contain this user's data $logs = get_transient('mcb_security_logs'); if (is_array($logs)) { $user_data = array(); // Note: We don't store email addresses, so we can't directly match // This is actually good for privacy! $user_data[] = array( 'name' => 'Security Logs Notice', 'value' => 'The Git Code Viewer plugin does not store email addresses. Any security logs contain only anonymized IP addresses and user agents.' ); $export_items[] = array( 'group_id' => 'git-code-viewer', 'group_label' => 'Git Code Viewer Data', 'item_id' => 'gcv-notice', 'data' => $user_data ); } return array( 'data' => $export_items, 'done' => true ); } /** * Register data eraser for GDPR requests */ public static function register_data_eraser($erasers) { $erasers['git-code-viewer'] = array( 'eraser_friendly_name' => __('Git Code Viewer Plugin'), 'callback' => array(__CLASS__, 'data_eraser') ); return $erasers; } /** * Erase user data for GDPR requests */ public static function data_eraser($email_address, $page = 1) { // Since we don't store email addresses or persistent user data, // we can only clear all transient data if requested if ($page === 1) { // Clear all security logs delete_transient('mcb_security_logs'); // Clear all rate limit transients (they expire in 60 seconds anyway) global $wpdb; $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mcb_rate_%'"); $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_mcb_rate_%'"); } return array( 'items_removed' => true, 'items_retained' => false, 'messages' => array('All temporary Git Code Viewer data has been removed.'), 'done' => true ); } /** * Get anonymized IP for privacy compliance */ public static function get_anonymized_ip($ip) { if (self::is_privacy_mode()) { return 'privacy-mode'; } // Anonymize IP by removing last octet for IPv4 or last 80 bits for IPv6 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $parts = explode('.', $ip); $parts[3] = '0'; return implode('.', $parts); } elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { // Zero out last 80 bits return substr($ip, 0, strrpos($ip, ':')) . ':0:0:0:0:0'; } return 'unknown'; } /** * Clean up old data automatically */ public static function cleanup_old_data() { // This is called on a daily schedule global $wpdb; // Remove expired rate limit transients $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_mcb_%' AND option_value < UNIX_TIMESTAMP()"); // Remove orphaned transients (fixed MySQL compatibility issue) // First get all valid transient names $valid_transients = $wpdb->get_col( "SELECT CONCAT('_transient_', SUBSTRING(option_name, 20)) FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_mcb_%'" ); if (!empty($valid_transients)) { // Build a safe IN clause $placeholders = array_fill(0, count($valid_transients), '%s'); $in_clause = implode(',', $placeholders); // Delete orphaned transients $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mcb_%' AND option_name NOT IN ($in_clause)", $valid_transients ) ); } else { // No valid transients with timeouts, remove all MCB transients $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mcb_%'"); } // Also clean up expired timeout options $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_mcb_%' AND option_value < UNIX_TIMESTAMP()"); } } // Initialize privacy features MCB_Privacy_Manager::init(); // Schedule cleanup (weekly is sufficient for transient cleanup) if (!wp_next_scheduled('mcb_privacy_cleanup')) { wp_schedule_event(time(), 'weekly', 'mcb_privacy_cleanup'); } add_action('mcb_privacy_cleanup', array('MCB_Privacy_Manager', 'cleanup_old_data'));