=== AmbassadorHub ===
Contributors:      trybes
Tags:              fundraising, donations, campaigns, ambassador, peer-to-peer
Requires at least: 6.7
Tested up to:      7.1
Requires PHP:      8.2
Stable tag:        1.0.0
License:           GPL-2.0-or-later
License URI:       https://www.gnu.org/licenses/gpl-2.0.html

Peer-to-peer fundraising platform — accounts, campaigns, fundraisers, and donations, running entirely on your own WordPress site.

== Description ==

AmbassadorHub is a peer-to-peer fundraising platform plugin for WordPress. It provides everything you need to run ambassador-led fundraising campaigns:

* **Accounts** — Ambassador role, email verification, custom profile fields, frontend portal
* **Campaigns** — Campaign custom post type with lifecycle management
* **Fundraisers** — Individual and nested (team) fundraiser pages, with a shared team total
* **Donations** — Donation tracking, donor deduplication, and GDPR anonymization
* **Payment Connectors** — Built-in Stripe and PayPal PSP connectors
* **Consent** — Privacy-policy and marketing-consent checkboxes, WP Privacy API export/erasure support
* **REST API** — Full REST API under `ambassadorhub/v1`

Need more payment providers (Mollie, Buckaroo), the automation rule builder, custom fields, or marketing integrations? Those ship in the optional [AmbassadorHub Premium](https://ambassadorhub.nl/prijzen) add-on. Want to run petitions and signature-collection campaigns alongside your fundraisers? See the optional [AmbassadorHub Petitions](https://ambassadorhub.nl/prijzen) add-on.

== Installation ==

1. Upload the `ambassadorhub` folder to `/wp-content/plugins/`.
2. Activate the plugin through the **Plugins** menu in WordPress.
3. Navigate to **AmbassadorHub → Settings** to configure the plugin.
4. Enable and configure a payment connector under **Settings → Payments**.

== Frequently Asked Questions ==

= Does this plugin require WooCommerce? =

No. The plugin uses Action Scheduler (bundled) for background jobs, but does not depend on WooCommerce itself.

= Can I use both Stripe and PayPal at the same time? =

Only one PSP can be active at a time. You can configure both but select the active one under **Settings → Payments**.

= Where do ambassadors log in? =

Ambassadors use a frontend portal block (not wp-admin). Add the Account block to any page to create the ambassador dashboard.

== External Services ==

This plugin connects to third-party payment services when you configure a payment provider. No external connections are made until you explicitly enable and configure a provider under **Settings → Integrations**.

**Gravatar**
Used to display a profile picture for ambassadors and donors who haven't uploaded their own image, via WordPress core's own `get_avatar()`/`get_avatar_url()` functions (the same fallback WordPress itself uses for comment authors and user profiles).
Data sent: the user's email address (hashed before sending, per Gravatar's own API).
Triggered when: an ambassador, donor, or fundraiser owner's avatar is displayed and no custom profile picture has been uploaded.
- Privacy policy: https://automattic.com/privacy/
- Terms of service: https://wordpress.com/tos/

**PayPal**
Processes payments via PayPal checkout.
Data sent: donation amount, currency, customer details, return and cancel URLs. The site's own configured PayPal API credentials are also used to obtain an OAuth access token, and to verify orders/process webhook events.
Triggered when: a donor initiates a payment and PayPal is the active provider; also when a PayPal webhook event arrives, and when a site administrator clicks "Test connection" in Settings → Payments.
- Privacy policy: https://www.paypal.com/us/legalhub/privacy-full
- Terms of service: https://www.paypal.com/us/legalhub/useragreement-full

**Stripe**
Processes payments via credit card and other Stripe-supported methods.
Data sent: donation amount, currency, customer details, payment method tokens.
Triggered when: a donor initiates a payment and Stripe is the active provider; also when a site administrator clicks "Test connection" in Settings → Payments (a read-only request to confirm the configured API key is valid).
- Privacy policy: https://stripe.com/privacy
- Terms of service: https://stripe.com/legal

