WordPress.org

Make WordPress Core

Opened 4 weeks ago

Last modified 3 weeks ago

#44151 new defect (bug)

Personal data exports - lower priority exporters should place their data after the higher priority ones

Reported by: robobot3000 Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: trunk
Component: Privacy Keywords: gdpr has-patch
Focuses: Cc:

Description

When two exporters are registered that export the data for the same group_id and the same item_id the data from the lower priority exporter is placed higher in the resulting file than the higher priority one.

For example, this code:

function exporter_1( $email_address, $page = 1 ) {
        return array(
                'data' => array(
                        'group_id'    => 'group-1',
                        'group_label' => __( 'Orders', 'woocommerce-services' ),
                        'item_id'     => 'item-1',
                        'data'        => array(
                                array(
                                        'name'  => __( 'Exporter 1' ),
                                        'value' => 1234,
                                ),
                        ),
                );,
                'done' => true,
        );
}

function exporter_2( $email_address, $page = 1 ) {
        return array(
                'data' => array(
                        'group_id'    => 'group-1',
                        'group_label' => __( 'Orders', 'woocommerce-services' ),
                        'item_id'     => 'item-1',
                        'data'        => array(
                                array(
                                        'name'  => __( 'Exporter 2' ),
                                        'value' => 4567,
                                ),
                        ),
                );,
                'done' => true,
        );
}

add_filter( 'wp_privacy_personal_data_exporters', 'exporter_1', 5 );
add_filter( 'wp_privacy_personal_data_exporters', 'exporter_2', 10 );

should result in a file where 'Exporter 1' appears before 'Exporter 2' (see the priority attribute passed to the add_filter call), but this isn't the case.

CC @allendav @jeffstieler

Attachments (3)

44151.patch (1.1 KB) - added by robobot3000 4 weeks ago.
Added a fix - needed to replace array_merge with custom code. While appending the new data instead of prepending, we don't want to overwrite the already existing data
44151.2.patch (1.1 KB) - added by robobot3000 4 weeks ago.
Fix the order of arguments passed to array_key_exists()
44151.3.patch (746 bytes) - added by robobot3000 3 weeks ago.
Always append the new data to the result array

Download all attachments as: .zip

Change History (12)

#1 @robobot3000
4 weeks ago

  • Keywords needs-patch added

@robobot3000
4 weeks ago

Added a fix - needed to replace array_merge with custom code. While appending the new data instead of prepending, we don't want to overwrite the already existing data

#2 @robobot3000
4 weeks ago

  • Keywords has-patch added; needs-patch removed

#3 @allendav
4 weeks ago

I've also confirmed this - @robobot3000 - note that your code snippet is not a proper exporter - nor registers exporters correctly - you need an array of arrays for data, i.e.:

<?php
function exporter_1( $email_address, $page = 1 ) {
        return array(
                'data' => array( array(
                        'group_id'    => 'group-1',
                        'group_label' => __( 'Orders', 'woocommerce-services' ),
                        'item_id'     => 'item-1',
                        'data'        => array(
                                array(
                                        'name'  => __( 'Exporter 1' ),
                                        'value' => 1234,
                                ),
                        ),
                ) ),
                'done' => true,
        );
}

function exporter_2( $email_address, $page = 1 ) {
        return array(
                'data' => array( array(
                        'group_id'    => 'group-1',
                        'group_label' => __( 'Orders', 'woocommerce-services' ),
                        'item_id'     => 'item-1',
                        'data'        => array(
                                array(
                                        'name'  => __( 'Exporter 2' ),
                                        'value' => 4567,
                                ),
                        ),
                ) ),
                'done' => true,
        );
}

function register_exporter_1( $exporters ) {
  $exporters['exporter_1'] = array(
    'exporter_friendly_name' => __( 'Exporter 1' ),
    'callback' => 'exporter_1',
  );
  return $exporters;
}

add_filter(
  'wp_privacy_personal_data_exporters',
  'register_exporter_1',
  5
);

function register_exporter_2( $exporters ) {
  $exporters['exporter_2'] = array(
    'exporter_friendly_name' => __( 'Exporter 2' ),
    'callback' => 'exporter_2',
  );
  return $exporters;
}

add_filter(
  'wp_privacy_personal_data_exporters',
  'register_exporter_2',
  10
);

#4 @allendav
4 weeks ago

@robobot3000 : you're right - it is because array_merge reindexes that things get moved out of order. But under what circumstance did you see non numeric keys in the $responsedata? array?

@robobot3000
4 weeks ago

Fix the order of arguments passed to array_key_exists()

#5 follow-up: @robobot3000
4 weeks ago

But under what circumstance did you see non numeric keys in the $response data array?

@allendav : I was replicating the documented behaviour of array_merge. But it's possible for any plugin author to define the exported data with non-numeric keys, even though it doesn't affect the output. For example:

<?php
$data_to_export[] = array(
        'group_id'    => 'woocommerce_orders',
        'group_label' => __( 'Orders', 'woocommerce-services' ),
        'item_id'     => 'order-' . $order_id,
        'data'        => array(
                'abc' => array(
                        'name'  => __( 'Shipping label service', 'woocommerce-services' ),
                        'value' => $label['service_name'],
                ),
                'def' => array(
                        'name'  => __( 'Shipping label tracking number', 'woocommerce-services' ),
                        'value' => $label['tracking'],
                ),
        ),
);
Last edited 4 weeks ago by robobot3000 (previous) (diff)

This ticket was mentioned in Slack in #gdpr-compliance by pepe. View the logs.


4 weeks ago

This ticket was mentioned in Slack in #gdpr-compliance by desrosj. View the logs.


3 weeks ago

#8 in reply to: ↑ 5 ; follow-up: @allendav
3 weeks ago

Replying to robobot3000:

But under what circumstance did you see non numeric keys in the $response data array?

@allendav : I was replicating the documented behaviour of array_merge. But it's possible for any plugin author to define the exported data with non-numeric keys, even though it doesn't affect the output.

I think we should probably flag that as doingitwrong

@robobot3000
3 weeks ago

Always append the new data to the result array

#9 in reply to: ↑ 8 @robobot3000
3 weeks ago

@allendav : if we want to keep the code simple and ignore the keys then we can just append the data to the result array (see 44151.3.patch).

I think we should probably flag that as doingitwrong

I'm not sure what the expected result of this would be. Could you elaborate? I looked into _doing_it_wrong and wp_send_json_error but the former doesn't work while doing AJAX, and the latter prevents the whole download from happening.

Note: See TracTickets for help on using tickets.