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.
1071 lines
43 KiB
PHP
1071 lines
43 KiB
PHP
<?php
|
|
/**
|
|
* Privacy Policy Generator Whisker for TigerStyle Whiskers
|
|
*
|
|
* AI-powered privacy policy generation with feline intelligence - like a cat
|
|
* understanding its territory and documenting every detail with precision
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class TigerStyleWhiskers_PrivacyPolicy {
|
|
|
|
/**
|
|
* Single instance
|
|
*/
|
|
private static $instance = null;
|
|
|
|
/**
|
|
* Policy templates for different jurisdictions
|
|
*/
|
|
private $policy_templates = array();
|
|
|
|
/**
|
|
* Data processing activities scanner
|
|
*/
|
|
private $activity_scanner = null;
|
|
|
|
/**
|
|
* Get instance
|
|
*/
|
|
public static function instance() {
|
|
if (is_null(self::$instance)) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
private function __construct() {
|
|
$this->init_policy_generator();
|
|
}
|
|
|
|
/**
|
|
* Initialize privacy policy generator
|
|
*/
|
|
private function init_policy_generator() {
|
|
// Admin hooks
|
|
if (is_admin()) {
|
|
add_action('admin_post_generate_privacy_policy', array($this, 'generate_policy'));
|
|
add_action('admin_post_update_policy_settings', array($this, 'update_policy_settings'));
|
|
add_action('wp_ajax_tigerstyle_whiskers_scan_site', array($this, 'ajax_scan_site'));
|
|
}
|
|
|
|
// Frontend hooks
|
|
add_shortcode('tigerstyle_privacy_policy', array($this, 'privacy_policy_shortcode'));
|
|
add_action('wp_head', array($this, 'inject_policy_metadata'));
|
|
|
|
// Initialize activity scanner
|
|
if (class_exists('TigerStyleWhiskers_DataMapper')) {
|
|
$this->activity_scanner = TigerStyleWhiskers_DataMapper::instance();
|
|
}
|
|
|
|
// Load policy templates
|
|
$this->load_policy_templates();
|
|
|
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
|
error_log('TigerStyle Whiskers: Privacy policy generator whisker is ready to document with feline precision!');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load policy templates for different jurisdictions
|
|
*/
|
|
private function load_policy_templates() {
|
|
$this->policy_templates = array(
|
|
'gdpr' => array(
|
|
'name' => 'GDPR (European Union)',
|
|
'description' => 'Comprehensive GDPR-compliant privacy policy',
|
|
'required_sections' => array(
|
|
'data_controller',
|
|
'legal_basis',
|
|
'data_categories',
|
|
'processing_purposes',
|
|
'data_retention',
|
|
'user_rights',
|
|
'data_transfers',
|
|
'security_measures',
|
|
'contact_dpo'
|
|
),
|
|
'optional_sections' => array(
|
|
'cookies_policy',
|
|
'marketing_communications',
|
|
'third_party_integrations'
|
|
)
|
|
),
|
|
'ccpa' => array(
|
|
'name' => 'CCPA (California)',
|
|
'description' => 'California Consumer Privacy Act compliant policy',
|
|
'required_sections' => array(
|
|
'business_identity',
|
|
'personal_info_categories',
|
|
'sources_of_info',
|
|
'business_purposes',
|
|
'third_party_sharing',
|
|
'consumer_rights',
|
|
'non_discrimination'
|
|
),
|
|
'optional_sections' => array(
|
|
'sale_of_personal_info',
|
|
'minors_privacy'
|
|
)
|
|
),
|
|
'generic' => array(
|
|
'name' => 'Generic Privacy Policy',
|
|
'description' => 'General privacy policy for global compliance',
|
|
'required_sections' => array(
|
|
'information_collection',
|
|
'information_use',
|
|
'information_sharing',
|
|
'data_security',
|
|
'user_choices',
|
|
'contact_information'
|
|
),
|
|
'optional_sections' => array(
|
|
'cookies_tracking',
|
|
'third_party_links',
|
|
'policy_updates'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Generate privacy policy based on site scan
|
|
*/
|
|
public function generate_policy() {
|
|
if (!current_user_can('manage_options')) {
|
|
wp_die(__('You do not have sufficient permissions', 'tigerstyle-whiskers'));
|
|
}
|
|
|
|
if (!wp_verify_nonce($_POST['policy_nonce'], 'generate_privacy_policy')) {
|
|
wp_die(__('Security check failed', 'tigerstyle-whiskers'));
|
|
}
|
|
|
|
$template_type = sanitize_text_field($_POST['template_type'] ?? 'gdpr');
|
|
$company_info = array(
|
|
'name' => sanitize_text_field($_POST['company_name'] ?? get_bloginfo('name')),
|
|
'email' => sanitize_email($_POST['contact_email'] ?? get_option('admin_email')),
|
|
'address' => sanitize_textarea_field($_POST['company_address'] ?? ''),
|
|
'phone' => sanitize_text_field($_POST['company_phone'] ?? ''),
|
|
'dpo_email' => sanitize_email($_POST['dpo_email'] ?? ''),
|
|
'website_url' => home_url()
|
|
);
|
|
|
|
// Scan website for data processing activities
|
|
$site_scan_results = $this->scan_website_comprehensively();
|
|
|
|
// Generate policy content
|
|
$policy_content = $this->build_policy_content($template_type, $company_info, $site_scan_results);
|
|
|
|
// Save the generated policy
|
|
$policy_id = $this->save_generated_policy($policy_content, $template_type, $company_info);
|
|
|
|
if ($policy_id) {
|
|
wp_redirect(admin_url('admin.php?page=tigerstyle-whiskers&tab=privacy-policy&message=policy_generated&policy_id=' . $policy_id));
|
|
} else {
|
|
wp_redirect(admin_url('admin.php?page=tigerstyle-whiskers&tab=privacy-policy&message=policy_generation_failed'));
|
|
}
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Scan website comprehensively for data processing activities
|
|
*/
|
|
private function scan_website_comprehensively() {
|
|
$scan_results = array(
|
|
'wordpress_core' => $this->scan_wordpress_core(),
|
|
'active_plugins' => $this->scan_active_plugins(),
|
|
'theme_analysis' => $this->scan_active_theme(),
|
|
'third_party_services' => $this->scan_third_party_services(),
|
|
'data_collection_points' => $this->scan_data_collection_points(),
|
|
'cookies_analysis' => $this->scan_cookies_usage(),
|
|
'external_integrations' => $this->scan_external_integrations(),
|
|
'user_generated_content' => $this->scan_user_content_features()
|
|
);
|
|
|
|
// Use data mapper if available for enhanced scanning
|
|
if ($this->activity_scanner) {
|
|
$scan_results['processing_activities'] = $this->activity_scanner->get_processing_activities();
|
|
$scan_results['data_categories'] = $this->activity_scanner->get_data_categories();
|
|
}
|
|
|
|
return $scan_results;
|
|
}
|
|
|
|
/**
|
|
* Scan WordPress core data processing
|
|
*/
|
|
private function scan_wordpress_core() {
|
|
$core_features = array(
|
|
'user_registration' => get_option('users_can_register', 0),
|
|
'comments_enabled' => get_option('default_comment_status', 'closed') === 'open',
|
|
'user_profiles' => true, // Always present
|
|
'admin_access_logs' => true, // WordPress logs admin access
|
|
'automatic_updates' => get_option('auto_update_core_minor', true),
|
|
'error_logging' => defined('WP_DEBUG_LOG') && WP_DEBUG_LOG,
|
|
'version_info' => array(
|
|
'wordpress' => get_bloginfo('version'),
|
|
'php' => PHP_VERSION,
|
|
'mysql' => $this->get_mysql_version()
|
|
)
|
|
);
|
|
|
|
return $core_features;
|
|
}
|
|
|
|
/**
|
|
* Scan active plugins for data processing
|
|
*/
|
|
private function scan_active_plugins() {
|
|
// Ensure we have the required WordPress functions loaded
|
|
if (!function_exists('get_plugin_data')) {
|
|
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
|
}
|
|
|
|
$active_plugins = get_option('active_plugins', array());
|
|
$plugin_analysis = array();
|
|
|
|
foreach ($active_plugins as $plugin_file) {
|
|
// Skip if plugin file doesn't exist
|
|
if (!file_exists(WP_PLUGIN_DIR . '/' . $plugin_file)) {
|
|
continue;
|
|
}
|
|
|
|
$plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_file);
|
|
$plugin_slug = dirname($plugin_file);
|
|
|
|
$analysis = array(
|
|
'name' => $plugin_data['Name'],
|
|
'version' => $plugin_data['Version'],
|
|
'author' => $plugin_data['Author'],
|
|
'description' => $plugin_data['Description'],
|
|
'data_processing_type' => $this->analyze_plugin_data_processing($plugin_slug, $plugin_data),
|
|
'privacy_implications' => $this->get_plugin_privacy_implications($plugin_slug),
|
|
'gdpr_compliance' => $this->check_plugin_gdpr_features($plugin_slug)
|
|
);
|
|
|
|
$plugin_analysis[$plugin_slug] = $analysis;
|
|
}
|
|
|
|
return $plugin_analysis;
|
|
}
|
|
|
|
/**
|
|
* Analyze plugin data processing patterns
|
|
*/
|
|
private function analyze_plugin_data_processing($plugin_slug, $plugin_data) {
|
|
$processing_types = array();
|
|
|
|
// Common plugin patterns
|
|
$plugin_patterns = array(
|
|
'contact' => array('contact-form', 'ninja-forms', 'wpforms', 'gravityforms'),
|
|
'analytics' => array('google-analytics', 'jetpack', 'monster-insights', 'tigerstyle-heat'),
|
|
'ecommerce' => array('woocommerce', 'easy-digital-downloads', 'wp-ecommerce'),
|
|
'social' => array('social', 'facebook', 'twitter', 'instagram'),
|
|
'marketing' => array('mailchimp', 'constant-contact', 'newsletter'),
|
|
'security' => array('wordfence', 'sucuri', 'ithemes-security'),
|
|
'backup' => array('updraftplus', 'backwpup', 'tigerstyle-life9'),
|
|
'seo' => array('yoast', 'rankmath', 'tigerstyle-heat'),
|
|
'membership' => array('memberpress', 'restrict-content', 'wishlist-member'),
|
|
'forum' => array('bbpress', 'buddypress', 'wpforo')
|
|
);
|
|
|
|
$name_lower = strtolower($plugin_data['Name']);
|
|
$slug_lower = strtolower($plugin_slug);
|
|
|
|
foreach ($plugin_patterns as $type => $patterns) {
|
|
foreach ($patterns as $pattern) {
|
|
if (strpos($name_lower, $pattern) !== false || strpos($slug_lower, $pattern) !== false) {
|
|
$processing_types[] = $type;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return array_unique($processing_types);
|
|
}
|
|
|
|
/**
|
|
* Get plugin privacy implications
|
|
*/
|
|
private function get_plugin_privacy_implications($plugin_slug) {
|
|
$implications = array();
|
|
|
|
// Known plugin privacy implications
|
|
$plugin_implications = array(
|
|
'woocommerce' => array(
|
|
'collects_payment_data' => true,
|
|
'stores_customer_profiles' => true,
|
|
'tracks_purchase_history' => true,
|
|
'requires_gdpr_compliance' => true,
|
|
'data_retention_required' => '7 years'
|
|
),
|
|
'contact-form-7' => array(
|
|
'collects_form_data' => true,
|
|
'stores_submissions' => false,
|
|
'sends_email_notifications' => true,
|
|
'requires_consent' => true
|
|
),
|
|
'google-analytics' => array(
|
|
'tracks_user_behavior' => true,
|
|
'uses_cookies' => true,
|
|
'shares_data_with_google' => true,
|
|
'requires_consent' => true,
|
|
'anonymization_available' => true
|
|
),
|
|
'mailchimp-for-wp' => array(
|
|
'collects_email_addresses' => true,
|
|
'syncs_with_external_service' => true,
|
|
'requires_double_opt_in' => 'recommended',
|
|
'data_transfers_to_us' => true
|
|
)
|
|
);
|
|
|
|
return $plugin_implications[$plugin_slug] ?? array();
|
|
}
|
|
|
|
/**
|
|
* Check plugin GDPR compliance features
|
|
*/
|
|
private function check_plugin_gdpr_features($plugin_slug) {
|
|
$compliance_features = array(
|
|
'has_privacy_policy' => false,
|
|
'supports_data_export' => false,
|
|
'supports_data_deletion' => false,
|
|
'consent_integration' => false,
|
|
'anonymization_options' => false
|
|
);
|
|
|
|
// Check if plugin registers privacy exporters/erasers
|
|
$privacy_exporters = apply_filters('wp_privacy_personal_data_exporters', array());
|
|
$privacy_erasers = apply_filters('wp_privacy_personal_data_erasers', array());
|
|
|
|
foreach ($privacy_exporters as $exporter) {
|
|
if (strpos($exporter['exporter_friendly_name'], $plugin_slug) !== false) {
|
|
$compliance_features['supports_data_export'] = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach ($privacy_erasers as $eraser) {
|
|
if (strpos($eraser['eraser_friendly_name'], $plugin_slug) !== false) {
|
|
$compliance_features['supports_data_deletion'] = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $compliance_features;
|
|
}
|
|
|
|
/**
|
|
* Scan active theme for data processing
|
|
*/
|
|
private function scan_active_theme() {
|
|
$theme = wp_get_theme();
|
|
|
|
$theme_analysis = array(
|
|
'name' => $theme->get('Name'),
|
|
'version' => $theme->get('Version'),
|
|
'author' => $theme->get('Author'),
|
|
'has_custom_scripts' => $this->theme_has_custom_scripts(),
|
|
'uses_google_fonts' => $this->theme_uses_google_fonts(),
|
|
'has_social_integration' => $this->theme_has_social_features(),
|
|
'custom_forms' => $this->theme_has_custom_forms(),
|
|
'tracking_codes' => $this->theme_has_tracking_codes()
|
|
);
|
|
|
|
return $theme_analysis;
|
|
}
|
|
|
|
/**
|
|
* Scan for third-party services
|
|
*/
|
|
private function scan_third_party_services() {
|
|
$services = array();
|
|
|
|
// Common third-party services to detect
|
|
$service_patterns = array(
|
|
'google_analytics' => array('google-analytics.com', 'googletagmanager.com'),
|
|
'google_fonts' => array('fonts.googleapis.com', 'fonts.gstatic.com'),
|
|
'facebook_pixel' => array('facebook.net', 'connect.facebook.net'),
|
|
'twitter_widgets' => array('platform.twitter.com'),
|
|
'youtube_embeds' => array('youtube.com', 'youtu.be'),
|
|
'vimeo_embeds' => array('vimeo.com'),
|
|
'gravatar' => array('gravatar.com'),
|
|
'recaptcha' => array('recaptcha.net', 'google.com/recaptcha'),
|
|
'disqus' => array('disqus.com'),
|
|
'mailchimp' => array('mailchimp.com'),
|
|
'stripe' => array('stripe.com'),
|
|
'paypal' => array('paypal.com')
|
|
);
|
|
|
|
// Scan page content for external service references
|
|
$home_content = $this->get_page_content(home_url());
|
|
|
|
foreach ($service_patterns as $service => $patterns) {
|
|
foreach ($patterns as $pattern) {
|
|
if (strpos($home_content, $pattern) !== false) {
|
|
$services[$service] = array(
|
|
'detected' => true,
|
|
'pattern_matched' => $pattern,
|
|
'privacy_implications' => $this->get_service_privacy_implications($service)
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $services;
|
|
}
|
|
|
|
/**
|
|
* Get service privacy implications
|
|
*/
|
|
private function get_service_privacy_implications($service) {
|
|
$implications = array(
|
|
'google_analytics' => array(
|
|
'data_shared' => 'Usage data, IP addresses, device information',
|
|
'purpose' => 'Website analytics and optimization',
|
|
'retention' => '26 months (default)',
|
|
'location' => 'United States (Google servers)',
|
|
'user_rights' => 'Users can opt-out via browser settings or privacy policy'
|
|
),
|
|
'google_fonts' => array(
|
|
'data_shared' => 'IP address, browser information',
|
|
'purpose' => 'Font delivery',
|
|
'retention' => 'Up to 1 year',
|
|
'location' => 'United States (Google servers)',
|
|
'user_rights' => 'No specific opt-out mechanism'
|
|
),
|
|
'facebook_pixel' => array(
|
|
'data_shared' => 'Website activity, device information, IP address',
|
|
'purpose' => 'Advertising and marketing analytics',
|
|
'retention' => 'Varies (see Facebook privacy policy)',
|
|
'location' => 'United States (Facebook servers)',
|
|
'user_rights' => 'Users can opt-out via Facebook privacy settings'
|
|
),
|
|
'recaptcha' => array(
|
|
'data_shared' => 'IP address, mouse movements, browser information',
|
|
'purpose' => 'Spam and bot protection',
|
|
'retention' => 'Varies (see Google privacy policy)',
|
|
'location' => 'United States (Google servers)',
|
|
'user_rights' => 'No specific opt-out mechanism (necessary for functionality)'
|
|
)
|
|
);
|
|
|
|
return $implications[$service] ?? array();
|
|
}
|
|
|
|
/**
|
|
* Scan data collection points
|
|
*/
|
|
private function scan_data_collection_points() {
|
|
// Ensure we have the required WordPress functions loaded
|
|
if (!function_exists('is_plugin_active')) {
|
|
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
|
}
|
|
|
|
$collection_points = array();
|
|
|
|
// Registration forms
|
|
if (get_option('users_can_register')) {
|
|
$collection_points['user_registration'] = array(
|
|
'type' => 'User Registration',
|
|
'data_collected' => 'Username, email address, password',
|
|
'purpose' => 'Account creation and management',
|
|
'legal_basis' => 'Consent',
|
|
'required' => true
|
|
);
|
|
}
|
|
|
|
// Comment forms
|
|
if (comments_open()) {
|
|
$collection_points['comments'] = array(
|
|
'type' => 'Comment Forms',
|
|
'data_collected' => 'Name, email address, website URL, IP address, comment content',
|
|
'purpose' => 'Comment moderation and display',
|
|
'legal_basis' => 'Legitimate interest',
|
|
'required' => false
|
|
);
|
|
}
|
|
|
|
// Contact forms (detect common plugins)
|
|
$contact_form_plugins = array(
|
|
'contact-form-7' => 'Contact Form 7',
|
|
'wpforms' => 'WPForms',
|
|
'gravityforms' => 'Gravity Forms',
|
|
'ninja-forms' => 'Ninja Forms'
|
|
);
|
|
|
|
foreach ($contact_form_plugins as $plugin => $name) {
|
|
if (function_exists('is_plugin_active') && is_plugin_active($plugin . '/' . $plugin . '.php')) {
|
|
$collection_points['contact_forms'] = array(
|
|
'type' => 'Contact Forms (' . $name . ')',
|
|
'data_collected' => 'Name, email address, message content, and other form fields',
|
|
'purpose' => 'Customer support and communication',
|
|
'legal_basis' => 'Legitimate interest',
|
|
'required' => false
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// E-commerce (WooCommerce)
|
|
if (class_exists('WooCommerce')) {
|
|
$collection_points['ecommerce'] = array(
|
|
'type' => 'E-commerce Orders',
|
|
'data_collected' => 'Billing information, shipping address, payment details, order history',
|
|
'purpose' => 'Order processing and customer service',
|
|
'legal_basis' => 'Contract performance',
|
|
'required' => true
|
|
);
|
|
}
|
|
|
|
return $collection_points;
|
|
}
|
|
|
|
/**
|
|
* Scan cookies usage
|
|
*/
|
|
private function scan_cookies_usage() {
|
|
$cookies_analysis = array(
|
|
'wordpress_core' => array(
|
|
'wp_logged_in' => 'User authentication',
|
|
'wp_session' => 'Session management',
|
|
'comment_author' => 'Comment form pre-filling'
|
|
),
|
|
'third_party' => array(),
|
|
'analytics' => array(),
|
|
'marketing' => array()
|
|
);
|
|
|
|
// Detect analytics cookies
|
|
if ((function_exists('is_plugin_active') && is_plugin_active('google-analytics-for-wordpress/googleanalytics.php')) ||
|
|
get_option('google_analytics_id')) {
|
|
$cookies_analysis['analytics']['google_analytics'] = array(
|
|
'cookies' => '_ga, _ga_*, _gid, _gat',
|
|
'purpose' => 'Website analytics and user behavior tracking',
|
|
'duration' => 'Up to 2 years',
|
|
'provider' => 'Google Analytics'
|
|
);
|
|
}
|
|
|
|
// Detect marketing cookies (Facebook Pixel, etc.)
|
|
if ($this->detect_facebook_pixel()) {
|
|
$cookies_analysis['marketing']['facebook_pixel'] = array(
|
|
'cookies' => '_fbp, _fbc',
|
|
'purpose' => 'Advertising and marketing analytics',
|
|
'duration' => 'Up to 90 days',
|
|
'provider' => 'Facebook'
|
|
);
|
|
}
|
|
|
|
return $cookies_analysis;
|
|
}
|
|
|
|
/**
|
|
* Scan external integrations
|
|
*/
|
|
private function scan_external_integrations() {
|
|
$integrations = array();
|
|
|
|
// Email marketing integrations
|
|
if (function_exists('is_plugin_active') && is_plugin_active('mailchimp-for-wp/mailchimp-for-wp.php')) {
|
|
$integrations['mailchimp'] = array(
|
|
'service' => 'Mailchimp',
|
|
'purpose' => 'Email marketing and newsletters',
|
|
'data_shared' => 'Email addresses, subscriber preferences',
|
|
'location' => 'United States'
|
|
);
|
|
}
|
|
|
|
// Payment processors
|
|
if (class_exists('WooCommerce')) {
|
|
// Detect payment gateways
|
|
$payment_gateways = WC()->payment_gateways()->get_available_payment_gateways();
|
|
foreach ($payment_gateways as $gateway_id => $gateway) {
|
|
if ($gateway->enabled === 'yes') {
|
|
$integrations[$gateway_id] = array(
|
|
'service' => $gateway->get_title(),
|
|
'purpose' => 'Payment processing',
|
|
'data_shared' => 'Payment information, billing details',
|
|
'location' => $this->get_payment_gateway_location($gateway_id)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $integrations;
|
|
}
|
|
|
|
/**
|
|
* Scan user-generated content features
|
|
*/
|
|
private function scan_user_content_features() {
|
|
$user_content = array();
|
|
|
|
// Comments
|
|
if (comments_open()) {
|
|
$user_content['comments'] = array(
|
|
'type' => 'Comments',
|
|
'moderation' => get_option('comment_moderation') ? 'enabled' : 'disabled',
|
|
'registration_required' => get_option('comment_registration'),
|
|
'data_retention' => 'Until manually deleted'
|
|
);
|
|
}
|
|
|
|
// User profiles
|
|
if (get_option('users_can_register')) {
|
|
$user_content['user_profiles'] = array(
|
|
'type' => 'User Profiles',
|
|
'editable_by_user' => true,
|
|
'data_retention' => 'Until account deletion'
|
|
);
|
|
}
|
|
|
|
// Forum features (if BuddyPress/bbPress active)
|
|
if (function_exists('is_plugin_active') && is_plugin_active('buddypress/bp-loader.php')) {
|
|
$user_content['social_features'] = array(
|
|
'type' => 'Social Community Features',
|
|
'features' => 'Profiles, activity streams, messaging',
|
|
'data_retention' => 'Until account deletion or manual removal'
|
|
);
|
|
}
|
|
|
|
return $user_content;
|
|
}
|
|
|
|
/**
|
|
* Build comprehensive policy content
|
|
*/
|
|
private function build_policy_content($template_type, $company_info, $scan_results) {
|
|
$policy_sections = array();
|
|
$template = $this->policy_templates[$template_type];
|
|
|
|
// Build each required section
|
|
foreach ($template['required_sections'] as $section) {
|
|
$policy_sections[$section] = $this->generate_policy_section($section, $template_type, $company_info, $scan_results);
|
|
}
|
|
|
|
// Build optional sections if relevant
|
|
foreach ($template['optional_sections'] as $section) {
|
|
if ($this->should_include_optional_section($section, $scan_results)) {
|
|
$policy_sections[$section] = $this->generate_policy_section($section, $template_type, $company_info, $scan_results);
|
|
}
|
|
}
|
|
|
|
return array(
|
|
'template_type' => $template_type,
|
|
'template_name' => $template['name'],
|
|
'generated_date' => current_time('mysql'),
|
|
'company_info' => $company_info,
|
|
'scan_results_summary' => $this->summarize_scan_results($scan_results),
|
|
'sections' => $policy_sections,
|
|
'last_updated' => current_time('mysql'),
|
|
'version' => '1.0'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Generate individual policy section
|
|
*/
|
|
private function generate_policy_section($section, $template_type, $company_info, $scan_results) {
|
|
$section_content = array(
|
|
'title' => $this->get_section_title($section),
|
|
'content' => '',
|
|
'subsections' => array()
|
|
);
|
|
|
|
switch ($section) {
|
|
case 'data_controller':
|
|
$section_content['content'] = $this->generate_data_controller_section($company_info);
|
|
break;
|
|
|
|
case 'legal_basis':
|
|
$section_content['content'] = $this->generate_legal_basis_section($scan_results);
|
|
break;
|
|
|
|
case 'data_categories':
|
|
$section_content['content'] = $this->generate_data_categories_section($scan_results);
|
|
break;
|
|
|
|
case 'processing_purposes':
|
|
$section_content['content'] = $this->generate_processing_purposes_section($scan_results);
|
|
break;
|
|
|
|
case 'user_rights':
|
|
$section_content['content'] = $this->generate_user_rights_section($template_type);
|
|
break;
|
|
|
|
case 'cookies_policy':
|
|
$section_content['content'] = $this->generate_cookies_section($scan_results);
|
|
break;
|
|
|
|
// Add more sections as needed
|
|
default:
|
|
$section_content['content'] = $this->generate_generic_section($section, $scan_results);
|
|
}
|
|
|
|
return $section_content;
|
|
}
|
|
|
|
/**
|
|
* Generate data controller section
|
|
*/
|
|
private function generate_data_controller_section($company_info) {
|
|
return sprintf(
|
|
"The data controller for this website is:\n\n" .
|
|
"**%s**\n" .
|
|
"%s\n" .
|
|
"Email: %s\n" .
|
|
"%s\n\n" .
|
|
"If you have any questions about this privacy policy or our data processing practices, " .
|
|
"please contact us using the information above.",
|
|
$company_info['name'],
|
|
!empty($company_info['address']) ? $company_info['address'] : '',
|
|
$company_info['email'],
|
|
!empty($company_info['phone']) ? 'Phone: ' . $company_info['phone'] : ''
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Generate legal basis section
|
|
*/
|
|
private function generate_legal_basis_section($scan_results) {
|
|
$content = "We process personal data based on the following legal grounds:\n\n";
|
|
|
|
$legal_bases = array(
|
|
'consent' => 'Your explicit consent (e.g., newsletter signup, cookie consent)',
|
|
'contract' => 'Performance of a contract (e.g., processing orders, user accounts)',
|
|
'legal_obligation' => 'Compliance with legal obligations (e.g., tax records, accounting)',
|
|
'legitimate_interest' => 'Our legitimate business interests (e.g., website security, analytics)',
|
|
'vital_interests' => 'Protection of vital interests (e.g., emergency situations)',
|
|
'public_task' => 'Performance of public tasks (if applicable)'
|
|
);
|
|
|
|
foreach ($legal_bases as $basis => $description) {
|
|
if ($this->scan_indicates_legal_basis($basis, $scan_results)) {
|
|
$content .= "- **" . ucwords(str_replace('_', ' ', $basis)) . "**: " . $description . "\n";
|
|
}
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Generate data categories section
|
|
*/
|
|
private function generate_data_categories_section($scan_results) {
|
|
$content = "We may collect and process the following categories of personal data:\n\n";
|
|
|
|
$data_categories = array(
|
|
'identity_data' => array(
|
|
'examples' => 'Name, username, title, date of birth',
|
|
'detected' => $this->has_identity_data($scan_results)
|
|
),
|
|
'contact_data' => array(
|
|
'examples' => 'Email address, phone number, postal address',
|
|
'detected' => $this->has_contact_data($scan_results)
|
|
),
|
|
'technical_data' => array(
|
|
'examples' => 'IP address, browser type, device information',
|
|
'detected' => $this->has_technical_data($scan_results)
|
|
),
|
|
'usage_data' => array(
|
|
'examples' => 'Pages visited, time spent, click patterns',
|
|
'detected' => $this->has_usage_data($scan_results)
|
|
),
|
|
'financial_data' => array(
|
|
'examples' => 'Payment information, billing details',
|
|
'detected' => $this->has_financial_data($scan_results)
|
|
)
|
|
);
|
|
|
|
foreach ($data_categories as $category => $info) {
|
|
if ($info['detected']) {
|
|
$category_name = ucwords(str_replace('_', ' ', $category));
|
|
$content .= "- **{$category_name}**: {$info['examples']}\n";
|
|
}
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Generate user rights section
|
|
*/
|
|
private function generate_user_rights_section($template_type) {
|
|
$content = "Under applicable privacy laws, you have the following rights regarding your personal data:\n\n";
|
|
|
|
if ($template_type === 'gdpr') {
|
|
$rights = array(
|
|
'access' => 'Right to access your personal data and receive information about our processing',
|
|
'rectification' => 'Right to correct inaccurate or incomplete personal data',
|
|
'erasure' => 'Right to deletion of your personal data ("right to be forgotten")',
|
|
'restrict_processing' => 'Right to restrict processing of your personal data',
|
|
'data_portability' => 'Right to receive your data in a portable format',
|
|
'object' => 'Right to object to processing based on legitimate interests',
|
|
'withdraw_consent' => 'Right to withdraw consent at any time'
|
|
);
|
|
} elseif ($template_type === 'ccpa') {
|
|
$rights = array(
|
|
'know' => 'Right to know what personal information we collect and how we use it',
|
|
'delete' => 'Right to delete personal information we have collected',
|
|
'opt_out' => 'Right to opt-out of the sale of personal information',
|
|
'non_discrimination' => 'Right to non-discriminatory treatment for exercising privacy rights'
|
|
);
|
|
} else {
|
|
$rights = array(
|
|
'access' => 'Right to access your personal information',
|
|
'correction' => 'Right to correct inaccurate information',
|
|
'deletion' => 'Right to request deletion of your information',
|
|
'opt_out' => 'Right to opt-out of certain data processing'
|
|
);
|
|
}
|
|
|
|
foreach ($rights as $right => $description) {
|
|
$right_name = ucwords(str_replace('_', ' ', $right));
|
|
$content .= "- **{$right_name}**: {$description}\n";
|
|
}
|
|
|
|
$content .= "\nTo exercise these rights, please contact us using the information provided in this policy.";
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Helper methods for checking scan results
|
|
*/
|
|
private function has_identity_data($scan_results) {
|
|
return $scan_results['wordpress_core']['user_registration'] ||
|
|
isset($scan_results['data_collection_points']['user_registration']);
|
|
}
|
|
|
|
private function has_contact_data($scan_results) {
|
|
return !empty($scan_results['data_collection_points']);
|
|
}
|
|
|
|
private function has_technical_data($scan_results) {
|
|
return !empty($scan_results['third_party_services']) ||
|
|
!empty($scan_results['cookies_analysis']['analytics']);
|
|
}
|
|
|
|
private function has_usage_data($scan_results) {
|
|
return !empty($scan_results['third_party_services']['google_analytics']) ||
|
|
!empty($scan_results['cookies_analysis']['analytics']);
|
|
}
|
|
|
|
private function has_financial_data($scan_results) {
|
|
return isset($scan_results['data_collection_points']['ecommerce']);
|
|
}
|
|
|
|
/**
|
|
* Save generated policy
|
|
*/
|
|
private function save_generated_policy($policy_content, $template_type, $company_info) {
|
|
global $wpdb;
|
|
|
|
$table_name = $wpdb->prefix . 'tigerstyle_whiskers_privacy_policies';
|
|
|
|
// Create table if it doesn't exist
|
|
$this->create_privacy_policies_table();
|
|
|
|
$result = $wpdb->insert(
|
|
$table_name,
|
|
array(
|
|
'template_type' => $template_type,
|
|
'company_name' => $company_info['name'],
|
|
'policy_content' => json_encode($policy_content),
|
|
'generated_date' => current_time('mysql'),
|
|
'status' => 'draft'
|
|
),
|
|
array('%s', '%s', '%s', '%s', '%s')
|
|
);
|
|
|
|
return $result ? $wpdb->insert_id : false;
|
|
}
|
|
|
|
/**
|
|
* Create privacy policies table
|
|
*/
|
|
private function create_privacy_policies_table() {
|
|
global $wpdb;
|
|
|
|
$table_name = $wpdb->prefix . 'tigerstyle_whiskers_privacy_policies';
|
|
|
|
$charset_collate = $wpdb->get_charset_collate();
|
|
|
|
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
|
|
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
|
template_type varchar(50) NOT NULL,
|
|
company_name varchar(255) NOT NULL,
|
|
policy_content longtext NOT NULL,
|
|
generated_date datetime DEFAULT CURRENT_TIMESTAMP,
|
|
status varchar(20) DEFAULT 'draft',
|
|
published_date datetime DEFAULT NULL,
|
|
last_updated datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY template_type (template_type),
|
|
KEY status (status),
|
|
KEY generated_date (generated_date)
|
|
) $charset_collate;";
|
|
|
|
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
|
dbDelta($sql);
|
|
}
|
|
|
|
/**
|
|
* Render admin page for privacy policy generator
|
|
*/
|
|
public function render_admin_page() {
|
|
?>
|
|
<div class="tigerstyle-whiskers-admin-section">
|
|
<h2><?php _e('Privacy Policy Generator', 'tigerstyle-whiskers'); ?></h2>
|
|
<p class="description">
|
|
<?php _e('Generate comprehensive privacy policies with feline intelligence - automatically scan your website and create compliant policies for your jurisdiction.', 'tigerstyle-whiskers'); ?>
|
|
</p>
|
|
|
|
<?php $this->render_policy_generator_form(); ?>
|
|
<?php $this->render_generated_policies_list(); ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render policy generator form
|
|
*/
|
|
private function render_policy_generator_form() {
|
|
?>
|
|
<div class="tw-policy-generator">
|
|
<h3><?php _e('Generate New Privacy Policy', 'tigerstyle-whiskers'); ?></h3>
|
|
|
|
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
|
|
<input type="hidden" name="action" value="generate_privacy_policy">
|
|
<?php wp_nonce_field('generate_privacy_policy', 'policy_nonce'); ?>
|
|
|
|
<table class="form-table">
|
|
<tr>
|
|
<th scope="row">
|
|
<label for="template_type"><?php _e('Policy Template', 'tigerstyle-whiskers'); ?></label>
|
|
</th>
|
|
<td>
|
|
<select id="template_type" name="template_type" class="regular-text">
|
|
<?php foreach ($this->policy_templates as $type => $template): ?>
|
|
<option value="<?php echo esc_attr($type); ?>">
|
|
<?php echo esc_html($template['name']); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<p class="description"><?php _e('Choose the appropriate template based on your primary jurisdiction.', 'tigerstyle-whiskers'); ?></p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row">
|
|
<label for="company_name"><?php _e('Company/Website Name', 'tigerstyle-whiskers'); ?></label>
|
|
</th>
|
|
<td>
|
|
<input type="text" id="company_name" name="company_name"
|
|
value="<?php echo esc_attr(get_bloginfo('name')); ?>" class="regular-text">
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row">
|
|
<label for="contact_email"><?php _e('Contact Email', 'tigerstyle-whiskers'); ?></label>
|
|
</th>
|
|
<td>
|
|
<input type="email" id="contact_email" name="contact_email"
|
|
value="<?php echo esc_attr(get_option('admin_email')); ?>" class="regular-text">
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row">
|
|
<label for="company_address"><?php _e('Company Address', 'tigerstyle-whiskers'); ?></label>
|
|
</th>
|
|
<td>
|
|
<textarea id="company_address" name="company_address" rows="3" class="large-text"></textarea>
|
|
<p class="description"><?php _e('Required for GDPR compliance if you are a business.', 'tigerstyle-whiskers'); ?></p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<?php submit_button(__('Scan Website & Generate Policy', 'tigerstyle-whiskers'), 'primary', 'generate_policy'); ?>
|
|
</form>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render generated policies list
|
|
*/
|
|
private function render_generated_policies_list() {
|
|
global $wpdb;
|
|
|
|
$table_name = $wpdb->prefix . 'tigerstyle_whiskers_privacy_policies';
|
|
$policies = $wpdb->get_results("SELECT * FROM $table_name ORDER BY generated_date DESC LIMIT 10");
|
|
|
|
if (!empty($policies)): ?>
|
|
<div class="tw-generated-policies">
|
|
<h3><?php _e('Generated Privacy Policies', 'tigerstyle-whiskers'); ?></h3>
|
|
|
|
<table class="wp-list-table widefat fixed striped">
|
|
<thead>
|
|
<tr>
|
|
<th><?php _e('Company', 'tigerstyle-whiskers'); ?></th>
|
|
<th><?php _e('Template', 'tigerstyle-whiskers'); ?></th>
|
|
<th><?php _e('Generated', 'tigerstyle-whiskers'); ?></th>
|
|
<th><?php _e('Status', 'tigerstyle-whiskers'); ?></th>
|
|
<th><?php _e('Actions', 'tigerstyle-whiskers'); ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($policies as $policy): ?>
|
|
<tr>
|
|
<td><?php echo esc_html($policy->company_name); ?></td>
|
|
<td><?php echo esc_html(ucwords($policy->template_type)); ?></td>
|
|
<td><?php echo esc_html(date_i18n(get_option('date_format'), strtotime($policy->generated_date))); ?></td>
|
|
<td>
|
|
<span class="tw-status-<?php echo esc_attr($policy->status); ?>">
|
|
<?php echo esc_html(ucwords($policy->status)); ?>
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<a href="<?php echo admin_url('admin.php?page=tigerstyle-whiskers&tab=privacy-policy&action=view&policy_id=' . $policy->id); ?>"
|
|
class="button button-small">
|
|
<?php _e('View', 'tigerstyle-whiskers'); ?>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif;
|
|
}
|
|
|
|
/**
|
|
* Inject privacy policy metadata into wp_head
|
|
*/
|
|
public function inject_policy_metadata() {
|
|
$policy_url = get_privacy_policy_url();
|
|
if (!$policy_url) {
|
|
return;
|
|
}
|
|
|
|
echo "\n<!-- TigerStyle Whiskers Privacy Policy Metadata -->\n";
|
|
echo '<meta name="privacy-policy" content="' . esc_url($policy_url) . '">' . "\n";
|
|
echo '<link rel="privacy-policy" href="' . esc_url($policy_url) . '">' . "\n";
|
|
echo "<!-- End TigerStyle Whiskers Privacy Policy Metadata -->\n\n";
|
|
}
|
|
|
|
// Additional helper methods would continue here...
|
|
// (get_mysql_version, theme detection methods, etc.)
|
|
}
|