=== Evenzo – Event Tickets, Calendar and Check-in for WooCommerce ===
Contributors: themology
Tags: event tickets, events, event registration, event calendar, qr code
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Sell event tickets with WooCommerce. Add an event calendar, take registrations, sell reserved seats, and check guests in with QR codes.

== Description ==

Evenzo lets you sell event tickets from your WooCommerce store. Create an event, turn a product into a ticket, and your customers buy it through the checkout they already know. Every sale is a regular WooCommerce order, so any payment gateway you use works for tickets too.

It covers the whole event day as well. Attendees get a ticket with a QR code, you scan it at the door from any phone or laptop, and the attendee list updates as people check in.

Use it for workshops, conferences, meetups, concerts, classes, webinars, and any event where you take registrations or sell seats. Events show on an event calendar, in blocks, or through shortcodes, and each event page includes Schema.org markup so search engines can read the date and venue.

= How Ticket Sales Work =

Create a WooCommerce product and mark it as an event ticket. The plugin adds a new tab in the product editor where you link the product to your event and configure ticket-specific settings like sales dates, minimum and maximum quantities, and attendee information fields. When customers purchase the product, the plugin automatically creates attendee records and generates unique ticket codes with QR codes.

= Core Features =

**Event Management**

* Single events, recurring events, and multi-day conferences.
* Event categories for organization.
* Event status tracking (scheduled, postponed, cancelled, sold out).
* In-person, virtual, and hybrid event types.
* Registration deadlines and capacity limits.

**Ticket Sales**

* Turn any WooCommerce product into an event ticket.
* Works with simple and variable products.
* Set minimum and maximum tickets per order.
* Configure sales start and end dates.
* Collect attendee name and email at checkout.
* Group tickets with multiple persons per ticket.
* Book tickets for a customer from the admin, with seats, recurring dates, paid or complimentary, and the ticket email on or off. Each booking is a regular WooCommerce order.

**Attendee Management**

* Automatic attendee creation from completed orders.
* Unique ticket codes for each attendee.
* Attendee contact details stored with each record.
* Search and filter attendees by event, status, name, email, or ticket code.
* Export attendee lists to CSV, with custom attendee fields.
* Edit an attendee's details, move them to another date of a series or another seat, and email their ticket again.
* Attendee fields on the classic and block checkouts.
* Buyers edit attendee details from My Account or the ticket email.

**Check-in System**

* QR code scanning from any device with a camera.
* Manual ticket code entry.
* Check-in statistics per event.
* Check-in and check-out tracking.
* Attendee search at the door.

**Printable Tickets**

* Printable event tickets with QR codes, saved as PDF from the browser.
* Event details, venue information, seat, and attendee data.
* Print from the My Account page or the attendee admin.

**Calendar and Display**

* Month view and list view calendars.
* AJAX navigation without page reloads.
* Category filtering.
* Event archive page.
* Single event pages with full details.

**Recurring Events**

* Daily, weekly, monthly, and yearly patterns.
* Custom intervals (every 2 weeks, every 3 months).
* End by date or number of occurrences.
* Edit or delete individual occurrences.

**Email Notifications**

* Registration confirmation emails.
* Ticket delivery with QR codes.
* Event reminder emails (configurable days before).
* Admin notifications for new registrations.

**Custom Event Attributes**

* Add custom key-value details to any event (dress code, age limit, parking, etc.).
* Repeatable fields in the event editor.
* Displayed on event pages in a clean grid layout.

**Venue and Organizer Profiles**

* Save venue details for reuse across events.
* Address and contact information.
* Organizer profiles with contact and social links.
* Google Maps integration for venue locations.

**Speaker Management**

* Speaker profiles with photos and bios.
* Social media links.
* Assign speakers to events.

**Waitlist**

* Waitlist sign-up form when a ticket product is out of stock.
* Notify waiting customers by email when stock is back, by hand or automatically.
* Configurable offer expiration time per product.

**Dynamic Pricing**

* Early bird percentage discount until a date.
* Last-minute percentage discount from a date.
* Quantity tier discounts.
* Role-based discounts for members.

**Seating Charts**

* Define seating per venue: named sections, number of rows, seats per row.
* Optional price adjustment per section (added to the ticket price).
* Customers pick their exact seat on the event page or ticket product page.
* Seats are held while customers check out, sold seats are blocked, and seat numbers print on tickets.

**Import and Export**

* Export events to CSV.
* Import events from CSV with field mapping.
* Export to iCal/ICS for calendar apps.
* Import from ICS files.
* Import from The Events Calendar and Event Tickets Plus: events, venues, organizers, categories, WooCommerce ticket products and attendees, with a dry run and undo.
* Calendar feed URL for subscriptions.
* Add to Calendar button (Google, Outlook, Yahoo, Apple).

**Blocks**

* Event Calendar block with month and list views.
* Events List block with grid or list layout.
* Upcoming Events block for sidebars.
* Event Card block for embedding events in posts.
* Event Countdown block with live timer.

**Shortcodes**

* `[emwc_calendar]` for calendar display.
* `[emwc_events]` for event lists and grids.
* `[emwc_upcoming]` for upcoming events.
* `[emwc_event]` for a single event card.
* `[emwc_venue_map]` for a venue map.

**Widgets**

* Upcoming Events widget.
* Mini Calendar widget.
* Event Categories widget.

**SEO and Structured Data**

* Schema.org Event JSON-LD markup on event pages.
* Rich snippets for Google search results.
* RSS feed for events at `/feed/emwc-events/`.
* Configurable under Events > Settings > Display.

**Privacy and GDPR**

* WordPress Privacy API integration.
* Personal data exporter for attendee records.
* Personal data eraser (anonymization) for attendee records.
* Suggested privacy policy text.
* Data retention period shown in the suggested policy text.

**Accessibility**

* Skip-to-content links on event pages.
* ARIA landmarks and labels for calendar and event content.
* Keyboard-navigable calendar with live region updates.
* Focus-visible outlines for keyboard users.
* Screen reader text for navigation controls.

**Developer Features**

* REST API for events, venues, organizers, and attendees.
* Webhooks for event, attendee, and check-in triggers (managed through the REST API).
* Template files that can be overridden in themes.
* Hooks and filters throughout the plugin.
* WordPress coding standards.
* Per-event timezone support with timezone display on frontend.

= My Account Integration =

Customers can view their tickets from their WooCommerce My Account page. Each ticket shows the event details, QR code, and a print button. Orders with attendees still editable show an Edit attendee details button.

== Installation ==

1. Upload the plugin files to `/wp-content/plugins/evenzo-events-manager` or install through the WordPress plugin directory.
2. Activate the plugin.
3. Make sure WooCommerce is installed and active.
4. Go to Events in your admin menu to create your first event.
5. Create a WooCommerce product, enable the "Event Ticket" option, and link it to your event.

= Requirements =

* WordPress 6.0 or newer
* WooCommerce 8.0 or newer
* PHP 7.4 or newer

== Frequently Asked Questions ==

= Does this plugin need WooCommerce? =

Yes. WooCommerce handles all payment processing, which lets you accept payments through any gateway WooCommerce supports.

= How do I sell tickets for an event? =

Create your event under Events > All Events > Add New Event and save it. In the event's Event Tickets box, click + Add New Ticket. The new product opens with Event Ticket checked and your event already selected, so you only need to add a name and price, then publish.

You can also start from Products > Add New. Check Event Ticket, open the Event Ticket tab, and pick your event from the Event dropdown before you publish.

For a recurring event, link the ticket to the main event of the series. One product then sells every date, and customers pick the date on the event page.

= Why doesn't my ticket show on the event? =

The ticket is not linked to an event yet. Checking Event Ticket marks the product as a ticket, and the Event dropdown in the Event Ticket tab links it to an event. Open the product, go to the Event Ticket tab, select the event, and click Update. Evenzo also shows a warning on any ticket product that has no event.

= Can I book tickets for a customer from the admin? =

Yes, from Events > Add Booking or the Book tickets link on an event in Events > All Events. Each booking is a regular WooCommerce order, paid or complimentary, so tickets, emails, stock and reports work as they do for an online order. Seats and capacity are checked before anything is booked, and booking over capacity needs a checkbox you tick on purpose.

