Merge pull request #26174 from woocommerce/fix/25843
Fix stock status saving for variable products on bulk and quick edit
This commit is contained in:
commit
aafb06929a
|
@ -7268,3 +7268,8 @@ table.bar_chart {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wc-quick-edit-warning {
|
||||||
|
color: darkred;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
/*global inlineEditPost, woocommerce_admin, woocommerce_quick_edit */
|
/*global inlineEditPost, woocommerce_admin, woocommerce_quick_edit */
|
||||||
jQuery(function( $ ) {
|
jQuery(
|
||||||
$( '#the-list' ).on( 'click', '.editinline', function() {
|
function( $ ) {
|
||||||
|
$( '#the-list' ).on(
|
||||||
|
'click',
|
||||||
|
'.editinline',
|
||||||
|
function() {
|
||||||
|
|
||||||
inlineEditPost.revert();
|
inlineEditPost.revert();
|
||||||
|
|
||||||
|
@ -12,7 +16,7 @@ jQuery(function( $ ) {
|
||||||
|
|
||||||
var sku = $wc_inline_data.find( '.sku' ).text(),
|
var sku = $wc_inline_data.find( '.sku' ).text(),
|
||||||
regular_price = $wc_inline_data.find( '.regular_price' ).text(),
|
regular_price = $wc_inline_data.find( '.regular_price' ).text(),
|
||||||
sale_price = $wc_inline_data.find( '.sale_price ').text(),
|
sale_price = $wc_inline_data.find( '.sale_price ' ).text(),
|
||||||
weight = $wc_inline_data.find( '.weight' ).text(),
|
weight = $wc_inline_data.find( '.weight' ).text(),
|
||||||
length = $wc_inline_data.find( '.length' ).text(),
|
length = $wc_inline_data.find( '.length' ).text(),
|
||||||
width = $wc_inline_data.find( '.width' ).text(),
|
width = $wc_inline_data.find( '.width' ).text(),
|
||||||
|
@ -26,10 +30,11 @@ jQuery(function( $ ) {
|
||||||
menu_order = $wc_inline_data.find( '.menu_order' ).text(),
|
menu_order = $wc_inline_data.find( '.menu_order' ).text(),
|
||||||
tax_status = $wc_inline_data.find( '.tax_status' ).text(),
|
tax_status = $wc_inline_data.find( '.tax_status' ).text(),
|
||||||
tax_class = $wc_inline_data.find( '.tax_class' ).text(),
|
tax_class = $wc_inline_data.find( '.tax_class' ).text(),
|
||||||
backorders = $wc_inline_data.find( '.backorders' ).text();
|
backorders = $wc_inline_data.find( '.backorders' ).text(),
|
||||||
|
product_type = $wc_inline_data.find( '.product_type' ).text();
|
||||||
|
|
||||||
var formatted_regular_price = regular_price.replace('.', woocommerce_admin.mon_decimal_point ),
|
var formatted_regular_price = regular_price.replace( '.', woocommerce_admin.mon_decimal_point ),
|
||||||
formatted_sale_price = sale_price.replace('.', woocommerce_admin.mon_decimal_point );
|
formatted_sale_price = sale_price.replace( '.', woocommerce_admin.mon_decimal_point );
|
||||||
|
|
||||||
$( 'input[name="_sku"]', '.inline-edit-row' ).val( sku );
|
$( 'input[name="_sku"]', '.inline-edit-row' ).val( sku );
|
||||||
$( 'input[name="_regular_price"]', '.inline-edit-row' ).val( formatted_regular_price );
|
$( 'input[name="_regular_price"]', '.inline-edit-row' ).val( formatted_regular_price );
|
||||||
|
@ -45,13 +50,22 @@ jQuery(function( $ ) {
|
||||||
$( 'input[name="_stock"]', '.inline-edit-row' ).val( stock );
|
$( 'input[name="_stock"]', '.inline-edit-row' ).val( stock );
|
||||||
$( 'input[name="menu_order"]', '.inline-edit-row' ).val( menu_order );
|
$( 'input[name="menu_order"]', '.inline-edit-row' ).val( menu_order );
|
||||||
|
|
||||||
// eslint-disable-next-line max-len
|
$(
|
||||||
$( 'select[name="_tax_status"] option, select[name="_tax_class"] option, select[name="_visibility"] option, select[name="_stock_status"] option, select[name="_backorders"] option' ).removeAttr( 'selected' );
|
'select[name="_tax_status"] option, ' +
|
||||||
|
'select[name="_tax_class"] option, ' +
|
||||||
|
'select[name="_visibility"] option, ' +
|
||||||
|
'select[name="_stock_status"] option, ' +
|
||||||
|
'select[name="_backorders"] option'
|
||||||
|
).removeAttr( 'selected' );
|
||||||
|
|
||||||
|
var is_variable_product = 'variable' === product_type;
|
||||||
|
$( 'select[name="_stock_status"] ~ .wc-quick-edit-warning', '.inline-edit-row' ).toggle( is_variable_product );
|
||||||
|
$( 'select[name="_stock_status"] option[value="' + (is_variable_product ? '' : stock_status) + '"]', '.inline-edit-row' )
|
||||||
|
.attr( 'selected', 'selected' );
|
||||||
|
|
||||||
$( 'select[name="_tax_status"] option[value="' + tax_status + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
$( 'select[name="_tax_status"] option[value="' + tax_status + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
||||||
$( 'select[name="_tax_class"] option[value="' + tax_class + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
$( 'select[name="_tax_class"] option[value="' + tax_class + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
||||||
$( 'select[name="_visibility"] option[value="' + visibility + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
$( 'select[name="_visibility"] option[value="' + visibility + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
||||||
$( 'select[name="_stock_status"] option[value="' + stock_status + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
|
||||||
$( 'select[name="_backorders"] option[value="' + backorders + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
$( 'select[name="_backorders"] option[value="' + backorders + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' );
|
||||||
|
|
||||||
if ( 'yes' === featured ) {
|
if ( 'yes' === featured ) {
|
||||||
|
@ -60,9 +74,8 @@ jQuery(function( $ ) {
|
||||||
$( 'input[name="_featured"]', '.inline-edit-row' ).removeAttr( 'checked' );
|
$( 'input[name="_featured"]', '.inline-edit-row' ).removeAttr( 'checked' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conditional display
|
// Conditional display.
|
||||||
var product_type = $wc_inline_data.find( '.product_type' ).text(),
|
var product_is_virtual = $wc_inline_data.find( '.product_is_virtual' ).text();
|
||||||
product_is_virtual = $wc_inline_data.find( '.product_is_virtual' ).text();
|
|
||||||
|
|
||||||
var product_supports_stock_status = 'external' !== product_type;
|
var product_supports_stock_status = 'external' !== product_type;
|
||||||
var product_supports_stock_fields = 'external' !== product_type && 'grouped' !== product_type;
|
var product_supports_stock_fields = 'external' !== product_type && 'grouped' !== product_type;
|
||||||
|
@ -97,11 +110,15 @@ jQuery(function( $ ) {
|
||||||
$( '.dimension_fields', '.inline-edit-row' ).show().removeAttr( 'style' );
|
$( '.dimension_fields', '.inline-edit-row' ).show().removeAttr( 'style' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename core strings
|
// Rename core strings.
|
||||||
$( 'input[name="comment_status"]' ).parent().find( '.checkbox-title' ).text( woocommerce_quick_edit.strings.allow_reviews );
|
$( 'input[name="comment_status"]' ).parent().find( '.checkbox-title' ).text( woocommerce_quick_edit.strings.allow_reviews );
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$( '#the-list' ).on( 'change', '.inline-edit-row input[name="_manage_stock"]', function() {
|
$( '#the-list' ).on(
|
||||||
|
'change',
|
||||||
|
'.inline-edit-row input[name="_manage_stock"]',
|
||||||
|
function() {
|
||||||
|
|
||||||
if ( $( this ).is( ':checked' ) ) {
|
if ( $( this ).is( ':checked' ) ) {
|
||||||
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).show().removeAttr( 'style' );
|
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).show().removeAttr( 'style' );
|
||||||
|
@ -111,15 +128,23 @@ jQuery(function( $ ) {
|
||||||
$( '.stock_status_field' ).show().removeAttr( 'style' );
|
$( '.stock_status_field' ).show().removeAttr( 'style' );
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$( '#wpbody' ).on( 'click', '#doaction, #doaction2', function() {
|
$( '#wpbody' ).on(
|
||||||
|
'click',
|
||||||
|
'#doaction, #doaction2',
|
||||||
|
function() {
|
||||||
$( 'input.text', '.inline-edit-row' ).val( '' );
|
$( 'input.text', '.inline-edit-row' ).val( '' );
|
||||||
$( '#woocommerce-fields' ).find( 'select' ).prop( 'selectedIndex', 0 );
|
$( '#woocommerce-fields' ).find( 'select' ).prop( 'selectedIndex', 0 );
|
||||||
$( '#woocommerce-fields-bulk' ).find( '.inline-edit-group .change-input' ).hide();
|
$( '#woocommerce-fields-bulk' ).find( '.inline-edit-group .change-input' ).hide();
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$( '#wpbody' ).on( 'change', '#woocommerce-fields-bulk .inline-edit-group .change_to', function() {
|
$( '#wpbody' ).on(
|
||||||
|
'change',
|
||||||
|
'#woocommerce-fields-bulk .inline-edit-group .change_to',
|
||||||
|
function() {
|
||||||
|
|
||||||
if ( 0 < $( this ).val() ) {
|
if ( 0 < $( this ).val() ) {
|
||||||
$( this ).closest( 'div' ).find( '.change-input' ).show();
|
$( this ).closest( 'div' ).find( '.change-input' ).show();
|
||||||
|
@ -127,9 +152,15 @@ jQuery(function( $ ) {
|
||||||
$( this ).closest( 'div' ).find( '.change-input' ).hide();
|
$( this ).closest( 'div' ).find( '.change-input' ).hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$( '#wpbody' ).on( 'click', '.trash-product', function() {
|
$( '#wpbody' ).on(
|
||||||
|
'click',
|
||||||
|
'.trash-product',
|
||||||
|
function() {
|
||||||
return window.confirm( woocommerce_admin.i18n_delete_product_notice );
|
return window.confirm( woocommerce_admin.i18n_delete_product_notice );
|
||||||
});
|
}
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
|
@ -79,6 +79,8 @@ class WC_Admin_Post_Types {
|
||||||
public function setup_screen() {
|
public function setup_screen() {
|
||||||
global $wc_list_table;
|
global $wc_list_table;
|
||||||
|
|
||||||
|
$request_data = $this->request_data();
|
||||||
|
|
||||||
$screen_id = false;
|
$screen_id = false;
|
||||||
|
|
||||||
if ( function_exists( 'get_current_screen' ) ) {
|
if ( function_exists( 'get_current_screen' ) ) {
|
||||||
|
@ -86,8 +88,8 @@ class WC_Admin_Post_Types {
|
||||||
$screen_id = isset( $screen, $screen->id ) ? $screen->id : '';
|
$screen_id = isset( $screen, $screen->id ) ? $screen->id : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['screen'] ) ) { // WPCS: input var ok.
|
if ( ! empty( $request_data['screen'] ) ) {
|
||||||
$screen_id = wc_clean( wp_unslash( $_REQUEST['screen'] ) ); // WPCS: input var ok, sanitization ok.
|
$screen_id = wc_clean( wp_unslash( $request_data['screen'] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( $screen_id ) {
|
switch ( $screen_id ) {
|
||||||
|
@ -296,6 +298,8 @@ class WC_Admin_Post_Types {
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function bulk_and_quick_edit_save_post( $post_id, $post ) {
|
public function bulk_and_quick_edit_save_post( $post_id, $post ) {
|
||||||
|
$request_data = $this->request_data();
|
||||||
|
|
||||||
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
|
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
|
||||||
if ( Constants::is_true( 'DOING_AUTOSAVE' ) ) {
|
if ( Constants::is_true( 'DOING_AUTOSAVE' ) ) {
|
||||||
return $post_id;
|
return $post_id;
|
||||||
|
@ -307,14 +311,15 @@ class WC_Admin_Post_Types {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check nonce.
|
// Check nonce.
|
||||||
if ( ! isset( $_REQUEST['woocommerce_quick_edit_nonce'] ) || ! wp_verify_nonce( $_REQUEST['woocommerce_quick_edit_nonce'], 'woocommerce_quick_edit_nonce' ) ) { // WPCS: input var ok, sanitization ok.
|
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
|
if ( ! isset( $request_data['woocommerce_quick_edit_nonce'] ) || ! wp_verify_nonce( $request_data['woocommerce_quick_edit_nonce'], 'woocommerce_quick_edit_nonce' ) ) {
|
||||||
return $post_id;
|
return $post_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the product and save.
|
// Get the product and save.
|
||||||
$product = wc_get_product( $post );
|
$product = wc_get_product( $post );
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['woocommerce_quick_edit'] ) ) { // WPCS: input var ok.
|
if ( ! empty( $request_data['woocommerce_quick_edit'] ) ) { // WPCS: input var ok.
|
||||||
$this->quick_edit_save( $post_id, $product );
|
$this->quick_edit_save( $post_id, $product );
|
||||||
} else {
|
} else {
|
||||||
$this->bulk_edit_save( $post_id, $product );
|
$this->bulk_edit_save( $post_id, $product );
|
||||||
|
@ -330,6 +335,8 @@ class WC_Admin_Post_Types {
|
||||||
* @param WC_Product $product Product object.
|
* @param WC_Product $product Product object.
|
||||||
*/
|
*/
|
||||||
private function quick_edit_save( $post_id, $product ) {
|
private function quick_edit_save( $post_id, $product ) {
|
||||||
|
$request_data = $this->request_data();
|
||||||
|
|
||||||
$data_store = $product->get_data_store();
|
$data_store = $product->get_data_store();
|
||||||
$old_regular_price = $product->get_regular_price();
|
$old_regular_price = $product->get_regular_price();
|
||||||
$old_sale_price = $product->get_sale_price();
|
$old_sale_price = $product->get_sale_price();
|
||||||
|
@ -344,14 +351,15 @@ class WC_Admin_Post_Types {
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ( $input_to_props as $input_var => $prop ) {
|
foreach ( $input_to_props as $input_var => $prop ) {
|
||||||
if ( isset( $_REQUEST[ $input_var ] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( isset( $request_data[ $input_var ] ) ) {
|
||||||
$product->{"set_{$prop}"}( wc_clean( wp_unslash( $_REQUEST[ $input_var ] ) ) ); // WPCS: input var ok, sanitization ok.
|
$product->{"set_{$prop}"}( wc_clean( wp_unslash( $request_data[ $input_var ] ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset( $_REQUEST['_sku'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( isset( $request_data['_sku'] ) ) {
|
||||||
$sku = $product->get_sku();
|
$sku = $product->get_sku();
|
||||||
$new_sku = (string) wc_clean( $_REQUEST['_sku'] ); // WPCS: input var ok, sanitization ok.
|
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
|
$new_sku = (string) wc_clean( $request_data['_sku'] );
|
||||||
|
|
||||||
if ( $new_sku !== $sku ) {
|
if ( $new_sku !== $sku ) {
|
||||||
if ( ! empty( $new_sku ) ) {
|
if ( ! empty( $new_sku ) ) {
|
||||||
|
@ -365,27 +373,30 @@ class WC_Admin_Post_Types {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_shipping_class'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_shipping_class'] ) ) {
|
||||||
if ( '_no_shipping_class' === $_REQUEST['_shipping_class'] ) { // WPCS: input var ok, sanitization ok.
|
if ( '_no_shipping_class' === $request_data['_shipping_class'] ) {
|
||||||
$product->set_shipping_class_id( 0 );
|
$product->set_shipping_class_id( 0 );
|
||||||
} else {
|
} else {
|
||||||
$shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $_REQUEST['_shipping_class'] ) ); // WPCS: input var ok, sanitization ok.
|
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
|
$shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $request_data['_shipping_class'] ) );
|
||||||
$product->set_shipping_class_id( $shipping_class_id );
|
$product->set_shipping_class_id( $shipping_class_id );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$product->set_featured( isset( $_REQUEST['_featured'] ) ); // WPCS: input var ok, sanitization ok.
|
$product->set_featured( isset( $request_data['_featured'] ) );
|
||||||
|
|
||||||
if ( $product->is_type( 'simple' ) || $product->is_type( 'external' ) ) {
|
if ( $product->is_type( 'simple' ) || $product->is_type( 'external' ) ) {
|
||||||
|
|
||||||
if ( isset( $_REQUEST['_regular_price'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( isset( $request_data['_regular_price'] ) ) {
|
||||||
$new_regular_price = ( '' === $_REQUEST['_regular_price'] ) ? '' : wc_format_decimal( $_REQUEST['_regular_price'] ); // WPCS: input var ok, sanitization ok.
|
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
|
$new_regular_price = ( '' === $request_data['_regular_price'] ) ? '' : wc_format_decimal( $request_data['_regular_price'] );
|
||||||
$product->set_regular_price( $new_regular_price );
|
$product->set_regular_price( $new_regular_price );
|
||||||
} else {
|
} else {
|
||||||
$new_regular_price = null;
|
$new_regular_price = null;
|
||||||
}
|
}
|
||||||
if ( isset( $_REQUEST['_sale_price'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( isset( $request_data['_sale_price'] ) ) {
|
||||||
$new_sale_price = ( '' === $_REQUEST['_sale_price'] ) ? '' : wc_format_decimal( $_REQUEST['_sale_price'] ); // WPCS: input var ok, sanitization ok.
|
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
|
$new_sale_price = ( '' === $request_data['_sale_price'] ) ? '' : wc_format_decimal( $request_data['_sale_price'] );
|
||||||
$product->set_sale_price( $new_sale_price );
|
$product->set_sale_price( $new_sale_price );
|
||||||
} else {
|
} else {
|
||||||
$new_sale_price = null;
|
$new_sale_price = null;
|
||||||
|
@ -407,35 +418,25 @@ class WC_Admin_Post_Types {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Stock Data.
|
// Handle Stock Data.
|
||||||
$manage_stock = ! empty( $_REQUEST['_manage_stock'] ) && 'grouped' !== $product->get_type() ? 'yes' : 'no'; // WPCS: input var ok, sanitization ok.
|
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||||
$backorders = ! empty( $_REQUEST['_backorders'] ) ? wc_clean( $_REQUEST['_backorders'] ) : 'no'; // WPCS: input var ok, sanitization ok.
|
$manage_stock = ! empty( $request_data['_manage_stock'] ) && 'grouped' !== $product->get_type() ? 'yes' : 'no';
|
||||||
$stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : 'instock'; // WPCS: input var ok, sanitization ok.
|
$backorders = ! empty( $request_data['_backorders'] ) ? wc_clean( $request_data['_backorders'] ) : 'no';
|
||||||
$stock_amount = 'yes' === $manage_stock && isset( $_REQUEST['_stock'] ) && is_numeric( wp_unslash( $_REQUEST['_stock'] ) ) ? wc_stock_amount( wp_unslash( $_REQUEST['_stock'] ) ) : ''; // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_stock_status'] ) ) {
|
||||||
|
$stock_status = wc_clean( $request_data['_stock_status'] );
|
||||||
|
} else {
|
||||||
|
$stock_status = $product->is_type( 'variable' ) ? null : 'instock';
|
||||||
|
}
|
||||||
|
// phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||||
|
|
||||||
$product->set_manage_stock( $manage_stock );
|
$product->set_manage_stock( $manage_stock );
|
||||||
$product->set_backorders( $backorders );
|
$product->set_backorders( $backorders );
|
||||||
|
|
||||||
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
|
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
|
||||||
|
$stock_amount = 'yes' === $manage_stock && isset( $request_data['_stock'] ) && is_numeric( wp_unslash( $request_data['_stock'] ) ) ? wc_stock_amount( wp_unslash( $request_data['_stock'] ) ) : '';
|
||||||
$product->set_stock_quantity( $stock_amount );
|
$product->set_stock_quantity( $stock_amount );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply product type constraints to stock status.
|
$product = $this->maybe_update_stock_status( $product, $stock_status );
|
||||||
if ( $product->is_type( 'external' ) ) {
|
|
||||||
// External products are always in stock.
|
|
||||||
$product->set_stock_status( 'instock' );
|
|
||||||
} elseif ( $product->is_type( 'variable' ) && ! $product->get_manage_stock() ) {
|
|
||||||
// Stock status is determined by children.
|
|
||||||
foreach ( $product->get_children() as $child_id ) {
|
|
||||||
$child = wc_get_product( $child_id );
|
|
||||||
if ( ! $product->get_manage_stock() ) {
|
|
||||||
$child->set_stock_status( $stock_status );
|
|
||||||
$child->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$product = WC_Product_Variable::sync( $product, false );
|
|
||||||
} else {
|
|
||||||
$product->set_stock_status( $stock_status );
|
|
||||||
}
|
|
||||||
|
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
|
@ -449,58 +450,61 @@ class WC_Admin_Post_Types {
|
||||||
* @param WC_Product $product Product object.
|
* @param WC_Product $product Product object.
|
||||||
*/
|
*/
|
||||||
public function bulk_edit_save( $post_id, $product ) {
|
public function bulk_edit_save( $post_id, $product ) {
|
||||||
|
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
|
|
||||||
|
$request_data = $this->request_data();
|
||||||
|
|
||||||
$data_store = $product->get_data_store();
|
$data_store = $product->get_data_store();
|
||||||
$old_regular_price = $product->get_regular_price();
|
|
||||||
$old_sale_price = $product->get_sale_price();
|
|
||||||
$data = wp_unslash( $_REQUEST ); // WPCS: input var ok, CSRF ok.
|
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['change_weight'] ) && isset( $_REQUEST['_weight'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['change_weight'] ) && isset( $request_data['_weight'] ) ) {
|
||||||
$product->set_weight( wc_clean( wp_unslash( $_REQUEST['_weight'] ) ) ); // WPCS: input var ok, sanitization ok.
|
$product->set_weight( wc_clean( wp_unslash( $request_data['_weight'] ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['change_dimensions'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['change_dimensions'] ) ) {
|
||||||
if ( isset( $_REQUEST['_length'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( isset( $request_data['_length'] ) ) {
|
||||||
$product->set_length( wc_clean( wp_unslash( $_REQUEST['_length'] ) ) ); // WPCS: input var ok, sanitization ok.
|
$product->set_length( wc_clean( wp_unslash( $request_data['_length'] ) ) );
|
||||||
}
|
}
|
||||||
if ( isset( $_REQUEST['_width'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( isset( $request_data['_width'] ) ) {
|
||||||
$product->set_width( wc_clean( wp_unslash( $_REQUEST['_width'] ) ) ); // WPCS: input var ok, sanitization ok.
|
$product->set_width( wc_clean( wp_unslash( $request_data['_width'] ) ) );
|
||||||
}
|
}
|
||||||
if ( isset( $_REQUEST['_height'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( isset( $request_data['_height'] ) ) {
|
||||||
$product->set_height( wc_clean( wp_unslash( $_REQUEST['_height'] ) ) ); // WPCS: input var ok, sanitization ok.
|
$product->set_height( wc_clean( wp_unslash( $request_data['_height'] ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_tax_status'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_tax_status'] ) ) {
|
||||||
$product->set_tax_status( wc_clean( $_REQUEST['_tax_status'] ) ); // WPCS: input var ok, sanitization ok.
|
$product->set_tax_status( wc_clean( $request_data['_tax_status'] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_tax_class'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_tax_class'] ) ) {
|
||||||
$tax_class = wc_clean( wp_unslash( $_REQUEST['_tax_class'] ) ); // WPCS: input var ok, sanitization ok.
|
$tax_class = wc_clean( wp_unslash( $request_data['_tax_class'] ) );
|
||||||
if ( 'standard' === $tax_class ) {
|
if ( 'standard' === $tax_class ) {
|
||||||
$tax_class = '';
|
$tax_class = '';
|
||||||
}
|
}
|
||||||
$product->set_tax_class( $tax_class );
|
$product->set_tax_class( $tax_class );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_shipping_class'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_shipping_class'] ) ) {
|
||||||
if ( '_no_shipping_class' === $_REQUEST['_shipping_class'] ) { // WPCS: input var ok, sanitization ok.
|
if ( '_no_shipping_class' === $request_data['_shipping_class'] ) {
|
||||||
$product->set_shipping_class_id( 0 );
|
$product->set_shipping_class_id( 0 );
|
||||||
} else {
|
} else {
|
||||||
$shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $_REQUEST['_shipping_class'] ) ); // WPCS: input var ok, sanitization ok.
|
$shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $request_data['_shipping_class'] ) );
|
||||||
$product->set_shipping_class_id( $shipping_class_id );
|
$product->set_shipping_class_id( $shipping_class_id );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_visibility'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_visibility'] ) ) {
|
||||||
$product->set_catalog_visibility( wc_clean( $_REQUEST['_visibility'] ) ); // WPCS: input var ok, sanitization ok.
|
$product->set_catalog_visibility( wc_clean( $request_data['_visibility'] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_featured'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_featured'] ) ) {
|
||||||
$product->set_featured( wp_unslash( $_REQUEST['_featured'] ) ); // WPCS: input var ok, sanitization ok.
|
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||||
|
$product->set_featured( wp_unslash( $request_data['_featured'] ) );
|
||||||
|
// phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_sold_individually'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_sold_individually'] ) ) {
|
||||||
if ( 'yes' === $_REQUEST['_sold_individually'] ) { // WPCS: input var ok, sanitization ok.
|
if ( 'yes' === $request_data['_sold_individually'] ) {
|
||||||
$product->set_sold_individually( 'yes' );
|
$product->set_sold_individually( 'yes' );
|
||||||
} else {
|
} else {
|
||||||
$product->set_sold_individually( '' );
|
$product->set_sold_individually( '' );
|
||||||
|
@ -518,93 +522,10 @@ class WC_Admin_Post_Types {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $can_product_type_change_price ) {
|
if ( $can_product_type_change_price ) {
|
||||||
$price_changed = false;
|
$regular_price_changed = $this->set_new_price( $product, 'regular' );
|
||||||
|
$sale_price_changed = $this->set_new_price( $product, 'sale' );
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['change_regular_price'] ) && isset( $_REQUEST['_regular_price'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( $regular_price_changed || $sale_price_changed ) {
|
||||||
$change_regular_price = absint( $_REQUEST['change_regular_price'] ); // WPCS: input var ok, sanitization ok.
|
|
||||||
$raw_regular_price = wc_clean( wp_unslash( $_REQUEST['_regular_price'] ) ); // WPCS: input var ok, sanitization ok.
|
|
||||||
$is_percentage = (bool) strstr( $raw_regular_price, '%' );
|
|
||||||
$regular_price = wc_format_decimal( $raw_regular_price );
|
|
||||||
|
|
||||||
switch ( $change_regular_price ) {
|
|
||||||
case 1:
|
|
||||||
$new_price = $regular_price;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if ( $is_percentage ) {
|
|
||||||
$percent = $regular_price / 100;
|
|
||||||
$new_price = $old_regular_price + ( round( $old_regular_price * $percent, wc_get_price_decimals() ) );
|
|
||||||
} else {
|
|
||||||
$new_price = $old_regular_price + $regular_price;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if ( $is_percentage ) {
|
|
||||||
$percent = $regular_price / 100;
|
|
||||||
$new_price = max( 0, $old_regular_price - ( round( $old_regular_price * $percent, wc_get_price_decimals() ) ) );
|
|
||||||
} else {
|
|
||||||
$new_price = max( 0, $old_regular_price - $regular_price );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isset( $new_price ) && $new_price !== $old_regular_price ) {
|
|
||||||
$price_changed = true;
|
|
||||||
$new_price = round( $new_price, wc_get_price_decimals() );
|
|
||||||
$product->set_regular_price( $new_price );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['change_sale_price'] ) && isset( $_REQUEST['_sale_price'] ) ) { // WPCS: input var ok, sanitization ok.
|
|
||||||
$change_sale_price = absint( $_REQUEST['change_sale_price'] ); // WPCS: input var ok, sanitization ok.
|
|
||||||
$raw_sale_price = wc_clean( wp_unslash( $_REQUEST['_sale_price'] ) ); // WPCS: input var ok, sanitization ok.
|
|
||||||
$is_percentage = (bool) strstr( $raw_sale_price, '%' );
|
|
||||||
$sale_price = wc_format_decimal( $raw_sale_price );
|
|
||||||
|
|
||||||
switch ( $change_sale_price ) {
|
|
||||||
case 1:
|
|
||||||
$new_price = $sale_price;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if ( $is_percentage ) {
|
|
||||||
$percent = $sale_price / 100;
|
|
||||||
$new_price = $old_sale_price + ( $old_sale_price * $percent );
|
|
||||||
} else {
|
|
||||||
$new_price = $old_sale_price + $sale_price;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if ( $is_percentage ) {
|
|
||||||
$percent = $sale_price / 100;
|
|
||||||
$new_price = max( 0, $old_sale_price - ( $old_sale_price * $percent ) );
|
|
||||||
} else {
|
|
||||||
$new_price = max( 0, $old_sale_price - $sale_price );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if ( $is_percentage ) {
|
|
||||||
$percent = $sale_price / 100;
|
|
||||||
$new_price = max( 0, $product->regular_price - ( $product->regular_price * $percent ) );
|
|
||||||
} else {
|
|
||||||
$new_price = max( 0, $product->regular_price - $sale_price );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isset( $new_price ) && $new_price !== $old_sale_price ) {
|
|
||||||
$price_changed = true;
|
|
||||||
$new_price = ! empty( $new_price ) || '0' === $new_price ? round( $new_price, wc_get_price_decimals() ) : '';
|
|
||||||
$product->set_sale_price( $new_price );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $price_changed ) {
|
|
||||||
$product->set_date_on_sale_to( '' );
|
$product->set_date_on_sale_to( '' );
|
||||||
$product->set_date_on_sale_from( '' );
|
$product->set_date_on_sale_from( '' );
|
||||||
|
|
||||||
|
@ -616,24 +537,22 @@ class WC_Admin_Post_Types {
|
||||||
|
|
||||||
// Handle Stock Data.
|
// Handle Stock Data.
|
||||||
$was_managing_stock = $product->get_manage_stock() ? 'yes' : 'no';
|
$was_managing_stock = $product->get_manage_stock() ? 'yes' : 'no';
|
||||||
$stock_status = $product->get_stock_status();
|
|
||||||
$backorders = $product->get_backorders();
|
$backorders = $product->get_backorders();
|
||||||
$backorders = ! empty( $_REQUEST['_backorders'] ) ? wc_clean( $_REQUEST['_backorders'] ) : $backorders; // WPCS: input var ok, sanitization ok.
|
$backorders = ! empty( $request_data['_backorders'] ) ? wc_clean( $request_data['_backorders'] ) : $backorders;
|
||||||
$stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : $stock_status; // WPCS: input var ok, sanitization ok.
|
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_manage_stock'] ) ) { // WPCS: input var ok, sanitization ok.
|
if ( ! empty( $request_data['_manage_stock'] ) ) {
|
||||||
$manage_stock = 'yes' === wc_clean( $_REQUEST['_manage_stock'] ) && 'grouped' !== $product->get_type() ? 'yes' : 'no'; // WPCS: input var ok, sanitization ok.
|
$manage_stock = 'yes' === wc_clean( $request_data['_manage_stock'] ) && 'grouped' !== $product->get_type() ? 'yes' : 'no';
|
||||||
} else {
|
} else {
|
||||||
$manage_stock = $was_managing_stock;
|
$manage_stock = $was_managing_stock;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stock_amount = 'yes' === $manage_stock && ! empty( $_REQUEST['change_stock'] ) && isset( $_REQUEST['_stock'] ) ? wc_stock_amount( $_REQUEST['_stock'] ) : $product->get_stock_quantity(); // WPCS: input var ok, sanitization ok.
|
$stock_amount = 'yes' === $manage_stock && ! empty( $request_data['change_stock'] ) && isset( $request_data['_stock'] ) ? wc_stock_amount( $request_data['_stock'] ) : $product->get_stock_quantity();
|
||||||
|
|
||||||
$product->set_manage_stock( $manage_stock );
|
$product->set_manage_stock( $manage_stock );
|
||||||
$product->set_backorders( $backorders );
|
$product->set_backorders( $backorders );
|
||||||
|
|
||||||
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
|
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
|
||||||
$change_stock = absint( $_REQUEST['change_stock'] );
|
$change_stock = absint( $request_data['change_stock'] );
|
||||||
switch ( $change_stock ) {
|
switch ( $change_stock ) {
|
||||||
case 2:
|
case 2:
|
||||||
wc_update_product_stock( $product, $stock_amount, 'increase', true );
|
wc_update_product_stock( $product, $stock_amount, 'increase', true );
|
||||||
|
@ -651,27 +570,14 @@ class WC_Admin_Post_Types {
|
||||||
$product->set_manage_stock( 'no' );
|
$product->set_manage_stock( 'no' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply product type constraints to stock status.
|
$stock_status = empty( $request_data['_stock_status'] ) ? null : wc_clean( $request_data['_stock_status'] );
|
||||||
if ( $product->is_type( 'external' ) ) {
|
$product = $this->maybe_update_stock_status( $product, $stock_status );
|
||||||
// External products are always in stock.
|
|
||||||
$product->set_stock_status( 'instock' );
|
|
||||||
} elseif ( $product->is_type( 'variable' ) && ! $product->get_manage_stock() ) {
|
|
||||||
// Stock status is determined by children.
|
|
||||||
foreach ( $product->get_children() as $child_id ) {
|
|
||||||
$child = wc_get_product( $child_id );
|
|
||||||
if ( ! $product->get_manage_stock() ) {
|
|
||||||
$child->set_stock_status( $stock_status );
|
|
||||||
$child->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$product = WC_Product_Variable::sync( $product, false );
|
|
||||||
} else {
|
|
||||||
$product->set_stock_status( $stock_status );
|
|
||||||
}
|
|
||||||
|
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
do_action( 'woocommerce_product_bulk_edit_save', $product );
|
do_action( 'woocommerce_product_bulk_edit_save', $product );
|
||||||
|
|
||||||
|
// phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -719,11 +625,13 @@ class WC_Admin_Post_Types {
|
||||||
* @param WP_Post $post Current post object.
|
* @param WP_Post $post Current post object.
|
||||||
*/
|
*/
|
||||||
public function edit_form_after_title( $post ) {
|
public function edit_form_after_title( $post ) {
|
||||||
|
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
if ( 'shop_coupon' === $post->post_type ) {
|
if ( 'shop_coupon' === $post->post_type ) {
|
||||||
?>
|
?>
|
||||||
<textarea id="woocommerce-coupon-description" name="excerpt" cols="5" rows="2" placeholder="<?php esc_attr_e( 'Description (optional)', 'woocommerce' ); ?>"><?php echo $post->post_excerpt; // WPCS: XSS ok. ?></textarea>
|
<textarea id="woocommerce-coupon-description" name="excerpt" cols="5" rows="2" placeholder="<?php esc_attr_e( 'Description (optional)', 'woocommerce' ); ?>"><?php echo $post->post_excerpt; ?></textarea>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -802,7 +710,8 @@ class WC_Admin_Post_Types {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function upload_dir( $pathdata ) {
|
public function upload_dir( $pathdata ) {
|
||||||
if ( isset( $_POST['type'] ) && 'downloadable_product' === $_POST['type'] ) { // WPCS: CSRF ok, input var ok.
|
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||||
|
if ( isset( $_POST['type'] ) && 'downloadable_product' === $_POST['type'] ) {
|
||||||
|
|
||||||
if ( empty( $pathdata['subdir'] ) ) {
|
if ( empty( $pathdata['subdir'] ) ) {
|
||||||
$pathdata['path'] = $pathdata['path'] . '/woocommerce_uploads';
|
$pathdata['path'] = $pathdata['path'] . '/woocommerce_uploads';
|
||||||
|
@ -817,6 +726,7 @@ class WC_Admin_Post_Types {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $pathdata;
|
return $pathdata;
|
||||||
|
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -830,7 +740,8 @@ class WC_Admin_Post_Types {
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public function update_filename( $full_filename, $ext, $dir ) {
|
public function update_filename( $full_filename, $ext, $dir ) {
|
||||||
if ( ! isset( $_POST['type'] ) || ! 'downloadable_product' === $_POST['type'] ) { // WPCS: CSRF ok, input var ok.
|
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||||
|
if ( ! isset( $_POST['type'] ) || ! 'downloadable_product' === $_POST['type'] ) {
|
||||||
return $full_filename;
|
return $full_filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,6 +754,7 @@ class WC_Admin_Post_Types {
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->unique_filename( $full_filename, $ext );
|
return $this->unique_filename( $full_filename, $ext );
|
||||||
|
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -961,6 +873,118 @@ class WC_Admin_Post_Types {
|
||||||
|
|
||||||
return $post_states;
|
return $post_states;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply product type constraints to stock status.
|
||||||
|
*
|
||||||
|
* @param WC_Product $product The product whose stock status will be adjusted.
|
||||||
|
* @param string|null $stock_status The stock status to use for adjustment, or null if no new stock status has been supplied in the request.
|
||||||
|
* @return WC_Product The supplied product, or the synced product if it was a variable product.
|
||||||
|
*/
|
||||||
|
private function maybe_update_stock_status( $product, $stock_status ) {
|
||||||
|
if ( $product->is_type( 'external' ) ) {
|
||||||
|
// External products are always in stock.
|
||||||
|
$product->set_stock_status( 'instock' );
|
||||||
|
} elseif ( isset( $stock_status ) ) {
|
||||||
|
if ( $product->is_type( 'variable' ) && ! $product->get_manage_stock() ) {
|
||||||
|
// Stock status is determined by children.
|
||||||
|
foreach ( $product->get_children() as $child_id ) {
|
||||||
|
$child = wc_get_product( $child_id );
|
||||||
|
if ( ! $product->get_manage_stock() ) {
|
||||||
|
$child->set_stock_status( $stock_status );
|
||||||
|
$child->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$product = WC_Product_Variable::sync( $product, false );
|
||||||
|
} else {
|
||||||
|
$product->set_stock_status( $stock_status );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $product;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the new regular or sale price if requested.
|
||||||
|
*
|
||||||
|
* @param WC_Product $product The product to set the new price for.
|
||||||
|
* @param string $price_type 'regular' or 'sale'.
|
||||||
|
* @return bool true if a new price has been set, false otherwise.
|
||||||
|
*/
|
||||||
|
private function set_new_price( $product, $price_type ) {
|
||||||
|
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
|
|
||||||
|
$request_data = $this->request_data();
|
||||||
|
|
||||||
|
if ( empty( $request_data[ "change_{$price_type}_price" ] ) || ! isset( $request_data[ "_{$price_type}_price" ] ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$old_price = $product->{"get_{$price_type}_price"}();
|
||||||
|
$price_changed = false;
|
||||||
|
|
||||||
|
$change_price = absint( $request_data[ "change_{$price_type}_price" ] );
|
||||||
|
$raw_price = wc_clean( wp_unslash( $request_data[ "_{$price_type}_price" ] ) );
|
||||||
|
$is_percentage = (bool) strstr( $raw_price, '%' );
|
||||||
|
$price = wc_format_decimal( $raw_price );
|
||||||
|
|
||||||
|
switch ( $change_price ) {
|
||||||
|
case 1:
|
||||||
|
$new_price = $price;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if ( $is_percentage ) {
|
||||||
|
$percent = $price / 100;
|
||||||
|
$new_price = $old_price + ( $old_price * $percent );
|
||||||
|
} else {
|
||||||
|
$new_price = $old_price + $price;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if ( $is_percentage ) {
|
||||||
|
$percent = $price / 100;
|
||||||
|
$new_price = max( 0, $old_price - ( $old_price * $percent ) );
|
||||||
|
} else {
|
||||||
|
$new_price = max( 0, $old_price - $price );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if ( 'sale' !== $price_type ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$regular_price = $product->get_regular_price();
|
||||||
|
if ( $is_percentage ) {
|
||||||
|
$percent = $price / 100;
|
||||||
|
$new_price = max( 0, $regular_price - ( round( $regular_price * $percent, wc_get_price_decimals() ) ) );
|
||||||
|
} else {
|
||||||
|
$new_price = max( 0, $regular_price - $price );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $new_price ) && $new_price !== $old_price ) {
|
||||||
|
$price_changed = true;
|
||||||
|
$new_price = round( $new_price, wc_get_price_decimals() );
|
||||||
|
$product->{"set_{$price_type}_price"}( $new_price );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $price_changed;
|
||||||
|
|
||||||
|
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current request data ($_REQUEST superglobal).
|
||||||
|
* This method is added to ease unit testing.
|
||||||
|
*
|
||||||
|
* @return array The $_REQUEST superglobal.
|
||||||
|
*/
|
||||||
|
protected function request_data() {
|
||||||
|
return $_REQUEST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new WC_Admin_Post_Types();
|
new WC_Admin_Post_Types();
|
||||||
|
|
|
@ -140,7 +140,8 @@ defined( 'ABSPATH' ) || exit;
|
||||||
<select class="visibility" name="_visibility">
|
<select class="visibility" name="_visibility">
|
||||||
<?php
|
<?php
|
||||||
$options = apply_filters(
|
$options = apply_filters(
|
||||||
'woocommerce_product_visibility_options', array(
|
'woocommerce_product_visibility_options',
|
||||||
|
array(
|
||||||
'visible' => __( 'Catalog & search', 'woocommerce' ),
|
'visible' => __( 'Catalog & search', 'woocommerce' ),
|
||||||
'catalog' => __( 'Catalog', 'woocommerce' ),
|
'catalog' => __( 'Catalog', 'woocommerce' ),
|
||||||
'search' => __( 'Search', 'woocommerce' ),
|
'search' => __( 'Search', 'woocommerce' ),
|
||||||
|
@ -174,11 +175,15 @@ defined( 'ABSPATH' ) || exit;
|
||||||
<span class="input-text-wrap">
|
<span class="input-text-wrap">
|
||||||
<select class="stock_status" name="_stock_status">
|
<select class="stock_status" name="_stock_status">
|
||||||
<?php
|
<?php
|
||||||
|
echo '<option value="" id="stock_status_no_change">' . esc_html__( '— No Change —', 'woocommerce' ) . '</option>';
|
||||||
foreach ( wc_get_product_stock_status_options() as $key => $value ) {
|
foreach ( wc_get_product_stock_status_options() as $key => $value ) {
|
||||||
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
|
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</select>
|
</select>
|
||||||
|
<div class="wc-quick-edit-warning" style="display:none">
|
||||||
|
<?php echo esc_html__( 'This will change the stock status of all variations.', 'woocommerce' ); ?></p>
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Base class for REST API test classes.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Tests\Framework
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WC API Unit Test Case
|
* WC API Unit Test Case
|
||||||
*
|
*
|
||||||
|
@ -19,18 +25,16 @@ class WC_API_Unit_Test_Case extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
// load API classes
|
// load API classes.
|
||||||
WC()->api->includes();
|
WC()->api->includes();
|
||||||
|
|
||||||
// set user
|
// set user.
|
||||||
$this->user_id = $this->factory->user->create( array( 'role' => 'shop_manager' ) );
|
$this->user_id = $this->login_as_role( 'shop_manager' );
|
||||||
wp_set_current_user( $this->user_id );
|
|
||||||
|
|
||||||
// this isn't used, but it causes a warning unless set
|
// this isn't used, but it causes a warning unless set.
|
||||||
$_SERVER['REQUEST_METHOD'] = null;
|
$_SERVER['REQUEST_METHOD'] = null;
|
||||||
|
|
||||||
// mock the API server to prevent headers from being sent
|
// mock the API server to prevent headers from being sent.
|
||||||
// $this->mock_server = $this->getMock( 'WC_API_Server', array( 'header' ), array( '/' ) );
|
|
||||||
$this->mock_server = $this->getMockBuilder( 'WC_API_Server' )->setMethods( array( 'header' ) )->disableOriginalConstructor()->getMock();
|
$this->mock_server = $this->getMockBuilder( 'WC_API_Server' )->setMethods( array( 'header' ) )->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
WC()->api->register_resources( $this->mock_server );
|
WC()->api->register_resources( $this->mock_server );
|
||||||
|
@ -40,19 +44,19 @@ class WC_API_Unit_Test_Case extends WC_Unit_Test_Case {
|
||||||
* Assert the given response is an API error with a specific code and status.
|
* Assert the given response is an API error with a specific code and status.
|
||||||
*
|
*
|
||||||
* @since 2.2
|
* @since 2.2
|
||||||
* @param string $code error code, e.g. `woocommerce_api_user_cannot_read_orders_count`
|
* @param string $code error code, e.g. `woocommerce_api_user_cannot_read_orders_count`.
|
||||||
* @param int|null $status HTTP status code associated with error, e.g. 400
|
* @param int|null $status HTTP status code associated with error, e.g. 400.
|
||||||
* @param WP_Error $response
|
* @param WP_Error $response Response to assert.
|
||||||
* @param string $message optional message to render when assertion fails
|
* @param string $message optional message to render when assertion fails.
|
||||||
*/
|
*/
|
||||||
public function assertHasAPIError( $code, $status = null, $response, $message = '' ) {
|
public function assertHasAPIError( $code, $status = null, $response, $message = '' ) {
|
||||||
|
|
||||||
$this->assertWPError( $response, $message );
|
$this->assertWPError( $response, $message );
|
||||||
|
|
||||||
// code
|
// code.
|
||||||
$this->assertEquals( $code, $response->get_error_code(), $message );
|
$this->assertEquals( $code, $response->get_error_code(), $message );
|
||||||
|
|
||||||
// status
|
// status.
|
||||||
$data = $response->get_error_data();
|
$data = $response->get_error_data();
|
||||||
|
|
||||||
$this->assertArrayHasKey( 'status', $data, $message );
|
$this->assertArrayHasKey( 'status', $data, $message );
|
||||||
|
@ -65,14 +69,14 @@ class WC_API_Unit_Test_Case extends WC_Unit_Test_Case {
|
||||||
* permission checking.
|
* permission checking.
|
||||||
*
|
*
|
||||||
* @since 2.2
|
* @since 2.2
|
||||||
* @param string $capability, e.g. `read_private_shop_orders`
|
* @param string $capability e.g. `read_private_shop_orders`.
|
||||||
*/
|
*/
|
||||||
protected function disable_capability( $capability ) {
|
protected function disable_capability( $capability ) {
|
||||||
|
|
||||||
$user = wp_get_current_user();
|
$user = wp_get_current_user();
|
||||||
$user->add_cap( $capability, false );
|
$user->add_cap( $capability, false );
|
||||||
|
|
||||||
// flush capabilities, see https://core.trac.wordpress.org/ticket/28374
|
// flush capabilities, see https://core.trac.wordpress.org/ticket/28374.
|
||||||
$user->get_role_caps();
|
$user->get_role_caps();
|
||||||
$user->update_user_level_from_caps();
|
$user->update_user_level_from_caps();
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,6 @@ class WC_Unit_Test_Case extends WP_HTTP_TestCase {
|
||||||
throw new Exception( $message, $code );
|
throw new Exception( $message, $code );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies a file, temporarily disabling the code hacker.
|
* Copies a file, temporarily disabling the code hacker.
|
||||||
* Use this instead of "copy" in tests for compatibility with the code hacker.
|
* Use this instead of "copy" in tests for compatibility with the code hacker.
|
||||||
|
@ -149,9 +148,31 @@ class WC_Unit_Test_Case extends WP_HTTP_TestCase {
|
||||||
self::disable_code_hacker();
|
self::disable_code_hacker();
|
||||||
$result = copy( $source, $dest );
|
$result = copy( $source, $dest );
|
||||||
self::reenable_code_hacker();
|
self::reenable_code_hacker();
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new user in a given role and set it as the current user.
|
||||||
|
*
|
||||||
|
* @param string $role The role for the user to be created.
|
||||||
|
* @return int The id of the user created.
|
||||||
|
*/
|
||||||
|
public function login_as_role( $role ) {
|
||||||
|
$user_id = $this->factory->user->create( array( 'role' => $role ) );
|
||||||
|
wp_set_current_user( $user_id );
|
||||||
|
return $user_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new administrator user and set it as the current user.
|
||||||
|
*
|
||||||
|
* @return int The id of the user created.
|
||||||
|
*/
|
||||||
|
public function login_as_administrator() {
|
||||||
|
return $this->login_as_role( 'administrator' );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an instance of a class that has been registered in the dependency injection container.
|
* Get an instance of a class that has been registered in the dependency injection container.
|
||||||
* To get an instance of a legacy class (such as the ones in the 'íncludes' directory) use
|
* To get an instance of a legacy class (such as the ones in the 'íncludes' directory) use
|
||||||
|
|
|
@ -29,11 +29,12 @@ class WC_Helper_Product {
|
||||||
*
|
*
|
||||||
* @since 2.3
|
* @since 2.3
|
||||||
* @param bool $save Save or return object.
|
* @param bool $save Save or return object.
|
||||||
|
* @param array $props Properties to be set in the new product, as an associative array.
|
||||||
* @return WC_Product_Simple
|
* @return WC_Product_Simple
|
||||||
*/
|
*/
|
||||||
public static function create_simple_product( $save = true ) {
|
public static function create_simple_product( $save = true, $props = array() ) {
|
||||||
$product = new WC_Product_Simple();
|
$product = new WC_Product_Simple();
|
||||||
$product->set_props(
|
$default_props =
|
||||||
array(
|
array(
|
||||||
'name' => 'Dummy Product',
|
'name' => 'Dummy Product',
|
||||||
'regular_price' => 10,
|
'regular_price' => 10,
|
||||||
|
@ -45,9 +46,10 @@ class WC_Helper_Product {
|
||||||
'virtual' => false,
|
'virtual' => false,
|
||||||
'stock_status' => 'instock',
|
'stock_status' => 'instock',
|
||||||
'weight' => '1.1',
|
'weight' => '1.1',
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$product->set_props( array_merge( $default_props, $props ) );
|
||||||
|
|
||||||
if ( $save ) {
|
if ( $save ) {
|
||||||
$product->save();
|
$product->save();
|
||||||
return wc_get_product( $product->get_id() );
|
return wc_get_product( $product->get_id() );
|
||||||
|
|
|
@ -355,12 +355,7 @@ class WC_Tests_Paypal_Gateway_Request extends WC_Unit_Test_Case {
|
||||||
*/
|
*/
|
||||||
public function test_request_url() {
|
public function test_request_url() {
|
||||||
// User set up.
|
// User set up.
|
||||||
$this->user = $this->factory->user->create(
|
$this->login_as_administrator();
|
||||||
array(
|
|
||||||
'role' => 'administrator',
|
|
||||||
)
|
|
||||||
);
|
|
||||||
wp_set_current_user( $this->user );
|
|
||||||
|
|
||||||
// wc_tax_enabled(), wc_prices_include_tax() and WC_Gateway_Paypal_Request::prepare_line_items() determine if
|
// wc_tax_enabled(), wc_prices_include_tax() and WC_Gateway_Paypal_Request::prepare_line_items() determine if
|
||||||
// shipping tax should be included, these are the correct options.
|
// shipping tax should be included, these are the correct options.
|
||||||
|
@ -371,6 +366,7 @@ class WC_Tests_Paypal_Gateway_Request extends WC_Unit_Test_Case {
|
||||||
// woocommerce_calc_taxes, woocommerce_prices_include_tax, $shipping_tax_included values.
|
// woocommerce_calc_taxes, woocommerce_prices_include_tax, $shipping_tax_included values.
|
||||||
array( 'no', 'no', false ),
|
array( 'no', 'no', false ),
|
||||||
array( 'yes', 'no', false ),
|
array( 'yes', 'no', false ),
|
||||||
|
// phpcs:ignore Squiz.PHP.CommentedOutCode.Found
|
||||||
// array( 'no', 'yes', false ), // this is not a valid option due to definition of wc_prices_include_tax().
|
// array( 'no', 'yes', false ), // this is not a valid option due to definition of wc_prices_include_tax().
|
||||||
array( 'yes', 'yes', true ),
|
array( 'yes', 'yes', true ),
|
||||||
);
|
);
|
||||||
|
@ -399,7 +395,7 @@ class WC_Tests_Paypal_Gateway_Request extends WC_Unit_Test_Case {
|
||||||
// Many items in order -> forced to use one line item -> shipping tax included.
|
// Many items in order -> forced to use one line item -> shipping tax included.
|
||||||
$this->check_large_order( true, $testmode );
|
$this->check_large_order( true, $testmode );
|
||||||
|
|
||||||
// Test removing tags from line item name
|
// Test removing tags from line item name.
|
||||||
$this->check_product_title_containing_html( $testmode );
|
$this->check_product_title_containing_html( $testmode );
|
||||||
|
|
||||||
// Test amount < 0.
|
// Test amount < 0.
|
||||||
|
|
|
@ -1,22 +1,30 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Payment_Tokens class file.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Tests\Payment_Tokens
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Payment_Tokens
|
* Class Payment_Tokens
|
||||||
* @package WooCommerce\Tests\Payment_Tokens
|
|
||||||
*/
|
*/
|
||||||
class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the test case.
|
||||||
|
*
|
||||||
|
* @see WC_Unit_Test_Case::setUp()
|
||||||
|
*/
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$this->user_id = $this->factory->user->create( array( 'role' => 'shop_manager' ) );
|
$this->user_id = $this->login_as_role( 'shop_manager' );
|
||||||
wp_set_current_user( $this->user_id );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test getting tokens associated with an order.
|
* Test getting tokens associated with an order.
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_payment_tokens_get_order_tokens() {
|
public function test_wc_payment_tokens_get_order_tokens() {
|
||||||
$order = WC_Helper_Order::create_order();
|
$order = WC_Helper_Order::create_order();
|
||||||
$this->assertEmpty( WC_Payment_Tokens::get_order_tokens( $order->get_id() ) );
|
$this->assertEmpty( WC_Payment_Tokens::get_order_tokens( $order->get_id() ) );
|
||||||
|
|
||||||
|
@ -31,7 +39,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
* Test getting tokens associated with a user and no gateway ID.
|
* Test getting tokens associated with a user and no gateway ID.
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_payment_tokens_get_customer_tokens_no_gateway() {
|
public function test_wc_payment_tokens_get_customer_tokens_no_gateway() {
|
||||||
$this->assertEmpty( WC_Payment_Tokens::get_customer_tokens( $this->user_id ) );
|
$this->assertEmpty( WC_Payment_Tokens::get_customer_tokens( $this->user_id ) );
|
||||||
|
|
||||||
$token = WC_Helper_Payment_Token::create_cc_token();
|
$token = WC_Helper_Payment_Token::create_cc_token();
|
||||||
|
@ -49,7 +57,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
* Test getting tokens associated with a user and for a specific gateway.
|
* Test getting tokens associated with a user and for a specific gateway.
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_payment_tokens_get_customer_tokens_with_gateway() {
|
public function test_wc_payment_tokens_get_customer_tokens_with_gateway() {
|
||||||
$this->assertEmpty( WC_Payment_Tokens::get_customer_tokens( $this->user_id ) );
|
$this->assertEmpty( WC_Payment_Tokens::get_customer_tokens( $this->user_id ) );
|
||||||
|
|
||||||
$token = WC_Helper_Payment_Token::create_cc_token();
|
$token = WC_Helper_Payment_Token::create_cc_token();
|
||||||
|
@ -74,7 +82,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
* Test getting a customers default token.
|
* Test getting a customers default token.
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_get_customer_default_token() {
|
public function test_wc_get_customer_default_token() {
|
||||||
$token = WC_Helper_Payment_Token::create_cc_token();
|
$token = WC_Helper_Payment_Token::create_cc_token();
|
||||||
$token->set_user_id( $this->user_id );
|
$token->set_user_id( $this->user_id );
|
||||||
$token->set_gateway_id( 'bacs' );
|
$token->set_gateway_id( 'bacs' );
|
||||||
|
@ -99,7 +107,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
* @group failing
|
* @group failing
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_get_customer_default_token_returns_first_created_when_no_default_token_set() {
|
public function test_wc_get_customer_default_token_returns_first_created_when_no_default_token_set() {
|
||||||
$token = WC_Helper_Payment_Token::create_cc_token( $this->user_id );
|
$token = WC_Helper_Payment_Token::create_cc_token( $this->user_id );
|
||||||
$token->set_gateway_id( 'bacs' );
|
$token->set_gateway_id( 'bacs' );
|
||||||
$token->save();
|
$token->save();
|
||||||
|
@ -118,7 +126,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
* Test getting a token by ID.
|
* Test getting a token by ID.
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_payment_tokens_get() {
|
public function test_wc_payment_tokens_get() {
|
||||||
$token = WC_Helper_Payment_Token::create_cc_token();
|
$token = WC_Helper_Payment_Token::create_cc_token();
|
||||||
$token_id = $token->get_id();
|
$token_id = $token->get_id();
|
||||||
$get_token = WC_Payment_Tokens::get( $token_id );
|
$get_token = WC_Payment_Tokens::get( $token_id );
|
||||||
|
@ -129,7 +137,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
* Test deleting a token by ID.
|
* Test deleting a token by ID.
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_payment_tokens_delete() {
|
public function test_wc_payment_tokens_delete() {
|
||||||
$token = WC_Helper_Payment_Token::create_cc_token();
|
$token = WC_Helper_Payment_Token::create_cc_token();
|
||||||
$token_id = $token->get_id();
|
$token_id = $token->get_id();
|
||||||
|
|
||||||
|
@ -143,7 +151,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
* Test getting a token's type by ID.
|
* Test getting a token's type by ID.
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_payment_tokens_get_type_by_id() {
|
public function test_wc_payment_tokens_get_type_by_id() {
|
||||||
$token = WC_Helper_Payment_Token::create_cc_token();
|
$token = WC_Helper_Payment_Token::create_cc_token();
|
||||||
$token_id = $token->get_id();
|
$token_id = $token->get_id();
|
||||||
$this->assertEquals( 'CC', WC_Payment_Tokens::get_token_type_by_id( $token_id ) );
|
$this->assertEquals( 'CC', WC_Payment_Tokens::get_token_type_by_id( $token_id ) );
|
||||||
|
@ -153,7 +161,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
* Test setting a users default token.
|
* Test setting a users default token.
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
function test_wc_payment_tokens_set_users_default() {
|
public function test_wc_payment_tokens_set_users_default() {
|
||||||
$token = WC_Helper_Payment_Token::create_cc_token( $this->user_id );
|
$token = WC_Helper_Payment_Token::create_cc_token( $this->user_id );
|
||||||
$token_id = $token->get_id();
|
$token_id = $token->get_id();
|
||||||
$token->save();
|
$token->save();
|
||||||
|
@ -162,7 +170,7 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
|
||||||
$token_id_2 = $token2->get_id();
|
$token_id_2 = $token2->get_id();
|
||||||
$token2->save();
|
$token2->save();
|
||||||
|
|
||||||
$this->assertTrue( $token->is_default() ); // first created is default
|
$this->assertTrue( $token->is_default() ); // first created is default.
|
||||||
$this->assertFalse( $token2->is_default() );
|
$this->assertFalse( $token2->is_default() );
|
||||||
|
|
||||||
WC_Payment_Tokens::set_users_default( $this->user_id, $token_id_2 );
|
WC_Payment_Tokens::set_users_default( $this->user_id, $token_id_2 );
|
||||||
|
|
|
@ -19,8 +19,7 @@ class WC_Tests_Setup_Functions extends WC_Unit_Test_Case {
|
||||||
$setup_wizard = new WC_Admin_Setup_Wizard();
|
$setup_wizard = new WC_Admin_Setup_Wizard();
|
||||||
|
|
||||||
// non-admin user.
|
// non-admin user.
|
||||||
$this->user_id = $this->factory->user->create( array( 'role' => 'shop_manager' ) );
|
$this->user_id = $this->login_as_role( 'shop_manager' );
|
||||||
wp_set_current_user( $this->user_id );
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
array(
|
||||||
'paypal' => false,
|
'paypal' => false,
|
||||||
|
@ -29,8 +28,7 @@ class WC_Tests_Setup_Functions extends WC_Unit_Test_Case {
|
||||||
);
|
);
|
||||||
|
|
||||||
// set admin user.
|
// set admin user.
|
||||||
$this->user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
|
$this->user_id = $this->login_as_administrator();
|
||||||
wp_set_current_user( $this->user_id );
|
|
||||||
|
|
||||||
update_option( 'woocommerce_default_country', 'US' );
|
update_option( 'woocommerce_default_country', 'US' );
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Unit tests for the post types admin class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Tests\Admin
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WC_Admin_Post_Types tests.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\Tests\Admin
|
||||||
|
*/
|
||||||
|
class WC_Tests_Admin_Post_Types extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new SUT (System Under Test) instance and configure the specified fake request data.
|
||||||
|
*
|
||||||
|
* @param array $request_data Fake request data to configure.
|
||||||
|
* @return WC_Admin_Post_Types
|
||||||
|
*/
|
||||||
|
private function get_sut_with_request_data( $request_data ) {
|
||||||
|
$sut = $this
|
||||||
|
->getMockBuilder( WC_Admin_Post_Types::class )
|
||||||
|
->setMethods( array( 'request_data' ) )
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$sut->method( 'request_data' )->willReturn( $request_data );
|
||||||
|
|
||||||
|
return $sut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data for bulk_and_quick_edit_stock_status_for_variable_product test.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function data_provider_bulk_and_quick_edit_stock_status_for_variable_product() {
|
||||||
|
return array(
|
||||||
|
// phpcs:ignore Squiz.PHP.CommentedOutCode.Found
|
||||||
|
// $edit_type, $change_stock_request_value, $expected_new_stock_status
|
||||||
|
array( 'quick_edit', '', 'outofstock' ),
|
||||||
|
array( 'quick_edit', 'instock', 'instock' ),
|
||||||
|
array( 'bulk_edit', '', 'outofstock' ),
|
||||||
|
array( 'bulk_edit', 'instock', 'instock' ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @testdox When quick or bulk editing a variable product, stock status for the variations should change only if a new stock status is supplied.
|
||||||
|
* @dataProvider data_provider_bulk_and_quick_edit_stock_status_for_variable_product
|
||||||
|
*
|
||||||
|
* @param string $edit_type 'quick_edit' or 'bulk_edit'.
|
||||||
|
* @param string $change_stock_request_value The value of '_stock_status' from the request.
|
||||||
|
* @param string $expected_new_stock_status Expected value of the stock status for the variations after the save operation.
|
||||||
|
*/
|
||||||
|
public function bulk_and_quick_edit_stock_status_for_variable_product( $edit_type, $change_stock_request_value, $expected_new_stock_status ) {
|
||||||
|
$product = WC_Helper_Product::create_variation_product();
|
||||||
|
|
||||||
|
foreach ( $product->get_children() as $child_id ) {
|
||||||
|
$child = wc_get_product( $child_id );
|
||||||
|
$product->set_manage_stock( false );
|
||||||
|
$child->set_stock_status( 'outofstock' );
|
||||||
|
$child->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->login_as_administrator();
|
||||||
|
|
||||||
|
$request_data = array(
|
||||||
|
"woocommerce_{$edit_type}" => '1',
|
||||||
|
'_stock_status' => $change_stock_request_value,
|
||||||
|
'woocommerce_quick_edit_nonce' => wp_create_nonce( 'woocommerce_quick_edit_nonce' ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$sut = $this->get_sut_with_request_data( $request_data );
|
||||||
|
|
||||||
|
$sut->bulk_and_quick_edit_save_post( $product->get_id(), get_post( $product->get_id() ) );
|
||||||
|
|
||||||
|
foreach ( $product->get_children() as $child_id ) {
|
||||||
|
$child = wc_get_product( $child_id );
|
||||||
|
$this->assertEquals( $expected_new_stock_status, $child->get_stock_status() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data for bulk_change_price test.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function data_provider_bulk_change_price() {
|
||||||
|
$dataset = array();
|
||||||
|
|
||||||
|
// phpcs:ignore Squiz.PHP.CommentedOutCode.Found
|
||||||
|
// $type_of_price, $initial_price, $type_of_change, $change_amount, $expected_new_price
|
||||||
|
foreach ( array( 'regular', 'sale' ) as $type ) {
|
||||||
|
array_push( $dataset, array( $type, '10.33', '1', '5.339', 5.34 ) );
|
||||||
|
array_push( $dataset, array( $type, '10.33', '2', '5.3333', 15.66 ) );
|
||||||
|
array_push( $dataset, array( $type, '10.33', '2', '15.555%', 11.94 ) );
|
||||||
|
array_push( $dataset, array( $type, '10.33', '3', '5.339', 4.99 ) );
|
||||||
|
array_push( $dataset, array( $type, '10.33', '3', '15.555%', 8.72 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push( $dataset, array( 'regular', '10.33', '4', '5.339', 10.33 ) );
|
||||||
|
array_push( $dataset, array( 'regular', '10.33', '4', '15.555%', 10.33 ) );
|
||||||
|
|
||||||
|
array_push( $dataset, array( 'sale', '10.33', '4', '5.339', 97.96 ) );
|
||||||
|
array_push( $dataset, array( 'sale', '10.33', '4', '15.555%', 87.23 ) );
|
||||||
|
|
||||||
|
return $dataset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @testdox Prices should change appropriately when a price change is requested via bulk edit.
|
||||||
|
* @dataProvider data_provider_bulk_change_price
|
||||||
|
*
|
||||||
|
* @param string $type_of_price 'regular' or 'sale'.
|
||||||
|
* @param string $initial_price Initial value for the price.
|
||||||
|
* @param string $type_of_change 1=absolute, 2=increase, 3=decrease, 4=regular minus (for sale price only).
|
||||||
|
* @param string $change_amount The amount to change, ending with '%' if it's a percent.
|
||||||
|
* @param string $expected_new_price Expected value of the product price after the save operation.
|
||||||
|
*/
|
||||||
|
public function bulk_change_price( $type_of_price, $initial_price, $type_of_change, $change_amount, $expected_new_price ) {
|
||||||
|
if ( 'regular' === $type_of_price ) {
|
||||||
|
$props = array( 'regular_price' => $initial_price );
|
||||||
|
} else {
|
||||||
|
$props = array(
|
||||||
|
'regular_price' => $initial_price * 10,
|
||||||
|
'sale_price' => $initial_price,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$product = WC_Helper_Product::create_simple_product( true, $props );
|
||||||
|
|
||||||
|
$this->login_as_administrator();
|
||||||
|
|
||||||
|
$request_data = array(
|
||||||
|
'woocommerce_bulk_edit' => '1',
|
||||||
|
'woocommerce_quick_edit_nonce' => wp_create_nonce( 'woocommerce_quick_edit_nonce' ),
|
||||||
|
"change_{$type_of_price}_price" => $type_of_change,
|
||||||
|
"_{$type_of_price}_price" => $change_amount,
|
||||||
|
);
|
||||||
|
|
||||||
|
$sut = $this->get_sut_with_request_data( $request_data );
|
||||||
|
|
||||||
|
$sut->bulk_and_quick_edit_save_post( $product->get_id(), get_post( $product->get_id() ) );
|
||||||
|
|
||||||
|
$product = wc_get_product( $product->get_id() );
|
||||||
|
$actual = $product->{"get_{$type_of_price}_price"}();
|
||||||
|
$this->assertEquals( $expected_new_price, $actual );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue