Merge branch 'master' into e2e-shopper-browse-search-sort
This commit is contained in:
commit
c09a151392
|
@ -191,6 +191,30 @@ class WC_Admin_Exporters {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the product types that can be exported.
|
||||
*
|
||||
* @since 5.1.0
|
||||
* @return array The product types keys and labels.
|
||||
*/
|
||||
public static function get_product_types() {
|
||||
$product_types = wc_get_product_types();
|
||||
$product_types['variation'] = __( 'Product variations', 'woocommerce' );
|
||||
|
||||
/**
|
||||
* Allow third-parties to filter the exportable product types.
|
||||
*
|
||||
* @since 5.1.0
|
||||
* @param array $product_types {
|
||||
* The product type key and label.
|
||||
*
|
||||
* @type string Product type key - eg 'variable', 'simple' etc.
|
||||
* @type string A translated product label which appears in the export product type dropdown.
|
||||
* }
|
||||
*/
|
||||
return apply_filters( 'woocommerce_exporter_product_types', $product_types );
|
||||
}
|
||||
}
|
||||
|
||||
new WC_Admin_Exporters();
|
||||
|
|
|
@ -49,11 +49,10 @@ $exporter = new WC_Product_CSV_Exporter();
|
|||
<td>
|
||||
<select id="woocommerce-exporter-types" class="woocommerce-exporter-types wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all products', 'woocommerce' ); ?>">
|
||||
<?php
|
||||
foreach ( wc_get_product_types() as $value => $label ) {
|
||||
foreach ( WC_Admin_Exporters::get_product_types() as $value => $label ) {
|
||||
echo '<option value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
|
||||
}
|
||||
?>
|
||||
<option value="variation"><?php esc_html_e( 'Product variations', 'woocommerce' ); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -1018,3 +1018,19 @@ if ( 0 < count( $dropins_mu_plugins['mu_plugins'] ) ) :
|
|||
</table>
|
||||
|
||||
<?php do_action( 'woocommerce_system_status_report' ); ?>
|
||||
|
||||
<table class="wc_status_table widefat" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="3" data-export-label="Status report information"><h2><?php esc_html_e( 'Status report information', 'woocommerce' ); ?><?php echo wc_help_tip( esc_html__( 'This section shows information about this status report.', 'woocommerce' ) ); ?></h2></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td data-export-label="Generated at"><?php esc_html_e( 'Generated at', 'woocommerce' ); ?>:</td>
|
||||
<td class="help"> </td>
|
||||
<td><?php echo esc_html( current_time( 'Y-m-d H:i:s P' ) ); ?></td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -688,23 +688,25 @@ class WC_Checkout {
|
|||
foreach ( $fieldset as $key => $field ) {
|
||||
$type = sanitize_title( isset( $field['type'] ) ? $field['type'] : 'text' );
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
switch ( $type ) {
|
||||
case 'checkbox':
|
||||
$value = isset( $_POST[ $key ] ) ? 1 : ''; // WPCS: input var ok, CSRF ok.
|
||||
$value = isset( $_POST[ $key ] ) ? 1 : '';
|
||||
break;
|
||||
case 'multiselect':
|
||||
$value = isset( $_POST[ $key ] ) ? implode( ', ', wc_clean( wp_unslash( $_POST[ $key ] ) ) ) : ''; // WPCS: input var ok, CSRF ok.
|
||||
$value = isset( $_POST[ $key ] ) ? implode( ', ', wc_clean( wp_unslash( $_POST[ $key ] ) ) ) : '';
|
||||
break;
|
||||
case 'textarea':
|
||||
$value = isset( $_POST[ $key ] ) ? wc_sanitize_textarea( wp_unslash( $_POST[ $key ] ) ) : ''; // WPCS: input var ok, CSRF ok.
|
||||
$value = isset( $_POST[ $key ] ) ? wc_sanitize_textarea( wp_unslash( $_POST[ $key ] ) ) : '';
|
||||
break;
|
||||
case 'password':
|
||||
$value = isset( $_POST[ $key ] ) ? wp_unslash( $_POST[ $key ] ) : ''; // WPCS: input var ok, CSRF ok, sanitization ok.
|
||||
$value = isset( $_POST[ $key ] ) ? wp_unslash( $_POST[ $key ] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
break;
|
||||
default:
|
||||
$value = isset( $_POST[ $key ] ) ? wc_clean( wp_unslash( $_POST[ $key ] ) ) : ''; // WPCS: input var ok, CSRF ok.
|
||||
$value = isset( $_POST[ $key ] ) ? wc_clean( wp_unslash( $_POST[ $key ] ) ) : '';
|
||||
break;
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
|
||||
$data[ $key ] = apply_filters( 'woocommerce_process_checkout_' . $type . '_field', apply_filters( 'woocommerce_process_checkout_field_' . $key, $value ) );
|
||||
}
|
||||
|
@ -744,6 +746,13 @@ class WC_Checkout {
|
|||
$format = array_filter( isset( $field['validate'] ) ? (array) $field['validate'] : array() );
|
||||
$field_label = isset( $field['label'] ) ? $field['label'] : '';
|
||||
|
||||
if ( $validate_fieldset &&
|
||||
'country' === $field['type'] &&
|
||||
! WC()->countries->country_exists( $data[ $key ] ) ) {
|
||||
/* translators: ISO 3166-1 alpha-2 country code */
|
||||
$errors->add( $key . '_validation', sprintf( __( "'%s' is not a valid country code.", 'woocommerce' ), $data[ $key ] ) );
|
||||
}
|
||||
|
||||
switch ( $fieldset_key ) {
|
||||
case 'shipping':
|
||||
/* translators: %s: field name */
|
||||
|
@ -830,18 +839,21 @@ class WC_Checkout {
|
|||
$this->validate_posted_data( $data, $errors );
|
||||
$this->check_cart_items();
|
||||
|
||||
if ( empty( $data['woocommerce_checkout_update_totals'] ) && empty( $data['terms'] ) && ! empty( $_POST['terms-field'] ) ) { // WPCS: input var ok, CSRF ok.
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
if ( empty( $data['woocommerce_checkout_update_totals'] ) && empty( $data['terms'] ) && ! empty( $_POST['terms-field'] ) ) {
|
||||
$errors->add( 'terms', __( 'Please read and accept the terms and conditions to proceed with your order.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( WC()->cart->needs_shipping() ) {
|
||||
$shipping_country = WC()->customer->get_shipping_country();
|
||||
$shipping_country = isset( $data['shipping_country'] ) ? $data['shipping_country'] : WC()->customer->get_shipping_country();
|
||||
|
||||
if ( empty( $shipping_country ) ) {
|
||||
$errors->add( 'shipping', __( 'Please enter an address to continue.', 'woocommerce' ) );
|
||||
} elseif ( ! in_array( WC()->customer->get_shipping_country(), array_keys( WC()->countries->get_shipping_countries() ), 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() ) );
|
||||
} elseif ( ! in_array( $shipping_country, array_keys( WC()->countries->get_shipping_countries() ), true ) ) {
|
||||
if ( WC()->countries->country_exists( $shipping_country ) ) {
|
||||
/* translators: %s: shipping location (prefix e.g. 'to' + ISO 3166-1 alpha-2 country code) */
|
||||
$errors->add( 'shipping', sprintf( __( 'Unfortunately <strong>we do not ship %s</strong>. Please enter an alternative shipping address.', 'woocommerce' ), WC()->countries->shipping_to_prefix() . ' ' . $shipping_country ) );
|
||||
}
|
||||
} else {
|
||||
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
||||
|
||||
|
@ -963,7 +975,7 @@ class WC_Checkout {
|
|||
$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id );
|
||||
|
||||
if ( ! is_ajax() ) {
|
||||
wp_redirect( $result['redirect'] );
|
||||
wp_safe_redirect( $result['redirect'] );
|
||||
exit;
|
||||
}
|
||||
|
||||
|
@ -1203,8 +1215,8 @@ class WC_Checkout {
|
|||
*/
|
||||
public function get_value( $input ) {
|
||||
// If the form was posted, get the posted value. This will only tend to happen when JavaScript is disabled client side.
|
||||
if ( ! empty( $_POST[ $input ] ) ) { // WPCS: input var ok, CSRF OK.
|
||||
return wc_clean( wp_unslash( $_POST[ $input ] ) ); // WPCS: input var ok, CSRF OK.
|
||||
if ( ! empty( $_POST[ $input ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
return wc_clean( wp_unslash( $_POST[ $input ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
}
|
||||
|
||||
// Allow 3rd parties to short circuit the logic and return their own default value.
|
||||
|
|
|
@ -57,6 +57,17 @@ class WC_Countries {
|
|||
return $this->countries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given code represents a valid ISO 3166-1 alpha-2 code for a country known to us.
|
||||
*
|
||||
* @since 5.1.0
|
||||
* @param string $country_code The country code to check as a ISO 3166-1 alpha-2 code.
|
||||
* @return bool True if the country is known to us, false otherwise.
|
||||
*/
|
||||
public function country_exists( $country_code ) {
|
||||
return isset( $this->get_countries()[ $country_code ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all continents.
|
||||
*
|
||||
|
@ -919,7 +930,7 @@ class WC_Countries {
|
|||
),
|
||||
'state' => array(
|
||||
'required' => false,
|
||||
'hidden' => true,
|
||||
'hidden' => true,
|
||||
),
|
||||
),
|
||||
'DK' => array(
|
||||
|
@ -928,7 +939,7 @@ class WC_Countries {
|
|||
),
|
||||
'state' => array(
|
||||
'required' => false,
|
||||
'hidden' => true,
|
||||
'hidden' => true,
|
||||
),
|
||||
),
|
||||
'EE' => array(
|
||||
|
@ -999,7 +1010,7 @@ class WC_Countries {
|
|||
),
|
||||
),
|
||||
'HU' => array(
|
||||
'last_name' => array(
|
||||
'last_name' => array(
|
||||
'class' => array( 'form-row-first' ),
|
||||
'priority' => 10,
|
||||
),
|
||||
|
@ -1007,20 +1018,20 @@ class WC_Countries {
|
|||
'class' => array( 'form-row-last' ),
|
||||
'priority' => 20,
|
||||
),
|
||||
'postcode' => array(
|
||||
'postcode' => array(
|
||||
'class' => array( 'form-row-first', 'address-field' ),
|
||||
'priority' => 65,
|
||||
),
|
||||
'city' => array(
|
||||
'city' => array(
|
||||
'class' => array( 'form-row-last', 'address-field' ),
|
||||
),
|
||||
'address_1' => array(
|
||||
'address_1' => array(
|
||||
'priority' => 71,
|
||||
),
|
||||
'address_2' => array(
|
||||
'address_2' => array(
|
||||
'priority' => 72,
|
||||
),
|
||||
'state' => array(
|
||||
'state' => array(
|
||||
'label' => __( 'County', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
|
@ -1242,7 +1253,7 @@ class WC_Countries {
|
|||
'required' => true,
|
||||
),
|
||||
'state' => array(
|
||||
'label' => __( 'District', 'woocommerce' ),
|
||||
'label' => __( 'District', 'woocommerce' ),
|
||||
'required' => false,
|
||||
),
|
||||
),
|
||||
|
@ -1314,7 +1325,7 @@ class WC_Countries {
|
|||
),
|
||||
'state' => array(
|
||||
'required' => false,
|
||||
'hidden' => true,
|
||||
'hidden' => true,
|
||||
),
|
||||
),
|
||||
'TR' => array(
|
||||
|
|
|
@ -55,7 +55,7 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
|
|||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->set_product_types_to_export( array_merge( array_keys( wc_get_product_types() ), array( 'variation' ) ) );
|
||||
$this->set_product_types_to_export( array_keys( WC_Admin_Exporters::get_product_types() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -174,10 +174,8 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
|
|||
|
||||
// Type is the most important part here because we need to be using the correct class and methods.
|
||||
if ( isset( $data['type'] ) ) {
|
||||
$types = array_keys( wc_get_product_types() );
|
||||
$types[] = 'variation';
|
||||
|
||||
if ( ! in_array( $data['type'], $types, true ) ) {
|
||||
if ( ! array_key_exists( $data['type'], WC_Admin_Exporters::get_product_types() ) ) {
|
||||
return new WP_Error( 'woocommerce_product_importer_invalid_type', __( 'Invalid product type.', 'woocommerce' ), array( 'status' => 401 ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ class WC_Tracks {
|
|||
'blog_lang' => get_user_locale( $user_id ),
|
||||
'blog_id' => class_exists( 'Jetpack_Options' ) ? Jetpack_Options::get_option( 'id' ) : null,
|
||||
'products_count' => self::get_products_count(),
|
||||
'wc_version' => WC()->version,
|
||||
);
|
||||
set_transient( 'wc_tracks_blog_details', $blog_details, DAY_IN_SECONDS );
|
||||
}
|
||||
|
|
|
@ -8,5 +8,5 @@
|
|||
*/
|
||||
|
||||
return array(
|
||||
// 'get_option'
|
||||
'wc_get_shipping_method_count',
|
||||
);
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
/**
|
||||
* Unit tests for the WC_Cart_Test class.
|
||||
*
|
||||
* @package WooCommerce\Tests\Checkout.
|
||||
*/
|
||||
|
||||
use Automattic\WooCommerce\Testing\Tools\CodeHacking\Hacks\FunctionsMockerHack;
|
||||
|
||||
/**
|
||||
* Class WC_Checkout
|
||||
*/
|
||||
class WC_Checkout_Test extends \WC_Unit_Test_Case {
|
||||
|
||||
/**
|
||||
* @var object The system under test.
|
||||
*/
|
||||
private $sut;
|
||||
|
||||
/**
|
||||
* Runs before each test.
|
||||
*/
|
||||
public function setUp() {
|
||||
// phpcs:disable Generic.CodeAnalysis, Squiz.Commenting
|
||||
$this->sut = new class() extends WC_Checkout {
|
||||
public function validate_posted_data( &$data, &$errors ) {
|
||||
return parent::validate_posted_data( $data, $errors );
|
||||
}
|
||||
|
||||
public function validate_checkout( &$data, &$errors ) {
|
||||
return parent::validate_checkout( $data, $errors );
|
||||
}
|
||||
};
|
||||
// phpcs:enable Generic.CodeAnalysis, Squiz.Commenting
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox 'validate_posted_data' adds errors for non-existing billing/shipping countries.
|
||||
*
|
||||
* @testWith [true, true]
|
||||
* [false, false]
|
||||
*
|
||||
* @param bool $ship_to_different_address True to simulate shipping to a different address than the billing address.
|
||||
* @param bool $expect_error_message_for_shipping_country True to expect an error to be generated for the shipping country.
|
||||
*/
|
||||
public function test_validate_posted_data_adds_error_for_non_existing_country( $ship_to_different_address, $expect_error_message_for_shipping_country ) {
|
||||
$_POST = array(
|
||||
'billing_country' => 'XX',
|
||||
'shipping_country' => 'YY',
|
||||
'ship_to_different_address' => $ship_to_different_address,
|
||||
);
|
||||
$data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
|
||||
add_filter(
|
||||
'woocommerce_cart_needs_shipping_address',
|
||||
function() {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
$errors = new WP_Error();
|
||||
|
||||
$this->sut->validate_posted_data( $data, $errors );
|
||||
|
||||
$this->assertEquals( "'XX' is not a valid country code.", $errors->get_error_message( 'billing_country_validation' ) );
|
||||
$this->assertEquals(
|
||||
$expect_error_message_for_shipping_country ? "'YY' is not a valid country code." : '',
|
||||
$errors->get_error_message( 'shipping_country_validation' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox 'validate_posted_data' doesn't add errors for existing billing/shipping countries.
|
||||
*
|
||||
* @testWith [true]
|
||||
* [false]
|
||||
*
|
||||
* @param bool $ship_to_different_address True to simulate shipping to a different address than the billing address.
|
||||
*/
|
||||
public function test_validate_posted_data_does_not_add_error_for_existing_country( $ship_to_different_address ) {
|
||||
$_POST = array(
|
||||
'billing_country' => 'ES',
|
||||
'shipping_country' => 'ES',
|
||||
'ship_to_different_address' => $ship_to_different_address,
|
||||
);
|
||||
$data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
|
||||
$errors = new WP_Error();
|
||||
|
||||
$this->sut->validate_posted_data( $data, $errors );
|
||||
|
||||
$this->assertEmpty( $errors->get_error_message( 'billing_country_validation' ) );
|
||||
$this->assertEmpty( $errors->get_error_message( 'shipping_country_validation' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox 'validate_checkout' adds a "We don't ship to country X" error but only if the country exists.
|
||||
*
|
||||
* @testWith [ "XX", false ]
|
||||
* [ "JP", true ]
|
||||
*
|
||||
* @param string $country The billing/shipping country.
|
||||
* @param bool $expect_we_dont_ship_error True to expect a "We don't ship to X" error.
|
||||
*/
|
||||
public function test_validate_checkout_adds_we_dont_ship_error_only_if_country_exists( $country, $expect_we_dont_ship_error ) {
|
||||
add_filter(
|
||||
'woocommerce_countries_allowed_countries',
|
||||
function() {
|
||||
return array( 'ES' );
|
||||
}
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'woocommerce_cart_needs_shipping',
|
||||
function() {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'wc_shipping_enabled',
|
||||
function() {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
FunctionsMockerHack::add_function_mocks(
|
||||
array(
|
||||
'wc_get_shipping_method_count' => function( $include_legacy = false, $enabled_only = false ) {
|
||||
return 1;
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
$_POST = array(
|
||||
'billing_country' => $country,
|
||||
'shipping_country' => $country,
|
||||
'ship_to_different_address' => false,
|
||||
);
|
||||
$data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
|
||||
$errors = new WP_Error();
|
||||
|
||||
$this->sut->validate_checkout( $data, $errors );
|
||||
|
||||
$this->assertEquals(
|
||||
$expect_we_dont_ship_error ? 'Unfortunately <strong>we do not ship to the JP</strong>. Please enter an alternative shipping address.' : '',
|
||||
$errors->get_error_message( 'shipping' )
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue