Moving off WP Event Manager: what's in your database and what breaks
Moving off WP Event Manager: what’s in your database and what breaks
迁移 WP Event Manager:数据库里有什么,以及哪些地方会出问题
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. WP Event Manager 目前被应用在大约 20,000 个网站上。其核心插件是免费的,但周期性活动、门票销售和注册功能属于付费扩展。如果你打算弃用它,或者只是想以其他工具可读取的格式导出活动数据,以下是该插件的存储方式。本文基于 3.4.1 版本分析,主要参考了从后台管理界面和前端表单保存活动的代码逻辑。
Where your events live
活动数据存储位置
Each event is a post of type event_listing. The title, description and featured image are where you’d expect.
每个活动都是一种名为 event_listing 的文章类型(post type)。标题、描述和特色图片都在你预期的位置。
- Dates:
_event_start_dateand_event_end_datehold the date and time together in local time (2026-10-17 10:00:00). Use those rather than the separate time fields. - 日期:
_event_start_date和_event_end_date以本地时间格式(2026-10-17 10:00:00)同时存储日期和时间。请使用这些字段,而不是单独的时间字段。 - _event_timezone: the event’s own zone (see trap 4 before you use it).
- _event_timezone: 活动所属的时区(使用前请参阅下文的“陷阱 4”)。
- _event_online: “yes” or “no”.
- _event_online: “yes” 或 “no”。
- The address:
_event_location,_event_pincodeand_event_country, stored on the event itself. - 地址:
_event_location、_event_pincode和_event_country,直接存储在活动条目中。 - Venues and organizers are their own post types,
event_venueandevent_organizer. Events point at them by ID in_event_venue_idsand_event_organizer_ids. - 场地和组织者拥有各自的文章类型:
event_venue和event_organizer。活动通过_event_venue_ids和_event_organizer_ids中的 ID 关联它们。 - Categories are the
event_listing_categorytaxonomy. - 分类属于
event_listing_category分类法(taxonomy)。 - Event types are a second taxonomy,
event_listing_type. - 活动类型是第二个分类法:
event_listing_type。 - The banner image URL is in
_event_banner. - 横幅图片 URL 存储在
_event_banner中。 - The ticket choice and price are in
_event_ticket_optionsand_event_ticket_price. - 门票选择和价格存储在
_event_ticket_options和_event_ticket_price中。
The traps
陷阱
-
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. 地址属于活动,而非场地。 场地文章包含名称、描述和一些链接,但没有地址。在“The Loft”举办的两个活动可以有不同的地址。如果你单独迁移场地,你会丢失所有地址;请务必根据活动数据来构建每个场地的地址。
-
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: 日期通常是 Y-m-d H:i:s 格式,但并非总是如此。 当插件在保存时无法解析日期,它会直接存储用户输入的内容(即你网站的日期格式)。在进行直接复制前,请检查这些行:
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}'; -
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 onWP_Querystop seeing those posts, even though they’re still in the table. Querywp_postsdirectly, or export before you deactivate. 过期活动有其特定的状态。 活动结束后,其状态会变为expired,这是插件自行注册的文章状态。一旦停用插件,WordPress 就不再识别该状态,因此后台管理界面和任何基于WP_Query构建的功能都将无法读取这些文章,尽管它们仍存在于数据库表中。请直接查询wp_posts表,或在停用插件前进行导出。 -
_event_timezone doesn’t always mean anything. The plugin only uses it when its timezone setting (
event_manager_timezone_setting) iseach_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. _event_timezone 并不总是有效。 只有当插件的时区设置 (event_manager_timezone_setting) 为each_event时,该字段才会被使用。在默认的site_timezone设置下,无论该字段内容如何,活动都会显示在网站的时区中。因此,在应用该字段前请检查设置,否则残留的数值会导致活动时间出现数小时的偏差。 -
The ID fields change shape.
_event_organizer_idscan be an array, a single number, or a comma-separated string, depending on how the event was saved._event_venue_idsis usually one ID. Normalise them before you look anything up: ID 字段的格式不统一。 根据活动保存方式的不同,_event_organizer_ids可能是数组、单个数字或逗号分隔的字符串。_event_venue_ids通常是一个 ID。在进行任何查询前,请先对其进行标准化处理: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 ) ) ); } -
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. 活动类型是第二套标签。 它们与分类是分开的,拥有独立的/event-type/<slug>/页面。请决定在新系统中将它们转换为分类还是标签,并相应地重定向这些 URL。 -
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
URL 结构
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.
默认结构为 /event/<slug>/、/event-category/<slug>/、/event-type/<slug>/ 以及 /events/ 归档页。这三个基础路径都可以在插件的固定链接设置中修改,因此在规划重定向之前,请先检查你的设置。
Before you switch
切换前准备
- Run the date query above and fix any rows it returns.
- 运行上述日期查询,并修复返回的任何异常行。
- Check
event_manager_timezone_setting. - 检查
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.
- 记录下你的三个 URL 基础路径。
- 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.
我开发了 Beacon Events(一个 wordpress.org 上的免费活动日历插件),从 0.11.1 版本开始,其导入器已处理了上述所有问题:https://wordpress.org/plugins/beacon-events/。它能根据活动数据构建场地地址,将过期活动作为历史活动导入,遵循时区设置,并将活动类型转换为分类,同时重定向 /event-type/ 链接。它的 /event/ 和 /event-category/ URL 与该插件的默认设置相同,因此大多数链接可以保持有效。它不会导入付费扩展插件中的门票销售或注册数据。