accepted() ) { update_option( 'goconsent_scan_pending', 1, false ); Cron::schedule(); } } /** * Deactivation hook. Data is kept; uninstall.php removes it. */ public static function deactivate() { Cron::unschedule(); } /** * Run upgrades when the stored DB version is older than the code. */ public static function maybe_upgrade() { if ( get_option( 'goconsent_db_version' ) !== GOCONSENT_DB_VERSION ) { self::create_tables(); update_option( 'goconsent_db_version', GOCONSENT_DB_VERSION, false ); } // Moved to another folder (GoConsent ⇄ GoConsent Pro): its script and style addresses // changed, so cached pages must be rebuilt. $dir = basename( GOCONSENT_DIR ); if ( get_option( 'goconsent_dir' ) !== $dir ) { // First run in a new folder (older copies didn't record theirs, but always used "goconsent"). if ( false !== get_option( 'goconsent_dir' ) || 'goconsent' !== $dir ) { self::clear_page_caches(); } update_option( 'goconsent_dir', $dir, true ); if ( ( new Terms() )->accepted() ) { Cron::schedule(); } } } /** * Ask the common page-cache plugins and hosts to clear their cache. */ public static function clear_page_caches() { // Other plugins' own cache hooks, called by their names on purpose. // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound do_action( 'wphb_clear_page_cache' ); // Hummingbird (WPMU DEV). do_action( 'litespeed_purge_all' ); // LiteSpeed Cache. do_action( 'breeze_clear_all_cache' ); // Breeze. do_action( 'sg_cachepress_purge_everything' ); // SiteGround. // phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound if ( function_exists( 'rocket_clean_domain' ) ) { rocket_clean_domain(); // WP Rocket. } if ( function_exists( 'w3tc_flush_all' ) ) { w3tc_flush_all(); // W3 Total Cache. } if ( function_exists( 'wp_cache_clear_cache' ) ) { wp_cache_clear_cache(); // WP Super Cache. } wp_cache_flush(); } /** * Traffic tables. Aggregated counts only; no personal data. */ public static function create_tables() { global $wpdb; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $charset = $wpdb->get_charset_collate(); // One row per day + metric + value, e.g. (2026-10-07, page, /book-now/, 312 views, 280 visitors). dbDelta( "CREATE TABLE {$wpdb->prefix}goconsent_stats ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, day date NOT NULL, metric varchar(20) NOT NULL, dim varchar(191) NOT NULL DEFAULT '', views int(10) unsigned NOT NULL DEFAULT 0, visitors int(10) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (id), UNIQUE KEY day_metric_dim (day,metric,dim), KEY metric_day (metric,day) ) $charset;" ); // Anonymous daily fingerprints (salted hash, salt rotates daily) used only to count // unique visitors for the current day. Rows older than today are deleted hourly. dbDelta( "CREATE TABLE {$wpdb->prefix}goconsent_seen ( day date NOT NULL, hash char(32) NOT NULL, PRIMARY KEY (day,hash) ) $charset;" ); // Proof-of-consent records (kept 24 months). Compliance\ConsentLog::create_table( $charset ); } /** * Carry settings over from the RoxxiStudios Managed WP+ consent module, if present. */ private static function migrate_from_wp_plus() { if ( get_option( Settings::OPTION ) ) { return; } $map = array( 'block' => 'roxxistudios_consent_block', 'gpc' => 'roxxistudios_consent_gpc', 'footer_link' => 'roxxistudios_consent_footer_link', 'analytics_default' => 'roxxistudios_consent_analytics_default', 'policy_date' => 'roxxistudios_consent_policy_date', 'privacy_page' => 'roxxistudios_consent_privacy_page', 'version' => 'roxxistudios_consent_version', 'overrides' => 'roxxistudios_consent_overrides', 'location' => 'roxxistudios_consent_location', 'industries' => 'roxxistudios_consent_industries', 'enforce_at' => 'roxxistudios_consent_enforce_at', ); $settings = new Settings(); foreach ( $map as $key => $old ) { $val = get_option( $old, null ); if ( null !== $val && '' !== $val ) { $settings->set( $key, $val ); } } } }