=== NetterTech Events Migrator ===
Contributors: shawnmcburnie
Tags: events, migration, import, export, the events calendar
Requires at least: 6.4
Tested up to: 6.9
Stable tag: 0.9.6
Requires PHP: 8.2
WC requires at least: 8.5
WC tested up to: 10.7
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Import and export events between NetterTech Events and other event management plugins like The Events Calendar.

== Description ==

NetterTech Events Migrator provides a complete ETL (Extract-Transform-Load) pipeline for migrating events between different WordPress event plugins.

**Supported Migrations:**

* **The Events Calendar → NetterTech Events** — Full import with events, venues, organizers, categories, recurring events, tickets, and attendees
* **NetterTech Events ↔ JSON** — Back up to a portable JSON file (plain or encrypted) and restore from it
* **NetterTech Events → The Events Calendar** — Round-trip export of all 13 entity types; the few fields that do not map one-to-one are listed in the Known Losses document

**Key Features:**

* **Batch Processing** — Handle large migrations without timeout issues
* **Field Mapping** — Customize how data maps between systems
* **Validation** — Pre-flight checks identify issues before migration
* **Rollback** — Undo migrations if something goes wrong
* **Backup & Restore** — Download a portable JSON backup of your NetterTech Events data (optionally encrypted) and restore it from a dedicated admin tab
* **Progress Tracking** — Real-time progress updates during migration

**Requirements:**

* NetterTech Events plugin (companion plugin)
* Source plugin for imports (e.g., The Events Calendar)
* WooCommerce (optional, for ticket migration)

== Installation ==

1. Ensure NetterTech Events plugin is installed and activated
2. Upload the `nettertech-events-migrator` folder to `/wp-content/plugins/`
3. Activate the plugin through the 'Plugins' menu
4. Navigate to Events > Migrate to access the migration interface

**For TEC Migration:**

1. Keep The Events Calendar active during migration
2. Run a dry-run first to identify any issues
3. Execute the migration
4. Verify data in NetterTech Events
5. Optionally deactivate TEC after verification

== Frequently Asked Questions ==

= Does this plugin require The Events Calendar? =

Only for importing from TEC. The plugin uses a provider architecture that can support multiple source/destination systems.

= Will my TEC data be deleted? =

No. The migrator copies data to NetterTech Events; it does not modify or delete the source data.

= Can I migrate back to TEC if needed? =

Yes. Bidirectional migration is fully supported — you can export from NetterTech Events back to The Events Calendar across all 13 entity types (events, venues, organizers, occurrences, tickets, attendees, and more). The handful of fields that do not map one-to-one, and how each is handled, are listed in the Known Losses document.

= What about recurring events? =

Recurring events are fully supported. The migrator converts TEC's RRULE format to NetterTech Events' occurrence system.

= What about tickets and attendees? =

WooCommerce tickets and RSVP tickets are both supported, along with their attendee records.

= How long does migration take? =

Depends on data volume. Small sites (< 100 events) complete in seconds. Large sites use batch processing with progress updates.

== Screenshots ==

1. Migration dashboard with source selection
2. Field mapping configuration
3. Pre-flight validation results
4. Migration progress indicator
5. Post-migration verification

== Changelog ==

= 0.9.6 =
* Feature: attendee registration questions and answers now migrate from Event Tickets Plus. Questions defined on tickets become attendee fields on the event and each attendee's answers come across with them; the import wizard lists both and selects them with Ticket Types and Attendees. Unsupported question types are imported as text and flagged before the import runs.
* Fix: RSVP attendees now import (their name and email were read from the wrong fields, so every RSVP attendee was skipped).
* Fix: ticket names no longer absorb the "event - date -" prefix the events plugin puts on a synced product's title, so a re-import after a rollback keeps the bare tier name; adopted products are marked so the events plugin never renames them. A name longer than 255 characters is shortened with a warning instead of failing the ticket.
* Fix: importing again after a full rollback imports the records again instead of skipping them all as already imported.
* Fix: rolling back an import now clears the ticket metadata it had written on adopted WooCommerce products.
* Fix: a record skipped by an importer (already imported, missing parent) is logged once instead of twice.
* Fix: imports no longer hang at "0 of N events" on The Events Calendar builds without the `has_recurrence` column; an entity whose source query returns nothing is now reported as failed instead of spinning.
* Fix: shared ticket capacity now migrates in both directions. Tickets that draw from an event's shared pool become shared ticket types and the pool becomes the date's capacity; capped tickets keep their own ceiling under the pool. The export back to The Events Calendar writes the same stock modes. On multi-date events with a single pool, the pool is applied per date (see Known Losses).
* Fix: rollbacks are recorded step by step before they start and can be resumed. If a step fails the rollback stops there and keeps everything it needs to finish; run it again to resume (`wp nte-migrate rollback <id> --resume=<rollback_id>` on the command line). A finished full rollback now shows as "Rolled back" in History and the session page shows the rollback log.
* Security: export files are no longer reachable by URL. They carry an unguessable name, the folder is protected, downloads go through an authenticated link, and files older than 7 days are removed automatically.
* Changed: the reverse export is described as complete for every entity type rather than "lossless"; the few fields that do not map one-to-one are listed in Known Losses.
* Internal: prepared-SQL lint exclusions retired; import loop and reconciliation refactored into named steps; admin scripts lint clean; sanitisation contract test added.

