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; + } }