= Can customers pick their own seats? =

Yes. Set up sections, rows, and seats on the venue, and add a price change per section if you want. Customers pick their seat on the event page, the seat is held while they check out, and the seat number prints on the ticket.

= Can I check in attendees from my phone? =

Yes. Open Events > Check-in on any device with a camera and scan the QR code on the ticket. You can also type the ticket code or search by name or email.

= Can I use variable products for different ticket types? =

Yes. Create a variable product with different variations for each ticket type (General Admission, VIP, etc.). Each variation can have its own price and settings.

= How does attendee information collection work? =

Turn on "Collect attendee info" in the product's Event Ticket tab. The checkout then asks for each attendee's first name, last name, and email, and the data is saved with each attendee record. Any rows you add to the ticket's Attendee fields table are asked too, on both the classic and block checkouts, and a required answer must be filled in before the order can be placed. See "Can buyers change attendee details after checkout?" for fixing a mistake later.

= Can I create recurring events? =

Yes. When creating an event, set a Repeat Event pattern. The plugin generates individual occurrences that you can manage separately.

= Can I switch from The Events Calendar? =

Yes. Go to Events > Import > The Events Calendar. Run the dry run first. It changes nothing and reports what will be created, skipped and flagged. The import then copies events, venues, organizers, categories and featured images into Evenzo. Event Tickets Plus WooCommerce ticket products are linked to the new events, and attendees of paid orders come across with their ticket codes and check-ins. Nothing in The Events Calendar changes, and Undo removes what the import made.

A few things don't import. RSVP and Tickets Commerce tickets and attendees are skipped because they have no WooCommerce order, and the report lists them. Event tags are listed in the report, not imported. Recurring events from Events Calendar Pro import as one event per date. The Event Tickets Plus part was tested with sample data, so check the dry run report before you import. The switching guide in the documentation has the full steps.

= How do PDF tickets work? =

After purchase, customers can view and print their tickets from the My Account page. Each ticket includes the event details, attendee information, and a QR code for check-in.

= How does check-in work? =

Go to Events > Check-in in your admin. Select your event and use the camera scanner to scan QR codes, type a ticket code, or search for attendees by name or email. The system tracks who has checked in and when.

= Does it work with WooCommerce block checkout? =

Yes. Tickets can be bought through both the classic checkout and the block checkout. When "Collect attendee info" is on, the block checkout asks each attendee's name, email and Attendee fields, like the classic checkout.

= Do Apple Pay and Google Pay buttons work with tickets? =

Yes, for tickets with no required Attendee fields. Express pay buttons on the product and cart pages skip the checkout form, so each attendee gets the buyer's name and email, as in 1.0.2. For tickets with a required Attendee field, Evenzo hides the WooPayments and Stripe express pay buttons, so buyers go through the checkout and answer the fields there. If another payment plugin's express button still places such an order, it fails with a message asking for the attendee details.

= Can I export custom attendee fields? =

Yes. The attendees CSV export adds one column for each custom attendee field, using the field's current label. If you rename a field, past answers still export, under the new label. If you remove a field, attendees who already answered it still export that answer.

= Can buyers change attendee details after checkout? =

Yes. An Edit attendee details button appears on the order in **My Account > Orders**, and **My Account > My Tickets** shows one line per order with the button above the tickets list. The buyer's order emails and their own ticket email carry the link when the order has a ticket with "Collect attendee info" on. Guests open it from the email link; account holders can also log in and use My Account. Only the buyer's own ticket email carries the link, not the copies sent to other attendees. The page asks a ticket's Attendee fields only when "Collect attendee info" is on for that ticket, the same as the checkout. Details can be changed until the event starts or the attendee is checked in.

= Can I show events without selling tickets? =

Yes. You can create events without linking any products. They will display on your calendar and event pages without a purchase option.

= Do QR codes in ticket emails need anything on my server? =

By default the QR images in tickets and emails are made on your own site. If your site is private, for example behind a password, a maintenance mode, or a "members only" plugin, email recipients can't load them. Set QR Code Images to QR Server API under Events > Settings > PDF Tickets for those sites.