**Google Analytics / Google Tag Manager (opt-in, off by default)**
Under Settings → Advanced → Analytics, the site owner can enable pushing fundraiser, campaign, and ambassador-registration events to the browser dataLayer. This setting is disabled by default and nothing is pushed until it is turned on. When enabled, events are consumed by whatever GTM container or gtag.js snippet the site owner has already installed — the plugin does not load Google's scripts itself.
Data pushed: event name, and the fundraiser or campaign's title (for fundraiser/campaign events only — the ambassador-registration event carries no additional data).
Triggered when: this setting is enabled, and a fundraiser is published, a campaign starts or ends, or an ambassador registers.
Cookie: only while this setting is enabled, and only when a payment provider is also configured, the plugin sets a first-party cookie named `ambh_tk` (a random UUID, no personal data) to correlate browser sessions across page loads. The cookie has a one-year expiry and is not set otherwise.
- Privacy policy: https://policies.google.com/privacy
- Terms of service: https://policies.google.com/terms

== Screenshots ==

1. Admin dashboard — campaign, ambassador, and donation stats, plus the guided setup checklist.
2. A published fundraiser page — donation progress, recent supporters, and the ambassador's own story.
3. Donation checkout — amount selection, donor details, and payment method (iDEAL, card, SEPA).
4. Frontend ambassador portal — an ambassador's own dashboard with totals across their campaigns and petitions.

== Changelog ==

= 1.0.0 =
* First stable release — AmbassadorHub is now available directly from the WordPress.org Plugin Directory.
* Added built-in spam protection for the public signup, donation, and team-invite forms: an invisible honeypot field, a submission-timing check, per-visitor rate limiting, a disposable/blocked-email-domain filter, and a link-count filter on the donation message field. Every check runs entirely on this site — no CAPTCHA provider, no external service, nothing sent off-site — and is configurable (including fully disabled) from the new Settings → Spam Protection tab, which also shows a log of recently blocked attempts.
* Added a per-account daily cap on team-member invitations, closing a gap where the existing per-team hourly limit could be bypassed by repeatedly creating new teams.

= 0.7.6 =
* Updated "Tested up to" to 7.1 in both the plugin header and readme.txt.

= 0.7.5 =
* Fixed the third round of WordPress.org review findings: broken legal links in External Services, unescaped QR code SVG output, and an admin page slug that kept getting flagged despite already being properly prefixed at runtime.
* Consolidated the plugin onto a single naming prefix throughout (previously three separate, individually-distinctive prefixes).

= 0.7.4 =
* Fixed the second round of WordPress.org review findings: excluded non-standard bundled files from the package, documented Gravatar as an external service, hardened settings/REST security (ownership checks, nonces, sanitization), and prefixed five overly generic shortcode tags.
* Proactively swept the same categories rather than waiting for a third review round: fixed broken settings checkboxes, an unsaved settings field, a broken REST endpoint, and two more request-value-as-storage-key issues.
* Hardened CI to catch these categories automatically going forward (naming-prefix rule, shortcode/file-type checks).

= 0.7.3 =
* Fixed the remaining WordPress.org review findings: moved all inline `<style>`/`<script>` output to properly enqueued assets, sanitized full `$_POST` payloads before handing them to action hooks (not just individual fields), made analytics/dataLayer tracking opt-in and off by default, and closed a PayPal webhook status-forgery path by deriving the persisted donation status only from PayPal's own verified order data.
* Bumped Chart.js to 4.5.1 and chillerlan/php-qrcode to ^6.0 (raises the minimum PHP requirement to 8.2).
* Fixed: the admin menu icon could render oversized on most admin screens — the sizing fix was wired to a WordPress hook that fires after styles are already printed, so it was silently dropped almost everywhere.
* Added `phpcs` (WordPress-Extra ruleset) and the WordPress Plugin Check tool to CI on every push, not just tagged releases, and resolved the full backlog they surfaced.
* CI now also builds and uploads the properly-excluded distribution package (no bundled translations, no dev tooling) as a downloadable artifact on every push, so it can be inspected without cutting a release.

