=== 410Gone Consent Manager for Google Consent Mode and GTM ===
Contributors: pvalibus
Tags: consent, cookies, gtm, privacy
Requires at least: 6.0
Tested up to: 6.9
Requires PHP: 7.4
Stable Tag: 1.8.2
License: GPLv3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html

Lightweight CMP for WordPress: cookie banner, Consent Mode v2, GTM, Polylang/WPML-ready.

== Description ==
410Gone Consent Manager for Google Consent Mode and GTM is a lightweight CMP with a cookie banner, customization modal, and Google Consent Mode v2 + Google Tag Manager compatibility. It includes desktop/mobile previews in the admin, design and label settings, and multilingual support (Polylang, WPML, or via filter).
You can find the documentation in french for the plugin here : [Official website for the consent managemet wordpress plugin(FR)](https://www.410-gone.fr/blog/plugin-cmp-wordpress-gratuit-consent-mode-v2-gtm.html)

== Key features ==
* Configurable banner and “Customize” modal (titles, texts, buttons, links, category titles/subtitles, named recipients and retention per category).
* Banner position: centered card, bottom banner, or full-width bar.
* Blocking overlay driven in pure CSS (immune to page cache and JS delay) with adjustable opacity, or non-blocking veil, or none.
* Strict Accept/Reject parity: configurable Reject button colors with a built-in contrast/parity guard.
* Enable/disable each proposed category (Analytics, Retargeting, Session recording).
* Keyboard focus trap (RGAA); Escape and the close button never count as consent.
* Google Consent Mode v2 with the seven signals, in basic or advanced mode (advanced is opt-in with an explicit legal warning).
* Tracking modes: all inclusive, hybrid, or GTM-only; the consent cookie is read in the `<head>` in every mode so returning visitors are measured at load.
* One-click **GTM container export** generated from the current settings (mergeable), plus a paused example for non-Google pixels.
* Server-side **consent proof log** (dedicated table, admin viewer, CSV export) without directly identifying data.
* Editable palette with color pickers and a live desktop/mobile preview in the admin (tabbed UI).
* Shortcode `[cmp410gone_manage_cookies]` to display a “Manage my cookies” link.
* Translation-ready for Polylang/WPML, with the `cmp410gone_translate_setting` filter for other multilingual plugins.

== Installation ==
1. Copy the plugin folder into `wp-content/plugins/` (or zip it and install via *Plugins → Add New → Upload Plugin*).
2. Activate “410Gone Consent Manager for Google Consent Mode and GTM” in the WordPress dashboard.
3. Open *Settings → 🍪 410Gone Consent Manager* to configure the CMP.

The settings page (*Settings → 🍪 410Gone Consent Manager*) is organised in four tabs with a sticky live preview.

=== Design ===
* Enable/disable the CMP.
* **Banner position**: centered card, bottom banner, or full-width bar.
* **Blocking overlay**: active (choice required) / non-blocking veil / none, with an opacity slider (20–70%).
* Button colors — Accept, **Reject** (new, with a contrast/parity guard), Customize — plus background and text colors, via color pickers.
* **Proposed categories**: enable/disable Analytics, Retargeting and Session recording (a disabled category disappears from the modal and its consent is no longer requested).
* **Keyboard focus trap** (RGAA).

=== Labels ===
* Banner and modal titles/text; button labels (incl. the modal **Reject-all** button).
* Category titles and subtitles; **named recipients and retention** per category (CNIL requirement).
* Policy link labels and privacy/cookie policy URLs.

=== Tracking & configuration ===
* Choose the tracking mode (all inclusive, hybrid, GTM-only).
* Enter the GTM container ID (e.g. `GTM-XXXXXXX`) and the GA4 measurement ID (e.g. `G-XXXXXXXXXX`).
* Adjust `wait_for_update` (ms) and whether to initialise the dataLayer.
* **Advanced Consent Mode** (opt-in, with a legal warning): cookieless pings before consent, `ads_data_redaction=true`, `url_passthrough=false`.
* **Download GTM container**: exports a mergeable container tailored to the settings above (see the GTM section below).

=== Advanced ===
* Consent retention duration (days, default 180).
* Debug mode (console) and force display for testing.

== Translations ==
1. Save your texts in the main language.
2. **Polylang**: go to *Languages → String translations*, group **CMP 410gone**, and translate each key (`cmp410gone_banner_title`, `cmp410gone_btn_accept`, etc.).
3. **WPML**: go to *WPML → String Translation*, domain **CMP 410gone**, then translate the same keys.
4. **Other plugins**: hook into the `cmp410gone_translate_setting` filter to provide custom translations.

== Frontend usage ==
* The banner and modal are injected automatically (`wp_head`, `wp_footer`).
* The shortcode `[cmp410gone_manage_cookies label="Manage my cookies"]` displays a management link.
* Third-party scripts should be controlled via GTM to respect consent choices.

== Consent categories & signals ==
The banner exposes three opt-in categories mapped to the seven Google Consent Mode v2 signals:

* **Analytics (measurement)** → `analytics_storage`.
* **Retargeting** → `ad_storage`, `ad_user_data`, `ad_personalization`.
* **Session recording** (Clarity, Hotjar…) → `personalization_storage`, `functionality_storage`.
* **Essentials** are always on → `security_storage` is granted; every other signal defaults to `denied` until a choice is made.

== GTM integration recipe (REQUIRED for non-Google tags) ==
Consent Mode only governs Google tags. For any **non-Google** pixel (Meta, Taboola, LinkedIn, Clarity, Hotjar…) you MUST prevent the tag from loading until consent is given — a "decorative" Consent Mode condition does not block anything. Apply this on every site using the CMP:

1. Listen only to the single canonical dataLayer event **`cmp410gone_consent_update`** (see below). Do NOT trigger tags on `ga4_after_consent` (deprecated alias, kept for backward compatibility only).
2. On that event the CMP publishes booleans you must gate with:
   * `cmp410gone_analytics` (measurement, incl. session recording tools attached to analytics),
   * `cmp410gone_retargeting`,
   * `cmp410gone_session` (session recording / heatmaps).
3. Each non-Google tag carries the consent condition of its category (e.g. `ad_storage` + `ad_personalization` for retargeting) **and** its trigger adds an exception when the matching boolean is `false`.
4. Mandatory QA: in a partial-consent state, confirm there is **no network request** to the tracker's domain.

Canonical event payload:
```js
dataLayer.push({
  event: 'cmp410gone_consent_update',
  cmp410gone_analytics: true|false,
  cmp410gone_retargeting: true|false,
  cmp410gone_session: true|false,
  cmp410gone_consent_changed: true|false // true only when the choice was just made by the user
});
```

`cmp410gone_consent_changed` is `true` only when the update comes from a user action (accept/reject/save), and `false` on the init replay for a returning visitor. Combined with `cmp410gone_analytics`, it lets GTM re-send a GA4 `page_view` for the current page the instant a **new** visitor accepts (so the landing shows in GA4 real time without a refresh), without double-counting returning visitors.

== GTM container export ==
The Tracking tab has a **Download GTM container** button that generates a mergeable container from your settings: a GA4 configuration tag on *All Pages* (consent `NOT_SET` in advanced mode, otherwise requiring `analytics_storage`), a Conversion Linker (url_passthrough off), the canonical `cmp410gone_consent_update` trigger, dataLayer variables and “granted” triggers for the enabled categories, a GA4 `page_view (post-consent)` tag (basic mode), and a paused example for non-Google pixels. No site-specific pixel is included — the integrator adds them from the example. In advanced mode the GA4 config already emits a cookieless page_view at load, so the post-consent page_view tag should be removed to avoid double-counting.

== Consent proof (server-side log) ==
Every choice is logged server-side in a dedicated table (`{prefix}cmp410gone_consent_log`) to satisfy the CNIL/GDPR requirement to *demonstrate* consent. Stored data: timestamp, purposes version, and the choice — **no directly identifying data** (IP and User-Agent are only kept as salted SHA-256 hashes). View and export entries under *Settings → 🍪 Consent log*. Entries older than 3 years are pruned automatically. The table is kept on uninstall (proof retention) unless `CMP410GONE_DELETE_LOG_ON_UNINSTALL` is defined to `true`.

== Screenshots ==
1. Plugin backend display a preview for the banner and the customize popin.
2. You can customize the color for the button and the text used in the plugin, you can find more documentation here: https://www.410-gone.fr/blog/plugin-cmp-wordpress-gratuit-consent-mode-v2-gtm.html .
3. Everything can be translated.
4. Complete translation setup using polylang (for example, wpml is also available)


== Changelog ==
= 1.8.2 =
* Real-time measurement of the current page when consent is given: the plugin now reads the cookie and emits the consent update in the `<head>` in every tracking mode (so returning consented visitors are measured at load), and adds `cmp410gone_consent_changed` to the canonical event so GTM can re-send a page_view for the current page the instant a new visitor accepts.
* GTM: the generated/updated containers now include a **GA4 “page_view (post-consent)”** tag firing on `cmp410gone_consent_update` when analytics is granted **and** the choice was just made — no double count for returning visitors.
* **GTM change required** for existing setups: add the `cmp410gone_consent_changed` dataLayer variable (default false), a trigger on `cmp410gone_consent_update` with `cmp410gone_analytics = true` AND `cmp410gone_consent_changed = true`, and a GA4 event `page_view` tag on that trigger (or just re-import the container).
= 1.8.1 =
* Admin: settings redesigned as tabs (Design / Labels / Tracking / Advanced) with a sticky live preview in a two-column layout.
* Added a **“Download GTM container”** button (Tracking tab) that generates a mergeable Google Tag Manager container tailored to the current settings: GA4 configuration tag (consent NOT_SET in advanced mode, else requires analytics_storage), Conversion Linker (url_passthrough off), the canonical `cmp410gone_consent_update` trigger, dataLayer variables and “granted” triggers for the enabled categories, and a paused example tag for non-Google pixels. No site-specific pixel is included.
= 1.8.0 =
* CNIL compliance & conversion (brief lots 1, 2, 4): full banner/modal redesign with strict Accept/Reject parity (both full-color, same size), Customize demoted to an underlined link, and a new **Reject-all** button in the modal.
* New back-office options (Design tab): **Banner position** (centered card / bottom banner / full-width bar), **Blocking overlay** (active / non-blocking veil / none) with opacity 20–70%, **Reject button colors** with a contrast parity guard, **Category enable/disable** (Session recording off by default — no tool deployed), and a **keyboard focus trap** (RGAA).
* Overlay is now pure-CSS, driven by the banner state — immune to page cache and JS delay. The old “Overlay blocking timing” option is removed (migrated).
* Removed pre-checked non-essential checkboxes from the HTML (correct default without JS). Escape/close never write a cookie and never count as consent.
* Named recipients + retention shown per category in the modal, two policy links + 180-day retention in the modal footer. GTM `noscript` iframe now only in `gtm` mode.
* Banner HTML always served visible; JS alone hides it for returning visitors (cache-robust).
* **Advanced Consent Mode** (opt-in, with an explicit legal warning): cookieless pings before consent, `ads_data_redaction=true`, `url_passthrough=false`, and cookie read in the `<head>` in every mode; also fixes `hybrid` so GTM loads without a prior consent cookie.
= 1.7.0 =
* Fixed: GA4 is now configured with valid `gtag('js')`/`gtag('config')` calls instead of inert array pushes — the landing page where consent is given is now measured (audit P1-1).
* Fixed: a global `gtag` wrapper is guaranteed, so the `consent update` always reaches Google on the click page, in every tracking mode (audit P1-2).
* Added: all seven Consent Mode v2 signals are now declared (`security_storage` granted, others denied by default), turning GTM consent conditions from inert to effective (audit P2-1).
* Changed: a single canonical dataLayer event `cmp410gone_consent_update` is now the only recommended hook; `ga4_after_consent` is deprecated and de-duplicated across the head/footer paths (audit P2-2).
* Added: new **Session recording** category (`personalization_storage` + `functionality_storage`) for tools like Clarity/Hotjar.
* Added: server-side consent proof log (dedicated table, REST endpoint, admin viewer, CSV export, 3-year auto-pruning), without directly identifying data.
* Added: governance — exposed `CMP410GONE.version`, legacy cookie migration, consent re-ask on purposes-version change, and admin warnings for missing/identical policy URLs.
* Removed: duplicate `page_view` re-emission by the CMP (GA4 config sends its own).
= 1.6.0 =
* Added tracking modes for analytics loading (all inclusive, hybrid, GTM-only).
* Added GA4 measurement ID configuration in settings.
* Improved consent flow to trigger page_view after consent without reload.
= 1.5.0 =
Add configuration and switch to default overlayoff if no javascript (SEO enhancement for bot crawling)
= 1.4.2 =
* Initial release.

== External services ==
This plugin can load Google Tag Manager when you provide a GTM Container ID in the settings.

* Service: Google Tag Manager (gtm.js and noscript iframe).
* Data sent: the GTM container ID and the consent state stored in the dataLayer.
* When: on page load, only if GTM is enabled in the plugin settings.
* Terms: https://marketingplatform.google.com/about/tag-manager/
* Privacy: https://policies.google.com/privacy

== Troubleshooting ==
* If using JS optimization (e.g. WP Rocket), exclude `cmp.js`/`410gone-consent-manager` from “Delay JavaScript execution”, then clear cache.
* Enable debug mode to follow the consent flow in the console.

More information: https://www.410-gone.fr/blog/plugin-cmp-wordpress-gratuit-consent-mode-v2-gtm.html
