Merge pull request #19743 from woocommerce/update/gdpr-order-cleanup

GDPR: Order cleanup
This commit is contained in:
Claudiu Lodromanean 2018-04-18 09:51:01 -07:00 committed by GitHub
commit 26fb91dc61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 1009 additions and 137 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3476,12 +3476,16 @@ img.help_tip {
margin: 0;
padding: 6px;
box-sizing: border-box;
vertical-align: top;
}
select {
width: 400px;
margin: 0;
box-sizing: border-box;
height: 32px;
line-height: 32px;
vertical-align: top;
}
input[size] {
@ -3523,6 +3527,11 @@ img.help_tip {
padding-right: 24px;
}
th label {
position: relative;
display: block;
}
.select2-container {
vertical-align: top;
margin-bottom: 3px;
@ -3534,8 +3543,10 @@ img.help_tip {
th img.help_tip,
th .woocommerce-help-tip {
margin: 2px -24px 0 0;
float: right;
margin: -8px -24px 0 0;
position: absolute;
right: 0;
top: 50%;
}
.wp-list-table .woocommerce-help-tip {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

273
assets/css/jquery-ui/jquery-ui.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -423,8 +423,7 @@ abstract class WC_Settings_API {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<fieldset>
@ -467,8 +466,7 @@ abstract class WC_Settings_API {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<fieldset>
@ -511,8 +509,7 @@ abstract class WC_Settings_API {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<fieldset>
@ -567,8 +564,7 @@ abstract class WC_Settings_API {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<fieldset>
@ -613,8 +609,7 @@ abstract class WC_Settings_API {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<fieldset>
@ -661,8 +656,7 @@ abstract class WC_Settings_API {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<fieldset>
@ -707,8 +701,7 @@ abstract class WC_Settings_API {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<fieldset>
@ -758,8 +751,7 @@ abstract class WC_Settings_API {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<fieldset>

View File

@ -162,7 +162,7 @@ abstract class WC_Background_Process extends WP_Background_Process {
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
if ( property_exists( $this, 'cron_interval' ) ) {
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval_identifier );
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval );
}
// Adds every 5 minutes to the existing schedules.

View File

@ -32,12 +32,12 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
global $wp_scripts;
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
$screen_id = $screen ? $screen->id: '';
// Register admin styles.
wp_register_style( 'woocommerce_admin_menu_styles', WC()->plugin_url() . '/assets/css/menu.css', array(), WC_VERSION );
wp_register_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
wp_register_style( 'jquery-ui-style', WC()->plugin_url() . '/assets/css/jquery-ui.min.css', array(), WC_VERSION );
wp_register_style( 'jquery-ui-style', WC()->plugin_url() . '/assets/css/jquery-ui/jquery-ui.min.css', array(), WC_VERSION );
wp_register_style( 'woocommerce_admin_dashboard_styles', WC()->plugin_url() . '/assets/css/dashboard.css', array(), WC_VERSION );
wp_register_style( 'woocommerce_admin_print_reports_styles', WC()->plugin_url() . '/assets/css/reports-print.css', array(), WC_VERSION, 'print' );

View File

@ -285,8 +285,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
?><tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
<td class="forminp forminp-<?php echo esc_attr( sanitize_title( $value['type'] ) ); ?>">
<input
@ -311,8 +310,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
<td class="forminp forminp-<?php echo esc_attr( sanitize_title( $value['type'] ) ); ?>">&lrm;
<span class="colorpickpreview" style="background: <?php echo esc_attr( $option_value ); ?>"></span>
@ -340,8 +338,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
<td class="forminp forminp-<?php echo esc_attr( sanitize_title( $value['type'] ) ); ?>">
<?php echo $description; // WPCS: XSS ok. ?>
@ -367,8 +364,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
<td class="forminp forminp-<?php echo esc_attr( sanitize_title( $value['type'] ) ); ?>">
<select
@ -410,8 +406,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
<td class="forminp forminp-<?php echo esc_attr( sanitize_title( $value['type'] ) ); ?>">
<fieldset>
@ -580,8 +575,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
<td class="forminp"><select name="<?php echo esc_attr( $value['id'] ); ?>" style="<?php echo esc_attr( $value['css'] ); ?>" data-placeholder="<?php esc_attr_e( 'Choose a country&hellip;', 'woocommerce' ); ?>" aria-label="<?php esc_attr_e( 'Country', 'woocommerce' ); ?>" class="wc-enhanced-select">
<?php WC()->countries->country_dropdown_options( $country, $state ); ?>
@ -605,8 +599,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; // WPCS: XSS ok. ?>
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<select multiple="multiple" name="<?php echo esc_attr( $value['id'] ); ?>[]" style="width:350px" data-placeholder="<?php esc_attr_e( 'Choose countries&hellip;', 'woocommerce' ); ?>" aria-label="<?php esc_attr_e( 'Country', 'woocommerce' ); ?>" class="wc-enhanced-select">
@ -623,6 +616,45 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
<?php
break;
// Days/months/years selector.
case 'relative_date_selector':
$periods = array(
'days' => __( 'Day(s)', 'woocommerce' ),
'weeks' => __( 'Week(s)', 'woocommerce' ),
'months' => __( 'Month(s)', 'woocommerce' ),
'years' => __( 'Year(s)', 'woocommerce' ),
);
$option_value = wc_parse_relative_date_option( self::get_option( $value['id'], $value['default'] ) );
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> <?php echo $tooltip_html; // WPCS: XSS ok. ?></label>
</th>
<td class="forminp">
<input
name="<?php echo esc_attr( $value['id'] ); ?>[number]"
id="<?php echo esc_attr( $value['id'] ); ?>"
type="number"
style="width: 80px;"
value="<?php echo esc_attr( $option_value['number'] ); ?>"
class="<?php echo esc_attr( $value['class'] ); ?>"
placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
step="1"
min="1"
<?php echo implode( ' ', $custom_attributes ); // WPCS: XSS ok. ?>
/>&nbsp;
<select name="<?php echo esc_attr( $value['id'] ); ?>[unit]" style="width: auto;">
<?php
foreach ( $periods as $value => $label ) {
echo '<option value="' . esc_attr( $value ) . '"' . selected( $option_value['unit'], $value, false ) . '>' . esc_html( $label ) . '</option>';
}
?>
</select> <?php echo ( $description ) ? $description : ''; // WPCS: XSS ok. ?>
</td>
</tr>
<?php
break;
// Default: run an action.
default:
do_action( 'woocommerce_admin_field_' . $value['type'], $value );
@ -743,6 +775,9 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
$default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] );
$value = in_array( $raw_value, $allowed_values, true ) ? $raw_value : $default;
break;
case 'relative_date_selector':
$value = wc_parse_relative_date_option( $raw_value );
break;
default:
$value = wc_clean( $raw_value );
break;

View File

@ -38,7 +38,6 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'type' => 'title',
'id' => 'account_registration_options',
),
array(
'title' => __( 'Guest checkout', 'woocommerce' ),
'desc' => __( 'Allow customers to place orders without an account.', 'woocommerce' ),
@ -48,7 +47,6 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'checkboxgroup' => 'start',
'autoload' => false,
),
array(
'title' => __( 'Login', 'woocommerce' ),
'desc' => __( 'Allow customers to log into an existing account during checkout', 'woocommerce' ),
@ -58,7 +56,6 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'checkboxgroup' => 'end',
'autoload' => false,
),
array(
'title' => __( 'Account creation', 'woocommerce' ),
'desc' => __( 'Allow customers to create an account during checkout.', 'woocommerce' ),
@ -68,7 +65,6 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'checkboxgroup' => 'start',
'autoload' => false,
),
array(
'desc' => __( 'Allow customers to create an account on the "My account" page.', 'woocommerce' ),
'id' => 'woocommerce_enable_myaccount_registration',
@ -77,7 +73,6 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'checkboxgroup' => '',
'autoload' => false,
),
array(
'desc' => __( 'When creating an account, automatically generate a username from the customer\'s email address.', 'woocommerce' ),
'id' => 'woocommerce_registration_generate_username',
@ -86,7 +81,6 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'checkboxgroup' => '',
'autoload' => false,
),
array(
'desc' => __( 'When creating an account, automatically generate an account password.', 'woocommerce' ),
'id' => 'woocommerce_registration_generate_password',
@ -95,12 +89,10 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'checkboxgroup' => 'end',
'autoload' => false,
),
array(
'type' => 'sectionend',
'id' => 'account_registration_options',
),
array(
'title' => __( 'Privacy policy', 'woocommerce' ),
'type' => 'title',
@ -136,12 +128,56 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'type' => 'textarea',
'css' => 'min-width: 50%; height: 75px;',
),
array(
'type' => 'sectionend',
'id' => 'privacy_policy_options',
),
array(
'title' => __( 'Personal data cleanup', 'woocommerce' ),
'desc' => __( 'These tools let you clean up personal data when it\'s no longer needed for processing.', 'woocommerce' ),
'type' => 'title',
'id' => 'order_cleanup_options',
),
array(
'title' => __( 'Trash pending orders after: ', 'woocommerce' ),
'desc_tip' => __( 'Automatically trash orders with this status after a certain period of time. Leave blank to disable.', 'woocommerce' ),
'id' => 'woocommerce_trash_pending_orders',
'type' => 'relative_date_selector',
'placeholder' => __( 'N/A', 'woocommerce' ),
'default' => '',
'autoload' => false,
),
array(
'title' => __( 'Trash failed orders after: ', 'woocommerce' ),
'desc_tip' => __( 'Automatically trash orders with this status after a certain period of time. Leave blank to disable.', 'woocommerce' ),
'id' => 'woocommerce_trash_failed_orders',
'type' => 'relative_date_selector',
'placeholder' => __( 'N/A', 'woocommerce' ),
'default' => '',
'autoload' => false,
),
array(
'title' => __( 'Trash cancelled orders after: ', 'woocommerce' ),
'desc_tip' => __( 'Automatically trash orders with this status after a certain period of time. Leave blank to disable.', 'woocommerce' ),
'id' => 'woocommerce_trash_cancelled_orders',
'type' => 'relative_date_selector',
'placeholder' => __( 'N/A', 'woocommerce' ),
'default' => '',
'autoload' => false,
),
array(
'title' => __( 'Anonymize completed guest orders after: ', 'woocommerce' ),
'desc_tip' => __( 'Remove personal data from guest orders after a certain period of time. Leave blank to disable.', 'woocommerce' ),
'id' => 'woocommerce_anonymize_completed_orders',
'type' => 'relative_date_selector',
'placeholder' => __( 'N/A', 'woocommerce' ),
'default' => '',
'autoload' => false,
),
array(
'type' => 'sectionend',
'id' => 'order_cleanup_options',
),
)
);

View File

@ -22,8 +22,10 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( 0 !== $zone->get_id() ) : ?>
<tr valign="top" class="">
<th scope="row" class="titledesc">
<label for="zone_name"><?php esc_html_e( 'Zone name', 'woocommerce' ); ?></label>
<label for="zone_name">
<?php esc_html_e( 'Zone name', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'This is the name of the zone for your reference.', 'woocommerce' ) ); // @codingStandardsIgnoreLine ?>
</label>
</th>
<td class="forminp">
<input type="text" data-attribute="zone_name" name="zone_name" id="zone_name" value="<?php echo esc_attr( $zone->get_zone_name( 'edit' ) ); ?>" placeholder="<?php esc_attr_e( 'Zone name', 'woocommerce' ); ?>">
@ -31,8 +33,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top" class="">
<th scope="row" class="titledesc">
<label for="zone_locations"><?php esc_html_e( 'Zone regions', 'woocommerce' ); ?></label>
<label for="zone_locations">
<?php esc_html_e( 'Zone regions', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'These are regions inside this zone. Customers will be matched against these regions.', 'woocommerce' ) ); // @codingStandardsIgnoreLine ?>
</label>
</th>
<td class="forminp">
<select multiple="multiple" data-attribute="zone_locations" id="zone_locations" name="zone_locations" data-placeholder="<?php esc_html_e( 'Select regions within this zone', 'woocommerce' ); ?>" class="wc-shipping-zone-region-select chosen_select">
@ -67,8 +71,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top" class="">
<th scope="row" class="titledesc">
<label><?php esc_html_e( 'Shipping methods', 'woocommerce' ); ?></label>
<label>
<?php esc_html_e( 'Shipping methods', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'The following shipping methods apply to customers with shipping addresses within this zone.', 'woocommerce' ) ); // @codingStandardsIgnoreLine ?>
</label>
</th>
<td class="">
<table class="wc-shipping-zone-methods widefat">

View File

@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<div id="key-fields" class="settings-panel">
<h2><?php _e( 'Key details', 'woocommerce' ); ?></h2>
<h2><?php esc_html_e( 'Key details', 'woocommerce' ); ?></h2>
<input type="hidden" id="key_id" value="<?php echo esc_attr( $key_id ); ?>" />
@ -13,8 +13,10 @@ if ( ! defined( 'ABSPATH' ) ) {
<tbody>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="key_description"><?php _e( 'Description', 'woocommerce' ); ?></label>
<label for="key_description">
<?php esc_html_e( 'Description', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'Friendly name for identifying this key.', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<input id="key_description" type="text" class="input-text regular-input" value="<?php echo esc_attr( $key_data['description'] ); ?>" />
@ -22,8 +24,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="key_user"><?php _e( 'User', 'woocommerce' ); ?></label>
<label for="key_user">
<?php esc_html_e( 'User', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'Owner of these keys.', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<?php
@ -45,8 +49,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="key_permissions"><?php _e( 'Permissions', 'woocommerce' ); ?></label>
<label for="key_permissions">
<?php esc_html_e( 'Permissions', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'Select the access type of these keys.', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<select id="key_permissions" class="wc-enhanced-select">
@ -68,7 +74,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( 0 !== $key_id ) : ?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php _e( 'Consumer key ending in', 'woocommerce' ); ?>
<?php esc_html_e( 'Consumer key ending in', 'woocommerce' ); ?>
</th>
<td class="forminp">
<code>&hellip;<?php echo esc_html( $key_data['truncated_key'] ); ?></code>
@ -76,7 +82,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<?php _e( 'Last access', 'woocommerce' ); ?>
<?php esc_html_e( 'Last access', 'woocommerce' ); ?>
</th>
<td class="forminp">
<span>
@ -87,7 +93,7 @@ if ( ! defined( 'ABSPATH' ) ) {
echo apply_filters( 'woocommerce_api_key_last_access_datetime', $date, $key_data['last_access'] );
} else {
_e( 'Unknown', 'woocommerce' );
esc_html_e( 'Unknown', 'woocommerce' );
}
?>
</span>
@ -106,7 +112,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<p class="submit">
<?php submit_button( __( 'Save changes', 'woocommerce' ), 'primary', 'update_api_key', false ); ?>
<a style="color: #a00; text-decoration: none; margin-left: 10px;" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'revoke-key' => $key_id ), admin_url( 'admin.php?page=wc-settings&tab=advanced&section=keys' ) ), 'revoke' ) ); ?>"><?php _e( 'Revoke key', 'woocommerce' ); ?></a>
<a style="color: #a00; text-decoration: none; margin-left: 10px;" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'revoke-key' => $key_id ), admin_url( 'admin.php?page=wc-settings&tab=advanced&section=keys' ) ), 'revoke' ) ); ?>"><?php esc_html_e( 'Revoke key', 'woocommerce' ); ?></a>
</p>
<?php
}
@ -119,23 +125,23 @@ if ( ! defined( 'ABSPATH' ) ) {
<tbody>
<tr valign="top">
<th scope="row" class="titledesc">
<?php _e( 'Consumer key', 'woocommerce' ); ?>
<?php esc_html_e( 'Consumer key', 'woocommerce' ); ?>
</th>
<td class="forminp">
<input id="key_consumer_key" type="text" value="{{ data.consumer_key }}" size="55" readonly="readonly"> <button type="button" class="button-secondary copy-key" data-tip="<?php esc_attr_e( 'Copied!', 'woocommerce' ); ?>"><?php _e( 'Copy', 'woocommerce' ); ?></button>
<input id="key_consumer_key" type="text" value="{{ data.consumer_key }}" size="55" readonly="readonly"> <button type="button" class="button-secondary copy-key" data-tip="<?php esc_attr_e( 'Copied!', 'woocommerce' ); ?>"><?php esc_html_e( 'Copy', 'woocommerce' ); ?></button>
</td>
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<?php _e( 'Consumer secret', 'woocommerce' ); ?>
<?php esc_html_e( 'Consumer secret', 'woocommerce' ); ?>
</th>
<td class="forminp">
<input id="key_consumer_secret" type="text" value="{{ data.consumer_secret }}" size="55" readonly="readonly"> <button type="button" class="button-secondary copy-secret" data-tip="<?php esc_attr_e( 'Copied!', 'woocommerce' ); ?>"><?php _e( 'Copy', 'woocommerce' ); ?></button>
<input id="key_consumer_secret" type="text" value="{{ data.consumer_secret }}" size="55" readonly="readonly"> <button type="button" class="button-secondary copy-secret" data-tip="<?php esc_attr_e( 'Copied!', 'woocommerce' ); ?>"><?php esc_html_e( 'Copy', 'woocommerce' ); ?></button>
</td>
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<?php _e( 'QRCode', 'woocommerce' ); ?>
<?php esc_html_e( 'QRCode', 'woocommerce' ); ?>
</th>
<td class="forminp">
<div id="keys-qrcode"></div>

View File

@ -18,11 +18,13 @@ if ( ! defined( 'ABSPATH' ) ) {
<tbody>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="webhook_name"><?php esc_html_e( 'Name', 'woocommerce' ); ?></label>
<label for="webhook_name">
<?php esc_html_e( 'Name', 'woocommerce' ); ?>
<?php
/* translators: %s: date */
echo wc_help_tip( sprintf( __( 'Friendly name for identifying this webhook, defaults to Webhook created on %s.', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ) ); // @codingStandardsIgnoreLine
?>
</label>
</th>
<td class="forminp">
<input name="webhook_name" id="webhook_name" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_name() ); ?>" />
@ -30,8 +32,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="webhook_status"><?php esc_html_e( 'Status', 'woocommerce' ); ?></label>
<label for="webhook_status">
<?php esc_html_e( 'Status', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'The options are &quot;Active&quot; (delivers payload), &quot;Paused&quot; (does not deliver), or &quot;Disabled&quot; (does not deliver due delivery failures).', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<select name="webhook_status" id="webhook_status" class="wc-enhanced-select">
@ -48,8 +52,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="webhook_topic"><?php esc_html_e( 'Topic', 'woocommerce' ); ?></label>
<label for="webhook_topic">
<?php esc_html_e( 'Topic', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'Select when the webhook will fire.', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<select name="webhook_topic" id="webhook_topic" class="wc-enhanced-select">
@ -87,8 +93,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top" id="webhook-action-event-wrap">
<th scope="row" class="titledesc">
<label for="webhook_action_event"><?php esc_html_e( 'Action event', 'woocommerce' ); ?></label>
<label for="webhook_action_event">
<?php esc_html_e( 'Action event', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'Enter the action that will trigger this webhook.', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<input name="webhook_action_event" id="webhook_action_event" type="text" class="input-text regular-input" value="<?php echo esc_attr( $topic_data['event'] ); ?>" />
@ -96,8 +104,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="webhook_delivery_url"><?php esc_html_e( 'Delivery URL', 'woocommerce' ); ?></label>
<label for="webhook_delivery_url">
<?php esc_html_e( 'Delivery URL', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'URL where the webhook payload is delivered.', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<input name="webhook_delivery_url" id="webhook_delivery_url" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_delivery_url() ); ?>" />
@ -105,8 +115,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="webhook_secret"><?php esc_html_e( 'Secret', 'woocommerce' ); ?></label>
<label for="webhook_secret">
<?php esc_html_e( 'Secret', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'The secret key is used to generate a hash of the delivered webhook and provided in the request headers.', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<input name="webhook_secret" id="webhook_secret" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_secret() ); ?>" />
@ -114,8 +126,10 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="webhook_api_version"><?php esc_html_e( 'API Version', 'woocommerce' ); ?></label>
<label for="webhook_api_version">
<?php esc_html_e( 'API Version', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'REST API version used in the webhook deliveries.', 'woocommerce' ) ); ?>
</label>
</th>
<td class="forminp">
<select name="webhook_api_version" id="webhook_api_version">

View File

@ -351,6 +351,7 @@ class WC_Install {
wp_clear_scheduled_hook( 'woocommerce_scheduled_sales' );
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
wp_clear_scheduled_hook( 'woocommerce_cleanup_sessions' );
wp_clear_scheduled_hook( 'woocommerce_cleanup_orders' );
wp_clear_scheduled_hook( 'woocommerce_geoip_updater' );
wp_clear_scheduled_hook( 'woocommerce_tracker_send_event' );
@ -364,6 +365,7 @@ class WC_Install {
wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}
wp_schedule_event( time(), 'daily', 'woocommerce_cleanup_orders' );
wp_schedule_event( time(), 'twicedaily', 'woocommerce_cleanup_sessions' );
wp_schedule_event( strtotime( 'first tuesday of next month' ), 'monthly', 'woocommerce_geoip_updater' );
wp_schedule_event( time(), apply_filters( 'woocommerce_tracker_event_recurrence', 'daily' ), 'woocommerce_tracker_send_event' );

View File

@ -0,0 +1,67 @@
<?php
/**
* Order cleanup background process.
*
* @package WooCommerce/Classes
* @version 3.4.0
* @since 3.4.0
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WC_Background_Process', false ) ) {
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';
}
/**
* WC_Privacy_Background_Process class.
*/
class WC_Privacy_Background_Process extends WC_Background_Process {
/**
* Initiate new background process.
*/
public function __construct() {
// Uses unique prefix per blog so each blog has separate queue.
$this->prefix = 'wp_' . get_current_blog_id();
$this->action = 'wc_privacy_cleanup';
parent::__construct();
}
/**
* Code to execute for each item in the queue
*
* @param string $item Queue item to iterate over.
* @return bool
*/
protected function task( $item ) {
if ( ! $item || empty( $item['task'] ) ) {
return false;
}
$process_count = 0;
$process_limit = 20;
switch ( $item['task'] ) {
case 'trash_pending_orders':
$process_count = WC_Privacy::trash_pending_orders( $process_limit );
break;
case 'trash_failed_orders':
$process_count = WC_Privacy::trash_failed_orders( $process_limit );
break;
case 'trash_cancelled_orders':
$process_count = WC_Privacy::trash_cancelled_orders( $process_limit );
break;
case 'anonymize_completed_orders':
$process_count = WC_Privacy::anonymize_completed_orders( $process_limit );
break;
}
if ( $process_limit === $process_count ) {
// Needs to run again.
return $item;
}
return false;
}
}

View File

@ -13,14 +13,21 @@ defined( 'ABSPATH' ) || exit;
*/
class WC_Privacy {
/**
* Background process to clean up orders.
*
* @var WC_Privacy_Background_Process
*/
protected static $background_process;
/**
* Init - hook into events.
*/
public static function init() {
// We need to ensure we're using a version of WP with GDPR support.
if ( ! function_exists( 'wp_privacy_anonymize_data' ) ) {
return;
}
self::$background_process = new WC_Privacy_Background_Process();
// Cleanup orders daily - this is a callback on a daily cron event.
add_action( 'woocommerce_cleanup_orders', array( __CLASS__, 'order_cleanup_process' ) );
// This hook registers WooCommerce data exporters.
add_filter( 'wp_privacy_personal_data_exporters', array( __CLASS__, 'register_data_exporters' ), 10 );
@ -35,6 +42,146 @@ class WC_Privacy {
add_action( 'admin_init', array( __CLASS__, 'add_privacy_policy_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 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 ) {
self::remove_order_personal_data( $order );
$count ++;
}
}
return $count;
}
/**
* Spawn events for order cleanup.
*/
public static function order_cleanup_process() {
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();
}
/**
* 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 from guests.
*
* @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,
'customer_id' => 0,
) );
}
/**
* Registers the personal data exporter for comments.
*
@ -467,6 +614,12 @@ class WC_Privacy {
continue;
}
if ( function_exists( 'wp_privacy_anonymize_data' ) ) {
$anon_value = wp_privacy_anonymize_data( $data_type, $value );
} else {
$anon_value = '';
}
/**
* Expose a way to control the anonymized value of a prop via 3rd party code.
*
@ -477,14 +630,18 @@ class WC_Privacy {
* @param string $data_type Type of data.
* @param WC_Order $order An order object.
*/
$anonymized_data[ $prop ] = apply_filters( 'woocommerce_privacy_remove_order_personal_data_prop_value', wp_privacy_anonymize_data( $data_type, $value ), $prop, $value, $data_type, $order );
$anonymized_data[ $prop ] = apply_filters( 'woocommerce_privacy_remove_order_personal_data_prop_value', $anon_value, $prop, $value, $data_type, $order );
}
}
// Set all new props and persist the new data to the database.
$order->set_props( $anonymized_data );
$order->update_meta_data( '_anonymized', 'yes' );
$order->save();
// Add note that this event occured.
$order->add_order_note( __( 'Personal data removed.', 'woocommerce' ) );
/**
* Allow extensions to remove their own personal data for this order.
*
@ -492,9 +649,6 @@ class WC_Privacy {
* @param WC_Order $order A customer object.
*/
do_action( 'woocommerce_privacy_remove_order_personal_data', $order );
// Add note that this event occured.
$order->add_order_note( __( 'Personal data removed.', 'woocommerce' ) );
}
/**

View File

@ -327,6 +327,7 @@ final class WooCommerce {
include_once WC_ABSPATH . 'includes/customizer/class-wc-shop-customizer.php';
include_once WC_ABSPATH . 'includes/class-wc-regenerate-images.php';
include_once WC_ABSPATH . 'includes/class-wc-privacy.php';
include_once WC_ABSPATH . 'includes/class-wc-privacy-background-process.php';
/**
* Data stores - used to store and retrieve CRUD object data from the database.

View File

@ -697,6 +697,20 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
}
}
if ( isset( $query_vars['anonymized'] ) ) {
if ( $query_vars['anonymized'] ) {
$wp_query_args['meta_query'][] = array(
'key' => '_anonymized',
'value' => 'yes',
);
} else {
$wp_query_args['meta_query'][] = array(
'key' => '_anonymized',
'compare' => 'NOT EXISTS',
);
}
}
if ( ! isset( $query_vars['paginate'] ) || ! $query_vars['paginate'] ) {
$wp_query_args['no_found_rows'] = true;
}

View File

@ -1344,3 +1344,32 @@ function wc_implode_html_attributes( $raw_attributes ) {
}
return implode( ' ', $attributes );
}
/**
* Parse a relative date option from the settings API into a standard format.
*
* @since 3.4.0
* @param mixed $raw_value Value stored in DB.
* @return array Nicely formatted array with number and unit values.
*/
function wc_parse_relative_date_option( $raw_value ) {
$periods = array(
'days' => __( 'Day(s)', 'woocommerce' ),
'weeks' => __( 'Week(s)', 'woocommerce' ),
'months' => __( 'Month(s)', 'woocommerce' ),
'years' => __( 'Year(s)', 'woocommerce' ),
);
$value = wp_parse_args( (array) $raw_value, array(
'number' => '',
'unit' => 'days',
) );
$value['number'] = ! empty( $value['number'] ) ? absint( $value['number'] ) : '';
if ( ! in_array( $value['unit'], array_keys( $periods ), true ) ) {
$value['unit'] = 'days';
}
return $value;
}

View File

@ -15,6 +15,7 @@ global $wpdb, $wp_version;
wp_clear_scheduled_hook( 'woocommerce_scheduled_sales' );
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
wp_clear_scheduled_hook( 'woocommerce_cleanup_sessions' );
wp_clear_scheduled_hook( 'woocommerce_cleanup_orders' );
wp_clear_scheduled_hook( 'woocommerce_geoip_updater' );
wp_clear_scheduled_hook( 'woocommerce_tracker_send_event' );