@@ -22,6 +22,13 @@ class Checkout_Mutation {
2222 */
2323 private static $ fields ;
2424
25+ /**
26+ * Caches customer object. @see get_value.
27+ *
28+ * @var WC_Customer
29+ */
30+ private $ logged_in_customer = null ;
31+
2532 /**
2633 * Is registration required to checkout?
2734 *
@@ -63,12 +70,11 @@ protected static function maybe_skip_fieldset( $fieldset_key, $data ) {
6370 */
6471 public static function prepare_checkout_args ( $ input , $ context , $ info ) {
6572 $ data = array (
66- 'terms ' => (int ) isset ( $ input ['terms ' ] ),
67- 'createaccount ' => (int ) ! empty ( $ input ['account ' ] ),
68- 'payment_method ' => isset ( $ input ['paymentMethod ' ] ) ? $ input ['paymentMethod ' ] : '' ,
69- 'shipping_method ' => isset ( $ input ['shippingMethod ' ] ) ? $ input ['shippingMethod ' ] : '' ,
70- 'ship_to_different_address ' => ! empty ( $ input ['shipToDifferentAddress ' ] ) && ! wc_ship_to_billing_address_only (),
71- 'woocommerce_checkout_update_totals ' => isset ( $ input ['updateTotals ' ] ),
73+ 'terms ' => (int ) isset ( $ input ['terms ' ] ),
74+ 'createaccount ' => (int ) ! empty ( $ input ['account ' ] ),
75+ 'payment_method ' => isset ( $ input ['paymentMethod ' ] ) ? $ input ['paymentMethod ' ] : '' ,
76+ 'shipping_method ' => isset ( $ input ['shippingMethod ' ] ) ? $ input ['shippingMethod ' ] : '' ,
77+ 'ship_to_different_address ' => ! empty ( $ input ['shipToDifferentAddress ' ] ) && ! wc_ship_to_billing_address_only (),
7278 );
7379 $ skipped = array ();
7480
@@ -79,11 +85,14 @@ public static function prepare_checkout_args( $input, $context, $info ) {
7985 }
8086
8187 foreach ( $ fieldset as $ field => $ input_key ) {
88+ $ key = "{$ fieldset_key }_ {$ field }" ;
8289 $ value = ! empty ( $ input [ $ fieldset_key ][ $ input_key ] )
8390 ? $ input [ $ fieldset_key ][ $ input_key ]
8491 : null ;
8592 if ( $ value ) {
86- $ data [ "{$ fieldset_key }_ {$ field }" ] = $ value ;
93+ $ data [ $ key ] = $ value ;
94+ } elseif ( 'billing_country ' === $ key || 'shipping_country ' === $ key ) {
95+ $ data [ $ key ] = self ::get_value ( $ key );
8796 }
8897 }
8998 }
@@ -460,6 +469,11 @@ protected function process_order_without_payment( $order_id ) {
460469 $ order = wc_get_order ( $ order_id );
461470 $ order ->payment_complete ();
462471 wc_empty_cart ();
472+
473+ return array (
474+ 'result ' => 'success ' ,
475+ 'redirect ' => apply_filters ( 'woocommerce_checkout_no_payment_needed_redirect ' , $ order ->get_checkout_order_received_url (), $ order ),
476+ );
463477 }
464478
465479 /**
@@ -468,12 +482,11 @@ protected function process_order_without_payment( $order_id ) {
468482 * @param array $data Order data.
469483 * @param AppContext $context AppContext instance.
470484 * @param ResolveInfo $info ResolveInfo instance.
485+ * @param array $results Order status.
471486 *
472487 * @throws UserError When validation fails.
473488 */
474- public static function process_checkout ( $ data , $ context , $ info ) {
475- WC ()->session ->set ( 'refresh_totals ' , true );
476-
489+ public static function process_checkout ( $ data , $ context , $ info , &$ results = null ) {
477490 wc_maybe_define_constant ( 'WOOCOMMERCE_CHECKOUT ' , true );
478491 wc_set_time_limit ( 0 );
479492
@@ -491,28 +504,68 @@ public static function process_checkout( $data, $context, $info ) {
491504 // Validate posted data and cart items before proceeding.
492505 self ::validate_checkout ( $ data );
493506
494- if ( empty ( $ data ['woocommerce_checkout_update_totals ' ] ) ) {
495- self ::process_customer ( $ data );
496- $ order_id = WC ()->checkout ->create_order ( $ data );
497- $ order = wc_get_order ( $ order_id );
507+ self ::process_customer ( $ data );
508+ $ order_id = WC ()->checkout ->create_order ( $ data );
509+ $ order = wc_get_order ( $ order_id );
498510
499- if ( is_wp_error ( $ order_id ) ) {
500- throw new UserError ( $ order_id ->get_error_message () );
501- }
511+ if ( is_wp_error ( $ order_id ) ) {
512+ throw new UserError ( $ order_id ->get_error_message () );
513+ }
502514
503- if ( ! $ order ) {
504- throw new UserError ( __ ( 'Unable to create order. ' , 'wp-graphql-woocommerce ' ) );
505- }
515+ if ( ! $ order ) {
516+ throw new UserError ( __ ( 'Unable to create order. ' , 'wp-graphql-woocommerce ' ) );
517+ }
506518
507- do_action ( 'woocommerce_checkout_order_processed ' , $ order_id , $ data , $ order );
519+ do_action ( 'woocommerce_checkout_order_processed ' , $ order_id , $ data , $ order );
508520
509- if ( WC ()->cart ->needs_payment () ) {
510- self ::process_order_payment ( $ order_id , $ data ['payment_method ' ] );
511- } else {
512- self ::process_order_without_payment ( $ order_id );
513- }
521+ if ( WC ()->cart ->needs_payment () ) {
522+ $ results = self ::process_order_payment ( $ order_id , $ data ['payment_method ' ] );
523+ } else {
524+ $ results = self ::process_order_without_payment ( $ order_id );
514525 }
515526
516527 return $ order_id ;
517528 }
529+
530+ /**
531+ * Gets the value either from 3rd party logic or the customer object. Sets the default values in checkout fields.
532+ *
533+ * @param string $input Name of the input we want to grab data for. e.g. billing_country.
534+ * @return string The default value.
535+ */
536+ public static function get_value ( $ input ) {
537+ // Allow 3rd parties to short circuit the logic and return their own default value.
538+ $ value = apply_filters ( 'woocommerce_checkout_get_value ' , null , $ input );
539+ if ( ! is_null ( $ value ) ) {
540+ return $ value ;
541+ }
542+
543+ /**
544+ * For logged in customers, pull data from their account rather than the session which may contain incomplete data.
545+ * Another reason is that WC sets shipping address to the billing address on the checkout updates unless the
546+ * "shipToDifferentAddress" is set.
547+ */
548+ $ customer_object = false ;
549+ if ( is_user_logged_in () ) {
550+ // Load customer object, but keep it cached to avoid reloading it multiple times.
551+ if ( is_null ( self ::$ logged_in_customer ) ) {
552+ self ::$ logged_in_customer = new WC_Customer ( get_current_user_id (), true );
553+ }
554+ $ customer_object = new WC_Customer ( get_current_user_id (), true );
555+ }
556+
557+ if ( ! $ customer_object ) {
558+ $ customer_object = WC ()->customer ;
559+ }
560+
561+ if ( is_callable ( array ( $ customer_object , "get_ $ input " ) ) ) {
562+ $ value = $ customer_object ->{"get_ $ input " }();
563+ } elseif ( $ customer_object ->meta_exists ( $ input ) ) {
564+ $ value = $ customer_object ->get_meta ( $ input , true );
565+ }
566+ if ( '' === $ value ) {
567+ $ value = null ;
568+ }
569+ return apply_filters ( 'default_checkout_ ' . $ input , $ value , $ input );
570+ }
518571}
0 commit comments