diff --git a/plugins/woocommerce/changelog/fix-50245-fatal-error-checkout-customer b/plugins/woocommerce/changelog/fix-50245-fatal-error-checkout-customer
new file mode 100644
index 00000000000..4c7ba4fcea1
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-50245-fatal-error-checkout-customer
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Prevent an error in the WC_Checkout class when WooCommerce has not been properly initialized yet
diff --git a/plugins/woocommerce/includes/class-wc-checkout.php b/plugins/woocommerce/includes/class-wc-checkout.php
index 943746642e8..3c920e598a4 100644
--- a/plugins/woocommerce/includes/class-wc-checkout.php
+++ b/plugins/woocommerce/includes/class-wc-checkout.php
@@ -1357,7 +1357,7 @@ class WC_Checkout {
if ( is_callable( array( $customer_object, "get_$input" ) ) ) {
$value = $customer_object->{"get_$input"}();
- } elseif ( $customer_object->meta_exists( $input ) ) {
+ } elseif ( is_callable( array( $customer_object, 'meta_exists' ) ) && $customer_object->meta_exists( $input ) ) {
$value = $customer_object->get_meta( $input, true );
}
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-checkout-test.php b/plugins/woocommerce/tests/php/includes/class-wc-checkout-test.php
index ef7a26d47c7..2c8b7406ad9 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-checkout-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-checkout-test.php
@@ -46,12 +46,11 @@ class WC_Checkout_Test extends \WC_Unit_Test_Case {
* @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(
+ $data = 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',
@@ -75,12 +74,11 @@ class WC_Checkout_Test extends \WC_Unit_Test_Case {
* @testdox the customer notes are correctly sanitized.
*/
public function test_order_notes() {
- $_POST = array(
+ $data = array(
'ship_to_different_address' => false,
'order_comments' => 'This text should not save inside an anchor.',
'payment_method' => 'bacs',
);
- $data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$errors = new WP_Error();
@@ -108,12 +106,11 @@ class WC_Checkout_Test extends \WC_Unit_Test_Case {
* @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(
+ $data = 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();
@@ -132,12 +129,11 @@ class WC_Checkout_Test extends \WC_Unit_Test_Case {
* @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_empty_country( $ship_to_different_address ) {
- $_POST = array(
+ $data = array(
'billing_country' => '',
'shipping_country' => '',
'ship_to_different_address' => $ship_to_different_address,
);
- $data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$errors = new WP_Error();
@@ -186,12 +182,11 @@ class WC_Checkout_Test extends \WC_Unit_Test_Case {
)
);
- $_POST = array(
+ $data = array(
'billing_country' => $country,
'shipping_country' => $country,
'ship_to_different_address' => false,
);
- $data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$errors = new WP_Error();
@@ -202,5 +197,20 @@ class WC_Checkout_Test extends \WC_Unit_Test_Case {
$errors->get_error_message( 'shipping' )
);
}
+
+ /**
+ * @testdox If the WooCommerce class's customer object is null (like if WC has not been fully initialized yet),
+ * calling WC_Checkout::get_value should not throw an error.
+ */
+ public function test_get_value_no_error_on_null_customer() {
+ $sut = WC_Checkout::instance();
+
+ $orig_customer = WC()->customer;
+ WC()->customer = null;
+
+ $this->assertNull( $sut->get_value( 'billing_country' ) );
+
+ WC()->customer = $orig_customer;
+ }
}