WordPress.org

Make WordPress Core

Changeset 43075


Ignore:
Timestamp:
05/02/2018 12:02:01 AM (18 months ago)
Author:
SergeyBiryukov
Message:

Privacy: add means to erase personal data by username or email address. First run.

Props allendav, coreymckrill, ericdaams, azaozz.
Merges [42986] to the 4.9 branch.
See #43637, #43602.

Location:
branches/4.9
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/4.9

  • branches/4.9/src/wp-admin/admin-ajax.php

    r43074 r43075  
    6767    'get-post-thumbnail-html', 'get-community-events', 'edit-theme-plugin-file',
    6868    'wp-privacy-export-personal-data',
     69    'wp-privacy-erase-personal-data',
    6970);
    7071
  • branches/4.9/src/wp-admin/includes/ajax-actions.php

    r43074 r43075  
    40204020
    40214021function wp_ajax_wp_privacy_export_personal_data() {
    4022 //  check_ajax_referer( 'wp-privacy-export-personal-data', 'security' );
     4022    check_ajax_referer( 'wp-privacy-export-personal-data', 'security' );
    40234023
    40244024    if ( ! current_user_can( 'manage_options' ) ) {
    4025         wp_send_json_error( 'access denied' );
     4025        wp_send_json_error( __( 'Error: Invalid request.' ) );
    40264026    }
    40274027
     
    40334033     * Filters the array of exporter callbacks.
    40344034     *
    4035      * @since 4.9.5.
     4035     * @since 4.9.6
    40364036     *
    40374037     * @param array $args {
     
    41214121     * Allows the export response to be consumed by destinations in addition to Ajax.
    41224122     *
    4123      * @since 4.9.5
     4123     * @since 4.9.6
    41244124     *
    41254125     * @param array  $response        The personal data for the given exporter and page.
     
    41354135    wp_send_json_success( $response );
    41364136}
     4137
     4138/**
     4139 * Ajax handler for erasing personal data.
     4140 *
     4141 * @since 4.9.6
     4142 */
     4143function wp_ajax_wp_privacy_erase_personal_data() {
     4144    $request_id  = (int) $_POST['id'];
     4145
     4146    if ( empty( $request_id ) ) {
     4147        wp_send_json_error( __( 'Error: Invalid request ID.' ) );
     4148    }
     4149
     4150    if ( ! current_user_can( 'delete_users' ) ) {
     4151        wp_send_json_error( __( 'Error: Invalid request.' ) );
     4152    }
     4153
     4154    check_ajax_referer( 'wp-privacy-erase-personal-data-' . $request_id, 'security' );
     4155
     4156    // Find the request CPT
     4157    $request = get_post( $request_id );
     4158    if ( 'user_remove_request' !== $request->post_type ) {
     4159        wp_send_json_error( __( 'Error: Invalid request ID.' ) );
     4160    }
     4161
     4162    $email_address = get_post_meta( $request_id, '_user_email', true );
     4163
     4164    if ( ! is_email( $email_address ) ) {
     4165        wp_send_json_error( __( 'Error: Invalid email address in request.' ) );
     4166    }
     4167
     4168    $eraser_index = (int) $_POST['eraser'];
     4169    $page         = (int) $_POST['page'];
     4170
     4171    /**
     4172     * Filters the array of personal data eraser callbacks.
     4173     *
     4174     * @since 4.9.6
     4175     *
     4176     * @param array $args {
     4177     *     An array of callable erasers of personal data. Default empty array.
     4178     *     [
     4179     *         callback             string Callable eraser that accepts an email address and
     4180     *                                     a page and returns an array with the number of items
     4181     *                                     removed, the number of items retained and any messages
     4182     *                                     from the eraser, as well as if additional pages are
     4183     *                                     available.
     4184     *         eraser_friendly_name string Translated user facing friendly name for the eraser.
     4185     *     ]
     4186     * }
     4187     */
     4188    $erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );
     4189
     4190    // Do we have any registered erasers?
     4191    if ( 0 < count( $erasers ) ) {
     4192        if ( $eraser_index < 1 ) {
     4193            wp_send_json_error( __( 'Error: Eraser index cannot be less than one.' ) );
     4194        }
     4195
     4196        if ( $eraser_index > count( $erasers ) ) {
     4197            wp_send_json_error( __( 'Error: Eraser index is out of range.' ) );
     4198        }
     4199
     4200        if ( $page < 1 ) {
     4201            wp_send_json_error( __( 'Error: Page index cannot be less than one.' ) );
     4202        }
     4203
     4204        $index = $eraser_index - 1; // Convert to zero based for eraser index
     4205        $eraser = $erasers[ $index ];
     4206        if ( ! is_array( $eraser ) ) {
     4207            wp_send_json_error(
     4208                sprintf(
     4209                    __( 'Error: Expected an array describing the eraser at index %d.' ),
     4210                    $eraser_index
     4211                )
     4212            );
     4213        }
     4214        if ( ! array_key_exists( 'callback', $eraser ) ) {
     4215            wp_send_json_error(
     4216                sprintf(
     4217                    __( 'Error: Eraser array at index %d does not include a callback.' ),
     4218                    $eraser_index
     4219                )
     4220            );
     4221        }
     4222        if ( ! is_callable( $eraser['callback'] ) ) {
     4223            wp_send_json_error(
     4224                sprintf(
     4225                    __( 'Error: Eraser callback at index %d is not a valid callback.' ),
     4226                    $eraser_index
     4227                )
     4228            );
     4229        }
     4230        if ( ! array_key_exists( 'eraser_friendly_name', $eraser ) ) {
     4231            wp_send_json_error(
     4232                sprintf(
     4233                    __( 'Error: Eraser array at index %d does not include a friendly name.' ),
     4234                    $eraser_index
     4235                )
     4236            );
     4237        }
     4238
     4239        $callback = $erasers[ $index ]['callback'];
     4240        $eraser_friendly_name = $erasers[ $index ]['eraser_friendly_name'];
     4241
     4242        $response = call_user_func( $callback, $email_address, $page );
     4243        if ( is_wp_error( $response ) ) {
     4244            wp_send_json_error( $response );
     4245        }
     4246
     4247        if ( ! is_array( $response ) ) {
     4248            wp_send_json_error(
     4249                sprintf(
     4250                    __( 'Error: Did not receive array from %s eraser (index %d).' ),
     4251                    $eraser_friendly_name,
     4252                    $eraser_index
     4253                )
     4254            );
     4255        }
     4256        if ( ! array_key_exists( 'num_items_removed', $response ) ) {
     4257            wp_send_json_error(
     4258                sprintf(
     4259                    __( 'Error: Expected num_items_removed key in response array from %s eraser (index %d).' ),
     4260                    $eraser_friendly_name,
     4261                    $eraser_index
     4262                )
     4263            );
     4264        }
     4265        if ( ! array_key_exists( 'num_items_retained', $response ) ) {
     4266            wp_send_json_error(
     4267                sprintf(
     4268                    __( 'Error: Expected num_items_retained key in response array from %s eraser (index %d).' ),
     4269                    $eraser_friendly_name,
     4270                    $eraser_index
     4271                )
     4272            );
     4273        }
     4274        if ( ! array_key_exists( 'messages', $response ) ) {
     4275            wp_send_json_error(
     4276                sprintf(
     4277                    __( 'Error: Expected messages key in response array from %s eraser (index %d).' ),
     4278                    $eraser_friendly_name,
     4279                    $eraser_index
     4280                )
     4281            );
     4282        }
     4283        if ( ! is_array( $response['messages'] ) ) {
     4284            wp_send_json_error(
     4285                sprintf(
     4286                    __( 'Error: Expected messages key to reference an array in response array from %s eraser (index %d).' ),
     4287                    $eraser_friendly_name,
     4288                    $eraser_index
     4289                )
     4290            );
     4291        }
     4292        if ( ! array_key_exists( 'done', $response ) ) {
     4293            wp_send_json_error(
     4294                sprintf(
     4295                    __( 'Error: Expected done flag in response array from %s eraser (index %d).' ),
     4296                    $eraser_friendly_name,
     4297                    $eraser_index
     4298                )
     4299            );
     4300        }
     4301    } else {
     4302        // No erasers, so we're done
     4303        $response = array(
     4304            'num_items_removed' => 0,
     4305            'num_items_retained' => 0,
     4306            'messages' => array(),
     4307            'done' => true,
     4308        );
     4309    }
     4310
     4311    /**
     4312     * Filters a page of personal data eraser data.
     4313     *
     4314     * Allows the erasure response to be consumed by destinations in addition to Ajax.
     4315     *
     4316     * @since 4.9.6
     4317     *
     4318     * @param array  $response        The personal data for the given exporter and page.
     4319     * @param int    $exporter_index  The index of the exporter that provided this data.
     4320     * @param string $email_address   The email address associated with this personal data.
     4321     * @param int    $page            The zero-based page for this response.
     4322     * @param int    $request_id      The privacy request post ID associated with this request.
     4323     */
     4324    $response = apply_filters( 'wp_privacy_personal_data_erasure_page', $response, $eraser_index, $email_address, $page, $request_id );
     4325    if ( is_wp_error( $response ) ) {
     4326        wp_send_json_error( $response );
     4327    }
     4328
     4329    wp_send_json_success( $response );
     4330}
  • branches/4.9/src/wp-admin/includes/user.php

    r43073 r43075  
    543543 * Get action description from the name.
    544544 *
    545  * @since 5.0.0
     545 * @since 4.9.6
    546546 * @access private
    547547 *
     
    560560 * Log a request and send to the user.
    561561 *
    562  * @since 5.0.0
     562 * @since 4.9.6
    563563 * @access private
    564564 *
     
    600600 * Resend an existing request and return the result.
    601601 *
    602  * @since 5.0.0
     602 * @since 4.9.6
    603603 * @access private
    604604 *
     
    640640 * Marks a request as completed by the admin and logs the datetime.
    641641 *
    642  * @since 5.0.0
     642 * @since 4.9.6
    643643 * @access private
    644644 *
     
    665665 * Handle list table actions.
    666666 *
    667  * @since 5.0.0
     667 * @since 4.9.6
    668668 * @access private
    669669 */
    670670function _wp_personal_data_handle_actions() {
    671     if ( isset( $_POST['export_personal_data_email_retry'] ) ) { // WPCS: input var ok.
     671    if ( isset( $_POST['privacy_action_email_retry'] ) ) { // WPCS: input var ok.
    672672        check_admin_referer( 'bulk-privacy_requests' );
    673673
    674         $request_id = absint( current( array_keys( (array) wp_unslash( $_POST['export_personal_data_email_retry'] ) ) ) ); // WPCS: input var ok, sanitization ok.
     674        $request_id = absint( current( array_keys( (array) wp_unslash( $_POST['privacy_action_email_retry'] ) ) ) ); // WPCS: input var ok, sanitization ok.
    675675        $result     = _wp_privacy_resend_request( $request_id );
    676676
    677677        if ( is_wp_error( $result ) ) {
    678678            add_settings_error(
    679                 'export_personal_data_email_retry',
    680                 'export_personal_data_email_retry',
     679                'privacy_action_email_retry',
     680                'privacy_action_email_retry',
    681681                $result->get_error_message(),
    682682                'error'
     
    684684        } else {
    685685            add_settings_error(
    686                 'export_personal_data_email_retry',
    687                 'export_personal_data_email_retry',
     686                'privacy_action_email_retry',
     687                'privacy_action_email_retry',
    688688                __( 'Confirmation request re-resent successfully.' ),
    689689                'updated'
     
    797797 * Personal data export.
    798798 *
    799  * @since 5.0.0
     799 * @since 4.9.6
    800800 * @access private
    801801 */
     
    858858 * Personal data anonymization.
    859859 *
    860  * @since 5.0.0
     860 * @since 4.9.6
    861861 * @access private
    862862 */
    863863function _wp_personal_data_removal_page() {
    864     if ( ! current_user_can( 'manage_options' ) ) {
     864    if ( ! current_user_can( 'delete_users' ) ) {
    865865        wp_die( esc_html__( 'Sorry, you are not allowed to manage privacy on this site.' ) );
    866866    }
    867867
    868868    _wp_personal_data_handle_actions();
     869
     870    // "Borrow" xfn.js for now so we don't have to create new files.
     871    wp_enqueue_script( 'xfn' );
    869872
    870873    $requests_table = new WP_Privacy_Data_Removal_Requests_Table( array(
     
    872875        'singular' => 'privacy_request',
    873876    ) );
     877
    874878    $requests_table->process_bulk_action();
    875879    $requests_table->prepare_items();
     880
    876881    ?>
    877882    <div class="wrap nosubsub">
     
    919924 * Add requests pages.
    920925 *
    921  * @since 5.0.0
     926 * @since 4.9.6
    922927 * @access private
    923928 */
     
    942947     * e.g. 'export_personal_data'
    943948     *
    944      * @since 5.0.0
     949     * @since 4.9.6
    945950     *
    946951     * @var string $request_type Name of action.
     
    951956     * Post type to be used.
    952957     *
    953      * @since 5.0.0
     958     * @since 4.9.6
    954959     *
    955960     * @var string $post_type The post type.
     
    960965     * Get columns to show in the list table.
    961966     *
    962      * @since 5.0.0
     967     * @since 4.9.6
    963968     *
    964969     * @param array Array of columns.
     
    978983     * Get a list of sortable columns.
    979984     *
    980      * @since 5.0.0
     985     * @since 4.9.6
    981986     *
    982987     * @return array
     
    989994     * Default primary column.
    990995     *
    991      * @since 5.0.0
     996     * @since 4.9.6
    992997     *
    993998     * @return string
     
    10011006     * of views available on this table.
    10021007     *
    1003      * @since 5.0.0
     1008     * @since 4.9.6
    10041009     *
    10051010     * @return array
     
    10261031     * Get bulk actions.
    10271032     *
    1028      * @since 5.0.0
     1033     * @since 4.9.6
    10291034     *
    10301035     * @return array
     
    10401045     * Process bulk actions.
    10411046     *
    1042      * @since 5.0.0
     1047     * @since 4.9.6
    10431048     */
    10441049    public function process_bulk_action() {
     
    10891094     * Prepare items to output.
    10901095     *
    1091      * @since 5.0.0
     1096     * @since 4.9.6
    10921097     */
    10931098    public function prepare_items() {
     
    11541159     * Checkbox column.
    11551160     *
    1156      * @since 5.0.0
     1161     * @since 4.9.6
    11571162     *
    11581163     * @param array $item Item being shown.
     
    11661171     * Status column.
    11671172     *
    1168      * @since 5.0.0
     1173     * @since 4.9.6
    11691174     *
    11701175     * @param array $item Item being shown.
     
    12031208     * Convert timestamp for display.
    12041209     *
    1205      * @since 5.0.0
     1210     * @since 4.9.6
    12061211     *
    12071212     * @param int $timestamp Event timestamp.
     
    12251230     * Default column handler.
    12261231     *
    1227      * @since 5.0.0
     1232     * @since 4.9.6
    12281233     *
    12291234     * @param array $item         Item being shown.
     
    12441249     * Actions column. Overriden by children.
    12451250     *
    1246      * @since 5.0.0
     1251     * @since 4.9.6
    12471252     *
    12481253     * @param array $item Item being shown.
     
    12561261     * Next steps column. Overriden by children.
    12571262     *
    1258      * @since 5.0.0
     1263     * @since 4.9.6
    12591264     *
    12601265     * @param array $item Item being shown.
     
    12651270     * Generates content for a single row of the table
    12661271     *
    1267      * @since 5.0.0
     1272     * @since 4.9.6
    12681273     *
    12691274     * @param object $item The current item
     
    12801285     * Embed scripts used to perform actions. Overriden by children.
    12811286     *
    1282      * @since 5.0.0
     1287     * @since 4.9.6
    12831288     */
    12841289    public function embed_scripts() {}
     
    12881293 * WP_Privacy_Data_Export_Requests_Table class.
    12891294 *
    1290  * @since 5.0.0
     1295 * @since 4.9.6
    12911296 */
    12921297class WP_Privacy_Data_Export_Requests_Table extends WP_Privacy_Requests_Table {
     
    12941299     * Action name for the requests this table will work with.
    12951300     *
    1296      * @since 5.0.0
     1301     * @since 4.9.6
    12971302     *
    12981303     * @var string $request_type Name of action.
     
    13031308     * Post type for the requests.
    13041309     *
    1305      * @since 5.0.0
     1310     * @since 4.9.6
    13061311     *
    13071312     * @var string $post_type The post type.
     
    13121317     * Actions column.
    13131318     *
    1314      * @since 5.0.0
     1319     * @since 4.9.6
    13151320     *
    13161321     * @param array $item Item being shown.
     
    13181323     */
    13191324    public function column_email( $item ) {
     1325        $exporters       = apply_filters( 'wp_privacy_personal_data_exporters', array() );
     1326        $exporters_count = count( $exporters );
     1327        $request_id      = $item['request_id'];
     1328        $nonce           = wp_create_nonce( 'wp-privacy-export-personal-data-' . $request_id );
     1329
     1330        $download_data_markup = '<div class="download_personal_data" ' .
     1331            'data-exporters-count="' . esc_attr( $exporters_count ) . '" ' .
     1332            'data-request-id="' . esc_attr( $request_id ) . '" ' .
     1333            'data-nonce="' . esc_attr( $nonce ) .
     1334            '">';
     1335
     1336        $download_data_markup .= '<span class="download_personal_data_idle"><a href="#" >' . __( 'Download Personal Data' ) . '</a></span>' .
     1337            '<span style="display:none" class="download_personal_data_processing" >' . __( 'Downloading Data...' ) . '</span>' .
     1338            '<span style="display:none" class="download_personal_data_failed">' . __( 'Download Failed!' ) . ' <a href="#" >' . __( 'Retry' ) . '</a></span>';
     1339
    13201340        $row_actions = array(
    1321             'download_data' => __( 'Download Personal Data' ),
     1341            'download_data' => $download_data_markup,
    13221342        );
    13231343
     
    13281348     * Next steps column.
    13291349     *
    1330      * @since 5.0.0
     1350     * @since 4.9.6
    13311351     *
    13321352     * @param array $item Item being shown.
     
    13431363                break;
    13441364            case 'request-failed':
    1345                 submit_button( __( 'Retry' ), 'secondary', 'export_personal_data_email_retry[' . $item['request_id'] . ']', false );
     1365                submit_button( __( 'Retry' ), 'secondary', 'privacy_action_email_retry[' . $item['request_id'] . ']', false );
    13461366                break;
    13471367            case 'request-completed':
     
    13581378 * WP_Privacy_Data_Removal_Requests_Table class.
    13591379 *
    1360      * @since 5.0.0
     1380     * @since 4.9.6
    13611381 */
    13621382class WP_Privacy_Data_Removal_Requests_Table extends WP_Privacy_Requests_Table {
     
    13641384     * Action name for the requests this table will work with.
    13651385     *
    1366      * @since 5.0.0
     1386     * @since 4.9.6
    13671387     *
    13681388     * @var string $request_type Name of action.
     
    13731393     * Post type for the requests.
    13741394     *
    1375      * @since 5.0.0
     1395     * @since 4.9.6
    13761396     *
    13771397     * @var string $post_type The post type.
     
    13821402     * Actions column.
    13831403     *
    1384      * @since 5.0.0
     1404     * @since 4.9.6
    13851405     *
    13861406     * @param array $item Item being shown.
     
    13881408     */
    13891409    public function column_email( $item ) {
    1390         $row_actions = array(
    1391             // TODO Complete in follow on patch.
    1392             'remove_data' => __( 'Remove Personal Data' ),
    1393         );
    1394 
    1395         // If we have a user ID, include a delete user action.
    1396         if ( ! empty( $item['user_id'] ) ) {
    1397             // TODO Complete in follow on patch.
    1398             $row_actions['delete_user'] = __( 'Delete User' );
     1410        $row_actions = array();
     1411
     1412        // Allow the administrator to "force remove" the personal data even if confirmation has not yet been received
     1413        $status = get_post_status( $item['request_id'] );
     1414        if ( 'request-confirmed' !== $status ) {
     1415            $erasers       = apply_filters( 'wp_privacy_personal_data_erasers', array() );
     1416            $erasers_count = count( $erasers );
     1417            $request_id    = $item['request_id'];
     1418            $nonce         = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
     1419
     1420            $remove_data_markup = '<div class="remove_personal_data force_remove_personal_data" ' .
     1421                'data-erasers-count="' . esc_attr( $erasers_count ) . '" ' .
     1422                'data-request-id="' . esc_attr( $request_id ) . '" ' .
     1423                'data-nonce="' . esc_attr( $nonce ) .
     1424                '">';
     1425
     1426            $remove_data_markup .= '<span class="remove_personal_data_idle"><a href="#" >' . __( 'Force Remove Personal Data' ) . '</a></span>' .
     1427                '<span style="display:none" class="remove_personal_data_processing" >' . __( 'Removing Data...' ) . '</span>' .
     1428                '<span style="display:none" class="remove_personal_data_failed">' . __( 'Force Remove Failed!' ) . ' <a href="#" >' . __( 'Retry' ) . '</a></span>';
     1429
     1430            $row_actions = array(
     1431                'remove_data' => $remove_data_markup,
     1432            );
    13991433        }
    14001434
     
    14051439     * Next steps column.
    14061440     *
    1407      * @since 5.0.0
     1441     * @since 4.9.6
    14081442     *
    14091443     * @param array $item Item being shown.
    14101444     */
    14111445    public function column_next_steps( $item ) {
    1412     }
    1413 
    1414 }
     1446        $status = get_post_status( $item['request_id'] );
     1447
     1448        switch ( $status ) {
     1449            case 'request-pending':
     1450                esc_html_e( 'Waiting for confirmation' );
     1451                break;
     1452            case 'request-confirmed':
     1453                $erasers       = apply_filters( 'wp_privacy_personal_data_erasers', array() );
     1454                $erasers_count = count( $erasers );
     1455                $request_id    = $item['request_id'];
     1456                $nonce         = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
     1457
     1458                echo '<div class="remove_personal_data" ' .
     1459                    'data-force-erase="1" ' .
     1460                    'data-erasers-count="' . esc_attr( $erasers_count ) . '" ' .
     1461                    'data-request-id="' . esc_attr( $request_id ) . '" ' .
     1462                    'data-nonce="' . esc_attr( $nonce ) .
     1463                    '">';
     1464
     1465                ?>
     1466                <span class="remove_personal_data_idle"><a class="button" href="#" ><?php _e( 'Remove Personal Data' ); ?></a></span>
     1467                <span style="display:none" class="remove_personal_data_processing button updating-message" ><?php _e( 'Removing Data...' ); ?></span>
     1468                <span style="display:none" class="remove_personal_data_failed"><?php _e( 'Removing Data Failed!' ); ?> <a class="button" href="#" ><?php _e( 'Retry' ); ?></a></span>
     1469                <?php
     1470
     1471                break;
     1472            case 'request-failed':
     1473                submit_button( __( 'Retry' ), 'secondary', 'privacy_action_email_retry[' . $item['request_id'] . ']', false );
     1474                break;
     1475            case 'request-completed':
     1476                echo '<a href="' . esc_url( wp_nonce_url( add_query_arg( array(
     1477                    'action' => 'delete',
     1478                    'request_id' => array( $item['request_id'] ),
     1479                ), admin_url( 'tools.php?page=remove_personal_data' ) ), 'bulk-privacy_requests' ) ) . '">' . esc_html__( 'Remove request' ) . '</a>';
     1480                break;
     1481        }
     1482    }
     1483
     1484}
  • branches/4.9/src/wp-admin/js/xfn.js

    r26174 r43075  
    1616    });
    1717});
     18
     19// Privacy request action handling
     20
     21jQuery( document ).ready( function( $ ) {
     22    var strings = window.privacyToolsL10n || {};
     23
     24    function set_action_state( $action, state ) {
     25        $action.children().hide();
     26        $action.children( '.' + state ).show();
     27    }
     28
     29    function clearResultsAfterRow( $requestRow ) {
     30        if ( $requestRow.next().hasClass( 'request-results' ) ) {
     31            $requestRow.next().remove();
     32        }
     33    }
     34
     35    function appendResultsAfterRow( $requestRow, classes, summaryMessage, additionalMessages ) {
     36        clearResultsAfterRow( $requestRow );
     37        if ( additionalMessages.length ) {
     38            // TODO - render additionalMessages after the summaryMessage
     39        }
     40
     41        $requestRow.after( function() {
     42            return '<tr class="request-results"><td colspan="5"><div class="notice inline notice-alt ' + classes + '"><p>' +
     43                summaryMessage +
     44                '</p></div></td></tr>';
     45        } );
     46    }
     47
     48    $( '.remove_personal_data a' ).click( function( event ) {
     49        event.preventDefault();
     50        event.stopPropagation();
     51
     52        var $this         = $( this );
     53        var $action       = $this.parents( '.remove_personal_data' );
     54        var $requestRow   = $this.parents( 'tr' );
     55        var requestID     = $action.data( 'request-id' );
     56        var nonce         = $action.data( 'nonce' );
     57        var erasersCount  = $action.data( 'erasers-count' );
     58
     59        var removedCount  = 0;
     60        var retainedCount = 0;
     61        var messages      = [];
     62
     63        $action.blur();
     64        clearResultsAfterRow( $requestRow );
     65
     66        function on_erasure_done_success() {
     67            set_action_state( $action, 'remove_personal_data_idle' );
     68            var summaryMessage = strings.noDataFound;
     69            var classes = 'notice-success';
     70            if ( 0 == removedCount ) {
     71                if ( 0 == retainedCount ) {
     72                    summaryMessage = strings.noDataFound;
     73                } else {
     74                    summaryMessage = strings.noneRemoved;
     75                    classes = 'notice-warning';
     76                }
     77            } else {
     78                if ( 0 == retainedCount ) {
     79                    summaryMessage = strings.foundAndRemoved;
     80                } else {
     81                    summaryMessage = strings.someNotRemoved;
     82                    classes = 'notice-warning';
     83                }
     84            }
     85            appendResultsAfterRow( $requestRow, 'notice-success', summaryMessage, [] );
     86        }
     87
     88        function on_erasure_failure( textStatus, error ) {
     89            set_action_state( $action, 'remove_personal_data_failed' );
     90            appendResultsAfterRow( $requestRow, 'notice-error', strings.anErrorOccurred, [] );
     91        }
     92
     93        function do_next_erasure( eraserIndex, pageIndex ) {
     94            $.ajax( {
     95                url: ajaxurl,
     96                data: {
     97                    action: 'wp-privacy-erase-personal-data',
     98                    eraser: eraserIndex,
     99                    id: requestID,
     100                    page: pageIndex,
     101                    security: nonce,
     102                },
     103                method: 'post'
     104            } ).done( function( response ) {
     105                if ( ! response.success ) {
     106                    on_erasure_failure( 'error', response.data );
     107                    return;
     108                }
     109                var responseData = response.data;
     110                if ( responseData.num_items_removed ) {
     111                    removedCount += responseData.num_items_removed;
     112                }
     113                if ( responseData.num_items_retained ) {
     114                    retainedCount += responseData.num_items_removed;
     115                }
     116                if ( responseData.messages ) {
     117                    messages = messages.concat( responseData.messages );
     118                }
     119                if ( ! responseData.done ) {
     120                    setTimeout( do_next_erasure( eraserIndex, pageIndex + 1 ) );
     121                } else {
     122                    if ( eraserIndex < erasersCount ) {
     123                        setTimeout( do_next_erasure( eraserIndex + 1, 1 ) );
     124                    } else {
     125                        on_erasure_done_success();
     126                    }
     127                }
     128            } ).fail( function( jqxhr, textStatus, error ) {
     129                on_erasure_failure( textStatus, error );
     130            } );
     131        }
     132
     133        // And now, let's begin
     134        set_action_state( $action, 'remove_personal_data_processing' );
     135
     136        do_next_erasure( 1, 1 );
     137    } )
     138} );
  • branches/4.9/src/wp-includes/script-loader.php

    r42811 r43075  
    660660
    661661        $scripts->add( 'xfn', "/wp-admin/js/xfn$suffix.js", array('jquery'), false, 1 );
     662        did_action( 'init' ) && $scripts->localize(
     663            'xfn', 'privacyToolsL10n', array(
     664                'noDataFound'     => __( 'No personal data was found for this user.' ),
     665                'foundAndRemoved' => __( 'All of the personal data found for this user was removed.' ),
     666                'noneRemoved'     => __( 'Personal data was found for this user but was not removed.' ),
     667                'someNotRemoved'  => __( 'Personal data was found for this user but some of the personal data found was not removed.' ),
     668                'anErrorOccurred' => __( 'An error occurred while attempting to find and remove personal data.' ),
     669            )
     670        );
    662671
    663672        $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array('jquery-ui-sortable'), false, 1 );
Note: See TracChangeset for help on using the changeset viewer.