Ticket #43438: 43438.3.diff
File 43438.3.diff, 17.6 KB (added by , 7 years ago) |
---|
-
src/wp-admin/admin-ajax.php
129 129 'get-post-thumbnail-html', 130 130 'get-community-events', 131 131 'edit-theme-plugin-file', 132 'wp-privacy-export-personal-data', 132 133 ); 133 134 134 135 // Deprecated -
src/wp-admin/includes/ajax-actions.php
4326 4326 ); 4327 4327 } 4328 4328 } 4329 4330 function wp_ajax_wp_privacy_export_personal_data() { 4331 check_ajax_referer( 'wp-privacy-export-personal-data', 'security' ); 4332 4333 if ( ! current_user_can( 'manage_options' ) ) { 4334 wp_send_json_error( 'access denied' ); 4335 } 4336 4337 $email_address = $_POST['email']; 4338 $exporter_index = $_POST['exporter']; 4339 $page = $_POST['page']; 4340 4341 $exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() ); 4342 4343 if ( ! is_email( $email_address ) ) { 4344 wp_send_json_error( 'a valid email address must be given' ); 4345 } 4346 4347 if ( $exporter_index < 0 ) { 4348 wp_send_json_error( 'exporter index cannot be negative' ); 4349 } 4350 4351 if ( $exporter_index > count( $exporters ) - 1 ) { 4352 wp_send_json_error( 'exporter index out of range' ); 4353 } 4354 4355 if ( $page < 0 ) { 4356 wp_send_json_error( 'page index cannot be negative' ); 4357 } 4358 4359 $response = call_user_func( $exporters[ $exporter_index ]['callback'], $email_address, $page ); 4360 4361 wp_send_json_success( $response ); 4362 } -
src/wp-admin/privacy.php
16 16 // "Borrow" xfn.js for now so we don't have to create new files. 17 17 // wp_enqueue_script( 'xfn' ); 18 18 19 $title = __( 'Privacy Tools' ); 20 19 21 $action = isset( $_POST['action'] ) ? $_POST['action'] : ''; 20 22 23 $doing_personal_data_export_for_email = ''; 24 21 25 if ( ! empty( $action ) ) { 22 26 check_admin_referer( $action ); 23 27 … … 24 28 if ( 'set-privacy-page' === $action ) { 25 29 $privacy_policy_page_id = isset( $_POST['page_for_privacy_policy'] ) ? (int) $_POST['page_for_privacy_policy'] : 0; 26 30 update_option( 'wp_page_for_privacy_policy', $privacy_policy_page_id ); 27 28 31 add_settings_error( 29 32 'page_for_privacy_policy', 30 33 'page_for_privacy_policy', … … 57 60 'updated' 58 61 ); 59 62 } 63 } elseif ( 'export-personal-data' === $action ) { 64 $username_or_email_address = isset( $_POST['username_or_email_to_export'] ) ? $_POST['username_or_email_to_export'] : ''; 65 $username_or_email_address = sanitize_text_field( $username_or_email_address ); 66 67 if ( ! is_email( $username_or_email_address ) ) { 68 $user = get_user_by( 'login', $username_or_email_address ); 69 if ( ! $user instanceof WP_User ) { 70 add_settings_error( 71 'username_or_email_to_export', 72 'username_or_email_to_export', 73 __( 'Unable to export personal data. Username not recognized.' ), 74 'error' 75 ); 76 } else { 77 $doing_personal_data_export_for_email = $user->user_email; 78 } 79 } else { 80 $doing_personal_data_export_for_email = $username_or_email_address; 81 } 82 83 if ( ! empty( $doing_personal_data_export_for_email ) ) { 84 $title = __( 'Export Personal Data' ); 85 } 60 86 } 61 87 } 62 88 63 // If a privacy policy page ID is available, make sure the page actually exists. If not, display a warning 64 $privacy_policy_page_exists = false; 65 $privacy_policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); 89 if ( empty( $doing_personal_data_export_for_email ) ) { 90 // If a privacy policy page ID is available, make sure the page actually exists. If not, display a warning 91 $privacy_policy_page_exists = false; 92 $privacy_policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); 66 93 67 if ( ! empty( $privacy_policy_page_id ) ) {94 if ( ! empty( $privacy_policy_page_id ) ) { 68 95 $privacy_policy_page = get_post( $privacy_policy_page_id ); 69 96 if ( ! $privacy_policy_page instanceof WP_Post ) { 70 97 add_settings_error( … … 79 106 'page_for_privacy_policy', 80 107 'page_for_privacy_policy', 81 108 sprintf( 109 /* translators: URL to trashed pages list view */ 82 110 __( 'The currently selected privacy policy page is in the trash. Please create or select new privacy policy page or <a href="%s">restore the current page</a>.' ), 83 111 'edit.php?post_status=trash&post_type=page' 84 112 ), … … 88 116 $privacy_policy_page_exists = true; 89 117 } 90 118 } 91 }119 } 92 120 93 $title = __( 'Privacy Tools' ); 121 get_current_screen()->add_help_tab( array( 122 'id' => 'privacy', 123 'title' => __( 'Privacy' ), 124 'content' => '<p>' . __( 'This page provides tools with which you can manage your user\'s personal data and site\'s privacy policy.' ) . '</p>', 125 ) ); 94 126 95 get_current_screen()->add_help_tab( array(96 'id' => 'privacy',97 'title' => __( 'Privacy' ),98 'content' => '<p>' . __( 'This page provides tools with which you can manage your user\'s personal data and site\'s privacy policy.' ) . '</p>',99 ) ); 127 get_current_screen()->set_help_sidebar( 128 '<p><strong>' . __( 'For more information:' ) . '</strong></p>' . 129 '<p>' . __( '<a href="#">Documentation on privacy</a>' ) . '</p>' 130 ); 131 } 100 132 101 get_current_screen()->set_help_sidebar(102 '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .103 '<p>' . __( '<a href="#">Documentation on privacy</a>' ) . '</p>'104 );105 106 133 require_once( ABSPATH . 'wp-admin/admin-header.php' ); 107 134 108 135 ?> … … 109 136 <div class="wrap"> 110 137 <h1><?php echo esc_html( $title ); ?></h1> 111 138 <?php settings_errors(); ?> 139 <?php 112 140 113 <h2 class="title"><?php _e( 'Privacy policy page' ); ?></h2> 114 <table class="form-table"> 141 // If we have an email address, bootstrap the exporter 142 if ( ! empty( $doing_personal_data_export_for_email ) ) { 143 if ( $username_or_email_address === $doing_personal_data_export_for_email ) { 144 $heading = sprintf( 145 /* translators: An email address */ 146 __( 'Exporting personal data for %s' ), 147 $doing_personal_data_export_for_email 148 ); 149 } else { 150 $heading = sprintf( 151 /* translators: An email address and a username */ 152 __( 'Exporting personal data for %1$s (%2$s)' ), 153 $doing_personal_data_export_for_email, 154 $username_or_email_address 155 ); 156 } 157 ?> 158 <p> 159 <?php echo esc_html( $heading ); ?> 160 </p> 161 162 <div id="exporters-container"> 163 <ul id="exporter-list"> 164 </ul> 165 <table class="wp-list-table widefat striped" id="exported-data-table"> 166 <tr> 167 <th><?php _e( 'Name' ); ?></th> 168 <th><?php _e( 'Value' ); ?></th> 169 </tr> 170 </table> 171 </div> 172 115 173 <?php 174 // Build the array of exporters and emit it as an array accessible to javascript along with a nonce 175 $exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() ); 116 176 117 if ( $privacy_policy_page_exists ) { 118 $edit_href = add_query_arg( 119 array( 120 'post' => $privacy_policy_page_id, 121 'action' => 'edit', 122 ), 123 admin_url( 'post.php' ) 124 ); 125 $view_href = get_permalink( $privacy_policy_page_id ); 126 127 ?> 128 <tr> 129 <th colspan="2"> 130 <?php 131 printf( 132 __( '<a href="%1$s">Edit</a> or <a href="%2$s">view</a> your privacy policy.' ), 133 $edit_href, 134 $view_href 135 ); 136 ?> 137 </th> 138 </tr> 139 <?php 177 $exporter_names = array(); 178 foreach ( (array) $exporters as $exporter ) { 179 $exporter_names[] = $exporter['exporter_friendly_name']; 140 180 } 141 181 142 182 ?> 143 <tr> 144 <th scope="row"> 183 184 <!-- scripts for the exporter --> 185 186 <script> 187 ( function( $ ) { 188 $( document ).ready( function() { 189 var nonce = <?php echo json_encode( wp_create_nonce( 'wp-privacy-export-personal-data' ) ); ?>; 190 var exportForEmail = <?php echo json_encode( $doing_personal_data_export_for_email ); ?>; 191 var exporterNames = <?php echo json_encode( $exporter_names ); ?>; 192 var successMessage = "<?php echo esc_attr( __( 'Export completed successfully' ) ); ?>"; 193 var failureMessage = "<?php echo esc_attr( __( 'A failure occurred during export' ) ); ?>"; 194 195 function on_exports_done_success() { 196 $( '#exporters-container' ).append( '<p>' + successMessage + '</p>' ); 197 } 198 199 function on_export_failure( textStatus, error ) { 200 $( '#exporters-container' ).append( '<p>' + failureMessage + '</p>' ); 201 $( '#exporters-container' ).append( '<p>' + textStatus + '</p>' ); 202 } 203 204 function do_next_export( exporterIndex, pageIndex ) { 205 $.ajax( { 206 url: ajaxurl, 207 data: { 208 action: 'wp-privacy-export-personal-data', 209 email: exportForEmail, 210 exporter: exporterIndex, 211 page: pageIndex, 212 security: nonce, 213 }, 214 method: 'post' 215 } ).done( function( response ) { 216 var responseData = response.data; 217 for ( var dataIndex = 0; dataIndex < responseData.data.length; dataIndex++ ) { 218 $( '#exported-data-table' ).append( '<tr><td>' + responseData.data[ dataIndex ].name + '</td><td>' + responseData.data[ dataIndex ].value + '</td></tr>' ); 219 } 220 if ( ! responseData.done ) { 221 setTimeout( do_next_export( exporterIndex, pageIndex + 1 ) ); 222 } else { 223 if ( exporterIndex < exporterNames.length - 1 ) { 224 setTimeout( do_next_export( exporterIndex + 1, 0 ) ); 225 } else { 226 on_exports_done_success(); 227 } 228 } 229 } ).fail( function( jqxhr, textStatus, error ) { 230 on_export_failure( textStatus, error ); 231 } ); 232 } 233 234 // And now, let's begin 235 do_next_export( 0, 0 ); 236 } ) 237 } ) ( jQuery ); 238 </script> 239 240 <p> 241 <a href="privacy.php"><?php esc_html_e( 'Return to privacy tools' ); ?></a> 242 </p> 243 <?php 244 } else { 245 // No email address to export for? Then just display the privacy tools form table 246 ?> 247 <h2 class="title"><?php _e( 'Privacy policy page' ); ?></h2> 248 <table class="form-table"> 145 249 <?php 146 250 147 251 if ( $privacy_policy_page_exists ) { 148 _e( 'Select another page for your privacy policy' ); 149 } else { 150 _e( 'Select an existing privacy policy page' ); 252 $edit_href = add_query_arg( 253 array( 254 'post' => $privacy_policy_page_id, 255 'action' => 'edit', 256 ), 257 admin_url( 'post.php' ) 258 ); 259 $view_href = get_permalink( $privacy_policy_page_id ); 260 261 ?> 262 <tr> 263 <th colspan="2"> 264 <?php 265 printf( 266 /* translators: URL to edit the privacy policy page, URL to view the privacy policy page */ 267 __( '<a href="%1$s">Edit</a> or <a href="%2$s">view</a> your privacy policy.' ), 268 $edit_href, 269 $view_href 270 ); 271 ?> 272 </th> 273 </tr> 274 <?php 151 275 } 152 276 153 277 ?> 154 </th> 155 <td id="front-static-pages"> 156 <form method="post" action=""> 157 <?php wp_nonce_field( 'set-privacy-page' ); ?> 158 <input type="hidden" name="action" value="set-privacy-page" /> 159 <fieldset> 160 <legend class="screen-reader-text"><span><?php _e( 'Select your privacy policy page.' ); ?></span></legend> 161 <label for="page_for_privacy_policy"> 162 <?php wp_dropdown_pages( 163 array( 164 'name' => 'page_for_privacy_policy', 165 'show_option_none' => __( '— Select —' ), 166 'option_none_value' => '0', 167 'selected' => $privacy_policy_page_id, 168 'post_status' => array( 'draft', 'publish' ), 169 ) 170 ); 171 ?> 172 </label> 173 </fieldset> 174 <?php submit_button( __( 'Set Page' ) ); ?> 175 </form> 176 </td> 177 </tr> 178 <?php 278 <tr> 279 <th scope="row"> 280 <?php 179 281 180 if ( ! $privacy_policy_page_exists ) { 282 if ( $privacy_policy_page_exists ) { 283 _e( 'Select another page for your privacy policy' ); 284 } else { 285 _e( 'Select an existing privacy policy page' ); 286 } 287 288 ?> 289 </th> 290 <td id="privacy-policy-page"> 291 <form method="post" action=""> 292 <?php wp_nonce_field( 'set-privacy-page' ); ?> 293 <input type="hidden" name="action" value="set-privacy-page" /> 294 <fieldset> 295 <legend class="screen-reader-text"><span><?php _e( 'Select your privacy policy page.' ); ?></span></legend> 296 <label for="page_for_privacy_policy"> 297 <?php 298 wp_dropdown_pages( 299 array( 300 'name' => 'page_for_privacy_policy', 301 'show_option_none' => __( '— Select —' ), 302 'option_none_value' => '0', 303 'selected' => $privacy_policy_page_id, 304 'post_status' => array( 'draft', 'publish' ), 305 ) 306 ); 307 ?> 308 </label> 309 </fieldset> 310 <?php submit_button( __( 'Set Page' ) ); ?> 311 </form> 312 </td> 313 </tr> 314 <?php 315 316 if ( ! $privacy_policy_page_exists ) { 317 ?> 318 <tr> 319 <th scope="row"><?php _e( 'Create new page for your privacy policy' ); ?></th> 320 <td> 321 <form method="post" action=""> 322 <input type="hidden" name="action" value="create-privacy-page" /> 323 <?php wp_nonce_field( 'create-privacy-page' ); ?> 324 <?php submit_button( __( 'Create Page' ) ); ?> 325 </form> 326 </td> 327 </tr> 328 <?php 329 } 181 330 ?> 331 </table> 332 333 <h2 class="title"><?php _e( 'Personal Data Management' ); ?></h2> 334 <table class="form-table"> 182 335 <tr> 183 <th scope="row"><?php _e( ' Create new page for your privacy policy' ); ?></th>184 <td >336 <th scope="row"><?php _e( 'Export personal data' ); ?></th> 337 <td id="export-personal-data-form-container"> 185 338 <form method="post" action=""> 186 <input type="hidden" name="action" value="create-privacy-page" /> 187 <?php wp_nonce_field( 'create-privacy-page' ); ?> 188 <?php submit_button( __( 'Create Page' ) ); ?> 339 <input type="hidden" name="action" value="export-personal-data" /> 340 <?php wp_nonce_field( 'export-personal-data' ); ?> 341 <fieldset> 342 <legend class="screen-reader-text"><span><?php _e( 'Enter the username or email address of the user whose personal data you wish to export' ); ?></span></legend> 343 <label for="username_or_email_to_export"> 344 <input type="text" class="regular-text" name="username_or_email_to_export" /> 345 </label> 346 <p class="description"><?php _e( 'The username or email address of the user whose personal data you wish to export' ); ?></p> 347 </fieldset> 348 <?php submit_button( __( 'Begin Export' ) ); ?> 189 349 </form> 190 350 </td> 191 351 </tr> 192 <?php 193 } 194 195 ?> 196 </table> 352 </table> 353 <?php 354 } 355 ?> 197 356 </div> 198 357 199 358 <?php -
src/wp-includes/comment.php
3274 3274 3275 3275 return get_comment( $comment_id ); 3276 3276 } 3277 3278 /** 3279 * Registers the personal data exporter for comments 3280 * 3281 * @param array $exporters An array of personal data exporters. 3282 * @return array An array of personal data exporters. 3283 */ 3284 function wp_register_comment_personal_data_exporter( $exporters ) { 3285 $exporters[] = array( 3286 'exporter_friendly_name' => __( 'WordPress Comments' ), 3287 'callback' => 'wp_comments_personal_data_exporter', 3288 ); 3289 3290 return $exporters; 3291 } 3292 3293 /** 3294 * Finds and exports data which could be used to identify a person from comments assocated with an email address. 3295 * 3296 * @param string $email The comment author email address. 3297 * @param int $page Comment page, zero based. 3298 * @return array An array of personal data in name value pairs 3299 */ 3300 function wp_comments_personal_data_exporter( $email_address, $page ) { 3301 3302 $personal_data = array(); 3303 3304 // Technically, strtolower isn't necessary since get_comments will match email insensitive 3305 // But it is a good example for plugin developers whose targets might not be as generous 3306 $email_address = trim( strtolower( $email_address ) ); 3307 3308 // Limit us to 100 comments at a time to avoid timing out 3309 $number = 100; 3310 $offset = $number * (int) $page; 3311 3312 $comments = get_comments( 3313 array( 3314 'author_email' => $email_address, 3315 'number' => $number, 3316 'offset' => $offset, 3317 'order_by' => 'comment_ID', 3318 'order' => 'ASC', 3319 ) 3320 ); 3321 3322 $comment_personal_data_props = array( 3323 'comment_author' => __( 'Comment Author' ), 3324 'comment_author_email' => __( 'Comment Author Email' ), 3325 'comment_author_url' => __( 'Comment Author URL' ), 3326 'comment_author_IP' => __( 'Comment Author IP' ), 3327 'comment_agent' => __( 'Comment Agent' ), 3328 ); 3329 3330 foreach ( (array) $comments as $comment ) { 3331 foreach ( (array) $comment_personal_data_props as $key => $description ) { 3332 $value = $comment->$key; 3333 if ( ! empty( $value ) ) { 3334 /* translators: %1$d: ID of a comment, %2$s: Description of a comment field */ 3335 $name = sprintf( __( 'Comment %1$d : %2$s' ), $comment->comment_ID, $description ); 3336 $personal_data[] = array( 3337 'name' => $name, 3338 'value' => $value, 3339 ); 3340 } 3341 } 3342 } 3343 3344 $done = count( $comments ) <= 0; 3345 3346 return array( 3347 'data' => $personal_data, 3348 'done' => $done, 3349 ); 3350 } -
src/wp-includes/default-filters.php
328 328 add_action( 'do_pings', 'do_all_pings', 10, 1 ); 329 329 add_action( 'do_robots', 'do_robots' ); 330 330 add_action( 'set_comment_cookies', 'wp_set_comment_cookies', 10, 3 ); 331 add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_comment_personal_data_exporter', 10 ); 331 332 add_action( 'sanitize_comment_cookies', 'sanitize_comment_cookies' ); 332 333 add_action( 'admin_print_scripts', 'print_emoji_detection_script' ); 333 334 add_action( 'admin_print_scripts', 'print_head_scripts', 20 );