Über dieses Plugin

IDF Event Tickets verbindet The Events Calendar (StellarWP) mit WooCommerce, um Tickets für Veranstaltungen zu verkaufen. Für jedes Event können verschiedene Ticket-Typen mit individueller Kapazität und Preisgestaltung angelegt werden. Nach Kaufabschluss erhalten Kunden eine E-Mail mit individuellen Ticket-Nummern und QR-Codes. Am Veranstaltungstag kann das Event-Personal über die Admin-Oberfläche, einen Frontend-Shortcode oder die REST API einchecken.

Features

  • Frontend-Buchungsblock: Shortcode [idf_event_tickets] rendert auf der Event-Seite einen vollständigen Buchungs-Block mit Tickettyp-Auswahl, Mengen-Stepper, Verfügbarkeitsanzeige und Add-to-Cart. Verkaufszeitraum und Event-Ende werden respektiert.
  • Ticket-Typen pro Event: Beliebig viele Typen (z. B. Standard, VIP, Early Bird) mit individuellen Preisen, Kapazitäten und Verkaufszeiträumen — direkt im Event-Editor von The Events Calendar.
  • WooCommerce-Integration: Automatische Produkt-Erstellung pro Tickettyp, Bestandssynchronisation und Bestellverarbeitung über den normalen Checkout. Beitragsbild des Events wird als Produktbild übernommen.
  • QR-Code-Tickets: Eindeutige Ticket-Nummern mit QR-Codes für schnelles Einchecken am Veranstaltungstag.
  • Check-in-System: Admin-Oberfläche, Frontend-Shortcode [idf_event_checkin] und REST API für flexibles Einchecken — mit Doppel-Check-in-Schutz und Undo.
  • E-Mail-Benachrichtigung: Separate Ticket-E-Mail mit allen Details und QR-Codes nach Kaufabschluss.
  • Order-Lifecycle-Sync: Bei Storno, Refund, Verschieben in den Papierkorb oder endgültigem Löschen einer Bestellung werden die zugehörigen Tickets automatisch storniert und die Plätze stehen sofort wieder zum Verkauf — auch bei HPOS.
  • Bidirektionale Lösch-Sync: Wird ein Tickettyp im Event-Editor entfernt, wird das verknüpfte WooCommerce-Produkt mit gelöscht — und umgekehrt. Beide Datenquellen bleiben synchron.
  • Direkt-URL-Schutz: Wer die Single-Product-URL eines Ticket-Produkts aufruft, wird per 301 zur Event-Seite umgeleitet — der Buchungsblock ist der einzige offizielle Verkaufsweg.
  • Wartungs-Funktion: Button „Bestände neu berechnen“ auf der Settings-Seite repariert verwaiste Tickets aus historischen Order-Löschungen — idempotent, mit Statistik-Ausgabe.
  • Admin-Dashboard: Übersicht aller Events mit Verkaufszahlen, Kapazität und Check-in-Quote.
  • REST API: Endpunkte für Ticket-Verifizierung, Check-in, Statistiken und Teilnehmerlisten.
  • Theme-Integration: Plugin liefert nur Layout-Klassen (BEM), keine eigene Typografie oder Farben — Block erbt komplett vom Theme.
  • Voraussetzungen: The Events Calendar (StellarWP) und WooCommerce müssen aktiv sein. IDF Home für automatische Updates empfohlen.
  • Uninstall: Optionale vollständige Datenlöschung über die Uninstall-Seite.

Changelog

v1.6.0 - 2026-07-29

Hinzugefügt

  • Neue Admin-Seite „DSGVO" (Event Tickets → DSGVO, Capability manage_options). Setzt die IDF-Plugin-Konvention um, nach der jedes Plugin offenlegt, welche personenbezogenen Daten es verarbeitet, und einen fertigen Textvorschlag für die Datenschutzerklärung des Betreibers mitliefert. Aufbau: - Tabelle aller verarbeiteten Daten mit Speicherort (konkrete Tabellennamen inkl. Präfix) und Zweck. - Ausdrückliche Aussage zur Übermittlung an Dritte - bei diesem Plugin: keine. - Kopierbarer Textvorschlag für die Datenschutzerklärung, mit Platzhaltern für alles, was der Betreiber selbst festlegen muss. - Abschnitt „Was Sie selbst festlegen müssen": Speicherdauer, die öffentliche Ticketprüfung und die noch fehlende Anbindung an die WordPress-Werkzeuge für Auskunft und Löschung.

v1.5.3 - 2026-07-29