= 0.7.2 =
* Fix: Plugin URI and Author URI were both set to the same address (ambassadorhub.nl) — a WordPress.org requirement is that they point to different pages (one for the plugin, one for the author). Author URI now points to trybes.nl.

= 0.7.1 =
* Fix: .distignore didn't exclude itself, so it would have shipped inside the actual WordPress.org submission zip
* Now ships composer.json/composer.lock alongside the bundled vendor/ folder for build transparency (previously excluded, which Plugin Check flags as an incomplete-looking pairing)
* Ran a full pass against the WordPress security APIs (escaping, sanitization, nonces, capability checks, REST permission callbacks, file upload validation) and the Plugin Check tool — no issues found beyond a few already-reviewed, appropriately-scoped meta_query performance advisories
* Cleaned up readme.txt: removed a stray Dutch word from the description, fixed several old changelog typos, normalized spelling
* Added a GitHub Actions release workflow: pushing a version tag now builds a spec-compliant distribution zip (correct folder structure, .distignore respected, translations compiled) and publishes it as a GitHub Release, gated on the plugin header/readme/tag versions matching and a clean Plugin Check run

= 0.7.0 =
* The admin menu icon and every settings/page header now use the AmbassadorHub brand mark instead of a mix of generic dashicons — the sidebar menu icon is a monochrome silhouette (matching how WordPress treats every other menu icon), page headers show the full-color logo.
* Settings screens: long field explanations are now a small help icon next to the label instead of an always-visible paragraph — hover or focus to read it. Fully translatable and still reachable by screen readers via aria-describedby.
* Tools → Export data is now a clean list (name, description, download button per row) instead of a wrapping row of bare buttons.

= 0.6.0 =
* New: the donation form's address step (street, postal code, city, country) can now be turned off entirely from Settings → Fundraisers → "Collect Donor Address" — useful for organisations that don't need a donor's address. Enabled by default to match existing behaviour.

= 0.5.6 =
* Cleanup: removed dead CSS left over from a previously-removed "Extensions store" admin page and other unused legacy rules (~200 lines) — no visual or functional change, all confirmed unused in this plugin and the Premium/Petitions add-ons

= 0.5.5 =
* Fix: on the Ambassadors admin list (and other AmbassadorHub list tables), the Name/Location columns could render at 0px wide with each character wrapped onto its own line — the default WP "fixed" table layout was locking in a bad initial column-width guess; switched these tables to auto layout

= 0.5.4 =
* Fix: the "Send test email" table on the Tools tab had a leftover 520px width cap, making that one section look noticeably narrower than every other settings section

= 0.5.3 =
* Fix: settings sections each render their own table, so the label column width was computed per-section and drifted between sections/tabs; now fixed to the same width everywhere

= 0.5.2 =
* Settings page: the payment connector list no longer sits in its own nested box — it now shares the same single panel as every other settings section
* Settings page: form fields now stretch to the full width of the panel instead of a fixed 360px, and stay aligned in one column regardless of section

= 0.5.1 =
* Fix: regenerated the Composer autoloader after the 0.5.0 Premium split — a stale class map was still pointing at the old (now-removed) location of the Custom Fields class, causing repeated PHP warnings on the Ambassadors admin screen
* Fix: uninstall.php no longer deletes Premium-owned options/tables/scheduled hooks (Mollie settings, automation rule-engine tables) — only Free-tier data is cleaned up on uninstall
* Settings page redesign: sections now list in a left-hand column with the fields on the right (previously top tabs), matching a cleaner, more app-like settings layout
* Fix: the settings page's own stylesheet was never enqueued and had no effect — its styles are now part of the plugin's main admin stylesheet

