Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
31.03% covered (danger)
31.03%
9 / 29
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Blocks
31.03% covered (danger)
31.03%
9 / 29
75.00% covered (warning)
75.00%
3 / 4
35.57
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 register_integration
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 register_update_callback
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 update_callback
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2/**
3 * Register the blocks checkout integration and handle updating the cart through `extensionCartUpdate` JavaScript.
4 *
5 * @package brianhenryie/bh-wc-postcode-address-autofill
6 */
7
8namespace BrianHenryIE\WC_Postcode_Address_Autofill\WooCommerce;
9
10use Automattic\WooCommerce\Blocks\Integrations\IntegrationRegistry;
11use BrianHenryIE\WC_Postcode_Address_Autofill\API_Interface;
12use BrianHenryIE\WC_Postcode_Address_Autofill\Settings_Interface;
13
14/**
15 * Register with WooCommerce's `IntegrationRegistry` and `extensionCartUpdate`.
16 */
17class Blocks {
18    /**
19     * The core plugin functions.
20     *
21     * @uses API_Interface::get_locations_for_postcode()
22     */
23    protected API_Interface $api;
24
25    /**
26     * Plugin settings.
27     */
28    protected Settings_Interface $settings;
29
30    /**
31     * Constructor
32     *
33     * @param API_Interface      $api The main plugin functions.
34     * @param Settings_Interface $settings The plugin settings.
35     */
36    public function __construct( API_Interface $api, Settings_Interface $settings ) {
37        $this->settings = $settings;
38        $this->api      = $api;
39    }
40
41    /**
42     * Use the IntegrationRegistry to enqueue scripts wherever the checkout is displayed.
43     *
44     * @hooked woocommerce_blocks_checkout_block_registration
45     * @see https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/third-party-developers/extensibility/checkout-block/integration-interface.md
46     *
47     * @param IntegrationRegistry $integration_registry WooCommerce core class for managing blocks' assets.
48     */
49    public function register_integration( IntegrationRegistry $integration_registry ): void {
50        $integration_registry->register( new Checkout_Blocks( $this->settings ) );
51    }
52
53    /**
54     * Register a function to handle updating the cart in JavaScript using the `extensionCartUpdate` function.
55     *
56     * @hooked woocommerce_blocks_loaded
57     * @see https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/third-party-developers/extensibility/rest-api/extend-rest-api-update-cart.md
58     */
59    public function register_update_callback(): void {
60        woocommerce_store_api_register_update_callback(
61            array(
62                'namespace' => 'bh-wc-postcode-address-autofill',
63                'callback'  => array( $this, 'update_callback' ),
64            )
65        );
66    }
67
68    /**
69     * Handle the update sent from the frontend.
70     *
71     * Handle autofill on postcode entry on the WooCommerce Blocks checkout.
72     *
73     * Find the state+city for the country+postcode and apply them to the cart address.
74     * This should only be called when a new postcode has been entered.
75     *
76     * @param array{shipping:array{postcode:string, country:string},billing:array{postcode:string, country:string}} $data The data object as passed from our JavaScript.
77     */
78    public function update_callback( array $data ): void {
79
80        foreach ( $data as $address_type => $address_data ) {
81
82            $postcode = $address_data['postcode'];
83            $country  = $address_data['country'];
84
85            $cart = WC()->cart;
86
87            if ( 'shipping' === $address_type ) {
88                $cart->get_customer()->set_shipping_postcode( $postcode );
89                $cart->get_customer()->set_shipping_country( $country );
90            } else {
91                $cart->get_customer()->set_billing_country( $country );
92                $cart->get_customer()->set_billing_postcode( $postcode );
93            }
94
95            $locations = $this->api->get_locations_for_postcode( $country, $postcode );
96
97            if ( empty( $locations ) ) {
98                return;
99            }
100
101            $location = $locations->get_first();
102
103            if ( empty( $location ) ) {
104                return;
105            }
106
107            if ( 'shipping' === $address_type ) {
108                $cart->get_customer()->set_shipping_state( $location->get_state() );
109                $cart->get_customer()->set_shipping_city( $location->get_city() );
110            } else {
111                $cart->get_customer()->set_billing_state( $location->get_state() );
112                $cart->get_customer()->set_billing_city( $location->get_city() );
113            }
114        }
115    }
116}