Skip to main content

Documentation

No results found.
Features

Smart Privacy Policy

WebProCMS can generate a privacy policy that matches how the site actually works. Instead of a static legal page that drifts out of date, the CMS inspects its own configuration — which features are enabled, whether analytics runs cookieless...

WebProCMS can generate a privacy policy that matches how the site actually works. Instead of a static legal page that drifts out of date, the CMS inspects its own configuration — which features are enabled, whether analytics runs cookieless or with a persistent cookie, whether Google Analytics or tracking snippets are configured, whether any page embeds a YouTube/Vimeo video, which OAuth and email providers are wired up — and composes an accurate policy from curated section templates. When the detected services later change (a feature is toggled, a GA ID is added, an embed appears), the dashboard flags the policy as out of date and offers one-click regeneration.


How it works

Three pieces under app/Support/PrivacyPolicy/:

  1. PrivacySignalRegistry — the inventory of every data-practice signal the CMS can detect at runtime. Each signal reports whether it's active, a human-readable status line (shown on the settings page), and the data its policy section needs (retention days, provider names, OAuth provider labels, …).
  2. PrivacyPolicyGenerator — composes the full policy HTML from the active signals plus the manual facts, then writes it through the same pipeline the page editor uses: content_overrides upsert → page sidecar recompile (PageDataCompiler) → response-cache clear. It locates the policy's rich-text row by parsing the live page blade (the row slug is install-specific — ThemeInstaller rewrites theme slugs), never by hardcoding a slug.
  3. Section templates in resources/views/partials/privacy-policy/ — one curated Blade partial per signal plus the fixed skeleton (intro, cookies table, data-sale/CCPA, retention, your-rights, children, changes, contact). Every sentence is __()-wrapped with :placeholder substitution, so the wording is translator-ready.

The generated policy is written into the page's editable rich-text row — the page stays fully hand-editable in the page editor afterward. Generation is always explicit (a button), never automatic.

Detected signals

Signal Active when Section discloses
Built-in analytics Analytics feature enabled Server-side, cookieless tracking; daily-rotating SHA-256 visitor hashes; retention period; the optional consent-gated persistent visitor cookie when enabled
Google Analytics A GA4 measurement ID is configured Google receives visitor data; link to Google's policy
Cookie consent banner Cookie Consent enabled The visitor's cookie choices, preference cookie lifetime
Tracking snippets Any active snippet categorized Analytics or Marketing Third-party scripts may collect visit data and set cookies
Embedded videos Any page has an embed-mode x-dl.video (detected from content_overrides) YouTube/Vimeo may set cookies once a video loads
Forms Any form exists Stored submissions + IP (when "save submissions" is on), CRM feeding, reCAPTCHA/Turnstile processing
CRM CRM feature enabled Contact records kept (name, email, phone, company, interactions)
Newsletters Newsletters feature enabled Subscriber storage, unsubscribe, open/click tracking, the delivery provider (Postmark/Resend/Mailgun/SendGrid) when not sending from the server
Online shop Ecommerce feature enabled Order data stored; Stripe processes payments
Member accounts Memberships feature enabled Account data, enabled OAuth sign-in providers, Stripe subscriptions
Blog comments Comments enabled Comment text + name/email/IP/user-agent, OAuth sign-in providers
AI chat assistant AI Chat feature enabled Conversation storage, third-party AI processing, retention period
Google Reviews Places API key + Place ID configured Reviews fetched server-side, no visitor data sent
Search query logging Analytics feature enabled Search terms logged, not identity-linked

The cookies table at the bottom of the policy is derived from the same signals: session/CSRF and wpcms_visitor always; wpcms_consent when the consent banner is on; wpcms_vid when the analytics persistent cookie is enabled; a third-party row when GA/snippets/embeds are present.

Manual facts (Settings → Privacy & Compliance)

The dashboard page at Settings → Privacy & Compliance records the things the code can't know, stored under privacy.* Settings:

  • Legal entity name (defaults from Business settings) and privacy contact email
  • Governing law / jurisdiction (optional)
  • "We sell or share personal data" toggle — drives the CCPA wording
  • Data retention statement (optional override of the generic paragraph)
  • Other third-party services free text (CDN, fulfillment partner, …) — gets its own section
  • Last reviewed date (for the operator's records)
  • Policy page slug (advanced — only if the policy lives at a non-default URL)

The same page shows the live detected data practices readout (every signal with an active/inactive dot and status line) and the Generate / Regenerate controls.

Drift detection

At generation time the registry's fingerprint (every signal's active state + data, plus the manual facts) is snapshotted into the privacy.snapshot Setting along with a content hash of the generated HTML. On the settings page:

  • Drift callout — shown when the current fingerprint differs from the snapshot ("your detected services have changed — regenerate").
  • Hand-edit warning — when the current override's hash differs from the snapshot's content hash, the page was edited by hand since generation; regenerating asks for confirmation (a Flux modal) before overwriting.

AI rewrite (optional)

Generate + rewrite with AI composes the deterministic policy, then passes it through the configured AI text provider (AiTextService) with a system prompt that forbids adding, removing, or changing any factual claim — tone and readability only. If the provider fails or returns unusable output, the deterministic text is written instead and the error is surfaced. The button only appears when an AI provider is configured.

Adding a signal for a new feature

  1. Add one private builder method to PrivacySignalRegistry returning a PrivacySignal (key, translated label, active, status summary, template data, view), and one line in all().
  2. Add the section partial at resources/views/partials/privacy-policy/{key}.blade.php — semantic class-free HTML (<h3>, <p>, <ul>), every sentence __()-wrapped.
  3. That's it — the readout, generation, and drift detection all flow from the registry.

Limits / notes

  • Multilingual: v1 generates in the site's default language only. Translations can be layered later via the {key}__{lang} override convention.
  • Not legal advice: the generated text is an accurate, honest description of what the CMS does, but operators in regulated industries should still have counsel review it.
  • The generator targets the standard theme-installed privacy page; a renamed page is supported via the page-slug setting, and cloned (page-scoped) overrides are written back to their own scope.