| 开发者 | royalpluginsteam |
|---|---|
| 更新时间 | 2026年4月30日 16:33 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 6.9 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
CF-IPCountry), Fastly, KeyCDN, Sucuri. Geo detection runs server-side from existing CDN headers with a browser-timezone fallback — no IP geolocation API is contacted.script_loader_tag filter to change the type attribute of analytics and marketing scripts to text/plain until consent is given, preventing execution.gtag('consent', 'default', {...}) call with a denied state before Google Tag Manager loads, and sends consent update events when the visitor makes a choice.CF-IPCountry etc.) with a browser-timezone fallback. Banner behavior switches between opt-in (GDPR), opt-out (CCPA), and other jurisdictions as configured.CF-IPCountry and similar headers already present in the incoming request. Falls back to the browser's timezone via JavaScript. No IP lookup service is called.royalcomply folder to /wp-content/plugins/.RoyalComply uses WordPress's script_loader_tag filter to change script types from text/javascript to text/plain until consent is given. This prevents scripts from executing. The approach does not require output buffering or DOM manipulation.
Yes. When Google Consent Mode v2 is enabled, RoyalComply outputs the required gtag('consent', 'default', {...}) call before GTM loads, then updates consent state when the user makes a choice.
RoyalComply is designed to help site owners meet GDPR's consent requirements. It blocks analytics and marketing scripts until the visitor gives explicit opt-in consent, stores a record of each consent choice with a SHA-256 hashed identifier, and provides a "Reject All" button with the same prominence as "Accept All". Whether a given site is fully GDPR compliant also depends on the rest of its privacy practices (privacy policy, data processing agreements, etc.), which are outside the scope of this plugin.
Yes. When the visitor's region is detected as California (or any configured opt-out jurisdiction), RoyalComply switches the banner to opt-out mode and displays a "Do Not Sell or Share My Personal Information" link that records the visitor's opt-out choice.
No. Geo detection uses CDN headers (Cloudflare, etc.) that are already present in the request, plus browser timezone as a fallback. No third-party services are contacted.
Yes. Visitor identifiers are SHA-256 hashed with a site-specific salt. No IP addresses or personally identifiable information is stored.
Yes. WooCommerce session and cart cookies are automatically categorized as "necessary" and are never blocked.
CookieYes, Complianz, Cookiebot, Iubenda, OneTrust, and Termly are commercial cookie consent solutions that typically charge $9–49/mo per site or per-page-view (Cookiebot's pricing scales with monthly visitors and can reach hundreds of dollars per month for high-traffic sites). RoyalComply is free with no usage limits, no per-page-view billing, and no external SaaS dependency. Core features — script blocking, Google Consent Mode v2, GDPR opt-in, CCPA opt-out, regional auto-detection, consent logging, and the cookie scanner — are included.
Yes. Enable Google Consent Mode v2 in RoyalComply settings and the plugin outputs the required gtag('consent', 'default', { analytics_storage: 'denied', ad_storage: 'denied', ... }) call before GA4 or Google Tag Manager loads. When the visitor accepts, RoyalComply fires a gtag('consent', 'update', ...) event with their selections and GA4 begins receiving data. Without consent, GA4 still runs in cookieless mode and reports basic anonymized events (this is Google's intended Consent Mode v2 behavior).
Yes. Meta Pixel, Google Ads, LinkedIn Insight Tag, TikTok Pixel, Pinterest Tag, Twitter (X) Pixel, Snapchat Pixel, and Reddit Pixel are auto-categorized as "Marketing" cookies and blocked until the visitor accepts marketing consent. The script-blocking approach uses WordPress's script_loader_tag filter to change each script's type attribute to text/plain until consent is granted, so pixels never fire prematurely.
No. The combined frontend CSS and JavaScript is under 8KB. Banner state is checked from localStorage, which is faster than a server round-trip. The cookie scanner runs only when an admin clicks "Scan Site" — never on a visitor request.
Yes. The banner is rendered with the same HTML for every visitor and the show/hide decision is made client-side by reading localStorage. Page caches serve the same HTML to all visitors and the banner correctly hides for returning visitors who already gave consent. No cache exclusion rules required.
In RoyalComply settings, enable CCPA mode and set California as an opt-out jurisdiction. When a visitor's request arrives with a CDN header indicating California (or matches a California timezone fallback), the banner automatically switches from opt-in to opt-out mode and displays the "Do Not Sell or Share My Personal Information" link. Clicking the link records the visitor's opt-out in the consent log.
Yes. Go to RoyalComply > Consent Log and click "Export CSV". The export includes hashed visitor IDs, timestamps, region, banner version, and category selections — sufficient for demonstrating consent under GDPR Article 7 and CCPA record-keeping requirements. No IP addresses are exported.
$wpdb queries that referenced custom tables now use the %i identifier placeholder (WordPress 6.2+) instead of interpolating the table name into the SQL string. The previous interpolations were not exploitable — the table name was always $wpdb->prefix . 'rcomply_*' (hardcoded literal, no user input) — but they caused 27 PCP / WPCS warnings and made the code harder to audit. Requires at least raised from 5.9 to 6.2 because %i is a 6.2+ feature.var rcomplyConfig script in the rendered HTML, so when a full-page cache (ForgeCache, WP Rocket, W3TC, or any host CDN) captured the response the FIRST visitor's values were baked in and served to everyone afterwards. Two consequences: the nonce eventually expired past WordPress's nonce TTL (~24h), causing every visitor's consent-log AJAX to return "Security check failed" once the cache outlived the token; and the geo result froze on the first visitor's country, so a UK visitor landing on a cache populated by a US visitor would display banner state derived from the wrong region. Both values are now fetched on demand via a new rcomply_init AJAX endpoint at admin-ajax.php — uncached by every cache plugin — and returned per request. Cached HTML now contains only static config (categories, expiry days, GCM toggle, etc.) which is identical for all visitors.rcomply_init AJAX action (public, no nonce required since its purpose is to issue one). Returns {nonce, region, country} for the current request. banner.js calls it lazily — only the first time a consent action needs to POST.isset() to detect the checkbox state, but the JavaScript always sends every checkbox as 1 or 0 (so the key was always present, making isset() always return true). Switched to ! empty() which correctly treats "0" as false.royal-comply to royalcomply so it matches the plugin slug, as required by WordPress.org internationalization guidelines.