= 0.5.0 =
* Split the plugin into Free (this plugin) and a separate AmbassadorHub Premium add-on, ahead of the first WordPress.org submission
* Moved to Premium: the Mollie payment connector, the automation rule builder/engine (the trigger-dispatch primitive stays here so free-tier modules keep working), custom fields, the self-service consent REST API, donation-level GA4 tracking events, and the Custom Fields settings tab
* Petitions, Signers, and Signatures move to a separate, optional Petitions add-on (works with Free or Premium)
* No functional change for sites only using Free-tier features (accounts, campaigns, fundraisers incl. team fundraising, donations, Stripe/PayPal, consent checkboxes, dashboard, CSV/Excel export)

= 0.4.2 =
* Fix: signing a petition failed with "Error submitting signature" whenever the Country field held a full country name (e.g. "Netherlands") instead of a 2-letter code — widened wp_ambh_signers.country from varchar(2) to varchar(100)

= 0.4.1 =
* Petitions admin Stats page — KPI cards, goal progress, and a 12-month confirmed-signatures chart, matching the fundraiser stats screen
* Petition list table now opens the Stats page by default when clicking a petition, same behavior as fundraisers
* Two new sitewide KPI cards ("Active petitions", "Total signatures") on the main AmbassadorHub dashboard

= 0.4.0 =
* Petitions — new petition custom post type (org-created root + ambassador-created sub-petitions), REST API, signature goal tracking, and automations
* Signatures — signature collection with mandatory double opt-in email confirmation, stored separately from donor data (wp_ambh_signers / wp_ambh_signatures)
* Petition pages — single and archive block templates, sign form, signers wall, share/QR blocks, and an owner-posted Updates feed
* Signatures admin screen — view pending/confirmed signatures across all petitions, with a resend-confirmation action

= 0.2.5 =
* Ambassador dashboard improvements
* Invite users to groups

= 0.2.2 =
* Automation engine now logs when emails or webhooks fail to deliver
* Added a warning when trying to create an email action without a correctly configured email setup

= 0.2.1 =
* Fixed and improved the automation engine
* Email actions now include recipient context in the automator
* Webhook settings now accept payloads, more HTTP methods, and custom header options

= 0.2.0 =
* Added teams, groups, individuals
* Multistep donation forms
* Donate directly to a team member
* Changed the creation flow (campaign fundraiser → team fundraiser → individual fundraiser)
* Contextual content tags within emails and webhooks

= 0.1.71 =
* Custom Fields module: define and collect custom fields on signup, donation, and profile forms
* Campaign → Fundraiser migration: converts ambh_campaign posts to root-level (depth=0) ambh_fundraiser posts and re-parents child fundraisers
* Root Fundraiser admin metaboxes replacing campaign metaboxes
* Create Fundraiser form: new step-select-root screen replaces step-select-campaign
* Donor address fields: street, city, postal_code, state, country added to donor records
* Currency input component for amount fields
* Account profile frontend template
* Email verification for ambassador accounts

= 0.1.70 =
* New default block templates (fundraisers-archive, fundraiser-detail, fundraiser-archive) with better responsiveness.

= 0.1.69 =
* Fixed fatal error caused by missing Composer classmap entry for AddConsentTextColumn migration class — replaced with a re-run of CreateTables via dbDelta (idempotent, no separate class needed)

= 0.1.68 =
* Fixed consent text not being saved: passing an explicit empty default to get_option() bypassed the registered setting default, causing empty consent_text on fresh installs
* Added database migration to add consent_text column to existing installs
* Regenerated Composer autoloader classmap to include new migration class

= 0.1.67 =
* Consent Records: added Consent Text column to the admin list table, showing the exact text the user agreed to at the time of giving consent
* Consent Records: consent text displayed as a hover tooltip (truncated preview + info icon) to keep the table readable

= 0.1.66 =
* Updated readme.txt to match plugin header requirements (Requires at least 6.7, PHP 8.2)
* Plugin Check compliance: moved escaping to output points, added wp_kses_post() around wp_dropdown_pages() output
* Wrapped register_block_template() in function_exists() for compatibility with WP < 6.7

= 0.1.65 =
* Fixed datetime-local input not styled consistently with other form fields in Create Fundraiser Form

= 0.1.64 =
* Plugin appearance settings (Primary Color) now applied as initial default on Create Fundraiser Button and Create Team Button, overriding any conflicting theme button styles while remaining overridable per-block

