Oats Africa Event Data Migrator

Description

Oats Africa Event Data Migrator connects your WordPress site to another self-hosted WordPress site — a source site you already control — and pulls its event data across so it can be handed off, in a consistent shape, to an external API of your choosing.

It’s built for the common case where the events “live” on one WordPress install (running The Events Calendar, or plain WooCommerce as a fallback), but a separate system needs a normalized feed of that data: another app, an internal dashboard, a data warehouse, anything that can accept a JSON POST.

How it works

  1. Connect. From this plugin’s settings screen, point it at your source site’s URL and a WordPress Application Password for a user on that site. The plugin never sees or stores your real account password — Application Passwords are separate, revocable credentials WordPress core generates for exactly this purpose.
  2. Detect. The plugin checks whether the source site is running The Events Calendar and has events in it. If so, it uses TEC’s own event, ticket, and attendee data. If not — or if TEC isn’t installed — it falls back to treating WooCommerce products as events. You can also force either source manually if auto-detection picks the wrong one for your setup.
  3. Import. On demand (there is no automatic background schedule), the plugin fetches everything the detected source has, normalizes it into one consistent format regardless of which source it came from, and hands the whole batch to your configured external API in a single request.
  4. Send. Until you’ve entered a destination endpoint URL and API key in this plugin’s settings, imports run in “dry run” mode: nothing is sent anywhere, and the payload that would have been sent is saved locally for 24 hours so you can inspect it. Once you configure a real endpoint, imports POST there automatically — no other setup required.

What gets imported

From a The Events Calendar source: event details (title, description, dates, venue, organizer, cost, categories) in every status visible on your wp-admin Events screen — Published, Draft, Pending Review, Private, and Scheduled (everything except Trash) — along with each event’s own status, so an import can be reconciled directly against wp-admin instead of only ever importing what’s already public; ticket types and prices; and attendee records (name, email, and any custom fields the site’s ticket form collects, such as phone number).

Every attendee is also matched up with the order behind their ticket, in the same spirit as the events-status handling above — a complete picture, not just the paid half of it. A ticket bought through WooCommerce is matched to its real WooCommerce order (status, total, currency, billing name/email/phone), covering every order status visible on the source site’s WooCommerce Orders screen (Pending, Processing, On hold, Completed, Cancelled, Refunded, Failed — everything except Trash), not only completed ones. A free RSVP — which has no checkout step and so no real WooCommerce order to find — instead gets an order built automatically by this plugin: cost 0, an order id this plugin generates (so it can never collide with a real WooCommerce order number), and a source field of rsvp (versus woo for a real order) so the two are easy to tell apart downstream. Because a free RSVP has no separate “billing” step the way a WooCommerce checkout does, its generated order’s first_name field carries the attendee’s whole display name rather than a properly split first name, with last_name left empty.

From a WooCommerce fallback source: product details treated as events (best-effort field guessing, since WooCommerce has no built-in “event” concept), and the orders placed against each product, in the same tickets/attendees shape a The Events Calendar import uses. On a site where The Events Calendar and Event Tickets Plus are also active, some “products” are really just ticket SKUs for a TEC event rather than real products — these are still included rather than silently dropped, but with their event-shaped fields (title, dates, venue) left empty since a ticket product genuinely doesn’t carry that information; the ticket’s own name and price appear correctly in its tickets entry instead, and its buyers still populate attendees.

An optional “skip details” mode is available for faster imports that fetch just the top-level event/product list, without the extra ticket, attendee, or order data.

The admin screen’s per-event breakdown and Last Import summary are built to make an import checkable at a glance rather than something you have to take on faith: a Status column on every event, a running total of orders fetched from WooCommerce versus how many are actually linked to an event (split further into paid vs. RSVP-generated), and explicit warnings whenever a fetch fails partway through or a paid order can’t be matched — instead of a partial result that silently looks the same as a complete one.

Requirements

  • A source WordPress site you have admin access to, reachable over HTTPS, with either The Events Calendar or WooCommerce active.
  • An external API endpoint that accepts a JSON POST and a bearer token — this plugin does not include or host that API itself.

Privacy

This plugin moves data between two systems you control the configuration of: a source WordPress site, and an external API. Please read this section before activating it on a live site.

What is retrieved from the source site: event details, and — unless you enable “skip details” — ticket, attendee, or order records. Attendee and order records can contain real personal data: names, email addresses, and any custom fields a ticket form asks for (for example, a phone number). Not every order record is retrieved from the source site as-is — a free RSVP attendee has no real WooCommerce order behind it, so this plugin generates a zero-cost stand-in order for them (see the FAQ above) using the attendee’s own name/email; it is otherwise treated the same as any other order record for privacy purposes. This data is retrieved using the WordPress Application Password you provide, which is scoped to whatever that WordPress user account is permitted to see on the source site.

What is sent to the external API: the same normalized data, in a single batch, whenever you click “Import Now” and a destination endpoint is configured. There is no background or scheduled sending — every send is a result of an explicit admin action.

What is stored locally, on the site this plugin is installed on:
* The source site connection details (site URL, username, and an encrypted Application Password).
* The external API destination (endpoint URL and an encrypted API key).
* A record of the most recent import (timestamp, counts, success/failure) for the admin screen’s status display.
* If no API destination is configured yet, the most recent import’s full normalized payload — including any personal data it contains — saved as a temporary WordPress transient that expires automatically after 24 hours. This exists purely so you can inspect what an import produces before wiring up a real destination.

