Export downloads and logs

This commit is contained in:
Mike Jolley 2018-04-13 17:00:26 +01:00
parent 965712a1d7
commit eb6d230d38
3 changed files with 137 additions and 39 deletions

View File

@ -43,8 +43,8 @@ class WC_Privacy {
'callback' => array( __CLASS__, 'order_data_exporter' ), 'callback' => array( __CLASS__, 'order_data_exporter' ),
); );
$exporters[] = array( $exporters[] = array(
'exporter_friendly_name' => __( 'WooCommerce Download Logs', 'woocommerce' ), 'exporter_friendly_name' => __( 'WooCommerce Downloads', 'woocommerce' ),
'callback' => array( __CLASS__, 'download_log_data_exporter' ), 'callback' => array( __CLASS__, 'download_data_exporter' ),
); );
return $exporters; return $exporters;
} }
@ -132,11 +132,100 @@ class WC_Privacy {
* @param int $page Page. * @param int $page Page.
* @return array An array of personal data in name value pairs * @return array An array of personal data in name value pairs
*/ */
public static function download_log_data_exporter( $email_address, $page ) { public static function download_data_exporter( $email_address, $page ) {
// @todo $done = false;
$page = (int) $page;
$user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
$data_to_export = array();
$downloads_query = array(
'limit' => 10,
'page' => $page,
);
if ( $user instanceof WP_User ) {
$downloads_query['user_id'] = (int) $user->ID;
} else {
$downloads_query['user_email'] = $email_address;
}
$customer_download_data_store = WC_Data_Store::load( 'customer-download' );
$customer_download_log_data_store = WC_Data_Store::load( 'customer-download-log' );
$downloads = $customer_download_data_store->get_downloads( $downloads_query );
if ( 0 < count( $downloads ) ) {
foreach ( $downloads as $download ) {
$data_to_export[] = array(
'group_id' => 'woocommerce_downloads',
'group_label' => __( 'Order Downloads', 'woocommerce' ),
'item_id' => 'download-' . $download->get_id(),
'data' => array(
array(
'name' => __( 'Download ID', 'woocommerce' ),
'value' => $download->get_id(),
),
array(
'name' => __( 'Order ID', 'woocommerce' ),
'value' => $download->get_order_id(),
),
array(
'name' => __( 'Product', 'woocommerce' ),
'value' => get_the_title( $download->get_product_id() ),
),
array(
'name' => __( 'User email', 'woocommerce' ),
'value' => $download->get_user_email(),
),
array(
'name' => __( 'Downloads remaining', 'woocommerce' ),
'value' => $download->get_downloads_remaining(),
),
array(
'name' => __( 'Download count', 'woocommerce' ),
'value' => $download->get_download_count(),
),
array(
'name' => __( 'Access granted', 'woocommerce' ),
'value' => date( 'Y-m-d', $download->get_access_granted( 'edit' )->getTimestamp() ),
),
array(
'name' => __( 'Access expires', 'woocommerce' ),
'value' => ! is_null( $download->get_access_expires( 'edit' ) ) ? date( 'Y-m-d', $download->get_access_expires( 'edit' )->getTimestamp() ) : null,
),
),
);
$download_logs = $customer_download_log_data_store->get_download_logs_for_permission( $download->get_id() );
foreach ( $download_logs as $download_log ) {
$data_to_export[] = array(
'group_id' => 'woocommerce_download_logs',
'group_label' => __( 'Download Logs', 'woocommerce' ),
'item_id' => 'download-log-' . $download_log->get_id(),
'data' => array(
array(
'name' => __( 'Download ID', 'woocommerce' ),
'value' => $download_log->get_permission_id(),
),
array(
'name' => __( 'Timestamp', 'woocommerce' ),
'value' => $download_log->get_timestamp(),
),
array(
'name' => __( 'IP Address', 'woocommerce' ),
'value' => $download_log->get_user_ip_address(),
),
),
);
}
}
$done = 10 > count( $downloads );
} else {
$done = true;
}
return array( return array(
'data' => array(), 'data' => $data_to_export,
'done' => true, 'done' => $done,
); );
} }
@ -265,13 +354,15 @@ class WC_Privacy {
* Note; this is separate to account deletion. WooCommerce handles account deletion/cleanup elsewhere. * Note; this is separate to account deletion. WooCommerce handles account deletion/cleanup elsewhere.
* This logic is simply to clean up data for guest users. * This logic is simply to clean up data for guest users.
* *
* @todo Add option to determine if order data should be left alone when removing personal data for a user.
*
* @param string $email_address Customer email address. * @param string $email_address Customer email address.
*/ */
public static function remove_personal_data( $email_address ) { public static function remove_personal_data( $email_address ) {
$user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB. $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB.
$has_account = $user instanceof WP_User; $has_account = $user instanceof WP_User;
// Remove personal data from the user's orders. @todo add option for this. // Remove personal data from the user's orders.
$order_query = array( $order_query = array(
'limit' => -1, 'limit' => -1,
); );
@ -290,11 +381,12 @@ class WC_Privacy {
} }
} }
// Revoke things such as download permissions for this email if it's a guest account. This is handled elsewhere for user accounts on delete.
if ( ! $has_account ) { if ( ! $has_account ) {
// Revoke things such as download permissions for this email if it's a guest account. This is handled elsewhere for user accounts on delete.
$data_store = WC_Data_Store::load( 'customer-download' ); $data_store = WC_Data_Store::load( 'customer-download' );
$data_store->delete_by_user_email( $email_address ); $data_store->delete_by_user_email( $email_address );
} else { } else {
// Remove address data from the user object. This is in case the user is not deleted for whatever reason.
self::remove_customer_personal_data( $user ); self::remove_customer_personal_data( $user );
} }
@ -317,37 +409,37 @@ class WC_Privacy {
$anonymized_data = array(); $anonymized_data = array();
/** /**
* Expose props and data types we'll be anonymizing. * Expose props and data types we'll be removing.
* *
* @since 3.4.0 * @since 3.4.0
* @param array $props Keys are the prop names, values are the data type we'll be passing to wp_privacy_anonymize_data(). * @param array $props A list of props we're removing from the user object.
* @param WC_Customer $customer A customer object. * @param WC_Customer $customer A customer object.
*/ */
$props_to_remove = apply_filters( 'woocommerce_privacy_remove_customer_personal_data_props', array( $props_to_remove = apply_filters( 'woocommerce_privacy_remove_customer_personal_data_props', array(
'billing_first_name' => 'address', 'billing_first_name',
'billing_last_name' => 'address', 'billing_last_name',
'billing_company' => 'address', 'billing_company',
'billing_address_1' => 'address', 'billing_address_1',
'billing_address_2' => 'address', 'billing_address_2',
'billing_city' => 'address', 'billing_city',
'billing_postcode' => 'address', 'billing_postcode',
'billing_state' => 'address', 'billing_state',
'billing_country' => 'address', 'billing_country',
'billing_phone' => 'phone', 'billing_phone',
'billing_email' => 'email', 'billing_email',
'shipping_first_name' => 'address', 'shipping_first_name',
'shipping_last_name' => 'address', 'shipping_last_name',
'shipping_company' => 'address', 'shipping_company',
'shipping_address_1' => 'address', 'shipping_address_1',
'shipping_address_2' => 'address', 'shipping_address_2',
'shipping_city' => 'address', 'shipping_city',
'shipping_postcode' => 'address', 'shipping_postcode',
'shipping_state' => 'address', 'shipping_state',
'shipping_country' => 'address', 'shipping_country',
), $customer ); ), $customer );
if ( ! empty( $props_to_remove ) && is_array( $props_to_remove ) ) { if ( ! empty( $props_to_remove ) && is_array( $props_to_remove ) ) {
foreach ( $props_to_remove as $prop => $data_type ) { foreach ( $props_to_remove as $prop ) {
// Get the current value in edit context. // Get the current value in edit context.
$value = $customer->{"get_$prop"}( 'edit' ); $value = $customer->{"get_$prop"}( 'edit' );
@ -363,10 +455,9 @@ class WC_Privacy {
* @param bool $anonymized_data Value of this prop after anonymization. * @param bool $anonymized_data Value of this prop after anonymization.
* @param string $prop Name of the prop being removed. * @param string $prop Name of the prop being removed.
* @param string $value Current value of the data. * @param string $value Current value of the data.
* @param string $data_type Type of data.
* @param WC_Customer $customer A customer object. * @param WC_Customer $customer A customer object.
*/ */
$anonymized_data[ $prop ] = apply_filters( 'woocommerce_privacy_remove_personal_data_customer_prop_value', wp_privacy_anonymize_data( $data_type, $value ), $prop, $value, $data_type, $customer ); $anonymized_data[ $prop ] = apply_filters( 'woocommerce_privacy_remove_personal_data_customer_prop_value', '', $prop, $value, $customer );
} }
} }

View File

@ -281,6 +281,7 @@ class WC_Customer_Download_Data_Store implements WC_Customer_Download_Data_Store
$args = wp_parse_args( $args = wp_parse_args(
$args, array( $args, array(
'user_email' => '', 'user_email' => '',
'user_id' => '',
'order_id' => '', 'order_id' => '',
'order_key' => '', 'order_key' => '',
'product_id' => '', 'product_id' => '',
@ -288,6 +289,7 @@ class WC_Customer_Download_Data_Store implements WC_Customer_Download_Data_Store
'orderby' => 'permission_id', 'orderby' => 'permission_id',
'order' => 'ASC', 'order' => 'ASC',
'limit' => -1, 'limit' => -1,
'page' => 1,
'return' => 'objects', 'return' => 'objects',
) )
); );
@ -312,6 +314,10 @@ class WC_Customer_Download_Data_Store implements WC_Customer_Download_Data_Store
$query[] = $wpdb->prepare( 'AND user_email = %s', sanitize_email( $args['user_email'] ) ); $query[] = $wpdb->prepare( 'AND user_email = %s', sanitize_email( $args['user_email'] ) );
} }
if ( $args['user_id'] ) {
$query[] = $wpdb->prepare( 'AND user_id = %d', absint( $args['user_id'] ) );
}
if ( $args['order_id'] ) { if ( $args['order_id'] ) {
$query[] = $wpdb->prepare( 'AND order_id = %d', $args['order_id'] ); $query[] = $wpdb->prepare( 'AND order_id = %d', $args['order_id'] );
} }
@ -334,7 +340,7 @@ class WC_Customer_Download_Data_Store implements WC_Customer_Download_Data_Store
$query[] = "ORDER BY {$orderby_sql}"; $query[] = "ORDER BY {$orderby_sql}";
if ( 0 < $args['limit'] ) { if ( 0 < $args['limit'] ) {
$query[] = $wpdb->prepare( 'LIMIT %d', $args['limit'] ); $query[] = $wpdb->prepare( 'LIMIT %d, %d', absint( $args['limit'] ) * absint( $args['page'] - 1 ), absint( $args['limit'] ) );
} }
// phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared

View File

@ -163,6 +163,7 @@ class WC_Customer_Download_Log_Data_Store implements WC_Customer_Download_Log_Da
'orderby' => 'download_log_id', 'orderby' => 'download_log_id',
'order' => 'DESC', 'order' => 'DESC',
'limit' => -1, 'limit' => -1,
'page' => 1,
'return' => 'objects', 'return' => 'objects',
) ); ) );
@ -188,7 +189,7 @@ class WC_Customer_Download_Log_Data_Store implements WC_Customer_Download_Log_Da
$query[] = "ORDER BY {$orderby_sql}"; $query[] = "ORDER BY {$orderby_sql}";
if ( 0 < $args['limit'] ) { if ( 0 < $args['limit'] ) {
$query[] = $wpdb->prepare( "LIMIT %d", $args['limit'] ); $query[] = $wpdb->prepare( 'LIMIT %d, %d', absint( $args['limit'] ) * absint( $args['page'] - 1 ), absint( $args['limit'] ) );
} }
$raw_download_logs = $wpdb->get_results( implode( ' ', $query ) ); $raw_download_logs = $wpdb->get_results( implode( ' ', $query ) );