Merge branch 'master' into feature/18477

This commit is contained in:
Claudio Sanches 2018-03-21 14:31:58 -03:00 committed by GitHub
commit 21dc6d28cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
110 changed files with 3333 additions and 2575 deletions

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

File diff suppressed because one or more lines are too long

View File

@ -13,6 +13,9 @@ body {
max-width: 30%;
}
}
.wc-setup {
text-align: center;
}
.wc-setup-content {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
padding: 2em;
@ -20,6 +23,7 @@ body {
background: #fff;
overflow: hidden;
zoom: 1;
text-align: left;
h1, h2, h3, table {
margin: 0 0 20px;
@ -297,7 +301,6 @@ body {
}
}
.woocommerce-newsletter,
.woocommerce-tracker,
.updated {
padding: 24px 24px 0;
margin: 0 0 24px;
@ -312,9 +315,74 @@ body {
margin: 0 0 24px;
}
}
.woocommerce-tracker + .woocommerce-newsletter {
margin-top: -24px;
border-top: 2px dashed #ddd;
.woocommerce-tracker {
margin: 24px 0;
border: 1px solid #eee;
padding: 20px;
border-radius: 4px;
overflow: hidden;
p {
font-size: 14px;
line-height: 1.5em;
}
.checkbox {
line-height: 24px;
font-weight: 500;
font-size: 1em;
margin-top: 0;
margin-bottom: 20px;
input[type="checkbox"] {
opacity: 0;
position: absolute;
left: -9999px;
}
label {
position: relative;
display: inline-block;
padding-left: 28px;
&:before,
&:after {
position: absolute;
content: "";
display: inline-block;
}
&:before {
height: 16px;
width: 16px;
left: 0px;
top: 3px;
border: 1px solid #aaa;
background-color: #fff;
border-radius: 3px;
}
&:after {
height: 5px;
width: 9px;
border-left: 2px solid;
border-bottom: 2px solid;
transform: rotate(-45deg);
left: 4px;
top: 7px;
color: #fff;
}
}
input[type="checkbox"] + label::after {
content: none;
}
input[type="checkbox"]:checked + label::after {
content: "";
}
input[type="checkbox"]:focus + label::before {
outline: rgb(59, 153, 252) auto 5px;
}
input[type="checkbox"]:checked + label::before {
background: #935687;
border-color: #935687;
outline: none;
}
}
}
}
.wc-setup-steps {
@ -417,8 +485,8 @@ body {
.wc-setup-footer-links {
font-size: 0.85em;
color: #b5b5b5;
margin: 1.18em 0;
display: block;
margin: 1.18em auto;
display: inline-block;
text-align: center;
}
@ -828,11 +896,21 @@ h3.jetpack-reasons {
font-size: 14px;
}
.jetpack-logo {
.jetpack-logo, .wcs-notice {
display: block;
margin: 1.75em auto 2em auto;
max-height: 175px;
}
.activate-splash {
.jetpack-logo {
width: 170px;
margin-bottom: 0;
}
.wcs-notice {
margin-top: 1em;
padding-left: 57px;
}
}
.step {
text-align: center;
@ -1072,15 +1150,6 @@ p.jetpack-terms {
}
}
.allow-tracking {
color: #9f9f9f;
margin-top: 1em;
text-align: center;
font-size: 0.9em;
padding-top: 2em;
border-top: 1px solid #ccc;
}
.wc-wizard-service-setting-stripe_create_account, .wc-wizard-service-setting-ppec_paypal_reroute_requests {
display: flex;
align-items: flex-start;

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@
setTimeout( function() {
$form.trigger( 'check_variations' );
$form.trigger( 'wc_variation_form' );
$form.loading = loading;
$form.loading = false;
}, 100 );
};

File diff suppressed because one or more lines are too long

View File

@ -5465,12 +5465,11 @@ S2.define('select2/core',[
$(document).on('keydown', function (evt) {
var key = evt.which;
if (self.isOpen()) {
if (key === KEYS.ESC || key === KEYS.TAB ||
(key === KEYS.UP && evt.altKey)) {
if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) {
self.close();
evt.preventDefault();
} else if (key === KEYS.ENTER) {
} else if (key === KEYS.ENTER || key === KEYS.TAB) {
self.trigger('results:select', {});
evt.preventDefault();

File diff suppressed because one or more lines are too long

View File

@ -5465,12 +5465,11 @@ S2.define('select2/core',[
$(document).on('keydown', function (evt) {
var key = evt.which;
if (self.isOpen()) {
if (key === KEYS.ESC || key === KEYS.TAB ||
(key === KEYS.UP && evt.altKey)) {
if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) {
self.close();
evt.preventDefault();
} else if (key === KEYS.ENTER) {
} else if (key === KEYS.ENTER || key === KEYS.TAB) {
self.trigger('results:select', {});
evt.preventDefault();

File diff suppressed because one or more lines are too long

View File

@ -110,7 +110,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
wp_register_script( 'wc-shipping-classes', WC()->plugin_url() . '/assets/js/admin/wc-shipping-classes' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone' ), WC_VERSION );
wp_register_script( 'wc-clipboard', WC()->plugin_url() . '/assets/js/admin/wc-clipboard' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'select2', WC()->plugin_url() . '/assets/js/select2/select2.full' . $suffix . '.js', array( 'jquery' ), '4.0.3' );
wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.3' );
wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.4' );
wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), WC_VERSION );
wp_localize_script(
'wc-enhanced-select',

View File

@ -2,15 +2,10 @@
/**
* Init WooCommerce data importers.
*
* @author Automattic
* @category Admin
* @package WooCommerce/Admin
* @version 3.1.0
* @package WooCommerce/Admin
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Admin_Importers Class.
@ -111,7 +106,6 @@ class WC_Admin_Importers {
* The tax rate importer which extends WP_Importer.
*/
public function tax_rates_importer() {
// Load Importer API
require_once ABSPATH . 'wp-admin/includes/import.php';
if ( ! class_exists( 'WP_Importer' ) ) {
@ -122,10 +116,8 @@ class WC_Admin_Importers {
}
}
// includes
require dirname( __FILE__ ) . '/importers/class-wc-tax-rate-importer.php';
// Dispatch
$importer = new WC_Tax_Rate_Importer();
$importer->dispatch();
}
@ -139,11 +131,11 @@ class WC_Admin_Importers {
public function post_importer_compatibility() {
global $wpdb;
if ( empty( $_POST['import_id'] ) || ! class_exists( 'WXR_Parser' ) ) {
if ( empty( $_POST['import_id'] ) || ! class_exists( 'WXR_Parser' ) ) { // PHPCS: input var ok, CSRF ok.
return;
}
$id = absint( $_POST['import_id'] );
$id = absint( $_POST['import_id'] ); // PHPCS: input var ok.
$file = get_attached_file( $id );
$parser = new WXR_Parser();
$import_data = $parser->parse( $file );
@ -156,8 +148,8 @@ class WC_Admin_Importers {
if ( ! taxonomy_exists( $term['domain'] ) ) {
$attribute_name = wc_sanitize_taxonomy_name( str_replace( 'pa_', '', $term['domain'] ) );
// Create the taxonomy
if ( ! in_array( $attribute_name, wc_get_attribute_taxonomies() ) ) {
// Create the taxonomy.
if ( ! in_array( $attribute_name, wc_get_attribute_taxonomies(), true ) ) {
wc_create_attribute(
array(
'name' => $attribute_name,
@ -198,19 +190,19 @@ class WC_Admin_Importers {
check_ajax_referer( 'wc-product-import', 'security' );
if ( ! current_user_can( 'edit_products' ) || ! isset( $_POST['file'] ) ) {
if ( ! current_user_can( 'edit_products' ) || ! isset( $_POST['file'] ) ) { // PHPCS: input var ok.
wp_die( -1 );
}
include_once WC_ABSPATH . 'includes/admin/importers/class-wc-product-csv-importer-controller.php';
include_once WC_ABSPATH . 'includes/import/class-wc-product-csv-importer.php';
$file = wc_clean( $_POST['file'] );
$file = wc_clean( wp_unslash( $_POST['file'] ) ); // PHPCS: input var ok.
$params = array(
'delimiter' => ! empty( $_POST['delimiter'] ) ? wc_clean( $_POST['delimiter'] ) : ',',
'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0,
'mapping' => isset( $_POST['mapping'] ) ? (array) $_POST['mapping'] : array(),
'update_existing' => isset( $_POST['update_existing'] ) ? (bool) $_POST['update_existing'] : false,
'delimiter' => ! empty( $_POST['delimiter'] ) ? wc_clean( wp_unslash( $_POST['delimiter'] ) ) : ',', // PHPCS: input var ok.
'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0, // PHPCS: input var ok.
'mapping' => isset( $_POST['mapping'] ) ? (array) wc_clean( wp_unslash( $_POST['mapping'] ) ) : array(), // PHPCS: input var ok.
'update_existing' => isset( $_POST['update_existing'] ) ? (bool) $_POST['update_existing'] : false, // PHPCS: input var ok.
'lines' => apply_filters( 'woocommerce_product_import_batch_size', 30 ),
'parse' => true,
);
@ -231,7 +223,7 @@ class WC_Admin_Importers {
if ( 100 === $percent_complete ) {
// Clear temp meta.
$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => '_original_id' ) );
$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => '_original_id' ) ); // @codingStandardsIgnoreLine.
$wpdb->query(
"DELETE {$wpdb->posts}, {$wpdb->postmeta}, {$wpdb->term_relationships}
FROM {$wpdb->posts}
@ -243,6 +235,14 @@ class WC_Admin_Importers {
AND {$wpdb->posts}.post_status = 'importing'"
);
// Clear orphan variations.
$wpdb->query(
"DELETE products
FROM {$wpdb->posts} products
LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent
WHERE wp.ID IS NULL AND products.post_type = 'product_variation';"
);
// Send success.
wp_send_json_success(
array(

View File

@ -171,12 +171,6 @@ class WC_Admin_Setup_Wizard {
unset( $default_steps['shipping'] );
}
// Hide the activate step if Jetpack is already active, but not
// if we're returning from connecting Jetpack on WordPress.com.
if ( class_exists( 'Jetpack' ) && Jetpack::is_active() && ! isset( $_GET['from'] ) && ! isset( $_GET['activate_error'] ) ) { // WPCS: CSRF ok, input var ok.
unset( $default_steps['activate'] );
}
// Whether or not there is a pending background install of Jetpack.
$pending_jetpack = ! class_exists( 'Jetpack' ) && get_option( 'woocommerce_setup_background_installing_jetpack' );
@ -298,21 +292,38 @@ class WC_Admin_Setup_Wizard {
* Output the steps.
*/
public function setup_wizard_steps() {
$output_steps = $this->steps;
$selected_features = array_filter( $this->wc_setup_activate_get_feature_list() );
// Hide the activate step if Jetpack is already active, unless WooCommerce Services
// features are selected, or unless the Activate step was already taken.
if ( class_exists( 'Jetpack' ) && Jetpack::is_active() && empty( $selected_features ) && 'yes' !== get_transient( 'wc_setup_activated' ) ) {
unset( $output_steps['activate'] );
}
?>
<ol class="wc-setup-steps">
<?php foreach ( $this->steps as $step_key => $step ) :
<?php
foreach ( $output_steps as $step_key => $step ) {
$is_completed = array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true );
if ( $step_key === $this->step ) : ?>
if ( $step_key === $this->step ) {
?>
<li class="active"><?php echo esc_html( $step['name'] ); ?></li>
<?php elseif ( $is_completed ) : ?>
<?php
} elseif ( $is_completed ) {
?>
<li class="done">
<a href="<?php echo esc_url( add_query_arg( 'step', $step_key, remove_query_arg( 'activate_error' ) ) ) ?>"><?php echo esc_html( $step['name'] ); ?></a>
<a href="<?php echo esc_url( add_query_arg( 'step', $step_key, remove_query_arg( 'activate_error' ) ) ); ?>"><?php echo esc_html( $step['name'] ); ?></a>
</li>
<?php else : ?>
<?php
} else {
?>
<li><?php echo esc_html( $step['name'] ); ?></li>
<?php endif; ?>
<?php endforeach; ?>
<?php
}
}
?>
</ol>
<?php
}
@ -476,12 +487,35 @@ class WC_Admin_Setup_Wizard {
<?php esc_html_e( 'I will also be selling products or services in person.', 'woocommerce' ); ?>
</label>
<?php if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) : ?>
<div class="allow-tracking">
<input type="checkbox" id="wc_tracker_optin" name="wc_tracker_optin" value="yes" checked />
<label for="wc_tracker_optin"><?php esc_html_e( 'Allow WooCommerce to collect non-sensitive diagnostic data and usage information.', 'woocommerce' ); ?></label>
<?php
if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) {
$tracking_opt_out = true;
// EU should be opt-in.
if ( in_array( $country, WC()->countries->get_european_union_countries(), true ) ) {
$tracking_opt_out = false;
}
// Respect the DNT header.
if ( ! empty( $_SERVER['HTTP_DNT'] ) ) { // WPCS: input var ok.
$tracking_opt_out = false;
}
?>
<div class="woocommerce-tracker">
<p class="checkbox">
<input type="checkbox" id="wc_tracker_optin" name="wc_tracker_optin" value="yes" <?php echo $tracking_opt_out ? 'checked' : ''; ?> />
<label for="wc_tracker_optin"><?php esc_html_e( 'Help WooCommerce improve by enabling usage tracking.', 'woocommerce' ); ?></label>
</p>
<p>
<?php
esc_html_e( 'Checking this box means making WooCommerce better &mdash; your store will be considered as we evaluate new features, judge the quality of an update, or determine if an improvement makes sense. If you do not check this box, we will not know this store exists and we will not collect any usage data.', 'woocommerce' );
echo ' <a target="_blank" href="https://woocommerce.com/usage-tracking/">' . esc_html__( 'Read more about what we collect.', 'woocommerce' ) . '</a>';
?>
</p>
</div>
<?php endif; ?>
<?php
}
?>
<p class="wc-setup-actions step">
<button type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( "Let's go!", 'woocommerce' ); ?>" name="save_step"><?php esc_html_e( "Let's go!", 'woocommerce' ); ?></button>
</p>
@ -1675,8 +1709,9 @@ class WC_Admin_Setup_Wizard {
}
}
protected function wc_setup_activate_get_description() {
$description = false;
protected function wc_setup_activate_get_feature_list() {
$features = array();
$stripe_settings = get_option( 'woocommerce_stripe_settings', false );
$stripe_enabled = is_array( $stripe_settings )
&& isset( $stripe_settings['create_account'] ) && 'yes' === $stripe_settings['create_account']
@ -1685,32 +1720,35 @@ class WC_Admin_Setup_Wizard {
$ppec_enabled = is_array( $ppec_settings )
&& isset( $ppec_settings['reroute_requests'] ) && 'yes' === $ppec_settings['reroute_requests']
&& isset( $ppec_settings['enabled'] ) && 'yes' === $ppec_settings['enabled'];
$payment_enabled = $stripe_enabled || $ppec_enabled;
$taxes_enabled = (bool) get_option( 'woocommerce_setup_automated_taxes', false );
$features['payment'] = $stripe_enabled || $ppec_enabled;
$features['taxes'] = (bool) get_option( 'woocommerce_setup_automated_taxes', false );
$domestic_rates = (bool) get_option( 'woocommerce_setup_domestic_live_rates_zone', false );
$intl_rates = (bool) get_option( 'woocommerce_setup_intl_live_rates_zone', false );
$rates_enabled = $domestic_rates || $intl_rates;
$features['rates'] = $domestic_rates || $intl_rates;
/* translators: %s: list of features, potentially comma separated */
$description_base = __( 'Your store is almost ready! To activate services like %s, just connect with Jetpack.', 'woocommerce' );
return $features;
}
if ( $payment_enabled && $taxes_enabled && $rates_enabled ) {
$description = sprintf( $description_base, __( 'payment setup, automated taxes, live rates and discounted shipping labels', 'woocommerce' ) );
} else if ( $payment_enabled && $taxes_enabled ) {
$description = sprintf( $description_base, __( 'payment setup and automated taxes', 'woocommerce' ) );
} else if ( $payment_enabled && $rates_enabled ) {
$description = sprintf( $description_base, __( 'payment setup, live rates and discounted shipping labels', 'woocommerce' ) );
} else if ( $payment_enabled ) {
$description = sprintf( $description_base, __( 'payment setup', 'woocommerce' ) );
} else if ( $taxes_enabled && $rates_enabled ) {
$description = sprintf( $description_base, __( 'automated taxes, live rates and discounted shipping labels', 'woocommerce' ) );
} else if ( $taxes_enabled ) {
$description = sprintf( $description_base, __( 'automated taxes', 'woocommerce' ) );
} else if ( $rates_enabled ) {
$description = sprintf( $description_base, __( 'live rates and discounted shipping labels', 'woocommerce' ) );
protected function wc_setup_activate_get_feature_list_str() {
$features = $this->wc_setup_activate_get_feature_list();
if ( $features['payment'] && $features['taxes'] && $features['rates'] ) {
return __( 'payment setup, automated taxes, live rates and discounted shipping labels', 'woocommerce' );
} else if ( $features['payment'] && $features['taxes'] ) {
return __( 'payment setup and automated taxes', 'woocommerce' );
} else if ( $features['payment'] && $features['rates'] ) {
return __( 'payment setup, live rates and discounted shipping labels', 'woocommerce' );
} else if ( $features['payment'] ) {
return __( 'payment setup', 'woocommerce' );
} else if ( $features['taxes'] && $features['rates'] ) {
return __( 'automated taxes, live rates and discounted shipping labels', 'woocommerce' );
} else if ( $features['taxes'] ) {
return __( 'automated taxes', 'woocommerce' );
} else if ( $features['rates'] ) {
return __( 'live rates and discounted shipping labels', 'woocommerce' );
}
return $description;
return false;
}
/**
@ -1719,6 +1757,8 @@ class WC_Admin_Setup_Wizard {
public function wc_setup_activate() {
$this->wc_setup_activate_actions();
$jetpack_connected = class_exists( 'Jetpack' ) && Jetpack::is_active();
$has_jetpack_error = false;
if ( isset( $_GET['activate_error'] ) ) {
$has_jetpack_error = true;
@ -1728,19 +1768,57 @@ class WC_Admin_Setup_Wizard {
$error_message = $this->get_activate_error_message( sanitize_text_field( wp_unslash( $_GET['activate_error'] ) ) );
$description = $error_message;
} else {
$description = $this->wc_setup_activate_get_description();
$title = $description ?
__( 'Connect your store to Jetpack', 'woocommerce' ) :
__( 'Connect your store to Jetpack to enable extra features', 'woocommerce' );
$feature_list = $this->wc_setup_activate_get_feature_list_str();
$description = false;
if ( $feature_list ) {
if ( ! $jetpack_connected ) {
/* translators: %s: list of features, potentially comma separated */
$description_base = __( 'Your store is almost ready! To activate services like %s, just connect with Jetpack.', 'woocommerce' );
} else {
$description_base = __( 'Thanks for using Jetpack! Your store is almost ready: to activate services like %s, just connect your store.', 'woocommerce' );
}
$description = sprintf( $description_base, $feature_list );
}
if ( ! $jetpack_connected ) {
$title = $feature_list ?
__( 'Connect your store to Jetpack', 'woocommerce' ) :
__( 'Connect your store to Jetpack to enable extra features', 'woocommerce' );
$button_text = __( 'Continue with Jetpack', 'woocommerce' );
} elseif ( $feature_list ) {
$title = __( 'Connect your store to activate WooCommerce Services', 'woocommerce' );
$button_text = __( 'Continue with WooCommerce Services', 'woocommerce' );
} else {
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
exit;
}
}
?>
<h1><?php echo esc_html( $title ); ?></h1>
<p><?php echo esc_html( $description ); ?></p>
<img
class="jetpack-logo"
src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/jetpack_vertical_logo.png' ); ?>"
alt="Jetpack logo"
/>
<?php if ( $jetpack_connected ) : ?>
<div class="activate-splash">
<img
class="jetpack-logo"
src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/jetpack_horizontal_logo.png' ); ?>"
alt="Jetpack logo"
/>
<img
class="wcs-notice"
src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/wcs-notice.png' ); ?>"
/>
</div>
<?php else : ?>
<img
class="jetpack-logo"
src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/jetpack_vertical_logo.png' ); ?>"
alt="Jetpack logo"
/>
<?php endif; ?>
<?php if ( $has_jetpack_error ) : ?>
<p class="wc-setup-actions step">
<a
@ -1762,53 +1840,55 @@ class WC_Admin_Setup_Wizard {
</p>
<form method="post" class="activate-jetpack">
<p class="wc-setup-actions step">
<button type="submit" class="button-primary button button-large" value="<?php esc_attr_e( 'Connect with Jetpack', 'woocommerce' ); ?>"><?php esc_html_e( 'Continue with Jetpack', 'woocommerce' ); ?></button>
<button type="submit" class="button-primary button button-large" value="<?php echo esc_attr( $button_text ); ?>"><?php echo esc_html( $button_text ); ?></button>
</p>
<input type="hidden" name="save_step" value="activate" />
<?php wp_nonce_field( 'wc-setup' ); ?>
</form>
<h3 class="jetpack-reasons">
<?php
echo esc_html( $description ?
__( "Bonus reasons you'll love Jetpack", 'woocommerce' ) :
__( "Reasons you'll love Jetpack", 'woocommerce' )
);
?>
</h3>
<ul class="wc-wizard-features">
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Better security', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Protect your store from unauthorized access.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Store stats', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Get insights on how your store is doing, including total sales, top products, and more.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Store monitoring', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Get an alert if your store is down for even a few minutes.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Product promotion', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( "Share new items on social media the moment they're live in your store.", 'woocommerce' ); ?>
</p>
</li>
</ul>
<?php if ( ! $jetpack_connected ) : ?>
<h3 class="jetpack-reasons">
<?php
echo esc_html( $description ?
__( "Bonus reasons you'll love Jetpack", 'woocommerce' ) :
__( "Reasons you'll love Jetpack", 'woocommerce' )
);
?>
</h3>
<ul class="wc-wizard-features">
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Better security', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Protect your store from unauthorized access.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Store stats', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Get insights on how your store is doing, including total sales, top products, and more.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Store monitoring', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Get an alert if your store is down for even a few minutes.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Product promotion', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( "Share new items on social media the moment they're live in your store.", 'woocommerce' ); ?>
</p>
</li>
</ul>
<?php endif; ?>
<?php endif; ?>
<?php
}
@ -1835,9 +1915,16 @@ class WC_Admin_Setup_Wizard {
public function wc_setup_activate_save() {
check_admin_referer( 'wc-setup' );
set_transient( 'wc_setup_activated', 'yes', MINUTE_IN_SECONDS * 10 );
// Leave a note for WooCommerce Services that Jetpack has been opted into.
update_option( 'woocommerce_setup_jetpack_opted_in', true );
if ( class_exists( 'Jetpack' ) && Jetpack::is_active() ) {
wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) );
exit;
}
WC_Install::background_installer( 'jetpack', array(
'file' => 'jetpack/jetpack.php',
'name' => __( 'Jetpack', 'woocommerce' ),

View File

@ -454,10 +454,9 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
// Search using CRUD.
if ( ! empty( $query_vars['s'] ) ) {
$data_store = WC_Data_Store::load( 'product' );
$ids = $data_store->search_products( wc_clean( $query_vars['s'] ), '', true, true );
$query_vars['post__in'] = array_merge( $ids, array( 0 ) );
// So we know we are searching products.
$data_store = WC_Data_Store::load( 'product' );
$ids = $data_store->search_products( wc_clean( wp_unslash( $query_vars['s'] ) ), '', true, true );
$query_vars['post__in'] = array_merge( $ids, array( 0 ) );
$query_vars['product_search'] = true;
unset( $query_vars['s'] );
}

View File

@ -1,394 +1,393 @@
<?php
<?php // @codingStandardsIgnoreLine.
/**
* WooCommerce Shipping Settings
* WooCommerce Checkout Settings
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
defined( 'ABSPATH' ) || exit;
if ( class_exists( 'WC_Settings_Payment_Gateways', false ) ) {
return new WC_Settings_Payment_Gateways();
}
if ( ! class_exists( 'WC_Settings_Payment_Gateways', false ) ) :
/**
* WC_Settings_Payment_Gateways.
*/
class WC_Settings_Payment_Gateways extends WC_Settings_Page {
/**
* WC_Settings_Payment_Gateways.
* Constructor.
*/
class WC_Settings_Payment_Gateways extends WC_Settings_Page {
public function __construct() {
$this->id = 'checkout';
$this->label = _x( 'Checkout', 'Settings tab label', 'woocommerce' );
/**
* Constructor.
*/
public function __construct() {
$this->id = 'checkout';
$this->label = _x( 'Checkout', 'Settings tab label', 'woocommerce' );
add_action( 'woocommerce_admin_field_payment_gateways', array( $this, 'payment_gateways_setting' ) );
parent::__construct();
}
add_action( 'woocommerce_admin_field_payment_gateways', array( $this, 'payment_gateways_setting' ) );
parent::__construct();
}
/**
* Get sections.
*
* @return array
*/
public function get_sections() {
$sections = array(
'' => __( 'Checkout options', 'woocommerce' ),
);
/**
* Get sections.
*
* @return array
*/
public function get_sections() {
$sections = array(
'' => __( 'Checkout options', 'woocommerce' ),
);
if ( ! defined( 'WC_INSTALLING' ) ) {
$payment_gateways = WC()->payment_gateways->payment_gateways();
foreach ( $payment_gateways as $gateway ) {
$title = empty( $gateway->method_title ) ? ucfirst( $gateway->id ) : $gateway->method_title;
$sections[ strtolower( $gateway->id ) ] = esc_html( $title );
}
}
return apply_filters( 'woocommerce_get_sections_' . $this->id, $sections );
}
/**
* Get settings array.
*
* @param string $current_section
*
* @return array
*/
public function get_settings( $current_section = '' ) {
$settings = array();
if ( '' === $current_section ) {
$settings = apply_filters(
'woocommerce_payment_gateways_settings', array(
array(
'title' => __( 'Checkout process', 'woocommerce' ),
'type' => 'title',
'id' => 'checkout_process_options',
),
array(
'title' => __( 'Coupons', 'woocommerce' ),
'desc' => __( 'Enable the use of coupons', 'woocommerce' ),
'id' => 'woocommerce_enable_coupons',
'default' => 'yes',
'type' => 'checkbox',
'checkboxgroup' => 'start',
'desc_tip' => __( 'Coupons can be applied from the cart and checkout pages.', 'woocommerce' ),
),
array(
'desc' => __( 'Calculate coupon discounts sequentially', 'woocommerce' ),
'id' => 'woocommerce_calc_discounts_sequentially',
'default' => 'no',
'type' => 'checkbox',
'desc_tip' => __( 'When applying multiple coupons, apply the first coupon to the full price and the second coupon to the discounted price and so on.', 'woocommerce' ),
'checkboxgroup' => 'end',
'autoload' => false,
),
array(
'title' => __( 'Checkout process', 'woocommerce' ),
'desc' => __( 'Enable guest checkout', 'woocommerce' ),
'desc_tip' => __( 'Allows customers to checkout without creating an account.', 'woocommerce' ),
'id' => 'woocommerce_enable_guest_checkout',
'default' => 'yes',
'type' => 'checkbox',
'checkboxgroup' => 'start',
'autoload' => false,
),
array(
'desc' => __( 'Force secure checkout', 'woocommerce' ),
'id' => 'woocommerce_force_ssl_checkout',
'default' => 'no',
'type' => 'checkbox',
'checkboxgroup' => '',
'show_if_checked' => 'option',
'desc_tip' => sprintf( __( 'Force SSL (HTTPS) on the checkout pages (<a href="%s" target="_blank">an SSL Certificate is required</a>).', 'woocommerce' ), 'https://docs.woocommerce.com/document/ssl-and-https/#section-3' ),
),
'unforce_ssl_checkout' => array(
'desc' => __( 'Force HTTP when leaving the checkout', 'woocommerce' ),
'id' => 'woocommerce_unforce_ssl_checkout',
'default' => 'no',
'type' => 'checkbox',
'checkboxgroup' => 'end',
'show_if_checked' => 'yes',
),
array(
'type' => 'sectionend',
'id' => 'checkout_process_options',
),
array(
'title' => __( 'Checkout pages', 'woocommerce' ),
'desc' => __( 'These pages need to be set so that WooCommerce knows where to send users to checkout.', 'woocommerce' ),
'type' => 'title',
'id' => 'checkout_page_options',
),
array(
'title' => __( 'Cart page', 'woocommerce' ),
'desc' => sprintf( __( 'Page contents: [%s]', 'woocommerce' ), apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) ),
'id' => 'woocommerce_cart_page_id',
'type' => 'single_select_page',
'default' => '',
'class' => 'wc-enhanced-select-nostd',
'css' => 'min-width:300px;',
'desc_tip' => true,
),
array(
'title' => __( 'Checkout page', 'woocommerce' ),
'desc' => sprintf( __( 'Page contents: [%s]', 'woocommerce' ), apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) ),
'id' => 'woocommerce_checkout_page_id',
'type' => 'single_select_page',
'default' => '',
'class' => 'wc-enhanced-select-nostd',
'css' => 'min-width:300px;',
'desc_tip' => true,
),
array(
'title' => __( 'Terms and conditions', 'woocommerce' ),
'desc' => __( 'If you define a "Terms" page the customer will be asked if they accept them when checking out.', 'woocommerce' ),
'id' => 'woocommerce_terms_page_id',
'default' => '',
'class' => 'wc-enhanced-select-nostd',
'css' => 'min-width:300px;',
'type' => 'single_select_page',
'args' => array( 'exclude' => wc_get_page_id( 'checkout' ) ),
'desc_tip' => true,
'autoload' => false,
),
array(
'type' => 'sectionend',
'id' => 'checkout_page_options',
),
array(
'title' => __( 'Checkout endpoints', 'woocommerce' ),
'type' => 'title',
'desc' => __( 'Endpoints are appended to your page URLs to handle specific actions during the checkout process. They should be unique.', 'woocommerce' ),
'id' => 'account_endpoint_options',
),
array(
'title' => __( 'Pay', 'woocommerce' ),
'desc' => __( 'Endpoint for the "Checkout &rarr; Pay" page.', 'woocommerce' ),
'id' => 'woocommerce_checkout_pay_endpoint',
'type' => 'text',
'default' => 'order-pay',
'desc_tip' => true,
),
array(
'title' => __( 'Order received', 'woocommerce' ),
'desc' => __( 'Endpoint for the "Checkout &rarr; Order received" page.', 'woocommerce' ),
'id' => 'woocommerce_checkout_order_received_endpoint',
'type' => 'text',
'default' => 'order-received',
'desc_tip' => true,
),
array(
'title' => __( 'Add payment method', 'woocommerce' ),
'desc' => __( 'Endpoint for the "Checkout &rarr; Add payment method" page.', 'woocommerce' ),
'id' => 'woocommerce_myaccount_add_payment_method_endpoint',
'type' => 'text',
'default' => 'add-payment-method',
'desc_tip' => true,
),
array(
'title' => __( 'Delete payment method', 'woocommerce' ),
'desc' => __( 'Endpoint for the delete payment method page.', 'woocommerce' ),
'id' => 'woocommerce_myaccount_delete_payment_method_endpoint',
'type' => 'text',
'default' => 'delete-payment-method',
'desc_tip' => true,
),
array(
'title' => __( 'Set default payment method', 'woocommerce' ),
'desc' => __( 'Endpoint for the setting a default payment method page.', 'woocommerce' ),
'id' => 'woocommerce_myaccount_set_default_payment_method_endpoint',
'type' => 'text',
'default' => 'set-default-payment-method',
'desc_tip' => true,
),
array(
'type' => 'sectionend',
'id' => 'checkout_endpoint_options',
),
array(
'title' => __( 'Payment gateways', 'woocommerce' ),
'desc' => __( 'Installed gateways are listed below. Drag and drop gateways to control their display order on the frontend.', 'woocommerce' ),
'type' => 'title',
'id' => 'payment_gateways_options',
),
array(
'type' => 'payment_gateways',
),
array(
'type' => 'sectionend',
'id' => 'payment_gateways_options',
),
)
);
if ( wc_site_is_https() ) {
unset( $settings['unforce_ssl_checkout'] );
}
}
return apply_filters( 'woocommerce_get_settings_' . $this->id, $settings, $current_section );
}
/**
* Output the settings.
*/
public function output() {
global $current_section;
// Load shipping methods so we can show any global options they may have.
if ( ! defined( 'WC_INSTALLING' ) ) {
$payment_gateways = WC()->payment_gateways->payment_gateways();
if ( $current_section ) {
foreach ( $payment_gateways as $gateway ) {
if ( in_array( $current_section, array( $gateway->id, sanitize_title( get_class( $gateway ) ) ) ) ) {
$gateway->admin_options();
break;
}
}
} else {
$settings = $this->get_settings();
WC_Admin_Settings::output_fields( $settings );
foreach ( $payment_gateways as $gateway ) {
$title = empty( $gateway->method_title ) ? ucfirst( $gateway->id ) : $gateway->method_title;
$sections[ strtolower( $gateway->id ) ] = esc_html( $title );
}
}
/**
* Output payment gateway settings.
*/
public function payment_gateways_setting() {
?>
<tr valign="top">
<th scope="row" class="titledesc"><?php _e( 'Gateway display order', 'woocommerce' ); ?></th>
<td class="forminp">
<table class="wc_gateways widefat" cellspacing="0">
<thead>
<tr>
<?php
$columns = apply_filters(
'woocommerce_payment_gateways_setting_columns', array(
'sort' => '',
'name' => __( 'Gateway', 'woocommerce' ),
'id' => __( 'Gateway ID', 'woocommerce' ),
'status' => __( 'Enabled', 'woocommerce' ),
)
);
return apply_filters( 'woocommerce_get_sections_' . $this->id, $sections );
}
foreach ( $columns as $key => $column ) {
echo '<th class="' . esc_attr( $key ) . '">' . esc_html( $column ) . '</th>';
}
?>
</tr>
</thead>
<tbody>
<?php
foreach ( WC()->payment_gateways->payment_gateways() as $gateway ) {
/**
* Get settings array.
*
* @param string $current_section Section being shown.
* @return array
*/
public function get_settings( $current_section = '' ) {
$settings = array();
echo '<tr>';
if ( '' === $current_section ) {
$settings = apply_filters(
'woocommerce_payment_gateways_settings', array(
foreach ( $columns as $key => $column ) {
array(
'title' => __( 'Checkout process', 'woocommerce' ),
'type' => 'title',
'id' => 'checkout_process_options',
),
switch ( $key ) {
array(
'title' => __( 'Coupons', 'woocommerce' ),
'desc' => __( 'Enable the use of coupons', 'woocommerce' ),
'id' => 'woocommerce_enable_coupons',
'default' => 'yes',
'type' => 'checkbox',
'checkboxgroup' => 'start',
'desc_tip' => __( 'Coupons can be applied from the cart and checkout pages.', 'woocommerce' ),
),
case 'sort':
echo '<td width="1%" class="sort">
<input type="hidden" name="gateway_order[]" value="' . esc_attr( $gateway->id ) . '" />
</td>';
break;
array(
'desc' => __( 'Calculate coupon discounts sequentially', 'woocommerce' ),
'id' => 'woocommerce_calc_discounts_sequentially',
'default' => 'no',
'type' => 'checkbox',
'desc_tip' => __( 'When applying multiple coupons, apply the first coupon to the full price and the second coupon to the discounted price and so on.', 'woocommerce' ),
'checkboxgroup' => 'end',
'autoload' => false,
),
case 'name':
$method_title = $gateway->get_title() ? $gateway->get_title() : __( '(no title)', 'woocommerce' );
echo '<td class="name">
<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout&section=' . strtolower( $gateway->id ) ) . '">' . esc_html( $method_title ) . '</a>
</td>';
break;
array(
'title' => __( 'Checkout process', 'woocommerce' ),
'desc' => __( 'Enable guest checkout', 'woocommerce' ),
'desc_tip' => __( 'Allows customers to checkout without creating an account.', 'woocommerce' ),
'id' => 'woocommerce_enable_guest_checkout',
'default' => 'yes',
'type' => 'checkbox',
'checkboxgroup' => 'start',
'autoload' => false,
),
case 'id':
echo '<td class="id">' . esc_html( $gateway->id ) . '</td>';
break;
array(
'desc' => __( 'Force secure checkout', 'woocommerce' ),
'id' => 'woocommerce_force_ssl_checkout',
'default' => 'no',
'type' => 'checkbox',
'checkboxgroup' => '',
'show_if_checked' => 'option',
/* Translators: %s Docs URL. */
'desc_tip' => sprintf( __( 'Force SSL (HTTPS) on the checkout pages (<a href="%s" target="_blank">an SSL Certificate is required</a>).', 'woocommerce' ), 'https://docs.woocommerce.com/document/ssl-and-https/#section-3' ),
),
case 'status':
echo '<td class="status">';
echo ( 'yes' === $gateway->enabled ) ? '<span class="status-enabled tips" data-tip="' . esc_attr__( 'Yes', 'woocommerce' ) . '">' . esc_html__( 'Yes', 'woocommerce' ) . '</span>' : '-';
echo '</td>';
break;
'unforce_ssl_checkout' => array(
'desc' => __( 'Force HTTP when leaving the checkout', 'woocommerce' ),
'id' => 'woocommerce_unforce_ssl_checkout',
'default' => 'no',
'type' => 'checkbox',
'checkboxgroup' => 'end',
'show_if_checked' => 'yes',
),
default:
do_action( 'woocommerce_payment_gateways_setting_column_' . $key, $gateway );
break;
}
}
array(
'type' => 'sectionend',
'id' => 'checkout_process_options',
),
echo '</tr>';
}
?>
</tbody>
</table>
</td>
</tr>
<?php
array(
'title' => __( 'Checkout pages', 'woocommerce' ),
'desc' => __( 'These pages need to be set so that WooCommerce knows where to send users to checkout.', 'woocommerce' ),
'type' => 'title',
'id' => 'checkout_page_options',
),
array(
'title' => __( 'Cart page', 'woocommerce' ),
/* Translators: %s Page contents. */
'desc' => sprintf( __( 'Page contents: [%s]', 'woocommerce' ), apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) ),
'id' => 'woocommerce_cart_page_id',
'type' => 'single_select_page',
'default' => '',
'class' => 'wc-enhanced-select-nostd',
'css' => 'min-width:300px;',
'desc_tip' => true,
),
array(
'title' => __( 'Checkout page', 'woocommerce' ),
/* Translators: %s Page contents. */
'desc' => sprintf( __( 'Page contents: [%s]', 'woocommerce' ), apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) ),
'id' => 'woocommerce_checkout_page_id',
'type' => 'single_select_page',
'default' => '',
'class' => 'wc-enhanced-select-nostd',
'css' => 'min-width:300px;',
'desc_tip' => true,
),
array(
'title' => __( 'Terms and conditions', 'woocommerce' ),
'desc' => __( 'If you define a "Terms" page the customer will be asked if they accept them when checking out.', 'woocommerce' ),
'id' => 'woocommerce_terms_page_id',
'default' => '',
'class' => 'wc-enhanced-select-nostd',
'css' => 'min-width:300px;',
'type' => 'single_select_page',
'args' => array( 'exclude' => wc_get_page_id( 'checkout' ) ),
'desc_tip' => true,
'autoload' => false,
),
array(
'type' => 'sectionend',
'id' => 'checkout_page_options',
),
array(
'title' => __( 'Checkout endpoints', 'woocommerce' ),
'type' => 'title',
'desc' => __( 'Endpoints are appended to your page URLs to handle specific actions during the checkout process. They should be unique.', 'woocommerce' ),
'id' => 'account_endpoint_options',
),
array(
'title' => __( 'Pay', 'woocommerce' ),
'desc' => __( 'Endpoint for the "Checkout &rarr; Pay" page.', 'woocommerce' ),
'id' => 'woocommerce_checkout_pay_endpoint',
'type' => 'text',
'default' => 'order-pay',
'desc_tip' => true,
),
array(
'title' => __( 'Order received', 'woocommerce' ),
'desc' => __( 'Endpoint for the "Checkout &rarr; Order received" page.', 'woocommerce' ),
'id' => 'woocommerce_checkout_order_received_endpoint',
'type' => 'text',
'default' => 'order-received',
'desc_tip' => true,
),
array(
'title' => __( 'Add payment method', 'woocommerce' ),
'desc' => __( 'Endpoint for the "Checkout &rarr; Add payment method" page.', 'woocommerce' ),
'id' => 'woocommerce_myaccount_add_payment_method_endpoint',
'type' => 'text',
'default' => 'add-payment-method',
'desc_tip' => true,
),
array(
'title' => __( 'Delete payment method', 'woocommerce' ),
'desc' => __( 'Endpoint for the delete payment method page.', 'woocommerce' ),
'id' => 'woocommerce_myaccount_delete_payment_method_endpoint',
'type' => 'text',
'default' => 'delete-payment-method',
'desc_tip' => true,
),
array(
'title' => __( 'Set default payment method', 'woocommerce' ),
'desc' => __( 'Endpoint for the setting a default payment method page.', 'woocommerce' ),
'id' => 'woocommerce_myaccount_set_default_payment_method_endpoint',
'type' => 'text',
'default' => 'set-default-payment-method',
'desc_tip' => true,
),
array(
'type' => 'sectionend',
'id' => 'checkout_endpoint_options',
),
array(
'title' => __( 'Payment gateways', 'woocommerce' ),
'desc' => __( 'Installed gateways are listed below. Drag and drop gateways to control their display order on the frontend.', 'woocommerce' ),
'type' => 'title',
'id' => 'payment_gateways_options',
),
array(
'type' => 'payment_gateways',
),
array(
'type' => 'sectionend',
'id' => 'payment_gateways_options',
),
)
);
if ( wc_site_is_https() ) {
unset( $settings['unforce_ssl_checkout'] );
}
}
/**
* Save settings.
*/
public function save() {
global $current_section;
return apply_filters( 'woocommerce_get_settings_' . $this->id, $settings, $current_section );
}
$wc_payment_gateways = WC_Payment_Gateways::instance();
/**
* Output the settings.
*/
public function output() {
global $current_section;
if ( ! $current_section ) {
// Prevent the T&Cs and checkout page from being set to the same page.
if ( isset( $_POST['woocommerce_terms_page_id'], $_POST['woocommerce_checkout_page_id'] ) && $_POST['woocommerce_terms_page_id'] === $_POST['woocommerce_checkout_page_id'] ) {
$_POST['woocommerce_terms_page_id'] = '';
}
// Load gateways so we can show any global options they may have.
$payment_gateways = WC()->payment_gateways->payment_gateways();
WC_Admin_Settings::save_fields( $this->get_settings() );
$wc_payment_gateways->process_admin_options();
} else {
foreach ( $wc_payment_gateways->payment_gateways() as $gateway ) {
if ( in_array( $current_section, array( $gateway->id, sanitize_title( get_class( $gateway ) ) ) ) ) {
do_action( 'woocommerce_update_options_payment_gateways_' . $gateway->id );
$wc_payment_gateways->init();
}
if ( $current_section ) {
foreach ( $payment_gateways as $gateway ) {
if ( in_array( $current_section, array( $gateway->id, sanitize_title( get_class( $gateway ) ) ), true ) ) {
$gateway->admin_options();
break;
}
}
} else {
$settings = $this->get_settings();
if ( $current_section ) {
do_action( 'woocommerce_update_options_' . $this->id . '_' . $current_section );
}
WC_Admin_Settings::output_fields( $settings );
}
}
endif;
/**
* Output payment gateway settings.
*/
public function payment_gateways_setting() {
?>
<tr valign="top">
<th scope="row" class="titledesc"><?php esc_html_e( 'Gateway display order', 'woocommerce' ); ?></th>
<td class="forminp">
<table class="wc_gateways widefat" cellspacing="0">
<thead>
<tr>
<?php
$columns = apply_filters(
'woocommerce_payment_gateways_setting_columns', array(
'sort' => '',
'name' => __( 'Gateway', 'woocommerce' ),
'id' => __( 'Gateway ID', 'woocommerce' ),
'status' => __( 'Enabled', 'woocommerce' ),
)
);
foreach ( $columns as $key => $column ) {
echo '<th class="' . esc_attr( $key ) . '">' . esc_html( $column ) . '</th>';
}
?>
</tr>
</thead>
<tbody>
<?php
foreach ( WC()->payment_gateways->payment_gateways() as $gateway ) {
echo '<tr>';
foreach ( $columns as $key => $column ) {
switch ( $key ) {
case 'sort':
echo '<td width="1%" class="sort">
<input type="hidden" name="gateway_order[]" value="' . esc_attr( $gateway->id ) . '" />
</td>';
break;
case 'name':
$method_title = $gateway->get_title() ? $gateway->get_title() : __( '(no title)', 'woocommerce' );
echo '<td class="name">
<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=checkout&section=' . strtolower( $gateway->id ) ) ) . '">' . esc_html( $method_title ) . '</a>
</td>';
break;
case 'id':
echo '<td class="id">' . esc_html( $gateway->id ) . '</td>';
break;
case 'status':
echo '<td class="status">';
echo ( 'yes' === $gateway->enabled ) ? '<span class="status-enabled tips" data-tip="' . esc_attr__( 'Yes', 'woocommerce' ) . '">' . esc_html__( 'Yes', 'woocommerce' ) . '</span>' : '-';
echo '</td>';
break;
default:
do_action( 'woocommerce_payment_gateways_setting_column_' . $key, $gateway );
break;
}
}
echo '</tr>';
}
?>
</tbody>
</table>
</td>
</tr>
<?php
}
/**
* Save settings.
*/
public function save() {
global $current_section;
$wc_payment_gateways = WC_Payment_Gateways::instance();
if ( ! $current_section ) {
// Prevent the T&Cs and checkout page from being set to the same page.
if ( isset( $_POST['woocommerce_terms_page_id'], $_POST['woocommerce_checkout_page_id'] ) && $_POST['woocommerce_terms_page_id'] === $_POST['woocommerce_checkout_page_id'] ) { // WPCS: input var ok, CSRF ok.
$_POST['woocommerce_terms_page_id'] = '';
}
WC_Admin_Settings::save_fields( $this->get_settings() );
$wc_payment_gateways->process_admin_options();
$wc_payment_gateways->init();
} else {
foreach ( $wc_payment_gateways->payment_gateways() as $gateway ) {
if ( in_array( $current_section, array( $gateway->id, sanitize_title( get_class( $gateway ) ) ), true ) ) {
do_action( 'woocommerce_update_options_payment_gateways_' . $gateway->id );
$wc_payment_gateways->init();
}
}
}
if ( $current_section ) {
do_action( 'woocommerce_update_options_' . $this->id . '_' . $current_section );
}
}
}
return new WC_Settings_Payment_Gateways();

View File

@ -1,16 +0,0 @@
<?php
/**
* Admin View: Notice - Tracking
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<div id="message" class="updated woocommerce-message woocommerce-tracker">
<p><?php printf( __( 'Want to help make WooCommerce even more awesome? Allow WooCommerce to collect non-sensitive diagnostic data and usage information, and get %1$s discount on your next WooThemes purchase. <a href="%2$s" target="_blank">Find out more</a>.', 'woocommerce' ), '20%', 'https://woocommerce.com/usage-tracking/' ); ?></p>
<p class="submit">
<a class="button-primary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc_tracker_optin', 'true' ), 'wc_tracker_optin', 'wc_tracker_nonce' ) ); ?>"><?php _e( 'Allow', 'woocommerce' ); ?></a>
<a class="skip button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc-hide-notice', 'tracking' ), 'woocommerce_hide_notices_nonce', '_wc_notice_nonce' ) ); ?>"><?php _e( 'No, do not bother me again', 'woocommerce' ); ?></a>
</p>
</div>

View File

@ -166,6 +166,7 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
'amount' => $data['amount'],
'reason' => $data['reason'],
'refunded_by' => $data['refunded_by'],
'refunded_payment' => $data['refunded_payment'],
'meta_data' => $data['meta_data'],
'line_items' => $data['line_items'],
);
@ -383,6 +384,11 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
'type' => 'integer',
'context' => array( 'view', 'edit' ),
),
'refunded_payment' => array(
'description' => __( 'If the payment was refunded via the API.', 'woocommerce' ),
'type' => 'boolean',
'context' => array( 'view' ),
),
'meta_data' => array(
'description' => __( 'Meta data.', 'woocommerce' ),
'type' => 'array',

View File

@ -4,15 +4,11 @@
*
* Handles WC-API endpoint requests.
*
* @author WooThemes
* @category API
* @package WooCommerce/API
* @since 2.0
* @package WooCommerce/API
* @since 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* API class.
@ -130,78 +126,78 @@ class WC_API extends WC_Legacy_API {
*/
private function rest_api_includes() {
// Exception handler.
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-exception.php' );
include_once dirname( __FILE__ ) . '/api/class-wc-rest-exception.php';
// Authentication.
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-authentication.php' );
include_once dirname( __FILE__ ) . '/api/class-wc-rest-authentication.php';
// Abstract controllers.
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-controller.php' );
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-posts-controller.php' );
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-crud-controller.php' );
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-terms-controller.php' );
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-shipping-zones-controller.php' );
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-settings-api.php' );
include_once dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-controller.php';
include_once dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-posts-controller.php';
include_once dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-crud-controller.php';
include_once dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-terms-controller.php';
include_once dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-shipping-zones-controller.php';
include_once dirname( __FILE__ ) . '/abstracts/abstract-wc-settings-api.php';
// REST API v1 controllers.
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-coupons-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-customer-downloads-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-customers-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-orders-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-order-notes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-order-refunds-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-attribute-terms-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-attributes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-categories-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-reviews-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-shipping-classes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-tags-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-products-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-report-sales-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-report-top-sellers-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-reports-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-tax-classes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-taxes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-webhook-deliveries-controller.php' );
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-webhooks-controller.php' );
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-coupons-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-customer-downloads-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-customers-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-orders-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-order-notes-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-order-refunds-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-attribute-terms-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-attributes-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-categories-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-reviews-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-shipping-classes-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-product-tags-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-products-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-report-sales-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-report-top-sellers-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-reports-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-tax-classes-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-taxes-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-webhook-deliveries-controller.php';
include_once dirname( __FILE__ ) . '/api/v1/class-wc-rest-webhooks-controller.php';
// Legacy v2 code.
include_once( dirname( __FILE__ ) . '/api/legacy/class-wc-rest-legacy-coupons-controller.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/class-wc-rest-legacy-orders-controller.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/class-wc-rest-legacy-products-controller.php' );
include_once dirname( __FILE__ ) . '/api/legacy/class-wc-rest-legacy-coupons-controller.php';
include_once dirname( __FILE__ ) . '/api/legacy/class-wc-rest-legacy-orders-controller.php';
include_once dirname( __FILE__ ) . '/api/legacy/class-wc-rest-legacy-products-controller.php';
// REST API v2 controllers.
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-coupons-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-customer-downloads-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-customers-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-orders-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-network-orders-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-order-notes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-order-refunds-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-attribute-terms-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-attributes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-categories-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-reviews-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-shipping-classes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-tags-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-products-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-variations-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-report-sales-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-report-top-sellers-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-reports-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-settings-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-setting-options-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zones-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zone-locations-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zone-methods-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-tax-classes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-taxes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhook-deliveries-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhooks-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-system-status-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-system-status-tools-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-methods-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-payment-gateways-controller.php' );
include_once dirname( __FILE__ ) . '/api/class-wc-rest-coupons-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-customer-downloads-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-customers-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-orders-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-network-orders-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-order-notes-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-order-refunds-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-product-attribute-terms-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-product-attributes-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-product-categories-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-product-reviews-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-product-shipping-classes-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-product-tags-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-products-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-product-variations-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-report-sales-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-report-top-sellers-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-reports-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-settings-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-setting-options-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zones-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zone-locations-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zone-methods-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-tax-classes-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-taxes-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-webhook-deliveries-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-webhooks-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-system-status-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-system-status-tools-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-shipping-methods-controller.php';
include_once dirname( __FILE__ ) . '/api/class-wc-rest-payment-gateways-controller.php';
}
/**

View File

@ -4,15 +4,15 @@
*
* Handles wc-auth endpoint requests.
*
* @author WooThemes
* @category API
* @package WooCommerce/API
* @since 2.4.0
* @package WooCommerce/API
* @since 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* Auth class.
*/
class WC_Auth {
/**
@ -28,23 +28,21 @@ class WC_Auth {
* @since 2.4.0
*/
public function __construct() {
// Add query vars
// Add query vars.
add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
// Register auth endpoint
// Register auth endpoint.
add_action( 'init', array( __CLASS__, 'add_endpoint' ), 0 );
// Handle auth requests
add_action( 'parse_request', array( $this, 'handle_auth_requests' ), 0 );
// Handle auth requests.
add_action( 'parse_request.', array( $this, 'handle_auth_requests' ), 0 );
}
/**
* Add query vars.
*
* @since 2.4.0
*
* @param array $vars
*
* @param array $vars Query variables.
* @return string[]
*/
public function add_query_vars( $vars ) {
@ -66,9 +64,7 @@ class WC_Auth {
* Get scope name.
*
* @since 2.4.0
*
* @param string $scope
*
* @param string $scope Permission scope.
* @return string
*/
protected function get_i18n_scope( $scope ) {
@ -85,34 +81,32 @@ class WC_Auth {
* Return a list of permissions a scope allows.
*
* @since 2.4.0
*
* @param string $scope
*
* @param string $scope Permission scope.
* @return array
*/
protected function get_permissions_in_scope( $scope ) {
$permissions = array();
switch ( $scope ) {
case 'read' :
case 'read':
$permissions[] = __( 'View coupons', 'woocommerce' );
$permissions[] = __( 'View customers', 'woocommerce' );
$permissions[] = __( 'View orders and sales reports', 'woocommerce' );
$permissions[] = __( 'View products', 'woocommerce' );
break;
case 'write' :
break;
case 'write':
$permissions[] = __( 'Create webhooks', 'woocommerce' );
$permissions[] = __( 'Create coupons', 'woocommerce' );
$permissions[] = __( 'Create customers', 'woocommerce' );
$permissions[] = __( 'Create orders', 'woocommerce' );
$permissions[] = __( 'Create products', 'woocommerce' );
break;
case 'read_write' :
break;
case 'read_write':
$permissions[] = __( 'Create webhooks', 'woocommerce' );
$permissions[] = __( 'View and manage coupons', 'woocommerce' );
$permissions[] = __( 'View and manage customers', 'woocommerce' );
$permissions[] = __( 'View and manage orders and sales reports', 'woocommerce' );
$permissions[] = __( 'View and manage products', 'woocommerce' );
break;
break;
}
return apply_filters( 'woocommerce_api_permissions_in_scope', $permissions, $scope );
}
@ -121,27 +115,28 @@ class WC_Auth {
* Build auth urls.
*
* @since 2.4.0
*
* @param array $data
* @param string $endpoint
*
* @param array $data Data to build URL.
* @param string $endpoint Endpoint.
* @return string
*/
protected function build_url( $data, $endpoint ) {
$url = wc_get_endpoint_url( 'wc-auth/v' . self::VERSION, $endpoint, home_url( '/' ) );
return add_query_arg( array(
'app_name' => wc_clean( $data['app_name'] ),
'user_id' => wc_clean( $data['user_id'] ),
'return_url' => urlencode( $this->get_formatted_url( $data['return_url'] ) ),
'callback_url' => urlencode( $this->get_formatted_url( $data['callback_url'] ) ),
'scope' => wc_clean( $data['scope'] ),
), $url );
return add_query_arg(
array(
'app_name' => wc_clean( $data['app_name'] ),
'user_id' => wc_clean( $data['user_id'] ),
'return_url' => rawurlencode( $this->get_formatted_url( $data['return_url'] ) ),
'callback_url' => rawurlencode( $this->get_formatted_url( $data['callback_url'] ) ),
'scope' => wc_clean( $data['scope'] ),
), $url
);
}
/**
* Decode and format a URL.
* @param string $url
*
* @param string $url URL.
* @return string
*/
protected function get_formatted_url( $url ) {
@ -158,8 +153,10 @@ class WC_Auth {
* Make validation.
*
* @since 2.4.0
* @throws Exception When validate fails.
*/
protected function make_validation() {
$data = array();
$params = array(
'app_name',
'user_id',
@ -169,19 +166,21 @@ class WC_Auth {
);
foreach ( $params as $param ) {
if ( empty( $_REQUEST[ $param ] ) ) {
if ( empty( $_REQUEST[ $param ] ) ) { // WPCS: input var ok, CSRF ok.
/* translators: %s: parameter */
throw new Exception( sprintf( __( 'Missing parameter %s', 'woocommerce' ), $param ) );
}
$data[ $param ] = wp_unslash( $_REQUEST[ $param ] ); // WPCS: input var ok, CSRF ok, sanitization ok.
}
if ( ! in_array( $_REQUEST['scope'], array( 'read', 'write', 'read_write' ) ) ) {
if ( ! in_array( $data['scope'], array( 'read', 'write', 'read_write' ), true ) ) {
/* translators: %s: scope */
throw new Exception( sprintf( __( 'Invalid scope %s', 'woocommerce' ), wc_clean( $_REQUEST['scope'] ) ) );
throw new Exception( sprintf( __( 'Invalid scope %s', 'woocommerce' ), wc_clean( $data['scope'] ) ) );
}
foreach ( array( 'return_url', 'callback_url' ) as $param ) {
$param = $this->get_formatted_url( $_REQUEST[ $param ] );
$param = $this->get_formatted_url( $data[ $param ] );
if ( false === filter_var( $param, FILTER_VALIDATE_URL ) ) {
/* translators: %s: url */
@ -189,7 +188,7 @@ class WC_Auth {
}
}
$callback_url = $this->get_formatted_url( $_REQUEST['callback_url'] );
$callback_url = $this->get_formatted_url( $data['callback_url'] );
if ( 0 !== stripos( $callback_url, 'https://' ) ) {
throw new Exception( __( 'The callback_url needs to be over SSL', 'woocommerce' ) );
@ -201,17 +200,17 @@ class WC_Auth {
*
* @since 2.4.0
*
* @param string $app_name
* @param string $app_user_id
* @param string $scope
* @param string $app_name App name.
* @param string $app_user_id User ID.
* @param string $scope Scope.
*
* @return array
*/
protected function create_keys( $app_name, $app_user_id, $scope ) {
global $wpdb;
/* translators: 1: app name 2: scope 3: date 4: time */
$description = sprintf(
/* translators: 1: app name 2: scope 3: date 4: time */
__( '%1$s - API %2$s (created on %3$s at %4$s).', 'woocommerce' ),
wc_clean( $app_name ),
$this->get_i18n_scope( $scope ),
@ -221,7 +220,7 @@ class WC_Auth {
$user = wp_get_current_user();
// Created API keys.
$permissions = ( in_array( $scope, array( 'read', 'write', 'read_write' ) ) ) ? sanitize_text_field( $scope ) : 'read';
$permissions = in_array( $scope, array( 'read', 'write', 'read_write' ), true ) ? sanitize_text_field( $scope ) : 'read';
$consumer_key = 'ck_' . wc_rand_hash();
$consumer_secret = 'cs_' . wc_rand_hash();
@ -259,17 +258,16 @@ class WC_Auth {
*
* @since 2.4.0
*
* @param array $consumer_data
* @param string $url
*
* @throws Exception When validation fails.
* @param array $consumer_data Consumer data.
* @param string $url URL.
* @return bool
* @throws Exception
*/
protected function post_consumer_data( $consumer_data, $url ) {
$params = array(
'body' => json_encode( $consumer_data ),
'timeout' => 60,
'headers' => array(
'body' => wp_json_encode( $consumer_data ),
'timeout' => 60,
'headers' => array(
'Content-Type' => 'application/json;charset=' . get_bloginfo( 'charset' ),
),
);
@ -278,7 +276,7 @@ class WC_Auth {
if ( is_wp_error( $response ) ) {
throw new Exception( $response->get_error_message() );
} elseif ( 200 != $response['response']['code'] ) {
} elseif ( 200 !== intval( $response['response']['code'] ) ) {
throw new Exception( __( 'An error occurred in the request and at the time were unable to send the consumer data', 'woocommerce' ) );
}
@ -293,15 +291,15 @@ class WC_Auth {
public function handle_auth_requests() {
global $wp;
if ( ! empty( $_GET['wc-auth-version'] ) ) {
$wp->query_vars['wc-auth-version'] = $_GET['wc-auth-version'];
if ( ! empty( $_GET['wc-auth-version'] ) ) { // WPCS: input var ok, CSRF ok.
$wp->query_vars['wc-auth-version'] = wc_clean( wp_unslash( $_GET['wc-auth-version'] ) ); // WPCS: input var ok, CSRF ok.
}
if ( ! empty( $_GET['wc-auth-route'] ) ) {
$wp->query_vars['wc-auth-route'] = $_GET['wc-auth-route'];
$wp->query_vars['wc-auth-route'] = wc_clean( wp_unslash( $_GET['wc-auth-route'] ) ); // WPCS: input var ok, CSRF ok.
}
// wc-auth endpoint requests
// wc-auth endpoint requests.
if ( ! empty( $wp->query_vars['wc-auth-version'] ) && ! empty( $wp->query_vars['wc-auth-route'] ) ) {
$this->auth_endpoint( $wp->query_vars['wc-auth-route'] );
}
@ -311,8 +309,8 @@ class WC_Auth {
* Auth endpoint.
*
* @since 2.4.0
*
* @param string $route
* @throws Exception When validation fails.
* @param string $route Route.
*/
protected function auth_endpoint( $route ) {
ob_start();
@ -327,50 +325,74 @@ class WC_Auth {
$route = strtolower( wc_clean( $route ) );
$this->make_validation();
// Login endpoint
if ( 'login' == $route && ! is_user_logged_in() ) {
wc_get_template( 'auth/form-login.php', array(
'app_name' => $_REQUEST['app_name'],
'return_url' => add_query_arg( array( 'success' => 0, 'user_id' => wc_clean( $_REQUEST['user_id'] ) ), $this->get_formatted_url( $_REQUEST['return_url'] ) ),
'redirect_url' => $this->build_url( $_REQUEST, 'authorize' ),
) );
$data = wp_unslash( $_REQUEST ); // WPCS: input var ok, CSRF ok.
// Login endpoint.
if ( 'login' === $route && ! is_user_logged_in() ) {
wc_get_template(
'auth/form-login.php', array(
'app_name' => wc_clean( $data['app_name'] ),
'return_url' => add_query_arg(
array(
'success' => 0,
'user_id' => wc_clean( $data['user_id'] ),
), $this->get_formatted_url( $data['return_url'] )
),
'redirect_url' => $this->build_url( $data, 'authorize' ),
)
);
exit;
// Redirect with user is logged in
} elseif ( 'login' == $route && is_user_logged_in() ) {
wp_redirect( esc_url_raw( $this->build_url( $_REQUEST, 'authorize' ) ) );
} elseif ( 'login' === $route && is_user_logged_in() ) {
// Redirect with user is logged in.
wp_redirect( esc_url_raw( $this->build_url( $data, 'authorize' ) ) );
exit;
// Redirect with user is not logged in and trying to access the authorize endpoint
} elseif ( 'authorize' == $route && ! is_user_logged_in() ) {
wp_redirect( esc_url_raw( $this->build_url( $_REQUEST, 'login' ) ) );
} elseif ( 'authorize' === $route && ! is_user_logged_in() ) {
// Redirect with user is not logged in and trying to access the authorize endpoint.
wp_redirect( esc_url_raw( $this->build_url( $data, 'login' ) ) );
exit;
// Authorize endpoint
} elseif ( 'authorize' == $route && current_user_can( 'manage_woocommerce' ) ) {
wc_get_template( 'auth/form-grant-access.php', array(
'app_name' => $_REQUEST['app_name'],
'return_url' => add_query_arg( array( 'success' => 0, 'user_id' => wc_clean( $_REQUEST['user_id'] ) ), $this->get_formatted_url( $_REQUEST['return_url'] ) ),
'scope' => $this->get_i18n_scope( wc_clean( $_REQUEST['scope'] ) ),
'permissions' => $this->get_permissions_in_scope( wc_clean( $_REQUEST['scope'] ) ),
'granted_url' => wp_nonce_url( $this->build_url( $_REQUEST, 'access_granted' ), 'wc_auth_grant_access', 'wc_auth_nonce' ),
'logout_url' => wp_logout_url( $this->build_url( $_REQUEST, 'login' ) ),
'user' => wp_get_current_user(),
) );
} elseif ( 'authorize' === $route && current_user_can( 'manage_woocommerce' ) ) {
// Authorize endpoint.
wc_get_template(
'auth/form-grant-access.php', array(
'app_name' => wc_clean( $data['app_name'] ),
'return_url' => add_query_arg(
array(
'success' => 0,
'user_id' => wc_clean( $data['user_id'] ),
), $this->get_formatted_url( $data['return_url'] )
),
'scope' => $this->get_i18n_scope( wc_clean( $data['scope'] ) ),
'permissions' => $this->get_permissions_in_scope( wc_clean( $data['scope'] ) ),
'granted_url' => wp_nonce_url( $this->build_url( $data, 'access_granted' ), 'wc_auth_grant_access', 'wc_auth_nonce' ),
'logout_url' => wp_logout_url( $this->build_url( $data, 'login' ) ),
'user' => wp_get_current_user(),
)
);
exit;
// Granted access endpoint
} elseif ( 'access_granted' == $route && current_user_can( 'manage_woocommerce' ) ) {
if ( ! isset( $_GET['wc_auth_nonce'] ) || ! wp_verify_nonce( $_GET['wc_auth_nonce'], 'wc_auth_grant_access' ) ) {
} elseif ( 'access_granted' === $route && current_user_can( 'manage_woocommerce' ) ) {
// Granted access endpoint.
if ( ! isset( $_GET['wc_auth_nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['wc_auth_nonce'] ) ), 'wc_auth_grant_access' ) ) { // WPCS: input var ok.
throw new Exception( __( 'Invalid nonce verification', 'woocommerce' ) );
}
$consumer_data = $this->create_keys( $_REQUEST['app_name'], $_REQUEST['user_id'], $_REQUEST['scope'] );
$response = $this->post_consumer_data( $consumer_data, $this->get_formatted_url( $_REQUEST['callback_url'] ) );
$consumer_data = $this->create_keys( $data['app_name'], $data['user_id'], $data['scope'] );
$response = $this->post_consumer_data( $consumer_data, $this->get_formatted_url( $data['callback_url'] ) );
if ( $response ) {
wp_redirect( esc_url_raw( add_query_arg( array( 'success' => 1, 'user_id' => wc_clean( $_REQUEST['user_id'] ) ), $this->get_formatted_url( $_REQUEST['return_url'] ) ) ) );
wp_redirect(
esc_url_raw(
add_query_arg(
array(
'success' => 1,
'user_id' => wc_clean( $data['user_id'] ),
), $this->get_formatted_url( $data['return_url'] )
)
)
);
exit;
}
} else {
@ -380,7 +402,7 @@ class WC_Auth {
$this->maybe_delete_key( $consumer_data );
/* translators: %s: error message */
wp_die( sprintf( __( 'Error: %s.', 'woocommerce' ), $e->getMessage() ), __( 'Access denied', 'woocommerce' ), array( 'response' => 401 ) );
wp_die( sprintf( esc_html__( 'Error: %s.', 'woocommerce' ), esc_html( $e->getMessage() ) ), esc_html__( 'Access denied', 'woocommerce' ), array( 'response' => 401 ) );
}
}
@ -389,7 +411,7 @@ class WC_Auth {
*
* @since 2.4.0
*
* @param array $key
* @param array $key Key.
*/
private function maybe_delete_key( $key ) {
global $wpdb;

View File

@ -1,16 +1,15 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WooCommerce Autoloader.
*
* @class WC_Autoloader
* @version 2.3.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @package WooCommerce/Classes
* @version 2.3.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Autoloader class.
*/
class WC_Autoloader {
@ -25,8 +24,8 @@ class WC_Autoloader {
* The Constructor.
*/
public function __construct() {
if ( function_exists( "__autoload" ) ) {
spl_autoload_register( "__autoload" );
if ( function_exists( '__autoload' ) ) {
spl_autoload_register( '__autoload' );
}
spl_autoload_register( array( $this, 'autoload' ) );
@ -37,7 +36,7 @@ class WC_Autoloader {
/**
* Take a class name and turn it into a file name.
*
* @param string $class
* @param string $class Class name.
* @return string
*/
private function get_file_name_from_class( $class ) {
@ -47,12 +46,12 @@ class WC_Autoloader {
/**
* Include a class file.
*
* @param string $path
* @return bool successful or not
* @param string $path File path.
* @return bool Successful or not.
*/
private function load_file( $path ) {
if ( $path && is_readable( $path ) ) {
include_once( $path );
include_once $path;
return true;
}
return false;
@ -61,7 +60,7 @@ class WC_Autoloader {
/**
* Auto-load WC classes on demand to reduce memory consumption.
*
* @param string $class
* @param string $class Class name.
*/
public function autoload( $class ) {
$class = strtolower( $class );
@ -70,14 +69,14 @@ class WC_Autoloader {
return;
}
$file = $this->get_file_name_from_class( $class );
$path = '';
$file = $this->get_file_name_from_class( $class );
$path = '';
if ( 0 === strpos( $class, 'wc_addons_gateway_' ) ) {
if ( 0 === strpos( $class, 'wc_addons_gateway_' ) ) {
$path = $this->include_path . 'gateways/' . substr( str_replace( '_', '-', $class ), 18 ) . '/';
} elseif ( 0 === strpos( $class, 'wc_gateway_' ) ) {
} elseif ( 0 === strpos( $class, 'wc_gateway_' ) ) {
$path = $this->include_path . 'gateways/' . substr( str_replace( '_', '-', $class ), 11 ) . '/';
} elseif ( 0 === strpos( $class, 'wc_shipping_' ) ) {
} elseif ( 0 === strpos( $class, 'wc_shipping_' ) ) {
$path = $this->include_path . 'shipping/' . substr( str_replace( '_', '-', $class ), 12 ) . '/';
} elseif ( 0 === strpos( $class, 'wc_shortcode_' ) ) {
$path = $this->include_path . 'shortcodes/';

View File

@ -2,13 +2,11 @@
/**
* Background Emailer
*
* @version 3.0.1
* @package WooCommerce/Classes
* @version 3.0.1
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WC_Background_Process', false ) ) {
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';
@ -59,7 +57,7 @@ class WC_Background_Emailer extends WC_Background_Process {
WC_Emails::send_queued_transactional_email( $callback['filter'], $callback['args'] );
} catch ( Exception $e ) {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
trigger_error( 'Transactional email triggered fatal error for callback ' . esc_html( $callback['filter'] ), E_USER_WARNING );
trigger_error( 'Transactional email triggered fatal error for callback ' . esc_html( $callback['filter'] ), E_USER_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
}
}
}
@ -89,7 +87,7 @@ class WC_Background_Emailer extends WC_Background_Process {
if ( ! headers_sent() ) {
header( 'Connection: close' );
}
@ob_end_flush();
@ob_end_flush(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
flush();
}
}
@ -117,7 +115,7 @@ class WC_Background_Emailer extends WC_Background_Process {
// Pass cookies through with the request so nonces function.
$cookies = array();
foreach ( $_COOKIE as $name => $value ) {
foreach ( $_COOKIE as $name => $value ) { // WPCS: input var ok.
if ( 'PHPSESSID' === $name ) {
continue;
}

View File

@ -2,13 +2,11 @@
/**
* Background Updater
*
* @version 2.6.0
* @package WooCommerce/Classes
* @version 2.6.0
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WC_Background_Process', false ) ) {
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';

View File

@ -1,17 +1,15 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Breadcrumb class.
*
* @class WC_Breadcrumb
* @version 2.3.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @package WooCommerce/Classes
* @version 2.3.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Breadcrumb class.
*/
class WC_Breadcrumb {
@ -25,8 +23,8 @@ class WC_Breadcrumb {
/**
* Add a crumb so we don't get lost.
*
* @param string $name
* @param string $link
* @param string $name Name.
* @param string $link Link.
*/
public function add_crumb( $name, $link = '' ) {
$this->crumbs[] = array(
@ -99,14 +97,14 @@ class WC_Breadcrumb {
$shop_page_id = wc_get_page_id( 'shop' );
$shop_page = get_post( $shop_page_id );
// If permalinks contain the shop page in the URI prepend the breadcrumb with shop
if ( $shop_page_id && $shop_page && isset( $permalinks['product_base'] ) && strstr( $permalinks['product_base'], '/' . $shop_page->post_name ) && get_option( 'page_on_front' ) != $shop_page_id ) {
// If permalinks contain the shop page in the URI prepend the breadcrumb with shop.
if ( $shop_page_id && $shop_page && isset( $permalinks['product_base'] ) && strstr( $permalinks['product_base'], '/' . $shop_page->post_name ) && intval( get_option( 'page_on_front' ) ) !== $shop_page_id ) {
$this->add_crumb( get_the_title( $shop_page ), get_permalink( $shop_page ) );
}
}
/**
* is home trail.
* Is home trail..
*/
private function add_crumbs_home() {
$this->add_crumb( single_post_title( '', false ) );
@ -120,7 +118,7 @@ class WC_Breadcrumb {
}
/**
* attachment trail.
* Attachment trail.
*/
private function add_crumbs_attachment() {
global $post;
@ -132,23 +130,27 @@ class WC_Breadcrumb {
/**
* Single post trail.
*
* @param int $post_id
* @param string $permalink
* @param int $post_id Post ID.
* @param string $permalink Post permalink.
*/
private function add_crumbs_single( $post_id = 0, $permalink = '' ) {
if ( ! $post_id ) {
global $post;
} else {
$post = get_post( $post_id );
$post = get_post( $post_id ); // WPCS: override ok.
}
if ( 'product' === get_post_type( $post ) ) {
$this->prepend_shop_page();
$terms = wc_get_product_terms( $post->ID, 'product_cat', apply_filters( 'woocommerce_breadcrumb_product_terms_args', array(
'orderby' => 'parent',
'order' => 'DESC',
) ) );
$terms = wc_get_product_terms(
$post->ID, 'product_cat', apply_filters(
'woocommerce_breadcrumb_product_terms_args', array(
'orderby' => 'parent',
'order' => 'DESC',
)
)
);
if ( $terms ) {
$main_term = apply_filters( 'woocommerce_breadcrumb_main_term', $terms[0], $terms );
@ -183,8 +185,8 @@ class WC_Breadcrumb {
$parent_id = $post->post_parent;
while ( $parent_id ) {
$page = get_post( $parent_id );
$parent_id = $page->post_parent;
$page = get_post( $parent_id );
$parent_id = $page->post_parent;
$parent_crumbs[] = array( get_the_title( $page->ID ), get_permalink( $page->ID ) );
}
@ -217,6 +219,8 @@ class WC_Breadcrumb {
$current_term = $GLOBALS['wp_query']->get_queried_object();
$this->prepend_shop_page();
/* translators: %s: product tag */
$this->add_crumb( sprintf( __( 'Products tagged &ldquo;%s&rdquo;', 'woocommerce' ), $current_term->name ) );
}
@ -224,7 +228,7 @@ class WC_Breadcrumb {
* Shop breadcrumb.
*/
private function add_crumbs_shop() {
if ( get_option( 'page_on_front' ) == wc_get_page_id( 'shop' ) ) {
if ( intval( get_option( 'page_on_front' ) ) === wc_get_page_id( 'shop' ) ) {
return;
}
@ -232,7 +236,7 @@ class WC_Breadcrumb {
if ( ! $_name ) {
$product_post_type = get_post_type_object( 'product' );
$_name = $product_post_type->labels->singular_name;
$_name = $product_post_type->labels->singular_name;
}
$this->add_crumb( $_name, get_post_type_archive_link( 'product' ) );
@ -255,7 +259,7 @@ class WC_Breadcrumb {
private function add_crumbs_category() {
$this_category = get_category( $GLOBALS['wp_query']->get_queried_object() );
if ( 0 != $this_category->parent ) {
if ( 0 !== intval( $this_category->parent ) ) {
$this->term_ancestors( $this_category->term_id, 'category' );
}
@ -267,6 +271,8 @@ class WC_Breadcrumb {
*/
private function add_crumbs_tag() {
$queried_object = $GLOBALS['wp_query']->get_queried_object();
/* translators: %s: tag name */
$this->add_crumb( sprintf( __( 'Posts tagged &ldquo;%s&rdquo;', 'woocommerce' ), single_tag_title( '', false ) ), get_tag_link( $queried_object->term_id ) );
}
@ -294,7 +300,7 @@ class WC_Breadcrumb {
$this->add_crumb( $taxonomy->labels->name );
if ( 0 != $this_term->parent ) {
if ( 0 !== intval( $this_term->parent ) ) {
$this->term_ancestors( $this_term->term_id, $this_term->taxonomy );
}
@ -308,14 +314,16 @@ class WC_Breadcrumb {
global $author;
$userdata = get_userdata( $author );
/* translators: %s: author name */
$this->add_crumb( sprintf( __( 'Author: %s', 'woocommerce' ), $userdata->display_name ) );
}
/**
* Add crumbs for a term.
*
* @param int $term_id
* @param string $taxonomy
* @param int $term_id Term ID.
* @param string $taxonomy Taxonomy.
*/
private function term_ancestors( $term_id, $taxonomy ) {
$ancestors = get_ancestors( $term_id, $taxonomy );
@ -334,8 +342,10 @@ class WC_Breadcrumb {
* Endpoints.
*/
private function endpoint_trail() {
// Is an endpoint showing?
if ( is_wc_endpoint_url() && ( $endpoint = WC()->query->get_current_endpoint() ) && ( $endpoint_title = WC()->query->get_endpoint_title( $endpoint ) ) ) {
$endpoint = is_wc_endpoint_url() ? WC()->query->get_current_endpoint() : '';
$endpoint_title = $endpoint ? WC()->query->get_endpoint_title( $endpoint ) : '';
if ( $endpoint_title ) {
$this->add_crumb( $endpoint_title );
}
}
@ -345,6 +355,7 @@ class WC_Breadcrumb {
*/
private function search_trail() {
if ( is_search() ) {
/* translators: %s: search term */
$this->add_crumb( sprintf( __( 'Search results for &ldquo;%s&rdquo;', 'woocommerce' ), get_search_query() ), remove_query_arg( 'paged' ) );
}
}
@ -354,6 +365,7 @@ class WC_Breadcrumb {
*/
private function paged_trail() {
if ( get_query_var( 'paged' ) ) {
/* translators: %d: page number */
$this->add_crumb( sprintf( __( 'Page %d', 'woocommerce' ), get_query_var( 'paged' ) ) );
}
}

View File

@ -2,16 +2,10 @@
/**
* WC_Cache_Helper class.
*
* @class WC_Cache_Helper
* @version 2.2.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Cache_Helper.
@ -26,6 +20,8 @@ class WC_Cache_Helper {
add_action( 'admin_notices', array( __CLASS__, 'notices' ) );
add_action( 'delete_version_transients', array( __CLASS__, 'delete_version_transients' ) );
add_action( 'wp', array( __CLASS__, 'prevent_caching' ) );
add_action( 'clean_term_cache', array( __CLASS__, 'clean_term_cache' ), 10, 2 );
add_action( 'edit_terms', array( __CLASS__, 'clean_term_cache' ), 10, 2 );
}
/**
@ -93,7 +89,7 @@ class WC_Cache_Helper {
public static function geolocation_ajax_redirect() {
if ( 'geolocation_ajax' === get_option( 'woocommerce_default_customer_address' ) && ! is_checkout() && ! is_cart() && ! is_account_page() && ! is_ajax() && empty( $_POST ) ) { // WPCS: CSRF ok, input var ok.
$location_hash = self::geolocation_ajax_get_location_hash();
$current_hash = isset( $_GET['v'] ) ? wc_clean( wp_unslash( $_GET['v'] ) ) : ''; // WPCS: sanitization ok, input var ok.
$current_hash = isset( $_GET['v'] ) ? wc_clean( wp_unslash( $_GET['v'] ) ) : ''; // WPCS: sanitization ok, input var ok, CSRF ok.
if ( empty( $current_hash ) || $current_hash !== $location_hash ) {
global $wp;
@ -141,7 +137,10 @@ class WC_Cache_Helper {
if ( false === $transient_value || true === $refresh ) {
self::delete_version_transients( $transient_value );
set_transient( $transient_name, $transient_value = time() );
$transient_value = time();
set_transient( $transient_name, $transient_value );
}
return $transient_value;
}
@ -196,11 +195,40 @@ class WC_Cache_Helper {
if ( $enabled && ! in_array( '_wc_session_', $settings, true ) ) {
?>
<div class="error">
<p><?php echo wp_kses_post( sprintf( __( 'In order for <strong>database caching</strong> to work with WooCommerce you must add %1$s to the "Ignored Query Strings" option in <a href="%2$s">W3 Total Cache settings</a>.', 'woocommerce' ), '<code>_wc_session_</code>', esc_url( admin_url( 'admin.php?page=w3tc_dbcache' ) ) ) ); ?></p>
<p>
<?php
/* translators: 1: key 2: URL */
echo wp_kses_post( sprintf( __( 'In order for <strong>database caching</strong> to work with WooCommerce you must add %1$s to the "Ignored Query Strings" option in <a href="%2$s">W3 Total Cache settings</a>.', 'woocommerce' ), '<code>_wc_session_</code>', esc_url( admin_url( 'admin.php?page=w3tc_dbcache' ) ) ) );
?>
</p>
</div>
<?php
}
}
/**
* Clean term caches added by WooCommerce.
*
* @since 3.3.4
* @param array|int $ids Array of ids or single ID to clear cache for.
* @param string $taxonomy Taxonomy name.
*/
public static function clean_term_cache( $ids, $taxonomy ) {
if ( 'product_cat' === $taxonomy ) {
$ids = is_array( $ids ) ? $ids : array( $ids );
foreach ( $ids as $id ) {
$clear_ids[] = $id;
$clear_ids = array_merge( $clear_ids, get_ancestors( $id, 'product_cat', 'taxonomy' ) );
}
$clear_ids = array_unique( $clear_ids );
foreach ( $clear_ids as $id ) {
wp_cache_delete( 'product-category-hierarchy-' . $id, 'product_cat' );
}
}
}
}
WC_Cache_Helper::init();

View File

@ -6,13 +6,11 @@
*
* We suggest using the action woocommerce_cart_calculate_fees hook for adding fees.
*
* @author Automattic
* @package WooCommerce/Classes
* @version 3.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Cart_Fees class.
@ -80,7 +78,7 @@ final class WC_Cart_Fees {
public function add_fee( $args = array() ) {
$fee_props = (object) wp_parse_args( $args, $this->default_fee_props );
$fee_props->name = $fee_props->name ? $fee_props->name : __( 'Fee', 'woocommerce' );
$fee_props->tax_class = in_array( $fee_props->tax_class, array_merge( WC_Tax::get_tax_classes(), WC_Tax::get_tax_class_slugs() ), true ) ? $fee_props->tax_class: '';
$fee_props->tax_class = in_array( $fee_props->tax_class, array_merge( WC_Tax::get_tax_classes(), WC_Tax::get_tax_class_slugs() ), true ) ? $fee_props->tax_class : '';
$fee_props->taxable = wc_string_to_bool( $fee_props->taxable );
$fee_props->amount = wc_format_decimal( $fee_props->amount );
@ -92,7 +90,9 @@ final class WC_Cart_Fees {
return new WP_Error( 'fee_exists', __( 'Fee has already been added.', 'woocommerce' ) );
}
return $this->fees[ $fee_props->id ] = $fee_props;
$this->fees[ $fee_props->id ] = $fee_props;
return $this->fees[ $fee_props->id ];
}
/**

View File

@ -2,8 +2,8 @@
/**
* Cart session handling class.
*
* @author Automattic
* @package WooCommerce/Classes
* @version 3.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -105,7 +105,7 @@ final class WC_Cart_Session {
wc_add_notice( sprintf( __( '%s has been removed from your cart because it can no longer be purchased. Please contact us if you need assistance.', 'woocommerce' ), $product->get_name() ), 'error' );
do_action( 'woocommerce_remove_cart_item_from_session', $key, $values );
} elseif ( ! empty( $values['data_hash'] ) && ! hash_equals( $values['data_hash'], wc_get_cart_item_data_hash( $product ) ) ) {
} elseif ( ! empty( $values['data_hash'] ) && ! hash_equals( $values['data_hash'], wc_get_cart_item_data_hash( $product ) ) ) { // phpcs:ignore PHPCompatibility.PHP.NewFunctions.hash_equalsFound
$update_cart_session = true;
/* translators: %1$s: product name. %2$s product permalink */
wc_add_notice( sprintf( __( '%1$s has been removed from your cart because it has since been modified. You can add it back to your cart <a href="%2$s">here</a>.', 'woocommerce' ), $product->get_name(), $product->get_permalink() ), 'notice' );
@ -113,9 +113,11 @@ final class WC_Cart_Session {
} else {
// Put session data into array. Run through filter so other plugins can load their own session data.
$session_data = array_merge( $values, array(
'data' => $product,
) );
$session_data = array_merge(
$values, array(
'data' => $product,
)
);
$cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', $session_data, $values, $key );
// Add to cart right away so the product is visible in woocommerce_get_cart_item_from_session hook.
@ -157,7 +159,7 @@ final class WC_Cart_Session {
if ( ! headers_sent() && did_action( 'wp_loaded' ) ) {
if ( ! $this->cart->is_empty() ) {
$this->set_cart_cookies( true );
} elseif ( isset( $_COOKIE['woocommerce_items_in_cart'] ) ) {
} elseif ( isset( $_COOKIE['woocommerce_items_in_cart'] ) ) { // WPCS: input var ok.
$this->set_cart_cookies( false );
}
}
@ -198,9 +200,11 @@ final class WC_Cart_Session {
*/
public function persistent_cart_update() {
if ( get_current_user_id() && apply_filters( 'woocommerce_persistent_cart_enabled', true ) ) {
update_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), array(
'cart' => $this->get_cart_for_session(),
) );
update_user_meta(
get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), array(
'cart' => $this->get_cart_for_session(),
)
);
}
}
@ -223,7 +227,7 @@ final class WC_Cart_Session {
if ( $set ) {
wc_setcookie( 'woocommerce_items_in_cart', 1 );
wc_setcookie( 'woocommerce_cart_hash', md5( wp_json_encode( $this->get_cart_for_session() ) ) );
} elseif ( isset( $_COOKIE['woocommerce_items_in_cart'] ) ) {
} elseif ( isset( $_COOKIE['woocommerce_items_in_cart'] ) ) { // WPCS: input var ok.
wc_setcookie( 'woocommerce_items_in_cart', 0, time() - HOUR_IN_SECONDS );
wc_setcookie( 'woocommerce_cart_hash', '', time() - HOUR_IN_SECONDS );
}

View File

@ -9,8 +9,8 @@
* - if something is being stored e.g. item total, store unrounded. This is so taxes can be recalculated later accurately.
* - if calculating a total, round (if settings allow).
*
* @author Automattic
* @package WooCommerce/Classes
* @version 3.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -102,16 +102,16 @@ final class WC_Cart_Totals {
* @var array
*/
protected $totals = array(
'fees_total' => 0,
'fees_total_tax' => 0,
'items_subtotal' => 0,
'items_subtotal_tax' => 0,
'items_total' => 0,
'items_total_tax' => 0,
'total' => 0,
'shipping_total' => 0,
'shipping_tax_total' => 0,
'discounts_total' => 0,
'fees_total' => 0,
'fees_total_tax' => 0,
'items_subtotal' => 0,
'items_subtotal_tax' => 0,
'items_total' => 0,
'items_total_tax' => 0,
'total' => 0,
'shipping_total' => 0,
'shipping_tax_total' => 0,
'discounts_total' => 0,
);
/**
@ -212,7 +212,7 @@ final class WC_Cart_Totals {
* into the same format for use by this class.
*
* Each item is made up of the following props, in addition to those returned by get_default_item_props() for totals.
* - key: An identifier for the item (cart item key or line item ID).
* - key: An identifier for the item (cart item key or line item ID).
* - cart_item: For carts, the cart item from the cart which may include custom data.
* - quantity: The qty for this line.
* - price: The line price in cents.
@ -312,13 +312,12 @@ final class WC_Cart_Totals {
$fee->taxes = wc_array_merge_recursive_numeric( $fee->taxes, WC_Tax::calc_tax( $fee->total * $proportion, WC_Tax::get_rates( $tax_class ) ) );
}
}
} elseif ( $fee->object->taxable ) {
$fee->taxes = WC_Tax::calc_tax( $fee->total, WC_Tax::get_rates( $fee->tax_class, $this->cart->get_customer() ), false );
}
}
$fee->taxes = apply_filters( 'woocommerce_cart_totals_get_fees_from_cart_taxes', $fee->taxes, $fee, $this );
$fee->taxes = apply_filters( 'woocommerce_cart_totals_get_fees_from_cart_taxes', $fee->taxes, $fee, $this );
$fee->total_tax = array_sum( array_map( array( $this, 'round_line_tax' ), $fee->taxes ) );
// Set totals within object.
@ -366,13 +365,13 @@ final class WC_Cart_Totals {
foreach ( $this->coupons as $coupon ) {
switch ( $coupon->get_discount_type() ) {
case 'fixed_product' :
case 'fixed_product':
$coupon->sort = 1;
break;
case 'percent' :
case 'percent':
$coupon->sort = 2;
break;
case 'fixed_cart' :
case 'fixed_cart':
$coupon->sort = 3;
break;
default:
@ -391,7 +390,7 @@ final class WC_Cart_Totals {
* Sort coupons so discounts apply consistently across installs.
*
* In order of priority;
* - sort param
* - sort param
* - usage restriction
* - coupon value
* - ID
@ -422,10 +421,10 @@ final class WC_Cart_Totals {
*/
protected function remove_item_base_taxes( $item ) {
if ( $item->price_includes_tax && $item->taxable ) {
$base_tax_rates = WC_Tax::get_base_tax_rates( $item->product->get_tax_class( 'unfiltered' ) );
$base_tax_rates = WC_Tax::get_base_tax_rates( $item->product->get_tax_class( 'unfiltered' ) );
// Work out a new base price without the shop's base tax.
$taxes = WC_Tax::calc_tax( $item->price, $base_tax_rates, true );
$taxes = WC_Tax::calc_tax( $item->price, $base_tax_rates, true );
// Now we have a new item price (excluding TAX).
$item->price = round( $item->price - array_sum( $taxes ) );
@ -452,11 +451,11 @@ final class WC_Cart_Totals {
if ( $item->tax_rates !== $base_tax_rates ) {
// Work out a new base price without the shop's base tax.
$taxes = WC_Tax::calc_tax( $item->price, $base_tax_rates, true );
$new_taxes = WC_Tax::calc_tax( $item->price - array_sum( $taxes ), $item->tax_rates, false );
$taxes = WC_Tax::calc_tax( $item->price, $base_tax_rates, true );
$new_taxes = WC_Tax::calc_tax( $item->price - array_sum( $taxes ), $item->tax_rates, false );
// Now we have a new item price.
$item->price = $item->price - array_sum( $taxes ) + array_sum( $new_taxes );
$item->price = round( $item->price - array_sum( $taxes ) + array_sum( $new_taxes ) );
}
}
return $item;
@ -551,7 +550,8 @@ final class WC_Cart_Totals {
* Get taxes merged by type.
*
* @since 3.2.0
* @param array|string $types Types to merge and return. Defaults to all.
* @param bool $in_cents If returned value should be in cents.
* @param array|string $types Types to merge and return. Defaults to all.
* @return array
*/
protected function get_merged_taxes( $in_cents = false, $types = array( 'items', 'fees', 'shipping' ) ) {
@ -584,7 +584,7 @@ final class WC_Cart_Totals {
* Combine item taxes into a single array, preserving keys.
*
* @since 3.2.0
* @param array $taxes Taxes to combine.
* @param array $item_taxes Taxes to combine.
* @return array
*/
protected function combine_item_taxes( $item_taxes ) {

View File

@ -5,18 +5,14 @@
* The WooCommerce cart class stores cart data and active coupons as well as handling customer sessions and some cart related urls.
* The cart class also has a price calculation function which calls upon other classes to calculate totals.
*
* @version 2.1.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @package WooCommerce/Classes
* @version 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
include_once( WC_ABSPATH . 'includes/legacy/class-wc-legacy-cart.php' );
include_once( WC_ABSPATH . 'includes/class-wc-cart-session.php' );
require_once WC_ABSPATH . 'includes/legacy/class-wc-legacy-cart.php';
require_once WC_ABSPATH . 'includes/class-wc-cart-session.php';
/**
* WC_Cart class.
@ -796,7 +792,8 @@ class WC_Cart extends WC_Legacy_Cart {
if ( get_option( 'woocommerce_hold_stock_minutes' ) > 0 && ! $product->backorders_allowed() ) {
$order_id = isset( WC()->session->order_awaiting_payment ) ? absint( WC()->session->order_awaiting_payment ) : 0;
$held_stock = $wpdb->get_var(
$wpdb->prepare( "
$wpdb->prepare(
"
SELECT SUM( order_item_meta.meta_value ) AS held_qty
FROM {$wpdb->posts} AS posts
LEFT JOIN {$wpdb->prefix}woocommerce_order_items as order_items ON posts.ID = order_items.order_id
@ -811,7 +808,7 @@ class WC_Cart extends WC_Legacy_Cart {
$product->get_stock_managed_by_id(),
$order_id
)
);
); // WPCS: unprepared SQL ok.
if ( $product->get_stock_quantity() < ( $held_stock + $product_qty_in_cart[ $product->get_stock_managed_by_id() ] ) ) {
/* translators: 1: product name 2: minutes */
@ -893,16 +890,16 @@ class WC_Cart extends WC_Legacy_Cart {
foreach ( $taxes as $key => $tax ) {
$code = WC_Tax::get_rate_code( $key );
if ( $code || $key === apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) ) {
if ( $code || apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) === $key ) {
if ( ! isset( $tax_totals[ $code ] ) ) {
$tax_totals[ $code ] = new stdClass();
$tax_totals[ $code ] = new stdClass();
$tax_totals[ $code ]->amount = 0;
}
$tax_totals[ $code ]->tax_rate_id = $key;
$tax_totals[ $code ]->is_compound = WC_Tax::is_compound( $key );
$tax_totals[ $code ]->label = WC_Tax::get_rate_label( $key );
$tax_totals[ $code ]->amount += wc_round_tax_total( $tax );
$tax_totals[ $code ]->formatted_amount = wc_price( wc_round_tax_total( $tax_totals[ $code ]->amount ) );
$tax_totals[ $code ]->tax_rate_id = $key;
$tax_totals[ $code ]->is_compound = WC_Tax::is_compound( $key );
$tax_totals[ $code ]->label = WC_Tax::get_rate_label( $key );
$tax_totals[ $code ]->amount += wc_round_tax_total( $tax );
$tax_totals[ $code ]->formatted_amount = wc_price( wc_round_tax_total( $tax_totals[ $code ]->amount ) );
}
}
@ -1055,10 +1052,10 @@ class WC_Cart extends WC_Legacy_Cart {
$cart_item_data = (array) apply_filters( 'woocommerce_add_cart_item_data', $cart_item_data, $product_id, $variation_id, $quantity );
// Generate a ID based on product ID, variation ID, variation data, and other cart item data.
$cart_id = $this->generate_cart_id( $product_id, $variation_id, $variation, $cart_item_data );
$cart_id = $this->generate_cart_id( $product_id, $variation_id, $variation, $cart_item_data );
// Find the cart item key in the existing cart.
$cart_item_key = $this->find_product_in_cart( $cart_id );
$cart_item_key = $this->find_product_in_cart( $cart_id );
// Force quantity to 1 if sold individually and check for existing item in cart.
if ( $product_data->is_sold_individually() ) {
@ -1077,6 +1074,7 @@ class WC_Cart extends WC_Legacy_Cart {
// Stock check - only check if we're managing stock and backorders are not allowed.
if ( ! $product_data->is_in_stock() ) {
/* translators: %s: product name */
throw new Exception( sprintf( __( 'You cannot add &quot;%s&quot; to the cart because the product is out of stock.', 'woocommerce' ), $product_data->get_name() ) );
}
@ -1090,12 +1088,15 @@ class WC_Cart extends WC_Legacy_Cart {
$products_qty_in_cart = $this->get_cart_item_quantities();
if ( isset( $products_qty_in_cart[ $product_data->get_stock_managed_by_id() ] ) && ! $product_data->has_enough_stock( $products_qty_in_cart[ $product_data->get_stock_managed_by_id() ] + $quantity ) ) {
throw new Exception( sprintf(
'<a href="%s" class="button wc-forward">%s</a> %s',
wc_get_cart_url(),
__( 'View Cart', 'woocommerce' ),
sprintf( __( 'You cannot add that amount to the cart &mdash; we have %1$s in stock and you already have %2$s in your cart.', 'woocommerce' ), wc_format_stock_quantity_for_display( $product_data->get_stock_quantity(), $product_data ), wc_format_stock_quantity_for_display( $products_qty_in_cart[ $product_data->get_stock_managed_by_id() ], $product_data ) )
) );
throw new Exception(
sprintf(
'<a href="%s" class="button wc-forward">%s</a> %s',
wc_get_cart_url(),
__( 'View Cart', 'woocommerce' ),
/* translators: 1: quantity in stock 2: current quantity */
sprintf( __( 'You cannot add that amount to the cart &mdash; we have %1$s in stock and you already have %2$s in your cart.', 'woocommerce' ), wc_format_stock_quantity_for_display( $product_data->get_stock_quantity(), $product_data ), wc_format_stock_quantity_for_display( $products_qty_in_cart[ $product_data->get_stock_managed_by_id() ], $product_data ) )
)
);
}
}
@ -1107,15 +1108,19 @@ class WC_Cart extends WC_Legacy_Cart {
$cart_item_key = $cart_id;
// Add item after merging with $cart_item_data - hook to allow plugins to modify cart item.
$this->cart_contents[ $cart_item_key ] = apply_filters( 'woocommerce_add_cart_item', array_merge( $cart_item_data, array(
'key' => $cart_item_key,
'product_id' => $product_id,
'variation_id' => $variation_id,
'variation' => $variation,
'quantity' => $quantity,
'data' => $product_data,
'data_hash' => wc_get_cart_item_data_hash( $product_data ),
) ), $cart_item_key );
$this->cart_contents[ $cart_item_key ] = apply_filters(
'woocommerce_add_cart_item', array_merge(
$cart_item_data, array(
'key' => $cart_item_key,
'product_id' => $product_id,
'variation_id' => $variation_id,
'variation' => $variation,
'quantity' => $quantity,
'data' => $product_data,
'data_hash' => wc_get_cart_item_data_hash( $product_data ),
)
), $cart_item_key
);
}
do_action( 'woocommerce_add_to_cart', $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data );
@ -1180,7 +1185,7 @@ class WC_Cart extends WC_Legacy_Cart {
/**
* Set the quantity for an item in the cart.
*
* @param string $cart_item_key contains the id of the cart item.
* @param string $cart_item_key contains the id of the cart item.
* @param int $quantity contains the quantity of the item.
* @param bool $refresh_totals whether or not to calculate totals after setting the new qty.
* @return bool
@ -1190,7 +1195,7 @@ class WC_Cart extends WC_Legacy_Cart {
do_action( 'woocommerce_before_cart_item_quantity_zero', $cart_item_key, $this );
unset( $this->cart_contents[ $cart_item_key ] );
} else {
$old_quantity = $this->cart_contents[ $cart_item_key ]['quantity'];
$old_quantity = $this->cart_contents[ $cart_item_key ]['quantity'];
$this->cart_contents[ $cart_item_key ]['quantity'] = $quantity;
do_action( 'woocommerce_after_cart_item_quantity_update', $cart_item_key, $quantity, $old_quantity, $this );
}
@ -1252,7 +1257,7 @@ class WC_Cart extends WC_Legacy_Cart {
$this->shipping_methods = $this->needs_shipping() ? $this->get_chosen_shipping_methods( WC()->shipping->calculate_shipping( $this->get_shipping_packages() ) ) : array();
$shipping_taxes = wp_list_pluck( $this->shipping_methods, 'taxes' );
$merged_taxes = array();
$merged_taxes = array();
foreach ( $shipping_taxes as $taxes ) {
foreach ( $taxes as $tax_id => $tax_amount ) {
if ( ! isset( $merged_taxes[ $tax_id ] ) ) {
@ -1280,7 +1285,7 @@ class WC_Cart extends WC_Legacy_Cart {
$chosen_methods = array();
// Get chosen methods for each package to get our totals.
foreach ( $calculated_shipping_packages as $key => $package ) {
$chosen_method = wc_get_chosen_shipping_method_for_package( $key, $package );
$chosen_method = wc_get_chosen_shipping_method_for_package( $key, $package );
if ( $chosen_method ) {
$chosen_methods[ $key ] = $package['rates'][ $chosen_method ];
}
@ -1324,7 +1329,8 @@ class WC_Cart extends WC_Legacy_Cart {
* @return array of cart items
*/
public function get_shipping_packages() {
return apply_filters( 'woocommerce_cart_shipping_packages',
return apply_filters(
'woocommerce_cart_shipping_packages',
array(
array(
'contents' => $this->get_items_needing_shipping(),
@ -1341,7 +1347,7 @@ class WC_Cart extends WC_Legacy_Cart {
'address' => $this->get_customer()->get_shipping_address(),
'address_2' => $this->get_customer()->get_shipping_address_2(),
),
'cart_subtotal' => $this->get_displayed_subtotal(),
'cart_subtotal' => $this->get_displayed_subtotal(),
),
)
);
@ -1445,10 +1451,18 @@ class WC_Cart extends WC_Legacy_Cart {
// Get user and posted emails to compare.
$current_user = wp_get_current_user();
$check_emails = array_unique( array_filter( array_map( 'strtolower', array_map( 'sanitize_email', array(
$posted['billing_email'],
$current_user->user_email,
) ) ) ) );
$check_emails = array_unique(
array_filter(
array_map(
'strtolower', array_map(
'sanitize_email', array(
$posted['billing_email'],
$current_user->user_email,
)
)
)
)
);
// Limit to defined email addresses.
$restrictions = $coupon->get_email_restrictions();
@ -1474,21 +1488,23 @@ class WC_Cart extends WC_Legacy_Cart {
}
// Check against billing emails of existing users.
$users_query = new WP_User_Query( array(
'fields' => 'ID',
'meta_query' => array(
array(
'key' => '_billing_email',
'value' => $check_emails,
'compare' => 'IN',
$users_query = new WP_User_Query(
array(
'fields' => 'ID',
'meta_query' => array(
array(
'key' => '_billing_email',
'value' => $check_emails,
'compare' => 'IN',
),
),
),
) );
)
); // WPCS: slow query ok.
$user_id_matches = array_unique( array_filter( array_merge( $user_id_matches, $users_query->get_results() ) ) );
foreach ( $user_id_matches as $user_id ) {
$usage_count += count( array_keys( $used_by, $user_id ) );
$usage_count += count( array_keys( $used_by, (string) $user_id, true ) );
}
if ( $usage_count >= $coupon->get_usage_limit_per_user() ) {
@ -1511,7 +1527,7 @@ class WC_Cart extends WC_Legacy_Cart {
foreach ( $check_emails as $check_email ) {
// With a direct match we return true.
if ( in_array( $check_email, $restrictions ) ) {
if ( in_array( $check_email, $restrictions, true ) ) {
return true;
}
@ -1545,7 +1561,7 @@ class WC_Cart extends WC_Legacy_Cart {
* Applies a coupon code passed to the method.
*
* @param string $coupon_code - The code to apply.
* @return bool True if the coupon is applied, false if it does not exist or cannot be applied.
* @return bool True if the coupon is applied, false if it does not exist or cannot be applied.
*/
public function apply_coupon( $coupon_code ) {
// Coupons are globally disabled.
@ -1615,7 +1631,7 @@ class WC_Cart extends WC_Legacy_Cart {
// Choose free shipping.
if ( $the_coupon->get_free_shipping() ) {
$packages = WC()->shipping->get_packages();
$packages = WC()->shipping->get_packages();
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
foreach ( $packages as $i => $package ) {
@ -1646,7 +1662,7 @@ class WC_Cart extends WC_Legacy_Cart {
}
foreach ( $this->get_applied_coupons() as $code ) {
$coupon = new WC_Coupon( $code );
$coupon = new WC_Coupon( $code );
$coupons[ $code ] = $coupon;
}
@ -1662,7 +1678,7 @@ class WC_Cart extends WC_Legacy_Cart {
*/
public function get_coupon_discount_amount( $code, $ex_tax = true ) {
$totals = $this->get_coupon_discount_totals();
$discount_amount = isset( $totals[ $code ] ) ? $totals[ $code ]: 0;
$discount_amount = isset( $totals[ $code ] ) ? $totals[ $code ] : 0;
if ( ! $ex_tax ) {
$discount_amount += $this->get_coupon_discount_tax_amount( $code );
@ -1701,8 +1717,8 @@ class WC_Cart extends WC_Legacy_Cart {
* @return bool
*/
public function remove_coupon( $coupon_code ) {
$coupon_code = wc_format_coupon_code( $coupon_code );
$position = array_search( $coupon_code, $this->get_applied_coupons(), true );
$coupon_code = wc_format_coupon_code( $coupon_code );
$position = array_search( $coupon_code, $this->get_applied_coupons(), true );
if ( false !== $position ) {
unset( $this->applied_coupons[ $position ] );
@ -1748,12 +1764,14 @@ class WC_Cart extends WC_Legacy_Cart {
* @param string $tax_class The tax class for the fee if taxable. A blank string is standard tax class. (default: '').
*/
public function add_fee( $name, $amount, $taxable = false, $tax_class = '' ) {
$this->fees_api()->add_fee( array(
'name' => $name,
'amount' => (float) $amount,
'taxable' => $taxable,
'tax_class' => $tax_class,
) );
$this->fees_api()->add_fee(
array(
'name' => $name,
'amount' => (float) $amount,
'taxable' => $taxable,
'tax_class' => $tax_class,
)
);
}
/**

View File

@ -1,18 +1,17 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Main checkout class.
* Checkout functionality
*
* The WooCommerce checkout class handles the checkout process, collecting user data and processing the payment.
*
* @class WC_Checkout
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @package WooCommerce/Classes
* @version 3.4.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Checkout class.
*/
class WC_Checkout {
@ -32,6 +31,7 @@ class WC_Checkout {
/**
* Holds posted data for backwards compatibility.
*
* @var array
*/
protected $legacy_posted_data = array();
@ -60,32 +60,36 @@ class WC_Checkout {
/**
* See if variable is set. Used to support legacy public variables which are no longer defined.
*
* @param string $key
* @param string $key Key.
* @return bool
*/
public function __isset( $key ) {
return in_array( $key, array(
'enable_signup',
'enable_guest_checkout',
'must_create_account',
'checkout_fields',
'posted',
'shipping_method',
'payment_method',
'customer_id',
'shipping_methods',
) );
return in_array(
$key,
array(
'enable_signup',
'enable_guest_checkout',
'must_create_account',
'checkout_fields',
'posted',
'shipping_method',
'payment_method',
'customer_id',
'shipping_methods',
),
true
);
}
/**
* Sets the legacy public variables for backwards compatibility.
*
* @param string $key
* @param mixed $value
* @param string $key Key.
* @param mixed $value Value.
*/
public function __set( $key, $value ) {
switch ( $key ) {
case 'enable_signup' :
case 'enable_signup':
$bool_value = wc_string_to_bool( $value );
if ( $bool_value !== $this->is_registration_enabled() ) {
@ -94,7 +98,7 @@ class WC_Checkout {
add_filter( 'woocommerce_checkout_registration_enabled', $bool_value ? '__return_true' : '__return_false', 0 );
}
break;
case 'enable_guest_checkout' :
case 'enable_guest_checkout':
$bool_value = wc_string_to_bool( $value );
if ( $bool_value === $this->is_registration_required() ) {
@ -103,13 +107,13 @@ class WC_Checkout {
add_filter( 'woocommerce_checkout_registration_required', $bool_value ? '__return_false' : '__return_true', 0 );
}
break;
case 'checkout_fields' :
case 'checkout_fields':
$this->fields = $value;
break;
case 'shipping_methods' :
case 'shipping_methods':
WC()->session->set( 'chosen_shipping_methods', $value );
break;
case 'posted' :
case 'posted':
$this->legacy_posted_data = $value;
break;
}
@ -118,33 +122,32 @@ class WC_Checkout {
/**
* Gets the legacy public variables for backwards compatibility.
*
* @param string $key
*
* @param string $key Key.
* @return array|string
*/
public function __get( $key ) {
if ( in_array( $key, array( 'posted', 'shipping_method', 'payment_method' ) ) && empty( $this->legacy_posted_data ) ) {
if ( in_array( $key, array( 'posted', 'shipping_method', 'payment_method' ), true ) && empty( $this->legacy_posted_data ) ) {
$this->legacy_posted_data = $this->get_posted_data();
}
switch ( $key ) {
case 'enable_signup' :
case 'enable_signup':
return $this->is_registration_enabled();
case 'enable_guest_checkout' :
case 'enable_guest_checkout':
return ! $this->is_registration_required();
case 'must_create_account' :
case 'must_create_account':
return $this->is_registration_required() && ! is_user_logged_in();
case 'checkout_fields' :
case 'checkout_fields':
return $this->get_checkout_fields();
case 'posted' :
case 'posted':
wc_doing_it_wrong( 'WC_Checkout->posted', 'Use $_POST directly.', '3.0.0' );
return $this->legacy_posted_data;
case 'shipping_method' :
case 'shipping_method':
return $this->legacy_posted_data['shipping_method'];
case 'payment_method' :
case 'payment_method':
return $this->legacy_posted_data['payment_method'];
case 'customer_id' :
case 'customer_id':
return apply_filters( 'woocommerce_checkout_customer_id', get_current_user_id() );
case 'shipping_methods' :
case 'shipping_methods':
return (array) WC()->session->get( 'chosen_shipping_methods' );
}
}
@ -206,19 +209,19 @@ class WC_Checkout {
);
if ( 'no' === get_option( 'woocommerce_registration_generate_username' ) ) {
$this->fields['account']['account_username'] = array(
'type' => 'text',
'label' => __( 'Account username', 'woocommerce' ),
'required' => true,
'placeholder' => esc_attr__( 'Username', 'woocommerce' ),
'type' => 'text',
'label' => __( 'Account username', 'woocommerce' ),
'required' => true,
'placeholder' => esc_attr__( 'Username', 'woocommerce' ),
);
}
if ( 'no' === get_option( 'woocommerce_registration_generate_password' ) ) {
$this->fields['account']['account_password'] = array(
'type' => 'password',
'label' => __( 'Create account password', 'woocommerce' ),
'required' => true,
'placeholder' => esc_attr__( 'Password', 'woocommerce' ),
'type' => 'password',
'label' => __( 'Create account password', 'woocommerce' ),
'required' => true,
'placeholder' => esc_attr__( 'Password', 'woocommerce' ),
);
}
@ -254,29 +257,31 @@ class WC_Checkout {
/**
* Create an order. Error codes:
* 520 - Cannot insert order into the database.
* 521 - Cannot get order after creation.
* 522 - Cannot update order.
* 525 - Cannot create line item.
* 526 - Cannot create fee item.
* 527 - Cannot create shipping item.
* 528 - Cannot create tax item.
* 529 - Cannot create coupon item.
* 520 - Cannot insert order into the database.
* 521 - Cannot get order after creation.
* 522 - Cannot update order.
* 525 - Cannot create line item.
* 526 - Cannot create fee item.
* 527 - Cannot create shipping item.
* 528 - Cannot create tax item.
* 529 - Cannot create coupon item.
*
* @throws Exception
* @param $data Posted data.
* @throws Exception When checkout validation fails.
* @param array $data Posted data.
* @return int|WP_ERROR
*/
public function create_order( $data ) {
// Give plugins the opportunity to create an order themselves.
if ( $order_id = apply_filters( 'woocommerce_create_order', null, $this ) ) {
$order_id = apply_filters( 'woocommerce_create_order', null, $this );
if ( $order_id ) {
return $order_id;
}
try {
$order_id = absint( WC()->session->get( 'order_awaiting_payment' ) );
$cart_hash = md5( json_encode( wc_clean( WC()->cart->get_cart_for_session() ) ) . WC()->cart->total );
$cart_hash = md5( wp_json_encode( wc_clean( WC()->cart->get_cart_for_session() ) ) . WC()->cart->total );
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
$order = $order_id ? wc_get_order( $order_id ) : null;
/**
* If there is an order pending payment, we can resume it here so
@ -284,7 +289,7 @@ class WC_Checkout {
* different items or cost, create a new order. We use a hash to
* detect changes which is based on cart items + order total.
*/
if ( $order_id && ( $order = wc_get_order( $order_id ) ) && $order->has_cart_hash( $cart_hash ) && $order->has_status( array( 'pending', 'failed' ) ) ) {
if ( $order && $order->has_cart_hash( $cart_hash ) && $order->has_status( array( 'pending', 'failed' ) ) ) {
// Action for 3rd parties.
do_action( 'woocommerce_resume_order', $order_id );
@ -298,10 +303,10 @@ class WC_Checkout {
if ( is_callable( array( $order, "set_{$key}" ) ) ) {
$order->{"set_{$key}"}( $value );
// Store custom fields prefixed with wither shipping_ or billing_. This is for backwards compatibility with 2.6.x.
// TODO: Fix conditional to only include shipping/billing address fields in a smarter way without str(i)pos.
// Store custom fields prefixed with wither shipping_ or billing_. This is for backwards compatibility with 2.6.x.
// TODO: Fix conditional to only include shipping/billing address fields in a smarter way without str(i)pos.
} elseif ( ( 0 === stripos( $key, 'billing_' ) || 0 === stripos( $key, 'shipping_' ) )
&& ! in_array( $key, array( 'shipping_method', 'shipping_total', 'shipping_tax' ) ) ) {
&& ! in_array( $key, array( 'shipping_method', 'shipping_total', 'shipping_tax' ), true ) ) {
$order->update_meta_data( '_' . $key, $value );
}
}
@ -314,7 +319,7 @@ class WC_Checkout {
$order->set_customer_ip_address( WC_Geolocation::get_ip_address() );
$order->set_customer_user_agent( wc_get_user_agent() );
$order->set_customer_note( isset( $data['order_comments'] ) ? $data['order_comments'] : '' );
$order->set_payment_method( isset( $available_gateways[ $data['payment_method'] ] ) ? $available_gateways[ $data['payment_method'] ] : $data['payment_method'] );
$order->set_payment_method( isset( $available_gateways[ $data['payment_method'] ] ) ? $available_gateways[ $data['payment_method'] ] : $data['payment_method'] );
$order->set_shipping_total( WC()->cart->get_shipping_total() );
$order->set_discount_total( WC()->cart->get_discount_total() );
$order->set_discount_tax( WC()->cart->get_discount_tax() );
@ -329,6 +334,7 @@ class WC_Checkout {
/**
* Action hook to adjust order before save.
*
* @since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order', $order, $data );
@ -347,40 +353,46 @@ class WC_Checkout {
/**
* Add line items to the order.
*
* @param WC_Order $order
* @param WC_Cart $cart
* @param WC_Order $order Order instance.
* @param WC_Cart $cart Cart instance.
*/
public function create_order_line_items( &$order, $cart ) {
foreach ( $cart->get_cart() as $cart_item_key => $values ) {
/**
* Filter hook to get initial item object.
*
* @since 3.1.0
*/
$item = apply_filters( 'woocommerce_checkout_create_order_line_item_object', new WC_Order_Item_Product(), $cart_item_key, $values, $order );
$product = $values['data'];
$item->legacy_values = $values; // @deprecated For legacy actions.
$item->legacy_cart_item_key = $cart_item_key; // @deprecated For legacy actions.
$item->set_props( array(
'quantity' => $values['quantity'],
'variation' => $values['variation'],
'subtotal' => $values['line_subtotal'],
'total' => $values['line_total'],
'subtotal_tax' => $values['line_subtotal_tax'],
'total_tax' => $values['line_tax'],
'taxes' => $values['line_tax_data'],
) );
$item->set_props(
array(
'quantity' => $values['quantity'],
'variation' => $values['variation'],
'subtotal' => $values['line_subtotal'],
'total' => $values['line_total'],
'subtotal_tax' => $values['line_subtotal_tax'],
'total_tax' => $values['line_tax'],
'taxes' => $values['line_tax_data'],
)
);
if ( $product ) {
$item->set_props( array(
'name' => $product->get_name(),
'tax_class' => $product->get_tax_class(),
'product_id' => $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id(),
'variation_id' => $product->is_type( 'variation' ) ? $product->get_id() : 0,
) );
$item->set_props(
array(
'name' => $product->get_name(),
'tax_class' => $product->get_tax_class(),
'product_id' => $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id(),
'variation_id' => $product->is_type( 'variation' ) ? $product->get_id() : 0,
)
);
}
$item->set_backorder_meta();
/**
* Action hook to adjust item before save.
*
* @since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order_line_item', $item, $cart_item_key, $values, $order );
@ -393,27 +405,30 @@ class WC_Checkout {
/**
* Add fees to the order.
*
* @param WC_Order $order
* @param WC_Cart $cart
* @param WC_Order $order Order instance.
* @param WC_Cart $cart Cart instance.
*/
public function create_order_fee_lines( &$order, $cart ) {
foreach ( $cart->get_fees() as $fee_key => $fee ) {
$item = new WC_Order_Item_Fee();
$item->legacy_fee = $fee; // @deprecated For legacy actions.
$item->legacy_fee_key = $fee_key; // @deprecated For legacy actions.
$item->set_props( array(
'name' => $fee->name,
'tax_class' => $fee->taxable ? $fee->tax_class: 0,
'amount' => $fee->amount,
'total' => $fee->total,
'total_tax' => $fee->tax,
'taxes' => array(
'total' => $fee->tax_data,
),
) );
$item->set_props(
array(
'name' => $fee->name,
'tax_class' => $fee->taxable ? $fee->tax_class : 0,
'amount' => $fee->amount,
'total' => $fee->total,
'total_tax' => $fee->tax,
'taxes' => array(
'total' => $fee->tax_data,
),
)
);
/**
* Action hook to adjust item before save.
*
* @since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order_fee_item', $item, $fee_key, $fee, $order );
@ -426,26 +441,27 @@ class WC_Checkout {
/**
* Add shipping lines to the order.
*
* @param WC_Order $order
* @param array $chosen_shipping_methods
* @param array $packages
* @param WC_Order $order Order Instance.
* @param array $chosen_shipping_methods Chosen shipping methods.
* @param array $packages Packages.
*/
public function create_order_shipping_lines( &$order, $chosen_shipping_methods, $packages ) {
foreach ( $packages as $package_key => $package ) {
if ( isset( $chosen_shipping_methods[ $package_key ], $package['rates'][ $chosen_shipping_methods[ $package_key ] ] ) ) {
/** @var WC_Shipping_Rate $shipping_rate */
$shipping_rate = $package['rates'][ $chosen_shipping_methods[ $package_key ] ];
$item = new WC_Order_Item_Shipping();
$item->legacy_package_key = $package_key; // @deprecated For legacy actions.
$item->set_props( array(
'method_title' => $shipping_rate->label,
'method_id' => $shipping_rate->method_id,
'instance_id' => $shipping_rate->instance_id,
'total' => wc_format_decimal( $shipping_rate->cost ),
'taxes' => array(
'total' => $shipping_rate->taxes,
),
) );
$item->set_props(
array(
'method_title' => $shipping_rate->label,
'method_id' => $shipping_rate->method_id,
'instance_id' => $shipping_rate->instance_id,
'total' => wc_format_decimal( $shipping_rate->cost ),
'taxes' => array(
'total' => $shipping_rate->taxes,
),
)
);
foreach ( $shipping_rate->get_meta_data() as $key => $value ) {
$item->add_meta_data( $key, $value, true );
@ -453,6 +469,7 @@ class WC_Checkout {
/**
* Action hook to adjust item before save.
*
* @since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order_shipping_item', $item, $package_key, $package, $order );
@ -466,24 +483,27 @@ class WC_Checkout {
/**
* Add tax lines to the order.
*
* @param WC_Order $order
* @param WC_Cart $cart
* @param WC_Order $order Order instance.
* @param WC_Cart $cart Cart instance.
*/
public function create_order_tax_lines( &$order, $cart ) {
foreach ( array_keys( $cart->get_cart_contents_taxes() + $cart->get_shipping_taxes() + $cart->get_fee_taxes() ) as $tax_rate_id ) {
if ( $tax_rate_id && apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) !== $tax_rate_id ) {
$item = new WC_Order_Item_Tax();
$item->set_props( array(
'rate_id' => $tax_rate_id,
'tax_total' => $cart->get_tax_amount( $tax_rate_id ),
'shipping_tax_total' => $cart->get_shipping_tax_amount( $tax_rate_id ),
'rate_code' => WC_Tax::get_rate_code( $tax_rate_id ),
'label' => WC_Tax::get_rate_label( $tax_rate_id ),
'compound' => WC_Tax::is_compound( $tax_rate_id ),
) );
$item->set_props(
array(
'rate_id' => $tax_rate_id,
'tax_total' => $cart->get_tax_amount( $tax_rate_id ),
'shipping_tax_total' => $cart->get_shipping_tax_amount( $tax_rate_id ),
'rate_code' => WC_Tax::get_rate_code( $tax_rate_id ),
'label' => WC_Tax::get_rate_label( $tax_rate_id ),
'compound' => WC_Tax::is_compound( $tax_rate_id ),
)
);
/**
* Action hook to adjust item before save.
*
* @since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order_tax_item', $item, $tax_rate_id, $order );
@ -497,21 +517,24 @@ class WC_Checkout {
/**
* Add coupon lines to the order.
*
* @param WC_Order $order
* @param WC_Cart $cart
* @param WC_Order $order Order instance.
* @param WC_Cart $cart Cart instance.
*/
public function create_order_coupon_lines( &$order, $cart ) {
foreach ( $cart->get_coupons() as $code => $coupon ) {
$item = new WC_Order_Item_Coupon();
$item->set_props( array(
'code' => $code,
'discount' => $cart->get_coupon_discount_amount( $code ),
'discount_tax' => $cart->get_coupon_discount_tax_amount( $code ),
) );
$item->set_props(
array(
'code' => $code,
'discount' => $cart->get_coupon_discount_amount( $code ),
'discount_tax' => $cart->get_coupon_discount_tax_amount( $code ),
)
);
$item->add_meta_data( 'coupon_data', $coupon->get_data() );
/**
* Action hook to adjust item before save.
*
* @since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order_coupon_item', $item, $code, $coupon, $order );
@ -525,10 +548,8 @@ class WC_Checkout {
* See if a fieldset should be skipped.
*
* @since 3.0.0
*
* @param string $fieldset_key
* @param array $data
*
* @param string $fieldset_key Fieldset key.
* @param array $data Posted data.
* @return bool
*/
protected function maybe_skip_fieldset( $fieldset_key, $data ) {
@ -550,12 +571,12 @@ class WC_Checkout {
public function get_posted_data() {
$skipped = array();
$data = array(
'terms' => (int) isset( $_POST['terms'] ),
'createaccount' => (int) ! empty( $_POST['createaccount'] ),
'payment_method' => isset( $_POST['payment_method'] ) ? wc_clean( $_POST['payment_method'] ) : '',
'shipping_method' => isset( $_POST['shipping_method'] ) ? wc_clean( $_POST['shipping_method'] ) : '',
'ship_to_different_address' => ! empty( $_POST['ship_to_different_address'] ) && ! wc_ship_to_billing_address_only(),
'woocommerce_checkout_update_totals' => isset( $_POST['woocommerce_checkout_update_totals'] ),
'terms' => (int) isset( $_POST['terms'] ), // WPCS: input var ok, CSRF ok.
'createaccount' => (int) ! empty( $_POST['createaccount'] ), // WPCS: input var ok, CSRF ok.
'payment_method' => isset( $_POST['payment_method'] ) ? wc_clean( wp_unslash( $_POST['payment_method'] ) ) : '', // WPCS: input var ok, CSRF ok.
'shipping_method' => isset( $_POST['shipping_method'] ) ? wc_clean( wp_unslash( $_POST['shipping_method'] ) ) : '', // WPCS: input var ok, CSRF ok.
'ship_to_different_address' => ! empty( $_POST['ship_to_different_address'] ) && ! wc_ship_to_billing_address_only(), // WPCS: input var ok, CSRF ok.
'woocommerce_checkout_update_totals' => isset( $_POST['woocommerce_checkout_update_totals'] ), // WPCS: input var ok, CSRF ok.
);
foreach ( $this->get_checkout_fields() as $fieldset_key => $fieldset ) {
if ( $this->maybe_skip_fieldset( $fieldset_key, $data ) ) {
@ -566,17 +587,17 @@ class WC_Checkout {
$type = sanitize_title( isset( $field['type'] ) ? $field['type'] : 'text' );
switch ( $type ) {
case 'checkbox' :
$value = isset( $_POST[ $key ] ) ? 1 : '';
case 'checkbox':
$value = isset( $_POST[ $key ] ) ? 1 : ''; // WPCS: input var ok, CSRF ok.
break;
case 'multiselect' :
$value = isset( $_POST[ $key ] ) ? implode( ', ', wc_clean( $_POST[ $key ] ) ) : '';
case 'multiselect':
$value = isset( $_POST[ $key ] ) ? implode( ', ', wc_clean( wp_unslash( $_POST[ $key ] ) ) ) : ''; // WPCS: input var ok, CSRF ok.
break;
case 'textarea' :
$value = isset( $_POST[ $key ] ) ? wc_sanitize_textarea( $_POST[ $key ] ) : '';
case 'textarea':
$value = isset( $_POST[ $key ] ) ? wc_sanitize_textarea( wp_unslash( $_POST[ $key ] ) ) : ''; // WPCS: input var ok, CSRF ok.
break;
default :
$value = isset( $_POST[ $key ] ) ? wc_clean( $_POST[ $key ] ) : '';
default:
$value = isset( $_POST[ $key ] ) ? wc_clean( wp_unslash( $_POST[ $key ] ) ) : ''; // WPCS: input var ok, CSRF ok.
break;
}
@ -584,7 +605,7 @@ class WC_Checkout {
}
}
if ( in_array( 'shipping', $skipped ) && ( WC()->cart->needs_shipping_address() || wc_ship_to_billing_address_only() ) ) {
if ( in_array( 'shipping', $skipped, true ) && ( WC()->cart->needs_shipping_address() || wc_ship_to_billing_address_only() ) ) {
foreach ( $this->get_checkout_fields( 'shipping' ) as $key => $field ) {
$data[ $key ] = isset( $data[ 'billing_' . substr( $key, 9 ) ] ) ? $data[ 'billing_' . substr( $key, 9 ) ] : '';
}
@ -600,8 +621,8 @@ class WC_Checkout {
* Validates the posted checkout data based on field properties.
*
* @since 3.0.0
* @param array $data An array of posted data.
* @param WP_Error $errors
* @param array $data An array of posted data.
* @param WP_Error $errors Validation error.
*/
protected function validate_posted_data( &$data, &$errors ) {
foreach ( $this->get_checkout_fields() as $fieldset_key => $fieldset ) {
@ -617,26 +638,27 @@ class WC_Checkout {
$field_label = isset( $field['label'] ) ? $field['label'] : '';
switch ( $fieldset_key ) {
case 'shipping' :
case 'shipping':
/* translators: %s: field name */
$field_label = sprintf( __( 'Shipping %s', 'woocommerce' ), $field_label );
break;
case 'billing' :
break;
case 'billing':
/* translators: %s: field name */
$field_label = sprintf( __( 'Billing %s', 'woocommerce' ), $field_label );
break;
break;
}
if ( in_array( 'postcode', $format ) ) {
if ( in_array( 'postcode', $format, true ) ) {
$country = isset( $data[ $fieldset_key . '_country' ] ) ? $data[ $fieldset_key . '_country' ] : WC()->customer->{"get_{$fieldset_key}_country"}();
$data[ $key ] = wc_format_postcode( $data[ $key ], $country );
if ( '' !== $data[ $key ] && ! WC_Validation::is_postcode( $data[ $key ], $country ) ) {
/* translators: %s: field name */
$errors->add( 'validation', sprintf( __( '%s is not a valid postcode / ZIP.', 'woocommerce' ), '<strong>' . esc_html( $field_label ) . '</strong>' ) );
}
}
if ( in_array( 'phone', $format ) ) {
if ( in_array( 'phone', $format, true ) ) {
$data[ $key ] = wc_format_phone_number( $data[ $key ] );
if ( '' !== $data[ $key ] && ! WC_Validation::is_phone( $data[ $key ] ) ) {
@ -645,7 +667,7 @@ class WC_Checkout {
}
}
if ( in_array( 'email', $format ) && '' !== $data[ $key ] ) {
if ( in_array( 'email', $format, true ) && '' !== $data[ $key ] ) {
$data[ $key ] = sanitize_email( $data[ $key ] );
if ( ! is_email( $data[ $key ] ) ) {
@ -655,11 +677,11 @@ class WC_Checkout {
}
}
if ( '' !== $data[ $key ] && in_array( 'state', $format ) ) {
if ( '' !== $data[ $key ] && in_array( 'state', $format, true ) ) {
$country = isset( $data[ $fieldset_key . '_country' ] ) ? $data[ $fieldset_key . '_country' ] : WC()->customer->{"get_{$fieldset_key}_country"}();
$valid_states = WC()->countries->get_states( $country );
if ( ! empty( $valid_states ) && is_array( $valid_states ) && sizeof( $valid_states ) > 0 ) {
if ( ! empty( $valid_states ) && is_array( $valid_states ) && count( $valid_states ) > 0 ) {
$valid_state_values = array_map( 'wc_strtoupper', array_flip( array_map( 'wc_strtoupper', $valid_states ) ) );
$data[ $key ] = wc_strtoupper( $data[ $key ] );
@ -668,7 +690,7 @@ class WC_Checkout {
$data[ $key ] = $valid_state_values[ $data[ $key ] ];
}
if ( ! in_array( $data[ $key ], $valid_state_values ) ) {
if ( ! in_array( $data[ $key ], $valid_state_values, true ) ) {
/* translators: 1: state field 2: valid states */
$errors->add( 'validation', sprintf( __( '%1$s is not valid. Please enter one of the following: %2$s', 'woocommerce' ), '<strong>' . esc_html( $field_label ) . '</strong>', implode( ', ', $valid_states ) ) );
}
@ -687,14 +709,14 @@ class WC_Checkout {
* Validates that the checkout has enough info to proceed.
*
* @since 3.0.0
* @param array $data An array of posted data.
* @param WP_Error $errors
* @param array $data An array of posted data.
* @param WP_Error $errors Validation errors.
*/
protected function validate_checkout( &$data, &$errors ) {
$this->validate_posted_data( $data, $errors );
$this->check_cart_items();
if ( empty( $data['woocommerce_checkout_update_totals'] ) && ! empty( $_POST['terms-field'] ) && empty( $data['terms'] ) && apply_filters( 'woocommerce_checkout_show_terms', wc_get_page_id( 'terms' ) > 0 ) ) {
if ( empty( $data['woocommerce_checkout_update_totals'] ) && ! empty( $_POST['terms-field'] ) && empty( $data['terms'] ) && apply_filters( 'woocommerce_checkout_show_terms', wc_get_page_id( 'terms' ) > 0 ) ) { // WPCS: input var ok, CSRF ok.
$errors->add( 'terms', __( 'You must accept our Terms &amp; Conditions.', 'woocommerce' ) );
}
@ -703,7 +725,8 @@ class WC_Checkout {
if ( empty( $shipping_country ) ) {
$errors->add( 'shipping', __( 'Please enter an address to continue.', 'woocommerce' ) );
} elseif ( ! in_array( WC()->customer->get_shipping_country(), array_keys( WC()->countries->get_shipping_countries() ) ) ) {
} elseif ( ! in_array( WC()->customer->get_shipping_country(), array_keys( WC()->countries->get_shipping_countries() ), true ) ) {
/* translators: %s: shipping location */
$errors->add( 'shipping', sprintf( __( 'Unfortunately <strong>we do not ship %s</strong>. Please enter an alternative shipping address.', 'woocommerce' ), WC()->countries->shipping_to_prefix() . ' ' . WC()->customer->get_shipping_country() ) );
} else {
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
@ -733,9 +756,9 @@ class WC_Checkout {
* Set address field for customer.
*
* @since 3.0.7
* @param $field string to update
* @param $key
* @param $data array of data to get the value from
* @param string $field String to update.
* @param string $key Field key.
* @param array $data Array of data to get the value from.
*/
protected function set_customer_address_fields( $field, $key, $data ) {
if ( isset( $data[ "billing_{$field}" ] ) ) {
@ -750,8 +773,8 @@ class WC_Checkout {
/**
* Update customer and session data from the posted checkout data.
*
* @since 3.0.0
* @param array $data
* @since 3.0.0
* @param array $data Posted data.
*/
protected function update_session( $data ) {
// Update both shipping and billing to the passed billing address first if set.
@ -767,7 +790,7 @@ class WC_Checkout {
array_walk( $address_fields, array( $this, 'set_customer_address_fields' ), $data );
WC()->customer->save();
// Update customer shipping and payment method to posted method
// Update customer shipping and payment method to posted method.
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
if ( is_array( $data['shipping_method'] ) ) {
@ -787,9 +810,9 @@ class WC_Checkout {
/**
* Process an order that does require payment.
*
* @since 3.0.0
* @param int $order_id
* @param string $payment_method
* @since 3.0.0
* @param int $order_id Order ID.
* @param string $payment_method Payment method.
*/
protected function process_order_payment( $order_id, $payment_method ) {
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
@ -798,13 +821,13 @@ class WC_Checkout {
return;
}
// Store Order ID in session so it can be re-used after payment failure
// Store Order ID in session so it can be re-used after payment failure.
WC()->session->set( 'order_awaiting_payment', $order_id );
// Process Payment
// Process Payment.
$result = $available_gateways[ $payment_method ]->process_payment( $order_id );
// Redirect to success/confirmation/payment page
// Redirect to success/confirmation/payment page.
if ( isset( $result['result'] ) && 'success' === $result['result'] ) {
$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id );
@ -820,8 +843,8 @@ class WC_Checkout {
/**
* Process an order that doesn't require payment.
*
* @since 3.0.0
* @param int $order_id
* @since 3.0.0
* @param int $order_id Order ID.
*/
protected function process_order_without_payment( $order_id ) {
$order = wc_get_order( $order_id );
@ -829,10 +852,12 @@ class WC_Checkout {
wc_empty_cart();
if ( is_ajax() ) {
wp_send_json( array(
'result' => 'success',
'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $order->get_checkout_order_received_url(), $order ),
) );
wp_send_json(
array(
'result' => 'success',
'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $order->get_checkout_order_received_url(), $order ),
)
);
} else {
wp_safe_redirect(
apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $order->get_checkout_order_received_url(), $order )
@ -843,8 +868,9 @@ class WC_Checkout {
/**
* Create a new customer account if needed.
* @param array $data
* @throws Exception
*
* @throws Exception When not able to create customer.
* @param array $data Posted data.
*/
protected function process_customer( $data ) {
$customer_id = apply_filters( 'woocommerce_checkout_customer_id', get_current_user_id() );
@ -861,10 +887,10 @@ class WC_Checkout {
wp_set_current_user( $customer_id );
wc_set_customer_auth_cookie( $customer_id );
// As we are now logged in, checkout will need to refresh to show logged in data
// As we are now logged in, checkout will need to refresh to show logged in data.
WC()->session->set( 'reload_checkout', true );
// Also, recalculate cart totals to reveal any role-based discounts that were unavailable before registering
// Also, recalculate cart totals to reveal any role-based discounts that were unavailable before registering.
WC()->cart->calculate_totals();
}
@ -895,7 +921,7 @@ class WC_Checkout {
if ( is_callable( array( $customer, "set_{$key}" ) ) ) {
$customer->{"set_{$key}"}( $value );
// Store custom fields prefixed with wither shipping_ or billing_.
// Store custom fields prefixed with wither shipping_ or billing_.
} elseif ( 0 === stripos( $key, 'billing_' ) || 0 === stripos( $key, 'shipping_' ) ) {
$customer->update_meta_data( $key, $value );
}
@ -903,6 +929,7 @@ class WC_Checkout {
/**
* Action hook to adjust customer before save.
*
* @since 3.0.0
*/
do_action( 'woocommerce_checkout_update_customer', $customer, $data );
@ -918,7 +945,7 @@ class WC_Checkout {
*/
protected function send_ajax_failure_response() {
if ( is_ajax() ) {
// only print notices if not reloading the checkout, otherwise they're lost in the page reload
// Only print notices if not reloading the checkout, otherwise they're lost in the page reload.
if ( ! isset( WC()->session->reload_checkout ) ) {
ob_start();
wc_print_notices();
@ -940,10 +967,14 @@ class WC_Checkout {
/**
* Process the checkout after the confirm order button is pressed.
*
* @throws Exception When validation fails.
*/
public function process_checkout() {
try {
if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-process_checkout' ) ) {
$nonce_value = wc_get_var( $_REQUEST['woocommerce-process-checkout-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( empty( $nonce_value ) || ! wp_verify_nonce( $nonce_value, 'woocommerce-process_checkout' ) ) {
WC()->session->set( 'refresh_totals', true );
throw new Exception( __( 'We were unable to process your order, please try again.', 'woocommerce' ) );
}
@ -954,6 +985,7 @@ class WC_Checkout {
do_action( 'woocommerce_before_checkout_process' );
if ( WC()->cart->is_empty() ) {
/* translators: %s: shop cart url */
throw new Exception( sprintf( __( 'Sorry, your session has expired. <a href="%s" class="wc-backward">Return to shop</a>', 'woocommerce' ), esc_url( wc_get_page_permalink( 'shop' ) ) ) );
}
@ -998,8 +1030,8 @@ class WC_Checkout {
/**
* Get a posted address field after sanitization and validation.
*
* @param string $key
* @param string $type billing for shipping
* @param string $key Field key.
* @param string $type Type of address. Available options: 'billing' or 'shipping'.
* @return string
*/
public function get_posted_address_data( $key, $type = 'billing' ) {
@ -1014,12 +1046,12 @@ class WC_Checkout {
/**
* Gets the value either from the posted data, or from the users meta data.
*
* @param string $input
* @param string $input Input key.
* @return string
*/
public function get_value( $input ) {
if ( ! empty( $_POST[ $input ] ) ) {
return wc_clean( $_POST[ $input ] );
if ( ! empty( $_POST[ $input ] ) ) { // WPCS: input var ok, CSRF OK.
return wc_clean( wp_unslash( $_POST[ $input ] ) ); // WPCS: input var ok, CSRF OK.
} else {

View File

@ -6,9 +6,7 @@
* @version 3.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* CLI class.

View File

@ -1,19 +1,17 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Comments
*
* Handle comments (reviews and order notes).
*
* @class WC_Comments
* @version 2.3.0
* @package WooCommerce/Classes/Products
* @category Class
* @author WooThemes
* @package WooCommerce/Classes/Products
* @version 2.3.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Comments class.
*/
class WC_Comments {
@ -21,34 +19,34 @@ class WC_Comments {
* Hook in methods.
*/
public static function init() {
// Rating posts
// Rating posts.
add_filter( 'comments_open', array( __CLASS__, 'comments_open' ), 10, 2 );
add_filter( 'preprocess_comment', array( __CLASS__, 'check_comment_rating' ), 0 );
add_action( 'comment_post', array( __CLASS__, 'add_comment_rating' ), 1 );
add_action( 'comment_moderation_recipients', array( __CLASS__, 'comment_moderation_recipients' ), 10, 2 );
// Clear transients
// Clear transients.
add_action( 'wp_update_comment_count', array( __CLASS__, 'clear_transients' ) );
// Secure order notes
// Secure order notes.
add_filter( 'comments_clauses', array( __CLASS__, 'exclude_order_comments' ), 10, 1 );
add_filter( 'comment_feed_where', array( __CLASS__, 'exclude_order_comments_from_feed_where' ) );
// Secure webhook comments
// Secure webhook comments.
add_filter( 'comments_clauses', array( __CLASS__, 'exclude_webhook_comments' ), 10, 1 );
add_filter( 'comment_feed_where', array( __CLASS__, 'exclude_webhook_comments_from_feed_where' ) );
// Count comments
// Count comments.
add_filter( 'wp_count_comments', array( __CLASS__, 'wp_count_comments' ), 10, 2 );
// Delete comments count cache whenever there is a new comment or a comment status changes
// Delete comments count cache whenever there is a new comment or a comment status changes.
add_action( 'wp_insert_comment', array( __CLASS__, 'delete_comments_count_cache' ) );
add_action( 'wp_set_comment_status', array( __CLASS__, 'delete_comments_count_cache' ) );
// Support avatars for `review` comment type
// Support avatars for `review` comment type.
add_filter( 'get_avatar_comment_types', array( __CLASS__, 'add_avatar_for_review_comment_type' ) );
// Review of verified purchase
// Review of verified purchase.
add_action( 'comment_post', array( __CLASS__, 'add_comment_purchase_verification' ) );
}
@ -56,8 +54,8 @@ class WC_Comments {
* See if comments are open.
*
* @since 3.1.0
* @param bool $open
* @param int $post_id
* @param bool $open Whether the current post is open for comments.
* @param int $post_id Post ID.
* @return bool
*/
public static function comments_open( $open, $post_id ) {
@ -75,7 +73,8 @@ class WC_Comments {
* shop managers can view orders anyway.
*
* The frontend view order pages get around this filter by using remove_filter('comments_clauses', array( 'WC_Comments' ,'exclude_order_comments'), 10, 1 );
* @param array $clauses
*
* @param array $clauses A compacted array of comment query clauses.
* @return array
*/
public static function exclude_order_comments( $clauses ) {
@ -84,7 +83,10 @@ class WC_Comments {
}
/**
* Exclude order comments from feed.
*
* @deprecated 3.1
* @param mixed $join Deprecated.
*/
public static function exclude_order_comments_from_feed_join( $join ) {
wc_deprecated_function( 'WC_Comments::exclude_order_comments_from_feed_join', '3.1' );
@ -93,7 +95,7 @@ class WC_Comments {
/**
* Exclude order comments from queries and RSS.
*
* @param string $where
* @param string $where The WHERE clause of the query.
* @return string
*/
public static function exclude_order_comments_from_feed_where( $where ) {
@ -102,8 +104,9 @@ class WC_Comments {
/**
* Exclude webhook comments from queries and RSS.
*
* @since 2.2
* @param array $clauses
* @param array $clauses A compacted array of comment query clauses.
* @return array
*/
public static function exclude_webhook_comments( $clauses ) {
@ -112,7 +115,10 @@ class WC_Comments {
}
/**
* Exclude webhooks comments from feed.
*
* @deprecated 3.1
* @param mixed $join Deprecated.
*/
public static function exclude_webhook_comments_from_feed_join( $join ) {
wc_deprecated_function( 'WC_Comments::exclude_webhook_comments_from_feed_join', '3.1' );
@ -120,8 +126,9 @@ class WC_Comments {
/**
* Exclude webhook comments from queries and RSS.
*
* @since 2.1
* @param string $where
* @param string $where The WHERE clause of the query.
* @return string
*/
public static function exclude_webhook_comments_from_feed_where( $where ) {
@ -131,13 +138,13 @@ class WC_Comments {
/**
* Validate the comment ratings.
*
* @param array $comment_data
* @param array $comment_data Comment data.
* @return array
*/
public static function check_comment_rating( $comment_data ) {
// If posting a comment (not trackback etc) and not logged in
if ( ! is_admin() && isset( $_POST['comment_post_ID'], $_POST['rating'], $comment_data['comment_type'] ) && 'product' === get_post_type( $_POST['comment_post_ID'] ) && empty( $_POST['rating'] ) && '' === $comment_data['comment_type'] && 'yes' === get_option( 'woocommerce_enable_review_rating' ) && 'yes' === get_option( 'woocommerce_review_rating_required' ) ) {
wp_die( __( 'Please rate the product.', 'woocommerce' ) );
// If posting a comment (not trackback etc) and not logged in.
if ( ! is_admin() && isset( $_POST['comment_post_ID'], $_POST['rating'], $comment_data['comment_type'] ) && 'product' === get_post_type( absint( $_POST['comment_post_ID'] ) ) && empty( $_POST['rating'] ) && '' === $comment_data['comment_type'] && 'yes' === get_option( 'woocommerce_enable_review_rating' ) && 'yes' === get_option( 'woocommerce_review_rating_required' ) ) { // WPCS: input var ok, CSRF ok.
wp_die( esc_html__( 'Please rate the product.', 'woocommerce' ) );
exit;
}
return $comment_data;
@ -145,16 +152,17 @@ class WC_Comments {
/**
* Rating field for comments.
* @param int $comment_id
*
* @param int $comment_id Comment ID.
*/
public static function add_comment_rating( $comment_id ) {
if ( isset( $_POST['rating'] ) && 'product' === get_post_type( $_POST['comment_post_ID'] ) ) {
if ( ! $_POST['rating'] || $_POST['rating'] > 5 || $_POST['rating'] < 0 ) {
if ( isset( $_POST['rating'], $_POST['comment_post_ID'] ) && 'product' === get_post_type( absint( $_POST['comment_post_ID'] ) ) ) { // WPCS: input var ok, CSRF ok.
if ( ! $_POST['rating'] || $_POST['rating'] > 5 || $_POST['rating'] < 0 ) { // WPCS: input var ok, CSRF ok, sanitization ok.
return;
}
add_comment_meta( $comment_id, 'rating', (int) esc_attr( $_POST['rating'] ), true );
add_comment_meta( $comment_id, 'rating', intval( $_POST['rating'] ), true ); // WPCS: input var ok, CSRF ok.
$post_id = isset( $_POST['comment_post_ID'] ) ? (int) $_POST['comment_post_ID'] : 0;
$post_id = isset( $_POST['comment_post_ID'] ) ? absint( $_POST['comment_post_ID'] ) : 0; // WPCS: input var ok, CSRF ok.
if ( $post_id ) {
self::clear_transients( $post_id );
}
@ -163,8 +171,9 @@ class WC_Comments {
/**
* Modify recipient of review email.
* @param array $emails
* @param int $comment_id
*
* @param array $emails Emails.
* @param int $comment_id Comment ID.
* @return array
*/
public static function comment_moderation_recipients( $emails, $comment_id ) {
@ -179,7 +188,8 @@ class WC_Comments {
/**
* Ensure product average rating and review count is kept up to date.
* @param int $post_id
*
* @param int $post_id Post ID.
*/
public static function clear_transients( $post_id ) {
@ -196,8 +206,6 @@ class WC_Comments {
* new comment or the status of a comment changes. Cache
* will be regenerated next time WC_Comments::wp_count_comments()
* is called.
*
* @return void
*/
public static function delete_comments_count_cache() {
delete_transient( 'wc_count_comments' );
@ -223,12 +231,14 @@ class WC_Comments {
'all' => 0,
);
$count = $wpdb->get_results( "
$count = $wpdb->get_results(
"
SELECT comment_approved, COUNT(*) AS num_comments
FROM {$wpdb->comments}
WHERE comment_type NOT IN ('order_note', 'webhook_delivery')
GROUP BY comment_approved
", ARRAY_A );
", ARRAY_A
);
$approved = array(
'0' => 'moderated',
@ -267,8 +277,9 @@ class WC_Comments {
/**
* Make sure WP displays avatars for comments with the `review` type.
*
* @since 2.3
* @param array $comment_types
* @param array $comment_types Comment types.
* @return array
*/
public static function add_avatar_for_review_comment_type( $comment_types ) {
@ -277,7 +288,8 @@ class WC_Comments {
/**
* Determine if a review is from a verified owner at submission.
* @param int $comment_id
*
* @param int $comment_id Comment ID.
* @return bool
*/
public static function add_comment_purchase_verification( $comment_id ) {
@ -294,7 +306,7 @@ class WC_Comments {
* Get product rating for a product. Please note this is not cached.
*
* @since 3.0.0
* @param WC_Product $product
* @param WC_Product $product Product instance.
* @return float
*/
public static function get_average_rating_for_product( &$product ) {
@ -303,14 +315,18 @@ class WC_Comments {
$count = $product->get_rating_count();
if ( $count ) {
$ratings = $wpdb->get_var( $wpdb->prepare("
$ratings = $wpdb->get_var(
$wpdb->prepare(
"
SELECT SUM(meta_value) FROM $wpdb->commentmeta
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
AND comment_post_ID = %d
AND comment_approved = '1'
AND meta_value > 0
", $product->get_id() ) );
", $product->get_id()
)
);
$average = number_format( $ratings / $count, 2, '.', '' );
} else {
$average = 0;
@ -328,18 +344,22 @@ class WC_Comments {
* Get product review count for a product (not replies). Please note this is not cached.
*
* @since 3.0.0
* @param WC_Product $product
* @param WC_Product $product Product instance.
* @return int
*/
public static function get_review_count_for_product( &$product ) {
global $wpdb;
$count = $wpdb->get_var( $wpdb->prepare("
$count = $wpdb->get_var(
$wpdb->prepare(
"
SELECT COUNT(*) FROM $wpdb->comments
WHERE comment_parent = 0
AND comment_post_ID = %d
AND comment_approved = '1'
", $product->get_id() ) );
", $product->get_id()
)
);
$product->set_review_count( $count );
@ -353,14 +373,16 @@ class WC_Comments {
* Get product rating count for a product. Please note this is not cached.
*
* @since 3.0.0
* @param WC_Product $product
* @return array of integers
* @param WC_Product $product Product instance.
* @return int[]
*/
public static function get_rating_counts_for_product( &$product ) {
global $wpdb;
$counts = array();
$raw_counts = $wpdb->get_results( $wpdb->prepare( "
$raw_counts = $wpdb->get_results(
$wpdb->prepare(
"
SELECT meta_value, COUNT( * ) as meta_value_count FROM $wpdb->commentmeta
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
@ -368,10 +390,12 @@ class WC_Comments {
AND comment_approved = '1'
AND meta_value > 0
GROUP BY meta_value
", $product->get_id() ) );
", $product->get_id()
)
);
foreach ( $raw_counts as $count ) {
$counts[ $count->meta_value ] = absint( $count->meta_value_count );
$counts[ $count->meta_value ] = absint( $count->meta_value_count ); // WPCS: slow query ok.
}
$product->set_rating_counts( $counts );

View File

@ -2,13 +2,11 @@
/**
* WooCommerce countries
*
* @version 3.3.0
* @package WooCommerce\l10n
* @package WooCommerce\l10n
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
defined( 'ABSPATH' ) || exit;
/**
* The WooCommerce countries class stores country/state data.
@ -84,7 +82,7 @@ class WC_Countries {
$continents = $this->get_continents();
$continents_and_ccs = wp_list_pluck( $continents, 'countries' );
foreach ( $continents_and_ccs as $continent_code => $countries ) {
if ( false !== array_search( $cc, $countries ) ) {
if ( false !== array_search( $cc, $countries, true ) ) {
return $continent_code;
}
}
@ -376,7 +374,7 @@ class WC_Countries {
public function shipping_to_prefix( $country_code = '' ) {
$country_code = $country_code ? $country_code : WC()->customer->get_shipping_country();
$countries = array( 'GB', 'US', 'AE', 'CZ', 'DO', 'NL', 'PH', 'USAF' );
$return = in_array( $country_code, $countries ) ? __( 'to the', 'woocommerce' ) : __( 'to', 'woocommerce' );
$return = in_array( $country_code, $countries, true ) ? __( 'to the', 'woocommerce' ) : __( 'to', 'woocommerce' );
return apply_filters( 'woocommerce_countries_shipping_to_prefix', $return, $country_code );
}
@ -390,7 +388,7 @@ class WC_Countries {
public function estimated_for_prefix( $country_code = '' ) {
$country_code = $country_code ? $country_code : $this->get_base_country();
$countries = array( 'GB', 'US', 'AE', 'CZ', 'DO', 'NL', 'PH', 'USAF' );
$return = in_array( $country_code, $countries ) ? __( 'the', 'woocommerce' ) . ' ' : '';
$return = in_array( $country_code, $countries, true ) ? __( 'the', 'woocommerce' ) . ' ' : '';
return apply_filters( 'woocommerce_countries_estimated_for_prefix', $return, $country_code );
}
@ -401,7 +399,7 @@ class WC_Countries {
* @return string
*/
public function tax_or_vat() {
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ) ) ) ? __( 'VAT', 'woocommerce' ) : __( 'Tax', 'woocommerce' );
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ) ), true ) ? __( 'VAT', 'woocommerce' ) : __( 'Tax', 'woocommerce' );
return apply_filters( 'woocommerce_countries_tax_or_vat', $return );
}
@ -412,7 +410,7 @@ class WC_Countries {
* @return string
*/
public function inc_tax_or_vat() {
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ) ) ) ? __( '(incl. VAT)', 'woocommerce' ) : __( '(incl. tax)', 'woocommerce' );
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ) ), true ) ? __( '(incl. VAT)', 'woocommerce' ) : __( '(incl. tax)', 'woocommerce' );
return apply_filters( 'woocommerce_countries_inc_tax_or_vat', $return );
}
@ -423,7 +421,7 @@ class WC_Countries {
* @return string
*/
public function ex_tax_or_vat() {
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ) ) ) ? __( '(ex. VAT)', 'woocommerce' ) : __( '(ex. tax)', 'woocommerce' );
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ) ), true ) ? __( '(ex. VAT)', 'woocommerce' ) : __( '(ex. tax)', 'woocommerce' );
return apply_filters( 'woocommerce_countries_ex_tax_or_vat', $return );
}
@ -928,7 +926,7 @@ class WC_Countries {
),
),
'IM' => array(
'state' => array(
'state' => array(
'required' => false,
),
),

View File

@ -1,25 +1,25 @@
<?php
include_once( 'legacy/class-wc-legacy-coupon.php' );
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WooCommerce coupons.
*
* The WooCommerce coupons class gets coupon data from storage and checks coupon validity.
*
* @class WC_Coupon
* @version 3.0.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @package WooCommerce/Classes
* @version 3.0.0
*/
defined( 'ABSPATH' ) || exit;
require_once dirname( __FILE__ ) . '/legacy/class-wc-legacy-coupon.php';
/**
* Coupon class.
*/
class WC_Coupon extends WC_Legacy_Coupon {
/**
* Data array, with defaults.
*
* @since 3.0.0
* @var array
*/
@ -49,7 +49,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
'virtual' => false,
);
// Coupon message codes
// Coupon message codes.
const E_WC_COUPON_INVALID_FILTERED = 100;
const E_WC_COUPON_INVALID_REMOVED = 101;
const E_WC_COUPON_NOT_YOURS_REMOVED = 102;
@ -62,7 +62,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
const E_WC_COUPON_NOT_APPLICABLE = 109;
const E_WC_COUPON_NOT_VALID_SALE_ITEMS = 110;
const E_WC_COUPON_PLEASE_ENTER = 111;
const E_WC_COUPON_MAX_SPEND_LIMIT_MET = 112;
const E_WC_COUPON_MAX_SPEND_LIMIT_MET = 112;
const E_WC_COUPON_EXCLUDED_PRODUCTS = 113;
const E_WC_COUPON_EXCLUDED_CATEGORIES = 114;
const WC_COUPON_SUCCESS = 200;
@ -70,12 +70,14 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Cache group.
*
* @var string
*/
protected $cache_group = 'coupons';
/**
* Coupon constructor. Loads coupon data.
*
* @param mixed $data Coupon data, object, ID or code.
*/
public function __construct( $data = '' ) {
@ -83,7 +85,10 @@ class WC_Coupon extends WC_Legacy_Coupon {
if ( $data instanceof WC_Coupon ) {
$this->set_id( absint( $data->get_id() ) );
} elseif ( $coupon = apply_filters( 'woocommerce_get_shop_coupon_data', false, $data ) ) {
}
$coupon = apply_filters( 'woocommerce_get_shop_coupon_data', false, $data );
if ( $coupon ) {
$this->read_manual_coupon( $data, $coupon );
return;
} elseif ( is_int( $data ) && 'shop_coupon' === get_post_type( $data ) ) {
@ -110,11 +115,12 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Checks the coupon type.
* @param string $type Array or string of types
*
* @param string $type Array or string of types.
* @return bool
*/
public function is_type( $type ) {
return ( $this->get_discount_type() === $type || ( is_array( $type ) && in_array( $this->get_discount_type(), $type ) ) );
return ( $this->get_discount_type() === $type || ( is_array( $type ) && in_array( $this->get_discount_type(), $type, true ) ) );
}
/**
@ -128,18 +134,19 @@ class WC_Coupon extends WC_Legacy_Coupon {
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
|
| Methods for getting data from the coupon object.
|
*/
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
|
| Methods for getting data from the coupon object.
|
*/
/**
* Get coupon code.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_code( $context = 'view' ) {
@ -148,8 +155,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get coupon description.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_description( $context = 'view' ) {
@ -158,8 +166,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get discount type.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_discount_type( $context = 'view' ) {
@ -168,8 +177,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get coupon amount.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return float
*/
public function get_amount( $context = 'view' ) {
@ -178,8 +188,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get coupon expiration date.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return WC_DateTime|NULL object if the date is set or null if there is no date.
*/
public function get_date_expires( $context = 'view' ) {
@ -188,8 +199,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get date_created
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return WC_DateTime|NULL object if the date is set or null if there is no date.
*/
public function get_date_created( $context = 'view' ) {
@ -198,8 +210,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get date_modified
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return WC_DateTime|NULL object if the date is set or null if there is no date.
*/
public function get_date_modified( $context = 'view' ) {
@ -208,8 +221,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get coupon usage count.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer
*/
public function get_usage_count( $context = 'view' ) {
@ -218,8 +232,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get the "indvidual use" checkbox status.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return bool
*/
public function get_individual_use( $context = 'view' ) {
@ -228,8 +243,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get product IDs this coupon can apply to.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_product_ids( $context = 'view' ) {
@ -238,8 +254,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get product IDs that this coupon should not apply to.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_excluded_product_ids( $context = 'view' ) {
@ -248,8 +265,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get coupon usage limit.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer
*/
public function get_usage_limit( $context = 'view' ) {
@ -258,8 +276,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get coupon usage limit per customer (for a single customer)
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer
*/
public function get_usage_limit_per_user( $context = 'view' ) {
@ -268,8 +287,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Usage limited to certain amount of items
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer|null
*/
public function get_limit_usage_to_x_items( $context = 'view' ) {
@ -278,8 +298,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* If this coupon grants free shipping or not.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return bool
*/
public function get_free_shipping( $context = 'view' ) {
@ -288,8 +309,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get product categories this coupon can apply to.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_product_categories( $context = 'view' ) {
@ -298,8 +320,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get product categories this coupon cannot not apply to.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_excluded_product_categories( $context = 'view' ) {
@ -308,8 +331,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* If this coupon should exclude items on sale.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return bool
*/
public function get_exclude_sale_items( $context = 'view' ) {
@ -318,8 +342,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get minimum spend amount.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return float
*/
public function get_minimum_amount( $context = 'view' ) {
@ -327,8 +352,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
}
/**
* Get maximum spend amount.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return float
*/
public function get_maximum_amount( $context = 'view' ) {
@ -337,8 +363,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get emails to check customer usage restrictions.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_email_restrictions( $context = 'view' ) {
@ -347,8 +374,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get records of all users who have used the current coupon.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_used_by( $context = 'view' ) {
@ -359,7 +387,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* If the filter is added through the woocommerce_get_shop_coupon_data filter, it's virtual and not in the DB.
*
* @since 3.2.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return boolean
*/
public function get_virtual( $context = 'view' ) {
@ -369,10 +397,10 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Get discount amount for a cart item.
*
* @param float $discounting_amount Amount the coupon is being applied to
* @param array|null $cart_item Cart item being discounted if applicable
* @param boolean $single True if discounting a single qty item, false if its the line
* @return float Amount this coupon has discounted
* @param float $discounting_amount Amount the coupon is being applied to.
* @param array|null $cart_item Cart item being discounted if applicable.
* @param boolean $single True if discounting a single qty item, false if its the line.
* @return float Amount this coupon has discounted.
*/
public function get_discount_amount( $discounting_amount, $cart_item = null, $single = false ) {
$discount = 0;
@ -406,21 +434,21 @@ class WC_Coupon extends WC_Legacy_Coupon {
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
|
| Functions for setting coupon data. These should not update anything in the
| database itself and should only change what is stored in the class
| object.
|
*/
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
|
| Functions for setting coupon data. These should not update anything in the
| database itself and should only change what is stored in the class
| object.
|
*/
/**
* Set coupon code.
* @since 3.0.0
* @param string $code
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param string $code Coupon code.
*/
public function set_code( $code ) {
$this->set_prop( 'code', wc_format_coupon_code( $code ) );
@ -428,9 +456,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set coupon description.
* @since 3.0.0
* @param string $description
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param string $description Description.
*/
public function set_description( $description ) {
$this->set_prop( 'description', $description );
@ -438,15 +466,15 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set discount type.
* @since 3.0.0
* @param string $discount_type
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param string $discount_type Discount type.
*/
public function set_discount_type( $discount_type ) {
if ( 'percent_product' === $discount_type ) {
$discount_type = 'percent'; // Backwards compatibility.
}
if ( ! in_array( $discount_type, array_keys( wc_get_coupon_types() ) ) ) {
if ( ! in_array( $discount_type, array_keys( wc_get_coupon_types() ), true ) ) {
$this->error( 'coupon_invalid_discount_type', __( 'Invalid discount type', 'woocommerce' ) );
}
$this->set_prop( 'discount_type', $discount_type );
@ -454,9 +482,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set amount.
* @since 3.0.0
* @param float $amount
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param float $amount Amount.
*/
public function set_amount( $amount ) {
$amount = wc_format_decimal( $amount );
@ -478,9 +506,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set expiration date.
*
* @since 3.0.0
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if there is no date.
* @throws WC_Data_Exception
*/
public function set_date_expires( $date ) {
$this->set_date_prop( 'date_expires', $date );
@ -488,9 +516,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set date_created
*
* @since 3.0.0
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if there is no date.
* @throws WC_Data_Exception
*/
public function set_date_created( $date ) {
$this->set_date_prop( 'date_created', $date );
@ -498,9 +526,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set date_modified
*
* @since 3.0.0
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if there is no date.
* @throws WC_Data_Exception
*/
public function set_date_modified( $date ) {
$this->set_date_prop( 'date_modified', $date );
@ -508,9 +536,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set how many times this coupon has been used.
* @since 3.0.0
* @param int $usage_count
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param int $usage_count Usage count.
*/
public function set_usage_count( $usage_count ) {
$this->set_prop( 'usage_count', absint( $usage_count ) );
@ -518,9 +546,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set if this coupon can only be used once.
* @since 3.0.0
* @param bool $is_individual_use
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param bool $is_individual_use If is for individual use.
*/
public function set_individual_use( $is_individual_use ) {
$this->set_prop( 'individual_use', (bool) $is_individual_use );
@ -528,9 +556,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set the product IDs this coupon can be used with.
* @since 3.0.0
* @param array $product_ids
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param array $product_ids Products IDs.
*/
public function set_product_ids( $product_ids ) {
$this->set_prop( 'product_ids', array_filter( wp_parse_id_list( (array) $product_ids ) ) );
@ -538,9 +566,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set the product IDs this coupon cannot be used with.
* @since 3.0.0
* @param array $excluded_product_ids
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param array $excluded_product_ids Exclude product IDs.
*/
public function set_excluded_product_ids( $excluded_product_ids ) {
$this->set_prop( 'excluded_product_ids', array_filter( wp_parse_id_list( (array) $excluded_product_ids ) ) );
@ -548,9 +576,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set the amount of times this coupon can be used.
* @since 3.0.0
* @param int $usage_limit
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param int $usage_limit Usage limit.
*/
public function set_usage_limit( $usage_limit ) {
$this->set_prop( 'usage_limit', absint( $usage_limit ) );
@ -558,9 +586,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set the amount of times this coupon can be used per user.
* @since 3.0.0
* @param int $usage_limit
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param int $usage_limit Usage limit.
*/
public function set_usage_limit_per_user( $usage_limit ) {
$this->set_prop( 'usage_limit_per_user', absint( $usage_limit ) );
@ -568,9 +596,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set usage limit to x number of items.
* @since 3.0.0
* @param int|null $limit_usage_to_x_items
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param int|null $limit_usage_to_x_items Limit usage to X items.
*/
public function set_limit_usage_to_x_items( $limit_usage_to_x_items ) {
$this->set_prop( 'limit_usage_to_x_items', is_null( $limit_usage_to_x_items ) ? null : absint( $limit_usage_to_x_items ) );
@ -578,9 +606,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set if this coupon enables free shipping or not.
* @since 3.0.0
* @param bool $free_shipping
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param bool $free_shipping If grant free shipping.
*/
public function set_free_shipping( $free_shipping ) {
$this->set_prop( 'free_shipping', (bool) $free_shipping );
@ -588,9 +616,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set the product category IDs this coupon can be used with.
* @since 3.0.0
* @param array $product_categories
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param array $product_categories List of product categories.
*/
public function set_product_categories( $product_categories ) {
$this->set_prop( 'product_categories', array_filter( wp_parse_id_list( (array) $product_categories ) ) );
@ -598,9 +626,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set the product category IDs this coupon cannot be used with.
* @since 3.0.0
* @param array $excluded_product_categories
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param array $excluded_product_categories List of excluded product categories.
*/
public function set_excluded_product_categories( $excluded_product_categories ) {
$this->set_prop( 'excluded_product_categories', array_filter( wp_parse_id_list( (array) $excluded_product_categories ) ) );
@ -608,9 +636,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set if this coupon should excluded sale items or not.
* @since 3.0.0
* @param bool $exclude_sale_items
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param bool $exclude_sale_items If should exclude sale items.
*/
public function set_exclude_sale_items( $exclude_sale_items ) {
$this->set_prop( 'exclude_sale_items', (bool) $exclude_sale_items );
@ -618,9 +646,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set the minimum spend amount.
* @since 3.0.0
* @param float $amount
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param float $amount Minium amount.
*/
public function set_minimum_amount( $amount ) {
$this->set_prop( 'minimum_amount', wc_format_decimal( $amount ) );
@ -628,9 +656,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set the maximum spend amount.
* @since 3.0.0
* @param float $amount
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param float $amount Maximum amount.
*/
public function set_maximum_amount( $amount ) {
$this->set_prop( 'maximum_amount', wc_format_decimal( $amount ) );
@ -638,9 +666,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set email restrictions.
* @since 3.0.0
* @param array $emails
* @throws WC_Data_Exception
*
* @since 3.0.0
* @param array $emails List of emails.
*/
public function set_email_restrictions( $emails = array() ) {
$emails = array_filter( array_map( 'sanitize_email', array_map( 'strtolower', (array) $emails ) ) );
@ -654,9 +682,9 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set which users have used this coupon.
*
* @since 3.0.0
* @param array $used_by
* @throws WC_Data_Exception
* @param array $used_by List of user IDs.
*/
public function set_used_by( $used_by ) {
$this->set_prop( 'used_by', array_filter( $used_by ) );
@ -664,6 +692,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Set coupon virtual state.
*
* @param boolean $virtual Whether it is virtual or not.
* @since 3.2.0
*/
@ -679,42 +708,43 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Developers can programmatically return coupons. This function will read those values into our WC_Coupon class.
* @since 3.0.0
* @param string $code Coupon code
* @param array $coupon Array of coupon properties
*
* @since 3.0.0
* @param string $code Coupon code.
* @param array $coupon Array of coupon properties.
*/
public function read_manual_coupon( $code, $coupon ) {
foreach ( $coupon as $key => $value ) {
switch ( $key ) {
case 'excluded_product_ids' :
case 'exclude_product_ids' :
case 'excluded_product_ids':
case 'exclude_product_ids':
if ( ! is_array( $coupon[ $key ] ) ) {
wc_doing_it_wrong( $key, $key . ' should be an array instead of a string.', '3.0' );
$coupon['excluded_product_ids'] = wc_string_to_array( $value );
}
break;
case 'exclude_product_categories' :
case 'excluded_product_categories' :
case 'exclude_product_categories':
case 'excluded_product_categories':
if ( ! is_array( $coupon[ $key ] ) ) {
wc_doing_it_wrong( $key, $key . ' should be an array instead of a string.', '3.0' );
$coupon['excluded_product_categories'] = wc_string_to_array( $value );
}
break;
case 'product_ids' :
case 'product_ids':
if ( ! is_array( $coupon[ $key ] ) ) {
wc_doing_it_wrong( $key, $key . ' should be an array instead of a string.', '3.0' );
$coupon[ $key ] = wc_string_to_array( $value );
}
break;
case 'individual_use' :
case 'free_shipping' :
case 'exclude_sale_items' :
case 'individual_use':
case 'free_shipping':
case 'exclude_sale_items':
if ( ! is_bool( $coupon[ $key ] ) ) {
wc_doing_it_wrong( $key, $key . ' should be true or false instead of yes or no.', '3.0' );
$coupon[ $key ] = wc_string_to_bool( $value );
}
break;
case 'expiry_date' :
case 'expiry_date':
$coupon['date_expires'] = $value;
break;
}
@ -728,7 +758,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Increase usage count for current coupon.
*
* @param string $used_by Either user ID or billing email
* @param string $used_by Either user ID or billing email.
*/
public function increase_usage_count( $used_by = '' ) {
if ( $this->get_id() && $this->data_store ) {
@ -745,7 +775,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Decrease usage count for current coupon.
*
* @param string $used_by Either user ID or billing email
* @param string $used_by Either user ID or billing email.
*/
public function decrease_usage_count( $used_by = '' ) {
if ( $this->get_id() && $this->get_usage_count() > 0 && $this->data_store ) {
@ -760,10 +790,10 @@ class WC_Coupon extends WC_Legacy_Coupon {
}
/*
|--------------------------------------------------------------------------
| Validation & Error Handling
|--------------------------------------------------------------------------
*/
|--------------------------------------------------------------------------
| Validation & Error Handling
|--------------------------------------------------------------------------
*/
/**
* Returns the error_message string.
@ -779,8 +809,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
* Check if a coupon is valid for the cart.
*
* @deprecated 3.2.0 In favor of WC_Discounts->is_coupon_valid.
* @throws Exception
* @return bool Validity.
* @return bool
*/
public function is_valid() {
$discounts = new WC_Discounts( WC()->cart );
@ -806,9 +835,8 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Check if a coupon is valid for a product.
*
* @param WC_Product $product
* @param array $values
*
* @param WC_Product $product Product instance.
* @param array $values Values.
* @return bool
*/
public function is_valid_for_product( $product, $values = array() ) {
@ -820,32 +848,32 @@ class WC_Coupon extends WC_Legacy_Coupon {
$product_cats = wc_get_product_cat_ids( $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id() );
$product_ids = array( $product->get_id(), $product->get_parent_id() );
// Specific products get the discount
if ( sizeof( $this->get_product_ids() ) && sizeof( array_intersect( $product_ids, $this->get_product_ids() ) ) ) {
// Specific products get the discount.
if ( count( $this->get_product_ids() ) && count( array_intersect( $product_ids, $this->get_product_ids() ) ) ) {
$valid = true;
}
// Category discounts
if ( sizeof( $this->get_product_categories() ) && sizeof( array_intersect( $product_cats, $this->get_product_categories() ) ) ) {
// Category discounts.
if ( count( $this->get_product_categories() ) && count( array_intersect( $product_cats, $this->get_product_categories() ) ) ) {
$valid = true;
}
// No product ids - all items discounted
if ( ! sizeof( $this->get_product_ids() ) && ! sizeof( $this->get_product_categories() ) ) {
// No product ids - all items discounted.
if ( ! count( $this->get_product_ids() ) && ! count( $this->get_product_categories() ) ) {
$valid = true;
}
// Specific product IDs excluded from the discount
if ( sizeof( $this->get_excluded_product_ids() ) && sizeof( array_intersect( $product_ids, $this->get_excluded_product_ids() ) ) ) {
// Specific product IDs excluded from the discount.
if ( count( $this->get_excluded_product_ids() ) && count( array_intersect( $product_ids, $this->get_excluded_product_ids() ) ) ) {
$valid = false;
}
// Specific categories excluded from the discount
if ( sizeof( $this->get_excluded_product_categories() ) && sizeof( array_intersect( $product_cats, $this->get_excluded_product_categories() ) ) ) {
// Specific categories excluded from the discount.
if ( count( $this->get_excluded_product_categories() ) && count( array_intersect( $product_cats, $this->get_excluded_product_categories() ) ) ) {
$valid = false;
}
// Sale Items excluded from discount
// Sale Items excluded from discount.
if ( $this->get_exclude_sale_items() && $product->is_on_sale() ) {
$valid = false;
}
@ -876,20 +904,20 @@ class WC_Coupon extends WC_Legacy_Coupon {
/**
* Map one of the WC_Coupon message codes to a message string.
*
* @param integer $msg_code
* @return string| Message/error string
* @param integer $msg_code Message code.
* @return string Message/error string.
*/
public function get_coupon_message( $msg_code ) {
switch ( $msg_code ) {
case self::WC_COUPON_SUCCESS :
case self::WC_COUPON_SUCCESS:
$msg = __( 'Coupon code applied successfully.', 'woocommerce' );
break;
case self::WC_COUPON_REMOVED :
break;
case self::WC_COUPON_REMOVED:
$msg = __( 'Coupon code removed successfully.', 'woocommerce' );
break;
break;
default:
$msg = '';
break;
break;
}
return apply_filters( 'woocommerce_coupon_message', $msg, $msg_code, $this );
}
@ -904,49 +932,49 @@ class WC_Coupon extends WC_Legacy_Coupon {
switch ( $err_code ) {
case self::E_WC_COUPON_INVALID_FILTERED:
$err = __( 'Coupon is not valid.', 'woocommerce' );
break;
break;
case self::E_WC_COUPON_NOT_EXIST:
/* translators: %s: coupon code */
$err = sprintf( __( 'Coupon "%s" does not exist!', 'woocommerce' ), $this->get_code() );
break;
break;
case self::E_WC_COUPON_INVALID_REMOVED:
/* translators: %s: coupon code */
$err = sprintf( __( 'Sorry, it seems the coupon "%s" is invalid - it has now been removed from your order.', 'woocommerce' ), $this->get_code() );
break;
break;
case self::E_WC_COUPON_NOT_YOURS_REMOVED:
/* translators: %s: coupon code */
$err = sprintf( __( 'Sorry, it seems the coupon "%s" is not yours - it has now been removed from your order.', 'woocommerce' ), $this->get_code() );
break;
break;
case self::E_WC_COUPON_ALREADY_APPLIED:
$err = __( 'Coupon code already applied!', 'woocommerce' );
break;
break;
case self::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY:
/* translators: %s: coupon code */
$err = sprintf( __( 'Sorry, coupon "%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce' ), $this->get_code() );
break;
break;
case self::E_WC_COUPON_USAGE_LIMIT_REACHED:
$err = __( 'Coupon usage limit has been reached.', 'woocommerce' );
break;
break;
case self::E_WC_COUPON_EXPIRED:
$err = __( 'This coupon has expired.', 'woocommerce' );
break;
break;
case self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET:
/* translators: %s: coupon minimum amount */
$err = sprintf( __( 'The minimum spend for this coupon is %s.', 'woocommerce' ), wc_price( $this->get_minimum_amount() ) );
break;
break;
case self::E_WC_COUPON_MAX_SPEND_LIMIT_MET:
/* translators: %s: coupon maximum amount */
$err = sprintf( __( 'The maximum spend for this coupon is %s.', 'woocommerce' ), wc_price( $this->get_maximum_amount() ) );
break;
break;
case self::E_WC_COUPON_NOT_APPLICABLE:
$err = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' );
break;
break;
case self::E_WC_COUPON_EXCLUDED_PRODUCTS:
// Store excluded products that are in cart in $products
// Store excluded products that are in cart in $products.
$products = array();
if ( ! WC()->cart->is_empty() ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( in_array( $cart_item['product_id'], $this->get_excluded_product_ids() ) || in_array( $cart_item['variation_id'], $this->get_excluded_product_ids() ) || in_array( $cart_item['data']->get_parent_id(), $this->get_excluded_product_ids() ) ) {
if ( in_array( intval( $cart_item['product_id'] ), $this->get_excluded_product_ids(), true ) || in_array( intval( $cart_item['variation_id'] ), $this->get_excluded_product_ids(), true ) || in_array( intval( $cart_item['data']->get_parent_id() ), $this->get_excluded_product_ids(), true ) ) {
$products[] = $cart_item['data']->get_name();
}
}
@ -956,16 +984,16 @@ class WC_Coupon extends WC_Legacy_Coupon {
$err = sprintf( __( 'Sorry, this coupon is not applicable to the products: %s.', 'woocommerce' ), implode( ', ', $products ) );
break;
case self::E_WC_COUPON_EXCLUDED_CATEGORIES:
// Store excluded categories that are in cart in $categories
// Store excluded categories that are in cart in $categories.
$categories = array();
if ( ! WC()->cart->is_empty() ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_cats = wc_get_product_cat_ids( $cart_item['product_id'] );
$intersect = array_intersect( $product_cats, $this->get_excluded_product_categories() );
if ( sizeof( $intersect = array_intersect( $product_cats, $this->get_excluded_product_categories() ) ) > 0 ) {
if ( count( $intersect ) > 0 ) {
foreach ( $intersect as $cat_id ) {
$cat = get_term( $cat_id, 'product_cat' );
$cat = get_term( $cat_id, 'product_cat' );
$categories[] = $cat->name;
}
}
@ -977,10 +1005,10 @@ class WC_Coupon extends WC_Legacy_Coupon {
break;
case self::E_WC_COUPON_NOT_VALID_SALE_ITEMS:
$err = __( 'Sorry, this coupon is not valid for sale items.', 'woocommerce' );
break;
break;
default:
$err = '';
break;
break;
}
return apply_filters( 'woocommerce_coupon_error', $err, $err_code, $this );
}
@ -990,22 +1018,22 @@ class WC_Coupon extends WC_Legacy_Coupon {
* No coupon instance will be available where a coupon does not exist,
* so this static method exists.
*
* @param int $err_code Error code
* @return string| Error string
* @param int $err_code Error code.
* @return string Error string.
*/
public static function get_generic_coupon_error( $err_code ) {
switch ( $err_code ) {
case self::E_WC_COUPON_NOT_EXIST:
$err = __( 'Coupon does not exist!', 'woocommerce' );
break;
break;
case self::E_WC_COUPON_PLEASE_ENTER:
$err = __( 'Please enter a coupon code.', 'woocommerce' );
break;
break;
default:
$err = '';
break;
break;
}
// When using this static method, there is no $this to pass to filter
// When using this static method, there is no $this to pass to filter.
return apply_filters( 'woocommerce_coupon_error', $err, $err_code, null );
}
}

View File

@ -2,18 +2,15 @@
/**
* Class for customer download logs.
*
* @version 3.3.0
* @since 3.3.0
* @package WooCommerce/Classes
* @author Automattic
* @package WooCommerce/Classes
* @version 3.3.0
* @since 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Customer_Download_Log.
* Customer download log class.
*/
class WC_Customer_Download_Log extends WC_Data {

View File

@ -1,20 +1,22 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class for customer download permissions.
*
* @version 3.0.0
* @since 3.0.0
* @package WooCommerce/Classes
* @author WooThemes
* @package WooCommerce/Classes
* @version 3.0.0
* @since 3.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Customer download class.
*/
class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* This is the name of this object type.
*
* @var string
*/
protected $object_type = 'customer_download';
@ -41,9 +43,9 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Constructor.
*
* @param int|object|array $download
* @param int|object|array $download Download ID, instance or data.
*/
public function __construct( $download = 0 ) {
public function __construct( $download = 0 ) {
parent::__construct( $download );
if ( is_numeric( $download ) && $download > 0 ) {
@ -63,7 +65,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
if ( $this->get_id() > 0 ) {
$this->data_store->read( $this );
}
}
}
/*
|--------------------------------------------------------------------------
@ -74,7 +76,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get download id.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_download_id( $context = 'view' ) {
@ -84,7 +86,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get product id.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer
*/
public function get_product_id( $context = 'view' ) {
@ -94,7 +96,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get user id.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer
*/
public function get_user_id( $context = 'view' ) {
@ -104,7 +106,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get user_email.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_user_email( $context = 'view' ) {
@ -114,7 +116,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get order_id.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer
*/
public function get_order_id( $context = 'view' ) {
@ -124,7 +126,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get order_key.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_order_key( $context = 'view' ) {
@ -134,7 +136,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get downloads_remaining.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer|string
*/
public function get_downloads_remaining( $context = 'view' ) {
@ -144,7 +146,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get access_granted.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return WC_DateTime|null Object if the date is set or null if there is no date.
*/
public function get_access_granted( $context = 'view' ) {
@ -154,7 +156,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get access_expires.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return WC_DateTime|null Object if the date is set or null if there is no date.
*/
public function get_access_expires( $context = 'view' ) {
@ -164,12 +166,12 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Get download_count.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return integer
*/
public function get_download_count( $context = 'view' ) {
// Check for count of download logs.
$data_store = WC_Data_Store::load( 'customer-download-log' );
$data_store = WC_Data_Store::load( 'customer-download-log' );
$download_log_ids = $data_store->get_download_logs_for_permission( $this->get_id() );
$download_log_count = 0;
@ -195,7 +197,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Set download id.
*
* @param string $value
* @param string $value Download ID.
*/
public function set_download_id( $value ) {
$this->set_prop( 'download_id', $value );
@ -203,7 +205,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Set product id.
*
* @param int $value
* @param int $value Product ID.
*/
public function set_product_id( $value ) {
$this->set_prop( 'product_id', absint( $value ) );
@ -212,7 +214,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Set user id.
*
* @param int $value
* @param int $value User ID.
*/
public function set_user_id( $value ) {
$this->set_prop( 'user_id', absint( $value ) );
@ -221,7 +223,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Set user_email.
*
* @param int $value
* @param int $value User email.
*/
public function set_user_email( $value ) {
$this->set_prop( 'user_email', sanitize_email( $value ) );
@ -230,7 +232,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Set order_id.
*
* @param int $value
* @param int $value Order ID.
*/
public function set_order_id( $value ) {
$this->set_prop( 'order_id', absint( $value ) );
@ -239,7 +241,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Set order_key.
*
* @param string $value
* @param string $value Order key.
*/
public function set_order_key( $value ) {
$this->set_prop( 'order_key', $value );
@ -248,7 +250,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Set downloads_remaining.
*
* @param integer|string $value
* @param integer|string $value Amount of downloads remaining.
*/
public function set_downloads_remaining( $value ) {
$this->set_prop( 'downloads_remaining', '' === $value ? '' : absint( $value ) );
@ -275,7 +277,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
/**
* Set download_count.
*
* @param int $value
* @param int $value Download count.
*/
public function set_download_count( $value ) {
$this->set_prop( 'download_count', absint( $value ) );
@ -285,8 +287,9 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
* Track a download on this permission.
*
* @since 3.3.0
* @param int user_id Id of the user performing the download
* @param string user_ip_address IP Address of the user performing the download
* @throws Exception When permission ID is invalid.
* @param int $user_id Id of the user performing the download.
* @param string $user_ip_address IP Address of the user performing the download.
*/
public function track_download( $user_id = null, $user_ip_address = null ) {
global $wpdb;
@ -300,15 +303,16 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
// Use SQL to avoid possible issues with downloads in quick succession.
// If downloads_remaining is blank, leave it blank (unlimited).
// Also, ensure downloads_remaining doesn't drop below zero.
$query = $wpdb->prepare( "
$query = $wpdb->prepare(
"
UPDATE {$wpdb->prefix}woocommerce_downloadable_product_permissions
SET download_count = download_count + 1,
downloads_remaining = IF( downloads_remaining = '', '', GREATEST( 0, downloads_remaining - 1 ) )
WHERE permission_id = %d",
$this->get_id()
);
$wpdb->query( $query );
$wpdb->query( $query ); // WPCS: unprepared SQL ok.
// Re-read this download from the data store to pull updated counts.
$this->data_store->read( $this );
@ -336,6 +340,7 @@ WHERE permission_id = %d",
/**
* Save data to the database.
*
* @since 3.0.0
* @return int Item ID
*/
@ -360,8 +365,9 @@ WHERE permission_id = %d",
*/
/**
* offsetGet
* @param string $offset
* OffsetGet.
*
* @param string $offset Offset.
* @return mixed
*/
public function offsetGet( $offset ) {
@ -371,9 +377,10 @@ WHERE permission_id = %d",
}
/**
* offsetSet
* @param string $offset
* @param mixed $value
* OffsetSet.
*
* @param string $offset Offset.
* @param mixed $value Value.
*/
public function offsetSet( $offset, $value ) {
if ( is_callable( array( $this, "set_$offset" ) ) ) {
@ -382,8 +389,9 @@ WHERE permission_id = %d",
}
/**
* offsetUnset
* @param string $offset
* OffsetUnset
*
* @param string $offset Offset.
*/
public function offsetUnset( $offset ) {
if ( is_callable( array( $this, "set_$offset" ) ) ) {
@ -392,12 +400,13 @@ WHERE permission_id = %d",
}
/**
* offsetExists
* @param string $offset
* OffsetExists.
*
* @param string $offset Offset.
* @return bool
*/
public function offsetExists( $offset ) {
return in_array( $offset, array_keys( $this->data ) );
return in_array( $offset, array_keys( $this->data ), true );
}
/**
@ -407,7 +416,7 @@ WHERE permission_id = %d",
* @return bool
*/
public function __isset( $key ) {
return in_array( $key, array_keys( $this->data ) );
return in_array( $key, array_keys( $this->data ), true );
}
/**

View File

@ -1,18 +1,17 @@
<?php
include_once( 'legacy/class-wc-legacy-customer.php' );
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* The WooCommerce customer class handles storage of the current customer's data, such as location.
*
* @class WC_Customer
* @version 3.0.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @package WooCommerce/Classes
* @version 3.0.0
*/
defined( 'ABSPATH' ) || exit;
require_once dirname( __FILE__ ) . '/legacy/class-wc-legacy-customer.php';
/**
* Customer class.
*/
class WC_Customer extends WC_Legacy_Customer {
@ -31,28 +30,28 @@ class WC_Customer extends WC_Legacy_Customer {
'role' => 'customer',
'username' => '',
'billing' => array(
'first_name' => '',
'last_name' => '',
'company' => '',
'address_1' => '',
'address_2' => '',
'city' => '',
'state' => '',
'postcode' => '',
'country' => '',
'email' => '',
'phone' => '',
'first_name' => '',
'last_name' => '',
'company' => '',
'address_1' => '',
'address_2' => '',
'city' => '',
'state' => '',
'postcode' => '',
'country' => '',
'email' => '',
'phone' => '',
),
'shipping' => array(
'first_name' => '',
'last_name' => '',
'company' => '',
'address_1' => '',
'address_2' => '',
'city' => '',
'state' => '',
'postcode' => '',
'country' => '',
'first_name' => '',
'last_name' => '',
'company' => '',
'address_1' => '',
'address_2' => '',
'city' => '',
'state' => '',
'postcode' => '',
'country' => '',
),
'is_paying_customer' => false,
);
@ -84,9 +83,9 @@ class WC_Customer extends WC_Legacy_Customer {
* If $customer is 'new', you can build a new WC_Customer object. If it's empty, some
* data will be pulled from the session for the current user/customer.
*
* @param WC_Customer|int $data Customer ID or data.
* @param bool $is_session True if this is the customer session
* @throws Exception if customer cannot be read/found and $data is set.
* @param WC_Customer|int $data Customer ID or data.
* @param bool $is_session True if this is the customer session.
* @throws Exception If customer cannot be read/found and $data is set.
*/
public function __construct( $data = 0, $is_session = false ) {
parent::__construct( $data );
@ -137,7 +136,12 @@ class WC_Customer extends WC_Legacy_Customer {
*/
public function delete_and_reassign( $reassign = null ) {
if ( $this->data_store ) {
$this->data_store->delete( $this, array( 'force_delete' => true, 'reassign' => $reassign ) );
$this->data_store->delete(
$this, array(
'force_delete' => true,
'reassign' => $reassign,
)
);
$this->set_id( 0 );
return true;
}
@ -175,13 +179,14 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get taxable address.
*
* @return array
*/
public function get_taxable_address() {
$tax_based_on = get_option( 'woocommerce_tax_based_on' );
// Check shipping method at this point to see if we need special handling
if ( true === apply_filters( 'woocommerce_apply_base_tax_for_local_pickup', true ) && sizeof( array_intersect( wc_get_chosen_shipping_method_ids(), apply_filters( 'woocommerce_local_pickup_methods', array( 'legacy_local_pickup', 'local_pickup' ) ) ) ) > 0 ) {
// Check shipping method at this point to see if we need special handling.
if ( true === apply_filters( 'woocommerce_apply_base_tax_for_local_pickup', true ) && count( array_intersect( wc_get_chosen_shipping_method_ids(), apply_filters( 'woocommerce_local_pickup_methods', array( 'legacy_local_pickup', 'local_pickup' ) ) ) ) > 0 ) {
$tax_based_on = 'base';
}
@ -267,7 +272,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set if customer has tax exemption.
*
* @param bool $is_vat_exempt
* @param bool $is_vat_exempt If is vat exempt.
*/
public function set_is_vat_exempt( $is_vat_exempt ) {
$this->is_vat_exempt = wc_string_to_bool( $is_vat_exempt );
@ -276,7 +281,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Calculated shipping?
*
* @param boolean $calculated
* @param bool $calculated If shipping is calculated.
*/
public function set_calculated_shipping( $calculated = true ) {
$this->calculated_shipping = wc_string_to_bool( $calculated );
@ -286,8 +291,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Set customer's password.
*
* @since 3.0.0
* @param string $password
* @throws WC_Data_Exception
* @param string $password Password.
*/
public function set_password( $password ) {
$this->password = wc_clean( $password );
@ -296,7 +300,6 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Gets the customers last order.
*
* @param WC_Customer
* @return WC_Order|false
*/
public function get_last_order() {
@ -306,7 +309,6 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Return the number of orders this customer has.
*
* @param WC_Customer
* @return integer
*/
public function get_order_count() {
@ -316,7 +318,6 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Return how much money this customer has spent.
*
* @param WC_Customer
* @return float
*/
public function get_total_spent() {
@ -324,16 +325,16 @@ class WC_Customer extends WC_Legacy_Customer {
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
/**
* Return the customer's username.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_username( $context = 'view' ) {
@ -344,7 +345,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Return the customer's email.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_email( $context = 'view' ) {
@ -355,7 +356,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Return customer's first name.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_first_name( $context = 'view' ) {
@ -366,7 +367,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Return customer's last name.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_last_name( $context = 'view' ) {
@ -377,7 +378,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Return customer's display name.
*
* @since 3.1.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_display_name( $context = 'view' ) {
@ -388,7 +389,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Return customer's user role.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_role( $context = 'view' ) {
@ -399,7 +400,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Return the date this customer was created.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return WC_DateTime|null object if the date is set or null if there is no date.
*/
public function get_date_created( $context = 'view' ) {
@ -410,7 +411,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Return the date this customer was last updated.
*
* @since 3.0.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return WC_DateTime|null object if the date is set or null if there is no date.
*/
public function get_date_modified( $context = 'view' ) {
@ -423,7 +424,7 @@ class WC_Customer extends WC_Legacy_Customer {
* @since 3.0.0
* @param string $prop Name of prop to get.
* @param string $address billing or shipping.
* @param string $context What the value is for. Valid values are view and edit.
* @param string $context What the value is for. Valid values are 'view' and 'edit'. What the value is for. Valid values are view and edit.
* @return mixed
*/
protected function get_address_prop( $prop, $address = 'billing', $context = 'view' ) {
@ -443,7 +444,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Get billing.
*
* @since 3.2.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_billing( $context = 'view' ) {
@ -453,7 +454,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_first_name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_first_name( $context = 'view' ) {
@ -463,7 +464,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_last_name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_last_name( $context = 'view' ) {
@ -473,7 +474,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_company.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_company( $context = 'view' ) {
@ -483,7 +484,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_address_1.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_address( $context = 'view' ) {
@ -493,7 +494,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_address_1.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_address_1( $context = 'view' ) {
@ -503,7 +504,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_address_2.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string $value
*/
public function get_billing_address_2( $context = 'view' ) {
@ -513,7 +514,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_city.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string $value
*/
public function get_billing_city( $context = 'view' ) {
@ -523,7 +524,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_state.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_state( $context = 'view' ) {
@ -533,7 +534,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_postcode.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_postcode( $context = 'view' ) {
@ -543,7 +544,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_country.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_country( $context = 'view' ) {
@ -553,7 +554,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_email.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_email( $context = 'view' ) {
@ -563,7 +564,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get billing_phone.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_billing_phone( $context = 'view' ) {
@ -574,7 +575,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Get shipping.
*
* @since 3.2.0
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_shipping( $context = 'view' ) {
@ -584,7 +585,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_first_name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_first_name( $context = 'view' ) {
@ -594,17 +595,17 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_last_name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_last_name( $context = 'view' ) {
return $this->get_address_prop( 'last_name', 'shipping', $context );
return $this->get_address_prop( 'last_name', 'shipping', $context );
}
/**
* Get shipping_company.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_company( $context = 'view' ) {
@ -614,7 +615,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_address_1.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_address( $context = 'view' ) {
@ -624,7 +625,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_address_1.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_address_1( $context = 'view' ) {
@ -634,7 +635,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_address_2.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_address_2( $context = 'view' ) {
@ -644,7 +645,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_city.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_city( $context = 'view' ) {
@ -654,7 +655,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_state.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_state( $context = 'view' ) {
@ -664,7 +665,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_postcode.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_postcode( $context = 'view' ) {
@ -674,7 +675,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Get shipping_country.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_country( $context = 'view' ) {
@ -684,11 +685,11 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Is the user a paying customer?
*
* @since 3.0.0
* @param string $context
* @since 3.0.0
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return bool
*/
function get_is_paying_customer( $context = 'view' ) {
public function get_is_paying_customer( $context = 'view' ) {
return $this->get_prop( 'is_paying_customer', $context );
}
@ -702,8 +703,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Set customer's username.
*
* @since 3.0.0
* @param string $username
* @throws WC_Data_Exception
* @param string $username Username.
*/
public function set_username( $username ) {
$this->set_prop( 'username', $username );
@ -713,8 +713,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Set customer's email.
*
* @since 3.0.0
* @param string $value
* @throws WC_Data_Exception
* @param string $value Email.
*/
public function set_email( $value ) {
if ( $value && ! is_email( $value ) ) {
@ -727,8 +726,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Set customer's first name.
*
* @since 3.0.0
* @param string $first_name
* @throws WC_Data_Exception
* @param string $first_name First name.
*/
public function set_first_name( $first_name ) {
$this->set_prop( 'first_name', $first_name );
@ -738,8 +736,7 @@ class WC_Customer extends WC_Legacy_Customer {
* Set customer's last name.
*
* @since 3.0.0
* @param string $last_name
* @throws WC_Data_Exception
* @param string $last_name Last name.
*/
public function set_last_name( $last_name ) {
$this->set_prop( 'last_name', $last_name );
@ -753,20 +750,19 @@ class WC_Customer extends WC_Legacy_Customer {
*/
public function set_display_name( $display_name ) {
/* translators: 1: first name 2: last name */
$this->set_prop( 'display_name', is_email( $display_name ) ? sprintf( __( '%1$s %2$s', 'display name', 'woocommerce' ), $this->get_first_name(), $this->get_last_name() ) : $display_name );
$this->set_prop( 'display_name', is_email( $display_name ) ? sprintf( _x( '%1$s %2$s', 'display name', 'woocommerce' ), $this->get_first_name(), $this->get_last_name() ) : $display_name );
}
/**
* Set customer's user role(s).
*
* @since 3.0.0
* @param mixed $role
* @throws WC_Data_Exception
* @param mixed $role User role.
*/
public function set_role( $role ) {
global $wp_roles;
if ( $role && ! empty( $wp_roles->roles ) && ! in_array( $role, array_keys( $wp_roles->roles ) ) ) {
if ( $role && ! empty( $wp_roles->roles ) && ! in_array( $role, array_keys( $wp_roles->roles ), true ) ) {
$this->error( 'customer_invalid_role', __( 'Invalid role', 'woocommerce' ) );
}
$this->set_prop( 'role', $role );
@ -777,7 +773,6 @@ class WC_Customer extends WC_Legacy_Customer {
*
* @since 3.0.0
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
* @throws WC_Data_Exception
*/
public function set_date_created( $date = null ) {
$this->set_date_prop( 'date_created', $date );
@ -788,7 +783,6 @@ class WC_Customer extends WC_Legacy_Customer {
*
* @since 3.0.0
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
* @throws WC_Data_Exception
*/
public function set_date_modified( $date = null ) {
$this->set_date_prop( 'date_modified', $date );
@ -798,7 +792,6 @@ class WC_Customer extends WC_Legacy_Customer {
* Set customer address to match shop base address.
*
* @since 3.0.0
* @throws WC_Data_Exception
*/
public function set_billing_address_to_base() {
$base = wc_get_customer_default_location();
@ -809,7 +802,6 @@ class WC_Customer extends WC_Legacy_Customer {
* Set customer shipping address to base address.
*
* @since 3.0.0
* @throws WC_Data_Exception
*/
public function set_shipping_address_to_base() {
$base = wc_get_customer_default_location();
@ -819,11 +811,10 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Sets all address info at once.
*
* @param string $country
* @param string $state
* @param string $postcode
* @param string $city
* @throws WC_Data_Exception
* @param string $country Country.
* @param string $state State.
* @param string $postcode Postcode.
* @param string $city City.
*/
public function set_billing_location( $country, $state = '', $postcode = '', $city = '' ) {
$billing = $this->get_prop( 'billing', 'edit' );
@ -837,11 +828,10 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Sets all shipping info at once.
*
* @param string $country
* @param string $state
* @param string $postcode
* @param string $city
* @throws WC_Data_Exception
* @param string $country Country.
* @param string $state State.
* @param string $postcode Postcode.
* @param string $city City.
*/
public function set_shipping_location( $country, $state = '', $postcode = '', $city = '' ) {
$shipping = $this->get_prop( 'shipping', 'edit' );
@ -856,9 +846,9 @@ class WC_Customer extends WC_Legacy_Customer {
* Sets a prop for a setter method.
*
* @since 3.0.0
* @param string $prop Name of prop to set.
* @param string $prop Name of prop to set.
* @param string $address Name of address to set. billing or shipping.
* @param mixed $value Value of the prop.
* @param mixed $value Value of the prop.
*/
protected function set_address_prop( $prop, $address = 'billing', $value ) {
if ( array_key_exists( $prop, $this->data[ $address ] ) ) {
@ -875,8 +865,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_first_name.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing first name.
*/
public function set_billing_first_name( $value ) {
$this->set_address_prop( 'first_name', 'billing', $value );
@ -885,8 +874,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_last_name.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing last name.
*/
public function set_billing_last_name( $value ) {
$this->set_address_prop( 'last_name', 'billing', $value );
@ -895,8 +883,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_company.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing company.
*/
public function set_billing_company( $value ) {
$this->set_address_prop( 'company', 'billing', $value );
@ -905,8 +892,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_address_1.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing address line 1.
*/
public function set_billing_address( $value ) {
$this->set_billing_address_1( $value );
@ -915,8 +901,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_address_1.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing address line 1.
*/
public function set_billing_address_1( $value ) {
$this->set_address_prop( 'address_1', 'billing', $value );
@ -925,8 +910,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_address_2.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing address line 2.
*/
public function set_billing_address_2( $value ) {
$this->set_address_prop( 'address_2', 'billing', $value );
@ -935,8 +919,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_city.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing city.
*/
public function set_billing_city( $value ) {
$this->set_address_prop( 'city', 'billing', $value );
@ -945,8 +928,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_state.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing state.
*/
public function set_billing_state( $value ) {
$this->set_address_prop( 'state', 'billing', $value );
@ -955,8 +937,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_postcode.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing postcode.
*/
public function set_billing_postcode( $value ) {
$this->set_address_prop( 'postcode', 'billing', $value );
@ -965,8 +946,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_country.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing country.
*/
public function set_billing_country( $value ) {
$this->set_address_prop( 'country', 'billing', $value );
@ -975,8 +955,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_email.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing email.
*/
public function set_billing_email( $value ) {
if ( $value && ! is_email( $value ) ) {
@ -988,8 +967,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set billing_phone.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Billing phone.
*/
public function set_billing_phone( $value ) {
$this->set_address_prop( 'phone', 'billing', $value );
@ -998,8 +976,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_first_name.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping first name.
*/
public function set_shipping_first_name( $value ) {
$this->set_address_prop( 'first_name', 'shipping', $value );
@ -1008,8 +985,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_last_name.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping last name.
*/
public function set_shipping_last_name( $value ) {
$this->set_address_prop( 'last_name', 'shipping', $value );
@ -1018,8 +994,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_company.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping company.
*/
public function set_shipping_company( $value ) {
$this->set_address_prop( 'company', 'shipping', $value );
@ -1028,8 +1003,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_address_1.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping address line 1.
*/
public function set_shipping_address( $value ) {
$this->set_shipping_address_1( $value );
@ -1038,8 +1012,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_address_1.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping address line 1.
*/
public function set_shipping_address_1( $value ) {
$this->set_address_prop( 'address_1', 'shipping', $value );
@ -1048,8 +1021,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_address_2.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping address line 2.
*/
public function set_shipping_address_2( $value ) {
$this->set_address_prop( 'address_2', 'shipping', $value );
@ -1058,8 +1030,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_city.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping city.
*/
public function set_shipping_city( $value ) {
$this->set_address_prop( 'city', 'shipping', $value );
@ -1068,8 +1039,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_state.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping state.
*/
public function set_shipping_state( $value ) {
$this->set_address_prop( 'state', 'shipping', $value );
@ -1078,8 +1048,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_postcode.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping postcode.
*/
public function set_shipping_postcode( $value ) {
$this->set_address_prop( 'postcode', 'shipping', $value );
@ -1088,8 +1057,7 @@ class WC_Customer extends WC_Legacy_Customer {
/**
* Set shipping_country.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Shipping country.
*/
public function set_shipping_country( $value ) {
$this->set_address_prop( 'country', 'shipping', $value );
@ -1099,10 +1067,9 @@ class WC_Customer extends WC_Legacy_Customer {
* Set if the user a paying customer.
*
* @since 3.0.0
* @param bool $is_paying_customer
* @throws WC_Data_Exception
* @param bool $is_paying_customer If is a paying customer.
*/
function set_is_paying_customer( $is_paying_customer ) {
public function set_is_paying_customer( $is_paying_customer ) {
$this->set_prop( 'is_paying_customer', (bool) $is_paying_customer );
}
}

View File

@ -4,18 +4,14 @@
*
* Extends Exception to provide additional data.
*
* @author WooThemes
* @category Core
* @package WooCommerce
* @since 3.0
* @package WooCommerce\Classes
* @since 3.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Data_Exception class.
* Data exception class.
*/
class WC_Data_Exception extends Exception {

View File

@ -1,20 +1,23 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC Data Store.
*
* @since 3.0.0
* @version 3.0.0
* @category Class
* @author WooThemes
* @package WooCommerce\Classes
* @since 3.0.0
* @version 3.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Data store class.
*/
class WC_Data_Store {
/**
* Contains an instance of the data store class that we are working with.
*
* @var WC_Data_Store
*/
private $instance = null;
@ -26,6 +29,8 @@ class WC_Data_Store {
* that type will be used first when available, if a store is requested like
* this and doesn't exist, then the store would fall back to 'product'.
* Ran through `woocommerce_data_stores`.
*
* @var array
*/
private $stores = array(
'coupon' => 'WC_Coupon_Data_Store_CPT',
@ -52,11 +57,14 @@ class WC_Data_Store {
/**
* Contains the name of the current data store's class name.
*
* @var string
*/
private $current_class_name = '';
/**
* The object type this store works with.
*
* @var string
*/
private $object_type = '';
@ -66,18 +74,17 @@ class WC_Data_Store {
* Tells WC_Data_Store which object (coupon, product, order, etc)
* store we want to work with.
*
* @throws Exception When validation fails.
* @param string $object_type Name of object.
*
* @throws Exception
*/
public function __construct( $object_type ) {
$this->object_type = $object_type;
$this->stores = apply_filters( 'woocommerce_data_stores', $this->stores );
$this->stores = apply_filters( 'woocommerce_data_stores', $this->stores );
// If this object type can't be found, check to see if we can load one
// level up (so if product-type isn't found, we try product).
if ( ! array_key_exists( $object_type, $this->stores ) ) {
$pieces = explode( '-', $object_type );
$pieces = explode( '-', $object_type );
$object_type = $pieces[0];
}
@ -88,13 +95,13 @@ class WC_Data_Store {
throw new Exception( __( 'Invalid data store.', 'woocommerce' ) );
}
$this->current_class_name = get_class( $store );
$this->instance = $store;
$this->instance = $store;
} else {
if ( ! class_exists( $store ) ) {
throw new Exception( __( 'Invalid data store.', 'woocommerce' ) );
}
$this->current_class_name = $store;
$this->instance = new $store;
$this->instance = new $store();
}
} else {
throw new Exception( __( 'Invalid data store.', 'woocommerce' ) );
@ -143,7 +150,7 @@ class WC_Data_Store {
* Reads an object from the data store.
*
* @since 3.0.0
* @param WC_Data
* @param WC_Data $data WooCommerce data instance.
*/
public function read( &$data ) {
$this->instance->read( $data );
@ -153,7 +160,7 @@ class WC_Data_Store {
* Create an object in the data store.
*
* @since 3.0.0
* @param WC_Data
* @param WC_Data $data WooCommerce data instance.
*/
public function create( &$data ) {
$this->instance->create( $data );
@ -163,7 +170,7 @@ class WC_Data_Store {
* Update an object in the data store.
*
* @since 3.0.0
* @param WC_Data
* @param WC_Data $data WooCommerce data instance.
*/
public function update( &$data ) {
$this->instance->update( $data );
@ -173,8 +180,8 @@ class WC_Data_Store {
* Delete an object from the data store.
*
* @since 3.0.0
* @param WC_Data
* @param array $args Array of args to pass to the delete method.
* @param WC_Data $data WooCommerce data instance.
* @param array $args Array of args to pass to the delete method.
*/
public function delete( &$data, $args = array() ) {
$this->instance->delete( $data, $args );
@ -186,10 +193,8 @@ class WC_Data_Store {
* through to the instance if that function exists.
*
* @since 3.0.0
*
* @param $method
* @param $parameters
*
* @param string $method Method.
* @param mixed $parameters Parameters.
* @return mixed
*/
public function __call( $method, $parameters ) {
@ -198,5 +203,4 @@ class WC_Data_Store {
return call_user_func_array( array( $this->instance, $method ), array_merge( array( &$object ), $parameters ) );
}
}
}

View File

@ -1,18 +1,16 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC Wrapper for PHP DateTime which adds support for gmt/utc offset when a
* timezone is absent.
* timezone is absent
*
* @class WC_DateTime
* @since 3.0.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @since 3.0.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* Datetime class.
*/
class WC_DateTime extends DateTime {
@ -37,7 +35,7 @@ class WC_DateTime extends DateTime {
/**
* Set UTC offset - this is a fixed offset instead of a timezone.
*
* @param int $offset
* @param int $offset Offset.
*/
public function set_utc_offset( $offset ) {
$this->utc_offset = intval( $offset );
@ -57,8 +55,7 @@ class WC_DateTime extends DateTime {
/**
* Set timezone.
*
* @param DateTimeZone $timezone
*
* @param DateTimeZone $timezone DateTimeZone instance.
* @return DateTime
*/
public function setTimezone( $timezone ) {
@ -90,7 +87,7 @@ class WC_DateTime extends DateTime {
* Format a date based on the offset timestamp.
*
* @since 3.0.0
* @param string $format
* @param string $format Date format.
* @return string
*/
public function date( $format ) {
@ -101,7 +98,7 @@ class WC_DateTime extends DateTime {
* Return a localised date based on offset timestamp. Wrapper for date_i18n function.
*
* @since 3.0.0
* @param string $format
* @param string $format Date format.
* @return string
*/
public function date_i18n( $format = 'Y-m-d' ) {

View File

@ -7,9 +7,7 @@
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* Handles deprecation notices and triggering of legacy action hooks.

View File

@ -7,9 +7,7 @@
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* Handles deprecation notices and triggering of legacy filter hooks

View File

@ -509,7 +509,7 @@ class WC_Discounts {
$this->discounts[ $coupon->get_code() ][ $item->key ] += $discount;
}
// Allow post-processing for custom coupon types (e.g. calculating discrepancy, etc)
// Allow post-processing for custom coupon types (e.g. calculating discrepancy, etc).
$this->discounts[ $coupon->get_code() ] = apply_filters( 'woocommerce_coupon_custom_discounts_array', $this->discounts[ $coupon->get_code() ], $coupon );
return array_sum( $this->discounts[ $coupon->get_code() ] );

View File

@ -1,11 +1,9 @@
<?php
/**
* WooCommerce Product Embed.
* WooCommerce product embed
*
* @version 2.4.11
* @package WooCommerce/Classes/Embed
* @category Class
* @author WooThemes
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -14,10 +12,6 @@ if ( ! defined( 'ABSPATH' ) ) {
/**
* Embed Class which handles any WooCommerce Products that are embedded on this site or another site.
*
* @class WC_Embed
* @version 2.4.11
* @author WooThemes
*/
class WC_Embed {
@ -80,7 +74,7 @@ class WC_Embed {
// Make sure we're only affecting embedded products.
if ( self::is_embedded_product() ) {
echo '<p><span class="wc-embed-price">' . $_product->get_price_html() . '</span></p>';
echo '<p><span class="wc-embed-price">' . $_product->get_price_html() . '</span></p>'; // WPCS: XSS ok.
if ( ! empty( $post->post_excerpt ) ) {
ob_start();
@ -121,12 +115,18 @@ class WC_Embed {
*/
public static function get_ratings() {
// Make sure we're only affecting embedded products.
if ( self::is_embedded_product() && ( $_product = wc_get_product( get_the_ID() ) ) && $_product->get_average_rating() > 0 ) {
if ( ! self::is_embedded_product() ) {
return;
}
$_product = wc_get_product( get_the_ID() );
if ( $_product && $_product->get_average_rating() > 0 ) {
?>
<div class="wc-embed-rating">
<?php
/* translators: %s: average rating */
printf(
/* translators: %s: average rating */
esc_html__( 'Rated %s out of 5', 'woocommerce' ),
esc_html( $_product->get_average_rating() )
);

View File

@ -71,12 +71,18 @@ class WC_Form_Handler {
return;
}
if ( empty( $_POST['action'] ) || 'edit_address' !== $_POST['action'] || empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-edit_address' ) ) {
if ( empty( $_POST['action'] ) || 'edit_address' !== $_POST['action'] ) {
return;
}
wc_nocache_headers();
$nonce_value = wc_get_var( $_REQUEST['woocommerce-edit-address-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! wp_verify_nonce( $nonce_value, 'woocommerce-edit_address' ) ) {
return;
}
$user_id = get_current_user_id();
if ( $user_id <= 0 ) {
@ -184,12 +190,18 @@ class WC_Form_Handler {
return;
}
if ( empty( $_POST['action'] ) || 'save_account_details' !== $_POST['action'] || empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'save_account_details' ) ) {
if ( empty( $_POST['action'] ) || 'save_account_details' !== $_POST['action'] ) {
return;
}
wc_nocache_headers();
$nonce_value = wc_get_var( $_REQUEST['save-account-details-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! wp_verify_nonce( $nonce_value, 'save_account_details' ) ) {
return;
}
$user_id = get_current_user_id();
if ( $user_id <= 0 ) {
@ -334,8 +346,15 @@ class WC_Form_Handler {
public static function pay_action() {
global $wp;
if ( isset( $_POST['woocommerce_pay'] ) && isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-pay' ) ) {
if ( isset( $_POST['woocommerce_pay'] ) ) {
wc_nocache_headers();
$nonce_value = wc_get_var( $_REQUEST['woocommerce-pay-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! wp_verify_nonce( $nonce_value, 'woocommerce-pay' ) ) {
return;
}
ob_start();
// Pay for existing order
@ -413,8 +432,15 @@ class WC_Form_Handler {
* Process the add payment method form.
*/
public static function add_payment_method_action() {
if ( isset( $_POST['woocommerce_add_payment_method'], $_POST['payment_method'], $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-add-payment-method' ) ) {
if ( isset( $_POST['woocommerce_add_payment_method'], $_POST['payment_method'] ) ) {
wc_nocache_headers();
$nonce_value = wc_get_var( $_REQUEST['woocommerce-add-payment-method-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! wp_verify_nonce( $nonce_value, 'woocommerce-add-payment-method' ) ) {
return;
}
ob_start();
$payment_method_id = wc_clean( wp_unslash( $_POST['payment_method'] ) );
@ -512,16 +538,19 @@ class WC_Form_Handler {
wc_nocache_headers();
$nonce_value = wc_get_var( $_REQUEST['woocommerce-cart-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! empty( $_POST['apply_coupon'] ) && ! empty( $_POST['coupon_code'] ) ) {
WC()->cart->add_discount( sanitize_text_field( $_POST['coupon_code'] ) );
WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
} elseif ( isset( $_GET['remove_coupon'] ) ) {
WC()->cart->remove_coupon( wc_clean( $_GET['remove_coupon'] ) );
WC()->cart->remove_coupon( wc_clean( wp_unslash( $_GET['remove_coupon'] ) ) );
} elseif ( ! empty( $_GET['remove_item'] ) && wp_verify_nonce( wc_get_var( $_REQUEST['_wpnonce'] ), 'woocommerce-cart' ) ) {
$cart_item_key = sanitize_text_field( $_GET['remove_item'] );
} elseif ( ! empty( $_GET['remove_item'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-cart' ) ) {
$cart_item_key = sanitize_text_field( wp_unslash( $_GET['remove_item'] ) );
$cart_item = WC()->cart->get_cart_item( $cart_item_key );
if ( $cart_item = WC()->cart->get_cart_item( $cart_item_key ) ) {
if ( $cart_item ) {
WC()->cart->remove_cart_item( $cart_item_key );
$product = wc_get_product( $cart_item['product_id'] );
@ -530,9 +559,11 @@ class WC_Form_Handler {
// Don't show undo link if removed item is out of stock.
if ( $product && $product->is_in_stock() && $product->has_enough_stock( $cart_item['quantity'] ) ) {
/* Translators: %s Product title. */
$removed_notice = sprintf( __( '%s removed.', 'woocommerce' ), $item_removed_title );
$removed_notice .= ' <a href="' . esc_url( wc_get_cart_undo_url( $cart_item_key ) ) . '" class="restore-item">' . __( 'Undo?', 'woocommerce' ) . '</a>';
} else {
/* Translators: %s Product title. */
$removed_notice = sprintf( __( '%s removed.', 'woocommerce' ), $item_removed_title );
}
@ -543,10 +574,10 @@ class WC_Form_Handler {
wp_safe_redirect( $referer );
exit;
} elseif ( ! empty( $_GET['undo_item'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'woocommerce-cart' ) ) {
} elseif ( ! empty( $_GET['undo_item'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-cart' ) ) {
// Undo Cart Item
$cart_item_key = sanitize_text_field( $_GET['undo_item'] );
// Undo Cart Item.
$cart_item_key = sanitize_text_field( wp_unslash( $_GET['undo_item'] ) );
WC()->cart->restore_cart_item( $cart_item_key );
@ -556,34 +587,35 @@ class WC_Form_Handler {
}
// Update Cart - checks apply_coupon too because they are in the same form
if ( ( ! empty( $_POST['apply_coupon'] ) || ! empty( $_POST['update_cart'] ) || ! empty( $_POST['proceed'] ) ) && wp_verify_nonce( wc_get_var( $_POST['_wpnonce'] ), 'woocommerce-cart' ) ) {
// Update Cart - checks apply_coupon too because they are in the same form.
if ( ( ! empty( $_POST['apply_coupon'] ) || ! empty( $_POST['update_cart'] ) || ! empty( $_POST['proceed'] ) ) && wp_verify_nonce( $nonce_value, 'woocommerce-cart' ) ) {
$cart_updated = false;
$cart_totals = isset( $_POST['cart'] ) ? $_POST['cart'] : '';
$cart_totals = isset( $_POST['cart'] ) ? wp_unslash( $_POST['cart'] ) : ''; // PHPCS: input var ok, CSRF ok, sanitization ok.
if ( ! WC()->cart->is_empty() && is_array( $cart_totals ) ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
// Skip product if no updated quantity was posted
// Skip product if no updated quantity was posted.
if ( ! isset( $cart_totals[ $cart_item_key ] ) || ! isset( $cart_totals[ $cart_item_key ]['qty'] ) ) {
continue;
}
// Sanitize
$quantity = apply_filters( 'woocommerce_stock_amount_cart_item', wc_stock_amount( preg_replace( "/[^0-9\.]/", '', $cart_totals[ $cart_item_key ]['qty'] ) ), $cart_item_key );
// Sanitize.
$quantity = apply_filters( 'woocommerce_stock_amount_cart_item', wc_stock_amount( preg_replace( '/[^0-9\.]/', '', $cart_totals[ $cart_item_key ]['qty'] ) ), $cart_item_key );
if ( '' === $quantity || $quantity === $values['quantity'] ) {
continue;
}
// Update cart validation
$passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $values, $quantity );
// Update cart validation.
$passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $values, $quantity );
// is_sold_individually
// is_sold_individually.
if ( $_product->is_sold_individually() && $quantity > 1 ) {
/* Translators: %s Product title. */
wc_add_notice( sprintf( __( 'You can only have 1 %s in your cart.', 'woocommerce' ), $_product->get_name() ), 'error' );
$passed_validation = false;
}
@ -595,11 +627,10 @@ class WC_Form_Handler {
}
}
// Trigger action - let 3rd parties update the cart if they need to and update the $cart_updated variable
// Trigger action - let 3rd parties update the cart if they need to and update the $cart_updated variable.
$cart_updated = apply_filters( 'woocommerce_update_cart_action_cart_updated', $cart_updated );
if ( $cart_updated ) {
// Recalc our totals
WC()->cart->calculate_totals();
}
@ -980,8 +1011,7 @@ class WC_Form_Handler {
*/
public static function process_login() {
// The global form-login.php template used `_wpnonce` in template versions < 3.3.0.
$nonce_value = isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '';
$nonce_value = isset( $_POST['woocommerce-login-nonce'] ) ? $_POST['woocommerce-login-nonce'] : $nonce_value;
$nonce_value = wc_get_var( $_REQUEST['woocommerce-login-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! empty( $_POST['login'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-login' ) ) {
@ -1043,7 +1073,13 @@ class WC_Form_Handler {
* Handle lost password form.
*/
public static function process_lost_password() {
if ( isset( $_POST['wc_reset_password'] ) && isset( $_POST['user_login'] ) && isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'lost_password' ) ) {
if ( isset( $_POST['wc_reset_password'], $_POST['user_login'] ) ) {
$nonce_value = wc_get_var( $_REQUEST['woocommerce-lost-password-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! wp_verify_nonce( $nonce_value, 'lost_password' ) ) {
return;
}
$success = WC_Shortcode_My_Account::retrieve_password();
// If successful, redirect to my account with query arg set.
@ -1058,7 +1094,7 @@ class WC_Form_Handler {
* Handle reset password form.
*/
public static function process_reset_password() {
$posted_fields = array( 'wc_reset_password', 'password_1', 'password_2', 'reset_key', 'reset_login', '_wpnonce' );
$posted_fields = array( 'wc_reset_password', 'password_1', 'password_2', 'reset_key', 'reset_login' );
foreach ( $posted_fields as $field ) {
if ( ! isset( $_POST[ $field ] ) ) {
@ -1067,7 +1103,9 @@ class WC_Form_Handler {
$posted_fields[ $field ] = $_POST[ $field ];
}
if ( ! wp_verify_nonce( $posted_fields['_wpnonce'], 'reset_password' ) ) {
$nonce_value = wc_get_var( $_REQUEST['woocommerce-reset-password-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! wp_verify_nonce( $nonce_value, 'reset_password' ) ) {
return;
}

View File

@ -220,7 +220,7 @@ class WC_Frontend_Scripts {
'selectWoo' => array(
'src' => self::get_asset_url( 'assets/js/selectWoo/selectWoo.full' . $suffix . '.js' ),
'deps' => array( 'jquery' ),
'version' => '1.0.3',
'version' => '1.0.4',
),
'wc-address-i18n' => array(
'src' => self::get_asset_url( 'assets/js/frontend/address-i18n' . $suffix . '.js' ),

View File

@ -2,13 +2,11 @@
/**
* Installation related functions and actions.
*
* @package WooCommerce/Classes
* @version 3.0.0
* @package WooCommerce/Classes
* @version 3.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Install Class.
@ -151,11 +149,11 @@ class WC_Install {
* This function is hooked into admin_init to affect admin only.
*/
public static function install_actions() {
if ( ! empty( $_GET['do_update_woocommerce'] ) ) {
if ( ! empty( $_GET['do_update_woocommerce'] ) ) { // WPCS: input var ok, CSRF ok.
self::update();
WC_Admin_Notices::add_notice( 'update' );
}
if ( ! empty( $_GET['force_update_woocommerce'] ) ) {
if ( ! empty( $_GET['force_update_woocommerce'] ) ) { // WPCS: input var ok, CSRF ok.
do_action( 'wp_' . get_current_blog_id() . '_wc_updater_cron' );
wp_safe_redirect( admin_url( 'admin.php?page=wc-settings' ) );
exit;
@ -358,7 +356,7 @@ class WC_Install {
$held_duration = get_option( 'woocommerce_hold_stock_minutes', '60' );
if ( '' != $held_duration ) {
if ( '' !== $held_duration ) {
wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}
@ -463,7 +461,7 @@ class WC_Install {
}
}
$woocommerce_default_category = get_option( 'default_product_cat', 0 );
$woocommerce_default_category = (int) get_option( 'default_product_cat', 0 );
if ( ! $woocommerce_default_category || ! term_exists( $woocommerce_default_category, 'product_cat' ) ) {
$default_product_cat_id = 0;
@ -475,7 +473,7 @@ class WC_Install {
} else {
$result = wp_insert_term( _x( 'Uncategorized', 'Default category slug', 'woocommerce' ), 'product_cat', array( 'slug' => $default_product_cat_slug ) );
if ( ! empty( $result['term_taxonomy_id'] ) ) {
if ( ! is_wp_error( $result ) && ! empty( $result['term_taxonomy_id'] ) ) {
$default_product_cat_id = absint( $result['term_taxonomy_id'] );
}
}
@ -780,6 +778,15 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
$tables[] = "{$wpdb->prefix}woocommerce_termmeta";
}
/**
* Filter the list of known WooCommerce tables.
*
* If WooCommerce plugins need to add new tables, they can inject them here.
*
* @param array $tables An array of WooCommerce-specific database table names.
*/
$tables = apply_filters( 'woocommerce_install_get_tables', $tables );
return $tables;
}
@ -1000,10 +1007,10 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
foreach ( $files as $file ) {
if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
$file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' );
$file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen
if ( $file_handle ) {
fwrite( $file_handle, $file['content'] );
fclose( $file_handle );
fwrite( $file_handle, $file['content'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite
fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
}
}
}
@ -1031,7 +1038,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
* @return array
*/
public static function plugin_row_meta( $links, $file ) {
if ( WC_PLUGIN_BASENAME == $file ) {
if ( WC_PLUGIN_BASENAME === $file ) {
$row_meta = array(
'docs' => '<a href="' . esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/documentation/plugins/woocommerce/' ) ) . '" aria-label="' . esc_attr__( 'View WooCommerce documentation', 'woocommerce' ) . '">' . esc_html__( 'Docs', 'woocommerce' ) . '</a>',
'apidocs' => '<a href="' . esc_url( apply_filters( 'woocommerce_apidocs_url', 'https://docs.woocommerce.com/wc-apidocs/' ) ) . '" aria-label="' . esc_attr__( 'View WooCommerce API docs', 'woocommerce' ) . '">' . esc_html__( 'API docs', 'woocommerce' ) . '</a>',
@ -1051,8 +1058,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
* @param string $key Plugin relative path. Example: woocommerce/woocommerce.php.
*/
private static function associate_plugin_slug( $plugins, $key ) {
$slug = explode( '/', $key );
$slug = explode( '.', end( $slug ) );
$slug = explode( '/', $key );
$slug = explode( '.', end( $slug ) );
$plugins[ $slug[0] ] = $key;
return $plugins;
}

View File

@ -1,19 +1,17 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WooCommerce Integrations class
*
* Loads Integrations into WooCommerce.
*
* @class WC_Integrations
* @version 2.3.0
* @package WooCommerce/Classes/Integrations
* @category Class
* @author WooThemes
* @version 2.3.0
* @package WooCommerce/Classes/Integrations
*/
defined( 'ABSPATH' ) || exit;
/**
* Integrations class.
*/
class WC_Integrations {
@ -33,7 +31,7 @@ class WC_Integrations {
$load_integrations = apply_filters( 'woocommerce_integrations', array() );
// Load integration classes
// Load integration classes.
foreach ( $load_integrations as $integration ) {
$load_integration = new $integration();
@ -45,7 +43,6 @@ class WC_Integrations {
/**
* Return loaded integrations.
*
* @access public
* @return array
*/
public function get_integrations() {

View File

@ -1,17 +1,15 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Standard log levels
*
* @class WC_Log_Levels
* @version 1.0.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @version 3.2.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* Log levels class.
*/
abstract class WC_Log_Levels {
@ -77,7 +75,7 @@ abstract class WC_Log_Levels {
/**
* Validate a level string.
*
* @param string $level
* @param string $level Log level.
* @return bool True if $level is a valid level.
*/
public static function is_valid_level( $level ) {
@ -87,7 +85,7 @@ abstract class WC_Log_Levels {
/**
* Translate level string to integer.
*
* @param string $level emergency|alert|critical|error|warning|notice|info|debug
* @param string $level Log level, options: emergency|alert|critical|error|warning|notice|info|debug.
* @return int 100 (debug) - 800 (emergency) or 0 if not recognized
*/
public static function get_level_severity( $level ) {
@ -102,7 +100,7 @@ abstract class WC_Log_Levels {
/**
* Translate severity integer to level string.
*
* @param int $severity
* @param int $severity Serevity level.
* @return bool|string False if not recognized. Otherwise string representation of level.
*/
public static function get_severity_level( $severity ) {

View File

@ -7,16 +7,12 @@
*
* @version 3.2.0
* @package WooCommerce
* @category Class
* @author crodas
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Meta_Data class.
* Meta data class.
*/
class WC_Meta_Data implements JsonSerializable {
@ -39,7 +35,7 @@ class WC_Meta_Data implements JsonSerializable {
/**
* Constructor.
*
* @param array $meta Data to wrap behind this function.
* @param array $meta Data to wrap behind this function.
*/
public function __construct( $meta = array() ) {
$this->current_data = $meta;

View File

@ -1,18 +1,17 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Factory Class
* Order Factory
*
* The WooCommerce order factory creating the right order objects.
*
* @class WC_Order_Factory
* @version 3.0.0
* @package WooCommerce/Classes
* @category Class
* @author WooCommerce
* @version 3.0.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* Order factory class
*/
class WC_Order_Factory {
@ -29,8 +28,9 @@ class WC_Order_Factory {
return false;
}
$order_type = WC_Data_Store::load( 'order' )->get_order_type( $order_id );
if ( $order_type_data = wc_get_order_type( $order_type ) ) {
$order_type = WC_Data_Store::load( 'order' )->get_order_type( $order_id );
$order_type_data = wc_get_order_type( $order_type );
if ( $order_type_data ) {
$classname = $order_type_data['class_name'];
} else {
$classname = false;
@ -75,22 +75,22 @@ class WC_Order_Factory {
if ( $id && $item_type ) {
$classname = false;
switch ( $item_type ) {
case 'line_item' :
case 'product' :
case 'line_item':
case 'product':
$classname = 'WC_Order_Item_Product';
break;
case 'coupon' :
break;
case 'coupon':
$classname = 'WC_Order_Item_Coupon';
break;
case 'fee' :
break;
case 'fee':
$classname = 'WC_Order_Item_Fee';
break;
case 'shipping' :
break;
case 'shipping':
$classname = 'WC_Order_Item_Shipping';
break;
case 'tax' :
break;
case 'tax':
$classname = 'WC_Order_Item_Tax';
break;
break;
}
$classname = apply_filters( 'woocommerce_get_order_item_classname', $classname, $item_type, $id );

View File

@ -1,20 +1,22 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (coupon)
*
* @package WooCommerce/Classes
* @version 3.0.0
* @since 3.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Order Line Item (coupon).
*
* @version 3.0.0
* @since 3.0.0
* @package WooCommerce/Classes
* @author WooCommerce
* Order item coupon class.
*/
class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Order Data array. This is the core order data exposed in APIs since 3.0.0.
*
* @since 3.0.0
* @var array
*/
@ -33,8 +35,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Set order item name.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Coupon code.
*/
public function set_name( $value ) {
return $this->set_code( $value );
@ -43,8 +44,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Set code.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Coupon code.
*/
public function set_code( $value ) {
$this->set_prop( 'code', wc_clean( $value ) );
@ -53,8 +53,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Set discount amount.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Discount.
*/
public function set_discount( $value ) {
$this->set_prop( 'discount', wc_format_decimal( $value ) );
@ -63,8 +62,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Set discounted tax amount.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Discount tax.
*/
public function set_discount_tax( $value ) {
$this->set_prop( 'discount_tax', wc_format_decimal( $value ) );
@ -88,7 +86,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Get order item name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_name( $context = 'view' ) {
@ -98,7 +96,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Get coupon code.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_code( $context = 'view' ) {
@ -108,7 +106,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Get discount amount.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_discount( $context = 'view' ) {
@ -118,7 +116,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Get discounted tax amount.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
*
* @return string
*/
@ -136,9 +134,10 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
*/
/**
* offsetGet for ArrayAccess/Backwards compatibility.
* OffsetGet for ArrayAccess/Backwards compatibility.
*
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param string $offset Offset.
* @return mixed
*/
public function offsetGet( $offset ) {
@ -151,10 +150,11 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
}
/**
* offsetSet for ArrayAccess/Backwards compatibility.
* OffsetSet for ArrayAccess/Backwards compatibility.
*
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param mixed $value
* @param string $offset Offset.
* @param mixed $value Value.
*/
public function offsetSet( $offset, $value ) {
if ( 'discount_amount' === $offset ) {
@ -166,12 +166,13 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* OffsetExists for ArrayAccess.
*
* @param string $offset Offset.
* @return bool
*/
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'discount_amount', 'discount_amount_tax' ) ) ) {
if ( in_array( $offset, array( 'discount_amount', 'discount_amount_tax' ), true ) ) {
return true;
}
return parent::offsetExists( $offset );

View File

@ -1,18 +1,19 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (fee).
* Order Line Item (fee)
*
* Fee is an amount of money charged for a particular piece of work
* or for a particular right or service, and not supposed to be negative.
*
* @version 3.0.0
* @since 3.0.0
* @package WooCommerce/Classes
* @author WooThemes
* @package WooCommerce/Classes
* @version 3.0.0
* @since 3.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Order item fee.
*/
class WC_Order_Item_Fee extends WC_Order_Item {
@ -52,7 +53,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
if ( 'taxable' !== $item->get_tax_status() ) {
$costs['non-taxable'] += $item->get_total();
} elseif ( 'inherit' === $item->get_tax_class() ) {
$inherit_class = reset( $order_item_tax_classes );
$inherit_class = reset( $order_item_tax_classes );
$costs[ $inherit_class ] += $item->get_total();
} else {
$costs[ $item->get_tax_class() ] += $item->get_total();
@ -76,7 +77,8 @@ class WC_Order_Item_Fee extends WC_Order_Item {
if ( 0 <= $this->get_total() ) {
return parent::calculate_taxes( $calculate_tax_for );
}
if ( wc_tax_enabled() && ( $order = $this->get_order() ) ) {
if ( wc_tax_enabled() && $this->get_order() ) {
// Apportion taxes to order items, shipping, and fees.
$order = $this->get_order();
$tax_class_costs = $this->get_tax_class_costs( $order );
@ -113,8 +115,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Set fee amount.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Amount.
*/
public function set_amount( $value ) {
$this->set_prop( 'amount', wc_format_decimal( $value ) );
@ -123,11 +124,10 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Set tax class.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Tax class.
*/
public function set_tax_class( $value ) {
if ( $value && ! in_array( $value, WC_Tax::get_tax_class_slugs() ) ) {
if ( $value && ! in_array( $value, WC_Tax::get_tax_class_slugs(), true ) ) {
$this->error( 'order_item_fee_invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) );
}
$this->set_prop( 'tax_class', $value );
@ -136,11 +136,10 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Set tax_status.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Tax status.
*/
public function set_tax_status( $value ) {
if ( in_array( $value, array( 'taxable', 'none' ) ) ) {
if ( in_array( $value, array( 'taxable', 'none' ), true ) ) {
$this->set_prop( 'tax_status', $value );
} else {
$this->set_prop( 'tax_status', 'taxable' );
@ -151,7 +150,6 @@ class WC_Order_Item_Fee extends WC_Order_Item {
* Set total.
*
* @param string $amount Fee amount (do not enter negative amounts).
* @throws WC_Data_Exception
*/
public function set_total( $amount ) {
$this->set_prop( 'total', wc_format_decimal( $amount ) );
@ -160,8 +158,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Set total tax.
*
* @param string $amount
* @throws WC_Data_Exception
* @param string $amount Amount.
*/
public function set_total_tax( $amount ) {
$this->set_prop( 'total_tax', wc_format_decimal( $amount ) );
@ -171,8 +168,8 @@ class WC_Order_Item_Fee extends WC_Order_Item {
* Set taxes.
*
* This is an array of tax ID keys with total amount values.
* @param array $raw_tax_data
* @throws WC_Data_Exception
*
* @param array $raw_tax_data Raw tax data.
*/
public function set_taxes( $raw_tax_data ) {
$raw_tax_data = maybe_unserialize( $raw_tax_data );
@ -195,7 +192,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Get fee amount.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_amount( $context = 'view' ) {
@ -205,7 +202,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Get order item name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_name( $context = 'view' ) {
@ -229,7 +226,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Get tax class.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_tax_class( $context = 'view' ) {
@ -239,7 +236,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Get tax status.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_tax_status( $context = 'view' ) {
@ -249,7 +246,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Get total fee.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_total( $context = 'view' ) {
@ -259,7 +256,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Get total tax.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_total_tax( $context = 'view' ) {
@ -269,7 +266,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Get fee taxes.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_taxes( $context = 'view' ) {
@ -286,9 +283,10 @@ class WC_Order_Item_Fee extends WC_Order_Item {
*/
/**
* offsetGet for ArrayAccess/Backwards compatibility.
* OffsetGet for ArrayAccess/Backwards compatibility.
*
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param string $offset Offset.
* @return mixed
*/
public function offsetGet( $offset ) {
@ -303,10 +301,11 @@ class WC_Order_Item_Fee extends WC_Order_Item {
}
/**
* offsetSet for ArrayAccess/Backwards compatibility.
* OffsetSet for ArrayAccess/Backwards compatibility.
*
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param mixed $value
* @param string $offset Offset.
* @param mixed $value Value.
*/
public function offsetSet( $offset, $value ) {
if ( 'line_total' === $offset ) {
@ -320,12 +319,13 @@ class WC_Order_Item_Fee extends WC_Order_Item {
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* OffsetExists for ArrayAccess
*
* @param string $offset Offset.
* @return bool
*/
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'line_total', 'line_tax', 'line_tax_data' ) ) ) {
if ( in_array( $offset, array( 'line_total', 'line_tax', 'line_tax_data' ), true ) ) {
return true;
}
return parent::offsetExists( $offset );

View File

@ -1,43 +1,59 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Item Meta
*
* A Simple class for managing order item meta so plugins add it in the correct format.
*
* @package WooCommerce/Classes
* @deprecated 3.0.0 wc_display_item_meta function is used instead.
* @class order_item_meta
* @version 2.4
* @package WooCommerce/Classes
* @author WooThemes
* @version 2.4
*/
defined( 'ABSPATH' ) || exit;
/**
* Order item meta class.
*/
class WC_Order_Item_Meta {
/** @var bool For handling backwards comp */
/**
* For handling backwards compatibility.
*
* @var bool
*/
private $legacy = false;
/** @var Array Order item */
private $item = null;
/**
* Order item
*
* @var array|null
*/
private $item = null;
/** @var Array Post meta data */
public $meta = null;
/**
* Post meta data
*
* @var array|null
*/
public $meta = null;
/** @var Product object */
/**
* Product object.
*
* @var WC_Product|null
*/
public $product = null;
/**
* Constructor.
*
* @param array $item defaults to array()
* @param \WC_Product $product defaults to null
* @param array $item defaults to array().
* @param \WC_Product $product defaults to null.
*/
public function __construct( $item = array(), $product = null ) {
wc_deprecated_function( 'WC_Order_Item_Meta::__construct', '3.1', 'WC_Order_Item_Product' );
// Backwards (pre 2.4) compatibility
// Backwards (pre 2.4) compatibility.
if ( ! isset( $item['item_meta'] ) ) {
$this->legacy = true;
$this->meta = array_filter( (array) $item );
@ -51,10 +67,10 @@ class WC_Order_Item_Meta {
/**
* Display meta in a formatted list.
*
* @param bool $flat (default: false)
* @param bool $return (default: false)
* @param string $hideprefix (default: _)
* @param string $delimiter Delimiter used to separate items when $flat is true
* @param bool $flat Flat (default: false).
* @param bool $return Return (default: false).
* @param string $hideprefix Hide prefix (default: _).
* @param string $delimiter Delimiter used to separate items when $flat is true.
* @return string|void
*/
public function display( $flat = false, $return = false, $hideprefix = '_', $delimiter = ", \n" ) {
@ -89,14 +105,14 @@ class WC_Order_Item_Meta {
if ( $return ) {
return $output;
} else {
echo $output;
echo $output; // WPCS: XSS ok.
}
}
/**
* Return an array of formatted item meta in format e.g.
*
* array(
* Returns: array(
* 'pa_size' => array(
* 'label' => 'Size',
* 'value' => 'Medium',
@ -104,7 +120,7 @@ class WC_Order_Item_Meta {
* )
*
* @since 2.4
* @param string $hideprefix exclude meta when key is prefixed with this, defaults to `_`
* @param string $hideprefix exclude meta when key is prefixed with this, defaults to '_'.
* @return array
*/
public function get_formatted( $hideprefix = '_' ) {
@ -116,14 +132,14 @@ class WC_Order_Item_Meta {
if ( ! empty( $this->item['item_meta_array'] ) ) {
foreach ( $this->item['item_meta_array'] as $meta_id => $meta ) {
if ( "" === $meta->value || is_serialized( $meta->value ) || ( ! empty( $hideprefix ) && substr( $meta->key, 0, 1 ) === $hideprefix ) ) {
if ( '' === $meta->value || is_serialized( $meta->value ) || ( ! empty( $hideprefix ) && substr( $meta->key, 0, 1 ) === $hideprefix ) ) {
continue;
}
$attribute_key = urldecode( str_replace( 'attribute_', '', $meta->key ) );
$meta_value = $meta->value;
// If this is a term slug, get the term's nice name
// If this is a term slug, get the term's nice name.
if ( taxonomy_exists( $attribute_key ) ) {
$term = get_term_by( 'slug', $meta_value, $attribute_key );
@ -147,7 +163,7 @@ class WC_Order_Item_Meta {
* Return an array of formatted item meta in format e.g.
* Handles @deprecated args.
*
* @param string $hideprefix
* @param string $hideprefix Hide prefix.
*
* @return array
*/
@ -159,18 +175,18 @@ class WC_Order_Item_Meta {
$formatted_meta = array();
foreach ( $this->meta as $meta_key => $meta_values ) {
if ( empty( $meta_values ) || ( ! empty( $hideprefix ) && substr( $meta_key, 0, 1 ) == $hideprefix ) ) {
if ( empty( $meta_values ) || ( ! empty( $hideprefix ) && substr( $meta_key, 0, 1 ) === $hideprefix ) ) {
continue;
}
foreach ( (array) $meta_values as $meta_value ) {
// Skip serialised meta
// Skip serialised meta.
if ( is_serialized( $meta_value ) ) {
continue;
}
$attribute_key = urldecode( str_replace( 'attribute_', '', $meta_key ) );
// If this is a term slug, get the term's nice name
// If this is a term slug, get the term's nice name.
if ( taxonomy_exists( $attribute_key ) ) {
$term = get_term_by( 'slug', $meta_value, $attribute_key );
if ( ! is_wp_error( $term ) && is_object( $term ) && $term->name ) {
@ -178,7 +194,7 @@ class WC_Order_Item_Meta {
}
}
// Unique key required
// Unique key required.
$formatted_meta_key = $meta_key;
$loop = 0;
while ( isset( $formatted_meta[ $formatted_meta_key ] ) ) {

View File

@ -1,15 +1,16 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (product)
*
* @package WooCommerce/Classes
* @version 3.0.0
* @since 3.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Order Line Item (product).
*
* @version 3.0.0
* @since 3.0.0
* @package WooCommerce/Classes
* @author WooThemes
* Order item product class.
*/
class WC_Order_Item_Product extends WC_Order_Item {
@ -43,8 +44,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Set quantity.
*
* @param int $value
* @throws WC_Data_Exception
* @param int $value Quantity.
*/
public function set_quantity( $value ) {
$this->set_prop( 'quantity', wc_stock_amount( $value ) );
@ -53,11 +53,10 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Set tax class.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Tax class.
*/
public function set_tax_class( $value ) {
if ( $value && ! in_array( $value, WC_Tax::get_tax_class_slugs() ) ) {
if ( $value && ! in_array( $value, WC_Tax::get_tax_class_slugs(), true ) ) {
$this->error( 'order_item_product_invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) );
}
$this->set_prop( 'tax_class', $value );
@ -66,8 +65,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Set Product ID
*
* @param int $value
* @throws WC_Data_Exception
* @param int $value Product ID.
*/
public function set_product_id( $value ) {
if ( $value > 0 && 'product' !== get_post_type( absint( $value ) ) ) {
@ -79,8 +77,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Set variation ID.
*
* @param int $value
* @throws WC_Data_Exception
* @param int $value Variation ID.
*/
public function set_variation_id( $value ) {
if ( $value > 0 && 'product_variation' !== get_post_type( $value ) ) {
@ -92,8 +89,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Line subtotal (before discounts).
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Subtotal.
*/
public function set_subtotal( $value ) {
$value = wc_format_decimal( $value );
@ -108,8 +104,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Line total (after discounts).
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Total.
*/
public function set_total( $value ) {
$value = wc_format_decimal( $value );
@ -120,7 +115,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
$this->set_prop( 'total', $value );
// Subtotal cannot be less than total
// Subtotal cannot be less than total.
if ( '' === $this->get_subtotal() || $this->get_subtotal() < $this->get_total() ) {
$this->set_subtotal( $value );
}
@ -129,8 +124,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Line subtotal tax (before discounts).
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Subtotal tax.
*/
public function set_subtotal_tax( $value ) {
$this->set_prop( 'subtotal_tax', wc_format_decimal( $value ) );
@ -139,8 +133,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Line total tax (after discounts).
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Total tax.
*/
public function set_total_tax( $value ) {
$this->set_prop( 'total_tax', wc_format_decimal( $value ) );
@ -149,8 +142,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Set line taxes and totals for passed in taxes.
*
* @param array $raw_tax_data
* @throws WC_Data_Exception
* @param array $raw_tax_data Raw tax data.
*/
public function set_taxes( $raw_tax_data ) {
$raw_tax_data = maybe_unserialize( $raw_tax_data );
@ -175,7 +167,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Set variation data (stored as meta data - write only).
*
* @param array $data Key/Value pairs
* @param array $data Key/Value pairs.
*/
public function set_variation( $data = array() ) {
if ( is_array( $data ) ) {
@ -188,8 +180,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Set properties based on passed in product object.
*
* @param WC_Product $product
* @throws WC_Data_Exception
* @param WC_Product $product Product instance.
*/
public function set_product( $product ) {
if ( ! is_a( $product, 'WC_Product' ) ) {
@ -234,7 +225,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get product ID.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return int
*/
public function get_product_id( $context = 'view' ) {
@ -244,7 +235,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get variation ID.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return int
*/
public function get_variation_id( $context = 'view' ) {
@ -254,7 +245,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get quantity.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return int
*/
public function get_quantity( $context = 'view' ) {
@ -264,7 +255,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get tax class.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_tax_class( $context = 'view' ) {
@ -274,7 +265,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get subtotal.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_subtotal( $context = 'view' ) {
@ -284,7 +275,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get subtotal tax.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_subtotal_tax( $context = 'view' ) {
@ -294,7 +285,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get total.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_total( $context = 'view' ) {
@ -304,7 +295,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get total tax.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_total_tax( $context = 'view' ) {
@ -314,7 +305,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get taxes.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return array
*/
public function get_taxes( $context = 'view' ) {
@ -333,7 +324,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
$product = wc_get_product( $this->get_product_id() );
}
// Backwards compatible filter from WC_Order::get_product_from_item()
// Backwards compatible filter from WC_Order::get_product_from_item().
if ( has_filter( 'woocommerce_get_product_from_item' ) ) {
$product = apply_filters( 'woocommerce_get_product_from_item', $product, $this, $this->get_order() );
}
@ -344,18 +335,20 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get the Download URL.
*
* @param int $download_id
* @param int $download_id Download ID.
* @return string
*/
public function get_item_download_url( $download_id ) {
$order = $this->get_order();
return $order ? add_query_arg( array(
'download_file' => $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(),
'order' => $order->get_order_key(),
'email' => urlencode( $order->get_billing_email() ),
'key' => $download_id,
), trailingslashit( home_url() ) ) : '';
return $order ? add_query_arg(
array(
'download_file' => $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(),
'order' => $order->get_order_key(),
'email' => rawurlencode( $order->get_billing_email() ),
'key' => $download_id,
), trailingslashit( home_url() )
) : '';
}
/**
@ -372,25 +365,29 @@ class WC_Order_Item_Product extends WC_Order_Item {
if ( $product && $order && $product->is_downloadable() && $order->is_download_permitted() ) {
$data_store = WC_Data_Store::load( 'customer-download' );
$customer_downloads = $data_store->get_downloads( array(
'user_email' => $order->get_billing_email(),
'order_id' => $order->get_id(),
'product_id' => $product_id,
) );
$customer_downloads = $data_store->get_downloads(
array(
'user_email' => $order->get_billing_email(),
'order_id' => $order->get_id(),
'product_id' => $product_id,
)
);
foreach ( $customer_downloads as $customer_download ) {
$download_id = $customer_download->get_download_id();
if ( $product->has_file( $download_id ) ) {
$file = $product->get_file( $download_id );
$files[ $download_id ] = $file->get_data();
$file = $product->get_file( $download_id );
$files[ $download_id ] = $file->get_data();
$files[ $download_id ]['downloads_remaining'] = $customer_download->get_downloads_remaining();
$files[ $download_id ]['access_expires'] = $customer_download->get_access_expires();
$files[ $download_id ]['download_url'] = add_query_arg( array(
'download_file' => $product_id,
'order' => $order->get_order_key(),
'uid' => $email_hash,
'key' => $download_id,
), trailingslashit( home_url() ) );
$files[ $download_id ]['download_url'] = add_query_arg(
array(
'download_file' => $product_id,
'order' => $order->get_order_key(),
'uid' => $email_hash,
'key' => $download_id,
), trailingslashit( home_url() )
);
}
}
}
@ -400,6 +397,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
/**
* Get tax status.
*
* @return string
*/
public function get_tax_status() {
@ -417,10 +415,10 @@ class WC_Order_Item_Product extends WC_Order_Item {
*/
/**
* offsetGet for ArrayAccess/Backwards compatibility.
* OffsetGet for ArrayAccess/Backwards compatibility.
*
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param string $offset Offset.
* @return mixed
*/
public function offsetGet( $offset ) {
@ -441,11 +439,11 @@ class WC_Order_Item_Product extends WC_Order_Item {
}
/**
* offsetSet for ArrayAccess/Backwards compatibility.
* OffsetSet for ArrayAccess/Backwards compatibility.
*
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param mixed $value
* @param string $offset Offset.
* @param mixed $value Value.
*/
public function offsetSet( $offset, $value ) {
if ( 'line_subtotal' === $offset ) {
@ -465,13 +463,13 @@ class WC_Order_Item_Product extends WC_Order_Item {
}
/**
* offsetExists for ArrayAccess
* OffsetExists for ArrayAccess.
*
* @param string $offset
* @param string $offset Offset.
* @return bool
*/
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'line_subtotal', 'line_subtotal_tax', 'line_total', 'line_tax', 'line_tax_data', 'item_meta_array', 'item_meta', 'qty' ) ) ) {
if ( in_array( $offset, array( 'line_subtotal', 'line_subtotal_tax', 'line_total', 'line_tax', 'line_tax_data', 'item_meta_array', 'item_meta', 'qty' ), true ) ) {
return true;
}
return parent::offsetExists( $offset );

View File

@ -1,18 +1,16 @@
<?php
/**
* Order Line Item (shipping).
* Order Line Item (shipping)
*
* @version 3.0.0
* @since 3.0.0
* @package WooCommerce/Classes
* @package WooCommerce/Classes
* @version 3.0.0
* @since 3.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Order_Item_Shipping class.
* Order item shipping class.
*/
class WC_Order_Item_Shipping extends WC_Order_Item {

View File

@ -1,20 +1,22 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (tax)
*
* @package WooCommerce/Classes
* @version 3.0.0
* @since 3.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Order Line Item (tax).
*
* @version 3.0.0
* @since 3.0.0
* @package WooCommerce/Classes
* @author WooThemes
* Order item tax.
*/
class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Order Data array. This is the core order data exposed in APIs since 3.0.0.
*
* @since 3.0.0
* @var array
*/
@ -36,8 +38,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Set order item name.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Name.
*/
public function set_name( $value ) {
$this->set_rate_code( $value );
@ -46,8 +47,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Set item name.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Rate code.
*/
public function set_rate_code( $value ) {
$this->set_prop( 'rate_code', wc_clean( $value ) );
@ -55,8 +55,8 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Set item name.
* @param string $value
* @throws WC_Data_Exception
*
* @param string $value Label.
*/
public function set_label( $value ) {
$this->set_prop( 'label', wc_clean( $value ) );
@ -64,8 +64,8 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Set tax rate id.
* @param int $value
* @throws WC_Data_Exception
*
* @param int $value Rate ID.
*/
public function set_rate_id( $value ) {
$this->set_prop( 'rate_id', absint( $value ) );
@ -73,26 +73,26 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Set tax total.
* @param string $value
* @throws WC_Data_Exception
*
* @param string $value Tax total.
*/
public function set_tax_total( $value ) {
$this->set_prop( 'tax_total', $value ? wc_format_decimal( $value ) : 0 );
}
/**
* Set shipping_tax_total
* @param string $value
* @throws WC_Data_Exception
* Set shipping tax total.
*
* @param string $value Shipping tax total.
*/
public function set_shipping_tax_total( $value ) {
$this->set_prop( 'shipping_tax_total', $value ? wc_format_decimal( $value ) : 0 );
}
/**
* Set compound
* @param bool $value
* @throws WC_Data_Exception
* Set compound.
*
* @param bool $value If tax is compound.
*/
public function set_compound( $value ) {
$this->set_prop( 'compound', (bool) $value );
@ -100,8 +100,8 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Set properties based on passed in tax rate by ID.
* @param int $tax_rate_id
* @throws WC_Data_Exception
*
* @param int $tax_rate_id Tax rate ID.
*/
public function set_rate( $tax_rate_id ) {
$tax_rate = WC_Tax::_get_tax_rate( $tax_rate_id, OBJECT );
@ -130,7 +130,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Get rate code/name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_name( $context = 'view' ) {
@ -140,7 +140,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Get rate code/name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_rate_code( $context = 'view' ) {
@ -150,7 +150,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Get label.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_label( $context = 'view' ) {
@ -165,7 +165,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Get tax rate ID.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return int
*/
public function get_rate_id( $context = 'view' ) {
@ -175,7 +175,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Get tax_total
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_tax_total( $context = 'view' ) {
@ -185,7 +185,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Get shipping_tax_total
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_shipping_tax_total( $context = 'view' ) {
@ -195,7 +195,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Get compound.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return bool
*/
public function get_compound( $context = 'view' ) {
@ -204,6 +204,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Is this a compound tax rate?
*
* @return boolean
*/
public function is_compound() {
@ -220,9 +221,10 @@ class WC_Order_Item_Tax extends WC_Order_Item {
*/
/**
* offsetGet for ArrayAccess/Backwards compatibility.
* O for ArrayAccess/Backwards compatibility.
*
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param string $offset Offset.
* @return mixed
*/
public function offsetGet( $offset ) {
@ -235,10 +237,11 @@ class WC_Order_Item_Tax extends WC_Order_Item {
}
/**
* offsetSet for ArrayAccess/Backwards compatibility.
* OffsetSet for ArrayAccess/Backwards compatibility.
*
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param mixed $value
* @param string $offset Offset.
* @param mixed $value Value.
*/
public function offsetSet( $offset, $value ) {
if ( 'tax_amount' === $offset ) {
@ -250,12 +253,13 @@ class WC_Order_Item_Tax extends WC_Order_Item {
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* OffsetExists for ArrayAccess.
*
* @param string $offset Offset.
* @return bool
*/
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'tax_amount', 'shipping_tax_amount' ) ) ) {
if ( in_array( $offset, array( 'tax_amount', 'shipping_tax_amount' ), true ) ) {
return true;
}
return parent::offsetExists( $offset );

View File

@ -1,23 +1,25 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Item
*
* A class which represents an item within an order and handles CRUD.
* Uses ArrayAccess to be BW compatible with WC_Orders::get_items().
*
* @version 3.0.0
* @since 3.0.0
* @package WooCommerce/Classes
* @author WooThemes
* @package WooCommerce/Classes
* @version 3.0.0
* @since 3.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Order item class.
*/
class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Order Data array. This is the core order data exposed in APIs since 3.0.0.
*
* @since 3.0.0
* @var array
*/
@ -29,6 +31,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Stores meta in cache for future reads.
* A group must be set to to enable caching.
*
* @var string
*/
protected $cache_group = 'order-items';
@ -37,18 +40,22 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
* Meta type. This should match up with
* the types available at https://codex.wordpress.org/Function_Reference/add_metadata.
* WP defines 'post', 'user', 'comment', and 'term'.
*
* @var string
*/
protected $meta_type = 'order_item';
/**
* This is the name of this object type.
*
* @var string
*/
protected $object_type = 'order_item';
/**
* Constructor.
* @param int|object|array $item ID to load from the DB, or WC_Order_Item Object
*
* @param int|object|array $item ID to load from the DB, or WC_Order_Item object.
*/
public function __construct( $item = 0 ) {
parent::__construct( $item );
@ -61,7 +68,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
$this->set_object_read( true );
}
$type = 'line_item' === $this->get_type() ? 'product' : $this->get_type();
$type = 'line_item' === $this->get_type() ? 'product' : $this->get_type();
$this->data_store = WC_Data_Store::load( 'order-item-' . $type );
if ( $this->get_id() > 0 ) {
$this->data_store->read( $this );
@ -78,7 +85,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
*/
public function apply_changes() {
if ( function_exists( 'array_replace' ) ) {
$this->data = array_replace( $this->data, $this->changes );
$this->data = array_replace( $this->data, $this->changes ); // phpcs:ignore PHPCompatibility.PHP.NewFunctions.array_replaceFound
} else { // PHP 5.2 compatibility.
foreach ( $this->changes as $key => $change ) {
$this->data[ $key ] = $change;
@ -96,7 +103,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Get order ID this meta belongs to.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return int
*/
public function get_order_id( $context = 'view' ) {
@ -106,7 +113,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Get order item name.
*
* @param string $context
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
* @return string
*/
public function get_name( $context = 'view' ) {
@ -119,11 +126,12 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
* @return string
*/
public function get_type() {
return;
return '';
}
/**
* Get quantity.
*
* @return int
*/
public function get_quantity() {
@ -132,6 +140,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Get tax status.
*
* @return string
*/
public function get_tax_status() {
@ -141,7 +150,6 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Get tax class.
*
* @param string $context
* @return string
*/
public function get_tax_class() {
@ -150,6 +158,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Get parent order object.
*
* @return WC_Order
*/
public function get_order() {
@ -165,8 +174,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Set order ID.
*
* @param int $value
* @throws WC_Data_Exception
* @param int $value Order ID.
*/
public function set_order_id( $value ) {
$this->set_prop( 'order_id', absint( $value ) );
@ -175,8 +183,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Set order item name.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Item name.
*/
public function set_name( $value ) {
$this->set_prop( 'name', wc_clean( $value ) );
@ -191,11 +198,11 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Type checking.
*
* @param string|array $type
* @param string|array $type Type.
* @return boolean
*/
public function is_type( $type ) {
return is_array( $type ) ? in_array( $this->get_type(), $type ) : $type === $this->get_type();
return is_array( $type ) ? in_array( $this->get_type(), $type, true ) : $type === $this->get_type();
}
/**
@ -216,7 +223,12 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
if ( method_exists( $this, 'get_subtotal' ) ) {
$subtotal_taxes = WC_Tax::calc_tax( $this->get_subtotal(), $tax_rates, false );
$this->set_taxes( array( 'total' => $taxes, 'subtotal' => $subtotal_taxes ) );
$this->set_taxes(
array(
'total' => $taxes,
'subtotal' => $subtotal_taxes,
)
);
} else {
$this->set_taxes( array( 'total' => $taxes ) );
}
@ -293,9 +305,10 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
*/
/**
* offsetSet for ArrayAccess
* @param string $offset
* @param mixed $value
* OffsetSet for ArrayAccess.
*
* @param string $offset Offset.
* @param mixed $value Value.
*/
public function offsetSet( $offset, $value ) {
if ( 'item_meta_array' === $offset ) {
@ -317,8 +330,9 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
}
/**
* offsetUnset for ArrayAccess
* @param string $offset
* OffsetUnset for ArrayAccess.
*
* @param string $offset Offset.
*/
public function offsetUnset( $offset ) {
$this->maybe_read_meta_data();
@ -340,8 +354,9 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* OffsetExists for ArrayAccess.
*
* @param string $offset Offset.
* @return bool
*/
public function offsetExists( $offset ) {
@ -353,8 +368,9 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
}
/**
* offsetGet for ArrayAccess
* @param string $offset
* OffsetGet for ArrayAccess.
*
* @param string $offset Offset.
* @return mixed
*/
public function offsetGet( $offset ) {

View File

@ -1,83 +1,86 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class for parameter-based Order querying.
* Parameter-based Order querying
* Args and usage: https://github.com/woocommerce/woocommerce/wiki/wc_get_orders-and-WC_Order_Query
*
* @version 3.1.0
* @since 3.1.0
* @package WooCommerce/Classes
* @category Class
* @package WooCommerce/Classes
* @version 3.1.0
* @since 3.1.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Order query class.
*/
class WC_Order_Query extends WC_Object_Query {
/**
* Valid query vars for orders.
*
* @return array
*/
protected function get_default_query_vars() {
return array_merge(
parent::get_default_query_vars(),
array(
'status' => array_keys( wc_get_order_statuses() ),
'type' => wc_get_order_types( 'view-orders' ),
'currency' => '',
'version' => '',
'prices_include_tax' => '',
'date_created' => '',
'date_modified' => '',
'date_completed' => '',
'date_paid' => '',
'discount_total' => '',
'discount_tax' => '',
'shipping_total' => '',
'shipping_tax' => '',
'cart_tax' => '',
'total' => '',
'total_tax' => '',
'customer' => '',
'customer_id' => '',
'order_key' => '',
'billing_first_name' => '',
'billing_last_name' => '',
'billing_company' => '',
'billing_address_1' => '',
'billing_address_2' => '',
'billing_city' => '',
'billing_state' => '',
'billing_postcode' => '',
'billing_country' => '',
'billing_email' => '',
'billing_phone' => '',
'shipping_first_name' => '',
'shipping_last_name' => '',
'shipping_company' => '',
'shipping_address_1' => '',
'shipping_address_2' => '',
'shipping_city' => '',
'shipping_state' => '',
'shipping_postcode' => '',
'shipping_country' => '',
'payment_method' => '',
'payment_method_title' => '',
'transaction_id' => '',
'customer_ip_address' => '',
'customer_user_agent' => '',
'created_via' => '',
'customer_note' => '',
'status' => array_keys( wc_get_order_statuses() ),
'type' => wc_get_order_types( 'view-orders' ),
'currency' => '',
'version' => '',
'prices_include_tax' => '',
'date_created' => '',
'date_modified' => '',
'date_completed' => '',
'date_paid' => '',
'discount_total' => '',
'discount_tax' => '',
'shipping_total' => '',
'shipping_tax' => '',
'cart_tax' => '',
'total' => '',
'total_tax' => '',
'customer' => '',
'customer_id' => '',
'order_key' => '',
'billing_first_name' => '',
'billing_last_name' => '',
'billing_company' => '',
'billing_address_1' => '',
'billing_address_2' => '',
'billing_city' => '',
'billing_state' => '',
'billing_postcode' => '',
'billing_country' => '',
'billing_email' => '',
'billing_phone' => '',
'shipping_first_name' => '',
'shipping_last_name' => '',
'shipping_company' => '',
'shipping_address_1' => '',
'shipping_address_2' => '',
'shipping_city' => '',
'shipping_state' => '',
'shipping_postcode' => '',
'shipping_country' => '',
'payment_method' => '',
'payment_method_title' => '',
'transaction_id' => '',
'customer_ip_address' => '',
'customer_user_agent' => '',
'created_via' => '',
'customer_note' => '',
)
);
}
/**
* Get orders matching the current query vars.
*
* @return array|object of WC_Order objects
*/
public function get_orders() {
$args = apply_filters( 'woocommerce_order_query_args', $this->get_query_vars() );
$args = apply_filters( 'woocommerce_order_query_args', $this->get_query_vars() );
$results = WC_Data_Store::load( 'order' )->query( $args );
return apply_filters( 'woocommerce_order_query', $results, $args );
}

View File

@ -1,16 +1,16 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order refund. Refunds are based on orders (essentially negative orders) and
* contain much of the same data.
*
* @version 3.0.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @version 3.0.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* Order refund class.
*/
class WC_Order_Refund extends WC_Abstract_Order {
@ -23,6 +23,7 @@ class WC_Order_Refund extends WC_Abstract_Order {
/**
* This is the name of this object type.
*
* @var string
*/
protected $object_type = 'order_refund';
@ -33,13 +34,15 @@ class WC_Order_Refund extends WC_Abstract_Order {
* @var array
*/
protected $extra_data = array(
'amount' => '',
'reason' => '',
'refunded_by' => 0,
'amount' => '',
'reason' => '',
'refunded_by' => 0,
'refunded_payment' => false,
);
/**
* Get internal type (post type.)
*
* @return string
*/
public function get_type() {
@ -49,7 +52,7 @@ class WC_Order_Refund extends WC_Abstract_Order {
/**
* Get status - always completed for refunds.
*
* @param string $context
* @param string $context What the value is for. Valid values are view and edit.
* @return string
*/
public function get_status( $context = 'view' ) {
@ -68,7 +71,7 @@ class WC_Order_Refund extends WC_Abstract_Order {
/**
* Get refunded amount.
*
* @param string $context
* @param string $context What the value is for. Valid values are view and edit.
* @return int|float
*/
public function get_amount( $context = 'view' ) {
@ -79,7 +82,7 @@ class WC_Order_Refund extends WC_Abstract_Order {
* Get refund reason.
*
* @since 2.2
* @param string $context
* @param string $context What the value is for. Valid values are view and edit.
* @return int|float
*/
public function get_reason( $context = 'view' ) {
@ -90,12 +93,22 @@ class WC_Order_Refund extends WC_Abstract_Order {
* Get ID of user who did the refund.
*
* @since 3.0
* @param string $context
* @param string $context What the value is for. Valid values are view and edit.
* @return int
*/
public function get_refunded_by( $context = 'view' ) {
return $this->get_prop( 'refunded_by', $context );
}
/**
* Return if the payment was refunded via API.
*
* @since 3.3
* @param string $context What the value is for. Valid values are view and edit.
* @return bool
*/
public function get_refunded_payment( $context = 'view' ) {
return $this->get_prop( 'refunded_payment', $context );
}
/**
@ -111,8 +124,8 @@ class WC_Order_Refund extends WC_Abstract_Order {
/**
* Set refunded amount.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Value to set.
* @throws WC_Data_Exception Exception if the amount is invalid.
*/
public function set_amount( $value ) {
$this->set_prop( 'amount', wc_format_decimal( $value ) );
@ -121,8 +134,8 @@ class WC_Order_Refund extends WC_Abstract_Order {
/**
* Set refund reason.
*
* @param string $value
* @throws WC_Data_Exception
* @param string $value Value to set.
* @throws WC_Data_Exception Exception if the amount is invalid.
*/
public function set_reason( $value ) {
$this->set_prop( 'reason', $value );
@ -131,17 +144,27 @@ class WC_Order_Refund extends WC_Abstract_Order {
/**
* Set refunded by.
*
* @param int $value
* @throws WC_Data_Exception
* @param int $value Value to set.
* @throws WC_Data_Exception Exception if the amount is invalid.
*/
public function set_refunded_by( $value ) {
$this->set_prop( 'refunded_by', absint( $value ) );
}
/**
* Set if the payment was refunded via API.
*
* @since 3.3
* @param bool $value Value to set.
*/
public function set_refunded_payment( $value ) {
$this->set_prop( 'refunded_payment', (bool) $value );
}
/**
* Magic __get method for backwards compatibility.
*
* @param string $key
* @param string $key Value to get.
* @return mixed
*/
public function __get( $key ) {
@ -159,24 +182,31 @@ class WC_Order_Refund extends WC_Abstract_Order {
/**
* Gets an refund from the database.
*
* @deprecated 3.0
* @param int $id (default: 0).
* @return bool
*/
public function get_refund( $id = 0 ) {
wc_deprecated_function( 'get_refund', '3.0', 'read' );
if ( ! $id ) {
return false;
}
if ( $result = get_post( $id ) ) {
$result = get_post( $id );
if ( $result ) {
$this->populate( $result );
return true;
}
return false;
}
/**
* Get refund amount.
*
* @deprecated 3.0
* @return int|float
*/
@ -187,6 +217,7 @@ class WC_Order_Refund extends WC_Abstract_Order {
/**
* Get refund reason.
*
* @deprecated 3.0
* @return int|float
*/

View File

@ -130,10 +130,12 @@ class WC_Order extends WC_Abstract_Order {
wc_transaction_query( 'rollback' );
$logger = wc_get_logger();
$logger->error( sprintf( 'Payment complete of order #%d failed!', $this->get_id() ), array(
'order' => $this,
'error' => $e,
) );
$logger->error(
sprintf( 'Payment complete of order #%d failed!', $this->get_id() ), array(
'order' => $this,
'error' => $e,
)
);
$this->add_order_note( __( 'Payment complete event failed.', 'woocommerce' ) . ' ' . $e->getMessage() );
return false;
@ -232,10 +234,12 @@ class WC_Order extends WC_Abstract_Order {
$this->status_transition();
} catch ( Exception $e ) {
$logger = wc_get_logger();
$logger->error( sprintf( 'Error saving order #%d', $this->get_id() ), array(
'order' => $this,
'error' => $e,
) );
$logger->error(
sprintf( 'Error saving order #%d', $this->get_id() ), array(
'order' => $this,
'error' => $e,
)
);
$this->add_order_note( __( 'Error saving order.', 'woocommerce' ) . ' ' . $e->getMessage() );
}
@ -326,10 +330,12 @@ class WC_Order extends WC_Abstract_Order {
wc_transaction_query( 'rollback' );
$logger = wc_get_logger();
$logger->error( sprintf( 'Update status of order #%d failed!', $this->get_id() ), array(
'order' => $this,
'error' => $e,
) );
$logger->error(
sprintf( 'Update status of order #%d failed!', $this->get_id() ), array(
'order' => $this,
'error' => $e,
)
);
$this->add_order_note( __( 'Update status event failed.', 'woocommerce' ) . ' ' . $e->getMessage() );
return false;
}
@ -364,10 +370,12 @@ class WC_Order extends WC_Abstract_Order {
$this->add_order_note( trim( $status_transition['note'] . ' ' . $transition_note ), 0, $status_transition['manual'] );
} catch ( Exception $e ) {
$logger = wc_get_logger();
$logger->error( sprintf( 'Status transition of order #%d errored!', $this->get_id() ), array(
'order' => $this,
'error' => $e,
) );
$logger->error(
sprintf( 'Status transition of order #%d errored!', $this->get_id() ), array(
'order' => $this,
'error' => $e,
)
);
$this->add_order_note( __( 'Error during status transition.', 'woocommerce' ) . ' ' . $e->getMessage() );
}
}
@ -1497,10 +1505,12 @@ class WC_Order extends WC_Abstract_Order {
if ( $on_checkout ) {
$pay_url = add_query_arg( 'key', $this->get_order_key(), $pay_url );
} else {
$pay_url = add_query_arg( array(
'pay_for_order' => 'true',
'key' => $this->get_order_key(),
), $pay_url );
$pay_url = add_query_arg(
array(
'pay_for_order' => 'true',
'key' => $this->get_order_key(),
), $pay_url
);
}
return apply_filters( 'woocommerce_get_checkout_payment_url', $pay_url, $this );
@ -1530,12 +1540,18 @@ class WC_Order extends WC_Abstract_Order {
* @return string
*/
public function get_cancel_order_url( $redirect = '' ) {
return apply_filters( 'woocommerce_get_cancel_order_url', wp_nonce_url( add_query_arg( array(
'cancel_order' => 'true',
'order' => $this->get_order_key(),
'order_id' => $this->get_id(),
'redirect' => $redirect,
), $this->get_cancel_endpoint() ), 'woocommerce-cancel_order' ) );
return apply_filters(
'woocommerce_get_cancel_order_url', wp_nonce_url(
add_query_arg(
array(
'cancel_order' => 'true',
'order' => $this->get_order_key(),
'order_id' => $this->get_id(),
'redirect' => $redirect,
), $this->get_cancel_endpoint()
), 'woocommerce-cancel_order'
)
);
}
/**
@ -1545,13 +1561,17 @@ class WC_Order extends WC_Abstract_Order {
* @return string The unescaped cancel-order URL.
*/
public function get_cancel_order_url_raw( $redirect = '' ) {
return apply_filters( 'woocommerce_get_cancel_order_url_raw', add_query_arg( array(
'cancel_order' => 'true',
'order' => $this->get_order_key(),
'order_id' => $this->get_id(),
'redirect' => $redirect,
'_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
), $this->get_cancel_endpoint() ) );
return apply_filters(
'woocommerce_get_cancel_order_url_raw', add_query_arg(
array(
'cancel_order' => 'true',
'order' => $this->get_order_key(),
'order_id' => $this->get_id(),
'redirect' => $redirect,
'_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
), $this->get_cancel_endpoint()
)
);
}
/**
@ -1620,7 +1640,8 @@ class WC_Order extends WC_Abstract_Order {
$comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) ) : 'noreply.com'; // WPCS: input var ok.
$comment_author_email = sanitize_email( $comment_author_email );
}
$commentdata = apply_filters( 'woocommerce_new_order_note_data',
$commentdata = apply_filters(
'woocommerce_new_order_note_data',
array(
'comment_post_ID' => $this->get_id(),
'comment_author' => $comment_author,
@ -1643,10 +1664,12 @@ class WC_Order extends WC_Abstract_Order {
if ( $is_customer_note ) {
add_comment_meta( $comment_id, 'is_customer_note', 1 );
do_action( 'woocommerce_new_customer_note', array(
'order_id' => $this->get_id(),
'customer_note' => $commentdata['comment_content'],
) );
do_action(
'woocommerce_new_customer_note', array(
'order_id' => $this->get_id(),
'customer_note' => $commentdata['comment_content'],
)
);
}
return $comment_id;
@ -1702,11 +1725,13 @@ class WC_Order extends WC_Abstract_Order {
return $cached_data;
}
$this->refunds = wc_get_orders( array(
'type' => 'shop_order_refund',
'parent' => $this->get_id(),
'limit' => -1,
) );
$this->refunds = wc_get_orders(
array(
'type' => 'shop_order_refund',
'parent' => $this->get_id(),
'limit' => -1,
)
);
wp_cache_set( $cache_key, $this->refunds, $this->cache_group );

View File

@ -1,4 +1,10 @@
<?php
/**
* Class WC_Product_Grouped file.
*
* @package WooCommerce\Classes\Products
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -8,11 +14,9 @@ if ( ! defined( 'ABSPATH' ) ) {
*
* Grouped products cannot be purchased - they are wrappers for other products.
*
* @class WC_Product_Grouped
* @version 3.0.0
* @package WooCommerce/Classes/Products
* @category Class
* @author WooThemes
* @class WC_Product_Grouped
* @version 3.0.0
* @package WooCommerce/Classes/Products
*/
class WC_Product_Grouped extends WC_Product {
@ -27,6 +31,7 @@ class WC_Product_Grouped extends WC_Product {
/**
* Get internal type.
*
* @return string
*/
public function get_type() {
@ -61,8 +66,6 @@ class WC_Product_Grouped extends WC_Product {
* @return bool
*/
public function is_on_sale( $context = 'view' ) {
global $wpdb;
$children = array_filter( array_map( 'wc_get_product', $this->get_children( $context ) ), 'wc_products_array_filter_visible_grouped' );
$on_sale = false;
@ -89,7 +92,7 @@ class WC_Product_Grouped extends WC_Product {
* Returns the price in html format.
*
* @access public
* @param string $price (default: '')
* @param string $price (default: '').
* @return string
*/
public function get_price_html( $price = '' ) {
@ -143,7 +146,7 @@ class WC_Product_Grouped extends WC_Product {
/**
* Return the children of this product.
*
* @param string $context
* @param string $context What the value is for. Valid values are view and edit.
* @return array
*/
public function get_children( $context = 'view' ) {
@ -161,7 +164,7 @@ class WC_Product_Grouped extends WC_Product {
/**
* Return the children of this product.
*
* @param array $children
* @param array $children List of product children.
*/
public function set_children( $children ) {
$this->set_prop( 'children', array_filter( wp_parse_id_list( (array) $children ) ) );
@ -178,7 +181,7 @@ class WC_Product_Grouped extends WC_Product {
* upwards (from child to parent) when the variation is saved.
*
* @param WC_Product|int $product Product object or ID for which you wish to sync.
* @param bool $save If true, the product object will be saved to the DB before returning it.
* @param bool $save If true, the product object will be saved to the DB before returning it.
* @return WC_Product Synced product object.
*/
public static function sync( $product, $save = true ) {

View File

@ -4,12 +4,9 @@
*
* @version 3.2.0
* @package WooCommerce\Classes
* @author Automattic
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Query Class.
@ -379,7 +376,7 @@ class WC_Query {
*/
public function product_query( $q ) {
if ( ! is_feed() ) {
$ordering = $this->get_catalog_ordering_args();
$ordering = $this->get_catalog_ordering_args();
$q->set( 'orderby', $ordering['orderby'] );
$q->set( 'order', $ordering['order'] );
@ -430,7 +427,7 @@ class WC_Query {
public function get_catalog_ordering_args( $orderby = '', $order = '' ) {
// Get ordering from query string unless defined.
if ( ! $orderby ) {
$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( (string) wp_unslash( $_GET['orderby'] ) ) : ''; // WPCS: sanitization ok, input var ok.
$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( (string) wp_unslash( $_GET['orderby'] ) ) : ''; // WPCS: sanitization ok, input var ok, CSRF ok.
if ( ! $orderby_value ) {
if ( is_search() ) {
@ -456,7 +453,7 @@ class WC_Query {
switch ( $orderby ) {
case 'menu_order':
$args['orderby'] = 'menu_order title';
$args['orderby'] = 'menu_order title';
break;
case 'title':
$args['orderby'] = 'title';
@ -510,7 +507,7 @@ class WC_Query {
if ( isset( $wp_query->queried_object, $wp_query->queried_object->term_taxonomy_id, $wp_query->queried_object->taxonomy ) && is_a( $wp_query->queried_object, 'WP_Term' ) ) {
$search_within_terms = get_term_children( $wp_query->queried_object->term_taxonomy_id, $wp_query->queried_object->taxonomy );
$search_within_terms[] = $wp_query->queried_object->term_taxonomy_id;
$args['join'] .= " INNER JOIN (
$args['join'] .= " INNER JOIN (
SELECT post_id, max( meta_value+0 ) price
FROM $wpdb->postmeta
INNER JOIN (
@ -521,7 +518,7 @@ class WC_Query {
) as products_within_terms ON $wpdb->postmeta.post_id = products_within_terms.object_id
WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
} else {
$args['join'] .= " INNER JOIN ( SELECT post_id, min( meta_value+0 ) price FROM $wpdb->postmeta WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
$args['join'] .= " INNER JOIN ( SELECT post_id, min( meta_value+0 ) price FROM $wpdb->postmeta WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
}
$args['orderby'] = " price_query.price ASC, $wpdb->posts.ID ASC ";
return $args;
@ -539,7 +536,7 @@ class WC_Query {
if ( isset( $wp_query->queried_object, $wp_query->queried_object->term_taxonomy_id, $wp_query->queried_object->taxonomy ) && is_a( $wp_query->queried_object, 'WP_Term' ) ) {
$search_within_terms = get_term_children( $wp_query->queried_object->term_taxonomy_id, $wp_query->queried_object->taxonomy );
$search_within_terms[] = $wp_query->queried_object->term_taxonomy_id;
$args['join'] .= " INNER JOIN (
$args['join'] .= " INNER JOIN (
SELECT post_id, max( meta_value+0 ) price
FROM $wpdb->postmeta
INNER JOIN (
@ -582,7 +579,7 @@ class WC_Query {
if ( ! is_array( $meta_query ) ) {
$meta_query = array();
}
$meta_query['price_filter'] = $this->price_filter_meta_query();
$meta_query['price_filter'] = $this->price_filter_meta_query();
return array_filter( apply_filters( 'woocommerce_product_query_meta_query', $meta_query, $this ) );
}
@ -660,7 +657,7 @@ class WC_Query {
*/
private function price_filter_meta_query() {
if ( isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) { // WPCS: input var ok, CSRF ok.
$meta_query = wc_get_min_max_price_meta_query( $_GET ); // WPCS: input var ok, CSRF ok.
$meta_query = wc_get_min_max_price_meta_query( $_GET ); // WPCS: input var ok, CSRF ok.
$meta_query['price_filter'] = true;
return $meta_query;
@ -749,14 +746,14 @@ class WC_Query {
foreach ( $attribute_taxonomies as $tax ) {
$attribute = wc_sanitize_taxonomy_name( $tax->attribute_name );
$taxonomy = wc_attribute_taxonomy_name( $attribute );
$filter_terms = ! empty( $_GET[ 'filter_' . $attribute ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ 'filter_' . $attribute ] ) ) ) : array(); // WPCS: sanitization ok, input var ok.
$filter_terms = ! empty( $_GET[ 'filter_' . $attribute ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ 'filter_' . $attribute ] ) ) ) : array(); // WPCS: sanitization ok, input var ok, CSRF ok.
if ( empty( $filter_terms ) || ! taxonomy_exists( $taxonomy ) ) {
continue;
}
$query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ), true ) ? wc_clean( wp_unslash( $_GET[ 'query_type_' . $attribute ] ) ) : ''; // WPCS: sanitization ok, input var ok.
self::$_chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding.
$query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ), true ) ? wc_clean( wp_unslash( $_GET[ 'query_type_' . $attribute ] ) ) : ''; // WPCS: sanitization ok, input var ok, CSRF ok.
self::$_chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding.
self::$_chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
}
}

View File

@ -6,7 +6,7 @@
*
* @package WooCommerce/Classes
* @version 3.3.0
* @since 3.3.0
* @since 3.3.0
*/
defined( 'ABSPATH' ) || exit;
@ -159,7 +159,8 @@ class WC_Regenerate_Images {
self::$background_process->kill_process();
$log = wc_get_logger();
$log->info( __( 'Cancelled product image regeneration job.', 'woocommerce' ),
$log->info(
__( 'Cancelled product image regeneration job.', 'woocommerce' ),
array(
'source' => 'wc-image-regeneration',
)
@ -174,11 +175,15 @@ class WC_Regenerate_Images {
* @return void
*/
public static function maybe_regenerate_images() {
$size_hash = md5( wp_json_encode( array(
wc_get_image_size( 'thumbnail' ),
wc_get_image_size( 'single' ),
wc_get_image_size( 'gallery_thumbnail' ),
) ) );
$size_hash = md5(
wp_json_encode(
array(
wc_get_image_size( 'thumbnail' ),
wc_get_image_size( 'single' ),
wc_get_image_size( 'gallery_thumbnail' ),
)
)
);
if ( update_option( 'woocommerce_maybe_regenerate_images_hash', $size_hash ) ) {
// Size settings have changed. Trigger regen.
@ -271,8 +276,8 @@ class WC_Regenerate_Images {
}
list( , , , , $dst_w, $dst_h ) = $dimensions;
$suffix = "{$dst_w}x{$dst_h}";
$file_ext = strtolower( pathinfo( $fullsizepath, PATHINFO_EXTENSION ) );
$suffix = "{$dst_w}x{$dst_h}";
$file_ext = strtolower( pathinfo( $fullsizepath, PATHINFO_EXTENSION ) );
return array(
'filename' => $editor->generate_filename( $suffix, null, $file_ext ),
@ -291,11 +296,11 @@ class WC_Regenerate_Images {
* @return string
*/
private static function resize_and_return_image( $attachment_id, $image, $size, $icon ) {
$image_size = wc_get_image_size( $size );
$wp_uploads = wp_upload_dir( null, false );
$wp_uploads_dir = $wp_uploads['basedir'];
$wp_uploads_url = $wp_uploads['baseurl'];
$attachment = get_post( $attachment_id );
$image_size = wc_get_image_size( $size );
$wp_uploads = wp_upload_dir( null, false );
$wp_uploads_dir = $wp_uploads['basedir'];
$wp_uploads_url = $wp_uploads['baseurl'];
$attachment = get_post( $attachment_id );
if ( ! $attachment || 'attachment' !== $attachment->post_type || ! self::is_regeneratable( $attachment ) ) {
return $image;
@ -378,9 +383,11 @@ class WC_Regenerate_Images {
ORDER BY ID DESC"
);
foreach ( $images as $image ) {
self::$background_process->push_to_queue( array(
'attachment_id' => $image->ID,
) );
self::$background_process->push_to_queue(
array(
'attachment_id' => $image->ID,
)
);
}
// Lets dispatch the queue to start processing.

View File

@ -1,19 +1,25 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Take settings registered for WP-Admin and hooks them up to the REST API.
* Take settings registered for WP-Admin and hooks them up to the REST API
*
* @package WooCommerce/Classes
* @version 3.0.0
* @since 3.0.0
* @package WooCommerce/Classes
* @category Class
*/
defined( 'ABSPATH' ) || exit;
/**
* Register WP admin settings class.
*/
class WC_Register_WP_Admin_Settings {
/** @var class Contains the current class to pull settings from. Either a admin page object or WC_Email object. */
/**
* Contains the current class to pull settings from.
* Either a admin page object or WC_Email object
*
* @var WC_Register_WP_Admin_Settings
*/
protected $object;
/**
@ -32,10 +38,10 @@ class WC_Register_WP_Admin_Settings {
if ( 'page' === $type ) {
add_filter( 'woocommerce_settings_groups', array( $this, 'register_page_group' ) );
add_filter( 'woocommerce_settings-' . $this->object->get_id(), array( $this, 'register_page_settings' ) );
add_filter( 'woocommerce_settings-' . $this->object->get_id(), array( $this, 'register_page_settings' ) );
} elseif ( 'email' === $type ) {
add_filter( 'woocommerce_settings_groups', array( $this, 'register_email_group' ) );
add_filter( 'woocommerce_settings-email_' . $this->object->id, array( $this, 'register_email_settings' ) );
add_filter( 'woocommerce_settings-email_' . $this->object->id, array( $this, 'register_email_settings' ) );
}
}
@ -68,7 +74,7 @@ class WC_Register_WP_Admin_Settings {
foreach ( $this->object->form_fields as $id => $setting ) {
$setting['id'] = $id;
$setting['option_key'] = array( $this->object->get_option_key(), $id );
$new_setting = $this->register_setting( $setting );
$new_setting = $this->register_setting( $setting );
if ( $new_setting ) {
$settings[] = $new_setting;
}
@ -95,19 +101,19 @@ class WC_Register_WP_Admin_Settings {
* Registers settings to a specific group.
*
* @since 3.0.0
* @param array $settings Existing registered settings
* @param array $settings Existing registered settings.
* @return array
*/
public function register_page_settings( $settings ) {
/**
* wp-admin settings can be broken down into separate sections from
* WP admin settings can be broken down into separate sections from
* a UI standpoint. This will grab all the sections associated with
* a particular setting group (like 'products') and register them
* to the REST API.
*/
$sections = $this->object->get_sections();
if ( empty( $sections ) ) {
// Default section is just an empty string, per admin page classes
// Default section is just an empty string, per admin page classes.
$sections = array( '' );
}
@ -131,7 +137,7 @@ class WC_Register_WP_Admin_Settings {
* Register a setting into the format expected for the Settings REST API.
*
* @since 3.0.0
* @param array $setting
* @param array $setting Setting data.
* @return array|bool
*/
public function register_setting( $setting ) {

View File

@ -8,16 +8,12 @@
* @class WC_Session_Handler
* @version 2.5.0
* @package WooCommerce/Classes
* @category Class
* @author Automattic
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Session_Handler
* Session handler class.
*/
class WC_Session_Handler extends WC_Session {

View File

@ -152,7 +152,7 @@ class WC_Shipping_Zone extends WC_Legacy_Shipping_Zone {
/**
* Get shipping methods linked to this zone.
*
* @param bool $enabled_only Only return enabled methods.
* @param bool $enabled_only Only return enabled methods.
* @param string $context Getting shipping methods for what context. Valid values, admin, json.
* @return array of objects
*/
@ -191,7 +191,7 @@ class WC_Shipping_Zone extends WC_Legacy_Shipping_Zone {
$methods[ $instance_id ]->method_order = absint( $raw_method->method_order );
$methods[ $instance_id ]->enabled = $raw_method->is_enabled ? 'yes' : 'no';
$methods[ $instance_id ]->has_settings = $methods[ $instance_id ]->has_settings();
$methods[ $instance_id ]->settings_html = $methods[ $instance_id ]->supports( 'instance-settings-modal' ) ? $methods[ $instance_id ]->get_admin_options_html(): false;
$methods[ $instance_id ]->settings_html = $methods[ $instance_id ]->supports( 'instance-settings-modal' ) ? $methods[ $instance_id ]->get_admin_options_html() : false;
$methods[ $instance_id ]->method_description = wp_kses_post( wpautop( $methods[ $instance_id ]->method_description ) );
}

View File

@ -94,7 +94,7 @@ class WC_Shipping_Zones {
$wc_shipping = WC_Shipping::instance();
$allowed_classes = $wc_shipping->get_shipping_method_class_names();
if ( ! empty( $raw_shipping_method ) && in_array( $raw_shipping_method->method_id, array_keys( $allowed_classes ) ) ) {
if ( ! empty( $raw_shipping_method ) && in_array( $raw_shipping_method->method_id, array_keys( $allowed_classes ), true ) ) {
$class_name = $allowed_classes[ $raw_shipping_method->method_id ];
if ( is_object( $class_name ) ) {
$class_name = get_class( $class_name );

View File

@ -4,11 +4,9 @@
*
* Handles shipping and loads shipping methods via hooks.
*
* @class WC_Shipping
* @version 2.6.0
* @package WooCommerce/Classes/Shipping
* @category Class
* @author WooThemes
* @class WC_Shipping
* @version 2.6.0
* @package WooCommerce/Classes/Shipping
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -20,20 +18,38 @@ if ( ! defined( 'ABSPATH' ) ) {
*/
class WC_Shipping {
/** @var bool True if shipping is enabled. */
public $enabled = false;
/** @var array|null Stores methods loaded into woocommerce. */
public $shipping_methods = null;
/** @var array Stores the shipping classes. */
public $shipping_classes = array();
/** @var array Stores packages to ship and to get quotes for. */
public $packages = array();
/**
* True if shipping is enabled.
*
* @var bool
*/
public $enabled = false;
/**
* @var WC_Shipping The single instance of the class
* Stores methods loaded into woocommerce.
*
* @var array|null
*/
public $shipping_methods = null;
/**
* Stores the shipping classes.
*
* @var array
*/
public $shipping_classes = array();
/**
* Stores packages to ship and to get quotes for.
*
* @var array
*/
public $packages = array();
/**
* The single instance of the class
*
* @var WC_Shipping
* @since 2.1
*/
protected static $_instance = null;
@ -80,10 +96,10 @@ class WC_Shipping {
*/
public function __get( $name ) {
// Grab from cart for backwards compatibility with versions prior to 3.2.
if ( 'shipping_total' === $name ){
if ( 'shipping_total' === $name ) {
return wc()->cart->get_shipping_total();
}
if ( 'shipping_taxes' === $name ){
if ( 'shipping_taxes' === $name ) {
return wc()->cart->get_shipping_taxes();
}
}
@ -108,17 +124,18 @@ class WC_Shipping {
/**
* Shipping methods register themselves by returning their main class name through the woocommerce_shipping_methods filter.
*
* @return array
*/
public function get_shipping_method_class_names() {
// Unique Method ID => Method Class name
// Unique Method ID => Method Class name.
$shipping_methods = array(
'flat_rate' => 'WC_Shipping_Flat_Rate',
'free_shipping' => 'WC_Shipping_Free_Shipping',
'local_pickup' => 'WC_Shipping_Local_Pickup',
);
// For backwards compatibility with 2.5.x we load any ENABLED legacy shipping methods here
// For backwards compatibility with 2.5.x we load any ENABLED legacy shipping methods here.
$maybe_load_legacy_methods = array( 'flat_rate', 'free_shipping', 'international_delivery', 'local_delivery', 'local_pickup' );
foreach ( $maybe_load_legacy_methods as $method ) {
@ -135,7 +152,7 @@ class WC_Shipping {
* Loads all shipping methods which are hooked in.
* If a $package is passed some methods may add themselves conditionally and zones will be used.
*
* @param array $package
* @param array $package Package information.
* @return array
*/
public function load_shipping_methods( $package = array() ) {
@ -144,7 +161,7 @@ class WC_Shipping {
$shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
$this->shipping_methods = $shipping_zone->get_shipping_methods( true );
// Debug output
// Debug output.
if ( $debug_mode && ! defined( 'WOOCOMMERCE_CHECKOUT' ) && ! defined( 'WC_DOING_AJAX' ) && ! wc_has_notice( 'Customer matched zone "' . $shipping_zone->get_zone_name() . '"' ) ) {
wc_add_notice( 'Customer matched zone "' . $shipping_zone->get_zone_name() . '"' );
}
@ -160,7 +177,7 @@ class WC_Shipping {
// Methods can register themselves manually through this hook if necessary.
do_action( 'woocommerce_load_shipping_methods', $package );
// Return loaded methods
// Return loaded methods.
return $this->get_shipping_methods();
}
@ -212,36 +229,17 @@ class WC_Shipping {
*/
public function get_shipping_classes() {
if ( empty( $this->shipping_classes ) ) {
$classes = get_terms( 'product_shipping_class', array( 'hide_empty' => '0', 'orderby' => 'name' ) );
$classes = get_terms(
'product_shipping_class', array(
'hide_empty' => '0',
'orderby' => 'name',
)
);
$this->shipping_classes = ! is_wp_error( $classes ) ? $classes : array();
}
return apply_filters( 'woocommerce_get_shipping_classes', $this->shipping_classes );
}
/**
* Get the default method.
* @param array $available_methods
* @param boolean $current_chosen_method
* @return string
*/
private function get_default_method( $available_methods, $current_chosen_method = false ) {
if ( ! empty( $available_methods ) ) {
if ( ! empty( $current_chosen_method ) ) {
if ( isset( $available_methods[ $current_chosen_method ] ) ) {
return $available_methods[ $current_chosen_method ]->id;
} else {
foreach ( $available_methods as $method_key => $method ) {
if ( strpos( $method->id, $current_chosen_method ) === 0 ) {
return $method->id;
}
}
}
}
return current( $available_methods )->id;
}
return '';
}
/**
* Calculate shipping for (multiple) packages of cart items.
*
@ -292,7 +290,7 @@ class WC_Shipping {
}
$allowed = array_keys( WC()->countries->get_shipping_countries() );
return in_array( $package['destination']['country'], $allowed );
return in_array( $package['destination']['country'], $allowed, true );
}
/**
@ -338,10 +336,12 @@ class WC_Shipping {
$package['rates'] = apply_filters( 'woocommerce_package_rates', $package['rates'], $package );
// Store in session to avoid recalculation.
WC()->session->set( $session_key, array(
'package_hash' => $package_hash,
'rates' => $package['rates'],
) );
WC()->session->set(
$session_key, array(
'package_hash' => $package_hash,
'rates' => $package['rates'],
)
);
} else {
$package['rates'] = $stored_rates['rates'];
}
@ -351,6 +351,7 @@ class WC_Shipping {
/**
* Get packages.
*
* @return array
*/
public function get_packages() {
@ -368,6 +369,8 @@ class WC_Shipping {
}
/**
* Deprecated
*
* @deprecated 2.6.0 Was previously used to determine sort order of methods, but this is now controlled by zones and thus unused.
*/
public function sort_shipping_methods() {

View File

@ -2,15 +2,11 @@
/**
* Shortcodes
*
* @author Automattic
* @category Class
* @package WooCommerce/Classes
* @version 3.2.0
* @package WooCommerce/Classes
* @version 3.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WooCommerce Shortcodes class.
@ -202,6 +198,7 @@ class WC_Shortcodes {
$columns = absint( $atts['columns'] );
wc_set_loop_prop( 'columns', $columns );
wc_set_loop_prop( 'is_shortcode', true );
ob_start();
@ -512,7 +509,7 @@ class WC_Shortcodes {
// Check if sku is a variation.
if ( isset( $atts['sku'] ) && $single_product->have_posts() && 'product_variation' === $single_product->post->post_type ) {
$variation = new WC_Product_Variation( $single_product->post->ID );
$variation = new WC_Product_Variation( $single_product->post->ID );
$attributes = $variation->get_attributes();
// Set preselected id to be used by JS to provide context.

View File

@ -2,17 +2,15 @@
/**
* Structured data's handler and generator using JSON-LD format.
*
* @package WooCommerce/Classes
* @since 3.0.0
* @version 3.0.0
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Structured_Data class.
* Structured data class.
*/
class WC_Structured_Data {
@ -240,8 +238,8 @@ class WC_Structured_Data {
}
} else {
$markup_offer = array(
'@type' => 'Offer',
'price' => wc_format_decimal( $product->get_price(), wc_get_price_decimals() ),
'@type' => 'Offer',
'price' => wc_format_decimal( $product->get_price(), wc_get_price_decimals() ),
'priceSpecification' => array(
'price' => wc_format_decimal( $product->get_price(), wc_get_price_decimals() ),
'priceCurrency' => $currency,

View File

@ -2,16 +2,13 @@
/**
* Template Loader
*
* @class WC_Template
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Template_Loader.
* Template loader class.
*/
class WC_Template_Loader {

View File

@ -1,25 +1,23 @@
<?php
/**
* General user data validation methods
*
* @package WooCommerce\Classes
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
defined( 'ABSPATH' ) || exit;
/**
* Contains Validation functions
*
* @class WC_Validation
* @version 2.4.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* Validation class.
*/
class WC_Validation {
/**
* Validates an email using WordPress native is_email function.
*
* @param string $email Email address to validate.
* @return bool
* @param string $email Email address to validate.
* @return bool
*/
public static function is_email( $email ) {
return is_email( $email );
@ -28,8 +26,8 @@ class WC_Validation {
/**
* Validates a phone number using a regular expression.
*
* @param string $phone Phone number to validate.
* @return bool
* @param string $phone Phone number to validate.
* @return bool
*/
public static function is_phone( $phone ) {
if ( 0 < strlen( trim( preg_replace( '/[\s\#0-9_\-\+\/\(\)]/', '', $phone ) ) ) ) {
@ -42,9 +40,9 @@ class WC_Validation {
/**
* Checks for a valid postcode.
*
* @param string $postcode Postcode to validate.
* @param string $country Country to validate the postcode for.
* @return bool
* @param string $postcode Postcode to validate.
* @param string $country Country to validate the postcode for.
* @return bool
*/
public static function is_postcode( $postcode, $country ) {
if ( strlen( trim( preg_replace( '/[\s\-A-Za-z0-9]/', '', $postcode ) ) ) > 0 ) {
@ -52,36 +50,36 @@ class WC_Validation {
}
switch ( $country ) {
case 'AT' :
case 'AT':
$valid = (bool) preg_match( '/^([0-9]{4})$/', $postcode );
break;
case 'BR' :
case 'BR':
$valid = (bool) preg_match( '/^([0-9]{5})([-])?([0-9]{3})$/', $postcode );
break;
case 'CH' :
case 'CH':
$valid = (bool) preg_match( '/^([0-9]{4})$/i', $postcode );
break;
case 'DE' :
case 'DE':
$valid = (bool) preg_match( '/^([0]{1}[1-9]{1}|[1-9]{1}[0-9]{1})[0-9]{3}$/', $postcode );
break;
case 'ES' :
case 'FR' :
case 'ES':
case 'FR':
$valid = (bool) preg_match( '/^([0-9]{5})$/i', $postcode );
break;
case 'GB' :
$valid = self::is_GB_postcode( $postcode );
case 'GB':
$valid = self::is_gb_postcode( $postcode );
break;
case 'JP' :
case 'JP':
$valid = (bool) preg_match( '/^([0-9]{3})([-])([0-9]{4})$/', $postcode );
break;
case 'PT' :
case 'PT':
$valid = (bool) preg_match( '/^([0-9]{4})([-])([0-9]{3})$/', $postcode );
break;
case 'US' :
case 'US':
$valid = (bool) preg_match( '/^([0-9]{5})(-[0-9]{4})?$/i', $postcode );
break;
case 'CA' :
// CA Postal codes cannot contain D,F,I,O,Q,U and cannot start with W or Z. https://en.wikipedia.org/wiki/Postal_codes_in_Canada#Number_of_possible_postal_codes
case 'CA':
// CA Postal codes cannot contain D,F,I,O,Q,U and cannot start with W or Z. https://en.wikipedia.org/wiki/Postal_codes_in_Canada#Number_of_possible_postal_codes.
$valid = (bool) preg_match( '/^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])([\ ])?(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/i', $postcode );
break;
case 'PL':
@ -92,7 +90,7 @@ class WC_Validation {
$valid = (bool) preg_match( '/^([0-9]{3})(\s?)([0-9]{2})$/', $postcode );
break;
default :
default:
$valid = true;
break;
}
@ -103,51 +101,50 @@ class WC_Validation {
/**
* Check if is a GB postcode.
*
* @author John Gardner
* @param string $to_check A postcode
* @param string $to_check A postcode.
* @return bool
*/
public static function is_GB_postcode( $to_check ) {
public static function is_gb_postcode( $to_check ) {
// Permitted letters depend upon their position in the postcode.
// https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation
$alpha1 = "[abcdefghijklmnoprstuwyz]"; // Character 1
$alpha2 = "[abcdefghklmnopqrstuvwxy]"; // Character 2
$alpha3 = "[abcdefghjkpstuw]"; // Character 3 == ABCDEFGHJKPSTUW
$alpha4 = "[abehmnprvwxy]"; // Character 4 == ABEHMNPRVWXY
$alpha5 = "[abdefghjlnpqrstuwxyz]"; // Character 5 != CIKMOV
// https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation.
$alpha1 = '[abcdefghijklmnoprstuwyz]'; // Character 1.
$alpha2 = '[abcdefghklmnopqrstuvwxy]'; // Character 2.
$alpha3 = '[abcdefghjkpstuw]'; // Character 3 == ABCDEFGHJKPSTUW.
$alpha4 = '[abehmnprvwxy]'; // Character 4 == ABEHMNPRVWXY.
$alpha5 = '[abdefghjlnpqrstuwxyz]'; // Character 5 != CIKMOV.
$pcexp = array();
// Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
// Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA.
$pcexp[0] = '/^(' . $alpha1 . '{1}' . $alpha2 . '{0,1}[0-9]{1,2})([0-9]{1}' . $alpha5 . '{2})$/';
// Expression for postcodes: ANA NAA
// Expression for postcodes: ANA NAA.
$pcexp[1] = '/^(' . $alpha1 . '{1}[0-9]{1}' . $alpha3 . '{1})([0-9]{1}' . $alpha5 . '{2})$/';
// Expression for postcodes: AANA NAA
// Expression for postcodes: AANA NAA.
$pcexp[2] = '/^(' . $alpha1 . '{1}' . $alpha2 . '[0-9]{1}' . $alpha4 . ')([0-9]{1}' . $alpha5 . '{2})$/';
// Exception for the special postcode GIR 0AA
// Exception for the special postcode GIR 0AA.
$pcexp[3] = '/^(gir)(0aa)$/';
// Standard BFPO numbers
// Standard BFPO numbers.
$pcexp[4] = '/^(bfpo)([0-9]{1,4})$/';
// c/o BFPO numbers
// c/o BFPO numbers.
$pcexp[5] = '/^(bfpo)(c\/o[0-9]{1,3})$/';
// Load up the string to check, converting into lowercase and removing spaces
// Load up the string to check, converting into lowercase and removing spaces.
$postcode = strtolower( $to_check );
$postcode = str_replace( ' ', '', $postcode );
// Assume we are not going to find a valid postcode
// Assume we are not going to find a valid postcode.
$valid = false;
// Check the string against the six types of postcodes
// Check the string against the six types of postcodes.
foreach ( $pcexp as $regexp ) {
if ( preg_match( $regexp, $postcode, $matches ) ) {
// Remember that we have found that the code is valid and break from loop
// Remember that we have found that the code is valid and break from loop.
$valid = true;
break;
}
@ -159,18 +156,18 @@ class WC_Validation {
/**
* Format the postcode according to the country and length of the postcode.
*
* @param string $postcode Postcode to format.
* @param string $country Country to format the postcode for.
* @return string Formatted postcode.
* @param string $postcode Postcode to format.
* @param string $country Country to format the postcode for.
* @return string Formatted postcode.
*/
public static function format_postcode( $postcode, $country ) {
return wc_format_postcode( $postcode, $country );
}
/**
* format_phone function.
* Format a given phone number.
*
* @param mixed $tel Phone number to format.
* @param mixed $tel Phone number to format.
* @return string
*/
public static function format_phone( $tel ) {

View File

@ -8,14 +8,10 @@
*
* @version 3.2.0
* @package WooCommerce/Webhooks
* @category Webhooks
* @since 2.2.0
* @author Automattic
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
defined( 'ABSPATH' ) || exit;
require_once 'legacy/class-wc-legacy-webhook.php';
@ -168,7 +164,7 @@ class WC_Webhook extends WC_Legacy_Webhook {
} elseif ( 'updated' === $this->get_event() && $resource_created ) {
$should_deliver = false;
}
} // End if().
}
/*
* Let other plugins intercept deliver for some messages queue like rabbit/zeromq.

View File

@ -2,8 +2,8 @@
/**
* WooCommerce setup
*
* @package WooCommerce
* @since 3.2.0
* @package WooCommerce
* @since 3.2.0
*/
defined( 'ABSPATH' ) || exit;

View File

@ -1,21 +1,18 @@
<?php
/**
* Class WC_Data_Store_WP file.
*
* @package WooCommerce\DataStores
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Shared logic for WP based data.
* Contains functions like meta handling for all default data stores.
* Your own data store doesn't need to use WC_Data_Store_WP -- you can write
* your own meta handling functions.
*
* @version 3.0.0
* @version 3.0.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Data_Store_WP class.
*/
class WC_Data_Store_WP {
@ -171,7 +168,6 @@ class WC_Data_Store_WP {
* @since 2.6.0
*
* @param string $key Prefix to be added to meta keys.
*
* @return string
*/
protected function prefix_key( $key ) {
@ -383,7 +379,6 @@ class WC_Data_Store_WP {
'compare' => $operator,
);
break;
case '<':
case '>=':
$wp_query_args['meta_query'][] = array(
@ -392,7 +387,6 @@ class WC_Data_Store_WP {
'compare' => $operator,
);
break;
default:
$wp_query_args['meta_query'][] = array(
'key' => $key,
@ -438,4 +432,61 @@ class WC_Data_Store_WP {
public function get_internal_meta_keys() {
return $this->internal_meta_keys;
}
/**
* Check if the terms are suitable for searching.
*
* Uses an array of stopwords (terms) that are excluded from the separate
* term matching when searching for posts. The list of English stopwords is
* the approximate search engines list, and is translatable.
*
* @since 3.4.0
* @param array $terms Terms to check.
* @return array Terms that are not stopwords.
*/
protected function get_valid_search_terms( $terms ) {
$valid_terms = array();
$stopwords = $this->get_search_stopwords();
foreach ( $terms as $term ) {
// keep before/after spaces when term is for exact match, otherwise trim quotes and spaces.
if ( preg_match( '/^".+"$/', $term ) ) {
$term = trim( $term, "\"'" );
} else {
$term = trim( $term, "\"' " );
}
// Avoid single A-Z and single dashes.
if ( empty( $term ) || ( 1 === strlen( $term ) && preg_match( '/^[a-z\-]$/i', $term ) ) ) {
continue;
}
if ( in_array( wc_strtolower( $term ), $stopwords, true ) ) {
continue;
}
$valid_terms[] = $term;
}
return $valid_terms;
}
/**
* Retrieve stopwords used when parsing search terms.
*
* @since 3.4.0
* @return array Stopwords.
*/
protected function get_search_stopwords() {
// Translators: This is a comma-separated list of very common words that should be excluded from a search, like a, an, and the. These are usually called "stopwords". You should not simply translate these individual words into your language. Instead, look for and provide commonly accepted stopwords in your language.
$stopwords = array_map( 'wc_strtolower', array_map( 'trim', explode(
',', _x(
'about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www',
'Comma-separated list of search stopwords in your language',
'woocommerce'
)
) ) );
return apply_filters( 'wp_search_stopwords', $stopwords );
}
}

View File

@ -27,6 +27,7 @@ class WC_Order_Refund_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT im
'_cart_discount',
'_refund_amount',
'_refunded_by',
'_refunded_payment',
'_refund_reason',
'_cart_discount_tax',
'_order_shipping',
@ -68,9 +69,10 @@ class WC_Order_Refund_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT im
$id = $refund->get_id();
$refund->set_props(
array(
'amount' => get_post_meta( $id, '_refund_amount', true ),
'refunded_by' => metadata_exists( 'post', $id, '_refunded_by' ) ? get_post_meta( $id, '_refunded_by', true ) : absint( $post_object->post_author ),
'reason' => metadata_exists( 'post', $id, '_refund_reason' ) ? get_post_meta( $id, '_refund_reason', true ) : $post_object->post_excerpt,
'amount' => get_post_meta( $id, '_refund_amount', true ),
'refunded_by' => metadata_exists( 'post', $id, '_refunded_by' ) ? get_post_meta( $id, '_refunded_by', true ) : absint( $post_object->post_author ),
'refunded_payment' => wc_string_to_bool( get_post_meta( $id, '_refunded_payment', true ) ),
'reason' => metadata_exists( 'post', $id, '_refund_reason' ) ? get_post_meta( $id, '_refund_reason', true ): $post_object->post_excerpt,
)
);
}
@ -86,9 +88,10 @@ class WC_Order_Refund_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT im
$updated_props = array();
$meta_key_to_props = array(
'_refund_amount' => 'amount',
'_refunded_by' => 'refunded_by',
'_refund_reason' => 'reason',
'_refund_amount' => 'amount',
'_refunded_by' => 'refunded_by',
'_refunded_payment' => 'refunded_payment',
'_refund_reason' => 'reason',
);
$props_to_update = $this->get_props_to_update( $refund, $meta_key_to_props );

View File

@ -700,6 +700,8 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
foreach ( $attributes as $attribute_key => $attribute ) {
$value = '';
delete_transient( 'wc_layered_nav_counts_' . $attribute_key );
if ( is_null( $attribute ) ) {
if ( taxonomy_exists( $attribute_key ) ) {
// Handle attributes that have been unset.
@ -725,7 +727,6 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
}
}
update_post_meta( $product->get_id(), '_product_attributes', $meta_values );
delete_transient( 'wc_layered_nav_counts' );
}
}
@ -1326,18 +1327,58 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
public function search_products( $term, $type = '', $include_variations = false, $all_statuses = false ) {
global $wpdb;
$like_term = '%' . $wpdb->esc_like( $term ) . '%';
$post_types = $include_variations ? array( 'product', 'product_variation' ) : array( 'product' );
$post_statuses = current_user_can( 'edit_private_products' ) ? array( 'private', 'publish' ) : array( 'publish' );
$type_join = '';
$type_where = '';
$status_where = '';
$term = wc_strtolower( $term );
if ( $type ) {
if ( in_array( $type, array( 'virtual', 'downloadable' ), true ) ) {
$type_join = " LEFT JOIN {$wpdb->postmeta} postmeta_type ON posts.ID = postmeta_type.post_id ";
$type_where = " AND ( postmeta_type.meta_key = '_{$type}' AND postmeta_type.meta_value = 'yes' ) ";
// See if search term contains OR keywords.
if ( strstr( $term, ' or ' ) ) {
$term_groups = explode( ' or ', $term );
} else {
$term_groups = array( $term );
}
$search_where = '';
$search_queries = array();
foreach ( $term_groups as $term_group ) {
// Parse search terms.
if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $term_group, $matches ) ) {
$search_terms = $this->get_valid_search_terms( $matches[0] );
$count = count( $search_terms );
// if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence.
if ( 9 < $count || 0 === $count ) {
$search_terms = array( $term_group );
}
} else {
$search_terms = array( $term_group );
}
$term_group_query = '';
$searchand = '';
foreach ( $search_terms as $search_term ) {
$like = '%' . $wpdb->esc_like( $search_term ) . '%';
$term_group_query .= $wpdb->prepare( " {$searchand} ( ( posts.post_title LIKE %s) OR ( posts.post_excerpt LIKE %s) OR ( posts.post_content LIKE %s ) OR ( postmeta.meta_key = '_sku' AND postmeta.meta_value LIKE %s ) )", $like, $like, $like, $like ); // @codingStandardsIgnoreLine.
$searchand = ' AND ';
}
if ( $term_group_query ) {
$search_queries[] = $term_group_query;
}
}
if ( $search_queries ) {
$search_where = 'AND (' . implode( ') OR (', $search_queries ) . ')';
}
if ( $type && in_array( $type, array( 'virtual', 'downloadable' ), true ) ) {
$type_join = " LEFT JOIN {$wpdb->postmeta} postmeta_type ON posts.ID = postmeta_type.post_id ";
$type_where = " AND ( postmeta_type.meta_key = '_{$type}' AND postmeta_type.meta_value = 'yes' ) ";
}
if ( ! $all_statuses ) {
@ -1347,25 +1388,14 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
// phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
$search_results = $wpdb->get_results(
// phpcs:disable
$wpdb->prepare(
"SELECT DISTINCT posts.ID as product_id, posts.post_parent as parent_id FROM {$wpdb->posts} posts
LEFT JOIN {$wpdb->postmeta} postmeta ON posts.ID = postmeta.post_id
$type_join
WHERE (
posts.post_title LIKE %s
OR posts.post_content LIKE %s
OR (
postmeta.meta_key = '_sku' AND postmeta.meta_value LIKE %s
)
)
AND posts.post_type IN ('" . implode( "','", $post_types ) . "')
$status_where
$type_where
ORDER BY posts.post_parent ASC, posts.post_title ASC",
$like_term,
$like_term,
$like_term
)
"SELECT DISTINCT posts.ID as product_id, posts.post_parent as parent_id FROM {$wpdb->posts} posts
LEFT JOIN {$wpdb->postmeta} postmeta ON posts.ID = postmeta.post_id
$type_join
WHERE posts.post_type IN ('" . implode( "','", $post_types ) . "')
$search_where
$status_where
$type_where
ORDER BY posts.post_parent ASC, posts.post_title ASC"
// phpcs:enable
);

View File

@ -197,7 +197,7 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
);
// Empty value indicates that all options for given attribute are available.
if ( in_array( '', $values, true ) || empty( $values ) ) {
if ( in_array( null, $values, true ) || in_array( '', $values, true ) || empty( $values ) ) {
$values = $attribute['is_taxonomy'] ? wc_get_object_terms( $product->get_id(), $attribute['name'], 'slug' ) : wc_get_text_attributes( $attribute['value'] );
// Get custom attributes (non taxonomy) as defined.
} elseif ( ! $attribute['is_taxonomy'] ) {

View File

@ -317,8 +317,9 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
*/
protected function set_product_data( &$product, $data ) {
if ( isset( $data['raw_attributes'] ) ) {
$attributes = array();
$default_attributes = array();
$attributes = array();
$default_attributes = array();
$existing_attributes = $product->get_attributes();
foreach ( $data['raw_attributes'] as $position => $attribute ) {
$attribute_id = 0;
@ -335,12 +336,22 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
$is_visible = 1;
}
// Set if is a variation attribute.
// Get name.
$attribute_name = $attribute_id ? wc_attribute_taxonomy_name_by_id( $attribute_id ) : $attribute['name'];
// Set if is a variation attribute based on existing attributes if possible so updates via CSV do not change this.
$is_variation = 0;
if ( $attribute_id ) {
$attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id );
if ( $existing_attributes ) {
foreach ( $existing_attributes as $existing_attribute ) {
if ( $existing_attribute->get_name() === $attribute_name ) {
$is_variation = $existing_attribute->get_variation();
break;
}
}
}
if ( $attribute_id ) {
if ( isset( $attribute['value'] ) ) {
$options = array_map( 'wc_sanitize_term_text_based', $attribute['value'] );
$options = array_filter( $options, 'strlen' );

View File

@ -66,10 +66,11 @@ class WC_Shortcode_Cart {
// Constants.
wc_maybe_define_constant( 'WOOCOMMERCE_CART', true );
$atts = shortcode_atts( array(), $atts, 'woocommerce_cart' );
$atts = shortcode_atts( array(), $atts, 'woocommerce_cart' );
$nonce_value = wc_get_var( $_REQUEST['woocommerce-shipping-calculator-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
// Update Shipping.
if ( ! empty( $_POST['calc_shipping'] ) && ! empty( $_POST['_wpnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wpnonce'] ) ), 'woocommerce-cart' ) ) { // WPCS: input var ok.
// Update Shipping. Nonce check uses new value and old value (woocommerce-cart). @todo remove in 4.0.
if ( ! empty( $_POST['calc_shipping'] ) && ( wp_verify_nonce( $nonce_value, 'woocommerce-shipping-calculator' ) || wp_verify_nonce( $nonce_value, 'woocommerce-cart' ) ) ) { // WPCS: input var ok.
self::calculate_shipping();
// Also calc totals before we check items so subtotals etc are up to date.

View File

@ -36,9 +36,10 @@ class WC_Shortcode_Order_Tracking {
return;
}
$atts = shortcode_atts( array(), $atts, 'woocommerce_order_tracking' );
$atts = shortcode_atts( array(), $atts, 'woocommerce_order_tracking' );
$nonce_value = wc_get_var( $_REQUEST['woocommerce-order-tracking-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( isset( $_REQUEST['orderid'], $_POST['_wpnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wpnonce'] ) ), 'woocommerce-order_tracking' ) ) { // WPCS: input var ok.
if ( isset( $_REQUEST['orderid'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-order_tracking' ) ) { // WPCS: input var ok.
$order_id = empty( $_REQUEST['orderid'] ) ? 0 : ltrim( wc_clean( wp_unslash( $_REQUEST['orderid'] ) ), '#' ); // WPCS: input var ok.
$order_email = empty( $_REQUEST['order_email'] ) ? '' : sanitize_email( wp_unslash( $_REQUEST['order_email'] ) ); // WPCS: input var ok.

View File

@ -113,7 +113,7 @@ class WC_Shortcode_Products {
$attributes = shortcode_atts(
array(
'limit' => '-1', // Results limit.
'columns' => '3', // Number of columns.
'columns' => '', // Number of columns.
'rows' => '', // Number of rows. If defined, limit will be ignored.
'orderby' => 'title', // menu_order, title, date, rand, price, popularity, rating, or id.
'order' => 'ASC', // ASC or DESC.
@ -134,7 +134,7 @@ class WC_Shortcode_Products {
);
if ( ! absint( $attributes['columns'] ) ) {
$attributes['columns'] = 3;
$attributes['columns'] = wc_get_default_products_per_row();
}
return $attributes;

View File

@ -4,8 +4,6 @@
*
* Functions for determining the current query/page.
*
* @author WooThemes
* @category Core
* @package WooCommerce/Functions
* @version 2.3.0
*/
@ -128,7 +126,7 @@ if ( ! function_exists( 'is_wc_endpoint_url' ) ) {
/**
* Is_wc_endpoint_url - Check if an endpoint is showing.
*
* @param string $endpoint Whether endpoint.
* @param string|false $endpoint Whether endpoint.
* @return bool
*/
function is_wc_endpoint_url( $endpoint = false ) {
@ -272,7 +270,7 @@ if ( ! function_exists( 'is_filtered' ) ) {
* @return bool
*/
function is_filtered() {
return apply_filters( 'woocommerce_is_filtered', ( count( WC_Query::get_layered_nav_chosen_attributes() ) > 0 || isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) || isset( $_GET['rating_filter'] ) ) );
return apply_filters( 'woocommerce_is_filtered', ( count( WC_Query::get_layered_nav_chosen_attributes() ) > 0 || isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) || isset( $_GET['rating_filter'] ) ) ); // WPCS: CSRF ok.
}
}
@ -308,7 +306,7 @@ if ( ! function_exists( 'meta_is_product_attribute' ) ) {
if ( $product && method_exists( $product, 'get_variation_attributes' ) ) {
$variation_attributes = $product->get_variation_attributes();
$attributes = $product->get_attributes();
return ( in_array( $name, array_keys( $attributes ) ) && in_array( $value, $variation_attributes[ $attributes[ $name ]['name'] ] ) );
return ( in_array( $name, array_keys( $attributes ), true ) && in_array( $value, $variation_attributes[ $attributes[ $name ]['name'] ], true ) );
} else {
return false;
}

View File

@ -571,6 +571,9 @@ function wc_create_refund( $args = array() ) {
$refund->delete();
return $result;
}
$refund->set_refunded_payment( true );
$refund->save();
}
if ( $args['restock_items'] ) {

View File

@ -982,7 +982,6 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
if ( ! wc_get_loop_prop( 'is_paginated' ) || ! woocommerce_products_will_display() ) {
return;
}
$orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); // WPCS: sanitization ok, input var ok, CSRF ok.
$show_default_orderby = 'menu_order' === apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
$catalog_orderby_options = apply_filters( 'woocommerce_catalog_orderby', array(
'menu_order' => __( 'Default sorting', 'woocommerce' ),
@ -993,12 +992,13 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
'price-desc' => __( 'Sort by price: high to low', 'woocommerce' ),
) );
$default_orderby = wc_get_loop_prop( 'is_search' ) ? 'relevance' : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby', '' ) );
$orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : $default_orderby; // WPCS: sanitization ok, input var ok, CSRF ok.
if ( wc_get_loop_prop( 'is_search' ) ) {
$catalog_orderby_options = array_merge( array( 'relevance' => __( 'Relevance', 'woocommerce' ) ), $catalog_orderby_options );
unset( $catalog_orderby_options['menu_order'] );
if ( 'menu_order' === $orderby ) {
$orderby = 'relevance';
}
}
if ( ! $show_default_orderby ) {
@ -1009,6 +1009,10 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
unset( $catalog_orderby_options['rating'] );
}
if ( ! array_key_exists( $orderby, $catalog_orderby_options ) ) {
$orderby = current( array_keys( $catalog_orderby_options ) );
}
wc_get_template( 'loop/orderby.php', array(
'catalog_orderby_options' => $catalog_orderby_options,
'orderby' => $orderby,
@ -1995,7 +1999,7 @@ if ( ! function_exists( 'woocommerce_get_product_subcategories' ) ) {
*/
function woocommerce_get_product_subcategories( $parent_id = 0 ) {
$parent_id = absint( $parent_id );
$product_categories = wp_cache_get( 'product-categories-' . $parent_id, 'product_cat' );
$product_categories = wp_cache_get( 'product-category-hierarchy-' . $parent_id, 'product_cat' );
if ( false === $product_categories ) {
// NOTE: using child_of instead of parent - this is not ideal but due to a WP bug ( https://core.trac.wordpress.org/ticket/15626 ) pad_counts won't work.
@ -2007,7 +2011,8 @@ if ( ! function_exists( 'woocommerce_get_product_subcategories' ) ) {
'taxonomy' => 'product_cat',
'pad_counts' => 1,
) ) );
wp_cache_set( 'product-categories-' . $parent_id, $product_categories, 'product_cat' );
wp_cache_set( 'product-category-hierarchy-' . $parent_id, $product_categories, 'product_cat' );
}
if ( apply_filters( 'woocommerce_product_subcategories_hide_empty', true ) ) {

View File

@ -369,13 +369,22 @@ class WC_Widget_Layered_Nav extends WC_Widget {
// We have a query - let's see if cached results of this query already exist.
$query_hash = md5( $query );
$cached_counts = (array) get_transient( 'wc_layered_nav_counts' );
// Maybe store a transient of the count values.
$cache = apply_filters( 'woocommerce_layered_nav_count_maybe_cache', true );
if ( true === $cache ) {
$cached_counts = (array) get_transient( 'wc_layered_nav_counts_' . $taxonomy );
} else {
$cached_counts = array();
}
if ( ! isset( $cached_counts[ $query_hash ] ) ) {
$results = $wpdb->get_results( $query, ARRAY_A ); // @codingStandardsIgnoreLine
$counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) );
$cached_counts[ $query_hash ] = $counts;
set_transient( 'wc_layered_nav_counts', $cached_counts, DAY_IN_SECONDS );
if ( true === $cache ) {
set_transient( 'wc_layered_nav_counts_' . $taxonomy, $cached_counts, DAY_IN_SECONDS );
}
}
return array_map( 'absint', (array) $cached_counts[ $query_hash ] );

45
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "woocommerce",
"version": "3.1.0",
"version": "3.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -1334,9 +1334,9 @@
}
},
"chromedriver": {
"version": "2.33.2",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.33.2.tgz",
"integrity": "sha512-etnQeM8Mqiys50ZB4IiuNqeB1WS2/EKFhVXwkPQ1qjzKMMAJUyrLjaRUcoZoHrbjGscnhBrWkRR+p3zcTGMhDg==",
"version": "2.36.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.36.0.tgz",
"integrity": "sha512-Lq2HrigCJ4RVdIdCmchenv1rVrejNSJ7EUCQojycQo12ww3FedQx4nb+GgTdqMhjbOMTqq5+ziaiZlrEN2z1gQ==",
"dev": true,
"requires": {
"del": "3.0.0",
@ -6032,9 +6032,9 @@
"dev": true
},
"url-join": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.2.tgz",
"integrity": "sha1-wHJ1aWetJLi1nldBVRyqx49QuLc=",
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz",
"integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=",
"dev": true
},
"user-home": {
@ -6086,9 +6086,9 @@
}
},
"wc-e2e-page-objects": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/wc-e2e-page-objects/-/wc-e2e-page-objects-0.5.0.tgz",
"integrity": "sha1-7oAQnDRqn9HE4NUbi7h/oeHDcMs=",
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/wc-e2e-page-objects/-/wc-e2e-page-objects-0.9.0.tgz",
"integrity": "sha512-oGOLFAN+lNULLylZkhNIMGT0n5hO+elpcVkpNQcT4HgWfS1yPoGfeWgrfAX33b4ZGVlpViv78Fj3LM5TciXVHw==",
"dev": true,
"requires": {
"lodash": "4.17.4",
@ -6174,7 +6174,22 @@
"selenium-webdriver": "3.6.0",
"slugs": "0.1.3",
"temp": "0.8.3",
"url-join": "2.0.2"
"url-join": "2.0.5"
},
"dependencies": {
"chromedriver": {
"version": "2.33.2",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.33.2.tgz",
"integrity": "sha512-etnQeM8Mqiys50ZB4IiuNqeB1WS2/EKFhVXwkPQ1qjzKMMAJUyrLjaRUcoZoHrbjGscnhBrWkRR+p3zcTGMhDg==",
"dev": true,
"requires": {
"del": "3.0.0",
"extract-zip": "1.6.6",
"kew": "0.7.0",
"mkdirp": "0.5.1",
"request": "2.83.0"
}
}
}
},
"wrap-ansi": {
@ -6209,13 +6224,13 @@
"dev": true,
"requires": {
"sax": "1.2.4",
"xmlbuilder": "9.0.4"
"xmlbuilder": "9.0.7"
}
},
"xmlbuilder": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz",
"integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=",
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
"dev": true
},
"xtend": {

View File

@ -26,7 +26,7 @@
"babel-preset-stage-2": "^6.13.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"chromedriver": "^2.33.0",
"chromedriver": "^2.36.0",
"config": "^1.24.0",
"cross-env": "~5.1.1",
"grunt": "~1.0.1",

View File

@ -25,6 +25,8 @@
<!-- Rules -->
<rule ref="WooCommerce-Core" />
<rule ref="PHPCompatibility">
<exclude name="PHPCompatibility.PHP.NewFunctions.hash_equalsFound" />
<exclude name="PHPCompatibility.PHP.NewInterfaces.jsonserializableFound" />
<exclude name="PHPCompatibility.PHP.NewKeywords.t_namespaceFound" />
<exclude-pattern>tests/</exclude-pattern>
</rule>
@ -38,10 +40,11 @@
<exclude name="WordPress.VIP.RestrictedFunctions" />
<exclude name="WordPress.VIP.RestrictedVariables.user_meta__wpdb__usermeta" />
<exclude name="WordPress.VIP.PostsPerPage.posts_per_page_posts_per_page" />
<exclude name="WordPress.VIP.RestrictedVariables.cache_constraints___COOKIE" />
</rule>
<rule ref="WordPress.VIP.ValidatedSanitizedInput">
<properties>
<property name="customSanitizingFunctions" type="array" value="wc_clean,wc_sanitize_tooltip,wc_format_decimal,wc_stock_amount,wc_sanitize_permalink" />
<property name="customSanitizingFunctions" type="array" value="wc_clean,wc_sanitize_tooltip,wc_format_decimal,wc_stock_amount,wc_sanitize_permalink,wc_sanitize_textarea" />
</properties>
</rule>
<rule ref="WordPress.XSS.EscapeOutput">

View File

@ -12,16 +12,12 @@
*
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates/Auth
* @version 3.3.0
* @version 3.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
?>
<?php do_action( 'woocommerce_auth_page_header' ); ?>
do_action( 'woocommerce_auth_page_header' ); ?>
<h1>
<?php
@ -49,7 +45,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input class="input-text" type="password" name="password" id="password" />
</p>
<p class="wc-auth-actions">
<?php wp_nonce_field( 'woocommerce-login' ); ?>
<?php wp_nonce_field( 'woocommerce-login', 'woocommerce-login-nonce' ); ?>
<button type="submit" class="button button-large button-primary wc-auth-login-button" name="login" value="<?php esc_attr_e( 'Login', 'woocommerce' ); ?>"><?php esc_html_e( 'Login', 'woocommerce' ); ?></button>
<input type="hidden" name="redirect" value="<?php echo esc_url( $redirect_url ); ?>" />
</p>

View File

@ -11,14 +11,11 @@
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 3.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
wc_print_notices();
@ -64,57 +61,63 @@ do_action( 'woocommerce_before_cart' ); ?>
?>
</td>
<td class="product-thumbnail"><?php
<td class="product-thumbnail">
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $product_permalink ) {
echo $thumbnail;
echo wp_kses_post( $thumbnail );
} else {
printf( '<a href="%s">%s</a>', esc_url( $product_permalink ), $thumbnail );
printf( '<a href="%s">%s</a>', esc_url( $product_permalink ), wp_kses_post( $thumbnail ) );
}
?></td>
?>
</td>
<td class="product-name" data-title="<?php esc_attr_e( 'Product', 'woocommerce' ); ?>"><?php
<td class="product-name" data-title="<?php esc_attr_e( 'Product', 'woocommerce' ); ?>">
<?php
if ( ! $product_permalink ) {
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) . '&nbsp;';
echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) . '&nbsp;' );
} else {
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '<a href="%s">%s</a>', esc_url( $product_permalink ), $_product->get_name() ), $cart_item, $cart_item_key );
echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', sprintf( '<a href="%s">%s</a>', esc_url( $product_permalink ), $_product->get_name() ), $cart_item, $cart_item_key ) );
}
// Meta data.
echo wc_get_formatted_cart_item_data( $cart_item );
echo wc_get_formatted_cart_item_data( $cart_item ); // PHPCS: XSS ok.
// Backorder notification.
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>';
}
?></td>
?>
</td>
<td class="product-price" data-title="<?php esc_attr_e( 'Price', 'woocommerce' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key ); // PHPCS: XSS ok.
?>
</td>
<td class="product-quantity" data-title="<?php esc_attr_e( 'Quantity', 'woocommerce' ); ?>"><?php
<td class="product-quantity" data-title="<?php esc_attr_e( 'Quantity', 'woocommerce' ); ?>">
<?php
if ( $_product->is_sold_individually() ) {
$product_quantity = sprintf( '1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key );
} else {
$product_quantity = woocommerce_quantity_input( array(
'input_name' => "cart[{$cart_item_key}][qty]",
'input_value' => $cart_item['quantity'],
'max_value' => $_product->get_max_purchase_quantity(),
'min_value' => '0',
'product_name' => $_product->get_name(),
'input_name' => "cart[{$cart_item_key}][qty]",
'input_value' => $cart_item['quantity'],
'max_value' => $_product->get_max_purchase_quantity(),
'min_value' => '0',
'product_name' => $_product->get_name(),
), $_product, false );
}
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item );
?></td>
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item ); // PHPCS: XSS ok.
?>
</td>
<td class="product-subtotal" data-title="<?php esc_attr_e( 'Total', 'woocommerce' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key );
echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // PHPCS: XSS ok.
?>
</td>
</tr>
@ -139,7 +142,7 @@ do_action( 'woocommerce_before_cart' ); ?>
<?php do_action( 'woocommerce_cart_actions' ); ?>
<?php wp_nonce_field( 'woocommerce-cart' ); ?>
<?php wp_nonce_field( 'woocommerce-cart', 'woocommerce-cart-nonce' ); ?>
</td>
</tr>

View File

@ -10,15 +10,12 @@
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 3.2.0
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates
* @version 3.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
if ( 'no' === get_option( 'woocommerce_enable_shipping_calc' ) || ! WC()->cart->needs_shipping() ) {
return;
@ -54,9 +51,12 @@ do_action( 'woocommerce_before_shipping_calculator' ); ?>
$states = WC()->countries->get_states( $current_cc );
if ( is_array( $states ) && empty( $states ) ) {
?><input type="hidden" name="calc_shipping_state" id="calc_shipping_state" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>" /><?php
?>
<input type="hidden" name="calc_shipping_state" id="calc_shipping_state" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>" />
<?php
} elseif ( is_array( $states ) ) {
?><span>
?>
<span>
<select name="calc_shipping_state" class="state_select" id="calc_shipping_state" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>">
<option value=""><?php esc_html_e( 'Select a state&hellip;', 'woocommerce' ); ?></option>
<?php
@ -65,9 +65,12 @@ do_action( 'woocommerce_before_shipping_calculator' ); ?>
}
?>
</select>
</span><?php
</span>
<?php
} else {
?><input type="text" class="input-text" value="<?php echo esc_attr( $current_r ); ?>" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>" name="calc_shipping_state" id="calc_shipping_state" /><?php
?>
<input type="text" class="input-text" value="<?php echo esc_attr( $current_r ); ?>" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>" name="calc_shipping_state" id="calc_shipping_state" />
<?php
}
?>
</p>
@ -92,7 +95,7 @@ do_action( 'woocommerce_before_shipping_calculator' ); ?>
<p><button type="submit" name="calc_shipping" value="1" class="button"><?php esc_html_e( 'Update totals', 'woocommerce' ); ?></button></p>
<?php wp_nonce_field( 'woocommerce-cart' ); ?>
<?php wp_nonce_field( 'woocommerce-shipping-calculator', 'woocommerce-shipping-calculator-nonce' ); ?>
</section>
</form>

View File

@ -10,16 +10,14 @@
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 3.3.0
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates
* @version 3.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
$totals = $order->get_order_item_totals();
?>
<form id="order_review" method="post">
@ -58,7 +56,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php endif; ?>
</tbody>
<tfoot>
<?php if ( $totals = $order->get_order_item_totals() ) : ?>
<?php if ( $totals ) : ?>
<?php foreach ( $totals as $total ) : ?>
<tr>
<th scope="row" colspan="2"><?php echo $total['label']; ?></th><?php // @codingStandardsIgnoreLine ?>
@ -94,7 +92,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php do_action( 'woocommerce_pay_order_after_submit' ); ?>
<?php wp_nonce_field( 'woocommerce-pay' ); ?>
<?php wp_nonce_field( 'woocommerce-pay', 'woocommerce-pay-nonce' ); ?>
</div>
</div>
</form>

View File

@ -10,15 +10,12 @@
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 3.3.0
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates
* @version 3.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
if ( ! is_ajax() ) {
do_action( 'woocommerce_review_order_before_payment' );
@ -52,7 +49,7 @@ if ( ! is_ajax() ) {
<?php do_action( 'woocommerce_review_order_after_submit' ); ?>
<?php wp_nonce_field( 'woocommerce-process_checkout' ); ?>
<?php wp_nonce_field( 'woocommerce-process_checkout', 'woocommerce-process-checkout-nonce' ); ?>
</div>
</div>
<?php

View File

@ -10,17 +10,16 @@
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates
* @version 3.3.0
* @version 3.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
if ( $available_gateways = WC()->payment_gateways->get_available_payment_gateways() ) : ?>
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
if ( $available_gateways ) : ?>
<form id="add_payment_method" method="post">
<div id="payment" class="woocommerce-Payment">
<ul class="woocommerce-PaymentMethods payment_methods methods">
@ -49,7 +48,7 @@ if ( $available_gateways = WC()->payment_gateways->get_available_payment_gateway
</ul>
<div class="form-row">
<?php wp_nonce_field( 'woocommerce-add-payment-method' ); ?>
<?php wp_nonce_field( 'woocommerce-add-payment-method', 'woocommerce-add-payment-method-nonce' ); ?>
<button type="submit" class="woocommerce-Button woocommerce-Button--alt button alt" id="place_order" value="<?php esc_attr_e( 'Add payment method', 'woocommerce' ); ?>"><?php esc_html_e( 'Add payment method', 'woocommerce' ); ?></button>
<input type="hidden" name="woocommerce_add_payment_method" id="woocommerce_add_payment_method" value="1" />
</div>

View File

@ -10,15 +10,12 @@
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates
* @version 3.3.0
* @version 3.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
defined( 'ABSPATH' ) || exit;
do_action( 'woocommerce_before_edit_account_form' ); ?>
@ -68,7 +65,7 @@ do_action( 'woocommerce_before_edit_account_form' ); ?>
<?php do_action( 'woocommerce_edit_account_form' ); ?>
<p>
<?php wp_nonce_field( 'save_account_details' ); ?>
<?php wp_nonce_field( 'save_account_details', 'save-account-details-nonce' ); ?>
<button type="submit" class="woocommerce-Button button" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>"><?php esc_html_e( 'Save changes', 'woocommerce' ); ?></button>
<input type="hidden" name="action" value="save_account_details" />
</p>

Some files were not shown because too many files have changed in this diff Show More