= Where can I find documentation? =

Documentation is available at [Themology Documentation](https://themology.com/docs/event-tickets-for-woocommerce/).

= Where can I get support? =

For support questions and feature requests, visit [Themology Support](https://themology.com/support/).

== Screenshots ==

1. Event creation screen with date and time settings.
2. Ticket product configuration.
3. Attendee management dashboard.
4. QR code check-in interface.
5. Calendar month view.
6. Single event page.
7. PDF ticket example.
8. Seating chart setup on the venue edit screen.
9. Recurring event settings.
10. Gutenberg blocks in editor.
11. Add New Venue screen.

== Changelog ==

= 1.1.0 =
* Added admin bookings. Book tickets for a customer from Events > Add Booking, with seats, recurring dates, paid or complimentary, and the ticket email on or off. Each booking is a regular WooCommerce order
* Added attendee editing. Change an attendee's details, move them to another date of a series or another seat, and email their ticket again
* Added an Also email each attendee their own ticket setting on the Emails settings tab. It's off by default, so the buyer keeps getting every ticket
* Changed Resend Ticket Email on an attendee to send only that attendee's ticket, to that attendee's email. The order screen still resends the whole order to the buyer
* Added recurring event tickets. Link one ticket product to a recurring event and customers pick the date. Capacity, seats, check-in, emails and My Account follow the chosen date
* Added dates to the event picker on the check-in screen, so the dates of a recurring event can be told apart
* Added the waitlist for recurring event tickets. Customers join the list for a sold-out date and hear when a spot opens on that date.
* Fixed Generate event tickets on an order creating duplicate attendees
* Changed tickets to keep the event they were bought for, even if the product is later linked to another event
* Changed ticket products linked to a recurring event to stop using product stock and the product's own Sales End date, since each date has its own capacity and sells until it starts. Updating from 1.0.2 fixes products and variations that already have them, and a notice lists the products whose Sales End date was removed
* Added event_start and series_id to attendees in the REST API and webhooks, and a series filter to the attendees endpoint
* Added attendee fields to the classic and block checkouts. The fields you add in a ticket's Attendee fields table are now asked for each attendee at checkout and saved with the ticket, and the order can't be placed while a required answer is missing
* Express pay buttons, such as Apple Pay and Google Pay, keep working for tickets with no required Attendee fields, and attendees get the buyer's name and email. For tickets with a required Attendee field, the WooPayments and Stripe express pay buttons are hidden, so buyers answer the fields at checkout
* Added an Edit attendee details page. Buyers open it from My Account or the link in their ticket email to fix an attendee's name, email or answers until the event starts or the ticket is checked in. The email links and the Attendee fields on the page appear only for tickets with "Collect attendee info" on
* Added custom attendee fields to admin bookings and to the attendee edit screen
* WooCommerce's personal data export for an order now lists each attendee's name, email and answers kept on the order, and removing an order's personal data removes them
* Improved the attendees CSV export. It now follows every filter on the Attendees screen and includes all pages, with a column for each custom attendee field, the seat, ticket type, price paid, order status, buyer, check-in time, event time zone and booking source
* Added dates to the event filter and Event column on the Attendees screen, plus a series (all dates) filter and a check-in filter
* The attendees CSV opens correctly in Excel and can't run formulas from attendee answers
* Fixed saving a published recurring event deleting its dates and creating many duplicate events. Dates now keep their IDs, dates with tickets are never removed, and a notice offers to move duplicates left by earlier versions to the trash
* Improved recurring events: a date you edit on its own keeps those edits when you update the main event, and scheduled recurring events get their dates when they publish
* Added a QR Code Images setting. QR codes are now made on your own site by default, so ticket codes are not sent to an outside service. The QR Server API is still available as an option
* Added a Seat Blocking box on the event screen. Click seats to block them for that event, and blocked seats can't be picked or bought
* Fixed a seat being sold twice when a customer's seat hold expired while the ticket was still in their cart. Checkout now checks every seat again
* Added a warning on the event screen when ticket sales are closed before the event starts, for example because the registration deadline has passed, with what to change to reopen sales
* Improved the Event Settings box layout. Event Status and Repeat Event moved to the left column, so both columns are about the same height
* Fixed event and speaker pages on block themes such as Twenty Twenty-Five showing a plain header without the theme's header, menu and footer
* Fixed trashed orders keeping their tickets active and their seats taken. Restoring the order brings the tickets back and notes a date that is now over capacity
* Fixed trashing a paid order not returning its stock, so single-event places and the waitlist never heard about them. The stock of every item in the order comes back, as when cancelling
* Fixed the "From" name and address on the Emails settings tab having no effect. They now apply to Evenzo's own emails only, and WooCommerce's emails keep their sender. The tab's email on/off and reminder timing settings were removed, since WooCommerce > Settings > Emails already controls them
* Seats you blocked go back to blocked when an admin booking on them is cancelled
* Added an importer for The Events Calendar and Event Tickets Plus: events, venues, organizers, categories, WooCommerce ticket products and attendees, with a dry run and undo
* Fixed private and pending events missing from the ticket's Event list
* Fixed event lists, the calendar, blocks, shortcodes, the RSS and iCal feeds, and the REST API using the UTC date as today. Near midnight they now follow your site's date, so today's events stay listed and yesterday's drop off
* Fixed the Live Now and Upcoming badges and the event countdown being off by the site's UTC offset. They now read each event's time in its own time zone
* Fixed event reminder emails going out a day early or late near midnight, and reaching only one attendee per event
* Fixed early bird and last minute prices starting and ending off by the site's UTC offset
* Fixed waitlist offers expiring early or late by the site's UTC offset
* Fixed a "translation loading was triggered too early" notice for WooCommerce on sites with debugging on
* Fixed uninstalling deleting every event and attendee after the Advanced settings were saved with Delete data on uninstall off
* Uninstalling with Delete data on now also removes the events, seating and webhook data, and always clears the plugin's scheduled tasks

= 1.0.2 =
* Fixed the + Add New Ticket button on the event screen not linking the new ticket to that event. The Event Ticket box is now checked and the event is selected for you
* Added a warning on ticket products that are not linked to an event, since those tickets do not show on any event

= 1.0.1 =
* Tested with WordPress 7.1 and WooCommerce 11.0.1
* Seats are now held for 15 minutes as soon as a customer picks them, and a seat already held or sold by someone else is rejected at add to cart
* Seats stay held for unpaid orders until the order is paid or cancelled
* Fixed seat records never being created, which also stopped seat confirmation on paid orders
* Fixed section price adjustments (Price +/-) not being added to the ticket price in the cart
* Fixed quantity discounts not changing the price in the cart
* Fixed waitlist and dynamic pricing fields never showing on ticket products
* Fixed venue and organizer not showing in shortcodes, calendar, blocks, and the REST API
* Fixed the Waitlist admin page missing from the Events menu
* Fixed attendee bulk actions (Check In, Check Out, Cancel Tickets, Delete) doing nothing
* Fixed the Print Ticket button in the attendee admin
* Fixed ticket code prefix and length settings being ignored
* Fixed speaker profile and archive not listing the speaker's events
* Fixed the Regenerate Instances button for recurring events
* Fixed a PHP deprecation notice in the admin new registration email
* Fixed REST check-in requests failing to write the check-in log
* Fixed duplicate webhook deliveries for events saved through the REST API
* Removed the Refunded attendee filter, refunds set tickets to Cancelled
* Clarified seating chart feature description to match what the plugin ships

= 1.0.0 =
* Initial release (review improvements included)
* Moved inline styles and scripts to enqueued CSS/JS files
* Added wp_strip_all_tags() sanitization for PDF ticket CSS output
* Added sanitize_text_field() before json_decode() for seat selection data
* Replaced manual JSON-LD echo with wp_print_inline_script_tag()
* Used $wpdb->prepare() for all database queries
* Replaced $table variable interpolation with $wpdb->prefix in queries
* Added unminified source for html5-qrcode and updated Chart.js to v4.5.1
* Documented QR Server API Terms of Service and webhooks as external services
* Fixed Plugin URI and documentation URLs
* Translated hardcoded strings for full i18n compliance
* Removed ABSPATH define from PHPStan bootstrap file
* Event management with single, recurring, and multi-day support
* WooCommerce ticket integration with simple and variable products
* Attendee tracking and management with custom fields
* QR code check-in system with web-based scanner
* PDF ticket generation and download
* Calendar views (month, list) with AJAX navigation
* Venue, organizer, and speaker management
* Google Maps integration for venues
* Email notifications (confirmation, reminder, updates)
* Waitlist system with auto-notification
* Dynamic pricing (early bird, last-minute, quantity, role-based)
* Seating charts (sections, rows, seats) with visual seat selection
* iCal/ICS import and export
* CSV import and export for events
* REST API for events, venues, organizers, attendees
* Webhooks for automation
* 5 Gutenberg blocks
* 5 shortcodes
* 3 widgets
* My Account integration for ticket viewing
* Schema.org Event structured data (JSON-LD) for SEO
* RSS feed for events
* Per-event timezone support with frontend display
* Custom event attributes (repeatable key-value pairs)
* WordPress Privacy API integration (GDPR exporter, eraser, policy text)
* Accessibility improvements (ARIA landmarks, skip links, keyboard navigation)

== Upgrade Notice ==

= 1.1.0 =
Adds admin bookings, attendee editing, recurring event tickets, attendee fields at checkout, seat blocking and an importer for The Events Calendar. Fixes dates near midnight on sites ahead of or behind UTC.

= 1.0.2 =
Links new tickets to their event from the event screen.

== External Services ==

This plugin uses external services as described below.

= QR Server API =

By default QR code images are made on your own site and nothing is sent to this service. The plugin only requests QR code images from the QR Server API when "QR Code Images" is set to "QR Server API" under Events > Settings > PDF Tickets, or when the server has no GD image support.

Data sent: The text encoded in the QR image, which is the ticket code or a check-in link on your site that contains the ticket code. No names, emails, or other personal information are sent.

When it happens: Only in the cases above, when a ticket, ticket email, or My Account ticket with a QR code is shown.

Provider: Foundata GmbH (Germany)
Terms of Service: [goqr.me/de/rechtliches](https://goqr.me/de/rechtliches/)
Privacy Policy: [goqr.me/de/rechtliches/datenschutz-qrserver.html](https://goqr.me/de/rechtliches/datenschutz-qrserver.html)

The API is free and does not require registration.

= Webhooks (User-configured) =

If the site admin registers webhook URLs through the plugin's REST API, the plugin sends HTTP POST requests to those user-specified endpoints when events are created, updated, or deleted, when attendees are created or updated, or when attendees are checked in or out.

Data sent: Depending on the webhook topic, the plugin sends event data, attendee data, or registration data to the configured URL. The site admin controls which URLs receive data and which topics trigger notifications.

When it happens: Only when a site admin has explicitly registered webhook URLs through the REST API. No data is sent to external servers unless the admin configures this feature.

Provider: Determined by the site admin. The plugin does not send data to any predefined third-party service through webhooks.

= Google Maps Platform =

If the site admin enables the Google Maps integration and provides an API key in the plugin settings, the plugin loads the Google Maps JavaScript API to display venue maps on event pages and for geocoding venue addresses.

Data sent: The Google Maps API key and venue address are sent to Google servers. No personal visitor information is transmitted by the plugin.

When it happens: Only when a site admin has explicitly entered a Google Maps API key under Events > Settings > Google Maps, and a visitor views an event page with a mapped venue.

Provider: Google LLC
Terms of Service: [cloud.google.com/maps-platform/terms](https://cloud.google.com/maps-platform/terms)
Privacy Policy: [policies.google.com/privacy](https://policies.google.com/privacy)

== Third-party libraries ==

* QR Code Generator for PHP by Kazuhiko Arase, MIT license: https://github.com/kazuhikoarase/qrcode-generator (bundled in includes/lib/qrcode with small changes listed in its file header)
* html5-qrcode, Apache 2.0 license: https://github.com/mebjas/html5-qrcode
* Chart.js, MIT license: https://github.com/chartjs/Chart.js