Geändert

  • QR-Codes liegen den Mails jetzt als Anhang bei, statt nachgeladen zu werden. v1.5.2 hatte die Erzeugung lokalisiert, den Code aber weiterhin über eine Bild-URL eingebunden. Das hat zwei Nachteile, die ein Ticket empfindlich treffen: - Outlook und Gmail blockieren externe Bilder standardmäßig. Der Empfänger hätte seinen QR-Code erst nach einem Klick auf „Bilder anzeigen" gesehen. - Jedes Nachladen erzeugt einen Server-Log-Eintrag mit IP-Adresse und Öffnungszeitpunkt - technisch dasselbe Muster wie ein Zählpixel, auch wenn nicht so gemeint. - Der Code wird jetzt über phpmailer_init als eingebettetes Bild angehängt und im HTML per cid: referenziert. Kein externer Abruf, keine Bildblockierung, funktioniert offline. Der Hook wird nur für die Dauer des einen Versands registriert, damit fremde Mails keine Anhänge abbekommen. - Fehlt GD auf dem Server, wird weiterhin die Bild-URL genutzt - dann ist der Code wenigstens erreichbar.
  • esc_url() erlaubt cid: nicht von sich aus und hätte das Bild stillschweigend entfernt; das Protokoll wird beim Rendern der Ticket-Karte explizit freigegeben.

v1.5.2 - 2026-07-29

Behoben

  • QR-Codes wurden nirgends mehr angezeigt. Die Erzeugung lief seit jeher über die Google-Charts-Infographics-API (chart.googleapis.com). Google hat diesen Dienst abgeschaltet, er liefert nur noch HTTP 404 - betroffen waren damit alle QR-Codes gleichzeitig: in der Ticket-Mail, in der Erinnerungs-Mail und im Kundenkonto. Ohne lesbaren Code funktionierte auch der Check-in per Scan nicht mehr. - QR-Codes werden jetzt lokal erzeugt. Neue Klasse IDF_Event_Tickets_QR_Encoder (Byte-Mode, Versionen 1 bis 10, alle EC-Level, self-contained, ohne externe Abhängigkeit; übernommen aus idf-qr-codes mit plugin-eigenem Klassennamen, damit es keinen Redeclare-Konflikt gibt). - Kundenkonto: Inline-SVG - unabhängig von der GD-Bibliothek, ohne zweiten Request und in jeder Auflösung scharf. - E-Mails: Bild-URL auf der eigenen Domain (?idf_et_qr=<hash>), ausgeliefert als PNG. Bewusst kein eingebettetes Bild, weil Outlook und Gmail Data-URIs nicht zuverlässig darstellen. Fehlt GD auf dem Server, liefert der Endpunkt SVG aus.

Geändert

  • Der Ticket-Hash verlässt den Server nicht mehr. Bisher wurde er als Teil der Verifizierungs-URL an Google übertragen, sobald ein QR-Code gerendert wurde. Das entfällt vollständig - relevant für die Datenschutzerklärung, und Consent-Tools blockieren nichts mehr.

v1.5.1 - 2026-07-29

Behoben

  • Teilnehmer wurden mehrfach angelegt. on_order_completed() hing an woocommerce_order_status_processing und woocommerce_order_status_completed und legte bei jedem Aufruf blind neue Datensätze an. Folge: Jede Bestellung, die von „in Bearbeitung" auf „abgeschlossen" wechselte, erzeugte den Teilnehmer ein zweites Mal, erhöhte sold erneut und verschickte eine zweite Ticket-Mail. Jeder Storno-Reaktivierungs-Zyklus legte einen weiteren an. - Die Methode ist jetzt idempotent: Sie gleicht pro Bestellposition die bestellte Menge gegen die vorhandenen aktiven Tickets ab und tut nichts, wenn das Soll bereits gedeckt ist.
  • Storno und Reaktivierung erzeugen keine neuen Tickets mehr. Wird eine stornierte Bestellung wieder auf „in Bearbeitung" gesetzt, werden die zuvor stornierten Tickets derselben Bestellung reaktiviert - Ticketnummer und QR-Code bleiben damit gültig. Erst wenn nicht genug stornierte Tickets vorhanden sind, werden fehlende neu angelegt. Neue Action idf/event-tickets/attendee_reactivated.
  • Ticket-Mail wurde doppelt verschickt. send_ticket_email() hängt an denselben beiden Hooks. Ein Order-Meta-Flag _idf_ticket_email_sent verhindert den zweiten Versand; beim Storno wird es gelöst, damit eine Reaktivierung die Tickets erneut zustellt.
  • Verkauft-Zähler lief davon. sold wurde inkrementell geführt (+ quantity beim Anlegen, - released beim Storno) und driftete bei mehrfach feuernden Hooks. Neue Methode recalculate_sold() leitet den Wert aus der Zählung der aktiven Tickets ab - dieselbe Quelle, die auch compute_stock_for_ticket_type() nutzt. Aufgerufen bei Anlage und bei Freigabe.

