Moodle local plugin · Consent manager

Advanced Cookie & Consent Manager

Complete guide for configuration, consent model, Google integration, US opt-out, compliance reporting, and operational QA tests.

1. Overview

The local_advancedcookiebanner plugin manages cookie/tracker consent, blocks optional categories before consent, logs decisions, and supports privacy scenarios (including US opt-out).

Granular consent categories Hook API (Moodle) Privacy API provider Audit log / retention

2. Installation

  1. Place the plugin in /local/advancedcookiebanner.
  2. Run upgrade from /admin.
  3. Run Purge all caches.
Important: after AMD/CSS changes, always purge Moodle caches and do a hard browser refresh.

3. Settings

Path: Site administration -> Plugins -> Local plugins -> Advanced Cookie Banner

AreaOptionsDescription
Coreenabled, consentversion, consentexpirydays, logretentiondaysEnablement, versioning, and consent evidence lifecycle.
Regulationsjurisdictionprofile, showdonotsellshare, respectdnt, respectgpcJurisdiction profile and browser privacy signals.
UIbannerposition, showfloatingbutton, floatingbuttonposition, hidefloatingafteracceptBanner/button placement; hidefloatingafteraccept enables the Close permanently action in modal header.
Modal sectionsshowcategoriessection, showpolicydetailssection, category togglesControls visibility of modal sections.
Googleenablega4, enablegtm, gtmconsentmodeGoogle loading and consent signaling control.
Custom embedscustomembedproviders, externalmediabypassproviderscustomembedproviders improves provider recognition/labeling; externalmediabypassproviders allows selected providers to bypass externalmedia blocking (example: keep YouTube blocked, allow Panopto).

5. GA4 / GTM

  • GA4/GTM start only after analytics consent.
  • With gtmconsentmode=1, consent updates are sent to Google.
  • No analytics consent = no Google Analytics/Tag Manager requests.

6. „Do not sell/share”

Clicking this action saves us_optout and enforces marketing=false.

Status
us_optout
Marketing
disabled
UI state
aria-pressed=true

7. Compliance report

Report: /local/advancedcookiebanner/report.php

  • configuration checklist,
  • consent evidence stat cards,
  • framework readiness matrix.
  • Cookie Scanner report page: /local/advancedcookiebanner/scannerreport.php.
  • Scanner tables support search and column filtering; long URLs wrap responsively.

8. Endpoints and data

  • /local/advancedcookiebanner/consent.php - decision write endpoint.
  • /local/advancedcookiebanner/client_privacy.php - export/delete for anonymous clientid using HMAC token.
  • Table: local_acbanner_consent.
  • Table: local_acbanner_scan_run (scanner run metadata).
  • Table: local_acbanner_scan_finding (detected scanner findings).
  • /local/advancedcookiebanner/scanner.php - manual scanner AJAX endpoint.

9. Regulatory coverage

GDPR (EU & UK)CCPA/CPRAVCDPA PIPEDALGPDCTDPACPA UCPAPDPLPOPIAnFADP DPAPrivacy ActPDPA

Coverage means technical support for controls. Final legal compliance still depends on real deployment, configuration, and legal validation by your organization.

10. Testing

  1. Incognito: verify first layer and Accept/Reject symmetry.
  2. Category test: preferences/analytics/marketing/externalmedia.
  3. Consent withdrawal and cookie cleanup test.
  4. US opt-out and us_optout status test.
  5. Network: no Google requests before analytics consent.
  6. Scanner smoke test: run Run scan on scanner report page.
  7. Target page test: run Scan selected page and verify return + findings.

State reset test (QA)

If you want to test from zero without closing the browser, clear local consent state:

localStorage.removeItem("local_advancedcookiebanner_consent");
localStorage.removeItem("local_advancedcookiebanner_clientid");
localStorage.removeItem("local_advancedcookiebanner_clienttoken");
document.cookie = "acb_consent_state=; Max-Age=0; path=/";
document.cookie = "acb_consent_version=; Max-Age=0; path=/";
document.cookie = "acb_clientid=; Max-Age=0; path=/";
document.cookie = "acb_consent_payload=; Max-Age=0; path=/";
location.reload();

Note: in incognito mode, decisions are usually remembered within the same private window session. After closing all private windows, state should reset.

11. Troubleshooting

  • Old assets: Purge all caches + hard refresh.
  • No report access: verify capability local/advancedcookiebanner:managelogs.
  • Script starts without consent: verify type="text/plain" and data-cookie-category.