Update abstract class and privacy code

This commit is contained in:
Mike Jolley 2018-04-26 11:29:51 +01:00
parent 41605a23eb
commit 091d5326f2
3 changed files with 189 additions and 260 deletions

View File

@ -2,12 +2,11 @@
/**
* WooCommerce abstract privacy class.
*
* @since 3.4.0
* @package WooCommerce/Abstracts
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* Abstract class that is intended to be extended by
@ -24,32 +23,36 @@ abstract class WC_Abstract_Privacy {
*
* @var string
*/
public $privacy_name;
public $name;
/**
* This is a list of exporters.
*
* @var array
*/
protected $exporters;
protected $exporters = array();
/**
* This is a list of erasers.
*
* @var array
*/
protected $erasers;
protected $erasers = array();
/**
* Constructor
*
* @param string $privacy_name Privacy identifier
* @param string $name Plugin identifier.
*/
public function __construct( $privacy_name = '' ) {
$this->privacy_name = $privacy_name;
$this->exporters = array();
$this->erasers = array();
public function __construct( $name = '' ) {
$this->name = $name;
$this->init();
}
/**
* Hook in events.
*/
protected function init() {
add_action( 'admin_init', array( $this, 'add_privacy_message' ) );
add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_exporters' ) );
add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'register_erasers' ) );
@ -60,7 +63,11 @@ abstract class WC_Abstract_Privacy {
*/
public function add_privacy_message() {
if ( function_exists( 'wp_add_privacy_policy_content' ) ) {
wp_add_privacy_policy_content( $this->privacy_name, $this->get_message() );
$content = $this->get_privacy_message();
if ( $content ) {
wp_add_privacy_policy_content( $this->name, $this->get_privacy_message() );
}
}
}
@ -70,7 +77,9 @@ abstract class WC_Abstract_Privacy {
*
* @return string
*/
abstract public function get_message();
public function get_privacy_message() {
return '';
}
/**
* Integrate this exporter implementation within the WordPress core exporters.
@ -95,110 +104,28 @@ abstract class WC_Abstract_Privacy {
/**
* Add exporter to list of exporters.
*
* @param string $name Exporter name
* @param string $callback Exporter callback
* @param string $name Exporter name.
* @param string $callback Exporter callback.
*/
public function add_exporter( $name, $callback ) {
$this->exporters[] = array(
'exporter_friendly_name' => $name,
'callback' => $callback,
);
return $this->exporters;
}
/**
* Add eraser to list of exporters.
*
* @param string $name Exporter name
* @param string $callback Exporter callback
* @param string $name Exporter name.
* @param string $callback Exporter callback.
*/
public function add_eraser( $name, $callback ) {
$this->erasers[] = array(
'eraser_friendly_name' => $name,
'callback' => $callback,
);
return $this->erasers;
}
/**
* Example implementation of an exporter.
*
* Plugins can add as many items in the item data array as they want. Example:
*
* $data = array(
* array(
* 'name' => __( 'Commenter Latitude' ),
* 'value' => $latitude
* ),
* array(
* 'name' => __( 'Commenter Longitude' ),
* 'value' => $longitude
* )
* );
*
* $export_items[] = array(
* 'group_id' => $group_id,
* 'group_label' => $group_label,
* 'item_id' => $item_id,
* 'data' => $data,
* );
* }
* }
*
* Tell core if we have more comments to work on still. Example:
* $done = count( $comments ) < $number;
*
* return array(
* 'data' => $export_items,
* 'done' => $done,
* );
*
* @param string $email_address E-mail address to export.
* @param int $page Pagination of data.
*
* @return array
*/
public final function example_exporter( $email_address, $page = 1 ) {}
/**
* Example implementation of an eraser.
*
* Plugins can add as many items in the item data array as they want. Example:
*
* $data = array(
* array(
* 'name' => __( 'Commenter Latitude' ),
* 'value' => $latitude
* ),
* array(
* 'name' => __( 'Commenter Longitude' ),
* 'value' => $longitude
* )
* );
*
* $export_items[] = array(
* 'group_id' => $group_id,
* 'group_label' => $group_label,
* 'item_id' => $item_id,
* 'data' => $data,
* );
* }
* }
*
* Tell core if we have more comments to work on still. Example:
* $done = count( $comments ) < $number;
*
* return array(
* 'data' => $export_items,
* 'done' => $done,
* );
*
* @param string $email_address E-mail address to export.
* @param int $page Pagination of data.
*
* @return array
*/
public final function example_eraser( $email_address, $page = 1 ) {}
}

View File

@ -22,10 +22,10 @@ class WC_Privacy_Erasers {
*/
public static function customer_data_eraser( $email_address, $page ) {
$response = array(
'messages' => array(),
'num_items_removed' => 0,
'num_items_retained' => 0,
'done' => true,
'items_removed' => false,
'items_retained' => false,
'messages' => array(),
'done' => true,
);
$user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
@ -80,8 +80,8 @@ class WC_Privacy_Erasers {
if ( $erased ) {
/* Translators: %s Prop name. */
$response['messages'][] = sprintf( __( 'Removed customer "%s"', 'woocommerce' ), $label );
$response['num_items_removed'] ++;
$response['messages'][] = sprintf( __( 'Removed customer "%s"', 'woocommerce' ), $label );
$response['items_removed'] = true;
}
}
@ -113,10 +113,10 @@ class WC_Privacy_Erasers {
$user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
$erasure_enabled = wc_string_to_bool( get_option( 'woocommerce_erasure_request_removes_order_data', 'no' ) );
$response = array(
'messages' => array(),
'num_items_removed' => 0,
'num_items_retained' => 0,
'done' => false,
'items_removed' => false,
'items_retained' => false,
'messages' => array(),
'done' => true,
);
$order_query = array(
@ -137,12 +137,12 @@ class WC_Privacy_Erasers {
WC_Privacy::remove_order_personal_data( $order );
/* Translators: %s Order number. */
$response['messages'][] = sprintf( __( 'Removed personal data from order %s.', 'woocommerce' ), $order->get_order_number() );
$response['num_items_removed'] ++;
$response['messages'][] = sprintf( __( 'Removed personal data from order %s.', 'woocommerce' ), $order->get_order_number() );
$response['items_removed'] = true;
} else {
/* Translators: %s Order number. */
$response['messages'][] = sprintf( __( 'Retained personal data in order %s due to settings.', 'woocommerce' ), $order->get_order_number() );
$response['num_items_retained'] ++;
$response['messages'][] = sprintf( __( 'Retained personal data in order %s due to settings.', 'woocommerce' ), $order->get_order_number() );
$response['items_retained'] = true;
}
}
$response['done'] = 10 > count( $orders );
@ -166,10 +166,10 @@ class WC_Privacy_Erasers {
$user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
$erasure_enabled = wc_string_to_bool( get_option( 'woocommerce_erasure_request_removes_download_data', 'no' ) );
$response = array(
'messages' => array(),
'num_items_removed' => 0,
'num_items_retained' => 0,
'done' => true,
'items_removed' => false,
'items_retained' => false,
'messages' => array(),
'done' => true,
);
$downloads_query = array(
@ -195,11 +195,11 @@ class WC_Privacy_Erasers {
} else {
$customer_download_data_store->delete_by_user_email( $email_address );
}
$response['messages'][] = __( 'Removed access to downloadable files.', 'woocommerce' );
$response['num_items_removed'] = count( $downloads );
$response['messages'][] = __( 'Removed access to downloadable files.', 'woocommerce' );
$response['items_removed'] = true;
} else {
$response['messages'][] = __( 'Retained access to downloadable files due to settings.', 'woocommerce' );
$response['num_items_retained'] = count( $downloads );
$response['messages'][] = __( 'Retained access to downloadable files due to settings.', 'woocommerce' );
$response['items_retained'] = true;
}
return $response;

View File

@ -18,7 +18,7 @@ class WC_Privacy extends WC_Abstract_Privacy {
*
* @var WC_Privacy_Background_Process
*/
protected $background_process;
protected static $background_process;
/**
* Init - hook into events.
@ -26,7 +26,9 @@ class WC_Privacy extends WC_Abstract_Privacy {
public function __construct() {
parent::__construct( 'WooCommerce' );
$this->background_process = new WC_Privacy_Background_Process();
if ( ! self::$background_process ) {
self::$background_process = new WC_Privacy_Background_Process();
}
// Include supporting classes.
include_once 'class-wc-privacy-erasers.php';
@ -45,11 +47,11 @@ class WC_Privacy extends WC_Abstract_Privacy {
// Cleanup orders daily - this is a callback on a daily cron event.
add_action( 'woocommerce_cleanup_orders', array( $this, 'order_cleanup_process' ) );
// When this is fired, data is removed in a given order. Called from bulk actions.
add_action( 'woocommerce_remove_order_personal_data', array( 'WC_Privacy_Erasers', 'remove_order_personal_data' ) );
// Handles custom anonomization types not included in core.
add_filter( 'wp_privacy_anonymize_data', array( $this, 'anonymize_custom_data_types' ), 10, 3 );
// When this is fired, data is removed in a given order. Called from bulk actions.
add_action( 'woocommerce_remove_order_personal_data', array( 'WC_Privacy_Erasers', 'remove_order_personal_data' ) );
}
/**
@ -57,7 +59,7 @@ class WC_Privacy extends WC_Abstract_Privacy {
*
* @since 3.4.0
*/
public function get_message() {
public function get_privacy_message() {
$content = wp_kses_post( apply_filters( 'wc_privacy_policy_content', wpautop( __( '
We collect information about you during the checkout process on our store. This information may include, but is not limited to, your name, billing address, shipping address, email address, phone number, credit card/payment details and any other details that might be requested from you for the purpose of processing your orders.
@ -82,143 +84,15 @@ Additionally we may also collect the following information:
return $content;
}
/**
* For a given query trash all matches.
*
* @since 3.4.0
* @param array $query Query array to pass to wc_get_orders().
* @return int Count of orders that were trashed.
*/
protected function trash_orders_query( $query ) {
$orders = wc_get_orders( $query );
$count = 0;
if ( $orders ) {
foreach ( $orders as $order ) {
$order->delete( false );
$count ++;
}
}
return $count;
}
/**
* For a given query, anonymize all matches.
*
* @since 3.4.0
* @param array $query Query array to pass to wc_get_orders().
* @return int Count of orders that were anonymized.
*/
protected function anonymize_orders_query( $query ) {
$orders = wc_get_orders( $query );
$count = 0;
if ( $orders ) {
foreach ( $orders as $order ) {
WC_Privacy_Erasers::remove_order_personal_data( $order );
$count ++;
}
}
return $count;
}
/**
* Spawn events for order cleanup.
*/
public function order_cleanup_process() {
$this->background_process->push_to_queue( array( 'task' => 'trash_pending_orders' ) );
$this->background_process->push_to_queue( array( 'task' => 'trash_failed_orders' ) );
$this->background_process->push_to_queue( array( 'task' => 'trash_cancelled_orders' ) );
$this->background_process->push_to_queue( array( 'task' => 'anonymize_completed_orders' ) );
$this->background_process->save()->dispatch();
}
/**
* Find and trash old orders.
*
* @since 3.4.0
* @param int $limit Limit orders to process per batch.
* @return int Number of orders processed.
*/
public function trash_pending_orders( $limit = 20 ) {
$option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_pending_orders' ) );
if ( empty( $option['number'] ) ) {
return 0;
}
return $this->trash_orders_query( array(
'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ),
'limit' => $limit, // Batches of 20.
'status' => 'wc-pending',
) );
}
/**
* Find and trash old orders.
*
* @since 3.4.0
* @param int $limit Limit orders to process per batch.
* @return int Number of orders processed.
*/
public function trash_failed_orders( $limit = 20 ) {
$option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_failed_orders' ) );
if ( empty( $option['number'] ) ) {
return 0;
}
return $this->trash_orders_query( array(
'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ),
'limit' => $limit, // Batches of 20.
'status' => 'wc-failed',
) );
}
/**
* Find and trash old orders.
*
* @since 3.4.0
* @param int $limit Limit orders to process per batch.
* @return int Number of orders processed.
*/
public function trash_cancelled_orders( $limit = 20 ) {
$option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_cancelled_orders' ) );
if ( empty( $option['number'] ) ) {
return 0;
}
return $this->trash_orders_query( array(
'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ),
'limit' => $limit, // Batches of 20.
'status' => 'wc-cancelled',
) );
}
/**
* Anonymize old completed orders.
*
* @since 3.4.0
* @param int $limit Limit orders to process per batch.
* @param int $page Page to process.
* @return int Number of orders processed.
*/
public function anonymize_completed_orders( $limit = 20, $page = 1 ) {
$option = wc_parse_relative_date_option( get_option( 'woocommerce_anonymize_completed_orders' ) );
if ( empty( $option['number'] ) ) {
return 0;
}
return $this->anonymize_orders_query( array(
'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ),
'limit' => $limit, // Batches of 20.
'status' => 'wc-completed',
'anonymized' => false,
) );
self::$background_process->push_to_queue( array( 'task' => 'trash_pending_orders' ) );
self::$background_process->push_to_queue( array( 'task' => 'trash_failed_orders' ) );
self::$background_process->push_to_queue( array( 'task' => 'trash_cancelled_orders' ) );
self::$background_process->push_to_queue( array( 'task' => 'anonymize_completed_orders' ) );
self::$background_process->save()->dispatch();
}
/**
@ -241,6 +115,134 @@ Additionally we may also collect the following information:
}
return $anonymous;
}
/**
* For a given query trash all matches.
*
* @since 3.4.0
* @param array $query Query array to pass to wc_get_orders().
* @return int Count of orders that were trashed.
*/
protected static function trash_orders_query( $query ) {
$orders = wc_get_orders( $query );
$count = 0;
if ( $orders ) {
foreach ( $orders as $order ) {
$order->delete( false );
$count ++;
}
}
return $count;
}
/**
* For a given query, anonymize all matches.
*
* @since 3.4.0
* @param array $query Query array to pass to wc_get_orders().
* @return int Count of orders that were anonymized.
*/
protected static function anonymize_orders_query( $query ) {
$orders = wc_get_orders( $query );
$count = 0;
if ( $orders ) {
foreach ( $orders as $order ) {
WC_Privacy_Erasers::remove_order_personal_data( $order );
$count ++;
}
}
return $count;
}
/**
* Find and trash old orders.
*
* @since 3.4.0
* @param int $limit Limit orders to process per batch.
* @return int Number of orders processed.
*/
public static function trash_pending_orders( $limit = 20 ) {
$option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_pending_orders' ) );
if ( empty( $option['number'] ) ) {
return 0;
}
return self::trash_orders_query( array(
'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ),
'limit' => $limit, // Batches of 20.
'status' => 'wc-pending',
) );
}
/**
* Find and trash old orders.
*
* @since 3.4.0
* @param int $limit Limit orders to process per batch.
* @return int Number of orders processed.
*/
public static function trash_failed_orders( $limit = 20 ) {
$option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_failed_orders' ) );
if ( empty( $option['number'] ) ) {
return 0;
}
return self::trash_orders_query( array(
'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ),
'limit' => $limit, // Batches of 20.
'status' => 'wc-failed',
) );
}
/**
* Find and trash old orders.
*
* @since 3.4.0
* @param int $limit Limit orders to process per batch.
* @return int Number of orders processed.
*/
public static function trash_cancelled_orders( $limit = 20 ) {
$option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_cancelled_orders' ) );
if ( empty( $option['number'] ) ) {
return 0;
}
return self::trash_orders_query( array(
'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ),
'limit' => $limit, // Batches of 20.
'status' => 'wc-cancelled',
) );
}
/**
* Anonymize old completed orders.
*
* @since 3.4.0
* @param int $limit Limit orders to process per batch.
* @param int $page Page to process.
* @return int Number of orders processed.
*/
public static function anonymize_completed_orders( $limit = 20, $page = 1 ) {
$option = wc_parse_relative_date_option( get_option( 'woocommerce_anonymize_completed_orders' ) );
if ( empty( $option['number'] ) ) {
return 0;
}
return self::anonymize_orders_query( array(
'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ),
'limit' => $limit, // Batches of 20.
'status' => 'wc-completed',
'anonymized' => false,
) );
}
}
new WC_Privacy();