added additional plugins
This commit is contained in:
parent
c85895d306
commit
00e60ec1b7
132 changed files with 27514 additions and 0 deletions
721
native/wordpress/maple-gdpr-cookies/maple-gdpr-cookies.php
Normal file
721
native/wordpress/maple-gdpr-cookies/maple-gdpr-cookies.php
Normal file
|
|
@ -0,0 +1,721 @@
|
|||
<?php
|
||||
/**
|
||||
* Plugin Name: Maple GDPR Cookies
|
||||
* Plugin URI: https://mapleopentech.ca/maple-gdpr-cookies
|
||||
* Description: A lightweight, secure, and fully GDPR-compliant cookie consent plugin with script blocking
|
||||
* Version: 4.1.3
|
||||
* Requires at least: 5.0
|
||||
* Requires PHP: 7.2
|
||||
* Author: Your Name
|
||||
* License: GPL v2 or later
|
||||
* Text Domain: maple-gdpr-cookies
|
||||
* WC requires at least: 3.0
|
||||
* WC tested up to: 8.5
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Define plugin constants
|
||||
define('MGC_PLUGIN_FILE', __FILE__);
|
||||
define('MGC_PLUGIN_PATH', plugin_dir_path(__FILE__));
|
||||
define('MGC_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
define('MGC_PLUGIN_VERSION', '4.1.3');
|
||||
define('MGC_DB_VERSION', '2.0');
|
||||
define('MGC_MIN_PHP_VERSION', '7.2');
|
||||
define('MGC_MIN_WP_VERSION', '5.0');
|
||||
|
||||
/**
|
||||
* Plugin activation checks
|
||||
*/
|
||||
function mgc_check_requirements() {
|
||||
$errors = array();
|
||||
|
||||
// Check PHP version
|
||||
if (version_compare(PHP_VERSION, MGC_MIN_PHP_VERSION, '<')) {
|
||||
$errors[] = sprintf(
|
||||
__('Maple GDPR Cookies requires PHP %s or higher. Your server is running PHP %s.', 'maple-gdpr-cookies'),
|
||||
MGC_MIN_PHP_VERSION,
|
||||
PHP_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
// Check WordPress version
|
||||
if (version_compare(get_bloginfo('version'), MGC_MIN_WP_VERSION, '<')) {
|
||||
$errors[] = sprintf(
|
||||
__('Maple GDPR Cookies requires WordPress %s or higher. You are running WordPress %s.', 'maple-gdpr-cookies'),
|
||||
MGC_MIN_WP_VERSION,
|
||||
get_bloginfo('version')
|
||||
);
|
||||
}
|
||||
|
||||
// Check for MySQL version if using utf8mb4
|
||||
global $wpdb;
|
||||
if ($wpdb->db_version() && version_compare($wpdb->db_version(), '5.5.3', '<')) {
|
||||
$errors[] = __('Maple GDPR Cookies requires MySQL 5.5.3 or higher for utf8mb4 support.', 'maple-gdpr-cookies');
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create database tables on activation
|
||||
*/
|
||||
function mgc_create_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
$table_name = $wpdb->prefix . 'mgc_consent_logs';
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
|
||||
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
user_id bigint(20) UNSIGNED NULL,
|
||||
ip_address varchar(45) NOT NULL,
|
||||
user_agent varchar(255) NOT NULL,
|
||||
consent_type varchar(20) NOT NULL,
|
||||
categories text NULL,
|
||||
consent_given tinyint(1) NOT NULL,
|
||||
consent_date datetime NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY user_id (user_id),
|
||||
KEY ip_address (ip_address),
|
||||
KEY consent_date (consent_date)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
||||
dbDelta($sql);
|
||||
|
||||
// Store database version
|
||||
update_option('mgc_db_version', MGC_DB_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default options on activation
|
||||
*/
|
||||
function mgc_set_defaults() {
|
||||
$default_options = array(
|
||||
'enabled' => true,
|
||||
'notice_text' => __('We use cookies to make this site work properly and to understand how you use it. This includes <strong>essential cookies</strong> (required), <strong>analytics cookies</strong> (to understand site usage), and <strong>marketing cookies</strong> (for personalized content). You can accept all, reject optional cookies, or customize your preferences.', 'maple-gdpr-cookies'),
|
||||
'accept_button_text' => __('Accept All', 'maple-gdpr-cookies'),
|
||||
'reject_button_text' => __('Reject Optional', 'maple-gdpr-cookies'),
|
||||
'settings_button_text' => __('Cookie Settings', 'maple-gdpr-cookies'),
|
||||
'privacy_policy_url' => get_privacy_policy_url(),
|
||||
'privacy_policy_text' => __('Privacy Policy', 'maple-gdpr-cookies'),
|
||||
'cookie_expiry' => 365,
|
||||
'position' => 'bottom',
|
||||
'theme' => 'light',
|
||||
'animation' => 'slide',
|
||||
'button_color' => 'blue',
|
||||
'custom_button_color' => '',
|
||||
'custom_button_hover_color' => '',
|
||||
'show_reject_button' => true,
|
||||
'show_settings_button' => true,
|
||||
'preference_display_type' => 'icon',
|
||||
'custom_css' => '',
|
||||
'enable_analytics' => true,
|
||||
'enable_marketing' => true,
|
||||
'enable_functional' => true,
|
||||
'enable_logging' => true
|
||||
);
|
||||
|
||||
foreach ($default_options as $key => $value) {
|
||||
if (get_option('mgc_' . $key) === false) {
|
||||
add_option('mgc_' . $key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all plugin caches - FIXED VERSION
|
||||
*/
|
||||
function mgc_clear_all_caches() {
|
||||
// Method 1: Clear WordPress object cache (if available)
|
||||
if (function_exists('wp_cache_flush')) {
|
||||
wp_cache_flush();
|
||||
}
|
||||
|
||||
// Method 2: Clear plugin-specific transients
|
||||
global $wpdb;
|
||||
|
||||
// Get all mgc transients
|
||||
$transients = $wpdb->get_col(
|
||||
"SELECT option_name FROM $wpdb->options
|
||||
WHERE option_name LIKE '_transient_mgc_%'
|
||||
OR option_name LIKE '_transient_timeout_mgc_%'"
|
||||
);
|
||||
|
||||
// Delete each transient
|
||||
foreach ($transients as $transient) {
|
||||
if (strpos($transient, '_transient_timeout_') === 0) {
|
||||
continue; // Skip timeout entries, they'll be deleted with the transient
|
||||
}
|
||||
|
||||
$transient_key = str_replace('_transient_', '', $transient);
|
||||
delete_transient($transient_key);
|
||||
}
|
||||
|
||||
// Method 3: Clear specific plugin caches
|
||||
$cache_keys = array(
|
||||
'mgc_settings',
|
||||
'mgc_stats',
|
||||
'mgc_consent_logs'
|
||||
);
|
||||
|
||||
foreach ($cache_keys as $key) {
|
||||
wp_cache_delete($key, 'maple-gdpr-cookies');
|
||||
delete_transient($key);
|
||||
}
|
||||
|
||||
// Method 4: Clear WooCommerce cache if present
|
||||
if (function_exists('wc_delete_shop_order_transients')) {
|
||||
wc_delete_shop_order_transients();
|
||||
}
|
||||
|
||||
// Method 5: Trigger cache clear hooks for other plugins
|
||||
do_action('mgc_clear_caches');
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin activation
|
||||
*/
|
||||
function mgc_activate() {
|
||||
// Check requirements
|
||||
$errors = mgc_check_requirements();
|
||||
if (!empty($errors)) {
|
||||
deactivate_plugins(plugin_basename(__FILE__));
|
||||
wp_die(
|
||||
implode('<br>', $errors),
|
||||
__('Plugin Activation Error', 'maple-gdpr-cookies'),
|
||||
array('back_link' => true)
|
||||
);
|
||||
}
|
||||
|
||||
// Create database tables
|
||||
mgc_create_tables();
|
||||
|
||||
// Set default options
|
||||
mgc_set_defaults();
|
||||
|
||||
// Clear all caches - now using fixed function
|
||||
mgc_clear_all_caches();
|
||||
|
||||
// Set activation flag
|
||||
set_transient('mgc_activation_redirect', true, 30);
|
||||
}
|
||||
register_activation_hook(__FILE__, 'mgc_activate');
|
||||
|
||||
/**
|
||||
* Plugin deactivation
|
||||
*/
|
||||
function mgc_deactivate() {
|
||||
// Clear all caches
|
||||
mgc_clear_all_caches();
|
||||
|
||||
// Clear scheduled events
|
||||
wp_clear_scheduled_hook('mgc_cleanup_logs');
|
||||
wp_clear_scheduled_hook('mgc_optimize_database');
|
||||
}
|
||||
register_deactivation_hook(__FILE__, 'mgc_deactivate');
|
||||
|
||||
/**
|
||||
* Plugin uninstall - only if user chooses to delete data
|
||||
*/
|
||||
function mgc_uninstall() {
|
||||
global $wpdb;
|
||||
|
||||
// Always clear scheduled tasks even if keeping data
|
||||
wp_clear_scheduled_hook('mgc_cleanup_logs');
|
||||
wp_clear_scheduled_hook('mgc_optimize_database');
|
||||
|
||||
// Check if user wants to keep data
|
||||
if (get_option('mgc_keep_data_on_uninstall', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Drop database tables
|
||||
$table_name = $wpdb->prefix . 'mgc_consent_logs';
|
||||
$wpdb->query("DROP TABLE IF EXISTS $table_name");
|
||||
|
||||
// Delete all plugin options
|
||||
$wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE 'mgc_%'");
|
||||
|
||||
// Clear all caches
|
||||
mgc_clear_all_caches();
|
||||
}
|
||||
register_uninstall_hook(__FILE__, 'mgc_uninstall');
|
||||
|
||||
/**
|
||||
* Load plugin textdomain for translations
|
||||
*/
|
||||
function mgc_load_textdomain() {
|
||||
load_plugin_textdomain(
|
||||
'maple-gdpr-cookies',
|
||||
false,
|
||||
dirname(plugin_basename(__FILE__)) . '/languages'
|
||||
);
|
||||
}
|
||||
add_action('plugins_loaded', 'mgc_load_textdomain');
|
||||
|
||||
/**
|
||||
* Enqueue frontend scripts and styles
|
||||
*/
|
||||
function mgc_enqueue_frontend_assets() {
|
||||
// Only load if enabled
|
||||
if (!get_option('mgc_enabled', true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user already has consent cookie
|
||||
$has_consent = isset($_COOKIE['mgc_consent']);
|
||||
|
||||
// Enqueue CSS
|
||||
wp_enqueue_style(
|
||||
'mgc-frontend',
|
||||
MGC_PLUGIN_URL . 'public/css/frontend.css',
|
||||
array(),
|
||||
MGC_PLUGIN_VERSION
|
||||
);
|
||||
|
||||
// Add custom CSS if provided
|
||||
$custom_css = get_option('mgc_custom_css');
|
||||
if (!empty($custom_css)) {
|
||||
wp_add_inline_style('mgc-frontend', $custom_css);
|
||||
}
|
||||
|
||||
// Add custom button colors if provided
|
||||
$custom_button_color = get_option('mgc_custom_button_color');
|
||||
$custom_button_hover_color = get_option('mgc_custom_button_hover_color');
|
||||
|
||||
if (!empty($custom_button_color) || !empty($custom_button_hover_color)) {
|
||||
$color_css = '';
|
||||
|
||||
if (!empty($custom_button_color)) {
|
||||
$color_css .= '.mgc-button { background: ' . esc_attr($custom_button_color) . ' !important; }';
|
||||
$color_css .= '.mgc-floating-button { background: ' . esc_attr($custom_button_color) . ' !important; }';
|
||||
}
|
||||
|
||||
if (!empty($custom_button_hover_color)) {
|
||||
$color_css .= '.mgc-button:hover { background: ' . esc_attr($custom_button_hover_color) . ' !important; }';
|
||||
$color_css .= '.mgc-floating-button:hover { background: ' . esc_attr($custom_button_hover_color) . ' !important; }';
|
||||
}
|
||||
|
||||
wp_add_inline_style('mgc-frontend', $color_css);
|
||||
}
|
||||
|
||||
// Enqueue the compliant JS (blocks scripts before consent)
|
||||
wp_enqueue_script(
|
||||
'mgc-frontend-compliant',
|
||||
MGC_PLUGIN_URL . 'public/js/frontend-compliant.js',
|
||||
array(),
|
||||
MGC_PLUGIN_VERSION,
|
||||
false // Load in head for early script blocking
|
||||
);
|
||||
|
||||
// Localize script with settings
|
||||
wp_localize_script('mgc-frontend-compliant', 'mgcSettings', array(
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('mgc_consent_nonce'),
|
||||
'noticeText' => get_option('mgc_notice_text'),
|
||||
'acceptButtonText' => get_option('mgc_accept_button_text'),
|
||||
'rejectButtonText' => get_option('mgc_reject_button_text'),
|
||||
'settingsButtonText' => get_option('mgc_settings_button_text'),
|
||||
'privacyPolicyUrl' => get_option('mgc_privacy_policy_url'),
|
||||
'privacyPolicyText' => get_option('mgc_privacy_policy_text'),
|
||||
'cookieExpiry' => intval(get_option('mgc_cookie_expiry', 365)),
|
||||
'position' => get_option('mgc_position', 'bottom'),
|
||||
'theme' => get_option('mgc_theme', 'light'),
|
||||
'animation' => get_option('mgc_animation', 'slide'),
|
||||
'buttonColor' => get_option('mgc_button_color', 'blue'),
|
||||
'showRejectButton' => (bool) get_option('mgc_show_reject_button', true),
|
||||
'showSettingsButton' => (bool) get_option('mgc_show_settings_button', true),
|
||||
'preferenceDisplayType' => get_option('mgc_preference_display_type', 'icon')
|
||||
));
|
||||
}
|
||||
add_action('wp_enqueue_scripts', 'mgc_enqueue_frontend_assets');
|
||||
|
||||
/**
|
||||
* Enqueue admin scripts and styles
|
||||
*/
|
||||
function mgc_enqueue_admin_assets($hook) {
|
||||
// Only load on plugin settings pages
|
||||
if (strpos($hook, 'maple-gdpr-cookies') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enqueue WordPress color picker
|
||||
wp_enqueue_style('wp-color-picker');
|
||||
|
||||
// Enqueue admin CSS
|
||||
wp_enqueue_style(
|
||||
'mgc-admin',
|
||||
MGC_PLUGIN_URL . 'admin/css/admin.css',
|
||||
array(),
|
||||
MGC_PLUGIN_VERSION
|
||||
);
|
||||
|
||||
// Enqueue admin JS
|
||||
wp_enqueue_script(
|
||||
'mgc-admin',
|
||||
MGC_PLUGIN_URL . 'admin/js/admin.js',
|
||||
array('jquery', 'wp-color-picker'),
|
||||
MGC_PLUGIN_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
add_action('admin_enqueue_scripts', 'mgc_enqueue_admin_assets');
|
||||
|
||||
/**
|
||||
* Add admin menu
|
||||
*/
|
||||
function mgc_add_admin_menu() {
|
||||
add_menu_page(
|
||||
__('Maple GDPR Cookies', 'maple-gdpr-cookies'),
|
||||
__('Cookie Settings', 'maple-gdpr-cookies'),
|
||||
'manage_options',
|
||||
'maple-gdpr-cookies',
|
||||
'mgc_admin_page',
|
||||
'dashicons-shield',
|
||||
100
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'maple-gdpr-cookies',
|
||||
__('Settings', 'maple-gdpr-cookies'),
|
||||
__('Settings', 'maple-gdpr-cookies'),
|
||||
'manage_options',
|
||||
'maple-gdpr-cookies',
|
||||
'mgc_admin_page'
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'maple-gdpr-cookies',
|
||||
__('Consent Logs', 'maple-gdpr-cookies'),
|
||||
__('Consent Logs', 'maple-gdpr-cookies'),
|
||||
'manage_options',
|
||||
'maple-gdpr-cookies-logs',
|
||||
'mgc_logs_page'
|
||||
);
|
||||
}
|
||||
add_action('admin_menu', 'mgc_add_admin_menu');
|
||||
|
||||
/**
|
||||
* Admin page callback
|
||||
*/
|
||||
function mgc_admin_page() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle form submission
|
||||
if (isset($_POST['mgc_save_settings']) && check_admin_referer('mgc_settings_nonce')) {
|
||||
mgc_save_settings();
|
||||
}
|
||||
|
||||
include MGC_PLUGIN_PATH . 'admin/views/settings.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs page callback
|
||||
*/
|
||||
function mgc_logs_page() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return;
|
||||
}
|
||||
|
||||
include MGC_PLUGIN_PATH . 'admin/views/logs.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings
|
||||
*/
|
||||
function mgc_save_settings() {
|
||||
$settings = array(
|
||||
'enabled',
|
||||
'notice_text',
|
||||
'accept_button_text',
|
||||
'reject_button_text',
|
||||
'settings_button_text',
|
||||
'privacy_policy_url',
|
||||
'privacy_policy_text',
|
||||
'cookie_expiry',
|
||||
'position',
|
||||
'theme',
|
||||
'animation',
|
||||
'button_color',
|
||||
'custom_button_color',
|
||||
'custom_button_hover_color',
|
||||
'show_reject_button',
|
||||
'show_settings_button',
|
||||
'preference_display_type',
|
||||
'custom_css',
|
||||
'enable_analytics',
|
||||
'enable_marketing',
|
||||
'enable_functional',
|
||||
'enable_logging'
|
||||
);
|
||||
|
||||
// List of checkbox fields (need special handling since unchecked = no POST data)
|
||||
$checkbox_fields = array(
|
||||
'enabled',
|
||||
'show_reject_button',
|
||||
'show_settings_button',
|
||||
'enable_analytics',
|
||||
'enable_marketing',
|
||||
'enable_functional',
|
||||
'enable_logging'
|
||||
);
|
||||
|
||||
foreach ($settings as $setting) {
|
||||
// Special handling for checkboxes
|
||||
if (in_array($setting, $checkbox_fields)) {
|
||||
// Checkbox: if it's in POST and = '1', it's checked. Otherwise it's unchecked.
|
||||
$value = (isset($_POST['mgc_' . $setting]) && $_POST['mgc_' . $setting] == '1') ? true : false;
|
||||
} else {
|
||||
$value = isset($_POST['mgc_' . $setting]) ? $_POST['mgc_' . $setting] : '';
|
||||
|
||||
// Sanitize based on type
|
||||
if ($setting === 'cookie_expiry') {
|
||||
$value = absint($value);
|
||||
// Enforce minimum and maximum values for GDPR compliance
|
||||
if ($value < 1) $value = 1;
|
||||
if ($value > 365) $value = 365;
|
||||
} elseif ($setting === 'custom_css') {
|
||||
$value = wp_strip_all_tags($value);
|
||||
// Remove any javascript: or data: URLs to prevent CSS injection attacks
|
||||
$value = preg_replace('/url\s*\(\s*[\'"]?\s*(?:javascript|data):/i', 'url(blocked:', $value);
|
||||
// Limit length to prevent abuse (10KB should be more than enough for custom CSS)
|
||||
$value = substr($value, 0, 10000);
|
||||
} elseif (in_array($setting, array('custom_button_color', 'custom_button_hover_color'))) {
|
||||
// Sanitize hex color
|
||||
$value = sanitize_text_field($value);
|
||||
// Validate hex color format
|
||||
if (!empty($value) && !preg_match('/^#[a-fA-F0-9]{6}$/', $value)) {
|
||||
$value = ''; // Clear invalid hex colors
|
||||
}
|
||||
} elseif ($setting === 'preference_display_type') {
|
||||
// Validate preference display type
|
||||
$value = sanitize_text_field($value);
|
||||
if (!in_array($value, array('icon', 'footer', 'neither'))) {
|
||||
$value = 'icon'; // Default to icon if invalid
|
||||
}
|
||||
} else {
|
||||
$value = sanitize_text_field($value);
|
||||
}
|
||||
}
|
||||
|
||||
update_option('mgc_' . $setting, $value);
|
||||
}
|
||||
|
||||
// Clear caches after saving
|
||||
mgc_clear_all_caches();
|
||||
|
||||
add_settings_error(
|
||||
'mgc_messages',
|
||||
'mgc_message',
|
||||
__('Settings saved successfully.', 'maple-gdpr-cookies'),
|
||||
'updated'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for saving consent
|
||||
*/
|
||||
function mgc_save_consent() {
|
||||
check_ajax_referer('mgc_consent_nonce', 'nonce');
|
||||
|
||||
// Rate limiting - max 10 consent saves per hour per IP to prevent abuse
|
||||
$ip = mgc_get_ip_address();
|
||||
$rate_key = 'mgc_consent_rate_' . md5($ip);
|
||||
$attempts = get_transient($rate_key);
|
||||
|
||||
if ($attempts && $attempts >= 10) {
|
||||
wp_send_json_error(array(
|
||||
'message' => __('Too many requests. Please try again later.', 'maple-gdpr-cookies')
|
||||
), 429);
|
||||
return;
|
||||
}
|
||||
|
||||
// Increment rate limit counter
|
||||
set_transient($rate_key, ($attempts ? $attempts + 1 : 1), HOUR_IN_SECONDS);
|
||||
|
||||
$consent_type = sanitize_text_field($_POST['consent_type']);
|
||||
$categories = isset($_POST['categories']) ? array_map('sanitize_text_field', $_POST['categories']) : array();
|
||||
|
||||
// Log consent if enabled
|
||||
if (get_option('mgc_enable_logging', true)) {
|
||||
mgc_log_consent($consent_type, $categories);
|
||||
}
|
||||
|
||||
wp_send_json_success(array(
|
||||
'message' => __('Consent saved successfully', 'maple-gdpr-cookies')
|
||||
));
|
||||
}
|
||||
add_action('wp_ajax_mgc_save_consent', 'mgc_save_consent');
|
||||
add_action('wp_ajax_nopriv_mgc_save_consent', 'mgc_save_consent');
|
||||
|
||||
/**
|
||||
* Log user consent
|
||||
*/
|
||||
function mgc_log_consent($consent_type, $categories = array()) {
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'mgc_consent_logs';
|
||||
|
||||
// Get and anonymize IP address (GDPR compliance)
|
||||
$ip_address = mgc_anonymize_ip(mgc_get_ip_address());
|
||||
|
||||
$wpdb->insert(
|
||||
$table_name,
|
||||
array(
|
||||
'user_id' => get_current_user_id(),
|
||||
'ip_address' => $ip_address,
|
||||
'user_agent' => sanitize_text_field(substr($_SERVER['HTTP_USER_AGENT'], 0, 255)),
|
||||
'consent_type' => $consent_type,
|
||||
'categories' => json_encode($categories),
|
||||
'consent_given' => ($consent_type === 'accept'),
|
||||
'consent_date' => current_time('mysql')
|
||||
),
|
||||
array('%d', '%s', '%s', '%s', '%s', '%d', '%s')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user IP address
|
||||
*/
|
||||
function mgc_get_ip_address() {
|
||||
$ip = '';
|
||||
|
||||
// Check if behind a proxy and validate
|
||||
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
// X-Forwarded-For can contain multiple IPs, get the first one (original client)
|
||||
$ip_list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
||||
$ip = trim($ip_list[0]);
|
||||
} elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
||||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} else {
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
// Validate it's a real IP address
|
||||
if (!filter_var($ip, FILTER_VALIDATE_IP)) {
|
||||
// If invalid, fall back to direct connection IP
|
||||
$ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
|
||||
}
|
||||
|
||||
return sanitize_text_field($ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Anonymize IP address (GDPR compliance)
|
||||
* Removes last octet for IPv4, last segment for IPv6
|
||||
*/
|
||||
function mgc_anonymize_ip($ip) {
|
||||
// Validate and anonymize IPv4
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
return preg_replace('/\.\d+$/', '.0', $ip);
|
||||
}
|
||||
|
||||
// Validate and anonymize IPv6
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
return preg_replace('/:[^:]+$/', ':0', $ip);
|
||||
}
|
||||
|
||||
// If invalid IP, return masked version
|
||||
return '0.0.0.0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule cleanup tasks
|
||||
*/
|
||||
function mgc_schedule_cleanup() {
|
||||
if (!wp_next_scheduled('mgc_cleanup_logs')) {
|
||||
wp_schedule_event(time(), 'daily', 'mgc_cleanup_logs');
|
||||
}
|
||||
|
||||
if (!wp_next_scheduled('mgc_optimize_database')) {
|
||||
wp_schedule_event(time(), 'weekly', 'mgc_optimize_database');
|
||||
}
|
||||
}
|
||||
add_action('wp', 'mgc_schedule_cleanup');
|
||||
|
||||
/**
|
||||
* Cleanup old consent logs
|
||||
*/
|
||||
function mgc_cleanup_old_logs() {
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'mgc_consent_logs';
|
||||
$retention_days = apply_filters('mgc_log_retention_days', 365);
|
||||
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $table_name WHERE consent_date < DATE_SUB(NOW(), INTERVAL %d DAY)",
|
||||
$retention_days
|
||||
)
|
||||
);
|
||||
}
|
||||
add_action('mgc_cleanup_logs', 'mgc_cleanup_old_logs');
|
||||
|
||||
/**
|
||||
* Optimize database tables
|
||||
*/
|
||||
function mgc_optimize_database_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'mgc_consent_logs';
|
||||
$wpdb->query("OPTIMIZE TABLE $table_name");
|
||||
}
|
||||
add_action('mgc_optimize_database', 'mgc_optimize_database_tables');
|
||||
|
||||
/**
|
||||
* Add settings link on plugins page
|
||||
*/
|
||||
function mgc_add_settings_link($links) {
|
||||
$settings_link = '<a href="' . admin_url('admin.php?page=maple-gdpr-cookies') . '">' . __('Settings', 'maple-gdpr-cookies') . '</a>';
|
||||
array_unshift($links, $settings_link);
|
||||
return $links;
|
||||
}
|
||||
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'mgc_add_settings_link');
|
||||
|
||||
/**
|
||||
* Redirect to settings page on activation
|
||||
*/
|
||||
function mgc_activation_redirect() {
|
||||
if (get_transient('mgc_activation_redirect')) {
|
||||
delete_transient('mgc_activation_redirect');
|
||||
|
||||
if (!isset($_GET['activate-multi'])) {
|
||||
wp_safe_redirect(admin_url('admin.php?page=maple-gdpr-cookies'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action('admin_init', 'mgc_activation_redirect');
|
||||
|
||||
/**
|
||||
* Cookie Preferences Shortcode
|
||||
* Usage: [mgc_cookie_preferences] or [mgc_cookie_preferences text="Manage Cookies"]
|
||||
*/
|
||||
function mgc_cookie_preferences_shortcode($atts) {
|
||||
// Only show if plugin is enabled
|
||||
if (!get_option('mgc_enabled', true)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Parse attributes
|
||||
$atts = shortcode_atts(array(
|
||||
'text' => __('Cookie Preferences', 'maple-gdpr-cookies'),
|
||||
'class' => 'mgc-preferences-link'
|
||||
), $atts);
|
||||
|
||||
// Return link with data attribute that JavaScript will handle
|
||||
return sprintf(
|
||||
'<a href="#" class="%s" data-mgc-preferences-trigger aria-label="%s">%s</a>',
|
||||
esc_attr($atts['class']),
|
||||
esc_attr($atts['text']),
|
||||
esc_html($atts['text'])
|
||||
);
|
||||
}
|
||||
add_shortcode('mgc_cookie_preferences', 'mgc_cookie_preferences_shortcode');
|
||||
Loading…
Add table
Add a link
Reference in a new issue