Hinzugefügt

  • Wartungs-Funktion „Doppelte Teilnehmer bereinigen" unter Einstellungen → Wartung. Repariert Daten, die vor diesem Fix entstanden sind: gleicht je Bestellung und Tickettyp die bestellte Menge gegen die aktiven Datensätze ab und entfernt die überzähligen. Eingecheckte Tickets bleiben immer erhalten, ebenso die ältesten je Bestellung. Bestellungen ohne auflösbare Ticket-Position werden übersprungen. Idempotent. Neue Action idf/event-tickets/duplicate_attendees_cleaned.

v1.5.0 - 2026-07-29

Hinzugefügt

  • Neuer Bereich „Meine Events" im Kundenkonto. Eigener WooCommerce-Endpoint unter Mein Konto → Meine Events mit einer nach kommenden und vergangenen Terminen getrennten Liste aller gebuchten Veranstaltungen. Pro Event eine Detailansicht mit den eigenen Tickets (Ticketnummer, Status, QR-Code) und den freigegebenen Unterlagen. Damit ist die Ticket-Mail nicht mehr der einzige Weg zum eigenen Ticket. - Neue Klasse IDF_Event_Tickets_Account, Templates account-events.php und account-event-single.php, Stylesheet assets/account.css (nur Layout, der Look kommt vom Theme). - Neuer Filter idf/event-tickets/account_endpoint_slug zum Umbenennen des Endpoints.
  • Unterlagen pro Event. Neue Metabox „Unterlagen" im Event-Editor. Dateien landen in einem per .htaccess gesperrten Verzeichnis unterhalb von uploads und sind ausschließlich über einen PHP-Proxy abrufbar, der prüft, ob der Anfragende ein gültiges Ticket für genau dieses Event besitzt. Die Mediathek wird bewusst nicht verwendet, weil deren Dateien per Direkt-URL öffentlich sind. - Sichtbarkeit pro Dokument wählbar: sofort oder erst nach dem Event (Standard). - Neue Klasse IDF_Event_Tickets_Handouts, Template metabox-handouts.php, Post-Meta _idf_event_handouts. - Neue Actions idf/event-tickets/handout_added, _removed und _downloaded, neuer Filter idf/event-tickets/handout_allowed_mimes. - Wird ein Event endgültig gelöscht, werden seine Unterlagen mit entfernt.
  • Zuordnung Ticket zu Kundenkonto. Neue Spalte user_id auf der Attendees-Tabelle samt Index (Auto-Migration bei Bestandsinstallationen, gated über idf_event_tickets_db_version). Bei jeder Bestellung wird das Kundenkonto mitgeschrieben. - Nachträgliche Zuordnung: Legt jemand erst nach der Buchung ein Konto an, werden seine historischen Tickets über die Teilnehmer-E-Mail einmalig zugeordnet und dauerhaft gespeichert (user_register, sowie profile_update bei geänderter Adresse). Neue Action idf/event-tickets/attendees_claimed. - Backfill für Bestandsdaten: Läuft einmalig beim ersten Admin-Pageload nach dem Update und ist über den Button Ticket-Zuordnung neu aufbauen in Einstellungen → Wartung wiederholbar. Zuerst über das Kundenkonto der Bestellung, danach über die Teilnehmer-E-Mail. Idempotent. Neue Action idf/event-tickets/user_ids_backfilled. - Neue Methoden get_user_events(), get_user_attendees(), user_has_ticket_for_event(), claim_attendees_for_user() und idf_event_tickets_db_version0 im Ticket-Manager.

Geändert

  • Manuell angelegte Teilnehmer werden mit einem bestehenden Kundenkonto verknüpft. create_manual_attendee_order() prüft jetzt, ob zur Teilnehmer-E-Mail schon ein Konto existiert, und setzt es als Kunden der Bestellung. Bisher entstanden diese Bestellungen grundsätzlich ohne Kundenkonto, wodurch eingeladene Gäste ihre Tickets im Konto nicht sehen konnten.
  • Die Deinstallation entfernt zusätzlich das Unterlagen-Verzeichnis, die Post-Metas _idf_event_handouts und die Per-Event-Metas der Erinnerungs-Metabox.

Hinweis

  • Der .htaccess-Schutz des Unterlagen-Verzeichnisses wirkt nur unter Apache. Auf Nginx muss die Sperre zusätzlich in der Server-Konfiguration gesetzt werden.

v1.4.0 - 2026-06-09

