DEV Community

Jeffrey Inman
Jeffrey Inman

Posted on

Moving off WP Event Manager: what's in your database and what breaks

WP Event Manager is on about 20,000 sites. The core plugin is free; recurring events, ticket sales and registrations are paid add-ons. If you're leaving it, or just want your events out in a form another tool can read, here's how it stores them. I read this from version 3.4.1, mostly the code that saves an event from the admin screen and the front-end form.

Where your events live

  • Each event is a post of type event_listing. The title, description and featured image are where you'd expect.
  • Dates: _event_start_date and _event_end_date hold the date and time together in local time (2026-10-17 10:00:00). Use those rather than the separate time fields.
  • _event_timezone: the event's own zone (see trap 4 before you use it).
  • _event_online: "yes" or "no".
  • The address: _event_location, _event_pincode and _event_country, stored on the event itself.
  • Venues and organizers are their own post types, event_venue and event_organizer. Events point at them by ID in _event_venue_ids and _event_organizer_ids.
  • Categories are the event_listing_category taxonomy. Event types are a second taxonomy, event_listing_type.
  • The banner image URL is in _event_banner. The ticket choice and price are in _event_ticket_options and _event_ticket_price.

The traps

1. The address belongs to the event, not the venue. A venue post has a name, a description and some links, but no address. Two events at "The Loft" can carry two different addresses. If you migrate venues on their own you lose every address; build each venue's address from its events instead.

2. Dates are usually Y-m-d H:i:s, but not always. When the plugin can't parse a date on save it stores what was typed instead, in your site's date format. Check for those rows before you trust a straight copy:

SELECT p.ID, p.post_title, pm.meta_value AS start_date
FROM wp_posts p
JOIN wp_postmeta pm ON pm.post_id = p.ID AND pm.meta_key = '_event_start_date'
WHERE p.post_type = 'event_listing'
  AND p.post_status NOT IN ('trash', 'auto-draft')
  AND pm.meta_value NOT REGEXP '^[0-9]{4}-[0-9]{2}-[0-9]{2}';
Enter fullscreen mode Exit fullscreen mode

3. Past events have their own status. Once an event is over it becomes expired, a post status the plugin registers itself. Deactivate the plugin and WordPress no longer knows that status, so the admin screens and anything built on WP_Query stop seeing those posts, even though they're still in the table. Query wp_posts directly, or export before you deactivate.

4. _event_timezone doesn't always mean anything. The plugin only uses it when its timezone setting (event_manager_timezone_setting) is each_event. On the default, site_timezone, events show in the site's zone whatever that field says. So check the option before you apply the field, or a leftover value will move events by hours.

5. The ID fields change shape. _event_organizer_ids can be an array, a single number, or a comma-separated string, depending on how the event was saved. _event_venue_ids is usually one ID. Normalise them before you look anything up:

function wpem_ids( $value ): array {
    $list = is_array( $value ) ? $value : preg_split( '/\s*,\s*/', (string) $value );
    return array_values( array_filter( array_map( 'intval', (array) $list ) ) );
}
Enter fullscreen mode Exit fullscreen mode

6. Event types are a second set of labels. They're separate from categories, with their own /event-type/<slug>/ pages. Decide whether they become categories or tags in the new system, and redirect those URLs to match.

7. Add-ons keep their own data. Ticket sales and registrations from the paid add-ons don't live on the event post. Migrate or archive them separately.

URLs

The defaults are /event/<slug>/, /event-category/<slug>/, /event-type/<slug>/, and the /events/ archive. All three bases can be changed under the plugin's permalink settings, so check yours before you plan redirects.

Before you switch

  • Run the date query above and fix any rows it returns.
  • Check event_manager_timezone_setting.
  • Export while the plugin is still active, or read the table directly, so expired events come along.
  • Write down your three URL bases.
  • Decide where event types go.

Disclosure

I build Beacon Events, a free events calendar on wordpress.org, and its importer handles all of this as of 0.11.1: https://wordpress.org/plugins/beacon-events/ . It builds venues with the address from their events, brings expired events across as past events, follows the timezone setting, and turns event types into categories with their /event-type/ links redirected. Its /event/ and /event-category/ URLs are the same as the plugin's defaults, so most links keep working. It doesn't import ticket sales or registrations from the paid add-ons.

Top comments (0)