tigerstyle-whiskers/includes/whiskers/class-cross-border.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

262 lines
9.2 KiB
PHP

<?php
/**
* TigerStyle Whiskers Cross-Border Compliance
*
* Navigate international privacy boundaries with feline precision - every territory has its rules!
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
class TigerStyleWhiskers_CrossBorder {
/**
* Single instance
*/
private static $instance = null;
/**
* Supported jurisdictions
*/
private $jurisdictions = 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_cross_border();
}
/**
* Initialize cross-border compliance
*/
private function init_cross_border() {
$this->define_jurisdictions();
add_action('tigerstyle_whiskers_geo_detected', array($this, 'handle_jurisdiction_change'));
}
/**
* Define supported jurisdictions
*/
private function define_jurisdictions() {
$this->jurisdictions = array(
'EU' => array(
'name' => __('European Union (GDPR)', 'tigerstyle-whiskers'),
'privacy_level' => 'strict',
'required_notices' => array('cookie_consent', 'privacy_policy', 'data_processing'),
'user_rights' => array('access', 'rectification', 'erasure', 'portability', 'objection'),
'consent_requirements' => 'explicit',
'data_retention_limits' => true
),
'US_CA' => array(
'name' => __('California (CCPA/CPRA)', 'tigerstyle-whiskers'),
'privacy_level' => 'moderate',
'required_notices' => array('privacy_policy', 'do_not_sell'),
'user_rights' => array('know', 'delete', 'opt_out', 'non_discrimination'),
'consent_requirements' => 'opt_out',
'data_retention_limits' => false
),
'BR' => array(
'name' => __('Brazil (LGPD)', 'tigerstyle-whiskers'),
'privacy_level' => 'strict',
'required_notices' => array('privacy_policy', 'data_processing'),
'user_rights' => array('access', 'correction', 'anonymization', 'portability'),
'consent_requirements' => 'explicit',
'data_retention_limits' => true
),
'CA' => array(
'name' => __('Canada (PIPEDA)', 'tigerstyle-whiskers'),
'privacy_level' => 'moderate',
'required_notices' => array('privacy_policy'),
'user_rights' => array('access', 'correction'),
'consent_requirements' => 'meaningful',
'data_retention_limits' => true
),
'default' => array(
'name' => __('Default Privacy Standards', 'tigerstyle-whiskers'),
'privacy_level' => 'basic',
'required_notices' => array('privacy_policy'),
'user_rights' => array('access'),
'consent_requirements' => 'opt_in',
'data_retention_limits' => false
)
);
}
/**
* Handle jurisdiction change
*/
public function handle_jurisdiction_change($geo_data) {
$jurisdiction = $this->determine_jurisdiction($geo_data);
$this->apply_jurisdiction_settings($jurisdiction);
}
/**
* Determine applicable jurisdiction
*/
public function determine_jurisdiction($geo_data) {
$country = $geo_data['country'] ?? '';
$region = $geo_data['region'] ?? '';
// EU countries
$eu_countries = array('DE', 'FR', 'IT', 'ES', 'NL', 'BE', 'AT', 'PT', 'IE', 'FI', 'SE', 'DK', 'PL', 'CZ', 'HU', 'SK', 'SI', 'HR', 'BG', 'RO', 'EE', 'LV', 'LT', 'LU', 'MT', 'CY', 'GR');
if (in_array($country, $eu_countries)) {
return 'EU';
}
if ($country === 'US' && $region === 'CA') {
return 'US_CA';
}
if ($country === 'BR') {
return 'BR';
}
if ($country === 'CA') {
return 'CA';
}
return 'default';
}
/**
* Apply jurisdiction-specific settings
*/
private function apply_jurisdiction_settings($jurisdiction_key) {
if (!isset($this->jurisdictions[$jurisdiction_key])) {
$jurisdiction_key = 'default';
}
$jurisdiction = $this->jurisdictions[$jurisdiction_key];
// Update consent requirements
$this->update_consent_settings($jurisdiction);
// Update privacy notices
$this->update_privacy_notices($jurisdiction);
// Store current jurisdiction
update_option('tigerstyle_whiskers_current_jurisdiction', $jurisdiction_key);
// Trigger action for other modules
do_action('tigerstyle_whiskers_jurisdiction_applied', $jurisdiction_key, $jurisdiction);
}
/**
* Update consent settings based on jurisdiction
*/
private function update_consent_settings($jurisdiction) {
$consent_settings = get_option('tigerstyle_whiskers_consent_settings', array());
$consent_settings['consent_type'] = $jurisdiction['consent_requirements'];
$consent_settings['privacy_level'] = $jurisdiction['privacy_level'];
$consent_settings['user_rights'] = $jurisdiction['user_rights'];
update_option('tigerstyle_whiskers_consent_settings', $consent_settings);
}
/**
* Update privacy notices based on jurisdiction
*/
private function update_privacy_notices($jurisdiction) {
$notice_settings = get_option('tigerstyle_whiskers_notice_settings', array());
$notice_settings['required_notices'] = $jurisdiction['required_notices'];
$notice_settings['data_retention_limits'] = $jurisdiction['data_retention_limits'];
update_option('tigerstyle_whiskers_notice_settings', $notice_settings);
}
/**
* Get current jurisdiction
*/
public function get_current_jurisdiction() {
$jurisdiction_key = get_option('tigerstyle_whiskers_current_jurisdiction', 'default');
return $this->jurisdictions[$jurisdiction_key] ?? $this->jurisdictions['default'];
}
/**
* Check if feature is required by current jurisdiction
*/
public function is_feature_required($feature) {
$jurisdiction = $this->get_current_jurisdiction();
return in_array($feature, $jurisdiction['required_notices']);
}
/**
* Get compliance status for current jurisdiction
*/
public function get_compliance_status() {
$jurisdiction = $this->get_current_jurisdiction();
$status = array(
'jurisdiction' => $jurisdiction['name'],
'privacy_level' => $jurisdiction['privacy_level'],
'compliance_score' => 0,
'required_features' => $jurisdiction['required_notices'],
'missing_features' => array(),
'recommendations' => array()
);
// Check each required feature
foreach ($jurisdiction['required_notices'] as $feature) {
if ($this->is_feature_implemented($feature)) {
$status['compliance_score'] += 1;
} else {
$status['missing_features'][] = $feature;
$status['recommendations'][] = $this->get_feature_recommendation($feature);
}
}
// Calculate percentage
$total_features = count($jurisdiction['required_notices']);
$status['compliance_percentage'] = $total_features > 0 ? ($status['compliance_score'] / $total_features) * 100 : 100;
return $status;
}
/**
* Check if a feature is implemented
*/
private function is_feature_implemented($feature) {
switch ($feature) {
case 'cookie_consent':
return class_exists('TigerStyleWhiskers_CookieConsent');
case 'privacy_policy':
return !empty(get_option('wp_page_for_privacy_policy'));
case 'data_processing':
return class_exists('TigerStyleWhiskers_DataMapper');
case 'do_not_sell':
// Check if "Do Not Sell" option is available
return get_option('tigerstyle_whiskers_do_not_sell_enabled', false);
default:
return false;
}
}
/**
* Get recommendation for missing feature
*/
private function get_feature_recommendation($feature) {
$recommendations = array(
'cookie_consent' => __('Implement granular cookie consent banner', 'tigerstyle-whiskers'),
'privacy_policy' => __('Create comprehensive privacy policy', 'tigerstyle-whiskers'),
'data_processing' => __('Document data processing activities', 'tigerstyle-whiskers'),
'do_not_sell' => __('Add "Do Not Sell My Personal Information" option', 'tigerstyle-whiskers')
);
return $recommendations[$feature] ?? __('Implementation required', 'tigerstyle-whiskers');
}
}