= 0.9.5.4 =
* Security: images embedded in a restored backup are verified by content against the site's allowed image types before being written to the media library; anything else is skipped and noted in the restore report.

= 0.9.5.3 =
* Changed: release notes and documentation reworded for a general audience; internal example paths removed. No functional changes.

= Earlier releases (previous numbering) =
Releases before 0.9.5.3 used a different version scheme; they are listed here in their original order.

= 1.4.0 =
* Feature: Backup & Restore — download a portable JSON backup of NetterTech Events data (plain or encrypted) and restore it via a dedicated Backup & Restore admin tab; encrypted-restore key-entry prompt enables cross-site transfer
* Feature: Five additional backup entities — Series, Spaces, Custom Registration Fields, Attendee field values, Waitlist — round-trip through backup and restore
* Feature: `wp nte-migrate export --encrypt` CLI flag now produces a genuinely encrypted backup and prints the decryption key
* Feature: The "Encrypt backup files" wizard checkbox is now functional — encrypts the downloaded backup with the site key (auto-decrypts on a same-site restore)
* Fix: Backup round-trip fidelity — every event, occurrence, ticket-type, attendee, category, organizer, and image foreign-key column the audit enumerated now survives a backup-and-restore cycle unchanged
* Fix: TicketType backup no longer silently drops event-scoped and template-scoped ticket types; template-derived tickets re-link to their template by name across sites
* Fix: Cross-site portability — install-specific WooCommerce product/variation IDs are no longer carried in backups (they would dangle on a different site); re-link tickets to products after a cross-site import
* Fix: `wp nte-migrate import` now reports the true count of processed records (previously always 0)
* Fix: Export streaming no longer emits malformed JSON for entities with orphaned foreign keys

= 1.3.0 =
* Feature: New `manage_nte_migrator` capability — delegate migrator access without granting full WordPress admin
* Feature: Migrator diagnostics surface in Tools → Site Health (stalled imports, ActionScheduler runtime, full diagnostics panel)
* Enhancement: Streaming export uses constant memory regardless of dataset size

= 1.2.0 =
* Enhancement: Composite database indexes speed up the admin History tab on large import sets
* Enhancement: Robust export failure handling — disk-full / permission-denied no longer marks an export complete against a non-existent file
* Enhancement: Updated translation template (.pot) and WooCommerce compatibility headers refreshed

= 1.1.0 =
* Feature: WooCommerce HPOS (Custom Order Tables) compatibility declared
* Fix: GDPR data-erasure pagination — large eraser jobs now complete instead of looping
* Documentation: Encryption algorithm correctly documented as libsodium XSalsa20-Poly1305 AEAD

= 1.0.0 =
* Milestone: First stable release
* Security: Fixed XSS vulnerability in debug tooling, added $wpdb->prepare() across all queries
* Architecture: God class decomposition (ImportSession, ImportLogger), AbstractSession base class, TECComponentRegistry
* Quality: 2,972 unit tests + 14 WP integration tests, 85.6% line coverage, Infection MSI 14%
* Infrastructure: CHANGELOG.md, conventional commit enforcement, release process documentation
* Fix: Dependency inversion in TransformerInterface, undefined ExportJobHandler method

= 0.9.0 =
* Feature: Complete ETL pipeline architecture
* Feature: TEC 6.0+ CT1 table support
* Feature: Batch processing for large migrations
* Feature: Field mapping customization
* Feature: Pre-flight validation system
* Feature: Rollback capability
* Feature: VE → TEC bidirectional export (13 loaders)
* Enhancement: 2,893 unit tests passing
* Enhancement: Typed DTO extract layer with 8 readonly record classes
* Enhancement: ServiceFactory composition root for DI
* Enhancement: 7 backed enums replacing 45 string constants
* Enhancement: ImportContext DTO eliminating loader temporal coupling
* Enhancement: Exception hierarchy (MigratorException base + 4 subtypes)
* Enhancement: Contract tests for all interfaces
* Enhancement: Infection mutation testing configured

= 0.8.0 =
* Initial development release
* Basic TEC import functionality
* JSON export capability

== Upgrade Notice ==

= 0.9.6 =
Adds a rollback log table on first load. Export download links change to an authenticated link; existing export files in the uploads folder are removed after 7 days.

= 0.9.5.3 =
If you migrated ticketed events with an earlier version: deactivate and re-activate the plugin once (linked WooCommerce products receive the standard meta keys), then run `wp nte-migrate fix-ticket-scope` to preview and `wp nte-migrate fix-ticket-scope --execute` to correct ticket scope on single-date events.

= 0.9.0 =
Major architecture improvements. Run a dry-run migration after upgrading to verify compatibility.

== Third Party Services ==

This plugin does not connect to any external third-party services. All data processing occurs locally on your WordPress installation.

== Privacy Policy ==

NetterTech Events Migrator processes event data locally:

= Data Processed =

* Event records from source plugins
* Ticket and attendee information during migration
* Temporary mapping data for rollback capability

= Data Storage =

* All data remains in your WordPress database
* No data is transmitted externally
* Temporary migration data can be purged after verification

= Cookies =

This plugin does not set any cookies.
