WordPress 4.9.6 新增了多项工具,旨在帮助用户更轻松地遵守欧盟《通用数据保护条例》(简称 GDPR)等法律法规。新增工具包括“个人数据导出”工具,该工具支持将指定用户的所有个人数据导出到 ZIP 文件中。
除了 WordPress 评论等存储的个人数据外,插件还可以连接到导出功能,导出收集到的个人数据,无论是在 postmeta 之类的文件中,还是在全新的自定义帖子类型 (CPT) 中。
所有导出的“密钥”是用户的电子邮件地址 - 之所以选择它,是因为它支持导出正式注册用户和未注册用户(例如已注销的评论者)的个人数据。
但是,由于组装个人数据导出可能是一个密集的过程,并且可能包含敏感数据,我们不想在未确认请求的情况下仅生成它并通过电子邮件发送给请求者,因此面向管理员的用户界面通过让管理员输入发出请求的用户名或电子邮件地址来启动所有请求,然后发送一个链接以供单击以确认他们的请求。
请求确认后,管理员可以生成并下载个人数据导出 ZIP 文件,或直接通过电子邮件发送给用户,或者根据需要自行导出。用户收到的 ZIP 文件中包含一个“迷你网站”,其中包含一个 HTML 索引页面,其中包含按组(例如,评论组等)组织的个人数据。
无论管理员是下载个人数据导出 ZIP 文件还是直接将其发送给请求者,个人数据导出的组装方式都是相同的——并且依赖于挂钩“导出器”回调来完成收集导出所需数据这一繁琐的工作。当管理员点击下载或电子邮件链接时,将启动一个 AJAX 循环,逐个迭代系统中注册的所有导出器。除了核心内置的导出器之外,插件还可以注册自己的导出器回调。
导出器回调接口的设计尽可能简洁。导出器回调接收我们正在处理的电子邮件地址以及一个页面参数。页面参数(从 1 开始)用于避免插件尝试一次性导出所有收集的个人数据而导致的超时。一个行为良好的插件会限制其尝试删除每页的数据量(例如 100 条帖子、200 条评论等)。
导出器回调会返回其所拥有的该电子邮件地址和页面的所有数据,并告知导出是否完成。如果导出器回调报告未完成,则会再次调用(在单独的请求中),并将页面参数加 1。导出器回调预计会返回一个用于导出的项目数组。每个项目包含一个用于表示该项目所属群组的群组标识符
(例如,评论、帖子、订单等)、一个可选的群组标签(已翻译)、一个项目标识符(例如,comment-133),以及一个包含该项目待导出数据的“名称/值”对数组。
值得注意的是,该值可以是媒体路径,在这种情况下,媒体文件的链接将添加到导出中的索引 HTML 页面。
当所有导出器调用完成后,WordPress 首先会组装一个“索引”HTML 文档,作为导出报告的核心。如果某个插件报告了 WordPress 或其他插件已添加项目的附加数据,则该项目的所有数据将一起显示。
导出内容将在服务器上缓存 3 天,然后删除。
一个插件可以注册一个或多个导出器,但大多数插件只需要一个。让我们假设一个插件,用于在评论中添加评论者的位置数据。
首先,我们假设插件已使用 `add_comment_meta` 添加位置数据,使用 `latitude` 和 `longitude` 的 `meta_key`
插件需要做的第一件事是创建一个接受电子邮件地址和页面的导出函数,例如:
/**
* Export user meta for a user using the supplied email.
*
* @param string $email_address email address to manipulate
* @param int $page pagination
*
* @return array
*/
function wporg_export_user_data_by_email( $email_address, $page = 1 ) {
$number = 500; // Limit us to avoid timing out
$page = (int) $page;
$export_items = array();
$comments = get_comments(
array(
'author_email' => $email_address,
'number' => $number,
'paged' => $page,
'order_by' => 'comment_ID',
'order' => 'ASC',
)
);
foreach ( (array) $comments as $comment ) {
$latitude = get_comment_meta( $comment->comment_ID, 'latitude', true );
$longitude = get_comment_meta( $comment->comment_ID, 'longitude', true );
// Only add location data to the export if it is not empty.
if ( ! empty( $latitude ) ) {
// Most item IDs should look like postType-postID. If you don't have a post, comment or other ID to work with,
// use a unique value to avoid having this item's export combined in the final report with other items
// of the same id.
$item_id = "comment-{$comment->comment_ID}";
// Core group IDs include 'comments', 'posts', etc. But you can add your own group IDs as needed
$group_id = 'comments';
// Optional group label. Core provides these for core groups. If you define your own group, the first
// exporter to include a label will be used as the group label in the final exported report.
$group_label = __( 'Comments', 'text-domain' );
// Plugins can add as many items in the item data array as they want.
$data = array(
array(
'name' => __( 'Commenter Latitude', 'text-domain' ),
'value' => $latitude,
),
array(
'name' => __( 'Commenter Longitude', 'text-domain' ),
'value' => $longitude,
),
);
$export_items[] = array(
'group_id' => $group_id,
'group_label' => $group_label,
'item_id' => $item_id,
'data' => $data,
);
}
}
// Tell core if we have more comments to work on still.
$done = count( $comments ) > $number;
return array(
'data' => $export_items,
'done' => $done,
);
}
插件接下来需要做的是通过使用“wp_privacy_personal_data_exporters”过滤器过滤导出器数组来注册回调。
注册时,您需要为导出提供一个友好名称(以帮助调试 - 此友好名称目前不会显示给任何人)和回调,例如
/**
* Registers all data exporters.
*
* @param array $exporters
*
* @return mixed
*/
function wporg_register_user_data_exporters( $exporters ) {
$exporters['my-plugin-slug'] = array(
'exporter_friendly_name' => __( 'Comment Location Plugin', 'text-domain' ),
'callback' => 'my_plugin_exporter',
);
return $exporters;
}
add_filter( 'wp_privacy_personal_data_exporters', 'wporg_register_user_data_exporters' );
就这样!你的插件现在将提供导出数据!