WordPress.org

Make WordPress Core

Changeset 42986


Ignore:
Timestamp:
04/18/2018 10:29:59 PM (16 months ago)
Author:
azaozz
Message:

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

Props allendav, coreymckrill, ericdaams, azaozz.
See #43637, #43602.

Location:
trunk/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/admin-ajax.php

    r42889 r42986  
    131131    'edit-theme-plugin-file',
    132132    'wp-privacy-export-personal-data',
     133    'wp-privacy-erase-personal-data',
    133134);
    134135
  • trunk/src/wp-admin/includes/ajax-actions.php

    r42889 r42986  
    43294329
    43304330function wp_ajax_wp_privacy_export_personal_data() {
    4331 //  check_ajax_referer( 'wp-privacy-export-personal-data', 'security' );
     4331    check_ajax_referer( 'wp-privacy-export-personal-data', 'security' );
    43324332
    43334333    if ( ! current_user_can( 'manage_options' ) ) {
    4334         wp_send_json_error( 'access denied' );
     4334        wp_send_json_error( __( 'Error: Invalid request.' ) );
    43354335    }
    43364336
     
    43424342     * Filters the array of exporter callbacks.
    43434343     *
    4344      * @since 4.9.5.
     4344     * @since 4.9.6
    43454345     *
    43464346     * @param array $args {
     
    44304430     * Allows the export response to be consumed by destinations in addition to Ajax.
    44314431     *
    4432      * @since 4.9.5
     4432     * @since 4.9.6
    44334433     *
    44344434     * @param array  $response        The personal data for the given exporter and page.
     
    44444444    wp_send_json_success( $response );
    44454445}
     4446
     4447/**
     4448 * Ajax handler for erasing personal data.
     4449 *
     4450 * @since 4.9.6
     4451 */
     4452function wp_ajax_wp_privacy_erase_personal_data() {
     4453    $request_id  = (int) $_POST['id'];
     4454
     4455    if ( empty( $request_id ) ) {
     4456        wp_send_json_error( __( 'Error: Invalid request ID.' ) );
     4457    }
     4458
     4459    if ( ! current_user_can( 'delete_users' ) ) {
     4460        wp_send_json_error( __( 'Error: Invalid request.' ) );
     4461    }
     4462
     4463    check_ajax_referer( 'wp-privacy-erase-personal-data-' . $request_id, 'security' );
     4464
     4465    // Find the request CPT
     4466    $request = get_post( $request_id );
     4467    if ( 'user_remove_request' !== $request->post_type ) {
     4468        wp_send_json_error( __( 'Error: Invalid request ID.' ) );
     4469    }
     4470
     4471    $email_address = get_post_meta( $request_id, '_user_email', true );
     4472
     4473    if ( ! is_email( $email_address ) ) {
     4474        wp_send_json_error( __( 'Error: Invalid email address in request.' ) );
     4475    }
     4476
     4477    $eraser_index = (int) $_POST['eraser'];
     4478    $page         = (int) $_POST['page'];
     4479
     4480    /**
     4481     * Filters the array of personal data eraser callbacks.
     4482     *
     4483     * @since 4.9.6
     4484     *
     4485     * @param array $args {
     4486     *     An array of callable erasers of personal data. Default empty array.
     4487     *     [
     4488     *         callback             string Callable eraser that accepts an email address and
     4489     *                                     a page and returns an array with the number of items
     4490     *                                     removed, the number of items retained and any messages
     4491     *                                     from the eraser, as well as if additional pages are
     4492     *                                     available.
     4493     *         eraser_friendly_name string Translated user facing friendly name for the eraser.
     4494     *     ]
     4495     * }
     4496     */
     4497    $erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );
     4498
     4499    // Do we have any registered erasers?
     4500    if ( 0 < count( $erasers ) ) {
     4501        if ( $eraser_index < 1 ) {
     4502            wp_send_json_error( __( 'Error: Eraser index cannot be less than one.' ) );
     4503        }
     4504
     4505        if ( $eraser_index > count( $erasers ) ) {
     4506            wp_send_json_error( __( 'Error: Eraser index is out of range.' ) );
     4507        }
     4508
     4509        if ( $page < 1 ) {
     4510            wp_send_json_error( __( 'Error: Page index cannot be less than one.' ) );
     4511        }
     4512
     4513        $index = $eraser_index - 1; // Convert to zero based for eraser index
     4514        $eraser = $erasers[ $index ];
     4515        if ( ! is_array( $eraser ) ) {
     4516            wp_send_json_error(
     4517                sprintf(
     4518                    __( 'Error: Expected an array describing the eraser at index %d.' ),
     4519                    $eraser_index
     4520                )
     4521            );
     4522        }
     4523        if ( ! array_key_exists( 'callback', $eraser ) ) {
     4524            wp_send_json_error(
     4525                sprintf(
     4526                    __( 'Error: Eraser array at index %d does not include a callback.' ),
     4527                    $eraser_index
     4528                )
     4529            );
     4530        }
     4531        if ( ! is_callable( $eraser['callback'] ) ) {
     4532            wp_send_json_error(
     4533                sprintf(
     4534                    __( 'Error: Eraser callback at index %d is not a valid callback.' ),
     4535                    $eraser_index
     4536                )
     4537            );
     4538        }
     4539        if ( ! array_key_exists( 'eraser_friendly_name', $eraser ) ) {
     4540            wp_send_json_error(
     4541                sprintf(
     4542                    __( 'Error: Eraser array at index %d does not include a friendly name.' ),
     4543                    $eraser_index
     4544                )
     4545            );
     4546        }
     4547
     4548        $callback = $erasers[ $index ]['callback'];
     4549        $eraser_friendly_name = $erasers[ $index ]['eraser_friendly_name'];
     4550
     4551        $response = call_user_func( $callback, $email_address, $page );
     4552        if ( is_wp_error( $response ) ) {
     4553            wp_send_json_error( $response );
     4554        }
     4555
     4556        if ( ! is_array( $response ) ) {
     4557            wp_send_json_error(
     4558                sprintf(
     4559                    __( 'Error: Did not receive array from %s eraser (index %d).' ),
     4560                    $eraser_friendly_name,
     4561                    $eraser_index
     4562                )
     4563            );
     4564        }
     4565        if ( ! array_key_exists( 'num_items_removed', $response ) ) {
     4566            wp_send_json_error(
     4567                sprintf(
     4568                    __( 'Error: Expected num_items_removed key in response array from %s eraser (index %d).' ),
     4569                    $eraser_friendly_name,
     4570                    $eraser_index
     4571                )
     4572            );
     4573        }
     4574        if ( ! array_key_exists( 'num_items_retained', $response ) ) {
     4575            wp_send_json_error(
     4576                sprintf(
     4577                    __( 'Error: Expected num_items_retained key in response array from %s eraser (index %d).' ),
     4578                    $eraser_friendly_name,
     4579                    $eraser_index
     4580                )
     4581            );
     4582        }
     4583        if ( ! array_key_exists( 'messages', $response ) ) {
     4584            wp_send_json_error(
     4585                sprintf(
     4586                    __( 'Error: Expected messages key in response array from %s eraser (index %d).' ),
     4587                    $eraser_friendly_name,
     4588                    $eraser_index
     4589                )
     4590            );
     4591        }
     4592        if ( ! is_array( $response['messages'] ) ) {
     4593            wp_send_json_error(
     4594                sprintf(
     4595                    __( 'Error: Expected messages key to reference an array in response array from %s eraser (index %d).' ),
     4596                    $eraser_friendly_name,
     4597                    $eraser_index
     4598                )
     4599            );
     4600        }
     4601        if ( ! array_key_exists( 'done', $response ) ) {
     4602            wp_send_json_error(
     4603                sprintf(
     4604                    __( 'Error: Expected done flag in response array from %s eraser (index %d).' ),
     4605                    $eraser_friendly_name,
     4606                    $eraser_index
     4607                )
     4608            );
     4609        }
     4610    } else {
     4611        // No erasers, so we're done
     4612        $response = array(
     4613            'num_items_removed' => 0,
     4614            'num_items_retained' => 0,
     4615            'messages' => array(),
     4616            'done' => true,
     4617        );
     4618    }
     4619
     4620    /**
     4621     * Filters a page of personal data eraser data.
     4622     *
     4623     * Allows the erasure response to be consumed by destinations in addition to Ajax.
     4624     *
     4625     * @since 4.9.6
     4626     *
     4627     * @param array  $response        The personal data for the given exporter and page.
     4628     * @param int    $exporter_index  The index of the exporter that provided this data.
     4629     * @param string $email_address   The email address associated with this personal data.
     4630     * @param int    $page            The zero-based page for this response.
     4631     * @param int    $request_id      The privacy request post ID associated with this request.
     4632     */
     4633    $response = apply_filters( 'wp_privacy_personal_data_erasure_page', $response, $eraser_index, $email_address, $page, $request_id );
     4634    if ( is_wp_error( $response ) ) {
     4635        wp_send_json_error( $response );
     4636    }
     4637
     4638    wp_send_json_success( $response );
     4639}
  • trunk/src/wp-admin/includes/user.php

    r42977 r42986  
    584584 * Get action description from the name.
    585585 *
    586  * @since 5.0.0
     586 * @since 4.9.6
    587587 * @access private
    588588 *
     
    601601 * Log a request and send to the user.
    602602 *
    603  * @since 5.0.0
     603 * @since 4.9.6
    604604 * @access private
    605605 *
     
    641641 * Resend an existing request and return the result.
    642642 *
    643  * @since 5.0.0
     643 * @since 4.9.6
    644644 * @access private
    645645 *
     
    681681 * Marks a request as completed by the admin and logs the datetime.
    682682 *
    683  * @since 5.0.0
     683 * @since 4.9.6
    684684 * @access private
    685685 *
     
    706706 * Handle list table actions.
    707707 *
    708  * @since 5.0.0
     708 * @since 4.9.6
    709709 * @access private
    710710 */
    711711function _wp_personal_data_handle_actions() {
    712     if ( isset( $_POST['export_personal_data_email_retry'] ) ) { // WPCS: input var ok.
     712    if ( isset( $_POST['privacy_action_email_retry'] ) ) { // WPCS: input var ok.
    713713        check_admin_referer( 'bulk-privacy_requests' );
    714714
    715         $request_id = absint( current( array_keys( (array) wp_unslash( $_POST['export_personal_data_email_retry'] ) ) ) ); // WPCS: input var ok, sanitization ok.
     715        $request_id = absint( current( array_keys( (array) wp_unslash( $_POST['privacy_action_email_retry'] ) ) ) ); // WPCS: input var ok, sanitization ok.
    716716        $result     = _wp_privacy_resend_request( $request_id );
    717717
    718718        if ( is_wp_error( $result ) ) {
    719719            add_settings_error(
    720                 'export_personal_data_email_retry',
    721                 'export_personal_data_email_retry',
     720                'privacy_action_email_retry',
     721                'privacy_action_email_retry',
    722722                $result->get_error_message(),
    723723                'error'
     
    725725        } else {
    726726            add_settings_error(
    727                 'export_personal_data_email_retry',
    728                 'export_personal_data_email_retry',
     727                'privacy_action_email_retry',
     728                'privacy_action_email_retry',
    729729                __( 'Confirmation request re-resent successfully.' ),
    730730                'updated'
     
    838838 * Personal data export.
    839839 *
    840  * @since 5.0.0
     840 * @since 4.9.6
    841841 * @access private
    842842 */
     
    899899 * Personal data anonymization.
    900900 *
    901  * @since 5.0.0
     901 * @since 4.9.6
    902902 * @access private
    903903 */
    904904function _wp_personal_data_removal_page() {
    905     if ( ! current_user_can( 'manage_options' ) ) {
     905    if ( ! current_user_can( 'delete_users' ) ) {
    906906        wp_die( esc_html__( 'Sorry, you are not allowed to manage privacy on this site.' ) );
    907907    }
    908908
    909909    _wp_personal_data_handle_actions();
     910
     911    // "Borrow" xfn.js for now so we don't have to create new files.
     912    wp_enqueue_script( 'xfn' );
    910913
    911914    $requests_table = new WP_Privacy_Data_Removal_Requests_Table( array(
     
    913916        'singular' => 'privacy_request',
    914917    ) );
     918
    915919    $requests_table->process_bulk_action();
    916920    $requests_table->prepare_items();
     921
    917922    ?>
    918923    <div class="wrap nosubsub">
     
    960965 * Add requests pages.
    961966 *
    962  * @since 5.0.0
     967 * @since 4.9.6
    963968 * @access private
    964969 */
     
    983988     * e.g. 'export_personal_data'
    984989     *
    985      * @since 5.0.0
     990     * @since 4.9.6
    986991     *
    987992     * @var string $request_type Name of action.
     
    992997     * Post type to be used.
    993998     *
    994      * @since 5.0.0
     999     * @since 4.9.6
    9951000     *
    9961001     * @var string $post_type The post type.
     
    10011006     * Get columns to show in the list table.
    10021007     *
    1003      * @since 5.0.0
     1008     * @since 4.9.6
    10041009     *
    10051010     * @param array Array of columns.
     
    10191024     * Get a list of sortable columns.
    10201025     *
    1021      * @since 5.0.0
     1026     * @since 4.9.6
    10221027     *
    10231028     * @return array
     
    10301035     * Default primary column.
    10311036     *
    1032      * @since 5.0.0
     1037     * @since 4.9.6
    10331038     *
    10341039     * @return string
     
    10421047     * of views available on this table.
    10431048     *
    1044      * @since 5.0.0
     1049     * @since 4.9.6
    10451050     *
    10461051     * @return array
     
    10671072     * Get bulk actions.
    10681073     *
    1069      * @since 5.0.0
     1074     * @since 4.9.6
    10701075     *
    10711076     * @return array
     
    10811086     * Process bulk actions.
    10821087     *
    1083      * @since 5.0.0
     1088     * @since 4.9.6
    10841089     */
    10851090    public function process_bulk_action() {
     
    11301135     * Prepare items to output.
    11311136     *
    1132      * @since 5.0.0
     1137     * @since 4.9.6
    11331138     */
    11341139    public function prepare_items() {
     
    11951200     * Checkbox column.
    11961201     *
    1197      * @since 5.0.0
     1202     * @since 4.9.6
    11981203     *
    11991204     * @param array $item Item being shown.
     
    12071212     * Status column.
    12081213     *
    1209      * @since 5.0.0
     1214     * @since 4.9.6
    12101215     *
    12111216     * @param array $item Item being shown.
     
    12441249     * Convert timestamp for display.
    12451250     *
    1246      * @since 5.0.0
     1251     * @since 4.9.6
    12471252     *
    12481253     * @param int $timestamp Event timestamp.
     
    12661271     * Default column handler.
    12671272     *
    1268      * @since 5.0.0
     1273     * @since 4.9.6
    12691274     *
    12701275     * @param array $item         Item being shown.
     
    12851290     * Actions column. Overriden by children.
    12861291     *
    1287      * @since 5.0.0
     1292     * @since 4.9.6
    12881293     *
    12891294     * @param array $item Item being shown.
     
    12971302     * Next steps column. Overriden by children.
    12981303     *
    1299      * @since 5.0.0
     1304     * @since 4.9.6
    13001305     *
    13011306     * @param array $item Item being shown.
     
    13061311     * Generates content for a single row of the table
    13071312     *
    1308      * @since 5.0.0
     1313     * @since 4.9.6
    13091314     *
    13101315     * @param object $item The current item
     
    13211326     * Embed scripts used to perform actions. Overriden by children.
    13221327     *
    1323      * @since 5.0.0
     1328     * @since 4.9.6
    13241329     */
    13251330    public function embed_scripts() {}
     
    13291334 * WP_Privacy_Data_Export_Requests_Table class.
    13301335 *
    1331  * @since 5.0.0
     1336 * @since 4.9.6
    13321337 */
    13331338class WP_Privacy_Data_Export_Requests_Table extends WP_Privacy_Requests_Table {
     
    13351340     * Action name for the requests this table will work with.
    13361341     *
    1337      * @since 5.0.0
     1342     * @since 4.9.6
    13381343     *
    13391344     * @var string $request_type Name of action.
     
    13441349     * Post type for the requests.
    13451350     *
    1346      * @since 5.0.0
     1351     * @since 4.9.6
    13471352     *
    13481353     * @var string $post_type The post type.
     
    13531358     * Actions column.
    13541359     *
    1355      * @since 5.0.0
     1360     * @since 4.9.6
    13561361     *
    13571362     * @param array $item Item being shown.
     
    13591364     */
    13601365    public function column_email( $item ) {
     1366        $exporters       = apply_filters( 'wp_privacy_personal_data_exporters', array() );
     1367        $exporters_count = count( $exporters );
     1368        $request_id      = $item['request_id'];
     1369        $nonce           = wp_create_nonce( 'wp-privacy-export-personal-data-' . $request_id );
     1370
     1371        $download_data_markup = '<div class="download_personal_data" ' .
     1372            'data-exporters-count="' . esc_attr( $exporters_count ) . '" ' .
     1373            'data-request-id="' . esc_attr( $request_id ) . '" ' .
     1374            'data-nonce="' . esc_attr( $nonce ) .
     1375            '">';
     1376
     1377        $download_data_markup .= '<span class="download_personal_data_idle"><a href="#" >' . __( 'Download Personal Data' ) . '</a></span>' .
     1378            '<span style="display:none" class="download_personal_data_processing" >' . __( 'Downloading Data...' ) . '</span>' .
     1379            '<span style="display:none" class="download_personal_data_failed">' . __( 'Download Failed!' ) . ' <a href="#" >' . __( 'Retry' ) . '</a></span>';
     1380
    13611381        $row_actions = array(
    1362             'download_data' => __( 'Download Personal Data' ),
     1382            'download_data' => $download_data_markup,
    13631383        );
    13641384
     
    13691389     * Next steps column.
    13701390     *
    1371      * @since 5.0.0
     1391     * @since 4.9.6
    13721392     *
    13731393     * @param array $item Item being shown.
     
    13841404                break;
    13851405            case 'request-failed':
    1386                 submit_button( __( 'Retry' ), 'secondary', 'export_personal_data_email_retry[' . $item['request_id'] . ']', false );
     1406                submit_button( __( 'Retry' ), 'secondary', 'privacy_action_email_retry[' . $item['request_id'] . ']', false );
    13871407                break;
    13881408            case 'request-completed':
     
    13991419 * WP_Privacy_Data_Removal_Requests_Table class.
    14001420 *
    1401      * @since 5.0.0
     1421     * @since 4.9.6
    14021422 */
    14031423class WP_Privacy_Data_Removal_Requests_Table extends WP_Privacy_Requests_Table {
     
    14051425     * Action name for the requests this table will work with.
    14061426     *
    1407      * @since 5.0.0
     1427     * @since 4.9.6
    14081428     *
    14091429     * @var string $request_type Name of action.
     
    14141434     * Post type for the requests.
    14151435     *
    1416      * @since 5.0.0
     1436     * @since 4.9.6
    14171437     *
    14181438     * @var string $post_type The post type.
     
    14231443     * Actions column.
    14241444     *
    1425      * @since 5.0.0
     1445     * @since 4.9.6
    14261446     *
    14271447     * @param array $item Item being shown.
     
    14291449     */
    14301450    public function column_email( $item ) {
    1431         $row_actions = array(
    1432             // TODO Complete in follow on patch.
    1433             'remove_data' => __( 'Remove Personal Data' ),
    1434         );
    1435 
    1436         // If we have a user ID, include a delete user action.
    1437         if ( ! empty( $item['user_id'] ) ) {
    1438             // TODO Complete in follow on patch.
    1439             $row_actions['delete_user'] = __( 'Delete User' );
     1451        $row_actions = array();
     1452
     1453        // Allow the administrator to "force remove" the personal data even if confirmation has not yet been received
     1454        $status = get_post_status( $item['request_id'] );
     1455        if ( 'request-confirmed' !== $status ) {
     1456            $erasers       = apply_filters( 'wp_privacy_personal_data_erasers', array() );
     1457            $erasers_count = count( $erasers );
     1458            $request_id    = $item['request_id'];
     1459            $nonce         = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
     1460
     1461            $remove_data_markup = '<div class="remove_personal_data force_remove_personal_data" ' .
     1462                'data-erasers-count="' . esc_attr( $erasers_count ) . '" ' .
     1463                'data-request-id="' . esc_attr( $request_id ) . '" ' .
     1464                'data-nonce="' . esc_attr( $nonce ) .
     1465                '">';
     1466
     1467            $remove_data_markup .= '<span class="remove_personal_data_idle"><a href="#" >' . __( 'Force Remove Personal Data' ) . '</a></span>' .
     1468                '<span style="display:none" class="remove_personal_data_processing" >' . __( 'Removing Data...' ) . '</span>' .
     1469                '<span style="display:none" class="remove_personal_data_failed">' . __( 'Force Remove Failed!' ) . ' <a href="#" >' . __( 'Retry' ) . '</a></span>';
     1470
     1471            $row_actions = array(
     1472                'remove_data' => $remove_data_markup,
     1473            );
    14401474        }
    14411475
     
    14461480     * Next steps column.
    14471481     *
    1448      * @since 5.0.0
     1482     * @since 4.9.6
    14491483     *
    14501484     * @param array $item Item being shown.
    14511485     */
    14521486    public function column_next_steps( $item ) {
    1453     }
    1454 
    1455 }
     1487        $status = get_post_status( $item['request_id'] );
     1488
     1489        switch ( $status ) {
     1490            case 'request-pending':
     1491                esc_html_e( 'Waiting for confirmation' );
     1492                break;
     1493            case 'request-confirmed':
     1494                $erasers       = apply_filters( 'wp_privacy_personal_data_erasers', array() );
     1495                $erasers_count = count( $erasers );
     1496                $request_id    = $item['request_id'];
     1497                $nonce         = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
     1498
     1499                echo '<div class="remove_personal_data" ' .
     1500                    'data-force-erase="1" ' .
     1501                    'data-erasers-count="' . esc_attr( $erasers_count ) . '" ' .
     1502                    'data-request-id="' . esc_attr( $request_id ) . '" ' .
     1503                    'data-nonce="' . esc_attr( $nonce ) .
     1504                    '">';
     1505
     1506                ?>
     1507                <span class="remove_personal_data_idle"><a class="button" href="#" ><?php _e( 'Remove Personal Data' ); ?></a></span>
     1508                <span style="display:none" class="remove_personal_data_processing button updating-message" ><?php _e( 'Removing Data...' ); ?></span>
     1509                <span style="display:none" class="remove_personal_data_failed"><?php _e( 'Removing Data Failed!' ); ?> <a class="button" href="#" ><?php _e( 'Retry' ); ?></a></span>
     1510                <?php
     1511
     1512                break;
     1513            case 'request-failed':
     1514                submit_button( __( 'Retry' ), 'secondary', 'privacy_action_email_retry[' . $item['request_id'] . ']', false );
     1515                break;
     1516            case 'request-completed':
     1517                echo '<a href="' . esc_url( wp_nonce_url( add_query_arg( array(
     1518                    'action' => 'delete',
     1519                    'request_id' => array( $item['request_id'] ),
     1520                ), admin_url( 'tools.php?page=remove_personal_data' ) ), 'bulk-privacy_requests' ) ) . '">' . esc_html__( 'Remove request' ) . '</a>';
     1521                break;
     1522        }
     1523    }
     1524
     1525}
  • trunk/src/wp-admin/js/xfn.js

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

    r42794 r42986  
    710710
    711711        $scripts->add( 'xfn', "/wp-admin/js/xfn$suffix.js", array( 'jquery' ), false, 1 );
     712        did_action( 'init' ) && $scripts->localize(
     713            'xfn', 'privacyToolsL10n', array(
     714                'noDataFound'     => __( 'No personal data was found for this user.' ),
     715                'foundAndRemoved' => __( 'All of the personal data found for this user was removed.' ),
     716                'noneRemoved'     => __( 'Personal data was found for this user but was not removed.' ),
     717                'someNotRemoved'  => __( 'Personal data was found for this user but some of the personal data found was not removed.' ),
     718                'anErrorOccurred' => __( 'An error occurred while attempting to find and remove personal data.' ),
     719            )
     720        );
    712721
    713722        $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.