Merge branch 'master' into update/19345
This commit is contained in:
commit
fb8b670cda
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
|
@ -13,6 +13,9 @@ body {
|
||||||
max-width: 30%;
|
max-width: 30%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.wc-setup {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
.wc-setup-content {
|
.wc-setup-content {
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
|
@ -20,6 +23,7 @@ body {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
zoom: 1;
|
zoom: 1;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
h1, h2, h3, table {
|
h1, h2, h3, table {
|
||||||
margin: 0 0 20px;
|
margin: 0 0 20px;
|
||||||
|
@ -297,7 +301,6 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.woocommerce-newsletter,
|
.woocommerce-newsletter,
|
||||||
.woocommerce-tracker,
|
|
||||||
.updated {
|
.updated {
|
||||||
padding: 24px 24px 0;
|
padding: 24px 24px 0;
|
||||||
margin: 0 0 24px;
|
margin: 0 0 24px;
|
||||||
|
@ -312,9 +315,74 @@ body {
|
||||||
margin: 0 0 24px;
|
margin: 0 0 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.woocommerce-tracker + .woocommerce-newsletter {
|
.woocommerce-tracker {
|
||||||
margin-top: -24px;
|
margin: 24px 0;
|
||||||
border-top: 2px dashed #ddd;
|
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 {
|
.wc-setup-steps {
|
||||||
|
@ -417,8 +485,8 @@ body {
|
||||||
.wc-setup-footer-links {
|
.wc-setup-footer-links {
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
color: #b5b5b5;
|
color: #b5b5b5;
|
||||||
margin: 1.18em 0;
|
margin: 1.18em auto;
|
||||||
display: block;
|
display: inline-block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,11 +896,21 @@ h3.jetpack-reasons {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jetpack-logo {
|
.jetpack-logo, .wcs-notice {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 1.75em auto 2em auto;
|
margin: 1.75em auto 2em auto;
|
||||||
max-height: 175px;
|
max-height: 175px;
|
||||||
}
|
}
|
||||||
|
.activate-splash {
|
||||||
|
.jetpack-logo {
|
||||||
|
width: 170px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.wcs-notice {
|
||||||
|
margin-top: 1em;
|
||||||
|
padding-left: 57px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.step {
|
.step {
|
||||||
text-align: center;
|
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 {
|
.wc-wizard-service-setting-stripe_create_account, .wc-wizard-service-setting-ppec_paypal_reroute_requests {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
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 |
|
@ -112,9 +112,6 @@ jQuery( function ( $ ) {
|
||||||
|
|
||||||
if ( ! $country_input.val() ) {
|
if ( ! $country_input.val() ) {
|
||||||
$country_input.val( woocommerce_admin_meta_boxes_order.default_country ).change();
|
$country_input.val( woocommerce_admin_meta_boxes_order.default_country ).change();
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! $state_input.val() ) {
|
|
||||||
$state_input.val( woocommerce_admin_meta_boxes_order.default_state ).change();
|
$state_input.val( woocommerce_admin_meta_boxes_order.default_state ).change();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -42,7 +42,7 @@
|
||||||
setTimeout( function() {
|
setTimeout( function() {
|
||||||
$form.trigger( 'check_variations' );
|
$form.trigger( 'check_variations' );
|
||||||
$form.trigger( 'wc_variation_form' );
|
$form.trigger( 'wc_variation_form' );
|
||||||
$form.loading = loading;
|
$form.loading = false;
|
||||||
}, 100 );
|
}, 100 );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5465,12 +5465,11 @@ S2.define('select2/core',[
|
||||||
$(document).on('keydown', function (evt) {
|
$(document).on('keydown', function (evt) {
|
||||||
var key = evt.which;
|
var key = evt.which;
|
||||||
if (self.isOpen()) {
|
if (self.isOpen()) {
|
||||||
if (key === KEYS.ESC || key === KEYS.TAB ||
|
if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) {
|
||||||
(key === KEYS.UP && evt.altKey)) {
|
|
||||||
self.close();
|
self.close();
|
||||||
|
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
} else if (key === KEYS.ENTER) {
|
} else if (key === KEYS.ENTER || key === KEYS.TAB) {
|
||||||
self.trigger('results:select', {});
|
self.trigger('results:select', {});
|
||||||
|
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5465,12 +5465,11 @@ S2.define('select2/core',[
|
||||||
$(document).on('keydown', function (evt) {
|
$(document).on('keydown', function (evt) {
|
||||||
var key = evt.which;
|
var key = evt.which;
|
||||||
if (self.isOpen()) {
|
if (self.isOpen()) {
|
||||||
if (key === KEYS.ESC || key === KEYS.TAB ||
|
if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) {
|
||||||
(key === KEYS.UP && evt.altKey)) {
|
|
||||||
self.close();
|
self.close();
|
||||||
|
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
} else if (key === KEYS.ENTER) {
|
} else if (key === KEYS.ENTER || key === KEYS.TAB) {
|
||||||
self.trigger('results:select', {});
|
self.trigger('results:select', {});
|
||||||
|
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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-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( '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( '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_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), WC_VERSION );
|
||||||
wp_localize_script(
|
wp_localize_script(
|
||||||
'wc-enhanced-select',
|
'wc-enhanced-select',
|
||||||
|
|
|
@ -2,15 +2,10 @@
|
||||||
/**
|
/**
|
||||||
* Init WooCommerce data importers.
|
* Init WooCommerce data importers.
|
||||||
*
|
*
|
||||||
* @author Automattic
|
* @package WooCommerce/Admin
|
||||||
* @category Admin
|
|
||||||
* @package WooCommerce/Admin
|
|
||||||
* @version 3.1.0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WC_Admin_Importers Class.
|
* WC_Admin_Importers Class.
|
||||||
|
@ -111,7 +106,6 @@ class WC_Admin_Importers {
|
||||||
* The tax rate importer which extends WP_Importer.
|
* The tax rate importer which extends WP_Importer.
|
||||||
*/
|
*/
|
||||||
public function tax_rates_importer() {
|
public function tax_rates_importer() {
|
||||||
// Load Importer API
|
|
||||||
require_once ABSPATH . 'wp-admin/includes/import.php';
|
require_once ABSPATH . 'wp-admin/includes/import.php';
|
||||||
|
|
||||||
if ( ! class_exists( 'WP_Importer' ) ) {
|
if ( ! class_exists( 'WP_Importer' ) ) {
|
||||||
|
@ -122,10 +116,8 @@ class WC_Admin_Importers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// includes
|
|
||||||
require dirname( __FILE__ ) . '/importers/class-wc-tax-rate-importer.php';
|
require dirname( __FILE__ ) . '/importers/class-wc-tax-rate-importer.php';
|
||||||
|
|
||||||
// Dispatch
|
|
||||||
$importer = new WC_Tax_Rate_Importer();
|
$importer = new WC_Tax_Rate_Importer();
|
||||||
$importer->dispatch();
|
$importer->dispatch();
|
||||||
}
|
}
|
||||||
|
@ -139,11 +131,11 @@ class WC_Admin_Importers {
|
||||||
public function post_importer_compatibility() {
|
public function post_importer_compatibility() {
|
||||||
global $wpdb;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = absint( $_POST['import_id'] );
|
$id = absint( $_POST['import_id'] ); // PHPCS: input var ok.
|
||||||
$file = get_attached_file( $id );
|
$file = get_attached_file( $id );
|
||||||
$parser = new WXR_Parser();
|
$parser = new WXR_Parser();
|
||||||
$import_data = $parser->parse( $file );
|
$import_data = $parser->parse( $file );
|
||||||
|
@ -156,8 +148,8 @@ class WC_Admin_Importers {
|
||||||
if ( ! taxonomy_exists( $term['domain'] ) ) {
|
if ( ! taxonomy_exists( $term['domain'] ) ) {
|
||||||
$attribute_name = wc_sanitize_taxonomy_name( str_replace( 'pa_', '', $term['domain'] ) );
|
$attribute_name = wc_sanitize_taxonomy_name( str_replace( 'pa_', '', $term['domain'] ) );
|
||||||
|
|
||||||
// Create the taxonomy
|
// Create the taxonomy.
|
||||||
if ( ! in_array( $attribute_name, wc_get_attribute_taxonomies() ) ) {
|
if ( ! in_array( $attribute_name, wc_get_attribute_taxonomies(), true ) ) {
|
||||||
wc_create_attribute(
|
wc_create_attribute(
|
||||||
array(
|
array(
|
||||||
'name' => $attribute_name,
|
'name' => $attribute_name,
|
||||||
|
@ -198,19 +190,19 @@ class WC_Admin_Importers {
|
||||||
|
|
||||||
check_ajax_referer( 'wc-product-import', 'security' );
|
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 );
|
wp_die( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
include_once WC_ABSPATH . 'includes/admin/importers/class-wc-product-csv-importer-controller.php';
|
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';
|
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(
|
$params = array(
|
||||||
'delimiter' => ! empty( $_POST['delimiter'] ) ? wc_clean( $_POST['delimiter'] ) : ',',
|
'delimiter' => ! empty( $_POST['delimiter'] ) ? wc_clean( wp_unslash( $_POST['delimiter'] ) ) : ',', // PHPCS: input var ok.
|
||||||
'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0,
|
'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0, // PHPCS: input var ok.
|
||||||
'mapping' => isset( $_POST['mapping'] ) ? (array) $_POST['mapping'] : array(),
|
'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,
|
'update_existing' => isset( $_POST['update_existing'] ) ? (bool) $_POST['update_existing'] : false, // PHPCS: input var ok.
|
||||||
'lines' => apply_filters( 'woocommerce_product_import_batch_size', 30 ),
|
'lines' => apply_filters( 'woocommerce_product_import_batch_size', 30 ),
|
||||||
'parse' => true,
|
'parse' => true,
|
||||||
);
|
);
|
||||||
|
@ -231,7 +223,7 @@ class WC_Admin_Importers {
|
||||||
|
|
||||||
if ( 100 === $percent_complete ) {
|
if ( 100 === $percent_complete ) {
|
||||||
// Clear temp meta.
|
// Clear temp meta.
|
||||||
$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => '_original_id' ) );
|
$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => '_original_id' ) ); // @codingStandardsIgnoreLine.
|
||||||
$wpdb->query(
|
$wpdb->query(
|
||||||
"DELETE {$wpdb->posts}, {$wpdb->postmeta}, {$wpdb->term_relationships}
|
"DELETE {$wpdb->posts}, {$wpdb->postmeta}, {$wpdb->term_relationships}
|
||||||
FROM {$wpdb->posts}
|
FROM {$wpdb->posts}
|
||||||
|
@ -243,6 +235,14 @@ class WC_Admin_Importers {
|
||||||
AND {$wpdb->posts}.post_status = 'importing'"
|
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.
|
// Send success.
|
||||||
wp_send_json_success(
|
wp_send_json_success(
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -171,12 +171,6 @@ class WC_Admin_Setup_Wizard {
|
||||||
unset( $default_steps['shipping'] );
|
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.
|
// Whether or not there is a pending background install of Jetpack.
|
||||||
$pending_jetpack = ! class_exists( 'Jetpack' ) && get_option( 'woocommerce_setup_background_installing_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.
|
* Output the steps.
|
||||||
*/
|
*/
|
||||||
public function setup_wizard_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">
|
<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 );
|
$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>
|
<li class="active"><?php echo esc_html( $step['name'] ); ?></li>
|
||||||
<?php elseif ( $is_completed ) : ?>
|
<?php
|
||||||
|
} elseif ( $is_completed ) {
|
||||||
|
?>
|
||||||
<li class="done">
|
<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>
|
</li>
|
||||||
<?php else : ?>
|
<?php
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
<li><?php echo esc_html( $step['name'] ); ?></li>
|
<li><?php echo esc_html( $step['name'] ); ?></li>
|
||||||
<?php endif; ?>
|
<?php
|
||||||
<?php endforeach; ?>
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
</ol>
|
</ol>
|
||||||
<?php
|
<?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' ); ?>
|
<?php esc_html_e( 'I will also be selling products or services in person.', 'woocommerce' ); ?>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<?php if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) : ?>
|
<?php
|
||||||
<div class="allow-tracking">
|
if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) {
|
||||||
<input type="checkbox" id="wc_tracker_optin" name="wc_tracker_optin" value="yes" checked />
|
$tracking_opt_out = true;
|
||||||
<label for="wc_tracker_optin"><?php esc_html_e( 'Allow WooCommerce to collect non-sensitive diagnostic data and usage information.', 'woocommerce' ); ?></label>
|
|
||||||
|
// 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 — 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>
|
</div>
|
||||||
<?php endif; ?>
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
<p class="wc-setup-actions step">
|
<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>
|
<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>
|
</p>
|
||||||
|
@ -1675,8 +1709,9 @@ class WC_Admin_Setup_Wizard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function wc_setup_activate_get_description() {
|
protected function wc_setup_activate_get_feature_list() {
|
||||||
$description = false;
|
$features = array();
|
||||||
|
|
||||||
$stripe_settings = get_option( 'woocommerce_stripe_settings', false );
|
$stripe_settings = get_option( 'woocommerce_stripe_settings', false );
|
||||||
$stripe_enabled = is_array( $stripe_settings )
|
$stripe_enabled = is_array( $stripe_settings )
|
||||||
&& isset( $stripe_settings['create_account'] ) && 'yes' === $stripe_settings['create_account']
|
&& 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 )
|
$ppec_enabled = is_array( $ppec_settings )
|
||||||
&& isset( $ppec_settings['reroute_requests'] ) && 'yes' === $ppec_settings['reroute_requests']
|
&& isset( $ppec_settings['reroute_requests'] ) && 'yes' === $ppec_settings['reroute_requests']
|
||||||
&& isset( $ppec_settings['enabled'] ) && 'yes' === $ppec_settings['enabled'];
|
&& isset( $ppec_settings['enabled'] ) && 'yes' === $ppec_settings['enabled'];
|
||||||
$payment_enabled = $stripe_enabled || $ppec_enabled;
|
$features['payment'] = $stripe_enabled || $ppec_enabled;
|
||||||
$taxes_enabled = (bool) get_option( 'woocommerce_setup_automated_taxes', false );
|
|
||||||
|
$features['taxes'] = (bool) get_option( 'woocommerce_setup_automated_taxes', false );
|
||||||
|
|
||||||
$domestic_rates = (bool) get_option( 'woocommerce_setup_domestic_live_rates_zone', 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 );
|
$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 */
|
return $features;
|
||||||
$description_base = __( 'Your store is almost ready! To activate services like %s, just connect with Jetpack.', 'woocommerce' );
|
}
|
||||||
|
|
||||||
if ( $payment_enabled && $taxes_enabled && $rates_enabled ) {
|
protected function wc_setup_activate_get_feature_list_str() {
|
||||||
$description = sprintf( $description_base, __( 'payment setup, automated taxes, live rates and discounted shipping labels', 'woocommerce' ) );
|
$features = $this->wc_setup_activate_get_feature_list();
|
||||||
} else if ( $payment_enabled && $taxes_enabled ) {
|
if ( $features['payment'] && $features['taxes'] && $features['rates'] ) {
|
||||||
$description = sprintf( $description_base, __( 'payment setup and automated taxes', 'woocommerce' ) );
|
return __( 'payment setup, automated taxes, live rates and discounted shipping labels', 'woocommerce' );
|
||||||
} else if ( $payment_enabled && $rates_enabled ) {
|
} else if ( $features['payment'] && $features['taxes'] ) {
|
||||||
$description = sprintf( $description_base, __( 'payment setup, live rates and discounted shipping labels', 'woocommerce' ) );
|
return __( 'payment setup and automated taxes', 'woocommerce' );
|
||||||
} else if ( $payment_enabled ) {
|
} else if ( $features['payment'] && $features['rates'] ) {
|
||||||
$description = sprintf( $description_base, __( 'payment setup', 'woocommerce' ) );
|
return __( 'payment setup, live rates and discounted shipping labels', 'woocommerce' );
|
||||||
} else if ( $taxes_enabled && $rates_enabled ) {
|
} else if ( $features['payment'] ) {
|
||||||
$description = sprintf( $description_base, __( 'automated taxes, live rates and discounted shipping labels', 'woocommerce' ) );
|
return __( 'payment setup', 'woocommerce' );
|
||||||
} else if ( $taxes_enabled ) {
|
} else if ( $features['taxes'] && $features['rates'] ) {
|
||||||
$description = sprintf( $description_base, __( 'automated taxes', 'woocommerce' ) );
|
return __( 'automated taxes, live rates and discounted shipping labels', 'woocommerce' );
|
||||||
} else if ( $rates_enabled ) {
|
} else if ( $features['taxes'] ) {
|
||||||
$description = sprintf( $description_base, __( 'live rates and discounted shipping labels', 'woocommerce' ) );
|
return __( 'automated taxes', 'woocommerce' );
|
||||||
|
} else if ( $features['rates'] ) {
|
||||||
|
return __( 'live rates and discounted shipping labels', 'woocommerce' );
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return $description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1719,6 +1757,8 @@ class WC_Admin_Setup_Wizard {
|
||||||
public function wc_setup_activate() {
|
public function wc_setup_activate() {
|
||||||
$this->wc_setup_activate_actions();
|
$this->wc_setup_activate_actions();
|
||||||
|
|
||||||
|
$jetpack_connected = class_exists( 'Jetpack' ) && Jetpack::is_active();
|
||||||
|
|
||||||
$has_jetpack_error = false;
|
$has_jetpack_error = false;
|
||||||
if ( isset( $_GET['activate_error'] ) ) {
|
if ( isset( $_GET['activate_error'] ) ) {
|
||||||
$has_jetpack_error = true;
|
$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'] ) ) );
|
$error_message = $this->get_activate_error_message( sanitize_text_field( wp_unslash( $_GET['activate_error'] ) ) );
|
||||||
$description = $error_message;
|
$description = $error_message;
|
||||||
} else {
|
} else {
|
||||||
$description = $this->wc_setup_activate_get_description();
|
$feature_list = $this->wc_setup_activate_get_feature_list_str();
|
||||||
$title = $description ?
|
|
||||||
__( 'Connect your store to Jetpack', 'woocommerce' ) :
|
$description = false;
|
||||||
__( 'Connect your store to Jetpack to enable extra features', 'woocommerce' );
|
|
||||||
|
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>
|
<h1><?php echo esc_html( $title ); ?></h1>
|
||||||
<p><?php echo esc_html( $description ); ?></p>
|
<p><?php echo esc_html( $description ); ?></p>
|
||||||
<img
|
|
||||||
class="jetpack-logo"
|
<?php if ( $jetpack_connected ) : ?>
|
||||||
src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/jetpack_vertical_logo.png' ); ?>"
|
<div class="activate-splash">
|
||||||
alt="Jetpack logo"
|
<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 ) : ?>
|
<?php if ( $has_jetpack_error ) : ?>
|
||||||
<p class="wc-setup-actions step">
|
<p class="wc-setup-actions step">
|
||||||
<a
|
<a
|
||||||
|
@ -1762,53 +1840,55 @@ class WC_Admin_Setup_Wizard {
|
||||||
</p>
|
</p>
|
||||||
<form method="post" class="activate-jetpack">
|
<form method="post" class="activate-jetpack">
|
||||||
<p class="wc-setup-actions step">
|
<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>
|
</p>
|
||||||
<input type="hidden" name="save_step" value="activate" />
|
<input type="hidden" name="save_step" value="activate" />
|
||||||
<?php wp_nonce_field( 'wc-setup' ); ?>
|
<?php wp_nonce_field( 'wc-setup' ); ?>
|
||||||
</form>
|
</form>
|
||||||
<h3 class="jetpack-reasons">
|
<?php if ( ! $jetpack_connected ) : ?>
|
||||||
<?php
|
<h3 class="jetpack-reasons">
|
||||||
echo esc_html( $description ?
|
<?php
|
||||||
__( "Bonus reasons you'll love Jetpack", 'woocommerce' ) :
|
echo esc_html( $description ?
|
||||||
__( "Reasons you'll love Jetpack", 'woocommerce' )
|
__( "Bonus reasons you'll love Jetpack", 'woocommerce' ) :
|
||||||
);
|
__( "Reasons you'll love Jetpack", 'woocommerce' )
|
||||||
?>
|
);
|
||||||
</h3>
|
?>
|
||||||
<ul class="wc-wizard-features">
|
</h3>
|
||||||
<li class="wc-wizard-feature-item">
|
<ul class="wc-wizard-features">
|
||||||
<p class="wc-wizard-feature-name">
|
<li class="wc-wizard-feature-item">
|
||||||
<strong><?php esc_html_e( 'Better security', 'woocommerce' ); ?></strong>
|
<p class="wc-wizard-feature-name">
|
||||||
</p>
|
<strong><?php esc_html_e( 'Better security', 'woocommerce' ); ?></strong>
|
||||||
<p class="wc-wizard-feature-description">
|
</p>
|
||||||
<?php esc_html_e( 'Protect your store from unauthorized access.', 'woocommerce' ); ?>
|
<p class="wc-wizard-feature-description">
|
||||||
</p>
|
<?php esc_html_e( 'Protect your store from unauthorized access.', 'woocommerce' ); ?>
|
||||||
</li>
|
</p>
|
||||||
<li class="wc-wizard-feature-item">
|
</li>
|
||||||
<p class="wc-wizard-feature-name">
|
<li class="wc-wizard-feature-item">
|
||||||
<strong><?php esc_html_e( 'Store stats', 'woocommerce' ); ?></strong>
|
<p class="wc-wizard-feature-name">
|
||||||
</p>
|
<strong><?php esc_html_e( 'Store stats', 'woocommerce' ); ?></strong>
|
||||||
<p class="wc-wizard-feature-description">
|
</p>
|
||||||
<?php esc_html_e( 'Get insights on how your store is doing, including total sales, top products, and more.', 'woocommerce' ); ?>
|
<p class="wc-wizard-feature-description">
|
||||||
</p>
|
<?php esc_html_e( 'Get insights on how your store is doing, including total sales, top products, and more.', 'woocommerce' ); ?>
|
||||||
</li>
|
</p>
|
||||||
<li class="wc-wizard-feature-item">
|
</li>
|
||||||
<p class="wc-wizard-feature-name">
|
<li class="wc-wizard-feature-item">
|
||||||
<strong><?php esc_html_e( 'Store monitoring', 'woocommerce' ); ?></strong>
|
<p class="wc-wizard-feature-name">
|
||||||
</p>
|
<strong><?php esc_html_e( 'Store monitoring', 'woocommerce' ); ?></strong>
|
||||||
<p class="wc-wizard-feature-description">
|
</p>
|
||||||
<?php esc_html_e( 'Get an alert if your store is down for even a few minutes.', 'woocommerce' ); ?>
|
<p class="wc-wizard-feature-description">
|
||||||
</p>
|
<?php esc_html_e( 'Get an alert if your store is down for even a few minutes.', 'woocommerce' ); ?>
|
||||||
</li>
|
</p>
|
||||||
<li class="wc-wizard-feature-item">
|
</li>
|
||||||
<p class="wc-wizard-feature-name">
|
<li class="wc-wizard-feature-item">
|
||||||
<strong><?php esc_html_e( 'Product promotion', 'woocommerce' ); ?></strong>
|
<p class="wc-wizard-feature-name">
|
||||||
</p>
|
<strong><?php esc_html_e( 'Product promotion', 'woocommerce' ); ?></strong>
|
||||||
<p class="wc-wizard-feature-description">
|
</p>
|
||||||
<?php esc_html_e( "Share new items on social media the moment they're live in your store.", 'woocommerce' ); ?>
|
<p class="wc-wizard-feature-description">
|
||||||
</p>
|
<?php esc_html_e( "Share new items on social media the moment they're live in your store.", 'woocommerce' ); ?>
|
||||||
</li>
|
</p>
|
||||||
</ul>
|
</li>
|
||||||
|
</ul>
|
||||||
|
<?php endif; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
@ -1835,9 +1915,16 @@ class WC_Admin_Setup_Wizard {
|
||||||
public function wc_setup_activate_save() {
|
public function wc_setup_activate_save() {
|
||||||
check_admin_referer( 'wc-setup' );
|
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.
|
// Leave a note for WooCommerce Services that Jetpack has been opted into.
|
||||||
update_option( 'woocommerce_setup_jetpack_opted_in', true );
|
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(
|
WC_Install::background_installer( 'jetpack', array(
|
||||||
'file' => 'jetpack/jetpack.php',
|
'file' => 'jetpack/jetpack.php',
|
||||||
'name' => __( 'Jetpack', 'woocommerce' ),
|
'name' => __( 'Jetpack', 'woocommerce' ),
|
||||||
|
|
|
@ -454,10 +454,9 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
|
||||||
|
|
||||||
// Search using CRUD.
|
// Search using CRUD.
|
||||||
if ( ! empty( $query_vars['s'] ) ) {
|
if ( ! empty( $query_vars['s'] ) ) {
|
||||||
$data_store = WC_Data_Store::load( 'product' );
|
$data_store = WC_Data_Store::load( 'product' );
|
||||||
$ids = $data_store->search_products( wc_clean( $query_vars['s'] ), '', true, true );
|
$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['post__in'] = array_merge( $ids, array( 0 ) );
|
||||||
// So we know we are searching products.
|
|
||||||
$query_vars['product_search'] = true;
|
$query_vars['product_search'] = true;
|
||||||
unset( $query_vars['s'] );
|
unset( $query_vars['s'] );
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,6 +360,15 @@ class WC_Meta_Box_Order_Data {
|
||||||
if ( ! isset( $field['id'] ) ) {
|
if ( ! isset( $field['id'] ) ) {
|
||||||
$field['id'] = '_billing_' . $key;
|
$field['id'] = '_billing_' . $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$field_name = 'billing_' . $key;
|
||||||
|
|
||||||
|
if ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
|
||||||
|
$field['value'] = $order->{"get_$field_name"}( 'edit' );
|
||||||
|
} else {
|
||||||
|
$field['value'] = $order->get_meta( '_' . $field_name );
|
||||||
|
}
|
||||||
|
|
||||||
switch ( $field['type'] ) {
|
switch ( $field['type'] ) {
|
||||||
case 'select':
|
case 'select':
|
||||||
woocommerce_wp_select( $field );
|
woocommerce_wp_select( $field );
|
||||||
|
@ -462,6 +471,14 @@ class WC_Meta_Box_Order_Data {
|
||||||
$field['id'] = '_shipping_' . $key;
|
$field['id'] = '_shipping_' . $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$field_name = 'shipping_' . $key;
|
||||||
|
|
||||||
|
if ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
|
||||||
|
$field['value'] = $order->{"get_$field_name"}( 'edit' );
|
||||||
|
} else {
|
||||||
|
$field['value'] = $order->get_meta( '_' . $field_name );
|
||||||
|
}
|
||||||
|
|
||||||
switch ( $field['type'] ) {
|
switch ( $field['type'] ) {
|
||||||
case 'select':
|
case 'select':
|
||||||
woocommerce_wp_select( $field );
|
woocommerce_wp_select( $field );
|
||||||
|
|
|
@ -1,394 +1,393 @@
|
||||||
<?php
|
<?php // @codingStandardsIgnoreLine.
|
||||||
/**
|
/**
|
||||||
* WooCommerce Shipping Settings
|
* WooCommerce Checkout Settings
|
||||||
*
|
*
|
||||||
* @author WooThemes
|
|
||||||
* @category Admin
|
|
||||||
* @package WooCommerce/Admin
|
* @package WooCommerce/Admin
|
||||||
* @version 2.5.0
|
* @version 2.5.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
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' );
|
||||||
|
|
||||||
/**
|
add_action( 'woocommerce_admin_field_payment_gateways', array( $this, 'payment_gateways_setting' ) );
|
||||||
* Constructor.
|
parent::__construct();
|
||||||
*/
|
}
|
||||||
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();
|
* Get sections.
|
||||||
}
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_sections() {
|
||||||
|
$sections = array(
|
||||||
|
'' => __( 'Checkout options', 'woocommerce' ),
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
if ( ! defined( 'WC_INSTALLING' ) ) {
|
||||||
* 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 → 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 → 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 → 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.
|
|
||||||
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
||||||
|
|
||||||
if ( $current_section ) {
|
foreach ( $payment_gateways as $gateway ) {
|
||||||
foreach ( $payment_gateways as $gateway ) {
|
$title = empty( $gateway->method_title ) ? ucfirst( $gateway->id ) : $gateway->method_title;
|
||||||
if ( in_array( $current_section, array( $gateway->id, sanitize_title( get_class( $gateway ) ) ) ) ) {
|
$sections[ strtolower( $gateway->id ) ] = esc_html( $title );
|
||||||
$gateway->admin_options();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$settings = $this->get_settings();
|
|
||||||
|
|
||||||
WC_Admin_Settings::output_fields( $settings );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return apply_filters( 'woocommerce_get_sections_' . $this->id, $sections );
|
||||||
* 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' ),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ( $columns as $key => $column ) {
|
/**
|
||||||
echo '<th class="' . esc_attr( $key ) . '">' . esc_html( $column ) . '</th>';
|
* Get settings array.
|
||||||
}
|
*
|
||||||
?>
|
* @param string $current_section Section being shown.
|
||||||
</tr>
|
* @return array
|
||||||
</thead>
|
*/
|
||||||
<tbody>
|
public function get_settings( $current_section = '' ) {
|
||||||
<?php
|
$settings = array();
|
||||||
foreach ( WC()->payment_gateways->payment_gateways() as $gateway ) {
|
|
||||||
|
|
||||||
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':
|
array(
|
||||||
echo '<td width="1%" class="sort">
|
'desc' => __( 'Calculate coupon discounts sequentially', 'woocommerce' ),
|
||||||
<input type="hidden" name="gateway_order[]" value="' . esc_attr( $gateway->id ) . '" />
|
'id' => 'woocommerce_calc_discounts_sequentially',
|
||||||
</td>';
|
'default' => 'no',
|
||||||
break;
|
'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':
|
array(
|
||||||
$method_title = $gateway->get_title() ? $gateway->get_title() : __( '(no title)', 'woocommerce' );
|
'title' => __( 'Checkout process', 'woocommerce' ),
|
||||||
echo '<td class="name">
|
'desc' => __( 'Enable guest checkout', 'woocommerce' ),
|
||||||
<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . strtolower( $gateway->id ) ) . '">' . esc_html( $method_title ) . '</a>
|
'desc_tip' => __( 'Allows customers to checkout without creating an account.', 'woocommerce' ),
|
||||||
</td>';
|
'id' => 'woocommerce_enable_guest_checkout',
|
||||||
break;
|
'default' => 'yes',
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'checkboxgroup' => 'start',
|
||||||
|
'autoload' => false,
|
||||||
|
),
|
||||||
|
|
||||||
case 'id':
|
array(
|
||||||
echo '<td class="id">' . esc_html( $gateway->id ) . '</td>';
|
'desc' => __( 'Force secure checkout', 'woocommerce' ),
|
||||||
break;
|
'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':
|
'unforce_ssl_checkout' => array(
|
||||||
echo '<td class="status">';
|
'desc' => __( 'Force HTTP when leaving the checkout', 'woocommerce' ),
|
||||||
echo ( 'yes' === $gateway->enabled ) ? '<span class="status-enabled tips" data-tip="' . esc_attr__( 'Yes', 'woocommerce' ) . '">' . esc_html__( 'Yes', 'woocommerce' ) . '</span>' : '-';
|
'id' => 'woocommerce_unforce_ssl_checkout',
|
||||||
echo '</td>';
|
'default' => 'no',
|
||||||
break;
|
'type' => 'checkbox',
|
||||||
|
'checkboxgroup' => 'end',
|
||||||
|
'show_if_checked' => 'yes',
|
||||||
|
),
|
||||||
|
|
||||||
default:
|
array(
|
||||||
do_action( 'woocommerce_payment_gateways_setting_column_' . $key, $gateway );
|
'type' => 'sectionend',
|
||||||
break;
|
'id' => 'checkout_process_options',
|
||||||
}
|
),
|
||||||
}
|
|
||||||
|
|
||||||
echo '</tr>';
|
array(
|
||||||
}
|
'title' => __( 'Checkout pages', 'woocommerce' ),
|
||||||
?>
|
'desc' => __( 'These pages need to be set so that WooCommerce knows where to send users to checkout.', 'woocommerce' ),
|
||||||
</tbody>
|
'type' => 'title',
|
||||||
</table>
|
'id' => 'checkout_page_options',
|
||||||
</td>
|
),
|
||||||
</tr>
|
|
||||||
<?php
|
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 → 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 → 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 → 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 );
|
||||||
* Save settings.
|
}
|
||||||
*/
|
|
||||||
public function save() {
|
|
||||||
global $current_section;
|
|
||||||
|
|
||||||
$wc_payment_gateways = WC_Payment_Gateways::instance();
|
/**
|
||||||
|
* Output the settings.
|
||||||
|
*/
|
||||||
|
public function output() {
|
||||||
|
global $current_section;
|
||||||
|
|
||||||
if ( ! $current_section ) {
|
// Load gateways so we can show any global options they may have.
|
||||||
// Prevent the T&Cs and checkout page from being set to the same page.
|
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
||||||
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'] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
WC_Admin_Settings::save_fields( $this->get_settings() );
|
if ( $current_section ) {
|
||||||
$wc_payment_gateways->process_admin_options();
|
foreach ( $payment_gateways as $gateway ) {
|
||||||
|
if ( in_array( $current_section, array( $gateway->id, sanitize_title( get_class( $gateway ) ) ), true ) ) {
|
||||||
} else {
|
$gateway->admin_options();
|
||||||
foreach ( $wc_payment_gateways->payment_gateways() as $gateway ) {
|
break;
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$settings = $this->get_settings();
|
||||||
|
|
||||||
if ( $current_section ) {
|
WC_Admin_Settings::output_fields( $settings );
|
||||||
do_action( 'woocommerce_update_options_' . $this->id . '_' . $current_section );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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§ion=' . 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();
|
return new WC_Settings_Payment_Gateways();
|
||||||
|
|
|
@ -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>
|
|
|
@ -214,6 +214,7 @@ function woocommerce_wp_select( $field ) {
|
||||||
$field_attributes['style'] = $field['style'];
|
$field_attributes['style'] = $field['style'];
|
||||||
$field_attributes['id'] = $field['id'];
|
$field_attributes['id'] = $field['id'];
|
||||||
$field_attributes['name'] = $field['name'];
|
$field_attributes['name'] = $field['name'];
|
||||||
|
$field_attributes['class'] = $field['class'];
|
||||||
|
|
||||||
$tooltip = ! empty( $field['description'] ) && false !== $field['desc_tip'] ? $field['description'] : '';
|
$tooltip = ! empty( $field['description'] ) && false !== $field['desc_tip'] ? $field['description'] : '';
|
||||||
$description = ! empty( $field['description'] ) && false === $field['desc_tip'] ? $field['description'] : '';
|
$description = ! empty( $field['description'] ) && false === $field['desc_tip'] ? $field['description'] : '';
|
||||||
|
|
|
@ -4,15 +4,11 @@
|
||||||
*
|
*
|
||||||
* Handles WC-API endpoint requests.
|
* Handles WC-API endpoint requests.
|
||||||
*
|
*
|
||||||
* @author WooThemes
|
* @package WooCommerce/API
|
||||||
* @category API
|
* @since 2.0.0
|
||||||
* @package WooCommerce/API
|
|
||||||
* @since 2.0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API class.
|
* API class.
|
||||||
|
@ -130,78 +126,78 @@ class WC_API extends WC_Legacy_API {
|
||||||
*/
|
*/
|
||||||
private function rest_api_includes() {
|
private function rest_api_includes() {
|
||||||
// Exception handler.
|
// Exception handler.
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-exception.php' );
|
include_once dirname( __FILE__ ) . '/api/class-wc-rest-exception.php';
|
||||||
|
|
||||||
// Authentication.
|
// Authentication.
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-authentication.php' );
|
include_once dirname( __FILE__ ) . '/api/class-wc-rest-authentication.php';
|
||||||
|
|
||||||
// Abstract controllers.
|
// Abstract controllers.
|
||||||
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-controller.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-posts-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-crud-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-terms-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-shipping-zones-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-settings-api.php';
|
||||||
|
|
||||||
// REST API v1 controllers.
|
// 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-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-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-customers-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/v1/class-wc-rest-orders-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-webhooks-controller.php';
|
||||||
|
|
||||||
// Legacy v2 code.
|
// 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-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-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-products-controller.php';
|
||||||
|
|
||||||
// REST API v2 controllers.
|
// REST API v2 controllers.
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-coupons-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-customer-downloads-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-customers-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-orders-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-network-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-notes-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-order-refunds-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-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-attributes-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-categories-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-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-shipping-classes-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-tags-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-products-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-variations-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-sales-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-report-top-sellers-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-reports-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-settings-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-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-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-locations-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zone-methods-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-tax-classes-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-taxes-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-webhook-deliveries-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhooks-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-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-system-status-tools-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-shipping-methods-controller.php';
|
||||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-payment-gateways-controller.php' );
|
include_once dirname( __FILE__ ) . '/api/class-wc-rest-payment-gateways-controller.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
*
|
*
|
||||||
* Handles wc-auth endpoint requests.
|
* Handles wc-auth endpoint requests.
|
||||||
*
|
*
|
||||||
* @author WooThemes
|
* @package WooCommerce/API
|
||||||
* @category API
|
* @since 2.4.0
|
||||||
* @package WooCommerce/API
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
*/
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auth class.
|
||||||
|
*/
|
||||||
class WC_Auth {
|
class WC_Auth {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,23 +28,21 @@ class WC_Auth {
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
// Add query vars
|
// Add query vars.
|
||||||
add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
|
add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
|
||||||
|
|
||||||
// Register auth endpoint
|
// Register auth endpoint.
|
||||||
add_action( 'init', array( __CLASS__, 'add_endpoint' ), 0 );
|
add_action( 'init', array( __CLASS__, 'add_endpoint' ), 0 );
|
||||||
|
|
||||||
// Handle auth requests
|
// Handle auth requests.
|
||||||
add_action( 'parse_request', array( $this, 'handle_auth_requests' ), 0 );
|
add_action( 'parse_request.', array( $this, 'handle_auth_requests' ), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add query vars.
|
* Add query vars.
|
||||||
*
|
*
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*
|
* @param array $vars Query variables.
|
||||||
* @param array $vars
|
|
||||||
*
|
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function add_query_vars( $vars ) {
|
public function add_query_vars( $vars ) {
|
||||||
|
@ -66,9 +64,7 @@ class WC_Auth {
|
||||||
* Get scope name.
|
* Get scope name.
|
||||||
*
|
*
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*
|
* @param string $scope Permission scope.
|
||||||
* @param string $scope
|
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function get_i18n_scope( $scope ) {
|
protected function get_i18n_scope( $scope ) {
|
||||||
|
@ -85,34 +81,32 @@ class WC_Auth {
|
||||||
* Return a list of permissions a scope allows.
|
* Return a list of permissions a scope allows.
|
||||||
*
|
*
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*
|
* @param string $scope Permission scope.
|
||||||
* @param string $scope
|
|
||||||
*
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function get_permissions_in_scope( $scope ) {
|
protected function get_permissions_in_scope( $scope ) {
|
||||||
$permissions = array();
|
$permissions = array();
|
||||||
switch ( $scope ) {
|
switch ( $scope ) {
|
||||||
case 'read' :
|
case 'read':
|
||||||
$permissions[] = __( 'View coupons', 'woocommerce' );
|
$permissions[] = __( 'View coupons', 'woocommerce' );
|
||||||
$permissions[] = __( 'View customers', 'woocommerce' );
|
$permissions[] = __( 'View customers', 'woocommerce' );
|
||||||
$permissions[] = __( 'View orders and sales reports', 'woocommerce' );
|
$permissions[] = __( 'View orders and sales reports', 'woocommerce' );
|
||||||
$permissions[] = __( 'View products', 'woocommerce' );
|
$permissions[] = __( 'View products', 'woocommerce' );
|
||||||
break;
|
break;
|
||||||
case 'write' :
|
case 'write':
|
||||||
$permissions[] = __( 'Create webhooks', 'woocommerce' );
|
$permissions[] = __( 'Create webhooks', 'woocommerce' );
|
||||||
$permissions[] = __( 'Create coupons', 'woocommerce' );
|
$permissions[] = __( 'Create coupons', 'woocommerce' );
|
||||||
$permissions[] = __( 'Create customers', 'woocommerce' );
|
$permissions[] = __( 'Create customers', 'woocommerce' );
|
||||||
$permissions[] = __( 'Create orders', 'woocommerce' );
|
$permissions[] = __( 'Create orders', 'woocommerce' );
|
||||||
$permissions[] = __( 'Create products', 'woocommerce' );
|
$permissions[] = __( 'Create products', 'woocommerce' );
|
||||||
break;
|
break;
|
||||||
case 'read_write' :
|
case 'read_write':
|
||||||
$permissions[] = __( 'Create webhooks', 'woocommerce' );
|
$permissions[] = __( 'Create webhooks', 'woocommerce' );
|
||||||
$permissions[] = __( 'View and manage coupons', 'woocommerce' );
|
$permissions[] = __( 'View and manage coupons', 'woocommerce' );
|
||||||
$permissions[] = __( 'View and manage customers', 'woocommerce' );
|
$permissions[] = __( 'View and manage customers', 'woocommerce' );
|
||||||
$permissions[] = __( 'View and manage orders and sales reports', 'woocommerce' );
|
$permissions[] = __( 'View and manage orders and sales reports', 'woocommerce' );
|
||||||
$permissions[] = __( 'View and manage products', 'woocommerce' );
|
$permissions[] = __( 'View and manage products', 'woocommerce' );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return apply_filters( 'woocommerce_api_permissions_in_scope', $permissions, $scope );
|
return apply_filters( 'woocommerce_api_permissions_in_scope', $permissions, $scope );
|
||||||
}
|
}
|
||||||
|
@ -121,27 +115,28 @@ class WC_Auth {
|
||||||
* Build auth urls.
|
* Build auth urls.
|
||||||
*
|
*
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*
|
* @param array $data Data to build URL.
|
||||||
* @param array $data
|
* @param string $endpoint Endpoint.
|
||||||
* @param string $endpoint
|
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function build_url( $data, $endpoint ) {
|
protected function build_url( $data, $endpoint ) {
|
||||||
$url = wc_get_endpoint_url( 'wc-auth/v' . self::VERSION, $endpoint, home_url( '/' ) );
|
$url = wc_get_endpoint_url( 'wc-auth/v' . self::VERSION, $endpoint, home_url( '/' ) );
|
||||||
|
|
||||||
return add_query_arg( array(
|
return add_query_arg(
|
||||||
'app_name' => wc_clean( $data['app_name'] ),
|
array(
|
||||||
'user_id' => wc_clean( $data['user_id'] ),
|
'app_name' => wc_clean( $data['app_name'] ),
|
||||||
'return_url' => urlencode( $this->get_formatted_url( $data['return_url'] ) ),
|
'user_id' => wc_clean( $data['user_id'] ),
|
||||||
'callback_url' => urlencode( $this->get_formatted_url( $data['callback_url'] ) ),
|
'return_url' => rawurlencode( $this->get_formatted_url( $data['return_url'] ) ),
|
||||||
'scope' => wc_clean( $data['scope'] ),
|
'callback_url' => rawurlencode( $this->get_formatted_url( $data['callback_url'] ) ),
|
||||||
), $url );
|
'scope' => wc_clean( $data['scope'] ),
|
||||||
|
), $url
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode and format a URL.
|
* Decode and format a URL.
|
||||||
* @param string $url
|
*
|
||||||
|
* @param string $url URL.
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function get_formatted_url( $url ) {
|
protected function get_formatted_url( $url ) {
|
||||||
|
@ -158,8 +153,10 @@ class WC_Auth {
|
||||||
* Make validation.
|
* Make validation.
|
||||||
*
|
*
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
|
* @throws Exception When validate fails.
|
||||||
*/
|
*/
|
||||||
protected function make_validation() {
|
protected function make_validation() {
|
||||||
|
$data = array();
|
||||||
$params = array(
|
$params = array(
|
||||||
'app_name',
|
'app_name',
|
||||||
'user_id',
|
'user_id',
|
||||||
|
@ -169,19 +166,21 @@ class WC_Auth {
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ( $params as $param ) {
|
foreach ( $params as $param ) {
|
||||||
if ( empty( $_REQUEST[ $param ] ) ) {
|
if ( empty( $_REQUEST[ $param ] ) ) { // WPCS: input var ok, CSRF ok.
|
||||||
/* translators: %s: parameter */
|
/* translators: %s: parameter */
|
||||||
throw new Exception( sprintf( __( 'Missing parameter %s', 'woocommerce' ), $param ) );
|
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 */
|
/* 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 ) {
|
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 ) ) {
|
if ( false === filter_var( $param, FILTER_VALIDATE_URL ) ) {
|
||||||
/* translators: %s: 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://' ) ) {
|
if ( 0 !== stripos( $callback_url, 'https://' ) ) {
|
||||||
throw new Exception( __( 'The callback_url needs to be over SSL', 'woocommerce' ) );
|
throw new Exception( __( 'The callback_url needs to be over SSL', 'woocommerce' ) );
|
||||||
|
@ -201,17 +200,17 @@ class WC_Auth {
|
||||||
*
|
*
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*
|
*
|
||||||
* @param string $app_name
|
* @param string $app_name App name.
|
||||||
* @param string $app_user_id
|
* @param string $app_user_id User ID.
|
||||||
* @param string $scope
|
* @param string $scope Scope.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function create_keys( $app_name, $app_user_id, $scope ) {
|
protected function create_keys( $app_name, $app_user_id, $scope ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
/* translators: 1: app name 2: scope 3: date 4: time */
|
|
||||||
$description = sprintf(
|
$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' ),
|
__( '%1$s - API %2$s (created on %3$s at %4$s).', 'woocommerce' ),
|
||||||
wc_clean( $app_name ),
|
wc_clean( $app_name ),
|
||||||
$this->get_i18n_scope( $scope ),
|
$this->get_i18n_scope( $scope ),
|
||||||
|
@ -221,7 +220,7 @@ class WC_Auth {
|
||||||
$user = wp_get_current_user();
|
$user = wp_get_current_user();
|
||||||
|
|
||||||
// Created API keys.
|
// 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_key = 'ck_' . wc_rand_hash();
|
||||||
$consumer_secret = 'cs_' . wc_rand_hash();
|
$consumer_secret = 'cs_' . wc_rand_hash();
|
||||||
|
|
||||||
|
@ -259,17 +258,16 @@ class WC_Auth {
|
||||||
*
|
*
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*
|
*
|
||||||
* @param array $consumer_data
|
* @throws Exception When validation fails.
|
||||||
* @param string $url
|
* @param array $consumer_data Consumer data.
|
||||||
*
|
* @param string $url URL.
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws Exception
|
|
||||||
*/
|
*/
|
||||||
protected function post_consumer_data( $consumer_data, $url ) {
|
protected function post_consumer_data( $consumer_data, $url ) {
|
||||||
$params = array(
|
$params = array(
|
||||||
'body' => json_encode( $consumer_data ),
|
'body' => wp_json_encode( $consumer_data ),
|
||||||
'timeout' => 60,
|
'timeout' => 60,
|
||||||
'headers' => array(
|
'headers' => array(
|
||||||
'Content-Type' => 'application/json;charset=' . get_bloginfo( 'charset' ),
|
'Content-Type' => 'application/json;charset=' . get_bloginfo( 'charset' ),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -278,7 +276,7 @@ class WC_Auth {
|
||||||
|
|
||||||
if ( is_wp_error( $response ) ) {
|
if ( is_wp_error( $response ) ) {
|
||||||
throw new Exception( $response->get_error_message() );
|
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' ) );
|
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() {
|
public function handle_auth_requests() {
|
||||||
global $wp;
|
global $wp;
|
||||||
|
|
||||||
if ( ! empty( $_GET['wc-auth-version'] ) ) {
|
if ( ! empty( $_GET['wc-auth-version'] ) ) { // WPCS: input var ok, CSRF ok.
|
||||||
$wp->query_vars['wc-auth-version'] = $_GET['wc-auth-version'];
|
$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'] ) ) {
|
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'] ) ) {
|
if ( ! empty( $wp->query_vars['wc-auth-version'] ) && ! empty( $wp->query_vars['wc-auth-route'] ) ) {
|
||||||
$this->auth_endpoint( $wp->query_vars['wc-auth-route'] );
|
$this->auth_endpoint( $wp->query_vars['wc-auth-route'] );
|
||||||
}
|
}
|
||||||
|
@ -311,8 +309,8 @@ class WC_Auth {
|
||||||
* Auth endpoint.
|
* Auth endpoint.
|
||||||
*
|
*
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*
|
* @throws Exception When validation fails.
|
||||||
* @param string $route
|
* @param string $route Route.
|
||||||
*/
|
*/
|
||||||
protected function auth_endpoint( $route ) {
|
protected function auth_endpoint( $route ) {
|
||||||
ob_start();
|
ob_start();
|
||||||
|
@ -327,50 +325,74 @@ class WC_Auth {
|
||||||
$route = strtolower( wc_clean( $route ) );
|
$route = strtolower( wc_clean( $route ) );
|
||||||
$this->make_validation();
|
$this->make_validation();
|
||||||
|
|
||||||
// Login endpoint
|
$data = wp_unslash( $_REQUEST ); // WPCS: input var ok, CSRF ok.
|
||||||
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' ),
|
|
||||||
) );
|
|
||||||
|
|
||||||
|
// 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;
|
exit;
|
||||||
|
|
||||||
// Redirect with user is logged in
|
} elseif ( 'login' === $route && is_user_logged_in() ) {
|
||||||
} elseif ( 'login' == $route && is_user_logged_in() ) {
|
// Redirect with user is logged in.
|
||||||
wp_redirect( esc_url_raw( $this->build_url( $_REQUEST, 'authorize' ) ) );
|
wp_redirect( esc_url_raw( $this->build_url( $data, 'authorize' ) ) );
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
// Redirect with user is not logged in and trying to access the authorize endpoint
|
} elseif ( 'authorize' === $route && ! is_user_logged_in() ) {
|
||||||
} 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( $_REQUEST, 'login' ) ) );
|
wp_redirect( esc_url_raw( $this->build_url( $data, 'login' ) ) );
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
// Authorize endpoint
|
} elseif ( 'authorize' === $route && current_user_can( 'manage_woocommerce' ) ) {
|
||||||
} elseif ( 'authorize' == $route && current_user_can( 'manage_woocommerce' ) ) {
|
// Authorize endpoint.
|
||||||
wc_get_template( 'auth/form-grant-access.php', array(
|
wc_get_template(
|
||||||
'app_name' => $_REQUEST['app_name'],
|
'auth/form-grant-access.php', array(
|
||||||
'return_url' => add_query_arg( array( 'success' => 0, 'user_id' => wc_clean( $_REQUEST['user_id'] ) ), $this->get_formatted_url( $_REQUEST['return_url'] ) ),
|
'app_name' => wc_clean( $data['app_name'] ),
|
||||||
'scope' => $this->get_i18n_scope( wc_clean( $_REQUEST['scope'] ) ),
|
'return_url' => add_query_arg(
|
||||||
'permissions' => $this->get_permissions_in_scope( wc_clean( $_REQUEST['scope'] ) ),
|
array(
|
||||||
'granted_url' => wp_nonce_url( $this->build_url( $_REQUEST, 'access_granted' ), 'wc_auth_grant_access', 'wc_auth_nonce' ),
|
'success' => 0,
|
||||||
'logout_url' => wp_logout_url( $this->build_url( $_REQUEST, 'login' ) ),
|
'user_id' => wc_clean( $data['user_id'] ),
|
||||||
'user' => wp_get_current_user(),
|
), $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;
|
exit;
|
||||||
|
|
||||||
// Granted access endpoint
|
} elseif ( 'access_granted' === $route && current_user_can( 'manage_woocommerce' ) ) {
|
||||||
} elseif ( 'access_granted' == $route && current_user_can( 'manage_woocommerce' ) ) {
|
// Granted access endpoint.
|
||||||
if ( ! isset( $_GET['wc_auth_nonce'] ) || ! wp_verify_nonce( $_GET['wc_auth_nonce'], 'wc_auth_grant_access' ) ) {
|
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' ) );
|
throw new Exception( __( 'Invalid nonce verification', 'woocommerce' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$consumer_data = $this->create_keys( $_REQUEST['app_name'], $_REQUEST['user_id'], $_REQUEST['scope'] );
|
$consumer_data = $this->create_keys( $data['app_name'], $data['user_id'], $data['scope'] );
|
||||||
$response = $this->post_consumer_data( $consumer_data, $this->get_formatted_url( $_REQUEST['callback_url'] ) );
|
$response = $this->post_consumer_data( $consumer_data, $this->get_formatted_url( $data['callback_url'] ) );
|
||||||
|
|
||||||
if ( $response ) {
|
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;
|
exit;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -380,7 +402,7 @@ class WC_Auth {
|
||||||
$this->maybe_delete_key( $consumer_data );
|
$this->maybe_delete_key( $consumer_data );
|
||||||
|
|
||||||
/* translators: %s: error message */
|
/* 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
|
* @since 2.4.0
|
||||||
*
|
*
|
||||||
* @param array $key
|
* @param array $key Key.
|
||||||
*/
|
*/
|
||||||
private function maybe_delete_key( $key ) {
|
private function maybe_delete_key( $key ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WooCommerce Autoloader.
|
* WooCommerce Autoloader.
|
||||||
*
|
*
|
||||||
* @class WC_Autoloader
|
* @package WooCommerce/Classes
|
||||||
* @version 2.3.0
|
* @version 2.3.0
|
||||||
* @package WooCommerce/Classes
|
*/
|
||||||
* @category Class
|
|
||||||
* @author WooThemes
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autoloader class.
|
||||||
*/
|
*/
|
||||||
class WC_Autoloader {
|
class WC_Autoloader {
|
||||||
|
|
||||||
|
@ -25,8 +24,8 @@ class WC_Autoloader {
|
||||||
* The Constructor.
|
* The Constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
if ( function_exists( "__autoload" ) ) {
|
if ( function_exists( '__autoload' ) ) {
|
||||||
spl_autoload_register( "__autoload" );
|
spl_autoload_register( '__autoload' );
|
||||||
}
|
}
|
||||||
|
|
||||||
spl_autoload_register( array( $this, '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.
|
* Take a class name and turn it into a file name.
|
||||||
*
|
*
|
||||||
* @param string $class
|
* @param string $class Class name.
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function get_file_name_from_class( $class ) {
|
private function get_file_name_from_class( $class ) {
|
||||||
|
@ -47,12 +46,12 @@ class WC_Autoloader {
|
||||||
/**
|
/**
|
||||||
* Include a class file.
|
* Include a class file.
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path File path.
|
||||||
* @return bool successful or not
|
* @return bool Successful or not.
|
||||||
*/
|
*/
|
||||||
private function load_file( $path ) {
|
private function load_file( $path ) {
|
||||||
if ( $path && is_readable( $path ) ) {
|
if ( $path && is_readable( $path ) ) {
|
||||||
include_once( $path );
|
include_once $path;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -61,7 +60,7 @@ class WC_Autoloader {
|
||||||
/**
|
/**
|
||||||
* Auto-load WC classes on demand to reduce memory consumption.
|
* Auto-load WC classes on demand to reduce memory consumption.
|
||||||
*
|
*
|
||||||
* @param string $class
|
* @param string $class Class name.
|
||||||
*/
|
*/
|
||||||
public function autoload( $class ) {
|
public function autoload( $class ) {
|
||||||
$class = strtolower( $class );
|
$class = strtolower( $class );
|
||||||
|
@ -70,14 +69,14 @@ class WC_Autoloader {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = $this->get_file_name_from_class( $class );
|
$file = $this->get_file_name_from_class( $class );
|
||||||
$path = '';
|
$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 ) . '/';
|
$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 ) . '/';
|
$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 ) . '/';
|
$path = $this->include_path . 'shipping/' . substr( str_replace( '_', '-', $class ), 12 ) . '/';
|
||||||
} elseif ( 0 === strpos( $class, 'wc_shortcode_' ) ) {
|
} elseif ( 0 === strpos( $class, 'wc_shortcode_' ) ) {
|
||||||
$path = $this->include_path . 'shortcodes/';
|
$path = $this->include_path . 'shortcodes/';
|
||||||
|
|
|
@ -2,13 +2,11 @@
|
||||||
/**
|
/**
|
||||||
* Background Emailer
|
* Background Emailer
|
||||||
*
|
*
|
||||||
* @version 3.0.1
|
* @version 3.0.1
|
||||||
* @package WooCommerce/Classes
|
* @package WooCommerce/Classes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! class_exists( 'WC_Background_Process', false ) ) {
|
if ( ! class_exists( 'WC_Background_Process', false ) ) {
|
||||||
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';
|
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'] );
|
WC_Emails::send_queued_transactional_email( $callback['filter'], $callback['args'] );
|
||||||
} catch ( Exception $e ) {
|
} catch ( Exception $e ) {
|
||||||
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
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() ) {
|
if ( ! headers_sent() ) {
|
||||||
header( 'Connection: close' );
|
header( 'Connection: close' );
|
||||||
}
|
}
|
||||||
@ob_end_flush();
|
@ob_end_flush(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +115,7 @@ class WC_Background_Emailer extends WC_Background_Process {
|
||||||
// Pass cookies through with the request so nonces function.
|
// Pass cookies through with the request so nonces function.
|
||||||
$cookies = array();
|
$cookies = array();
|
||||||
|
|
||||||
foreach ( $_COOKIE as $name => $value ) {
|
foreach ( $_COOKIE as $name => $value ) { // WPCS: input var ok.
|
||||||
if ( 'PHPSESSID' === $name ) {
|
if ( 'PHPSESSID' === $name ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,11 @@
|
||||||
/**
|
/**
|
||||||
* Background Updater
|
* Background Updater
|
||||||
*
|
*
|
||||||
* @version 2.6.0
|
* @version 2.6.0
|
||||||
* @package WooCommerce/Classes
|
* @package WooCommerce/Classes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! class_exists( 'WC_Background_Process', false ) ) {
|
if ( ! class_exists( 'WC_Background_Process', false ) ) {
|
||||||
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';
|
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WC_Breadcrumb class.
|
* WC_Breadcrumb class.
|
||||||
*
|
*
|
||||||
* @class WC_Breadcrumb
|
* @package WooCommerce/Classes
|
||||||
* @version 2.3.0
|
* @version 2.3.0
|
||||||
* @package WooCommerce/Classes
|
*/
|
||||||
* @category Class
|
|
||||||
* @author WooThemes
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breadcrumb class.
|
||||||
*/
|
*/
|
||||||
class WC_Breadcrumb {
|
class WC_Breadcrumb {
|
||||||
|
|
||||||
|
@ -25,8 +23,8 @@ class WC_Breadcrumb {
|
||||||
/**
|
/**
|
||||||
* Add a crumb so we don't get lost.
|
* Add a crumb so we don't get lost.
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name Name.
|
||||||
* @param string $link
|
* @param string $link Link.
|
||||||
*/
|
*/
|
||||||
public function add_crumb( $name, $link = '' ) {
|
public function add_crumb( $name, $link = '' ) {
|
||||||
$this->crumbs[] = array(
|
$this->crumbs[] = array(
|
||||||
|
@ -99,14 +97,14 @@ class WC_Breadcrumb {
|
||||||
$shop_page_id = wc_get_page_id( 'shop' );
|
$shop_page_id = wc_get_page_id( 'shop' );
|
||||||
$shop_page = get_post( $shop_page_id );
|
$shop_page = get_post( $shop_page_id );
|
||||||
|
|
||||||
// If permalinks contain the shop page in the URI prepend the breadcrumb with shop
|
// 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 ( $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 ) );
|
$this->add_crumb( get_the_title( $shop_page ), get_permalink( $shop_page ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* is home trail.
|
* Is home trail..
|
||||||
*/
|
*/
|
||||||
private function add_crumbs_home() {
|
private function add_crumbs_home() {
|
||||||
$this->add_crumb( single_post_title( '', false ) );
|
$this->add_crumb( single_post_title( '', false ) );
|
||||||
|
@ -120,7 +118,7 @@ class WC_Breadcrumb {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* attachment trail.
|
* Attachment trail.
|
||||||
*/
|
*/
|
||||||
private function add_crumbs_attachment() {
|
private function add_crumbs_attachment() {
|
||||||
global $post;
|
global $post;
|
||||||
|
@ -132,23 +130,27 @@ class WC_Breadcrumb {
|
||||||
/**
|
/**
|
||||||
* Single post trail.
|
* Single post trail.
|
||||||
*
|
*
|
||||||
* @param int $post_id
|
* @param int $post_id Post ID.
|
||||||
* @param string $permalink
|
* @param string $permalink Post permalink.
|
||||||
*/
|
*/
|
||||||
private function add_crumbs_single( $post_id = 0, $permalink = '' ) {
|
private function add_crumbs_single( $post_id = 0, $permalink = '' ) {
|
||||||
if ( ! $post_id ) {
|
if ( ! $post_id ) {
|
||||||
global $post;
|
global $post;
|
||||||
} else {
|
} else {
|
||||||
$post = get_post( $post_id );
|
$post = get_post( $post_id ); // WPCS: override ok.
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'product' === get_post_type( $post ) ) {
|
if ( 'product' === get_post_type( $post ) ) {
|
||||||
$this->prepend_shop_page();
|
$this->prepend_shop_page();
|
||||||
|
|
||||||
$terms = wc_get_product_terms( $post->ID, 'product_cat', apply_filters( 'woocommerce_breadcrumb_product_terms_args', array(
|
$terms = wc_get_product_terms(
|
||||||
'orderby' => 'parent',
|
$post->ID, 'product_cat', apply_filters(
|
||||||
'order' => 'DESC',
|
'woocommerce_breadcrumb_product_terms_args', array(
|
||||||
) ) );
|
'orderby' => 'parent',
|
||||||
|
'order' => 'DESC',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if ( $terms ) {
|
if ( $terms ) {
|
||||||
$main_term = apply_filters( 'woocommerce_breadcrumb_main_term', $terms[0], $terms );
|
$main_term = apply_filters( 'woocommerce_breadcrumb_main_term', $terms[0], $terms );
|
||||||
|
@ -183,8 +185,8 @@ class WC_Breadcrumb {
|
||||||
$parent_id = $post->post_parent;
|
$parent_id = $post->post_parent;
|
||||||
|
|
||||||
while ( $parent_id ) {
|
while ( $parent_id ) {
|
||||||
$page = get_post( $parent_id );
|
$page = get_post( $parent_id );
|
||||||
$parent_id = $page->post_parent;
|
$parent_id = $page->post_parent;
|
||||||
$parent_crumbs[] = array( get_the_title( $page->ID ), get_permalink( $page->ID ) );
|
$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();
|
$current_term = $GLOBALS['wp_query']->get_queried_object();
|
||||||
|
|
||||||
$this->prepend_shop_page();
|
$this->prepend_shop_page();
|
||||||
|
|
||||||
|
/* translators: %s: product tag */
|
||||||
$this->add_crumb( sprintf( __( 'Products tagged “%s”', 'woocommerce' ), $current_term->name ) );
|
$this->add_crumb( sprintf( __( 'Products tagged “%s”', 'woocommerce' ), $current_term->name ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +228,7 @@ class WC_Breadcrumb {
|
||||||
* Shop breadcrumb.
|
* Shop breadcrumb.
|
||||||
*/
|
*/
|
||||||
private function add_crumbs_shop() {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +236,7 @@ class WC_Breadcrumb {
|
||||||
|
|
||||||
if ( ! $_name ) {
|
if ( ! $_name ) {
|
||||||
$product_post_type = get_post_type_object( 'product' );
|
$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' ) );
|
$this->add_crumb( $_name, get_post_type_archive_link( 'product' ) );
|
||||||
|
@ -255,7 +259,7 @@ class WC_Breadcrumb {
|
||||||
private function add_crumbs_category() {
|
private function add_crumbs_category() {
|
||||||
$this_category = get_category( $GLOBALS['wp_query']->get_queried_object() );
|
$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' );
|
$this->term_ancestors( $this_category->term_id, 'category' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,6 +271,8 @@ class WC_Breadcrumb {
|
||||||
*/
|
*/
|
||||||
private function add_crumbs_tag() {
|
private function add_crumbs_tag() {
|
||||||
$queried_object = $GLOBALS['wp_query']->get_queried_object();
|
$queried_object = $GLOBALS['wp_query']->get_queried_object();
|
||||||
|
|
||||||
|
/* translators: %s: tag name */
|
||||||
$this->add_crumb( sprintf( __( 'Posts tagged “%s”', 'woocommerce' ), single_tag_title( '', false ) ), get_tag_link( $queried_object->term_id ) );
|
$this->add_crumb( sprintf( __( 'Posts tagged “%s”', '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 );
|
$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 );
|
$this->term_ancestors( $this_term->term_id, $this_term->taxonomy );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,14 +314,16 @@ class WC_Breadcrumb {
|
||||||
global $author;
|
global $author;
|
||||||
|
|
||||||
$userdata = get_userdata( $author );
|
$userdata = get_userdata( $author );
|
||||||
|
|
||||||
|
/* translators: %s: author name */
|
||||||
$this->add_crumb( sprintf( __( 'Author: %s', 'woocommerce' ), $userdata->display_name ) );
|
$this->add_crumb( sprintf( __( 'Author: %s', 'woocommerce' ), $userdata->display_name ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add crumbs for a term.
|
* Add crumbs for a term.
|
||||||
*
|
*
|
||||||
* @param int $term_id
|
* @param int $term_id Term ID.
|
||||||
* @param string $taxonomy
|
* @param string $taxonomy Taxonomy.
|
||||||
*/
|
*/
|
||||||
private function term_ancestors( $term_id, $taxonomy ) {
|
private function term_ancestors( $term_id, $taxonomy ) {
|
||||||
$ancestors = get_ancestors( $term_id, $taxonomy );
|
$ancestors = get_ancestors( $term_id, $taxonomy );
|
||||||
|
@ -334,8 +342,10 @@ class WC_Breadcrumb {
|
||||||
* Endpoints.
|
* Endpoints.
|
||||||
*/
|
*/
|
||||||
private function endpoint_trail() {
|
private function endpoint_trail() {
|
||||||
// Is an endpoint showing?
|
$endpoint = is_wc_endpoint_url() ? WC()->query->get_current_endpoint() : '';
|
||||||
if ( is_wc_endpoint_url() && ( $endpoint = WC()->query->get_current_endpoint() ) && ( $endpoint_title = WC()->query->get_endpoint_title( $endpoint ) ) ) {
|
$endpoint_title = $endpoint ? WC()->query->get_endpoint_title( $endpoint ) : '';
|
||||||
|
|
||||||
|
if ( $endpoint_title ) {
|
||||||
$this->add_crumb( $endpoint_title );
|
$this->add_crumb( $endpoint_title );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,6 +355,7 @@ class WC_Breadcrumb {
|
||||||
*/
|
*/
|
||||||
private function search_trail() {
|
private function search_trail() {
|
||||||
if ( is_search() ) {
|
if ( is_search() ) {
|
||||||
|
/* translators: %s: search term */
|
||||||
$this->add_crumb( sprintf( __( 'Search results for “%s”', 'woocommerce' ), get_search_query() ), remove_query_arg( 'paged' ) );
|
$this->add_crumb( sprintf( __( 'Search results for “%s”', 'woocommerce' ), get_search_query() ), remove_query_arg( 'paged' ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,6 +365,7 @@ class WC_Breadcrumb {
|
||||||
*/
|
*/
|
||||||
private function paged_trail() {
|
private function paged_trail() {
|
||||||
if ( get_query_var( 'paged' ) ) {
|
if ( get_query_var( 'paged' ) ) {
|
||||||
|
/* translators: %d: page number */
|
||||||
$this->add_crumb( sprintf( __( 'Page %d', 'woocommerce' ), get_query_var( 'paged' ) ) );
|
$this->add_crumb( sprintf( __( 'Page %d', 'woocommerce' ), get_query_var( 'paged' ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,10 @@
|
||||||
/**
|
/**
|
||||||
* WC_Cache_Helper class.
|
* WC_Cache_Helper class.
|
||||||
*
|
*
|
||||||
* @class WC_Cache_Helper
|
* @package WooCommerce/Classes
|
||||||
* @version 2.2.0
|
|
||||||
* @package WooCommerce/Classes
|
|
||||||
* @category Class
|
|
||||||
* @author WooThemes
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WC_Cache_Helper.
|
* WC_Cache_Helper.
|
||||||
|
@ -26,6 +20,8 @@ class WC_Cache_Helper {
|
||||||
add_action( 'admin_notices', array( __CLASS__, 'notices' ) );
|
add_action( 'admin_notices', array( __CLASS__, 'notices' ) );
|
||||||
add_action( 'delete_version_transients', array( __CLASS__, 'delete_version_transients' ) );
|
add_action( 'delete_version_transients', array( __CLASS__, 'delete_version_transients' ) );
|
||||||
add_action( 'wp', array( __CLASS__, 'prevent_caching' ) );
|
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() {
|
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.
|
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();
|
$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 ) {
|
if ( empty( $current_hash ) || $current_hash !== $location_hash ) {
|
||||||
global $wp;
|
global $wp;
|
||||||
|
|
||||||
|
@ -141,7 +137,10 @@ class WC_Cache_Helper {
|
||||||
|
|
||||||
if ( false === $transient_value || true === $refresh ) {
|
if ( false === $transient_value || true === $refresh ) {
|
||||||
self::delete_version_transients( $transient_value );
|
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;
|
return $transient_value;
|
||||||
}
|
}
|
||||||
|
@ -196,11 +195,40 @@ class WC_Cache_Helper {
|
||||||
if ( $enabled && ! in_array( '_wc_session_', $settings, true ) ) {
|
if ( $enabled && ! in_array( '_wc_session_', $settings, true ) ) {
|
||||||
?>
|
?>
|
||||||
<div class="error">
|
<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>
|
</div>
|
||||||
<?php
|
<?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();
|
WC_Cache_Helper::init();
|
||||||
|
|
|
@ -6,13 +6,11 @@
|
||||||
*
|
*
|
||||||
* We suggest using the action woocommerce_cart_calculate_fees hook for adding fees.
|
* We suggest using the action woocommerce_cart_calculate_fees hook for adding fees.
|
||||||
*
|
*
|
||||||
* @author Automattic
|
|
||||||
* @package WooCommerce/Classes
|
* @package WooCommerce/Classes
|
||||||
|
* @version 3.2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WC_Cart_Fees class.
|
* WC_Cart_Fees class.
|
||||||
|
@ -80,7 +78,7 @@ final class WC_Cart_Fees {
|
||||||
public function add_fee( $args = array() ) {
|
public function add_fee( $args = array() ) {
|
||||||
$fee_props = (object) wp_parse_args( $args, $this->default_fee_props );
|
$fee_props = (object) wp_parse_args( $args, $this->default_fee_props );
|
||||||
$fee_props->name = $fee_props->name ? $fee_props->name : __( 'Fee', 'woocommerce' );
|
$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->taxable = wc_string_to_bool( $fee_props->taxable );
|
||||||
$fee_props->amount = wc_format_decimal( $fee_props->amount );
|
$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 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 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
/**
|
/**
|
||||||
* Cart session handling class.
|
* Cart session handling class.
|
||||||
*
|
*
|
||||||
* @author Automattic
|
|
||||||
* @package WooCommerce/Classes
|
* @package WooCommerce/Classes
|
||||||
|
* @version 3.2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
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' );
|
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 );
|
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;
|
$update_cart_session = true;
|
||||||
/* translators: %1$s: product name. %2$s product permalink */
|
/* 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' );
|
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 {
|
} else {
|
||||||
// Put session data into array. Run through filter so other plugins can load their own session data.
|
// Put session data into array. Run through filter so other plugins can load their own session data.
|
||||||
$session_data = array_merge( $values, array(
|
$session_data = array_merge(
|
||||||
'data' => $product,
|
$values, array(
|
||||||
) );
|
'data' => $product,
|
||||||
|
)
|
||||||
|
);
|
||||||
$cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', $session_data, $values, $key );
|
$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.
|
// 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 ( ! headers_sent() && did_action( 'wp_loaded' ) ) {
|
||||||
if ( ! $this->cart->is_empty() ) {
|
if ( ! $this->cart->is_empty() ) {
|
||||||
$this->set_cart_cookies( true );
|
$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 );
|
$this->set_cart_cookies( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,9 +200,11 @@ final class WC_Cart_Session {
|
||||||
*/
|
*/
|
||||||
public function persistent_cart_update() {
|
public function persistent_cart_update() {
|
||||||
if ( get_current_user_id() && apply_filters( 'woocommerce_persistent_cart_enabled', true ) ) {
|
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(
|
update_user_meta(
|
||||||
'cart' => $this->get_cart_for_session(),
|
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 ) {
|
if ( $set ) {
|
||||||
wc_setcookie( 'woocommerce_items_in_cart', 1 );
|
wc_setcookie( 'woocommerce_items_in_cart', 1 );
|
||||||
wc_setcookie( 'woocommerce_cart_hash', md5( wp_json_encode( $this->get_cart_for_session() ) ) );
|
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_items_in_cart', 0, time() - HOUR_IN_SECONDS );
|
||||||
wc_setcookie( 'woocommerce_cart_hash', '', time() - HOUR_IN_SECONDS );
|
wc_setcookie( 'woocommerce_cart_hash', '', time() - HOUR_IN_SECONDS );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 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).
|
* - if calculating a total, round (if settings allow).
|
||||||
*
|
*
|
||||||
* @author Automattic
|
|
||||||
* @package WooCommerce/Classes
|
* @package WooCommerce/Classes
|
||||||
|
* @version 3.2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
@ -102,16 +102,16 @@ final class WC_Cart_Totals {
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $totals = array(
|
protected $totals = array(
|
||||||
'fees_total' => 0,
|
'fees_total' => 0,
|
||||||
'fees_total_tax' => 0,
|
'fees_total_tax' => 0,
|
||||||
'items_subtotal' => 0,
|
'items_subtotal' => 0,
|
||||||
'items_subtotal_tax' => 0,
|
'items_subtotal_tax' => 0,
|
||||||
'items_total' => 0,
|
'items_total' => 0,
|
||||||
'items_total_tax' => 0,
|
'items_total_tax' => 0,
|
||||||
'total' => 0,
|
'total' => 0,
|
||||||
'shipping_total' => 0,
|
'shipping_total' => 0,
|
||||||
'shipping_tax_total' => 0,
|
'shipping_tax_total' => 0,
|
||||||
'discounts_total' => 0,
|
'discounts_total' => 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,7 +212,7 @@ final class WC_Cart_Totals {
|
||||||
* into the same format for use by this class.
|
* 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.
|
* 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.
|
* - cart_item: For carts, the cart item from the cart which may include custom data.
|
||||||
* - quantity: The qty for this line.
|
* - quantity: The qty for this line.
|
||||||
* - price: The line price in cents.
|
* - 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 ) ) );
|
$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 ) {
|
} 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 = 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 ) );
|
$fee->total_tax = array_sum( array_map( array( $this, 'round_line_tax' ), $fee->taxes ) );
|
||||||
|
|
||||||
// Set totals within object.
|
// Set totals within object.
|
||||||
|
@ -366,13 +365,13 @@ final class WC_Cart_Totals {
|
||||||
|
|
||||||
foreach ( $this->coupons as $coupon ) {
|
foreach ( $this->coupons as $coupon ) {
|
||||||
switch ( $coupon->get_discount_type() ) {
|
switch ( $coupon->get_discount_type() ) {
|
||||||
case 'fixed_product' :
|
case 'fixed_product':
|
||||||
$coupon->sort = 1;
|
$coupon->sort = 1;
|
||||||
break;
|
break;
|
||||||
case 'percent' :
|
case 'percent':
|
||||||
$coupon->sort = 2;
|
$coupon->sort = 2;
|
||||||
break;
|
break;
|
||||||
case 'fixed_cart' :
|
case 'fixed_cart':
|
||||||
$coupon->sort = 3;
|
$coupon->sort = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -391,7 +390,7 @@ final class WC_Cart_Totals {
|
||||||
* Sort coupons so discounts apply consistently across installs.
|
* Sort coupons so discounts apply consistently across installs.
|
||||||
*
|
*
|
||||||
* In order of priority;
|
* In order of priority;
|
||||||
* - sort param
|
* - sort param
|
||||||
* - usage restriction
|
* - usage restriction
|
||||||
* - coupon value
|
* - coupon value
|
||||||
* - ID
|
* - ID
|
||||||
|
@ -422,10 +421,10 @@ final class WC_Cart_Totals {
|
||||||
*/
|
*/
|
||||||
protected function remove_item_base_taxes( $item ) {
|
protected function remove_item_base_taxes( $item ) {
|
||||||
if ( $item->price_includes_tax && $item->taxable ) {
|
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.
|
// 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).
|
// Now we have a new item price (excluding TAX).
|
||||||
$item->price = round( $item->price - array_sum( $taxes ) );
|
$item->price = round( $item->price - array_sum( $taxes ) );
|
||||||
|
@ -452,11 +451,11 @@ final class WC_Cart_Totals {
|
||||||
|
|
||||||
if ( $item->tax_rates !== $base_tax_rates ) {
|
if ( $item->tax_rates !== $base_tax_rates ) {
|
||||||
// Work out a new base price without the shop's base tax.
|
// 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 );
|
||||||
$new_taxes = WC_Tax::calc_tax( $item->price - array_sum( $taxes ), $item->tax_rates, false );
|
$new_taxes = WC_Tax::calc_tax( $item->price - array_sum( $taxes ), $item->tax_rates, false );
|
||||||
|
|
||||||
// Now we have a new item price.
|
// 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;
|
return $item;
|
||||||
|
@ -551,7 +550,8 @@ final class WC_Cart_Totals {
|
||||||
* Get taxes merged by type.
|
* Get taxes merged by type.
|
||||||
*
|
*
|
||||||
* @since 3.2.0
|
* @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
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function get_merged_taxes( $in_cents = false, $types = array( 'items', 'fees', 'shipping' ) ) {
|
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.
|
* Combine item taxes into a single array, preserving keys.
|
||||||
*
|
*
|
||||||
* @since 3.2.0
|
* @since 3.2.0
|
||||||
* @param array $taxes Taxes to combine.
|
* @param array $item_taxes Taxes to combine.
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function combine_item_taxes( $item_taxes ) {
|
protected function combine_item_taxes( $item_taxes ) {
|
||||||
|
|
|
@ -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 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.
|
* The cart class also has a price calculation function which calls upon other classes to calculate totals.
|
||||||
*
|
*
|
||||||
* @version 2.1.0
|
* @package WooCommerce/Classes
|
||||||
* @package WooCommerce/Classes
|
* @version 2.1.0
|
||||||
* @category Class
|
|
||||||
* @author WooThemes
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
include_once( WC_ABSPATH . 'includes/legacy/class-wc-legacy-cart.php' );
|
require_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/class-wc-cart-session.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WC_Cart class.
|
* 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() ) {
|
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;
|
$order_id = isset( WC()->session->order_awaiting_payment ) ? absint( WC()->session->order_awaiting_payment ) : 0;
|
||||||
$held_stock = $wpdb->get_var(
|
$held_stock = $wpdb->get_var(
|
||||||
$wpdb->prepare( "
|
$wpdb->prepare(
|
||||||
|
"
|
||||||
SELECT SUM( order_item_meta.meta_value ) AS held_qty
|
SELECT SUM( order_item_meta.meta_value ) AS held_qty
|
||||||
FROM {$wpdb->posts} AS posts
|
FROM {$wpdb->posts} AS posts
|
||||||
LEFT JOIN {$wpdb->prefix}woocommerce_order_items as order_items ON posts.ID = order_items.order_id
|
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(),
|
$product->get_stock_managed_by_id(),
|
||||||
$order_id
|
$order_id
|
||||||
)
|
)
|
||||||
);
|
); // WPCS: unprepared SQL ok.
|
||||||
|
|
||||||
if ( $product->get_stock_quantity() < ( $held_stock + $product_qty_in_cart[ $product->get_stock_managed_by_id() ] ) ) {
|
if ( $product->get_stock_quantity() < ( $held_stock + $product_qty_in_cart[ $product->get_stock_managed_by_id() ] ) ) {
|
||||||
/* translators: 1: product name 2: minutes */
|
/* translators: 1: product name 2: minutes */
|
||||||
|
@ -893,16 +890,16 @@ class WC_Cart extends WC_Legacy_Cart {
|
||||||
foreach ( $taxes as $key => $tax ) {
|
foreach ( $taxes as $key => $tax ) {
|
||||||
$code = WC_Tax::get_rate_code( $key );
|
$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 ] ) ) {
|
if ( ! isset( $tax_totals[ $code ] ) ) {
|
||||||
$tax_totals[ $code ] = new stdClass();
|
$tax_totals[ $code ] = new stdClass();
|
||||||
$tax_totals[ $code ]->amount = 0;
|
$tax_totals[ $code ]->amount = 0;
|
||||||
}
|
}
|
||||||
$tax_totals[ $code ]->tax_rate_id = $key;
|
$tax_totals[ $code ]->tax_rate_id = $key;
|
||||||
$tax_totals[ $code ]->is_compound = WC_Tax::is_compound( $key );
|
$tax_totals[ $code ]->is_compound = WC_Tax::is_compound( $key );
|
||||||
$tax_totals[ $code ]->label = WC_Tax::get_rate_label( $key );
|
$tax_totals[ $code ]->label = WC_Tax::get_rate_label( $key );
|
||||||
$tax_totals[ $code ]->amount += wc_round_tax_total( $tax );
|
$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 ]->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 );
|
$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.
|
// 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.
|
// 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.
|
// Force quantity to 1 if sold individually and check for existing item in cart.
|
||||||
if ( $product_data->is_sold_individually() ) {
|
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.
|
// Stock check - only check if we're managing stock and backorders are not allowed.
|
||||||
if ( ! $product_data->is_in_stock() ) {
|
if ( ! $product_data->is_in_stock() ) {
|
||||||
|
/* translators: %s: product name */
|
||||||
throw new Exception( sprintf( __( 'You cannot add "%s" to the cart because the product is out of stock.', 'woocommerce' ), $product_data->get_name() ) );
|
throw new Exception( sprintf( __( 'You cannot add "%s" 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();
|
$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 ) ) {
|
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(
|
throw new Exception(
|
||||||
'<a href="%s" class="button wc-forward">%s</a> %s',
|
sprintf(
|
||||||
wc_get_cart_url(),
|
'<a href="%s" class="button wc-forward">%s</a> %s',
|
||||||
__( 'View Cart', 'woocommerce' ),
|
wc_get_cart_url(),
|
||||||
sprintf( __( 'You cannot add that amount to the cart — 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 ) )
|
__( 'View Cart', 'woocommerce' ),
|
||||||
) );
|
/* translators: 1: quantity in stock 2: current quantity */
|
||||||
|
sprintf( __( 'You cannot add that amount to the cart — 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;
|
$cart_item_key = $cart_id;
|
||||||
|
|
||||||
// Add item after merging with $cart_item_data - hook to allow plugins to modify cart item.
|
// 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(
|
$this->cart_contents[ $cart_item_key ] = apply_filters(
|
||||||
'key' => $cart_item_key,
|
'woocommerce_add_cart_item', array_merge(
|
||||||
'product_id' => $product_id,
|
$cart_item_data, array(
|
||||||
'variation_id' => $variation_id,
|
'key' => $cart_item_key,
|
||||||
'variation' => $variation,
|
'product_id' => $product_id,
|
||||||
'quantity' => $quantity,
|
'variation_id' => $variation_id,
|
||||||
'data' => $product_data,
|
'variation' => $variation,
|
||||||
'data_hash' => wc_get_cart_item_data_hash( $product_data ),
|
'quantity' => $quantity,
|
||||||
) ), $cart_item_key );
|
'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 );
|
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.
|
* 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 int $quantity contains the quantity of the item.
|
||||||
* @param bool $refresh_totals whether or not to calculate totals after setting the new qty.
|
* @param bool $refresh_totals whether or not to calculate totals after setting the new qty.
|
||||||
* @return bool
|
* @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 );
|
do_action( 'woocommerce_before_cart_item_quantity_zero', $cart_item_key, $this );
|
||||||
unset( $this->cart_contents[ $cart_item_key ] );
|
unset( $this->cart_contents[ $cart_item_key ] );
|
||||||
} else {
|
} 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;
|
$this->cart_contents[ $cart_item_key ]['quantity'] = $quantity;
|
||||||
do_action( 'woocommerce_after_cart_item_quantity_update', $cart_item_key, $quantity, $old_quantity, $this );
|
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();
|
$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' );
|
$shipping_taxes = wp_list_pluck( $this->shipping_methods, 'taxes' );
|
||||||
$merged_taxes = array();
|
$merged_taxes = array();
|
||||||
foreach ( $shipping_taxes as $taxes ) {
|
foreach ( $shipping_taxes as $taxes ) {
|
||||||
foreach ( $taxes as $tax_id => $tax_amount ) {
|
foreach ( $taxes as $tax_id => $tax_amount ) {
|
||||||
if ( ! isset( $merged_taxes[ $tax_id ] ) ) {
|
if ( ! isset( $merged_taxes[ $tax_id ] ) ) {
|
||||||
|
@ -1280,7 +1285,7 @@ class WC_Cart extends WC_Legacy_Cart {
|
||||||
$chosen_methods = array();
|
$chosen_methods = array();
|
||||||
// Get chosen methods for each package to get our totals.
|
// Get chosen methods for each package to get our totals.
|
||||||
foreach ( $calculated_shipping_packages as $key => $package ) {
|
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 ) {
|
if ( $chosen_method ) {
|
||||||
$chosen_methods[ $key ] = $package['rates'][ $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
|
* @return array of cart items
|
||||||
*/
|
*/
|
||||||
public function get_shipping_packages() {
|
public function get_shipping_packages() {
|
||||||
return apply_filters( 'woocommerce_cart_shipping_packages',
|
return apply_filters(
|
||||||
|
'woocommerce_cart_shipping_packages',
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
'contents' => $this->get_items_needing_shipping(),
|
'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' => $this->get_customer()->get_shipping_address(),
|
||||||
'address_2' => $this->get_customer()->get_shipping_address_2(),
|
'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.
|
// Get user and posted emails to compare.
|
||||||
$current_user = wp_get_current_user();
|
$current_user = wp_get_current_user();
|
||||||
$check_emails = array_unique( array_filter( array_map( 'strtolower', array_map( 'sanitize_email', array(
|
$check_emails = array_unique(
|
||||||
$posted['billing_email'],
|
array_filter(
|
||||||
$current_user->user_email,
|
array_map(
|
||||||
) ) ) ) );
|
'strtolower', array_map(
|
||||||
|
'sanitize_email', array(
|
||||||
|
$posted['billing_email'],
|
||||||
|
$current_user->user_email,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Limit to defined email addresses.
|
// Limit to defined email addresses.
|
||||||
$restrictions = $coupon->get_email_restrictions();
|
$restrictions = $coupon->get_email_restrictions();
|
||||||
|
@ -1474,21 +1488,23 @@ class WC_Cart extends WC_Legacy_Cart {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check against billing emails of existing users.
|
// Check against billing emails of existing users.
|
||||||
$users_query = new WP_User_Query( array(
|
$users_query = new WP_User_Query(
|
||||||
'fields' => 'ID',
|
array(
|
||||||
'meta_query' => array(
|
'fields' => 'ID',
|
||||||
array(
|
'meta_query' => array(
|
||||||
'key' => '_billing_email',
|
array(
|
||||||
'value' => $check_emails,
|
'key' => '_billing_email',
|
||||||
'compare' => 'IN',
|
'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() ) ) );
|
$user_id_matches = array_unique( array_filter( array_merge( $user_id_matches, $users_query->get_results() ) ) );
|
||||||
|
|
||||||
foreach ( $user_id_matches as $user_id ) {
|
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() ) {
|
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 ) {
|
foreach ( $check_emails as $check_email ) {
|
||||||
// With a direct match we return true.
|
// With a direct match we return true.
|
||||||
if ( in_array( $check_email, $restrictions ) ) {
|
if ( in_array( $check_email, $restrictions, true ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1545,7 +1561,7 @@ class WC_Cart extends WC_Legacy_Cart {
|
||||||
* Applies a coupon code passed to the method.
|
* Applies a coupon code passed to the method.
|
||||||
*
|
*
|
||||||
* @param string $coupon_code - The code to apply.
|
* @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 ) {
|
public function apply_coupon( $coupon_code ) {
|
||||||
// Coupons are globally disabled.
|
// Coupons are globally disabled.
|
||||||
|
@ -1615,7 +1631,7 @@ class WC_Cart extends WC_Legacy_Cart {
|
||||||
|
|
||||||
// Choose free shipping.
|
// Choose free shipping.
|
||||||
if ( $the_coupon->get_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' );
|
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
||||||
|
|
||||||
foreach ( $packages as $i => $package ) {
|
foreach ( $packages as $i => $package ) {
|
||||||
|
@ -1646,7 +1662,7 @@ class WC_Cart extends WC_Legacy_Cart {
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ( $this->get_applied_coupons() as $code ) {
|
foreach ( $this->get_applied_coupons() as $code ) {
|
||||||
$coupon = new WC_Coupon( $code );
|
$coupon = new WC_Coupon( $code );
|
||||||
$coupons[ $code ] = $coupon;
|
$coupons[ $code ] = $coupon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1662,7 +1678,7 @@ class WC_Cart extends WC_Legacy_Cart {
|
||||||
*/
|
*/
|
||||||
public function get_coupon_discount_amount( $code, $ex_tax = true ) {
|
public function get_coupon_discount_amount( $code, $ex_tax = true ) {
|
||||||
$totals = $this->get_coupon_discount_totals();
|
$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 ) {
|
if ( ! $ex_tax ) {
|
||||||
$discount_amount += $this->get_coupon_discount_tax_amount( $code );
|
$discount_amount += $this->get_coupon_discount_tax_amount( $code );
|
||||||
|
@ -1701,8 +1717,8 @@ class WC_Cart extends WC_Legacy_Cart {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function remove_coupon( $coupon_code ) {
|
public function remove_coupon( $coupon_code ) {
|
||||||
$coupon_code = wc_format_coupon_code( $coupon_code );
|
$coupon_code = wc_format_coupon_code( $coupon_code );
|
||||||
$position = array_search( $coupon_code, $this->get_applied_coupons(), true );
|
$position = array_search( $coupon_code, $this->get_applied_coupons(), true );
|
||||||
|
|
||||||
if ( false !== $position ) {
|
if ( false !== $position ) {
|
||||||
unset( $this->applied_coupons[ $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: '').
|
* @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 = '' ) {
|
public function add_fee( $name, $amount, $taxable = false, $tax_class = '' ) {
|
||||||
$this->fees_api()->add_fee( array(
|
$this->fees_api()->add_fee(
|
||||||
'name' => $name,
|
array(
|
||||||
'amount' => (float) $amount,
|
'name' => $name,
|
||||||
'taxable' => $taxable,
|
'amount' => (float) $amount,
|
||||||
'tax_class' => $tax_class,
|
'taxable' => $taxable,
|
||||||
) );
|
'tax_class' => $tax_class,
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
<?php
|
<?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.
|
* The WooCommerce checkout class handles the checkout process, collecting user data and processing the payment.
|
||||||
*
|
*
|
||||||
* @class WC_Checkout
|
* @package WooCommerce/Classes
|
||||||
* @package WooCommerce/Classes
|
* @version 3.4.0
|
||||||
* @category Class
|
*/
|
||||||
* @author WooThemes
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checkout class.
|
||||||
*/
|
*/
|
||||||
class WC_Checkout {
|
class WC_Checkout {
|
||||||
|
|
||||||
|
@ -32,6 +31,7 @@ class WC_Checkout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds posted data for backwards compatibility.
|
* Holds posted data for backwards compatibility.
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $legacy_posted_data = 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.
|
* 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
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function __isset( $key ) {
|
public function __isset( $key ) {
|
||||||
return in_array( $key, array(
|
return in_array(
|
||||||
'enable_signup',
|
$key,
|
||||||
'enable_guest_checkout',
|
array(
|
||||||
'must_create_account',
|
'enable_signup',
|
||||||
'checkout_fields',
|
'enable_guest_checkout',
|
||||||
'posted',
|
'must_create_account',
|
||||||
'shipping_method',
|
'checkout_fields',
|
||||||
'payment_method',
|
'posted',
|
||||||
'customer_id',
|
'shipping_method',
|
||||||
'shipping_methods',
|
'payment_method',
|
||||||
) );
|
'customer_id',
|
||||||
|
'shipping_methods',
|
||||||
|
),
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the legacy public variables for backwards compatibility.
|
* Sets the legacy public variables for backwards compatibility.
|
||||||
*
|
*
|
||||||
* @param string $key
|
* @param string $key Key.
|
||||||
* @param mixed $value
|
* @param mixed $value Value.
|
||||||
*/
|
*/
|
||||||
public function __set( $key, $value ) {
|
public function __set( $key, $value ) {
|
||||||
switch ( $key ) {
|
switch ( $key ) {
|
||||||
case 'enable_signup' :
|
case 'enable_signup':
|
||||||
$bool_value = wc_string_to_bool( $value );
|
$bool_value = wc_string_to_bool( $value );
|
||||||
|
|
||||||
if ( $bool_value !== $this->is_registration_enabled() ) {
|
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 );
|
add_filter( 'woocommerce_checkout_registration_enabled', $bool_value ? '__return_true' : '__return_false', 0 );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'enable_guest_checkout' :
|
case 'enable_guest_checkout':
|
||||||
$bool_value = wc_string_to_bool( $value );
|
$bool_value = wc_string_to_bool( $value );
|
||||||
|
|
||||||
if ( $bool_value === $this->is_registration_required() ) {
|
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 );
|
add_filter( 'woocommerce_checkout_registration_required', $bool_value ? '__return_false' : '__return_true', 0 );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'checkout_fields' :
|
case 'checkout_fields':
|
||||||
$this->fields = $value;
|
$this->fields = $value;
|
||||||
break;
|
break;
|
||||||
case 'shipping_methods' :
|
case 'shipping_methods':
|
||||||
WC()->session->set( 'chosen_shipping_methods', $value );
|
WC()->session->set( 'chosen_shipping_methods', $value );
|
||||||
break;
|
break;
|
||||||
case 'posted' :
|
case 'posted':
|
||||||
$this->legacy_posted_data = $value;
|
$this->legacy_posted_data = $value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -118,33 +122,32 @@ class WC_Checkout {
|
||||||
/**
|
/**
|
||||||
* Gets the legacy public variables for backwards compatibility.
|
* Gets the legacy public variables for backwards compatibility.
|
||||||
*
|
*
|
||||||
* @param string $key
|
* @param string $key Key.
|
||||||
*
|
|
||||||
* @return array|string
|
* @return array|string
|
||||||
*/
|
*/
|
||||||
public function __get( $key ) {
|
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();
|
$this->legacy_posted_data = $this->get_posted_data();
|
||||||
}
|
}
|
||||||
switch ( $key ) {
|
switch ( $key ) {
|
||||||
case 'enable_signup' :
|
case 'enable_signup':
|
||||||
return $this->is_registration_enabled();
|
return $this->is_registration_enabled();
|
||||||
case 'enable_guest_checkout' :
|
case 'enable_guest_checkout':
|
||||||
return ! $this->is_registration_required();
|
return ! $this->is_registration_required();
|
||||||
case 'must_create_account' :
|
case 'must_create_account':
|
||||||
return $this->is_registration_required() && ! is_user_logged_in();
|
return $this->is_registration_required() && ! is_user_logged_in();
|
||||||
case 'checkout_fields' :
|
case 'checkout_fields':
|
||||||
return $this->get_checkout_fields();
|
return $this->get_checkout_fields();
|
||||||
case 'posted' :
|
case 'posted':
|
||||||
wc_doing_it_wrong( 'WC_Checkout->posted', 'Use $_POST directly.', '3.0.0' );
|
wc_doing_it_wrong( 'WC_Checkout->posted', 'Use $_POST directly.', '3.0.0' );
|
||||||
return $this->legacy_posted_data;
|
return $this->legacy_posted_data;
|
||||||
case 'shipping_method' :
|
case 'shipping_method':
|
||||||
return $this->legacy_posted_data['shipping_method'];
|
return $this->legacy_posted_data['shipping_method'];
|
||||||
case 'payment_method' :
|
case 'payment_method':
|
||||||
return $this->legacy_posted_data['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() );
|
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' );
|
return (array) WC()->session->get( 'chosen_shipping_methods' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,19 +209,19 @@ class WC_Checkout {
|
||||||
);
|
);
|
||||||
if ( 'no' === get_option( 'woocommerce_registration_generate_username' ) ) {
|
if ( 'no' === get_option( 'woocommerce_registration_generate_username' ) ) {
|
||||||
$this->fields['account']['account_username'] = array(
|
$this->fields['account']['account_username'] = array(
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'label' => __( 'Account username', 'woocommerce' ),
|
'label' => __( 'Account username', 'woocommerce' ),
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'placeholder' => esc_attr__( 'Username', 'woocommerce' ),
|
'placeholder' => esc_attr__( 'Username', 'woocommerce' ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'no' === get_option( 'woocommerce_registration_generate_password' ) ) {
|
if ( 'no' === get_option( 'woocommerce_registration_generate_password' ) ) {
|
||||||
$this->fields['account']['account_password'] = array(
|
$this->fields['account']['account_password'] = array(
|
||||||
'type' => 'password',
|
'type' => 'password',
|
||||||
'label' => __( 'Create account password', 'woocommerce' ),
|
'label' => __( 'Create account password', 'woocommerce' ),
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'placeholder' => esc_attr__( 'Password', 'woocommerce' ),
|
'placeholder' => esc_attr__( 'Password', 'woocommerce' ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,29 +257,31 @@ class WC_Checkout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an order. Error codes:
|
* Create an order. Error codes:
|
||||||
* 520 - Cannot insert order into the database.
|
* 520 - Cannot insert order into the database.
|
||||||
* 521 - Cannot get order after creation.
|
* 521 - Cannot get order after creation.
|
||||||
* 522 - Cannot update order.
|
* 522 - Cannot update order.
|
||||||
* 525 - Cannot create line item.
|
* 525 - Cannot create line item.
|
||||||
* 526 - Cannot create fee item.
|
* 526 - Cannot create fee item.
|
||||||
* 527 - Cannot create shipping item.
|
* 527 - Cannot create shipping item.
|
||||||
* 528 - Cannot create tax item.
|
* 528 - Cannot create tax item.
|
||||||
* 529 - Cannot create coupon item.
|
* 529 - Cannot create coupon item.
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception When checkout validation fails.
|
||||||
* @param $data Posted data.
|
* @param array $data Posted data.
|
||||||
* @return int|WP_ERROR
|
* @return int|WP_ERROR
|
||||||
*/
|
*/
|
||||||
public function create_order( $data ) {
|
public function create_order( $data ) {
|
||||||
// Give plugins the opportunity to create an order themselves.
|
// 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;
|
return $order_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$order_id = absint( WC()->session->get( 'order_awaiting_payment' ) );
|
$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();
|
$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
|
* 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
|
* different items or cost, create a new order. We use a hash to
|
||||||
* detect changes which is based on cart items + order total.
|
* 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.
|
// Action for 3rd parties.
|
||||||
do_action( 'woocommerce_resume_order', $order_id );
|
do_action( 'woocommerce_resume_order', $order_id );
|
||||||
|
|
||||||
|
@ -298,10 +303,10 @@ class WC_Checkout {
|
||||||
if ( is_callable( array( $order, "set_{$key}" ) ) ) {
|
if ( is_callable( array( $order, "set_{$key}" ) ) ) {
|
||||||
$order->{"set_{$key}"}( $value );
|
$order->{"set_{$key}"}( $value );
|
||||||
|
|
||||||
// Store custom fields prefixed with wither shipping_ or billing_. This is for backwards compatibility with 2.6.x.
|
// 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.
|
// 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_' ) )
|
} 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 );
|
$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_ip_address( WC_Geolocation::get_ip_address() );
|
||||||
$order->set_customer_user_agent( wc_get_user_agent() );
|
$order->set_customer_user_agent( wc_get_user_agent() );
|
||||||
$order->set_customer_note( isset( $data['order_comments'] ) ? $data['order_comments'] : '' );
|
$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_shipping_total( WC()->cart->get_shipping_total() );
|
||||||
$order->set_discount_total( WC()->cart->get_discount_total() );
|
$order->set_discount_total( WC()->cart->get_discount_total() );
|
||||||
$order->set_discount_tax( WC()->cart->get_discount_tax() );
|
$order->set_discount_tax( WC()->cart->get_discount_tax() );
|
||||||
|
@ -329,6 +334,7 @@ class WC_Checkout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action hook to adjust order before save.
|
* Action hook to adjust order before save.
|
||||||
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_checkout_create_order', $order, $data );
|
do_action( 'woocommerce_checkout_create_order', $order, $data );
|
||||||
|
@ -347,40 +353,46 @@ class WC_Checkout {
|
||||||
/**
|
/**
|
||||||
* Add line items to the order.
|
* Add line items to the order.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order
|
* @param WC_Order $order Order instance.
|
||||||
* @param WC_Cart $cart
|
* @param WC_Cart $cart Cart instance.
|
||||||
*/
|
*/
|
||||||
public function create_order_line_items( &$order, $cart ) {
|
public function create_order_line_items( &$order, $cart ) {
|
||||||
foreach ( $cart->get_cart() as $cart_item_key => $values ) {
|
foreach ( $cart->get_cart() as $cart_item_key => $values ) {
|
||||||
/**
|
/**
|
||||||
* Filter hook to get initial item object.
|
* Filter hook to get initial item object.
|
||||||
|
*
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
*/
|
*/
|
||||||
$item = apply_filters( 'woocommerce_checkout_create_order_line_item_object', new WC_Order_Item_Product(), $cart_item_key, $values, $order );
|
$item = apply_filters( 'woocommerce_checkout_create_order_line_item_object', new WC_Order_Item_Product(), $cart_item_key, $values, $order );
|
||||||
$product = $values['data'];
|
$product = $values['data'];
|
||||||
$item->legacy_values = $values; // @deprecated For legacy actions.
|
$item->legacy_values = $values; // @deprecated For legacy actions.
|
||||||
$item->legacy_cart_item_key = $cart_item_key; // @deprecated For legacy actions.
|
$item->legacy_cart_item_key = $cart_item_key; // @deprecated For legacy actions.
|
||||||
$item->set_props( array(
|
$item->set_props(
|
||||||
'quantity' => $values['quantity'],
|
array(
|
||||||
'variation' => $values['variation'],
|
'quantity' => $values['quantity'],
|
||||||
'subtotal' => $values['line_subtotal'],
|
'variation' => $values['variation'],
|
||||||
'total' => $values['line_total'],
|
'subtotal' => $values['line_subtotal'],
|
||||||
'subtotal_tax' => $values['line_subtotal_tax'],
|
'total' => $values['line_total'],
|
||||||
'total_tax' => $values['line_tax'],
|
'subtotal_tax' => $values['line_subtotal_tax'],
|
||||||
'taxes' => $values['line_tax_data'],
|
'total_tax' => $values['line_tax'],
|
||||||
) );
|
'taxes' => $values['line_tax_data'],
|
||||||
|
)
|
||||||
|
);
|
||||||
if ( $product ) {
|
if ( $product ) {
|
||||||
$item->set_props( array(
|
$item->set_props(
|
||||||
'name' => $product->get_name(),
|
array(
|
||||||
'tax_class' => $product->get_tax_class(),
|
'name' => $product->get_name(),
|
||||||
'product_id' => $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id(),
|
'tax_class' => $product->get_tax_class(),
|
||||||
'variation_id' => $product->is_type( 'variation' ) ? $product->get_id() : 0,
|
'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();
|
$item->set_backorder_meta();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action hook to adjust item before save.
|
* Action hook to adjust item before save.
|
||||||
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_checkout_create_order_line_item', $item, $cart_item_key, $values, $order );
|
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.
|
* Add fees to the order.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order
|
* @param WC_Order $order Order instance.
|
||||||
* @param WC_Cart $cart
|
* @param WC_Cart $cart Cart instance.
|
||||||
*/
|
*/
|
||||||
public function create_order_fee_lines( &$order, $cart ) {
|
public function create_order_fee_lines( &$order, $cart ) {
|
||||||
foreach ( $cart->get_fees() as $fee_key => $fee ) {
|
foreach ( $cart->get_fees() as $fee_key => $fee ) {
|
||||||
$item = new WC_Order_Item_Fee();
|
$item = new WC_Order_Item_Fee();
|
||||||
$item->legacy_fee = $fee; // @deprecated For legacy actions.
|
$item->legacy_fee = $fee; // @deprecated For legacy actions.
|
||||||
$item->legacy_fee_key = $fee_key; // @deprecated For legacy actions.
|
$item->legacy_fee_key = $fee_key; // @deprecated For legacy actions.
|
||||||
$item->set_props( array(
|
$item->set_props(
|
||||||
'name' => $fee->name,
|
array(
|
||||||
'tax_class' => $fee->taxable ? $fee->tax_class: 0,
|
'name' => $fee->name,
|
||||||
'amount' => $fee->amount,
|
'tax_class' => $fee->taxable ? $fee->tax_class : 0,
|
||||||
'total' => $fee->total,
|
'amount' => $fee->amount,
|
||||||
'total_tax' => $fee->tax,
|
'total' => $fee->total,
|
||||||
'taxes' => array(
|
'total_tax' => $fee->tax,
|
||||||
'total' => $fee->tax_data,
|
'taxes' => array(
|
||||||
),
|
'total' => $fee->tax_data,
|
||||||
) );
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action hook to adjust item before save.
|
* Action hook to adjust item before save.
|
||||||
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_checkout_create_order_fee_item', $item, $fee_key, $fee, $order );
|
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.
|
* Add shipping lines to the order.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order
|
* @param WC_Order $order Order Instance.
|
||||||
* @param array $chosen_shipping_methods
|
* @param array $chosen_shipping_methods Chosen shipping methods.
|
||||||
* @param array $packages
|
* @param array $packages Packages.
|
||||||
*/
|
*/
|
||||||
public function create_order_shipping_lines( &$order, $chosen_shipping_methods, $packages ) {
|
public function create_order_shipping_lines( &$order, $chosen_shipping_methods, $packages ) {
|
||||||
foreach ( $packages as $package_key => $package ) {
|
foreach ( $packages as $package_key => $package ) {
|
||||||
if ( isset( $chosen_shipping_methods[ $package_key ], $package['rates'][ $chosen_shipping_methods[ $package_key ] ] ) ) {
|
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 ] ];
|
$shipping_rate = $package['rates'][ $chosen_shipping_methods[ $package_key ] ];
|
||||||
$item = new WC_Order_Item_Shipping();
|
$item = new WC_Order_Item_Shipping();
|
||||||
$item->legacy_package_key = $package_key; // @deprecated For legacy actions.
|
$item->legacy_package_key = $package_key; // @deprecated For legacy actions.
|
||||||
$item->set_props( array(
|
$item->set_props(
|
||||||
'method_title' => $shipping_rate->label,
|
array(
|
||||||
'method_id' => $shipping_rate->method_id,
|
'method_title' => $shipping_rate->label,
|
||||||
'instance_id' => $shipping_rate->instance_id,
|
'method_id' => $shipping_rate->method_id,
|
||||||
'total' => wc_format_decimal( $shipping_rate->cost ),
|
'instance_id' => $shipping_rate->instance_id,
|
||||||
'taxes' => array(
|
'total' => wc_format_decimal( $shipping_rate->cost ),
|
||||||
'total' => $shipping_rate->taxes,
|
'taxes' => array(
|
||||||
),
|
'total' => $shipping_rate->taxes,
|
||||||
) );
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
foreach ( $shipping_rate->get_meta_data() as $key => $value ) {
|
foreach ( $shipping_rate->get_meta_data() as $key => $value ) {
|
||||||
$item->add_meta_data( $key, $value, true );
|
$item->add_meta_data( $key, $value, true );
|
||||||
|
@ -453,6 +469,7 @@ class WC_Checkout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action hook to adjust item before save.
|
* Action hook to adjust item before save.
|
||||||
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_checkout_create_order_shipping_item', $item, $package_key, $package, $order );
|
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.
|
* Add tax lines to the order.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order
|
* @param WC_Order $order Order instance.
|
||||||
* @param WC_Cart $cart
|
* @param WC_Cart $cart Cart instance.
|
||||||
*/
|
*/
|
||||||
public function create_order_tax_lines( &$order, $cart ) {
|
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 ) {
|
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 ) {
|
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 = new WC_Order_Item_Tax();
|
||||||
$item->set_props( array(
|
$item->set_props(
|
||||||
'rate_id' => $tax_rate_id,
|
array(
|
||||||
'tax_total' => $cart->get_tax_amount( $tax_rate_id ),
|
'rate_id' => $tax_rate_id,
|
||||||
'shipping_tax_total' => $cart->get_shipping_tax_amount( $tax_rate_id ),
|
'tax_total' => $cart->get_tax_amount( $tax_rate_id ),
|
||||||
'rate_code' => WC_Tax::get_rate_code( $tax_rate_id ),
|
'shipping_tax_total' => $cart->get_shipping_tax_amount( $tax_rate_id ),
|
||||||
'label' => WC_Tax::get_rate_label( $tax_rate_id ),
|
'rate_code' => WC_Tax::get_rate_code( $tax_rate_id ),
|
||||||
'compound' => WC_Tax::is_compound( $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.
|
* Action hook to adjust item before save.
|
||||||
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_checkout_create_order_tax_item', $item, $tax_rate_id, $order );
|
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.
|
* Add coupon lines to the order.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order
|
* @param WC_Order $order Order instance.
|
||||||
* @param WC_Cart $cart
|
* @param WC_Cart $cart Cart instance.
|
||||||
*/
|
*/
|
||||||
public function create_order_coupon_lines( &$order, $cart ) {
|
public function create_order_coupon_lines( &$order, $cart ) {
|
||||||
foreach ( $cart->get_coupons() as $code => $coupon ) {
|
foreach ( $cart->get_coupons() as $code => $coupon ) {
|
||||||
$item = new WC_Order_Item_Coupon();
|
$item = new WC_Order_Item_Coupon();
|
||||||
$item->set_props( array(
|
$item->set_props(
|
||||||
'code' => $code,
|
array(
|
||||||
'discount' => $cart->get_coupon_discount_amount( $code ),
|
'code' => $code,
|
||||||
'discount_tax' => $cart->get_coupon_discount_tax_amount( $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() );
|
$item->add_meta_data( 'coupon_data', $coupon->get_data() );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action hook to adjust item before save.
|
* Action hook to adjust item before save.
|
||||||
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_checkout_create_order_coupon_item', $item, $code, $coupon, $order );
|
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.
|
* See if a fieldset should be skipped.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*
|
* @param string $fieldset_key Fieldset key.
|
||||||
* @param string $fieldset_key
|
* @param array $data Posted data.
|
||||||
* @param array $data
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function maybe_skip_fieldset( $fieldset_key, $data ) {
|
protected function maybe_skip_fieldset( $fieldset_key, $data ) {
|
||||||
|
@ -550,12 +571,12 @@ class WC_Checkout {
|
||||||
public function get_posted_data() {
|
public function get_posted_data() {
|
||||||
$skipped = array();
|
$skipped = array();
|
||||||
$data = array(
|
$data = array(
|
||||||
'terms' => (int) isset( $_POST['terms'] ),
|
'terms' => (int) isset( $_POST['terms'] ), // WPCS: input var ok, CSRF ok.
|
||||||
'createaccount' => (int) ! empty( $_POST['createaccount'] ),
|
'createaccount' => (int) ! empty( $_POST['createaccount'] ), // WPCS: input var ok, CSRF ok.
|
||||||
'payment_method' => isset( $_POST['payment_method'] ) ? wc_clean( $_POST['payment_method'] ) : '',
|
'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( $_POST['shipping_method'] ) : '',
|
'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(),
|
'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'] ),
|
'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 ) {
|
foreach ( $this->get_checkout_fields() as $fieldset_key => $fieldset ) {
|
||||||
if ( $this->maybe_skip_fieldset( $fieldset_key, $data ) ) {
|
if ( $this->maybe_skip_fieldset( $fieldset_key, $data ) ) {
|
||||||
|
@ -566,17 +587,17 @@ class WC_Checkout {
|
||||||
$type = sanitize_title( isset( $field['type'] ) ? $field['type'] : 'text' );
|
$type = sanitize_title( isset( $field['type'] ) ? $field['type'] : 'text' );
|
||||||
|
|
||||||
switch ( $type ) {
|
switch ( $type ) {
|
||||||
case 'checkbox' :
|
case 'checkbox':
|
||||||
$value = isset( $_POST[ $key ] ) ? 1 : '';
|
$value = isset( $_POST[ $key ] ) ? 1 : ''; // WPCS: input var ok, CSRF ok.
|
||||||
break;
|
break;
|
||||||
case 'multiselect' :
|
case 'multiselect':
|
||||||
$value = isset( $_POST[ $key ] ) ? implode( ', ', wc_clean( $_POST[ $key ] ) ) : '';
|
$value = isset( $_POST[ $key ] ) ? implode( ', ', wc_clean( wp_unslash( $_POST[ $key ] ) ) ) : ''; // WPCS: input var ok, CSRF ok.
|
||||||
break;
|
break;
|
||||||
case 'textarea' :
|
case 'textarea':
|
||||||
$value = isset( $_POST[ $key ] ) ? wc_sanitize_textarea( $_POST[ $key ] ) : '';
|
$value = isset( $_POST[ $key ] ) ? wc_sanitize_textarea( wp_unslash( $_POST[ $key ] ) ) : ''; // WPCS: input var ok, CSRF ok.
|
||||||
break;
|
break;
|
||||||
default :
|
default:
|
||||||
$value = isset( $_POST[ $key ] ) ? wc_clean( $_POST[ $key ] ) : '';
|
$value = isset( $_POST[ $key ] ) ? wc_clean( wp_unslash( $_POST[ $key ] ) ) : ''; // WPCS: input var ok, CSRF ok.
|
||||||
break;
|
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 ) {
|
foreach ( $this->get_checkout_fields( 'shipping' ) as $key => $field ) {
|
||||||
$data[ $key ] = isset( $data[ 'billing_' . substr( $key, 9 ) ] ) ? $data[ 'billing_' . substr( $key, 9 ) ] : '';
|
$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.
|
* Validates the posted checkout data based on field properties.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
* @param array $data An array of posted data.
|
* @param array $data An array of posted data.
|
||||||
* @param WP_Error $errors
|
* @param WP_Error $errors Validation error.
|
||||||
*/
|
*/
|
||||||
protected function validate_posted_data( &$data, &$errors ) {
|
protected function validate_posted_data( &$data, &$errors ) {
|
||||||
foreach ( $this->get_checkout_fields() as $fieldset_key => $fieldset ) {
|
foreach ( $this->get_checkout_fields() as $fieldset_key => $fieldset ) {
|
||||||
|
@ -617,26 +638,27 @@ class WC_Checkout {
|
||||||
$field_label = isset( $field['label'] ) ? $field['label'] : '';
|
$field_label = isset( $field['label'] ) ? $field['label'] : '';
|
||||||
|
|
||||||
switch ( $fieldset_key ) {
|
switch ( $fieldset_key ) {
|
||||||
case 'shipping' :
|
case 'shipping':
|
||||||
/* translators: %s: field name */
|
/* translators: %s: field name */
|
||||||
$field_label = sprintf( __( 'Shipping %s', 'woocommerce' ), $field_label );
|
$field_label = sprintf( __( 'Shipping %s', 'woocommerce' ), $field_label );
|
||||||
break;
|
break;
|
||||||
case 'billing' :
|
case 'billing':
|
||||||
/* translators: %s: field name */
|
/* translators: %s: field name */
|
||||||
$field_label = sprintf( __( 'Billing %s', 'woocommerce' ), $field_label );
|
$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"}();
|
$country = isset( $data[ $fieldset_key . '_country' ] ) ? $data[ $fieldset_key . '_country' ] : WC()->customer->{"get_{$fieldset_key}_country"}();
|
||||||
$data[ $key ] = wc_format_postcode( $data[ $key ], $country );
|
$data[ $key ] = wc_format_postcode( $data[ $key ], $country );
|
||||||
|
|
||||||
if ( '' !== $data[ $key ] && ! WC_Validation::is_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>' ) );
|
$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 ] );
|
$data[ $key ] = wc_format_phone_number( $data[ $key ] );
|
||||||
|
|
||||||
if ( '' !== $data[ $key ] && ! WC_Validation::is_phone( $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 ] );
|
$data[ $key ] = sanitize_email( $data[ $key ] );
|
||||||
|
|
||||||
if ( ! is_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"}();
|
$country = isset( $data[ $fieldset_key . '_country' ] ) ? $data[ $fieldset_key . '_country' ] : WC()->customer->{"get_{$fieldset_key}_country"}();
|
||||||
$valid_states = WC()->countries->get_states( $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 ) ) );
|
$valid_state_values = array_map( 'wc_strtoupper', array_flip( array_map( 'wc_strtoupper', $valid_states ) ) );
|
||||||
$data[ $key ] = wc_strtoupper( $data[ $key ] );
|
$data[ $key ] = wc_strtoupper( $data[ $key ] );
|
||||||
|
|
||||||
|
@ -668,7 +690,7 @@ class WC_Checkout {
|
||||||
$data[ $key ] = $valid_state_values[ $data[ $key ] ];
|
$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 */
|
/* 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 ) ) );
|
$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.
|
* Validates that the checkout has enough info to proceed.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
* @param array $data An array of posted data.
|
* @param array $data An array of posted data.
|
||||||
* @param WP_Error $errors
|
* @param WP_Error $errors Validation errors.
|
||||||
*/
|
*/
|
||||||
protected function validate_checkout( &$data, &$errors ) {
|
protected function validate_checkout( &$data, &$errors ) {
|
||||||
$this->validate_posted_data( $data, $errors );
|
$this->validate_posted_data( $data, $errors );
|
||||||
$this->check_cart_items();
|
$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 & Conditions.', 'woocommerce' ) );
|
$errors->add( 'terms', __( 'You must accept our Terms & Conditions.', 'woocommerce' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,7 +725,8 @@ class WC_Checkout {
|
||||||
|
|
||||||
if ( empty( $shipping_country ) ) {
|
if ( empty( $shipping_country ) ) {
|
||||||
$errors->add( 'shipping', __( 'Please enter an address to continue.', 'woocommerce' ) );
|
$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() ) );
|
$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 {
|
} else {
|
||||||
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
||||||
|
@ -733,9 +756,9 @@ class WC_Checkout {
|
||||||
* Set address field for customer.
|
* Set address field for customer.
|
||||||
*
|
*
|
||||||
* @since 3.0.7
|
* @since 3.0.7
|
||||||
* @param $field string to update
|
* @param string $field String to update.
|
||||||
* @param $key
|
* @param string $key Field key.
|
||||||
* @param $data array of data to get the value from
|
* @param array $data Array of data to get the value from.
|
||||||
*/
|
*/
|
||||||
protected function set_customer_address_fields( $field, $key, $data ) {
|
protected function set_customer_address_fields( $field, $key, $data ) {
|
||||||
if ( isset( $data[ "billing_{$field}" ] ) ) {
|
if ( isset( $data[ "billing_{$field}" ] ) ) {
|
||||||
|
@ -750,8 +773,8 @@ class WC_Checkout {
|
||||||
/**
|
/**
|
||||||
* Update customer and session data from the posted checkout data.
|
* Update customer and session data from the posted checkout data.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
* @param array $data
|
* @param array $data Posted data.
|
||||||
*/
|
*/
|
||||||
protected function update_session( $data ) {
|
protected function update_session( $data ) {
|
||||||
// Update both shipping and billing to the passed billing address first if set.
|
// 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 );
|
array_walk( $address_fields, array( $this, 'set_customer_address_fields' ), $data );
|
||||||
WC()->customer->save();
|
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' );
|
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
||||||
|
|
||||||
if ( is_array( $data['shipping_method'] ) ) {
|
if ( is_array( $data['shipping_method'] ) ) {
|
||||||
|
@ -787,9 +810,9 @@ class WC_Checkout {
|
||||||
/**
|
/**
|
||||||
* Process an order that does require payment.
|
* Process an order that does require payment.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
* @param int $order_id
|
* @param int $order_id Order ID.
|
||||||
* @param string $payment_method
|
* @param string $payment_method Payment method.
|
||||||
*/
|
*/
|
||||||
protected function process_order_payment( $order_id, $payment_method ) {
|
protected function process_order_payment( $order_id, $payment_method ) {
|
||||||
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
|
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
|
||||||
|
@ -798,13 +821,13 @@ class WC_Checkout {
|
||||||
return;
|
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 );
|
WC()->session->set( 'order_awaiting_payment', $order_id );
|
||||||
|
|
||||||
// Process Payment
|
// Process Payment.
|
||||||
$result = $available_gateways[ $payment_method ]->process_payment( $order_id );
|
$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'] ) {
|
if ( isset( $result['result'] ) && 'success' === $result['result'] ) {
|
||||||
$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id );
|
$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.
|
* Process an order that doesn't require payment.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
* @param int $order_id
|
* @param int $order_id Order ID.
|
||||||
*/
|
*/
|
||||||
protected function process_order_without_payment( $order_id ) {
|
protected function process_order_without_payment( $order_id ) {
|
||||||
$order = wc_get_order( $order_id );
|
$order = wc_get_order( $order_id );
|
||||||
|
@ -829,10 +852,12 @@ class WC_Checkout {
|
||||||
wc_empty_cart();
|
wc_empty_cart();
|
||||||
|
|
||||||
if ( is_ajax() ) {
|
if ( is_ajax() ) {
|
||||||
wp_send_json( array(
|
wp_send_json(
|
||||||
'result' => 'success',
|
array(
|
||||||
'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $order->get_checkout_order_received_url(), $order ),
|
'result' => 'success',
|
||||||
) );
|
'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $order->get_checkout_order_received_url(), $order ),
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
wp_safe_redirect(
|
wp_safe_redirect(
|
||||||
apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $order->get_checkout_order_received_url(), $order )
|
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.
|
* 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 ) {
|
protected function process_customer( $data ) {
|
||||||
$customer_id = apply_filters( 'woocommerce_checkout_customer_id', get_current_user_id() );
|
$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 );
|
wp_set_current_user( $customer_id );
|
||||||
wc_set_customer_auth_cookie( $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 );
|
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();
|
WC()->cart->calculate_totals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,7 +921,7 @@ class WC_Checkout {
|
||||||
if ( is_callable( array( $customer, "set_{$key}" ) ) ) {
|
if ( is_callable( array( $customer, "set_{$key}" ) ) ) {
|
||||||
$customer->{"set_{$key}"}( $value );
|
$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_' ) ) {
|
} elseif ( 0 === stripos( $key, 'billing_' ) || 0 === stripos( $key, 'shipping_' ) ) {
|
||||||
$customer->update_meta_data( $key, $value );
|
$customer->update_meta_data( $key, $value );
|
||||||
}
|
}
|
||||||
|
@ -903,6 +929,7 @@ class WC_Checkout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action hook to adjust customer before save.
|
* Action hook to adjust customer before save.
|
||||||
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_checkout_update_customer', $customer, $data );
|
do_action( 'woocommerce_checkout_update_customer', $customer, $data );
|
||||||
|
@ -918,7 +945,7 @@ class WC_Checkout {
|
||||||
*/
|
*/
|
||||||
protected function send_ajax_failure_response() {
|
protected function send_ajax_failure_response() {
|
||||||
if ( is_ajax() ) {
|
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 ) ) {
|
if ( ! isset( WC()->session->reload_checkout ) ) {
|
||||||
ob_start();
|
ob_start();
|
||||||
wc_print_notices();
|
wc_print_notices();
|
||||||
|
@ -940,6 +967,8 @@ class WC_Checkout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the checkout after the confirm order button is pressed.
|
* Process the checkout after the confirm order button is pressed.
|
||||||
|
*
|
||||||
|
* @throws Exception When validation fails.
|
||||||
*/
|
*/
|
||||||
public function process_checkout() {
|
public function process_checkout() {
|
||||||
try {
|
try {
|
||||||
|
@ -956,6 +985,7 @@ class WC_Checkout {
|
||||||
do_action( 'woocommerce_before_checkout_process' );
|
do_action( 'woocommerce_before_checkout_process' );
|
||||||
|
|
||||||
if ( WC()->cart->is_empty() ) {
|
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' ) ) ) );
|
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' ) ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,8 +1030,8 @@ class WC_Checkout {
|
||||||
/**
|
/**
|
||||||
* Get a posted address field after sanitization and validation.
|
* Get a posted address field after sanitization and validation.
|
||||||
*
|
*
|
||||||
* @param string $key
|
* @param string $key Field key.
|
||||||
* @param string $type billing for shipping
|
* @param string $type Type of address. Available options: 'billing' or 'shipping'.
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function get_posted_address_data( $key, $type = 'billing' ) {
|
public function get_posted_address_data( $key, $type = 'billing' ) {
|
||||||
|
@ -1016,12 +1046,12 @@ class WC_Checkout {
|
||||||
/**
|
/**
|
||||||
* Gets the value either from the posted data, or from the users meta data.
|
* Gets the value either from the posted data, or from the users meta data.
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input Input key.
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function get_value( $input ) {
|
public function get_value( $input ) {
|
||||||
if ( ! empty( $_POST[ $input ] ) ) {
|
if ( ! empty( $_POST[ $input ] ) ) { // WPCS: input var ok, CSRF OK.
|
||||||
return wc_clean( $_POST[ $input ] );
|
return wc_clean( wp_unslash( $_POST[ $input ] ) ); // WPCS: input var ok, CSRF OK.
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ class WC_Frontend_Scripts {
|
||||||
'selectWoo' => array(
|
'selectWoo' => array(
|
||||||
'src' => self::get_asset_url( 'assets/js/selectWoo/selectWoo.full' . $suffix . '.js' ),
|
'src' => self::get_asset_url( 'assets/js/selectWoo/selectWoo.full' . $suffix . '.js' ),
|
||||||
'deps' => array( 'jquery' ),
|
'deps' => array( 'jquery' ),
|
||||||
'version' => '1.0.3',
|
'version' => '1.0.4',
|
||||||
),
|
),
|
||||||
'wc-address-i18n' => array(
|
'wc-address-i18n' => array(
|
||||||
'src' => self::get_asset_url( 'assets/js/frontend/address-i18n' . $suffix . '.js' ),
|
'src' => self::get_asset_url( 'assets/js/frontend/address-i18n' . $suffix . '.js' ),
|
||||||
|
|
|
@ -463,7 +463,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' ) ) {
|
if ( ! $woocommerce_default_category || ! term_exists( $woocommerce_default_category, 'product_cat' ) ) {
|
||||||
$default_product_cat_id = 0;
|
$default_product_cat_id = 0;
|
||||||
|
@ -475,7 +475,7 @@ class WC_Install {
|
||||||
} else {
|
} else {
|
||||||
$result = wp_insert_term( _x( 'Uncategorized', 'Default category slug', 'woocommerce' ), 'product_cat', array( 'slug' => $default_product_cat_slug ) );
|
$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'] );
|
$default_product_cat_id = absint( $result['term_taxonomy_id'] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,6 +780,15 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
|
||||||
$tables[] = "{$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;
|
return $tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Class WC_Product_Grouped file.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Classes\Products
|
||||||
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -8,11 +14,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||||
*
|
*
|
||||||
* Grouped products cannot be purchased - they are wrappers for other products.
|
* Grouped products cannot be purchased - they are wrappers for other products.
|
||||||
*
|
*
|
||||||
* @class WC_Product_Grouped
|
* @class WC_Product_Grouped
|
||||||
* @version 3.0.0
|
* @version 3.0.0
|
||||||
* @package WooCommerce/Classes/Products
|
* @package WooCommerce/Classes/Products
|
||||||
* @category Class
|
|
||||||
* @author WooThemes
|
|
||||||
*/
|
*/
|
||||||
class WC_Product_Grouped extends WC_Product {
|
class WC_Product_Grouped extends WC_Product {
|
||||||
|
|
||||||
|
@ -27,6 +31,7 @@ class WC_Product_Grouped extends WC_Product {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get internal type.
|
* Get internal type.
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function get_type() {
|
public function get_type() {
|
||||||
|
@ -61,8 +66,6 @@ class WC_Product_Grouped extends WC_Product {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function is_on_sale( $context = 'view' ) {
|
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' );
|
$children = array_filter( array_map( 'wc_get_product', $this->get_children( $context ) ), 'wc_products_array_filter_visible_grouped' );
|
||||||
$on_sale = false;
|
$on_sale = false;
|
||||||
|
|
||||||
|
@ -89,7 +92,7 @@ class WC_Product_Grouped extends WC_Product {
|
||||||
* Returns the price in html format.
|
* Returns the price in html format.
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $price (default: '')
|
* @param string $price (default: '').
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function get_price_html( $price = '' ) {
|
public function get_price_html( $price = '' ) {
|
||||||
|
@ -143,7 +146,7 @@ class WC_Product_Grouped extends WC_Product {
|
||||||
/**
|
/**
|
||||||
* Return the children of this 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
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_children( $context = 'view' ) {
|
public function get_children( $context = 'view' ) {
|
||||||
|
@ -161,7 +164,7 @@ class WC_Product_Grouped extends WC_Product {
|
||||||
/**
|
/**
|
||||||
* Return the children of this product.
|
* Return the children of this product.
|
||||||
*
|
*
|
||||||
* @param array $children
|
* @param array $children List of product children.
|
||||||
*/
|
*/
|
||||||
public function set_children( $children ) {
|
public function set_children( $children ) {
|
||||||
$this->set_prop( 'children', array_filter( wp_parse_id_list( (array) $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.
|
* 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 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.
|
* @return WC_Product Synced product object.
|
||||||
*/
|
*/
|
||||||
public static function sync( $product, $save = true ) {
|
public static function sync( $product, $save = true ) {
|
||||||
|
|
|
@ -152,7 +152,7 @@ class WC_Shipping_Zone extends WC_Legacy_Shipping_Zone {
|
||||||
/**
|
/**
|
||||||
* Get shipping methods linked to this 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.
|
* @param string $context Getting shipping methods for what context. Valid values, admin, json.
|
||||||
* @return array of objects
|
* @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 ]->method_order = absint( $raw_method->method_order );
|
||||||
$methods[ $instance_id ]->enabled = $raw_method->is_enabled ? 'yes' : 'no';
|
$methods[ $instance_id ]->enabled = $raw_method->is_enabled ? 'yes' : 'no';
|
||||||
$methods[ $instance_id ]->has_settings = $methods[ $instance_id ]->has_settings();
|
$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 ) );
|
$methods[ $instance_id ]->method_description = wp_kses_post( wpautop( $methods[ $instance_id ]->method_description ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class WC_Shipping_Zones {
|
||||||
$wc_shipping = WC_Shipping::instance();
|
$wc_shipping = WC_Shipping::instance();
|
||||||
$allowed_classes = $wc_shipping->get_shipping_method_class_names();
|
$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 ];
|
$class_name = $allowed_classes[ $raw_shipping_method->method_id ];
|
||||||
if ( is_object( $class_name ) ) {
|
if ( is_object( $class_name ) ) {
|
||||||
$class_name = get_class( $class_name );
|
$class_name = get_class( $class_name );
|
||||||
|
|
|
@ -4,11 +4,9 @@
|
||||||
*
|
*
|
||||||
* Handles shipping and loads shipping methods via hooks.
|
* Handles shipping and loads shipping methods via hooks.
|
||||||
*
|
*
|
||||||
* @class WC_Shipping
|
* @class WC_Shipping
|
||||||
* @version 2.6.0
|
* @version 2.6.0
|
||||||
* @package WooCommerce/Classes/Shipping
|
* @package WooCommerce/Classes/Shipping
|
||||||
* @category Class
|
|
||||||
* @author WooThemes
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
@ -20,20 +18,38 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||||
*/
|
*/
|
||||||
class WC_Shipping {
|
class WC_Shipping {
|
||||||
|
|
||||||
/** @var bool True if shipping is enabled. */
|
/**
|
||||||
public $enabled = false;
|
* True if shipping is enabled.
|
||||||
|
*
|
||||||
/** @var array|null Stores methods loaded into woocommerce. */
|
* @var bool
|
||||||
public $shipping_methods = null;
|
*/
|
||||||
|
public $enabled = false;
|
||||||
/** @var array Stores the shipping classes. */
|
|
||||||
public $shipping_classes = array();
|
|
||||||
|
|
||||||
/** @var array Stores packages to ship and to get quotes for. */
|
|
||||||
public $packages = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
protected static $_instance = null;
|
protected static $_instance = null;
|
||||||
|
@ -80,10 +96,10 @@ class WC_Shipping {
|
||||||
*/
|
*/
|
||||||
public function __get( $name ) {
|
public function __get( $name ) {
|
||||||
// Grab from cart for backwards compatibility with versions prior to 3.2.
|
// 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();
|
return wc()->cart->get_shipping_total();
|
||||||
}
|
}
|
||||||
if ( 'shipping_taxes' === $name ){
|
if ( 'shipping_taxes' === $name ) {
|
||||||
return wc()->cart->get_shipping_taxes();
|
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.
|
* Shipping methods register themselves by returning their main class name through the woocommerce_shipping_methods filter.
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_shipping_method_class_names() {
|
public function get_shipping_method_class_names() {
|
||||||
// Unique Method ID => Method Class name
|
// Unique Method ID => Method Class name.
|
||||||
$shipping_methods = array(
|
$shipping_methods = array(
|
||||||
'flat_rate' => 'WC_Shipping_Flat_Rate',
|
'flat_rate' => 'WC_Shipping_Flat_Rate',
|
||||||
'free_shipping' => 'WC_Shipping_Free_Shipping',
|
'free_shipping' => 'WC_Shipping_Free_Shipping',
|
||||||
'local_pickup' => 'WC_Shipping_Local_Pickup',
|
'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' );
|
$maybe_load_legacy_methods = array( 'flat_rate', 'free_shipping', 'international_delivery', 'local_delivery', 'local_pickup' );
|
||||||
|
|
||||||
foreach ( $maybe_load_legacy_methods as $method ) {
|
foreach ( $maybe_load_legacy_methods as $method ) {
|
||||||
|
@ -135,7 +152,7 @@ class WC_Shipping {
|
||||||
* Loads all shipping methods which are hooked in.
|
* Loads all shipping methods which are hooked in.
|
||||||
* If a $package is passed some methods may add themselves conditionally and zones will be used.
|
* 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
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function load_shipping_methods( $package = 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 );
|
$shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
|
||||||
$this->shipping_methods = $shipping_zone->get_shipping_methods( true );
|
$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() . '"' ) ) {
|
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() . '"' );
|
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.
|
// Methods can register themselves manually through this hook if necessary.
|
||||||
do_action( 'woocommerce_load_shipping_methods', $package );
|
do_action( 'woocommerce_load_shipping_methods', $package );
|
||||||
|
|
||||||
// Return loaded methods
|
// Return loaded methods.
|
||||||
return $this->get_shipping_methods();
|
return $this->get_shipping_methods();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,36 +229,17 @@ class WC_Shipping {
|
||||||
*/
|
*/
|
||||||
public function get_shipping_classes() {
|
public function get_shipping_classes() {
|
||||||
if ( empty( $this->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();
|
$this->shipping_classes = ! is_wp_error( $classes ) ? $classes : array();
|
||||||
}
|
}
|
||||||
return apply_filters( 'woocommerce_get_shipping_classes', $this->shipping_classes );
|
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.
|
* Calculate shipping for (multiple) packages of cart items.
|
||||||
*
|
*
|
||||||
|
@ -292,7 +290,7 @@ class WC_Shipping {
|
||||||
}
|
}
|
||||||
|
|
||||||
$allowed = array_keys( WC()->countries->get_shipping_countries() );
|
$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 );
|
$package['rates'] = apply_filters( 'woocommerce_package_rates', $package['rates'], $package );
|
||||||
|
|
||||||
// Store in session to avoid recalculation.
|
// Store in session to avoid recalculation.
|
||||||
WC()->session->set( $session_key, array(
|
WC()->session->set(
|
||||||
'package_hash' => $package_hash,
|
$session_key, array(
|
||||||
'rates' => $package['rates'],
|
'package_hash' => $package_hash,
|
||||||
) );
|
'rates' => $package['rates'],
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
$package['rates'] = $stored_rates['rates'];
|
$package['rates'] = $stored_rates['rates'];
|
||||||
}
|
}
|
||||||
|
@ -351,6 +351,7 @@ class WC_Shipping {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get packages.
|
* Get packages.
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_packages() {
|
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.
|
* @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() {
|
public function sort_shipping_methods() {
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
/**
|
/**
|
||||||
* Shortcodes
|
* Shortcodes
|
||||||
*
|
*
|
||||||
* @author Automattic
|
|
||||||
* @category Class
|
|
||||||
* @package WooCommerce/Classes
|
* @package WooCommerce/Classes
|
||||||
* @version 3.2.0
|
* @version 3.2.0
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Class WC_Validation file
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Classes
|
||||||
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
exit; // Exit if accessed directly
|
exit; // Exit if accessed directly.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,15 +15,13 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||||
* @class WC_Validation
|
* @class WC_Validation
|
||||||
* @version 2.4.0
|
* @version 2.4.0
|
||||||
* @package WooCommerce/Classes
|
* @package WooCommerce/Classes
|
||||||
* @category Class
|
|
||||||
* @author WooThemes
|
|
||||||
*/
|
*/
|
||||||
class WC_Validation {
|
class WC_Validation {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates an email using WordPress native is_email function.
|
* Validates an email using WordPress native is_email function.
|
||||||
*
|
*
|
||||||
* @param string $email Email address to validate.
|
* @param string $email Email address to validate.
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function is_email( $email ) {
|
public static function is_email( $email ) {
|
||||||
|
@ -28,7 +31,7 @@ class WC_Validation {
|
||||||
/**
|
/**
|
||||||
* Validates a phone number using a regular expression.
|
* Validates a phone number using a regular expression.
|
||||||
*
|
*
|
||||||
* @param string $phone Phone number to validate.
|
* @param string $phone Phone number to validate.
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function is_phone( $phone ) {
|
public static function is_phone( $phone ) {
|
||||||
|
@ -42,8 +45,8 @@ class WC_Validation {
|
||||||
/**
|
/**
|
||||||
* Checks for a valid postcode.
|
* Checks for a valid postcode.
|
||||||
*
|
*
|
||||||
* @param string $postcode Postcode to validate.
|
* @param string $postcode Postcode to validate.
|
||||||
* @param string $country Country to validate the postcode for.
|
* @param string $country Country to validate the postcode for.
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function is_postcode( $postcode, $country ) {
|
public static function is_postcode( $postcode, $country ) {
|
||||||
|
@ -52,36 +55,36 @@ class WC_Validation {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( $country ) {
|
switch ( $country ) {
|
||||||
case 'AT' :
|
case 'AT':
|
||||||
$valid = (bool) preg_match( '/^([0-9]{4})$/', $postcode );
|
$valid = (bool) preg_match( '/^([0-9]{4})$/', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'BR' :
|
case 'BR':
|
||||||
$valid = (bool) preg_match( '/^([0-9]{5})([-])?([0-9]{3})$/', $postcode );
|
$valid = (bool) preg_match( '/^([0-9]{5})([-])?([0-9]{3})$/', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'CH' :
|
case 'CH':
|
||||||
$valid = (bool) preg_match( '/^([0-9]{4})$/i', $postcode );
|
$valid = (bool) preg_match( '/^([0-9]{4})$/i', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'DE' :
|
case 'DE':
|
||||||
$valid = (bool) preg_match( '/^([0]{1}[1-9]{1}|[1-9]{1}[0-9]{1})[0-9]{3}$/', $postcode );
|
$valid = (bool) preg_match( '/^([0]{1}[1-9]{1}|[1-9]{1}[0-9]{1})[0-9]{3}$/', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'ES' :
|
case 'ES':
|
||||||
case 'FR' :
|
case 'FR':
|
||||||
$valid = (bool) preg_match( '/^([0-9]{5})$/i', $postcode );
|
$valid = (bool) preg_match( '/^([0-9]{5})$/i', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'GB' :
|
case 'GB':
|
||||||
$valid = self::is_GB_postcode( $postcode );
|
$valid = self::is_gb_postcode( $postcode );
|
||||||
break;
|
break;
|
||||||
case 'JP' :
|
case 'JP':
|
||||||
$valid = (bool) preg_match( '/^([0-9]{3})([-])([0-9]{4})$/', $postcode );
|
$valid = (bool) preg_match( '/^([0-9]{3})([-])([0-9]{4})$/', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'PT' :
|
case 'PT':
|
||||||
$valid = (bool) preg_match( '/^([0-9]{4})([-])([0-9]{3})$/', $postcode );
|
$valid = (bool) preg_match( '/^([0-9]{4})([-])([0-9]{3})$/', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'US' :
|
case 'US':
|
||||||
$valid = (bool) preg_match( '/^([0-9]{5})(-[0-9]{4})?$/i', $postcode );
|
$valid = (bool) preg_match( '/^([0-9]{5})(-[0-9]{4})?$/i', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'CA' :
|
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
|
// 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 );
|
$valid = (bool) preg_match( '/^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])([\ ])?(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/i', $postcode );
|
||||||
break;
|
break;
|
||||||
case 'PL':
|
case 'PL':
|
||||||
|
@ -92,7 +95,7 @@ class WC_Validation {
|
||||||
$valid = (bool) preg_match( '/^([0-9]{3})(\s?)([0-9]{2})$/', $postcode );
|
$valid = (bool) preg_match( '/^([0-9]{3})(\s?)([0-9]{2})$/', $postcode );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default:
|
||||||
$valid = true;
|
$valid = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -103,51 +106,50 @@ class WC_Validation {
|
||||||
/**
|
/**
|
||||||
* Check if is a GB postcode.
|
* Check if is a GB postcode.
|
||||||
*
|
*
|
||||||
* @author John Gardner
|
* @param string $to_check A postcode.
|
||||||
* @param string $to_check A postcode
|
|
||||||
* @return bool
|
* @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.
|
// Permitted letters depend upon their position in the postcode.
|
||||||
// https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation
|
// https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation.
|
||||||
$alpha1 = "[abcdefghijklmnoprstuwyz]"; // Character 1
|
$alpha1 = '[abcdefghijklmnoprstuwyz]'; // Character 1.
|
||||||
$alpha2 = "[abcdefghklmnopqrstuvwxy]"; // Character 2
|
$alpha2 = '[abcdefghklmnopqrstuvwxy]'; // Character 2.
|
||||||
$alpha3 = "[abcdefghjkpstuw]"; // Character 3 == ABCDEFGHJKPSTUW
|
$alpha3 = '[abcdefghjkpstuw]'; // Character 3 == ABCDEFGHJKPSTUW.
|
||||||
$alpha4 = "[abehmnprvwxy]"; // Character 4 == ABEHMNPRVWXY
|
$alpha4 = '[abehmnprvwxy]'; // Character 4 == ABEHMNPRVWXY.
|
||||||
$alpha5 = "[abdefghjlnpqrstuwxyz]"; // Character 5 != CIKMOV
|
$alpha5 = '[abdefghjlnpqrstuwxyz]'; // Character 5 != CIKMOV.
|
||||||
|
|
||||||
$pcexp = array();
|
$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})$/';
|
$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})$/';
|
$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})$/';
|
$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)$/';
|
$pcexp[3] = '/^(gir)(0aa)$/';
|
||||||
|
|
||||||
// Standard BFPO numbers
|
// Standard BFPO numbers.
|
||||||
$pcexp[4] = '/^(bfpo)([0-9]{1,4})$/';
|
$pcexp[4] = '/^(bfpo)([0-9]{1,4})$/';
|
||||||
|
|
||||||
// c/o BFPO numbers
|
// c/o BFPO numbers.
|
||||||
$pcexp[5] = '/^(bfpo)(c\/o[0-9]{1,3})$/';
|
$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 = strtolower( $to_check );
|
||||||
$postcode = str_replace( ' ', '', $postcode );
|
$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;
|
$valid = false;
|
||||||
|
|
||||||
// Check the string against the six types of postcodes
|
// Check the string against the six types of postcodes.
|
||||||
foreach ( $pcexp as $regexp ) {
|
foreach ( $pcexp as $regexp ) {
|
||||||
if ( preg_match( $regexp, $postcode, $matches ) ) {
|
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;
|
$valid = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -159,16 +161,16 @@ class WC_Validation {
|
||||||
/**
|
/**
|
||||||
* Format the postcode according to the country and length of the postcode.
|
* Format the postcode according to the country and length of the postcode.
|
||||||
*
|
*
|
||||||
* @param string $postcode Postcode to format.
|
* @param string $postcode Postcode to format.
|
||||||
* @param string $country Country to format the postcode for.
|
* @param string $country Country to format the postcode for.
|
||||||
* @return string Formatted postcode.
|
* @return string Formatted postcode.
|
||||||
*/
|
*/
|
||||||
public static function format_postcode( $postcode, $country ) {
|
public static function format_postcode( $postcode, $country ) {
|
||||||
return wc_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
|
* @return string
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
*
|
*
|
||||||
* @version 3.2.0
|
* @version 3.2.0
|
||||||
* @package WooCommerce/Webhooks
|
* @package WooCommerce/Webhooks
|
||||||
* @category Webhooks
|
|
||||||
* @since 2.2.0
|
* @since 2.2.0
|
||||||
* @author Automattic
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Class WC_Data_Store_WP file.
|
|
||||||
*
|
|
||||||
* @package WooCommerce\DataStores
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared logic for WP based data.
|
* Shared logic for WP based data.
|
||||||
* Contains functions like meta handling for all default data stores.
|
* 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 data store doesn't need to use WC_Data_Store_WP -- you can write
|
||||||
* your own meta handling functions.
|
* 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 {
|
class WC_Data_Store_WP {
|
||||||
|
|
||||||
|
@ -171,7 +168,6 @@ class WC_Data_Store_WP {
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*
|
*
|
||||||
* @param string $key Prefix to be added to meta keys.
|
* @param string $key Prefix to be added to meta keys.
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function prefix_key( $key ) {
|
protected function prefix_key( $key ) {
|
||||||
|
@ -383,7 +379,6 @@ class WC_Data_Store_WP {
|
||||||
'compare' => $operator,
|
'compare' => $operator,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
case '>=':
|
case '>=':
|
||||||
$wp_query_args['meta_query'][] = array(
|
$wp_query_args['meta_query'][] = array(
|
||||||
|
@ -392,7 +387,6 @@ class WC_Data_Store_WP {
|
||||||
'compare' => $operator,
|
'compare' => $operator,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$wp_query_args['meta_query'][] = array(
|
$wp_query_args['meta_query'][] = array(
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
|
@ -438,4 +432,61 @@ class WC_Data_Store_WP {
|
||||||
public function get_internal_meta_keys() {
|
public function get_internal_meta_keys() {
|
||||||
return $this->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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ) {
|
foreach ( $attributes as $attribute_key => $attribute ) {
|
||||||
$value = '';
|
$value = '';
|
||||||
|
|
||||||
|
delete_transient( 'wc_layered_nav_counts_' . $attribute_key );
|
||||||
|
|
||||||
if ( is_null( $attribute ) ) {
|
if ( is_null( $attribute ) ) {
|
||||||
if ( taxonomy_exists( $attribute_key ) ) {
|
if ( taxonomy_exists( $attribute_key ) ) {
|
||||||
// Handle attributes that have been unset.
|
// 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 );
|
update_post_meta( $product->get_id(), '_product_attributes', $meta_values );
|
||||||
delete_transient( 'wc_layered_nav_counts' );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1326,12 +1327,54 @@ 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 ) {
|
public function search_products( $term, $type = '', $include_variations = false, $all_statuses = false ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
$like_term = '%' . $wpdb->esc_like( $term ) . '%';
|
|
||||||
$post_types = $include_variations ? array( 'product', 'product_variation' ) : array( 'product' );
|
$post_types = $include_variations ? array( 'product', 'product_variation' ) : array( 'product' );
|
||||||
$post_statuses = current_user_can( 'edit_private_products' ) ? array( 'private', 'publish' ) : array( 'publish' );
|
$post_statuses = current_user_can( 'edit_private_products' ) ? array( 'private', 'publish' ) : array( 'publish' );
|
||||||
$type_join = '';
|
$type_join = '';
|
||||||
$type_where = '';
|
$type_where = '';
|
||||||
$status_where = '';
|
$status_where = '';
|
||||||
|
$term = wc_strtolower( $term );
|
||||||
|
|
||||||
|
// 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 ); // @codingStandardsIgnoreLine.
|
||||||
|
$searchand = ' AND ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $term_group_query ) {
|
||||||
|
$search_queries[] = $term_group_query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $search_queries ) {
|
||||||
|
$search_where = 'AND (' . implode( ') OR (', $search_queries ) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
if ( $type ) {
|
if ( $type ) {
|
||||||
if ( in_array( $type, array( 'virtual', 'downloadable' ), true ) ) {
|
if ( in_array( $type, array( 'virtual', 'downloadable' ), true ) ) {
|
||||||
|
@ -1347,25 +1390,14 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
||||||
// phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
|
// phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
|
||||||
$search_results = $wpdb->get_results(
|
$search_results = $wpdb->get_results(
|
||||||
// phpcs:disable
|
// phpcs:disable
|
||||||
$wpdb->prepare(
|
"SELECT DISTINCT posts.ID as product_id, posts.post_parent as parent_id FROM {$wpdb->posts} posts
|
||||||
"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
|
||||||
LEFT JOIN {$wpdb->postmeta} postmeta ON posts.ID = postmeta.post_id
|
$type_join
|
||||||
$type_join
|
WHERE posts.post_type IN ('" . implode( "','", $post_types ) . "')
|
||||||
WHERE (
|
$search_where
|
||||||
posts.post_title LIKE %s
|
$status_where
|
||||||
OR posts.post_content LIKE %s
|
$type_where
|
||||||
OR (
|
ORDER BY posts.post_parent ASC, posts.post_title ASC"
|
||||||
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
|
|
||||||
)
|
|
||||||
// phpcs:enable
|
// phpcs:enable
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
// 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'] );
|
$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.
|
// Get custom attributes (non taxonomy) as defined.
|
||||||
} elseif ( ! $attribute['is_taxonomy'] ) {
|
} elseif ( ! $attribute['is_taxonomy'] ) {
|
||||||
|
|
|
@ -317,8 +317,9 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
|
||||||
*/
|
*/
|
||||||
protected function set_product_data( &$product, $data ) {
|
protected function set_product_data( &$product, $data ) {
|
||||||
if ( isset( $data['raw_attributes'] ) ) {
|
if ( isset( $data['raw_attributes'] ) ) {
|
||||||
$attributes = array();
|
$attributes = array();
|
||||||
$default_attributes = array();
|
$default_attributes = array();
|
||||||
|
$existing_attributes = $product->get_attributes();
|
||||||
|
|
||||||
foreach ( $data['raw_attributes'] as $position => $attribute ) {
|
foreach ( $data['raw_attributes'] as $position => $attribute ) {
|
||||||
$attribute_id = 0;
|
$attribute_id = 0;
|
||||||
|
@ -335,12 +336,22 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
|
||||||
$is_visible = 1;
|
$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;
|
$is_variation = 0;
|
||||||
|
|
||||||
if ( $attribute_id ) {
|
if ( $existing_attributes ) {
|
||||||
$attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id );
|
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'] ) ) {
|
if ( isset( $attribute['value'] ) ) {
|
||||||
$options = array_map( 'wc_sanitize_term_text_based', $attribute['value'] );
|
$options = array_map( 'wc_sanitize_term_text_based', $attribute['value'] );
|
||||||
$options = array_filter( $options, 'strlen' );
|
$options = array_filter( $options, 'strlen' );
|
||||||
|
|
|
@ -113,7 +113,7 @@ class WC_Shortcode_Products {
|
||||||
$attributes = shortcode_atts(
|
$attributes = shortcode_atts(
|
||||||
array(
|
array(
|
||||||
'limit' => '-1', // Results limit.
|
'limit' => '-1', // Results limit.
|
||||||
'columns' => '3', // Number of columns.
|
'columns' => '', // Number of columns.
|
||||||
'rows' => '', // Number of rows. If defined, limit will be ignored.
|
'rows' => '', // Number of rows. If defined, limit will be ignored.
|
||||||
'orderby' => 'title', // menu_order, title, date, rand, price, popularity, rating, or id.
|
'orderby' => 'title', // menu_order, title, date, rand, price, popularity, rating, or id.
|
||||||
'order' => 'ASC', // ASC or DESC.
|
'order' => 'ASC', // ASC or DESC.
|
||||||
|
@ -134,7 +134,7 @@ class WC_Shortcode_Products {
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( ! absint( $attributes['columns'] ) ) {
|
if ( ! absint( $attributes['columns'] ) ) {
|
||||||
$attributes['columns'] = 3;
|
$attributes['columns'] = wc_get_default_products_per_row();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $attributes;
|
return $attributes;
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
*
|
*
|
||||||
* Functions for determining the current query/page.
|
* Functions for determining the current query/page.
|
||||||
*
|
*
|
||||||
* @author WooThemes
|
|
||||||
* @category Core
|
|
||||||
* @package WooCommerce/Functions
|
* @package WooCommerce/Functions
|
||||||
* @version 2.3.0
|
* @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.
|
* Is_wc_endpoint_url - Check if an endpoint is showing.
|
||||||
*
|
*
|
||||||
* @param string $endpoint Whether endpoint.
|
* @param string|false $endpoint Whether endpoint.
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function is_wc_endpoint_url( $endpoint = false ) {
|
function is_wc_endpoint_url( $endpoint = false ) {
|
||||||
|
@ -272,7 +270,7 @@ if ( ! function_exists( 'is_filtered' ) ) {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function is_filtered() {
|
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' ) ) {
|
if ( $product && method_exists( $product, 'get_variation_attributes' ) ) {
|
||||||
$variation_attributes = $product->get_variation_attributes();
|
$variation_attributes = $product->get_variation_attributes();
|
||||||
$attributes = $product->get_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 {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -982,7 +982,6 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
|
||||||
if ( ! wc_get_loop_prop( 'is_paginated' ) || ! woocommerce_products_will_display() ) {
|
if ( ! wc_get_loop_prop( 'is_paginated' ) || ! woocommerce_products_will_display() ) {
|
||||||
return;
|
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' ) );
|
$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(
|
$catalog_orderby_options = apply_filters( 'woocommerce_catalog_orderby', array(
|
||||||
'menu_order' => __( 'Default sorting', 'woocommerce' ),
|
'menu_order' => __( 'Default sorting', 'woocommerce' ),
|
||||||
|
@ -993,12 +992,13 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
|
||||||
'price-desc' => __( 'Sort by price: high to low', 'woocommerce' ),
|
'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' ) ) {
|
if ( wc_get_loop_prop( 'is_search' ) ) {
|
||||||
$catalog_orderby_options = array_merge( array( 'relevance' => __( 'Relevance', 'woocommerce' ) ), $catalog_orderby_options );
|
$catalog_orderby_options = array_merge( array( 'relevance' => __( 'Relevance', 'woocommerce' ) ), $catalog_orderby_options );
|
||||||
|
|
||||||
unset( $catalog_orderby_options['menu_order'] );
|
unset( $catalog_orderby_options['menu_order'] );
|
||||||
if ( 'menu_order' === $orderby ) {
|
|
||||||
$orderby = 'relevance';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $show_default_orderby ) {
|
if ( ! $show_default_orderby ) {
|
||||||
|
@ -1009,6 +1009,10 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
|
||||||
unset( $catalog_orderby_options['rating'] );
|
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(
|
wc_get_template( 'loop/orderby.php', array(
|
||||||
'catalog_orderby_options' => $catalog_orderby_options,
|
'catalog_orderby_options' => $catalog_orderby_options,
|
||||||
'orderby' => $orderby,
|
'orderby' => $orderby,
|
||||||
|
@ -1995,7 +1999,7 @@ if ( ! function_exists( 'woocommerce_get_product_subcategories' ) ) {
|
||||||
*/
|
*/
|
||||||
function woocommerce_get_product_subcategories( $parent_id = 0 ) {
|
function woocommerce_get_product_subcategories( $parent_id = 0 ) {
|
||||||
$parent_id = absint( $parent_id );
|
$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 ) {
|
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.
|
// 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',
|
'taxonomy' => 'product_cat',
|
||||||
'pad_counts' => 1,
|
'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 ) ) {
|
if ( apply_filters( 'woocommerce_product_subcategories_hide_empty', true ) ) {
|
||||||
|
@ -2326,8 +2331,18 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
|
||||||
$field = sprintf( $field_container, $container_class, $container_id, $field_html );
|
$field = sprintf( $field_container, $container_class, $container_id, $field_html );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter by type.
|
||||||
|
*/
|
||||||
$field = apply_filters( 'woocommerce_form_field_' . $args['type'], $field, $key, $args, $value );
|
$field = apply_filters( 'woocommerce_form_field_' . $args['type'], $field, $key, $args, $value );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General filter on form fields.
|
||||||
|
*
|
||||||
|
* @since 3.4.0
|
||||||
|
*/
|
||||||
|
$field = apply_filters( 'woocommerce_form_field', $field, $key, $args, $value );
|
||||||
|
|
||||||
if ( $args['return'] ) {
|
if ( $args['return'] ) {
|
||||||
return $field;
|
return $field;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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.
|
// We have a query - let's see if cached results of this query already exist.
|
||||||
$query_hash = md5( $query );
|
$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 ] ) ) {
|
if ( ! isset( $cached_counts[ $query_hash ] ) ) {
|
||||||
$results = $wpdb->get_results( $query, ARRAY_A ); // @codingStandardsIgnoreLine
|
$results = $wpdb->get_results( $query, ARRAY_A ); // @codingStandardsIgnoreLine
|
||||||
$counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) );
|
$counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) );
|
||||||
$cached_counts[ $query_hash ] = $counts;
|
$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 ] );
|
return array_map( 'absint', (array) $cached_counts[ $query_hash ] );
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "woocommerce",
|
"name": "woocommerce",
|
||||||
"version": "3.1.0",
|
"version": "3.3.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1334,9 +1334,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chromedriver": {
|
"chromedriver": {
|
||||||
"version": "2.33.2",
|
"version": "2.36.0",
|
||||||
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.33.2.tgz",
|
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.36.0.tgz",
|
||||||
"integrity": "sha512-etnQeM8Mqiys50ZB4IiuNqeB1WS2/EKFhVXwkPQ1qjzKMMAJUyrLjaRUcoZoHrbjGscnhBrWkRR+p3zcTGMhDg==",
|
"integrity": "sha512-Lq2HrigCJ4RVdIdCmchenv1rVrejNSJ7EUCQojycQo12ww3FedQx4nb+GgTdqMhjbOMTqq5+ziaiZlrEN2z1gQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"del": "3.0.0",
|
"del": "3.0.0",
|
||||||
|
@ -6032,9 +6032,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"url-join": {
|
"url-join": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz",
|
||||||
"integrity": "sha1-wHJ1aWetJLi1nldBVRyqx49QuLc=",
|
"integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"user-home": {
|
"user-home": {
|
||||||
|
@ -6086,9 +6086,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"wc-e2e-page-objects": {
|
"wc-e2e-page-objects": {
|
||||||
"version": "0.5.0",
|
"version": "0.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/wc-e2e-page-objects/-/wc-e2e-page-objects-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/wc-e2e-page-objects/-/wc-e2e-page-objects-0.9.0.tgz",
|
||||||
"integrity": "sha1-7oAQnDRqn9HE4NUbi7h/oeHDcMs=",
|
"integrity": "sha512-oGOLFAN+lNULLylZkhNIMGT0n5hO+elpcVkpNQcT4HgWfS1yPoGfeWgrfAX33b4ZGVlpViv78Fj3LM5TciXVHw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash": "4.17.4",
|
"lodash": "4.17.4",
|
||||||
|
@ -6174,7 +6174,22 @@
|
||||||
"selenium-webdriver": "3.6.0",
|
"selenium-webdriver": "3.6.0",
|
||||||
"slugs": "0.1.3",
|
"slugs": "0.1.3",
|
||||||
"temp": "0.8.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": {
|
"wrap-ansi": {
|
||||||
|
@ -6209,13 +6224,13 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"sax": "1.2.4",
|
"sax": "1.2.4",
|
||||||
"xmlbuilder": "9.0.4"
|
"xmlbuilder": "9.0.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"xmlbuilder": {
|
"xmlbuilder": {
|
||||||
"version": "9.0.4",
|
"version": "9.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
|
||||||
"integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=",
|
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"xtend": {
|
"xtend": {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"babel-preset-stage-2": "^6.13.0",
|
"babel-preset-stage-2": "^6.13.0",
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
"chai-as-promised": "^6.0.0",
|
"chai-as-promised": "^6.0.0",
|
||||||
"chromedriver": "^2.33.0",
|
"chromedriver": "^2.36.0",
|
||||||
"config": "^1.24.0",
|
"config": "^1.24.0",
|
||||||
"cross-env": "~5.1.1",
|
"cross-env": "~5.1.1",
|
||||||
"grunt": "~1.0.1",
|
"grunt": "~1.0.1",
|
||||||
|
|
|
@ -37,10 +37,11 @@
|
||||||
<exclude name="WordPress.VIP.RestrictedFunctions" />
|
<exclude name="WordPress.VIP.RestrictedFunctions" />
|
||||||
<exclude name="WordPress.VIP.RestrictedVariables.user_meta__wpdb__usermeta" />
|
<exclude name="WordPress.VIP.RestrictedVariables.user_meta__wpdb__usermeta" />
|
||||||
<exclude name="WordPress.VIP.PostsPerPage.posts_per_page_posts_per_page" />
|
<exclude name="WordPress.VIP.PostsPerPage.posts_per_page_posts_per_page" />
|
||||||
|
<exclude name="WordPress.VIP.RestrictedVariables.cache_constraints___COOKIE" />
|
||||||
</rule>
|
</rule>
|
||||||
<rule ref="WordPress.VIP.ValidatedSanitizedInput">
|
<rule ref="WordPress.VIP.ValidatedSanitizedInput">
|
||||||
<properties>
|
<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>
|
</properties>
|
||||||
</rule>
|
</rule>
|
||||||
<rule ref="WordPress.XSS.EscapeOutput">
|
<rule ref="WordPress.XSS.EscapeOutput">
|
||||||
|
|
|
@ -10,15 +10,12 @@
|
||||||
* happen. When this occurs the version of the template file will be bumped and
|
* happen. When this occurs the version of the template file will be bumped and
|
||||||
* the readme will list any important changes.
|
* the readme will list any important changes.
|
||||||
*
|
*
|
||||||
* @see https://docs.woocommerce.com/document/template-structure/
|
* @see https://docs.woocommerce.com/document/template-structure/
|
||||||
* @author WooThemes
|
* @package WooCommerce/Templates
|
||||||
* @package WooCommerce/Templates
|
* @version 3.4.0
|
||||||
* @version 3.3.0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
defined( 'ABSPATH' ) || exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $max_value && $min_value === $max_value ) {
|
if ( $max_value && $min_value === $max_value ) {
|
||||||
?>
|
?>
|
||||||
|
@ -27,10 +24,25 @@ if ( $max_value && $min_value === $max_value ) {
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
|
/* translators: %s: Quantity. */
|
||||||
|
$labelledby = ! empty( $args['product_name'] ) ? sprintf( __( '%s quantity', 'woocommerce' ), strip_tags( $args['product_name'] ) ) : '';
|
||||||
?>
|
?>
|
||||||
<div class="quantity">
|
<div class="quantity">
|
||||||
<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></label>
|
<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></label>
|
||||||
<input type="number" id="<?php echo esc_attr( $input_id ); ?>" class="input-text qty text" step="<?php echo esc_attr( $step ); ?>" min="<?php echo esc_attr( $min_value ); ?>" max="<?php echo esc_attr( 0 < $max_value ? $max_value : '' ); ?>" name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $input_value ); ?>" title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ) ?>" size="4" pattern="<?php echo esc_attr( $pattern ); ?>" inputmode="<?php echo esc_attr( $inputmode ); ?>" aria-labelledby="<?php echo ! empty( $args['product_name'] ) ? sprintf( esc_attr__( '%s quantity', 'woocommerce' ), $args['product_name'] ) : ''; ?>" />
|
<input
|
||||||
|
type="number"
|
||||||
|
id="<?php echo esc_attr( $input_id ); ?>"
|
||||||
|
class="input-text qty text"
|
||||||
|
step="<?php echo esc_attr( $step ); ?>"
|
||||||
|
min="<?php echo esc_attr( $min_value ); ?>"
|
||||||
|
max="<?php echo esc_attr( 0 < $max_value ? $max_value : '' ); ?>"
|
||||||
|
name="<?php echo esc_attr( $input_name ); ?>"
|
||||||
|
value="<?php echo esc_attr( $input_value ); ?>"
|
||||||
|
title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ); ?>"
|
||||||
|
size="4"
|
||||||
|
pattern="<?php echo esc_attr( $pattern ); ?>"
|
||||||
|
inputmode="<?php echo esc_attr( $inputmode ); ?>"
|
||||||
|
aria-labelledby="<?php echo esc_attr( $labelledby ); ?>" />
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ class WC_Tests_Cart extends WC_Unit_Test_Case {
|
||||||
/**
|
/**
|
||||||
* Test some discount logic which has caused issues in the past.
|
* Test some discount logic which has caused issues in the past.
|
||||||
* Tickets:
|
* Tickets:
|
||||||
* https://github.com/woocommerce/woocommerce/issues/10573
|
* https://github.com/woocommerce/woocommerce/issues/10573
|
||||||
* https://github.com/woocommerce/woocommerce/issues/10963
|
* https://github.com/woocommerce/woocommerce/issues/10963
|
||||||
*
|
*
|
||||||
* Due to discounts being split amongst products in cart.
|
* Due to discounts being split amongst products in cart.
|
||||||
|
@ -162,11 +162,11 @@ class WC_Tests_Cart extends WC_Unit_Test_Case {
|
||||||
WC()->cart->empty_cart();
|
WC()->cart->empty_cart();
|
||||||
WC()->cart->remove_coupons();
|
WC()->cart->remove_coupons();
|
||||||
|
|
||||||
$product = new WC_Product_Simple;
|
$product = new WC_Product_Simple();
|
||||||
$product->set_regular_price( 51.86 );
|
$product->set_regular_price( 51.86 );
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
$coupon = new WC_Coupon;
|
$coupon = new WC_Coupon();
|
||||||
$coupon->set_code( 'testpercent' );
|
$coupon->set_code( 'testpercent' );
|
||||||
$coupon->set_discount_type( 'percent' );
|
$coupon->set_discount_type( 'percent' );
|
||||||
$coupon->set_amount( 40 );
|
$coupon->set_amount( 40 );
|
||||||
|
@ -263,24 +263,24 @@ class WC_Tests_Cart extends WC_Unit_Test_Case {
|
||||||
WC_Tax::_insert_tax_rate( $tax_rate );
|
WC_Tax::_insert_tax_rate( $tax_rate );
|
||||||
|
|
||||||
// Create product.
|
// Create product.
|
||||||
$product = new WC_Product_Simple;
|
$product = new WC_Product_Simple();
|
||||||
$product->set_regular_price( '9.99' );
|
$product->set_regular_price( '9.99' );
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
// Create coupons.
|
// Create coupons.
|
||||||
$ten_coupon = new WC_Coupon;
|
$ten_coupon = new WC_Coupon();
|
||||||
$ten_coupon->set_code( '10off' );
|
$ten_coupon->set_code( '10off' );
|
||||||
$ten_coupon->set_discount_type( 'percent' );
|
$ten_coupon->set_discount_type( 'percent' );
|
||||||
$ten_coupon->set_amount( 10 );
|
$ten_coupon->set_amount( 10 );
|
||||||
$ten_coupon->save();
|
$ten_coupon->save();
|
||||||
|
|
||||||
$half_coupon = new WC_Coupon;
|
$half_coupon = new WC_Coupon();
|
||||||
$half_coupon->set_code( '50off' );
|
$half_coupon->set_code( '50off' );
|
||||||
$half_coupon->set_discount_type( 'percent' );
|
$half_coupon->set_discount_type( 'percent' );
|
||||||
$half_coupon->set_amount( 50 );
|
$half_coupon->set_amount( 50 );
|
||||||
$half_coupon->save();
|
$half_coupon->save();
|
||||||
|
|
||||||
$full_coupon = new WC_Coupon;
|
$full_coupon = new WC_Coupon();
|
||||||
$full_coupon->set_code( '100off' );
|
$full_coupon->set_code( '100off' );
|
||||||
$full_coupon->set_discount_type( 'percent' );
|
$full_coupon->set_discount_type( 'percent' );
|
||||||
$full_coupon->set_amount( 100 );
|
$full_coupon->set_amount( 100 );
|
||||||
|
@ -374,6 +374,125 @@ class WC_Tests_Cart extends WC_Unit_Test_Case {
|
||||||
update_option( 'woocommerce_calc_taxes', 'no' );
|
update_option( 'woocommerce_calc_taxes', 'no' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test cart calculations when out of base location with no matching taxes and using inclusive taxes and discounts.
|
||||||
|
*
|
||||||
|
* @see GitHub issue #19390.
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public function test_out_of_base_discounts_inclusive_tax_no_oob_tax() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
// Set up tax options.
|
||||||
|
update_option( 'woocommerce_prices_include_tax', 'yes' );
|
||||||
|
update_option( 'woocommerce_calc_taxes', 'yes' );
|
||||||
|
update_option( 'woocommerce_default_country', 'GB' );
|
||||||
|
update_option( 'woocommerce_default_customer_address', 'base' );
|
||||||
|
update_option( 'woocommerce_tax_based_on', 'shipping' );
|
||||||
|
|
||||||
|
// 20% tax for GB.
|
||||||
|
$tax_rate = array(
|
||||||
|
'tax_rate_country' => 'GB',
|
||||||
|
'tax_rate_state' => '',
|
||||||
|
'tax_rate' => '20.0000',
|
||||||
|
'tax_rate_name' => 'VAT',
|
||||||
|
'tax_rate_priority' => '1',
|
||||||
|
'tax_rate_compound' => '0',
|
||||||
|
'tax_rate_shipping' => '0',
|
||||||
|
'tax_rate_order' => '1',
|
||||||
|
'tax_rate_class' => '',
|
||||||
|
);
|
||||||
|
WC_Tax::_insert_tax_rate( $tax_rate );
|
||||||
|
|
||||||
|
// 0% tax everywhere else.
|
||||||
|
$tax_rate = array(
|
||||||
|
'tax_rate_country' => '',
|
||||||
|
'tax_rate_state' => '',
|
||||||
|
'tax_rate' => '0.0000',
|
||||||
|
'tax_rate_name' => 'TAX',
|
||||||
|
'tax_rate_priority' => '1',
|
||||||
|
'tax_rate_compound' => '0',
|
||||||
|
'tax_rate_shipping' => '0',
|
||||||
|
'tax_rate_order' => '1',
|
||||||
|
'tax_rate_class' => '',
|
||||||
|
);
|
||||||
|
WC_Tax::_insert_tax_rate( $tax_rate );
|
||||||
|
|
||||||
|
// Create product.
|
||||||
|
$product = new WC_Product_Simple();
|
||||||
|
$product->set_regular_price( '24.99' );
|
||||||
|
$product->save();
|
||||||
|
|
||||||
|
// Create coupon.
|
||||||
|
$ten_coupon = new WC_Coupon();
|
||||||
|
$ten_coupon->set_code( '10off' );
|
||||||
|
$ten_coupon->set_discount_type( 'percent' );
|
||||||
|
$ten_coupon->set_amount( 10 );
|
||||||
|
$ten_coupon->save();
|
||||||
|
|
||||||
|
$half_coupon = new WC_Coupon();
|
||||||
|
$half_coupon->set_code( '50off' );
|
||||||
|
$half_coupon->set_discount_type( 'percent' );
|
||||||
|
$half_coupon->set_amount( 50 );
|
||||||
|
$half_coupon->save();
|
||||||
|
|
||||||
|
$full_coupon = new WC_Coupon();
|
||||||
|
$full_coupon->set_code( '100off' );
|
||||||
|
$full_coupon->set_discount_type( 'percent' );
|
||||||
|
$full_coupon->set_amount( 100 );
|
||||||
|
$full_coupon->save();
|
||||||
|
|
||||||
|
add_filter( 'woocommerce_customer_get_shipping_country', array( $this, 'force_customer_us_shipping' ) );
|
||||||
|
WC()->cart->add_to_cart( $product->get_id(), 1 );
|
||||||
|
|
||||||
|
// Test out of store location with no coupon.
|
||||||
|
WC()->cart->calculate_totals();
|
||||||
|
$this->assertEquals( '20.83', wc_format_decimal( WC()->cart->get_subtotal(), 2 ) );
|
||||||
|
$this->assertEquals( '0.00', wc_format_decimal( WC()->cart->get_discount_total(), 2 ) );
|
||||||
|
$this->assertEquals( '0.00', wc_format_decimal( WC()->cart->get_total_tax(), 2 ) );
|
||||||
|
$this->assertEquals( '20.83', wc_format_decimal( WC()->cart->get_total( 'edit' ), 2 ) );
|
||||||
|
|
||||||
|
// Test out of store location with 10% coupon.
|
||||||
|
WC()->cart->add_discount( $ten_coupon->get_code() );
|
||||||
|
WC()->cart->calculate_totals();
|
||||||
|
$this->assertEquals( '20.83', wc_format_decimal( WC()->cart->get_subtotal(), 2 ) );
|
||||||
|
$this->assertEquals( '2.08', wc_format_decimal( WC()->cart->get_discount_total(), 2 ) );
|
||||||
|
$this->assertEquals( '0.00', wc_format_decimal( WC()->cart->get_total_tax(), 2 ) );
|
||||||
|
$this->assertEquals( '18.75', wc_format_decimal( WC()->cart->get_total( 'edit' ), 2 ) );
|
||||||
|
WC()->cart->remove_coupons();
|
||||||
|
|
||||||
|
// Test out of store location with 50% coupon.
|
||||||
|
WC()->cart->add_discount( $half_coupon->get_code() );
|
||||||
|
WC()->cart->calculate_totals();
|
||||||
|
$this->assertEquals( '20.83', wc_format_decimal( WC()->cart->get_subtotal(), 2 ) );
|
||||||
|
$this->assertEquals( '10.41', wc_format_decimal( WC()->cart->get_discount_total(), 2 ) );
|
||||||
|
$this->assertEquals( '0.00', wc_format_decimal( WC()->cart->get_total_tax(), 2 ) );
|
||||||
|
$this->assertEquals( '10.42', wc_format_decimal( WC()->cart->get_total( 'edit' ), 2 ) );
|
||||||
|
WC()->cart->remove_coupons();
|
||||||
|
|
||||||
|
// Test out of store location with 100% coupon.
|
||||||
|
WC()->cart->add_discount( $full_coupon->get_code() );
|
||||||
|
WC()->cart->calculate_totals();
|
||||||
|
$this->assertEquals( '20.83', wc_format_decimal( WC()->cart->get_subtotal(), 2 ) );
|
||||||
|
$this->assertEquals( '20.83', wc_format_decimal( WC()->cart->get_discount_total(), 2 ), 'Discount total out of base' );
|
||||||
|
$this->assertEquals( '0.00', wc_format_decimal( WC()->cart->get_total_tax(), 2 ) );
|
||||||
|
$this->assertEquals( '0.00', wc_format_decimal( WC()->cart->get_total( 'edit' ), 2 ) );
|
||||||
|
|
||||||
|
// Clean up.
|
||||||
|
WC()->cart->empty_cart();
|
||||||
|
WC()->cart->remove_coupons();
|
||||||
|
remove_filter( 'woocommerce_customer_get_shipping_country', array( $this, 'force_customer_us_shipping' ) );
|
||||||
|
WC_Helper_Product::delete_product( $product->get_id() );
|
||||||
|
WC_Helper_Coupon::delete_coupon( $ten_coupon->get_id() );
|
||||||
|
WC_Helper_Coupon::delete_coupon( $half_coupon->get_id() );
|
||||||
|
WC_Helper_Coupon::delete_coupon( $full_coupon->get_id() );
|
||||||
|
$wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates" );
|
||||||
|
$wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations" );
|
||||||
|
update_option( 'woocommerce_prices_include_tax', 'no' );
|
||||||
|
update_option( 'woocommerce_calc_taxes', 'no' );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper that can be hooked to a filter to force the customer's shipping country to be GB.
|
* Helper that can be hooked to a filter to force the customer's shipping country to be GB.
|
||||||
*
|
*
|
||||||
|
@ -443,7 +562,7 @@ class WC_Tests_Cart extends WC_Unit_Test_Case {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the product and add it to the cart.
|
// Create the product and add it to the cart.
|
||||||
$product = new WC_Product_Simple;
|
$product = new WC_Product_Simple();
|
||||||
$product->set_regular_price( '149.14' );
|
$product->set_regular_price( '149.14' );
|
||||||
$product->save();
|
$product->save();
|
||||||
WC()->cart->add_to_cart( $product->get_id(), 1 );
|
WC()->cart->add_to_cart( $product->get_id(), 1 );
|
||||||
|
@ -503,11 +622,11 @@ class WC_Tests_Cart extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
// Add 2 products whose retail prices (inc tax) are: £65, £50.
|
// Add 2 products whose retail prices (inc tax) are: £65, £50.
|
||||||
// Their net prices are therefore: £54.1666667 and £41.6666667.
|
// Their net prices are therefore: £54.1666667 and £41.6666667.
|
||||||
$product1 = new WC_Product_Simple;
|
$product1 = new WC_Product_Simple();
|
||||||
$product1->set_regular_price( '54.1666667' );
|
$product1->set_regular_price( '54.1666667' );
|
||||||
$product1->save();
|
$product1->save();
|
||||||
|
|
||||||
$product2 = new WC_Product_Simple;
|
$product2 = new WC_Product_Simple();
|
||||||
$product2->set_regular_price( '41.6666667' );
|
$product2->set_regular_price( '41.6666667' );
|
||||||
$product2->save();
|
$product2->save();
|
||||||
|
|
||||||
|
@ -1191,7 +1310,7 @@ class WC_Tests_Cart extends WC_Unit_Test_Case {
|
||||||
*/
|
*/
|
||||||
public function test_add_discount_code_id() {
|
public function test_add_discount_code_id() {
|
||||||
|
|
||||||
$coupon = new WC_Coupon;
|
$coupon = new WC_Coupon();
|
||||||
$coupon->set_code( 'test' );
|
$coupon->set_code( 'test' );
|
||||||
$coupon->set_amount( 100 );
|
$coupon->set_amount( 100 );
|
||||||
$coupon->save();
|
$coupon->save();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Data Store Tests: Tests WC_Products's WC_Data_Store.
|
* Data Store Tests: Tests WC_Products's WC_Data_Store.
|
||||||
|
*
|
||||||
* @package WooCommerce\Tests\Product
|
* @package WooCommerce\Tests\Product
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +12,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_product_store_loads() {
|
public function test_product_store_loads() {
|
||||||
$product_store = new WC_Data_Store( 'product' );
|
$product_store = new WC_Data_Store( 'product' );
|
||||||
$this->assertTrue( is_callable( array( $product_store, 'read' ) ) );
|
$this->assertTrue( is_callable( array( $product_store, 'read' ) ) );
|
||||||
$this->assertEquals( 'WC_Product_Data_Store_CPT', $product_store->get_current_class_name() );
|
$this->assertEquals( 'WC_Product_Data_Store_CPT', $product_store->get_current_class_name() );
|
||||||
|
@ -22,24 +23,24 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_product_create() {
|
public function test_product_create() {
|
||||||
$product = new WC_Product;
|
$product = new WC_Product();
|
||||||
$product->set_regular_price( 42 );
|
$product->set_regular_price( 42 );
|
||||||
$product->set_name( 'My Product' );
|
$product->set_name( 'My Product' );
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
$read_product = new WC_Product( $product->get_id() );
|
$read_product = new WC_Product( $product->get_id() );
|
||||||
|
|
||||||
$this->assertEquals( '42', $read_product->get_regular_price() );
|
$this->assertEquals( '42', $read_product->get_regular_price() );
|
||||||
$this->assertEquals( 'My Product', $read_product->get_name() );
|
$this->assertEquals( 'My Product', $read_product->get_name() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test reading a product.
|
* Test reading a product.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_product_read() {
|
public function test_product_read() {
|
||||||
$product = WC_Helper_Product::create_simple_product();
|
$product = WC_Helper_Product::create_simple_product();
|
||||||
$product = new WC_Product( $product->get_id() );
|
$product = new WC_Product( $product->get_id() );
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_product_update() {
|
public function test_product_update() {
|
||||||
$product = WC_Helper_Product::create_simple_product();
|
$product = WC_Helper_Product::create_simple_product();
|
||||||
|
|
||||||
$this->assertEquals( '10', $product->get_regular_price() );
|
$this->assertEquals( '10', $product->get_regular_price() );
|
||||||
|
@ -70,7 +71,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_product_trash() {
|
public function test_product_trash() {
|
||||||
$product = WC_Helper_Product::create_simple_product();
|
$product = WC_Helper_Product::create_simple_product();
|
||||||
$product->delete();
|
$product->delete();
|
||||||
$this->assertEquals( 'trash', $product->get_status() );
|
$this->assertEquals( 'trash', $product->get_status() );
|
||||||
|
@ -81,7 +82,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_product_delete() {
|
public function test_product_delete() {
|
||||||
$product = WC_Helper_Product::create_simple_product();
|
$product = WC_Helper_Product::create_simple_product();
|
||||||
$product->delete( true );
|
$product->delete( true );
|
||||||
$this->assertEquals( 0, $product->get_id() );
|
$this->assertEquals( 0, $product->get_id() );
|
||||||
|
@ -92,35 +93,36 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_grouped_product_create() {
|
public function test_grouped_product_create() {
|
||||||
$simple_product = WC_Helper_Product::create_simple_product();
|
$simple_product = WC_Helper_Product::create_simple_product();
|
||||||
$product = new WC_Product_Grouped;
|
$product = new WC_Product_Grouped();
|
||||||
$product->set_children( array( $simple_product->get_id() ) );
|
$product->set_children( array( $simple_product->get_id() ) );
|
||||||
$product->set_name( 'My Grouped Product' );
|
$product->set_name( 'My Grouped Product' );
|
||||||
$product->save();
|
$product->save();
|
||||||
$read_product = new WC_Product_Grouped( $product->get_id() );
|
$read_product = new WC_Product_Grouped( $product->get_id() );
|
||||||
$this->assertEquals( 'My Grouped Product', $read_product->get_name() );
|
$this->assertEquals( 'My Grouped Product', $read_product->get_name() );
|
||||||
$this->assertEquals( array( $simple_product->get_id() ), $read_product->get_children() );
|
$this->assertEquals( array( $simple_product->get_id() ), $read_product->get_children() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test getting / reading an grouped product.
|
* Test getting / reading an grouped product.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_grouped_product_read() {
|
public function test_grouped_product_read() {
|
||||||
$product = WC_Helper_Product::create_grouped_product();
|
$product = WC_Helper_Product::create_grouped_product();
|
||||||
$read_product = new WC_Product_Grouped( $product->get_id() );
|
$read_product = new WC_Product_Grouped( $product->get_id() );
|
||||||
$this->assertEquals( 'Dummy Grouped Product', $read_product->get_name() );
|
$this->assertEquals( 'Dummy Grouped Product', $read_product->get_name() );
|
||||||
$this->assertEquals( 2, count( $read_product->get_children() ) );
|
$this->assertEquals( 2, count( $read_product->get_children() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test updating an grouped product.
|
* Test updating an grouped product.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_grouped_product_update() {
|
public function test_grouped_product_update() {
|
||||||
$product = WC_Helper_Product::create_grouped_product();
|
$product = WC_Helper_Product::create_grouped_product();
|
||||||
$simple_product = WC_Helper_Product::create_simple_product();
|
$simple_product = WC_Helper_Product::create_simple_product();
|
||||||
$this->assertEquals( 'Dummy Grouped Product', $product->get_name() );
|
$this->assertEquals( 'Dummy Grouped Product', $product->get_name() );
|
||||||
$this->assertEquals( 2, count( $product->get_children() ) );
|
$this->assertEquals( 2, count( $product->get_children() ) );
|
||||||
|
@ -140,21 +142,21 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_external_product_create() {
|
public function test_external_product_create() {
|
||||||
$product = new WC_Product_External;
|
$product = new WC_Product_External();
|
||||||
$product->set_regular_price( 42 );
|
$product->set_regular_price( 42 );
|
||||||
$product->set_button_text( 'Test CRUD' );
|
$product->set_button_text( 'Test CRUD' );
|
||||||
$product->set_product_url( 'http://automattic.com' );
|
$product->set_product_url( 'http://automattic.com' );
|
||||||
$product->set_name( 'My External Product' );
|
$product->set_name( 'My External Product' );
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
$read_product = new WC_Product_External( $product->get_id() );
|
$read_product = new WC_Product_External( $product->get_id() );
|
||||||
|
|
||||||
$this->assertEquals( '42', $read_product->get_regular_price() );
|
$this->assertEquals( '42', $read_product->get_regular_price() );
|
||||||
$this->assertEquals( 'Test CRUD', $read_product->get_button_text() );
|
$this->assertEquals( 'Test CRUD', $read_product->get_button_text() );
|
||||||
$this->assertEquals( 'http://automattic.com', $read_product->get_product_url() );
|
$this->assertEquals( 'http://automattic.com', $read_product->get_product_url() );
|
||||||
$this->assertEquals( 'My External Product', $read_product->get_name() );
|
$this->assertEquals( 'My External Product', $read_product->get_name() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test getting / reading an external product. Make sure both our external
|
* Test getting / reading an external product. Make sure both our external
|
||||||
|
@ -162,7 +164,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_external_product_read() {
|
public function test_external_product_read() {
|
||||||
$product = WC_Helper_Product::create_external_product();
|
$product = WC_Helper_Product::create_external_product();
|
||||||
$product = new WC_Product_External( $product->get_id() );
|
$product = new WC_Product_External( $product->get_id() );
|
||||||
|
|
||||||
|
@ -176,7 +178,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_external_product_update() {
|
public function test_external_product_update() {
|
||||||
$product = WC_Helper_Product::create_external_product();
|
$product = WC_Helper_Product::create_external_product();
|
||||||
|
|
||||||
$this->assertEquals( 'Buy external product', $product->get_button_text() );
|
$this->assertEquals( 'Buy external product', $product->get_button_text() );
|
||||||
|
@ -199,7 +201,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public function test_variable_read() {
|
public function test_variable_read() {
|
||||||
$product = WC_Helper_Product::create_variation_product();
|
$product = WC_Helper_Product::create_variation_product();
|
||||||
$children = $product->get_children();
|
$children = $product->get_children();
|
||||||
|
|
||||||
// Test sale prices too
|
// Test sale prices too
|
||||||
|
@ -213,8 +215,10 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
$expected_prices['price'][ $children[0] ] = 8.00;
|
$expected_prices['price'][ $children[0] ] = 8.00;
|
||||||
$expected_prices['price'][ $children[1] ] = 15.00;
|
$expected_prices['price'][ $children[1] ] = 15.00;
|
||||||
|
|
||||||
$expected_prices['regular_price'][ $children[0] ] = 10.00;
|
$expected_prices['regular_price'][ $children[0] ] = 10.00;
|
||||||
$expected_prices['regular_price'][ $children[1] ] = 15.00;
|
$expected_prices['regular_price'][ $children[1] ] = 15.00;
|
||||||
|
|
||||||
$expected_prices['sale_price'][ $children[0] ] = 8.00;
|
$expected_prices['sale_price'][ $children[0] ] = 8.00;
|
||||||
$expected_prices['sale_price'][ $children[1] ] = 15.00;
|
$expected_prices['sale_price'][ $children[1] ] = 15.00;
|
||||||
|
|
||||||
|
@ -230,8 +234,8 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
function test_variables_and_variations() {
|
public function test_variables_and_variations() {
|
||||||
$product = new WC_Product_Variable;
|
$product = new WC_Product_Variable();
|
||||||
$product->set_name( 'Variable Product' );
|
$product->set_name( 'Variable Product' );
|
||||||
|
|
||||||
$attribute = new WC_Product_Attribute();
|
$attribute = new WC_Product_Attribute();
|
||||||
|
@ -246,7 +250,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
$this->assertEquals( 'Variable Product', $product->get_name() );
|
$this->assertEquals( 'Variable Product', $product->get_name() );
|
||||||
|
|
||||||
$variation = new WC_Product_Variation;
|
$variation = new WC_Product_Variation();
|
||||||
$variation->set_parent_id( $product->get_id() );
|
$variation->set_parent_id( $product->get_id() );
|
||||||
$variation->set_regular_price( 10 );
|
$variation->set_regular_price( 10 );
|
||||||
$variation->set_sku( 'CRUD DUMMY SKU VARIABLE GREEN' );
|
$variation->set_sku( 'CRUD DUMMY SKU VARIABLE GREEN' );
|
||||||
|
@ -260,14 +264,14 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$this->assertEquals( 'CRUD DUMMY SKU VARIABLE GREEN', $variation->get_sku() );
|
$this->assertEquals( 'CRUD DUMMY SKU VARIABLE GREEN', $variation->get_sku() );
|
||||||
$this->assertEquals( 10, $variation->get_price() );
|
$this->assertEquals( 10, $variation->get_price() );
|
||||||
|
|
||||||
$product = new WC_Product_Variable( $product->get_id() );
|
$product = new WC_Product_Variable( $product->get_id() );
|
||||||
$children = $product->get_children();
|
$children = $product->get_children();
|
||||||
$this->assertEquals( $variation->get_id(), $children[0] );
|
$this->assertEquals( $variation->get_id(), $children[0] );
|
||||||
|
|
||||||
$expected_attributes = array( 'pa_color' => array( 'green' ) );
|
$expected_attributes = array( 'pa_color' => array( 'green' ) );
|
||||||
$this->assertEquals( $expected_attributes, $product->get_variation_attributes() );
|
$this->assertEquals( $expected_attributes, $product->get_variation_attributes() );
|
||||||
|
|
||||||
$variation_2 = new WC_Product_Variation;
|
$variation_2 = new WC_Product_Variation();
|
||||||
$variation_2->set_parent_id( $product->get_id() );
|
$variation_2->set_parent_id( $product->get_id() );
|
||||||
$variation_2->set_regular_price( 10 );
|
$variation_2->set_regular_price( 10 );
|
||||||
$variation_2->set_sku( 'CRUD DUMMY SKU VARIABLE RED' );
|
$variation_2->set_sku( 'CRUD DUMMY SKU VARIABLE RED' );
|
||||||
|
@ -281,7 +285,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$this->assertEquals( 'CRUD DUMMY SKU VARIABLE RED', $variation_2->get_sku() );
|
$this->assertEquals( 'CRUD DUMMY SKU VARIABLE RED', $variation_2->get_sku() );
|
||||||
$this->assertEquals( 10, $variation_2->get_price() );
|
$this->assertEquals( 10, $variation_2->get_price() );
|
||||||
|
|
||||||
$product = new WC_Product_Variable( $product->get_id() );
|
$product = new WC_Product_Variable( $product->get_id() );
|
||||||
$children = $product->get_children();
|
$children = $product->get_children();
|
||||||
$this->assertEquals( $variation_2->get_id(), $children[1] );
|
$this->assertEquals( $variation_2->get_id(), $children[1] );
|
||||||
$this->assertEquals( 2, count( $children ) );
|
$this->assertEquals( 2, count( $children ) );
|
||||||
|
@ -295,10 +299,13 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$variation_2->save();
|
$variation_2->save();
|
||||||
|
|
||||||
$product = new WC_Product_Variable( $product->get_id() );
|
$product = new WC_Product_Variable( $product->get_id() );
|
||||||
|
|
||||||
$expected_prices['price'][ $children[0] ] = 10.00;
|
$expected_prices['price'][ $children[0] ] = 10.00;
|
||||||
$expected_prices['price'][ $children[1] ] = 9.99;
|
$expected_prices['price'][ $children[1] ] = 9.99;
|
||||||
|
|
||||||
$expected_prices['regular_price'][ $children[0] ] = 10.00;
|
$expected_prices['regular_price'][ $children[0] ] = 10.00;
|
||||||
$expected_prices['regular_price'][ $children[1] ] = 15.00;
|
$expected_prices['regular_price'][ $children[1] ] = 15.00;
|
||||||
|
|
||||||
$expected_prices['sale_price'][ $children[0] ] = 10.00;
|
$expected_prices['sale_price'][ $children[0] ] = 10.00;
|
||||||
$expected_prices['sale_price'][ $children[1] ] = 9.99;
|
$expected_prices['sale_price'][ $children[1] ] = 9.99;
|
||||||
|
|
||||||
|
@ -310,9 +317,9 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$product->delete();
|
$product->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_variation_save_attributes() {
|
public function test_variation_save_attributes() {
|
||||||
// Create a variable product with a color attribute.
|
// Create a variable product with a color attribute.
|
||||||
$product = new WC_Product_Variable;
|
$product = new WC_Product_Variable();
|
||||||
|
|
||||||
$attribute = new WC_Product_Attribute();
|
$attribute = new WC_Product_Attribute();
|
||||||
$attribute->set_id( 0 );
|
$attribute->set_id( 0 );
|
||||||
|
@ -325,7 +332,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
// Create a new variation with the color 'green'.
|
// Create a new variation with the color 'green'.
|
||||||
$variation = new WC_Product_Variation;
|
$variation = new WC_Product_Variation();
|
||||||
$variation->set_parent_id( $product->get_id() );
|
$variation->set_parent_id( $product->get_id() );
|
||||||
$variation->set_attributes( array( 'color' => 'green' ) );
|
$variation->set_attributes( array( 'color' => 'green' ) );
|
||||||
$variation->set_status( 'private' );
|
$variation->set_status( 'private' );
|
||||||
|
@ -347,46 +354,46 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
public function test_save_default_attributes() {
|
public function test_save_default_attributes() {
|
||||||
|
|
||||||
// Create a variable product with sold individually.
|
// Create a variable product with sold individually.
|
||||||
$product = new WC_Product_Variable;
|
$product = new WC_Product_Variable();
|
||||||
$product->save();
|
$product->save();
|
||||||
$product_id = $product->get_id();
|
$product_id = $product->get_id();
|
||||||
|
|
||||||
// Save with a set of FALSE equivalents and some values we expect to come through as true. We should see
|
// Save with a set of FALSE equivalents and some values we expect to come through as true. We should see
|
||||||
// string types with a value of '0' making it through filtration.
|
// string types with a value of '0' making it through filtration.
|
||||||
$test_object = new stdClass();
|
$test_object = new stdClass();
|
||||||
$test_object->property = '12345';
|
$test_object->property = '12345';
|
||||||
$product->set_default_attributes( array(
|
$product->set_default_attributes( array(
|
||||||
'sample-attribute-false-0' => 0,
|
'sample-attribute-false-0' => 0,
|
||||||
'sample-attribute-false-1' => false,
|
'sample-attribute-false-1' => false,
|
||||||
'sample-attribute-false-2' => '',
|
'sample-attribute-false-2' => '',
|
||||||
'sample-attribute-false-3' => null,
|
'sample-attribute-false-3' => null,
|
||||||
'sample-attribute-true-0' => '0',
|
'sample-attribute-true-0' => '0',
|
||||||
'sample-attribute-true-1' => 1,
|
'sample-attribute-true-1' => 1,
|
||||||
'sample-attribute-true-2' => 'true',
|
'sample-attribute-true-2' => 'true',
|
||||||
'sample-attribute-true-3' => 'false',
|
'sample-attribute-true-3' => 'false',
|
||||||
'sample-attribute-true-4' => array( 'exists' => 'false' ),
|
'sample-attribute-true-4' => array( 'exists' => 'false' ),
|
||||||
'sample-attribute-false-4' => $test_object,
|
'sample-attribute-false-4' => $test_object,
|
||||||
));
|
));
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
// Revive the product from the database and analyze results
|
// Revive the product from the database and analyze results
|
||||||
$product = wc_get_product( $product_id );
|
$product = wc_get_product( $product_id );
|
||||||
$default_attributes = $product->get_default_attributes();
|
$default_attributes = $product->get_default_attributes();
|
||||||
$this->assertEquals( $default_attributes, array(
|
$this->assertEquals( $default_attributes, array(
|
||||||
'sample-attribute-true-0' => '0',
|
'sample-attribute-true-0' => '0',
|
||||||
'sample-attribute-true-1' => 1,
|
'sample-attribute-true-1' => 1,
|
||||||
'sample-attribute-true-2' => 'true',
|
'sample-attribute-true-2' => 'true',
|
||||||
'sample-attribute-true-3' => 'false',
|
'sample-attribute-true-3' => 'false',
|
||||||
'sample-attribute-true-4' => array( 'exists' => 'false' ),
|
'sample-attribute-true-4' => array( 'exists' => 'false' ),
|
||||||
'sample-attribute-false-4' => $test_object,
|
'sample-attribute-false-4' => $test_object,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_variable_child_has_dimensions() {
|
public function test_variable_child_has_dimensions() {
|
||||||
$product = new WC_Product_Variable;
|
$product = new WC_Product_Variable();
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
$variation = new WC_Product_variation;
|
$variation = new WC_Product_Variation();
|
||||||
$variation->set_parent_id( $product->get_id() );
|
$variation->set_parent_id( $product->get_id() );
|
||||||
$variation->set_width( 10 );
|
$variation->set_width( 10 );
|
||||||
$variation->save();
|
$variation->save();
|
||||||
|
@ -398,11 +405,11 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$this->assertTrue( $store->child_has_dimensions( $product ) );
|
$this->assertTrue( $store->child_has_dimensions( $product ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_variable_child_has_dimensions_no_dimensions() {
|
public function test_variable_child_has_dimensions_no_dimensions() {
|
||||||
$product = new WC_Product_Variable;
|
$product = new WC_Product_Variable();
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
$variation = new WC_Product_variation;
|
$variation = new WC_Product_Variation();
|
||||||
$variation->set_parent_id( $product->get_id() );
|
$variation->set_parent_id( $product->get_id() );
|
||||||
$variation->save();
|
$variation->save();
|
||||||
|
|
||||||
|
@ -413,7 +420,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$this->assertFalse( $store->child_has_dimensions( $product ) );
|
$this->assertFalse( $store->child_has_dimensions( $product ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_get_on_sale_products() {
|
public function test_get_on_sale_products() {
|
||||||
$product_store = new WC_Product_Data_Store_CPT();
|
$product_store = new WC_Product_Data_Store_CPT();
|
||||||
|
|
||||||
$sale_product = WC_Helper_Product::create_simple_product();
|
$sale_product = WC_Helper_Product::create_simple_product();
|
||||||
|
@ -434,7 +441,7 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$future_sale_product->set_price( $future_sale_product->get_regular_price() );
|
$future_sale_product->set_price( $future_sale_product->get_regular_price() );
|
||||||
$future_sale_product->save();
|
$future_sale_product->save();
|
||||||
|
|
||||||
$sale_products = $product_store->get_on_sale_products();
|
$sale_products = $product_store->get_on_sale_products();
|
||||||
$sale_product_ids = wp_list_pluck( $sale_products, 'id' );
|
$sale_product_ids = wp_list_pluck( $sale_products, 'id' );
|
||||||
|
|
||||||
$this->assertContains( $sale_product->get_id(), $sale_product_ids );
|
$this->assertContains( $sale_product->get_id(), $sale_product_ids );
|
||||||
|
@ -442,64 +449,71 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
$this->assertNotContains( $future_sale_product->get_id(), $sale_product_ids );
|
$this->assertNotContains( $future_sale_product->get_id(), $sale_product_ids );
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_generate_product_title() {
|
public function test_generate_product_title() {
|
||||||
$product = new WC_Product;
|
$product = new WC_Product();
|
||||||
$product->set_name( 'Test Product' );
|
$product->set_name( 'Test Product' );
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
$one_attribute_variation = new WC_Product_Variation;
|
$one_attribute_variation = new WC_Product_Variation();
|
||||||
$one_attribute_variation->set_parent_id( $product->get_id() );
|
$one_attribute_variation->set_parent_id( $product->get_id() );
|
||||||
$one_attribute_variation->set_attributes( array( 'color' => 'Green' ) );
|
$one_attribute_variation->set_attributes( array( 'color' => 'Green' ) );
|
||||||
$one_attribute_variation->save();
|
$one_attribute_variation->save();
|
||||||
|
|
||||||
$two_attribute_variation = new WC_Product_Variation;
|
$two_attribute_variation = new WC_Product_Variation();
|
||||||
$two_attribute_variation->set_parent_id( $product->get_id() );
|
$two_attribute_variation->set_parent_id( $product->get_id() );
|
||||||
$two_attribute_variation->set_attributes( array( 'color' => 'Green', 'size' => 'Large' ) );
|
$two_attribute_variation->set_attributes( array(
|
||||||
|
'color' => 'Green',
|
||||||
|
'size' => 'Large',
|
||||||
|
) );
|
||||||
$two_attribute_variation->save();
|
$two_attribute_variation->save();
|
||||||
|
|
||||||
$multiword_attribute_variation = new WC_Product_Variation;
|
$multiword_attribute_variation = new WC_Product_Variation();
|
||||||
$multiword_attribute_variation->set_parent_id( $product->get_id() );
|
$multiword_attribute_variation->set_parent_id( $product->get_id() );
|
||||||
$multiword_attribute_variation->set_attributes( array( 'color' => 'Green', 'mounting-plate' => 'galaxy-s6', 'support' => 'one-year' ) );
|
$multiword_attribute_variation->set_attributes( array(
|
||||||
|
'color' => 'Green',
|
||||||
|
'mounting-plate' => 'galaxy-s6',
|
||||||
|
'support' => 'one-year',
|
||||||
|
) );
|
||||||
$multiword_attribute_variation->save();
|
$multiword_attribute_variation->save();
|
||||||
|
|
||||||
// Check the one attribute variation title.
|
// Check the one attribute variation title.
|
||||||
$this->assertEquals( "Test Product - Green", $one_attribute_variation->get_name() );
|
$this->assertEquals( 'Test Product - Green', $one_attribute_variation->get_name() );
|
||||||
|
|
||||||
// Check the two attribute variation title.
|
// Check the two attribute variation title.
|
||||||
$this->assertEquals( "Test Product - Green, Large", $two_attribute_variation->get_name() );
|
$this->assertEquals( 'Test Product - Green, Large', $two_attribute_variation->get_name() );
|
||||||
|
|
||||||
// Check the variation with a multiword attribute name.
|
// Check the variation with a multiword attribute name.
|
||||||
$this->assertEquals( "Test Product", $multiword_attribute_variation->get_name() );
|
$this->assertEquals( 'Test Product', $multiword_attribute_variation->get_name() );
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_generate_product_title_disable() {
|
public function test_generate_product_title_disable() {
|
||||||
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
|
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
|
||||||
|
|
||||||
$product = new WC_Product;
|
$product = new WC_Product();
|
||||||
$product->set_name( 'Test Product' );
|
$product->set_name( 'Test Product' );
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
$variation = new WC_Product_Variation;
|
$variation = new WC_Product_Variation();
|
||||||
$variation->set_parent_id( $product->get_id() );
|
$variation->set_parent_id( $product->get_id() );
|
||||||
$variation->set_attributes( array( 'color' => 'green' ) );
|
$variation->set_attributes( array( 'color' => 'green' ) );
|
||||||
$variation->save();
|
$variation->save();
|
||||||
|
|
||||||
$loaded_variation = wc_get_product( $variation->get_id() );
|
$loaded_variation = wc_get_product( $variation->get_id() );
|
||||||
$this->assertEquals( "Test Product", $loaded_variation->get_name() );
|
$this->assertEquals( 'Test Product', $loaded_variation->get_name() );
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_generate_product_title_no_attributes() {
|
public function test_generate_product_title_no_attributes() {
|
||||||
$product = new WC_Product;
|
$product = new WC_Product();
|
||||||
$product->set_name( 'Test Product' );
|
$product->set_name( 'Test Product' );
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
$variation = new WC_Product_Variation;
|
$variation = new WC_Product_Variation();
|
||||||
$variation->set_parent_id( $product->get_id() );
|
$variation->set_parent_id( $product->get_id() );
|
||||||
$variation->set_attributes( array() );
|
$variation->set_attributes( array() );
|
||||||
$variation->save();
|
$variation->save();
|
||||||
|
|
||||||
$loaded_variation = wc_get_product( $variation->get_id() );
|
$loaded_variation = wc_get_product( $variation->get_id() );
|
||||||
$this->assertEquals( "Test Product", $loaded_variation->get_name() );
|
$this->assertEquals( 'Test Product', $loaded_variation->get_name() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -507,8 +521,8 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
* https://github.com/woocommerce/woocommerce/issues/13960
|
* https://github.com/woocommerce/woocommerce/issues/13960
|
||||||
* @since 3.0.1
|
* @since 3.0.1
|
||||||
*/
|
*/
|
||||||
function test_product_meta_save_post() {
|
public function test_product_meta_save_post() {
|
||||||
$product = new WC_Product;
|
$product = new WC_Product();
|
||||||
$product->set_name( 'Test Product' );
|
$product->set_name( 'Test Product' );
|
||||||
$product->save();
|
$product->save();
|
||||||
update_post_meta( $product->get_id(), '_test2', 'default' ); // this is the value we don't want to get back.
|
update_post_meta( $product->get_id(), '_test2', 'default' ); // this is the value we don't want to get back.
|
||||||
|
@ -530,4 +544,85 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
remove_action( 'save_post', array( 'WC_Helper_Product', 'save_post_test_update_meta_data_direct' ) );
|
remove_action( 'save_post', array( 'WC_Helper_Product', 'save_post_test_update_meta_data_direct' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Product search functionality.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function test_search_products() {
|
||||||
|
// Create some products to search for.
|
||||||
|
$product = new WC_Product();
|
||||||
|
$product->set_regular_price( 42 );
|
||||||
|
$product->set_name( 'Blue widget' );
|
||||||
|
$product->set_sku( 'blue-widget-1' );
|
||||||
|
$product->set_description( "You bet I'm agitated! I may be surrounded by insanity, but I am not insane. I suggest you drop it, Mr. Data. Not if I weaken first. Earl Grey tea, watercress sandwiches... and Bularian canapés? Are you up for promotion? and attack the Romulans. Yesterday I did not know how to eat gagh." );
|
||||||
|
$product->save();
|
||||||
|
|
||||||
|
$product2 = new WC_Product();
|
||||||
|
$product2->set_regular_price( 42 );
|
||||||
|
$product2->set_name( 'Red widget' );
|
||||||
|
$product2->set_sku( 'red-widget-1' );
|
||||||
|
$product2->set_description( "and attack the Romulans. Fear is the true enemy, the only enemy. The game's not big enough unless it scares you a little. What? We're not at all alike! Now, how the hell do we defeat an enemy that knows us better than we know ourselves? Mr. Worf, you do remember how to fire phasers?" );
|
||||||
|
$product2->save();
|
||||||
|
|
||||||
|
$product3 = new WC_Product();
|
||||||
|
$product3->set_regular_price( 42 );
|
||||||
|
$product3->set_name( 'Green widget' );
|
||||||
|
$product3->set_sku( 'green-widget-1' );
|
||||||
|
$product3->set_description( 'For an android with no feelings, he sure managed to evoke them in others. Then maybe you should consider this: if anything happens to them, Starfleet is going to want a full investigation. We have a saboteur aboard.' );
|
||||||
|
$product3->save();
|
||||||
|
|
||||||
|
$product4 = new WC_Product();
|
||||||
|
$product4->set_regular_price( 42 );
|
||||||
|
$product4->set_name( 'Another green widget' );
|
||||||
|
$product4->set_sku( 'green-widget-2' );
|
||||||
|
$product4->set_description( 'For an android with no feelings, he sure managed to evoke them in others. Then maybe you should consider this: if anything happens to them, Starfleet is going to want a full investigation. We have a saboteur aboard.' );
|
||||||
|
$product4->save();
|
||||||
|
|
||||||
|
$data_store = WC_Data_Store::load( 'product' );
|
||||||
|
|
||||||
|
// Search some things :)
|
||||||
|
$results = $data_store->search_products( 'green', '', true, true );
|
||||||
|
$this->assertNotContains( $product->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product2->get_id(), $results );
|
||||||
|
$this->assertContains( $product3->get_id(), $results );
|
||||||
|
$this->assertContains( $product4->get_id(), $results );
|
||||||
|
|
||||||
|
$results = $data_store->search_products( 'blue-widget-1', '', true, true );
|
||||||
|
$this->assertContains( $product->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product2->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product3->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product4->get_id(), $results );
|
||||||
|
|
||||||
|
$results = $data_store->search_products( 'blue-widget-1 OR green-widget', '', true, true );
|
||||||
|
$this->assertContains( $product->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product2->get_id(), $results );
|
||||||
|
$this->assertContains( $product3->get_id(), $results );
|
||||||
|
$this->assertContains( $product4->get_id(), $results );
|
||||||
|
|
||||||
|
$results = $data_store->search_products( '"green widget"', '', true, true );
|
||||||
|
$this->assertNotContains( $product->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product2->get_id(), $results );
|
||||||
|
$this->assertContains( $product3->get_id(), $results );
|
||||||
|
$this->assertContains( $product4->get_id(), $results );
|
||||||
|
|
||||||
|
$results = $data_store->search_products( 'Another widget', '', true, true );
|
||||||
|
$this->assertNotContains( $product->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product2->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product3->get_id(), $results );
|
||||||
|
$this->assertContains( $product4->get_id(), $results );
|
||||||
|
|
||||||
|
$results = $data_store->search_products( '"Fear is the true enemy"', '', true, true );
|
||||||
|
$this->assertNotContains( $product->get_id(), $results );
|
||||||
|
$this->assertContains( $product2->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product3->get_id(), $results );
|
||||||
|
$this->assertNotContains( $product4->get_id(), $results );
|
||||||
|
|
||||||
|
// Clean up.
|
||||||
|
$product->delete();
|
||||||
|
$product2->delete();
|
||||||
|
$product3->delete();
|
||||||
|
$product4->delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
|
||||||
$shortcode = new WC_Shortcode_Products();
|
$shortcode = new WC_Shortcode_Products();
|
||||||
$expected = array(
|
$expected = array(
|
||||||
'limit' => '-1',
|
'limit' => '-1',
|
||||||
'columns' => '3',
|
'columns' => '4',
|
||||||
'orderby' => 'title',
|
'orderby' => 'title',
|
||||||
'order' => 'ASC',
|
'order' => 'ASC',
|
||||||
'ids' => '',
|
'ids' => '',
|
||||||
|
@ -40,7 +40,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
|
||||||
) );
|
) );
|
||||||
$expected2 = array(
|
$expected2 = array(
|
||||||
'limit' => '-1',
|
'limit' => '-1',
|
||||||
'columns' => '3',
|
'columns' => '4',
|
||||||
'orderby' => 'id',
|
'orderby' => 'id',
|
||||||
'order' => 'DESC',
|
'order' => 'DESC',
|
||||||
'ids' => '',
|
'ids' => '',
|
||||||
|
|
|
@ -125,4 +125,25 @@ class WC_Tests_Install extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
$this->assertEquals( $tables, WC_Install::get_tables() );
|
$this->assertEquals( $tables, WC_Install::get_tables() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test - get tables should apply the woocommerce_install_get_tables filter.
|
||||||
|
*/
|
||||||
|
public function test_get_tables_enables_filter() {
|
||||||
|
$default = WC_Install::get_tables();
|
||||||
|
$added = $this->append_table_to_get_tables( array() );
|
||||||
|
|
||||||
|
add_filter( 'woocommerce_install_get_tables', array( $this, 'append_table_to_get_tables' ) );
|
||||||
|
|
||||||
|
$this->assertEquals( $added, array_values( array_diff( WC_Install::get_tables(), $default ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter callback for test_get_tables_enables_filter().
|
||||||
|
*/
|
||||||
|
public function append_table_to_get_tables( $tables ) {
|
||||||
|
$tables[] = 'some_table_name';
|
||||||
|
|
||||||
|
return $tables;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,33 +106,33 @@ class WC_Tests_Validation extends WC_Unit_Test_Case {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data provider for test_is_GB_postcode.
|
* Data provider for test_is_gb_postcode.
|
||||||
*
|
*
|
||||||
* @since 2.4
|
* @since 2.4
|
||||||
*/
|
*/
|
||||||
public function data_provider_test_is_GB_postcode() {
|
public function data_provider_test_is_gb_postcode() {
|
||||||
return array(
|
return array(
|
||||||
array( true, WC_Validation::is_GB_postcode( 'AA9A 9AA' ) ),
|
array( true, WC_Validation::is_gb_postcode( 'AA9A 9AA' ) ),
|
||||||
array( true, WC_Validation::is_GB_postcode( 'A9A 9AA' ) ),
|
array( true, WC_Validation::is_gb_postcode( 'A9A 9AA' ) ),
|
||||||
array( true, WC_Validation::is_GB_postcode( 'A9 9AA' ) ),
|
array( true, WC_Validation::is_gb_postcode( 'A9 9AA' ) ),
|
||||||
array( true, WC_Validation::is_GB_postcode( 'A99 9AA' ) ),
|
array( true, WC_Validation::is_gb_postcode( 'A99 9AA' ) ),
|
||||||
array( true, WC_Validation::is_GB_postcode( 'AA99 9AA' ) ),
|
array( true, WC_Validation::is_gb_postcode( 'AA99 9AA' ) ),
|
||||||
array( true, WC_Validation::is_GB_postcode( 'BFPO 801' ) ),
|
array( true, WC_Validation::is_gb_postcode( 'BFPO 801' ) ),
|
||||||
array( false, WC_Validation::is_GB_postcode( '99999' ) ),
|
array( false, WC_Validation::is_gb_postcode( '99999' ) ),
|
||||||
array( false, WC_Validation::is_GB_postcode( '9999 999' ) ),
|
array( false, WC_Validation::is_gb_postcode( '9999 999' ) ),
|
||||||
array( false, WC_Validation::is_GB_postcode( '999 999' ) ),
|
array( false, WC_Validation::is_gb_postcode( '999 999' ) ),
|
||||||
array( false, WC_Validation::is_GB_postcode( '99 999' ) ),
|
array( false, WC_Validation::is_gb_postcode( '99 999' ) ),
|
||||||
array( false, WC_Validation::is_GB_postcode( '9A A9A' ) ),
|
array( false, WC_Validation::is_gb_postcode( '9A A9A' ) ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test is_GB_postcode().
|
* Test is_gb_postcode().
|
||||||
*
|
*
|
||||||
* @dataProvider data_provider_test_is_GB_postcode
|
* @dataProvider data_provider_test_is_gb_postcode
|
||||||
* @since 2.4
|
* @since 2.4
|
||||||
*/
|
*/
|
||||||
public function test_is_GB_postcode( $assert, $values ) {
|
public function test_is_gb_postcode( $assert, $values ) {
|
||||||
$this->assertEquals( $assert, $values );
|
$this->assertEquals( $assert, $values );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue