=== sinnvoll Booking Flow ===
Contributors: rmiarka
Tags: booking, events, registration, rsvp, attendees
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.11.17
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Seminar and event booking forms for trainers, coaches, and education providers.

== Description ==

sinnvoll Booking Flow lets you add seminar and event booking forms to any WordPress page or post with a shortcode. Visitors register for your events, you manage attendees and bookings from the admin, and everyone gets automatic confirmation emails.

= Key features =

* **Booking widget** for any event via `[sinnvoll_bf_widget id="EVENT_ID"]`
* **Event lists** by IDs or timeframe via `[sinnvoll_bf_event_list]`
* **Multiple attendees per booking** with per-attendee details
* **Ticket capacity** and minimum-tickets handling per event
* **Configurable confirmation emails** with placeholders (booker, attendee, event, booking details) and multi-language templates
* **Admin management** of events, bookings and attendees, including resend of confirmation emails
* **CSV export** of bookings and attendees
* **GDPR tools**: data export and erasure integration with WordPress Privacy, plus optional automatic anonymisation of old records
* **Cancellation policy** and statutory right-of-withdrawal (revocation) form via shortcode
* **Spam protection** for booking submissions (keyword/domain filters, minimum submit time)
* **Custom frontend texts** in multiple languages

= Shortcodes =

* `[sinnvoll_bf_widget id="EVENT_ID" lang="de|en"]` — full booking widget for one event
* `[sinnvoll_bf_button id="EVENT_ID"]` — just the "book" button
* `[sinnvoll_bf_event_list timeframe="future|past|all"]` — list of events
* `[sinnvoll_bf_confirmation]` — booking confirmation messages on your success page
* `[sinnvoll_bf_revocation_form]` — statutory right-of-withdrawal form
* `[sinnvoll_bf_cancellation_policy]` — outputs your cancellation policy text

= More power with sinnvoll Booking Flow Pro =

Need more? [sinnvoll Booking Flow Pro](https://sinnvoll-fuehren.com/sinnvoll-booking-flow/) adds coupons, PDF certificates for attendees, waiting lists, multiple ticket types per event, bookable add-ons, bulk emails to attendees, a visual form editor, Excel export and calendar invitations. One-time purchase, 12 months of updates and support included.

== Installation ==

1. Upload the plugin files to `/wp-content/plugins/sinnvoll-booking-flow`, or install through the WordPress Plugins screen directly.
2. Activate the plugin through the "Plugins" screen in WordPress.
3. Go to **sinnvoll Booking Flow** in the admin menu to create your first event.
4. Add a booking widget to any page with `[sinnvoll_bf_widget id="EVENT_ID"]` (the event ID is shown on the event list).
5. Configure confirmation emails, sender details and texts under **sinnvoll Booking Flow → Settings**.

== Frequently Asked Questions ==

= How do I show a booking form on a page? =

Create an event in the admin, note its ID, then place `[sinnvoll_bf_widget id="EVENT_ID"]` on any page or post.

= Can visitors register more than one attendee? =

Yes. A single booking can contain multiple attendees, each with their own name and email.

= Does it send confirmation emails? =

Yes. Confirmation emails are sent automatically and are fully configurable, including placeholders and multiple languages.

= Does it help with GDPR? =

The plugin provides tools that support GDPR workflows: it integrates with WordPress' personal-data export and erasure tools and offers optional automatic anonymisation of old records. It does not make your site compliant on its own — compliance always depends on how you configure and operate your site, your legal texts, and your own processes.

= Does the plugin set any cookies? =

It sets one cookie, `sinnvoll_bf_cid`, only when a booking widget or revocation
form that needs a security token is rendered for a logged-out visitor. It stores
a random pseudonymous identifier — it contains no booking data and is not used
for tracking — and serves solely to tie the form's security nonce to the
visitor's browser, hardening the public booking form against cross-site request
forgery and automated abuse. It is designed to function as a strictly necessary
security cookie, but this plugin cannot make legal determinations for your site
— you are responsible for assessing your local consent and disclosure
requirements and listing the cookie in your cookie/privacy notice. The plugin
registers suggested text in WordPress' Privacy Policy editor (Settings →
Privacy) to help with this.

= In which format can I export bookings? =

Bookings and attendees can be exported as CSV, which opens in any spreadsheet application.

== Privacy ==

This plugin processes personal data as part of running bookings on your site.
All data stays in your WordPress database; the plugin makes no calls to
external services. What it stores:

* **Booking data** you collect through the form (names, email addresses and any
  fields you configure), for as long as you keep the bookings.
* **Consent log:** when a visitor submits a booking, the plugin records which
  consent checkboxes were accepted together with a timestamp, the visitor's IP
  address and browser user agent, as proof of consent. The optional data
  retention settings anonymise the IP address after the configured period.
* **Audit log:** administrative changes to bookings and attendees are recorded
  with the acting user, IP address and user agent, so changes remain traceable.
* **Rate limiting:** public booking submissions are counted per client IP using
  a short-lived, hashed counter (a transient). No raw IP is persisted for this
  purpose and no cookie is involved.
* **Security cookie:** see the FAQ above for the `sinnvoll_bf_cid` cookie.

The plugin integrates with WordPress' personal-data export and erasure tools
(Tools → Export/Erase Personal Data) and registers suggested wording in the
Privacy Policy editor (Settings → Privacy). Reviewing and publishing your
site's privacy notice remains your responsibility.

== Screenshots ==

1. The booking widget your visitors see — dates, price, remaining places and the booking form.
2. Manage all your events with status, capacity and bookings at a glance.
3. The attendee list of an event — who booked what, with CSV export.

== Changelog ==

= 1.11.17 =
* Fixed: The per-IP limit on booking submissions could count too few attempts when several arrived at the same moment, so it engaged later than configured. Attempts are now counted in a way that cannot lose one.

= 1.11.16 =
* Fixed: A leftover scheduled task from older versions kept running twice a day even though nothing used it any more; deactivating the plugin now removes it.

= 1.11.15 =
* Fixed: In the booking dialog the keyboard focus could land in the invisible spam-protection field instead of the first real field — typing immediately after opening could end up nowhere and get the booking flagged as spam.

= 1.11.14 =
* Fixed: On sold-out events with an active waiting list, the "Add attendee" button refused to add anyone ("Only 0 seats left") — the seats-left check now stands down in waiting-list mode, where the server accepts any number of attendees.

= 1.11.13 =
* Fixed: All plugin strings could appear in English on translated sites even though complete translations exist — the wp.org language pack is now loaded explicitly instead of relying on WordPress' just-in-time loading.

= 1.11.12 =
* Fixed: Required checkbox groups (e.g. attendance days) demanded ALL options to be ticked — the browser silently blocked guests who selected only some. At least one is now enough, with a clear browser message when none is selected.
* Improved: When a required field is empty, the booking error now names the field instead of showing a generic message.
* Improved: When the submitted form is older than the current form definition (stale page cache), guests are asked to reload the page instead of seeing a generic error.

= 1.11.11 =
* Changed: The bookings export now shows the option labels guests actually selected (e.g. "Freitag (ab 17:00 Uhr)") instead of raw stored values (friday) — for radio, select and checkbox-group fields, using each booking's form snapshot.
* Changed: The bookings export no longer includes the internal ticket-type ID column; the ticket name is already part of the attendee data.

= 1.11.10 =
* Fixed: The bookings export (CSV and Pro Excel) showed empty cells for all custom form fields — only the column headings appeared. Values from the booking form (e.g. radio selections, checkbox groups, consents) now export correctly.
* Changed: The bookings export no longer creates columns for form elements that never carry a value (HTML blocks, the submit button, the attendee controls).

= 1.11.9 =
* Fixed: Event tabs (e.g. Coupons in Pro) could show a stale list after creating or editing entries in a modal — tab content was served from a five-minute browser cache. Tabs now always load fresh on every activation.
* Compatibility: Tested with WordPress 7.1.

= 1.11.8 =
* New: Event cards show "Price from:" with the lowest ticket price when an event has multiple ticket types with different prices (translatable via the Texts screen).
* Changed: "Hide tax" on a ticket type now means final price — the booking costs exactly the displayed amount; no tax is calculated or stored for such tickets.
* Changed: The price summary in the booking form collapses to a single Total line when there is no tax to show (0% rate or final-price tickets); the full breakdown returns when a taxed ticket type is selected.
* Fixed: Hidden price-summary lines were still visible due to a CSS specificity conflict.

= 1.11.7 =
* Fixed: Status badges in the attendee and booking lists (and the CSV export) now show translated labels instead of the raw English status value.
* Fixed: The admin toolbar above attendee/booking lists no longer overlaps the table header when its controls wrap onto a second line.
* Fixed: Setting attendees to booked/cancelled/missed now shows a matching success notice instead of "Attendee moved to trash."; German trash notices now say "Papierkorb".

= 1.11.6 =
* New: Guest emails now follow the language the booking was made in. The booking form language is stored with each booking; confirmation and cancellation emails use it, falling back to the event language and then the site language. Events gained a Language setting (default: site language), and the widget renders in the event's language when the shortcode has no lang attribute. Admin notifications intentionally stay in the site language.

= 1.11.5 =
* Initial release on the WordPress plugin directory.