Hinzugefügt

  • E-Mail-Vorschau im Browser. Auf der Seite Event Tickets → E-Mails öffnen zwei Buttons („Vorschau Ticket-Mail" / „Vorschau Erinnerungs-Mail") die fertig gerenderte Mail mit Beispieldaten (Beispiel-Teilnehmer + Beispiel-QR-Code) in einem neuen Tab - ohne echten Versand und ohne Datenbankzugriff. - Neue Methode IDF_Event_Tickets_Email::render_preview( $type ). - Ausgabe über einen capability- und nonce-geschützten idf_et_preview-Handler in IDF_Event_Tickets_Admin::handle_form_submissions(). Die Vorschau spiegelt den zuletzt gespeicherten Stand der Vorlagen-Optionen und -Texte.

v1.3.2 - 2026-06-09

Behoben

  • Logo in den E-Mails wurde beschnitten und nicht auf die eingestellte Größe skaliert. Das <img> hatte nur eine width, aber keine height - Clients wie Outlook skalierten das per full geladene Original nicht herunter, es lief über den 600px-Container und wurde durch dessen overflow:hidden (abgerundete Ecken) abgeschnitten. Jetzt werden die natürlichen Bildmaße ausgelesen, die proportionale Höhe zur Zielbreite berechnet und beide Maße explizit gesetzt (plus max-width:100%, kein Hochskalieren über die native Breite).

v1.3.1 - 2026-06-09

Behoben

  • Teilnehmer-hinzufügen-Tabelle war breiter als der Bildschirm. Die Eingabefelder nutzten feste WP-Breiten (regular-text = 25em) → bei 7 Spalten lief die Tabelle horizontal aus dem Container. Felder jetzt auf relative Breite (width:100%) umgestellt, Spaltenverhältnisse über ein <colgroup> mit table-layout:fixed fixiert. Die Tabelle passt sich jetzt der verfügbaren Breite an.

v1.3.0 - 2026-06-09

Hinzugefügt

  • Teilnehmerliste pro Event (neuer Menüpunkt Event Tickets → Teilnehmer). Zeigt alle gebuchten Tickets eines Events (alle Tickettypen) mit Ticketnummer, Tickettyp, Vor-/Nachname, E-Mail, Telefon, Adresse, Status und Bestell-Link. Erreichbar auch über den neuen Button „Teilnehmer" je Event-Zeile im Dashboard. - Manuelles Hinzufügen: Unter der Liste lassen sich beliebig viele Teilnehmer-Zeilen (Vorname, Name, E-Mail, Telefon, Straße, PLZ, Ort) erfassen. Jede Zeile wird als echte, abgeschlossene WooCommerce-Bestellung (Menge 1) gebucht - die bestehenden Completed-Hooks legen Ticket inkl. QR-Code an, verschicken die Ticket-Mail und buchen den Bestand ab. Preis pro Lauf wählbar: kostenlos (0 €) oder regulärer Ticketpreis. - Neue Methode IDF_Event_Tickets_WooCommerce_Integration::create_manual_attendee_order(). Setzt bewusst genau einen Status-Wechsel auf completed, damit die Attendee-Erzeugung nicht doppelt feuert. - Neue Action idf/event-tickets/manual_attendee_order_created.
  • Einzelverkauf pro Tickettyp (max. 1 Ticket pro Bestellung). Neue Checkbox „Einzelverkauf" in der Tickettyp-Metabox; sie wird auf das verknüpfte Woo-Produkt als sold_individually übertragen. Im Buchungsblock entfällt dann der Mengen-Stepper (Menge fix 1). Neue Spalte sold_individually in der Types-Tabelle (Auto-Migration bei Bestandsinstallationen, gated über idf_event_tickets_db_version).

Geändert

  • Ticket-Produkte werden jetzt immer virtuell angelegt (Create und Update) - keine Versandkosten, kein Versand-Tab. virtual und sold_individually werden bei jedem Event-Save nachgezogen (Event = Single Source of Truth).

v1.2.0 - 2026-06-04

