=== ConsentPilot ===
Contributors: helenegr1989
Tags: gdpr, cookie consent, consent, privacy, cookie banner
Requires at least: 6.3
Tested up to: 6.7
Requires PHP: 7.4
Stable tag: 0.1.10
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

GDPR consent management for WordPress: cookie banner, blocking of tracking scripts and iframes before consent, and a consent log with CSV export. Built and maintained by Helene Grønberg at [helene.cloud](https://helene.cloud).

== Description ==

ConsentPilot is a GDPR consent management plugin for WordPress. Known tracking
scripts and embedded iframes (YouTube, Vimeo, maps) stay blocked in the page
until the visitor agrees to the relevant category, and every consent is
logged in the database as documentation, as required by GDPR art. 7.1.

ConsentPilot is configurable out of the box: choose between three banner
layouts, position, colors and banner text; describe your cookie categories;
add custom blocking patterns for tracking scripts not covered by the built-in
list; and export the consent log as CSV for compliance documentation.

= Features =

* Consent banner in three layouts: box, bar or popup
* "Accept all", "Decline all" and per-category choice
* Blocks known tracking scripts before consent, Google Analytics, Google
  Tag Manager, Meta Pixel, Hotjar, LinkedIn and more
* Also blocks tracking scripts hosted on your own domain
* Iframe blocking for YouTube, Vimeo, Google Maps and Spotify
* Custom blocking patterns, block anything you add yourself
* Custom cookie categories with descriptions
* Consent log in the database with hashed, anonymized IP
* CSV export of the consent log for documentation
* Policy versioning, request fresh consent when your privacy policy changes
* Google Consent Mode v2 integration for Ads/Analytics in the EEA
* Geo-targeting, only show the banner in selected regions (with Cloudflare
  or a custom GeoIP integration)
* Keyboard accessible, light/dark theme aware
* No frontend dependencies, the banner is lightweight and fast
* Fully translatable

= Support and documentation =

Full documentation, screenshots and a contact form are available on the
plugin homepage at [helene.cloud/consentpilot.html](https://helene.cloud/consentpilot.html).
Bug reports and feature requests can also be sent through the contact form
on [helene.cloud](https://helene.cloud).

== Installation ==

1. Upload the `consentpilot` folder to `/wp-content/plugins/`, or install via
   "Plugins → Add New → Upload Plugin".
2. Activate the plugin under "Plugins" in wp-admin.
3. Go to "ConsentPilot → Settings" to customize the banner.
4. Describe your cookie categories under "ConsentPilot → Cookies".

Requirements: WordPress 6.3+, PHP 7.4+.

== Frequently Asked Questions ==

= Does the plugin store IP addresses? =

No. The consent log only stores a non-reversible SHA-256 hash of an
(optionally anonymized) IP address, never the address itself.

= Is any data sent to a third party? =

No. All data stays in your own WordPress database. ConsentPilot does not
contact any external service.

= Does it actually block Google Analytics before consent? =

Yes. Tracking scripts are neutralized in the page and only activated in the
browser once the visitor accepts the relevant category.

= Does it work with page caching? =

Yes. The blocking uses official WordPress filters and works regardless of
full-page caching.

= What if a tracking script isn't being blocked? =

Add the domain or script handle under "Custom patterns" in the settings,
using the format `pattern|category`.

= Is the consent log kept after uninstalling? =

Yes, by default, consent records are legal documentation. You can opt to
delete everything on uninstall from the settings.

== Screenshots ==

1. The consent banner as visitors see it.
2. Per-category choice when the visitor clicks "Customize".
3. The dashboard in wp-admin with status and statistics.
4. Settings, banner, script blocking and privacy.
5. The consent log with CSV export.

== Changelog ==

= 0.1.10 =
* Fixed: on the page view where a visitor accepts cookies,
  Google Analytics or Google Tag Manager would fail to send
  the pageview because the consent update reached dataLayer
  after the gtag script had already loaded and dispatched its
  first pageview as consent-less. The consent update is now
  pushed to dataLayer before the tracking scripts are
  unblocked, so gtag reads a granted state on its very first
  read of the queue. The visitor who accepts and closes the
  tab is now counted.
* Improved: scripts caught by the wp_head guard (introduced
  in 0.1.8) now correctly restore their src attribute from
  data-consentpilot-src when consent is given. Previously the
  unblock routine rebuilt the script element without setting
  src, so head-guarded scripts never fetched.
* Improved: Consent Mode v2 consent updates write directly to
  window.dataLayer via a local gtag wrapper instead of
  depending on window.gtag being defined as a function at
  call time, matching Google's recommended integration
  pattern.

= 0.1.9 =
* Compliance: "Accept all" and "Decline all" now share the same
  visual weight as a matched pair of primary-coloured buttons.
  The previous default made "Accept all" more prominent than
  "Decline all", which EDPB Guidelines 03/2022 on deceptive
  design patterns and the Norwegian Data Protection Authority
  identify as a pattern that can render consent invalid. The
  "Customize" button remains a lighter outline button, which is
  permitted since it is not a consent choice itself but a
  gateway to per-category selection. Existing custom-CSS
  overrides in the Pro version are not affected.
* Added a small stable public JavaScript API on window.ConsentPilot
  so other plugins and theme code can integrate without guessing
  at CSS class names. Methods:
    window.ConsentPilot.open()           - open the consent panel
    window.ConsentPilot.getConsent()     - read stored consent
    window.ConsentPilot.hasConsent(cat)  - check a category
  The internal method name openSettings() introduced in 0.1.7
  is kept as an alias for backwards compatibility.
* Fixed: scripts blocked by the wp_head guard (introduced in
  0.1.8) never actually loaded after consent was given. The
  head guard moves the "src" attribute to "data-consentpilot-src"
  to neutralize the script, but the unblock routine only knew
  about the old "type=text/plain" pattern from the enqueue-side
  blocker, so it rebuilt the script element without ever
  restoring the src. The unblock routine now restores src from
  data-consentpilot-src, mirroring how iframes are already
  handled. This was the root cause of Google Analytics not
  firing on the page view where consent was given.
* Fixed: Consent Mode v2 consent updates are now written
  directly to window.dataLayer instead of relying on
  window.gtag being defined as a function. gtag scripts load
  async, and the previous defensive check returned silently
  when window.gtag was not yet a function, dropping the
  consent-update signal for that page view. dataLayer is a
  queue that GA/GTM process when their script finishes
  loading, matching Google's own recommended pattern.

= 0.1.8 =
* Improved: raw tracking scripts embedded in themes or in
  "header/footer" plugin fields are now also caught. Previously
  ConsentPilot only blocked scripts that went through the
  WordPress script queue (wp_enqueue_script). A small guard is
  now written into the page head at priority 1 that watches the
  document for hardcoded <script src="..."> tags from Site Kit,
  WPCode, Insert Headers and Footers, GTM plugins, and theme
  header code, and neutralizes matched patterns before the
  browser fetches them.
* Scripts placed literally in header.php before the wp_head()
  call still cannot be blocked - the plugin has no code running
  at that point. This is a rare setup; move the script into a
  wp_head hook or into WordPress's enqueue system.

= 0.1.7 =
* Added a new setting to hide the floating "Cookies" reopen
  button. Site owners who prefer a discreet footer link over a
  permanently visible corner button can now switch it off under
  Settings > Appearance.
* Added a [consentpilot_link] shortcode that renders an "Change
  cookie settings" link anywhere in a page, post, or widget. The
  link opens the consent settings on click. Optional text and
  class attributes: [consentpilot_link text="Cookies"].
* Added a data-consentpilot-open attribute so a theme developer
  can hook a menu item or footer link to the same open action
  without a shortcode.
* Added a small public JS API: window.ConsentPilot.openSettings()
  for cases where JavaScript is the right integration point.
* Cleaned up two leftover "(Pro)" comments that suggested Consent
  Mode v2 and geo-targeting were paywalled - both have been fully
  free since 0.1.1.

= 0.1.6 =
* Fixed: the floating "Cookies" reopen button now uses the primary
  colour you have configured under Settings → Appearance, instead
  of falling back to the default blue on returning visitors.
  Previously the colour was only applied when the full banner
  rendered, so the reopen button on returning sessions never
  picked it up.

= 0.1.5 =
* Fixed: when a visitor reopens the consent banner after having
  saved their choices, the checkboxes now reflect what was
  previously saved (e.g. all four categories checked after
  "Accept all") instead of resetting to only "Necessary". Their
  actual saved consent was never lost — only the UI display was
  incorrect — but the mismatch was confusing.

= 0.1.4 =
* The floating "reopen consent" button now uses an inline SVG
  cookie icon and a small "Cookies" label, so visitors can see
  what the button does at a glance. Previously it relied on a
  cookie emoji that did not render reliably on all platforms.
* The reopen button has a tooltip and a soft shadow for better
  affordance. On screens narrower than 480px the label collapses
  and only the icon is shown.

= 0.1.3 =
* Added an "Upgrade to Pro" box to the plugin dashboard so users
  can discover the optional Pro tier with the privacy-policy
  generator, cookie scanner, audit-report PDF and other features.
  The box is hidden automatically when Pro is licensed.
* No changes to core functionality.

= 0.1.2 =
* Added discreet "Powered by ConsentPilot" link in the banner, with a
  filter so Pro users can hide it (`consentpilot_frontend_config`).
* Added support for an optional custom logo above the banner text.
* No breaking changes, existing installations keep all behavior.

= 0.1.1 =
* Removed the output-buffer-based script blocker. All blocking now uses
  WordPress filters (script_loader_tag, wp_inline_script_attributes,
  the_content), which are predictable and do not interact with the global
  output-buffer stack.
* Removed all license gates from Google Consent Mode v2 and geo-targeting
  settings. Both features are fully functional in this release.

= 0.1.0 =
* Initial release.
* Consent banner with three layouts and per-category choice.
* Blocking of tracking scripts and iframes before consent.
* Consent log with hashed IP and CSV export.
* Custom blocking patterns and policy versioning.

== Upgrade Notice ==

= 0.1.1 =
Fixes the issues raised in the WordPress.org plugin review: removed
output-buffer pattern and removed paywall checks on Consent Mode v2 and
geo-targeting.

= 0.1.0 =
First release of ConsentPilot.
