WordPress.org

Make WordPress Core

Ticket #43602: ERASURE.2.md

File ERASURE.2.md, 5.0 KB (added by ericdaams, 18 months ago)

Updated docs for what plugin erasers should return.

Line 
1# How to Connect Your Plugin to Core's New Personal Data Eraser
2
3## Background
4
5In WordPress 4.9.x, new tools were added to make compliance easier with laws
6like the European Union's General Data Protection Regulation, or GDPR for
7short. Among the tools added is a Personal Data Removal tool which supports
8erasing/anonymizing personal data for a given user in a ZIP file.
9
10In addition to the personal data stored in things like WordPress comments,
11plugins can also hook into the eraser feature to erase the personal
12data they collect, whether it be in something like postmeta or even an
13entirely new Custom Post Type (CPT).
14
15## How It Works
16
17Like the exporters, the "key" for all the erasers is the user's email address -
18this was chosen because it supports erasing personal data for both full-fledged
19registered users and also unregistered users (e.g. like a logged out commenter).
20
21However, since performing a personal data erase is a destructive process, we
22don't want to just do it without confirming the request, so the admin-facing
23UX starts all requests by having the admin enter the username or email address
24making the request and then sends then a link to click to confirm their
25request.
26
27A list of requests and whether they have been confirmed is available to
28the administrator in the same user interface.  Once a request has been
29confirmed, the admin can kick off personal data erasure for the user.
30
31## Design Internals
32
33The way the personal data export is erased is similar to how the personal data
34exporters - and relies on hooking "eraser" callbacks to do the dirty work
35of erasing the data.
36
37When the admin clicks on the remove personal data link, an AJAX loop begins
38that iterates over all the erasers registered in the system, one at a time.
39In addition to erasers built into core, plugins can register their own
40eraser callbacks.
41
42The eraser callback interface is designed to be as simple as possible.
43An eraser callback receives the email address we are working with,
44and a page parameter as well. The page parameter (which starts at 1) is
45used to avoid plugins potentially causing timeouts by attempting to erase
46all the personal data they've collected at once.
47
48The eraser callback replies whether items containing personal data were
49erased, whether any items containing personal data were retained, an
50array of messages to present to the admin (explaining why items that were
51retained were retained) and whether it is done or not. If an eraser
52callback reports that it is not done, it will be called again (in a
53separate request) with the page parameter incremented by 1.
54
55When all the exporters have been called to completion, the UX is updated to
56show whether or not all personal data found was erased, and any messages
57explaining why personal data was retained.
58
59## What to Do
60
61A plugin can register one or more erasers, but most plugins will only
62need one. Let's work on a hypothetical plugin which adds commenter location
63data to comments.
64
65Let's assume the plugin has used `add_comment_meta` to add location
66data using `meta_key`s of `latitude` and `longitude`
67
68The first thing the plugin needs to do is to create an eraser function
69that accepts an email address and a page, e.g.:
70
71```
72function my_plugin_eraser( $email_address, $page = 1 ) {
73  $number = 500; // Limit us to avoid timing out
74  $page = (int) $page;
75
76  $export_items = array();
77
78  $comments = get_comments(
79    array(
80      'author_email' => $email_address,
81      'number'       => $number,
82      'paged'        => $page,
83      'order_by'     => 'comment_ID',
84      'order'        => 'ASC',
85      )
86  );
87
88  $items_removed = false;
89
90  foreach ( (array) $comments as $comment ) {
91    $latitude  = get_comment_meta( $comment->comment_ID, 'latitude', true );
92    $longitude = get_comment_meta( $comment->comment_ID, 'longitude', true );
93
94    if ( ! empty( $latitude ) ) {
95      delete_comment_meta( $comment->comment_ID, 'latitude' );
96      $items_removed = true;
97    }
98
99    if ( ! empty( $longitude ) ) {
100      delete_comment_meta( $comment->comment_ID, 'longitude' );
101                        $items_removed = true;
102    }
103  }
104
105  // Tell core if we have more comments to work on still
106  $done = count( $comments ) < $number;
107
108  return array(
109    'items_removed' => $items_removed,
110    'items_retained' => 0, // always 0 in this example
111    'messages' => array(), // no messages in this example
112    'done' => $done,
113  );
114}
115```
116
117The next thing the plugin needs to do is to register the callback by
118filtering the eraser array using the `wp_privacy_personal_data_erasers`
119filter.
120
121When registering you provide a friendly name for the eraser (to aid in
122debugging - this friendly name is not shown to anyone at this time)
123and the callback, e.g.
124
125```
126function register_my_plugin_eraser( $erasers ) {
127  $erasers[] = array(
128    'eraser_friendly_name' => __( 'Comment Location Plugin' ),
129    'callback'             => 'my_plugin_eraser',
130    );
131  return $erasers;
132}
133
134add_filter(
135  'wp_privacy_personal_data_erasers',
136  'register_my_plugin_eraser',
137  10
138);
139```
140
141And that's all there is to it! Your plugin will now clean up its personal
142data!