= 0.1.63 =
* Create Fundraiser Button and Create Team Button now support WordPress color palette — background and text color can be set per-block in the editor

= 0.1.62 =
* New Mini Progress Bar block for compact overviews
* Breadcrumbs now work on campaign pages
* QR codes generated server-side (no external service dependency)
* Login, create fundraiser, and dashboard pages now respect appearance settings colors

= 0.1.54–0.1.61 =
* Internal builds: incremental bug fixes, performance improvements, and refactoring between public releases.

= 0.1.53 =
* Setup wizard: campaign title and description can now be entered inline on the last wizard step instead of being redirected to the campaign editor

= 0.1.34–0.1.52 =
* Internal builds: incremental bug fixes, performance improvements, and refactoring between public releases.

= 0.1.32 =
* Added new translations
* Bugfix in donors meta boxes
* Bugfix in donor link
* Added sorting to backend tables (donors, donations, fundraisers)
* Correct currency according to settings

= 0.1.31 =
* Added External Services section to readme.txt
* Removed admin footer "Powered by Trybes"
* Excluded package.json, package-lock.json, webpack.config.js from build
* Filled in changelog for all versions 0.1.0–0.1.30
* Created uninstall.php with full data cleanup

= 0.1.30 =
* Added GA4 auto-tracking integration
* Added default color display in color pickers
* Title and description fields now required when creating a fundraiser

= 0.1.28 =
* Fixed donation amount calculation bug
* Fixed dashboard and settings page rendering issues
* Improved donation form layout
* Cleaned up form field labels and depth indicators
* Removed infix/middle name fields from accounts and API

= 0.1.22 =
* Minor fixes and stability improvements

= 0.1.21 =
* Added appearance settings with color management
* Improved form styling

= 0.1.19 =
* Refactored admin pages using WP_List_Table
* Added WordPress block hierarchy filters
* Added fundraiser count column to ambassadors admin view
* Added screen options to admin list tables
* Added donor admin view with query optimisations
* Added fundraiser links in donation table
* Fixed automations stats display
* Added consent table with revoke-on-anonymise support
* Various label and UI improvements

= 0.1.17 =
* Minor fixes and improvements

= 0.1.16 =
* Improved integration with WordPress colour palette
* Admin alert notices no longer render inside page header

= 0.1.15 =
* Added GDPR consent module with consent tracking and donor anonymization
* Refactored donor data to a single PII source
* Fixed activity feed block

= 0.1.14 =
* Fixed template path case-sensitivity issue (Linux server compatibility)
* Added test payment support for PSP connectors
* Pipeline and build system cleanup

= 0.1.10 =
* WordPress plugin directory compliance fixes

= 0.1.4–0.1.9 =
* Build pipeline setup and testing

= 0.1.3 =
* Added Stripe PSP connector
* Added frontend countdown and activity feed blocks
* Added consent automation module
* Added tracking module with GA4 provider
* Improved setup wizard
* Added campaign info block with character limit

= 0.1.2 =
* Added nested/team fundraisers
* Added custom form fields with JavaScript support
* Added fundraiser statistics blocks
* Added PSP connection testing
* Connected donation form to PSP settings
* Improved campaign and fundraiser helpers

= 0.1.1 =
* Added Mollie and PayPal payment connectors
* Added fundraiser end date and auto-close
* Added admin dashboard with charts
* Added automations module
* Added Dutch and German translations

= 0.1.0 =
* Initial release

== Upgrade Notice ==

= 0.1.69 =
No breaking changes. Fixes fatal error on admin pages introduced in 0.1.68.

= 0.1.68 =
No breaking changes. Fixes empty consent_text on existing installs — migration runs automatically on first admin page load.

= 0.1.67 =
No breaking changes. Consent Records admin table now shows the exact consent text at the time of giving consent.

= 0.1.66 =
Requires WordPress 6.7 and PHP 8.2. Update your server environment before upgrading if you are on an older version.