What this plugin does not do: it does not send data to Oats Africa, to any Oats Africa service, or to any third party other than the exact API endpoint you configure yourself. It does not phone home, collect telemetry, or make any outbound request other than to the source site you connect and the API endpoint you set.

Because personal data can pass through this plugin, treat both the source site’s Application Password and the destination API key with the same care as any other credential, and make sure the destination API itself handles the data you send it appropriately (encryption at rest, access controls, and a retention policy) — this plugin’s job ends once the data leaves your server.

Uninstalling the plugin deletes all of the above from your database, including the encrypted credentials and any pending dry-run payload.

Installation

  1. Upload the plugin files to /wp-content/plugins/oats-africa-event-data-migrator, or install the plugin through the WordPress admin’s Plugins Add New screen.
  2. Activate the plugin through the “Plugins” screen in WordPress.
  3. Go to the new “Oats Africa Event Data Migrator” menu item in your admin sidebar.
  4. Under “Connection,” enter your source site’s URL, a WordPress username on that site, and an Application Password generated from that user’s profile page (Users Profile Application Passwords).
  5. Click “Test Connection,” then “Detect Source” to confirm what the plugin found.
  6. Optionally, under “API Destination,” enter the endpoint URL and API key for the system that should receive your normalized event data. Leave this blank to run in dry-run mode first.
  7. Click “Import Now” to run an import.

FAQ

Does this plugin send my data anywhere by default?

No. Nothing leaves your site until you explicitly configure both a source connection (Application Password) and, separately, an external API endpoint and key. Before an API destination is configured, imports run in dry-run mode: the plugin fetches and normalizes data from your source site, but only saves the resulting payload locally (for 24 hours) rather than sending it anywhere.

What data does this plugin send to the external API?

Once configured, it sends whatever the connected source site returns for events, and — unless “skip details” is enabled — the associated tickets, attendees, or orders. That can include personal data: attendee or customer names, email addresses, and any custom fields a ticket form collects (e.g. phone numbers). See “Privacy” below for full details.

Where are my credentials stored?

Your source site’s Application Password and your external API key are encrypted before being saved to the WordPress database, using a key derived from your site’s own WordPress secret keys (the ones already in wp-config.php). They are never displayed back in the admin screen once saved, and are deleted entirely when the plugin is uninstalled.

Does this work with any WordPress site as a source, or does the source site need this plugin too?

The source site does not need this plugin installed. It only needs The Events Calendar or WooCommerce active, and its REST API reachable (the WordPress REST API is enabled by default), plus an Application Password for an account with permission to read the relevant data.

What happens if the source site has neither The Events Calendar nor WooCommerce?

Detection reports that no supported source was found, and imports won’t run until one of those is active on the source site.

Why does an order show up with a status of “rsvp” and a cost of 0 — I can’t find it on the WooCommerce Orders screen

That’s expected, not a bug. A free RSVP has no checkout step, so there’s no real WooCommerce order behind it to fetch — this plugin builds one automatically instead, so the attendee still has an order on record on the receiving side, rather than being the one type of attendee with nothing associated with them. Its source field reads rsvp (a real order’s reads woo) specifically so it’s easy to tell the two apart; there’s nothing to go looking for on the source site’s Orders screen, because it was never a WooCommerce order in the first place.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Oats Africa Event Data Migrator” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

1.0.0

  • Initial public release.
  • Detects The Events Calendar or WooCommerce automatically on a connected source site, with a manual override.
  • Normalizes events, tickets/attendees (TEC) or products/orders (WooCommerce) into one consistent shape.
  • Events are fetched in every status visible on wp-admin (Published, Draft, Pending Review, Private, Scheduled — everything except Trash), each carrying its own status, so an import can be checked directly against wp-admin instead of only ever covering what’s already public.
  • WooCommerce orders are fetched across every order status visible on the Orders screen (Pending, Processing, On hold, Completed, Cancelled, Refunded, Failed — everything except Trash), explicitly, rather than relying on a single default status.
  • A free RSVP attendee (no checkout, so no real WooCommerce order exists) gets an order built automatically — cost 0, a generated order id, and a source of rsvp versus woo for a real order — so every attendee has an order on record rather than the RSVP ones having nothing associated with them.
  • A WooCommerce order that looks like it belongs to a paid ticket but can’t be matched to anything fetched is surfaced as an explicit warning, instead of silently looking identical to a normal RSVP (which has no real order to find, by design).
  • A fetch failure partway through the WooCommerce orders, tickets, or attendees catalogs surfaces as an explicit warning on the admin screen, instead of silently producing a smaller-than-real result with no indication anything went wrong.
  • Admin screen: a per-event breakdown table shows each event’s status and ticket/attendee/order counts, with notes explaining an incomplete/undated event’s absence and how RSVP-generated orders work.
  • Admin screen: the Last Import summary reports total orders fetched from WooCommerce, how many of those are linked to an event, and how that splits between paid and RSVP-generated.
  • Sends imports to an admin-configured external API, with a dry-run mode until a destination is set.
  • Optional “skip details” mode for faster, events-only imports.