Hinzugefügt

  • Editierbare E-Mail-Vorlage (analog idf-assessment). Neuer Menüpunkt Event Tickets → E-Mails mit zentral konfigurierbarem Layout (Logo, Header-Ausrichtung, Schriftfamilie), Farbpalette (Akzent, Hintergründe, Textfarbe, Button-Farbe/-Rundung), Absender (Name + Adresse) und freien Texten (Betreff, Header-Titel, Anrede, Fließtext, Fußzeile). - Die bisher hartcodierte Ticket-Bestätigungs-Mail wird jetzt aus dieser Vorlage gerendert; der Ticket-/QR-Block wird automatisch eingebettet. - Platzhalter für die Ticket-Mail: {{name}}, {{site_name}}, {{site_url}}. - Neue Methoden IDF_Event_Tickets_Email::get_template_options(), get_ticket_texts(), get_reminder_texts() und ein gemeinsamer render_template().
  • Erinnerungs-E-Mail (Followup). Erinnert Teilnehmer vor Veranstaltungsbeginn an ihre Teilnahme - wahlweise inkl. Ticketnummer und QR-Code. - Globaler Vorlauf (z. B. „2 Tage vor Beginn", Einheit Stunden/Tage) plus eigene Texte und optionaler CTA-Button zur Event-Seite. - Pro-Event-Override über die Metabox „Erinnerungs-E-Mail" im Event-Editor: Erinnerung global/aktiv/deaktiviert schalten und eigenen Vorlauf setzen. - Versand über stündlichen WP-Cron (idf_event_tickets_reminder_cron). Event-Startzeit kommt aus The Events Calendar (_EventStartDateUTC, Fallback _EventStartDate). - Neue Klasse IDF_Event_Tickets_Reminders mit run(), get_effective_settings(), get_event_start_ts(). - Neue Actions idf/event-tickets/reminder_sent und idf/event-tickets/reminders_processed.
  • Neue Attendees-Spalte reminder_sent_at (markiert versendete Erinnerungen, verhindert Doppelversand). Wird bei Bestandsinstallationen per admin_init-DB-Upgrade (gated über idf_event_tickets_db_version) nachgerüstet.

Geändert

  • send_ticket_email() nutzt jetzt Absender, Betreff und Texte aus den E-Mail-Einstellungen statt fester Vorgaben. Stornierte Attendees werden im Ticket-Block nicht mehr ausgegeben.
  • Aktivierung registriert den Erinnerungs-Cron und hält idf_event_tickets_db_version fest; Deaktivierung und Uninstall deregistrieren den Cron und räumen die neuen Optionen mit ab.

Hinweis

  • Die Erinnerung ist nach dem Update standardmäßig deaktiviert - erst unter „Event Tickets → E-Mails" aktivieren (und ggf. pro Event übersteuern).

v1.1.10 - 2026-05-06

Hinzugefügt

  • Cleanup historischer verwaister Attendees: v1.1.9 hat das Loch geschlossen, durch das Tickets nach Bestellung-Löschung blockiert blieben - repariert aber nur Bestellungen, die nach dem Update gelöscht wurden. Diese Version räumt jetzt auch alte Datenbestände auf. - Neue Methode IDF_Event_Tickets_WooCommerce_Integration::cleanup_orphan_attendees(). Geht über alle nicht-stornierten Attendees, prüft pro Order via wc_get_order (klassisch + HPOS), ob sie noch existiert. Verwaiste Orders → Attendees auf cancelled, sold aus aktiver Attendee-Zählung neu setzen, Woo-Produkt-Bestand neu rechnen. - Auto-Migration: läuft beim ersten Admin-Pageload nach dem Update einmal pro Site automatisch (admin_init-Hook, geschützt per idf_event_tickets_orphan_cleanup_done-Option mit Plugin-Version als Wert). Damit werden alle Customer-Sites beim nächsten WP-Admin-Aufruf sauber, ohne Eingriff. - Manueller Re-Run: Button „Bestände neu berechnen" auf der Settings-Seite (Capability idf_event_tickets_manage, Nonce-geschützt). Zeigt nach dem Lauf eine Statistik (geprüfte Bestellungen, gefundene Verwaiste, stornierte Tickets, neu berechnete Tickettypen). - Neue Action idf/event-tickets/orphan_attendees_cleaned mit Statistik-Array.
  • Wartungs-Sektion auf der Settings-Seite mit Erklärungstext, letzten Lauf-Stats und Button.

Geändert

  • cleanup_orphan_attendees() ist idempotent - beliebig oft aufrufbar, ein zweiter Lauf findet nichts mehr zu reparieren.
  • Uninstall räumt jetzt auch die neuen Optionen idf_event_tickets_orphan_cleanup_done und idf_event_tickets_orphan_cleanup_last_stats mit ab.

Hinweis

  • Wer das Plugin nach v1.1.10 noch einmal manuell triggern möchte (z. B. nach einer großen Order-Aufräum-Aktion in WooCommerce), kann den Button auf der Settings-Seite jederzeit klicken - das überschreibt die letzten Stats und korrigiert eventuelle neu entstandene Verwaisungen.

v1.1.9 - 2026-05-05

Behoben

  • Tickets kommen nach Bestellung-Löschung wieder in die Verfügbarkeit zurück. Bisher fingen wir nur woocommerce_order_status_cancelled/refunded ab - wer eine Bestellung in den Papierkorb verschob oder endgültig löschte, hinterließ verwaiste Attendees in der Plugin-DB, der sold-Counter blieb stehen und der Woo-Produkt-Bestand wurde nicht zurückgesetzt. Im Frontend zählten die Tickets der gelöschten Order weiter als „verkauft".
  • Auch beim normalen Stornieren wurde der sold-Counter bisher nicht dekrementiert - compute_stock_for_ticket_type() hat das zwar abgefangen, aber der Stats-Wert in der Tickettyp-Row lief immer weiter hoch. Wird im neuen Pfad mitkorrigiert.

Hinzugefügt

  • Neue Hooks in class-woo-integration.php: - wp_trash_post (klassischer Order-Storage, Trash) - before_delete_post mit Post-Type-Branch für shop_order (klassischer Order-Storage, endgültiges Löschen) - woocommerce_trash_order (HPOS, Trash) - woocommerce_before_delete_order (HPOS, endgültiges Löschen)
  • Zentraler Helper release_attendees_for_order( $order_id ): - Setzt aktive Attendees der Order (Status valid/checked_in) auf cancelled. - Dekrementiert den sold-Counter pro betroffenem Tickettyp. - Berechnet den Lagerbestand neu (compute_stock_for_ticket_type) und schreibt ihn ins Woo-Produkt zurück. - Idempotent (zweiter Aufruf mit derselben Order-ID ist no-op) und re-entry-geschützt für parallele Hook-Pfade innerhalb einer Request.
  • Neue Action idf/event-tickets/order_attendees_released ($order_id, $released_per_type).

Geändert

  • on_order_cancelled() nutzt jetzt den zentralen release_attendees_for_order-Helper. Damit haben Storno, Refund, Trash und endgültiges Löschen identisches Verhalten.

Hinweis

  • Wird eine Bestellung aus dem Papierkorb wiederhergestellt, sind die ursprünglichen Attendees auf cancelled und werden vom Status-Wechsel auf processing/completed als neue Tickets neu angelegt - der Kunde behält also die Tickets, aber mit neuen Ticket-Nummern. Wer eine Order wirklich versehentlich getrasht hat, sollte sie sofort wiederherstellen, bevor neue Verkäufe die Plätze auffüllen.

v1.1.8 - 2026-05-01

Behoben

  • Kritischer Hotfix - class-frontend.php Base64-Korruption: In v1.1.7 wurde includes/class-frontend.php fälschlicherweise als Base64-Text auf dem Dateisystem gespeichert, was beim Plugin-Laden zu einem PHP Fatal Error führte. Die Datei wurde wiederhergestellt - alle v1.1.7-Features (Kostenfrei-Anzeige, Headline „Tickets für dieses Event") sind weiterhin enthalten.

v1.1.7 - 2026-04-30

Geändert

  • Preisanzeige bei kostenlosen Tickets: Tickettypen mit Preis 0 € erscheinen im Buchungsblock jetzt mit dem Hinweis „Kostenfrei" statt „0,00 €". Greift sowohl in der Mehr-Typen-Auswahl als auch im Single-Type-Render.
  • Default-Headline umbenannt: „Tickets für diesen Termin" → „Tickets für dieses Event". Wer den Shortcode mit eigenem heading="…"-Attribut nutzt, ist nicht betroffen.
  • Einzelverkauf ohne Label: Bei sold_individually wird kein Label „Anzahl: 1 (Einzelverkauf)" mehr angezeigt - nur noch ein Hidden-Input für den Form-Submit, kein sichtbarer Text.

Abhängigkeiten

  • IDF Home Mindestversion auf v2.0.0 angehoben (Dependency-Checker aktualisiert).

v1.1.6 - 2026-04-30

Hinzugefügt

  • Direkt-URL-Redirect: Wer die Single-Product-URL eines Ticket-Produkts aufruft (z. B. /produkt/event-titel-vip/), wird per 301 zur Event-Seite umgeleitet. Damit läuft die Buchung immer über den [idf_event_tickets]-Block, nicht über die rohe Woo-Produktseite. Filter idf/event-tickets/product_redirect_url erlaubt Custom-Targets.

Geändert

  • Bei sold_individually wird der Mengen-Stepper komplett ersetzt durch ein hidden quantity=1-Field plus den Hinweis „Anzahl: 1 (Einzelverkauf)". Bisher hatte ich nur readonly am Input und disabled am Plus-Button gesetzt - das ist Browser-Quirks ausgesetzt (Number-Input-Spinner ignoriert readonly in manchen Browsern, disabled kann durch Theme-CSS überklickbar werden). Mit dem neuen Markup gibt's keinen Weg mehr, die Menge zu ändern.

v1.1.5 - 2026-04-30

Behoben

  • Frisch angelegter Tickettyp im Event-Editor erzeugte kein WooCommerce-Produkt (latent seit v1.0): sync_woo_products lief auf save_post_tribe_events-Priorität 10, save_ticket_metabox auf Priorität 20. Der Sync sah die Tickettyp-Liste bevor save_ticket_metabox die neue Zeile in die DB geschrieben hatte → leerer Loop → kein Produkt. Beim zweiten Speichern hätte es geklappt - beim ersten nicht. Fix: Priorität von sync_woo_products auf 30 setzen, damit der Sync nach save_ticket_metabox läuft.

v1.1.4 - 2026-04-30

Hinzugefügt

  • Bidirektionale Lösch-Sync zwischen Tickettyp und Woo-Produkt: - Wird ein Tickettyp im Event-Editor entfernt (Metabox-Zeile gelöscht), wird das verknüpfte WooCommerce-Produkt automatisch endgültig gelöscht. - Wird ein WooCommerce-Produkt mit _idf_ticket_type_id-Verweis endgültig gelöscht, wird der zugehörige Tickettyp aus der Plugin-DB entfernt und alle aktiven Attendees auf cancelled gesetzt. - Greift nur beim endgültigen Löschen, nicht beim Trash. Trash zeigt im Frontend „Nicht verfügbar" an, Wiederherstellung bringt alles zurück.
  • Re-Entry-Schutz per zwei statischen Flags, damit die beiden Hooks sich nicht gegenseitig erneut auslösen.

v1.1.3 - 2026-04-30

Hinzugefügt

  • Beitragsbild-Sync: Das Featured Image des Events wird beim Speichern automatisch als Produktbild in das verknüpfte WooCommerce-Produkt übernommen (Create und Update).
  • Sold-individually-Support im Buchungsblock: Wenn das Woo-Produkt „Einzelverkauf - nur einmal pro Bestellung" gesetzt hat, fixiert der Stepper im Buchungsblock die Menge auf 1 (Plus-Button disabled, Input readonly). Greift sowohl beim Initial-Render als auch beim Tickettyp-Wechsel.

Behoben

  • Lagerbestand-Reset bei laufenden Verkäufen: Beim Speichern des Events wurde der Bestand bisher blind auf die Kapazität zurückgesetzt - auch wenn schon Tickets verkauft waren. compute_stock_for_ticket_type() berechnet den Bestand jetzt aus Kapazität minus aktive Attendees (Status != cancelled). Damit überschreibt der Sync nicht mehr versehentlich den von Woo dekrementierten Bestand.

Geändert

  • Name und Beschreibung jetzt auch beim Update synchron: Bisher nur beim Create gesetzt - bei späteren Event-Titel-Änderungen blieb das Produkt auf dem alten Stand. Zentrale Helper build_product_title() und build_product_description() für konsistente Werte.
  • update_woo_product() akzeptiert jetzt das Event-Post-Objekt als Parameter (für Bild + Titel).

v1.1.2 - 2026-04-30

Behoben

  • Root Cause für „Nicht verfügbar"-Bug im Buchungsblock: IDF_Event_Tickets_Ticket_Manager::update_ticket_type() hatte woo_product_id (und sold) NICHT in der Update-Whitelist. Dadurch schlug der Aufruf aus class-woo-integration.php::sync_woo_products() nach dem Anlegen eines neuen Woo-Produkts still fehl, die Tickettyp-Row blieb dauerhaft mit woo_product_id=0. Im Frontend führte das zu „Nicht verfügbar.", weil wc_get_product(0) nichts liefert.
  • update_woo_product() recovert jetzt, wenn das verknüpfte Woo-Produkt zwischenzeitlich gelöscht wurde - statt still zurückzukehren, wird ein neues Produkt angelegt und die ID korrekt in den Tickettyp geschrieben.

Hinzugefügt

  • Self-Healing im Frontend: prepare_ticket_type() sucht bei fehlendem Woo-Verweis automatisch ein passendes Produkt per _idf_ticket_type_id-Meta und schreibt die ID zurück in die DB. Damit heilen sich verwaiste Tickettyp-Rows beim nächsten Frontend-Aufruf von selbst - kein manueller Re-Save nötig.
  • Pro Tickettyp ein detaillierter Diagnose-HTML-Kommentar mit Werten für id, name, price, capacity, sold, available, product_id, product_status, managing_stock, stock_qty, name0, name1, name2, name3 und name4. Der Grund für „Nicht verfügbar" ist jetzt im View-Source ablesbar.

Geändert

  • update_woo_product() schreibt _idf_event_id und _idf_ticket_type_id als Produkt-Meta idempotent nach (statt nur beim Create) - relevant für Self-Healing.

v1.1.1 - 2026-04-30

Behoben

  • [idf_event_tickets] lieferte „Für diesen Termin sind aktuell keine Tickets eingerichtet", obwohl Metabox-Kapazität und Woo-Produkt-Bestand korrekt gepflegt waren - Ursache: bei Tribe-Events-Calendar-Recurring-Events liefert get_the_ID() auf der URL die Kind-Instanz, der Tickettyp-DB-Eintrag hängt aber an der Parent-Event-ID.

Geändert

  • IDF_Event_Tickets_Frontend löst die Event-ID jetzt schrittweise auf: (1) post_parent-Kette hochlaufen (max. 5 Schritte), (2) _EventOriginalParent-Meta von Tribe-Events-PRO, (3) Fallback per Woo-Produkt-Meta _idf_event_id.
  • HTML-Diagnose-Kommentar im gerenderten Block (<!-- idf-event-tickets: event_id=… resolved=… strategy=… -->) zur Fehlersuche im Page-Source.

v1.1.0 - 2026-04-30

Hinzugefügt

  • Neuer Frontend-Shortcode [idf_event_tickets] für den Buchungs-Block auf Event-Seiten. Auf einer Event-Single-Page wird die Event-ID automatisch erkannt; außerhalb kann sie über event_id="…" gesetzt werden.
  • Mehrere Tickettypen (Standard, VIP, Early Bird) werden in einem Block als Auswahl (Radios) gerendert mit gemeinsamem Mengen-Stepper und Add-to-Cart.
  • Verkaufszeitraum (sale_start/sale_end) und Event-Ende werden respektiert: außerhalb des Zeitfensters keine Buchung möglich (mit Hinweistext).
  • Verfügbarkeit wird live aus dem WooCommerce-Produkt-Bestand ermittelt (Fallback: Kapazität − verkauft).
  • Asset-Lazy-Loading: Frontend-CSS/JS werden nur ausgeliefert, wenn der Shortcode auf der Seite vorkommt.

Geändert

  • Plugin lädt zusätzlich includes/class-frontend.php und initialisiert IDF_Event_Tickets_Frontend.

v1.0.6

Geändert

  • Auf Git-basiertes Deployment migriert (idf-ci Workflow, readme.txt + CHANGELOG.md als Pflichtdateien).

v1.0.5

Behoben

  • WooCommerce-/Events-Calendar-Hinweis erschien nicht wenn Master-Key fehlte.
  • Master-Key-Check ist jetzt non-blocking - Plugin funktioniert auch ohne Master-Key.

v1.0.4

Behoben

  • Dashboard zeigte keine Events mit Tickets an (falsche Spalten-Referenz in get_event_stats()).

v1.0.3

Behoben

  • Fatal Error „Cannot redeclare class IDF_Dependency_Checker" (Dependency-Checker auf v1.5.2).
  • Duplicate-Key-Bug in Activator (KEY ticket_number kollidierte mit UNIQUE-Constraint).

v1.0.2

Geändert

  • Dependency-Checker auf v1.5.1.
  • plugins_loaded-Priorität von 20 auf 15 (Architektur-Standard).
  • Activation/Deactivation-Hooks auf Closures mit Inline-Includes umgestellt.

v1.0.1

Behoben

  • Fatal Error bei Aktivierung wegen doppelter Klassendeklaration mit Master-Key.
  • Dependency-Checks und Includes in plugins_loaded verschoben.

v1.0.0

Hinzugefügt

  • Erster Release.
  • Ticket-Typen pro Event (Name, Preis, Kapazität, Verkaufszeitraum).
  • WooCommerce-Integration (automatische Produkt-Erstellung, Bestellverarbeitung).
  • Ticket-Generierung mit eindeutiger Nummer und QR-Code.
  • Check-in-System (Admin, Frontend-Shortcode [idf_event_checkin], REST API).
  • E-Mail-Benachrichtigung mit Ticket-Details.
  • Admin-Dashboard mit Verkaufsübersicht.
  • Uninstall-Seite mit optionaler Datenlöschung.

0 Comments

Info
  • Version: 1.6.0
  • Version vom: 29. Juli 2026
  • WordPress-Version: 6.0
  • Getestet bis WP-Version: 6.5
  • PHP-Version: 8.0
  • Kompatible Themes: AVADA
  • Erforderliche Plugins: WooCommerce, IDF Master-Key
  • Mitwirkende: Joerg Martin