Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
38.10% covered (danger)
38.10%
24 / 63
53.85% covered (warning)
53.85%
7 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
WooCommerce_Integration
38.10% covered (danger)
38.10%
24 / 63
53.85% covered (warning)
53.85%
7 / 13
53.09
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 register_hooks
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 define_frontend_hooks
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 define_template_hooks
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 define_payment_gateway_hooks
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 define_woocommerce_checkout_hooks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 define_thank_you_hooks
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
 define_email_hooks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 define_my_account_hooks
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 define_order_hooks
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 define_admin_order_ui_hooks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 define_woocommerce_features_hooks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 define_address_list_table_hooks
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * WooCommerce specific functionality.
4 *
5 * @package brianhenryie/bh-wp-bitcoin-gateway
6 */
7
8namespace BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce;
9
10use BrianHenryIE\WP_Bitcoin_Gateway\Frontend\Blocks\Bitcoin_Image_Block;
11use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\Blocks\Bitcoin_Order_Confirmation_Block;
12use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\Blocks\Order_Confirmation\Bitcoin_Exchange_Rate_Block;
13use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\Blocks\Order_Confirmation\Bitcoin_Order_Payment_Address_Block;
14use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\Blocks\Order_Confirmation\Bitcoin_Order_Payment_Amount_Received_Block;
15use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\Blocks\Order_Confirmation\Bitcoin_Order_Payment_Last_Checked_Block;
16use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\Blocks\Order_Confirmation\Bitcoin_Order_Payment_Status_Block;
17use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\Blocks\Order_Confirmation\Bitcoin_Order_Payment_Total_Block;
18use BrianHenryIE\WP_Bitcoin_Gateway\lucatume\DI52\Container as DI52_Container;
19use BrianHenryIE\WP_Bitcoin_Gateway\lucatume\DI52\ContainerException;
20use Psr\Container\ContainerExceptionInterface;
21use Psr\Container\ContainerInterface;
22use Psr\Container\NotFoundExceptionInterface;
23
24/**
25 * Instantiate classes and register hooks with WordPress.
26 */
27class WooCommerce_Integration {
28
29    /**
30     * Constructor
31     *
32     * @param ContainerInterface&DI52_Container $container PSR container.
33     * @throws ContainerException E.g. if the bound class cannot be instantiated.
34     */
35    public function __construct(
36        protected DI52_Container $container,
37    ) {
38        $this->container->bind( API_WooCommerce_Interface::class, API_WooCommerce::class );
39    }
40
41    /**
42     * Define the core functionality of the plugin.
43     *
44     * Set the plugin name and the plugin version that can be used throughout the plugin.
45     * Load the dependencies, define the locale, and set the hooks for the admin area and
46     * the frontend-facing side of the site.
47     *
48     * @throws NotFoundExceptionInterface If the class cannot be resolved (often when an interface does not have a bound class).
49     * @throws ContainerException Other problems when instantiating the requested class.
50     * @throws ContainerExceptionInterface PSR interface for all container exceptions.
51     */
52    public function register_hooks(): void {
53
54        $this->define_frontend_hooks();
55        $this->define_template_hooks();
56
57        $this->define_payment_gateway_hooks();
58        $this->define_woocommerce_checkout_hooks();
59
60        $this->define_thank_you_hooks();
61        $this->define_email_hooks();
62        $this->define_my_account_hooks();
63
64        $this->define_order_hooks();
65
66        $this->define_admin_order_ui_hooks();
67
68        $this->define_woocommerce_features_hooks();
69
70        $this->define_address_list_table_hooks();
71    }
72
73    /**
74     * Enqueue styles, scripts and AJAX to style and handle the templates.
75     */
76    protected function define_frontend_hooks(): void {
77
78        /** @var Frontend_Assets $plugin_frontend */
79        $plugin_frontend = $this->container->get( Frontend_Assets::class );
80
81        add_action( 'wp_enqueue_scripts', array( $plugin_frontend, 'enqueue_styles' ) );
82        add_action( 'wp_enqueue_scripts', array( $plugin_frontend, 'enqueue_scripts' ) );
83
84        /** @var AJAX $ajax */
85        $ajax = $this->container->get( AJAX::class );
86
87        add_action( 'wp_ajax_bh_wp_bitcoin_gateway_refresh_order_details', array( $ajax, 'get_order_details' ) );
88        add_action( 'wp_ajax_nopriv_bh_wp_bitcoin_gateway_refresh_order_details', array( $ajax, 'get_order_details' ) );
89
90        /** @var Bitcoin_Image_Block $bitcoin_image_block */
91        $bitcoin_image_block = $this->container->get( Bitcoin_Image_Block::class );
92        add_filter( 'get_block_type_variations', array( $bitcoin_image_block, 'add_bitcoin_image_variation' ), 10, 2 );
93    }
94
95    /**
96     * Hooks into WooCommerce templating system to provide the templates used to display the payment details
97     * after checkout, on the my-account order view, and in email.
98     */
99    protected function define_template_hooks(): void {
100
101        /** @var Templates $templates */
102        $templates = $this->container->get( Templates::class );
103
104        add_filter( 'wc_get_template', array( $templates, 'load_bitcoin_templates' ), 10, 5 );
105    }
106
107    /**
108     * Register the gateway class with WooCommerce.
109     * Add a filter for the WooCommerce Settings payment gateways view to filter to only Bitcoin gateways.
110     */
111    protected function define_payment_gateway_hooks(): void {
112
113        /** @var Payment_Gateways $payment_gateways */
114        $payment_gateways = $this->container->get( Payment_Gateways::class );
115
116        // Register the payment gateway with WooCommerce.
117        add_filter( 'woocommerce_payment_gateways', array( $payment_gateways, 'add_to_woocommerce' ) );
118
119        // Register the payment gateway with WooCommerce Blocks checkout.
120        add_action( 'woocommerce_blocks_payment_method_type_registration', array( $payment_gateways, 'register_woocommerce_block_checkout_support' ) );
121
122        /** @var Menu $menu */
123        $menu = $this->container->get( Menu::class );
124
125        add_action( 'admin_menu', array( $menu, 'add_woocommerce_payments_submenu' ) );
126    }
127
128    /**
129     * Always check for an unused address when opening the checkout.
130     */
131    protected function define_woocommerce_checkout_hooks(): void {
132
133        /** @var Checkout $checkout */
134        $checkout = $this->container->get( Checkout::class );
135
136        add_action( 'woocommerce_checkout_init', array( $checkout, 'ensure_one_address_for_payment' ) );
137    }
138
139    /**
140     * Hook into the "Thank You" page to display payment instructions / status.
141     */
142    protected function define_thank_you_hooks(): void {
143
144        /** @var Thank_You $thank_you */
145        $thank_you = $this->container->get( Thank_You::class );
146        add_action( 'woocommerce_thankyou', array( $thank_you, 'print_instructions' ), 5 );
147
148        /** @var Bitcoin_Exchange_Rate_Block $bitcoin_exchange_rate_block */
149        $bitcoin_exchange_rate_block = $this->container->get( Bitcoin_Exchange_Rate_Block::class );
150        add_action( 'init', array( $bitcoin_exchange_rate_block, 'register_block' ) );
151
152        /** @var Bitcoin_Order_Confirmation_Block $bitcoin_order_confirmation_block */
153        $bitcoin_order_confirmation_block = $this->container->get( Bitcoin_Order_Confirmation_Block::class );
154        add_action( 'init', array( $bitcoin_order_confirmation_block, 'register_block' ) );
155
156        /** @var Bitcoin_Order_Payment_Status_Block $bitcoin_payment_status_block */
157        $bitcoin_payment_status_block = $this->container->get( Bitcoin_Order_Payment_Status_Block::class );
158        add_action( 'init', array( $bitcoin_payment_status_block, 'register_block' ) );
159
160        /** @var Bitcoin_Order_Payment_Address_Block $bitcoin_payment_address_block */
161        $bitcoin_payment_address_block = $this->container->get( Bitcoin_Order_Payment_Address_Block::class );
162        add_action( 'init', array( $bitcoin_payment_address_block, 'register_block' ) );
163
164        /** @var Bitcoin_Order_Payment_Total_Block $bitcoin_payment_total_block */
165        $bitcoin_payment_total_block = $this->container->get( Bitcoin_Order_Payment_Total_Block::class );
166        add_action( 'init', array( $bitcoin_payment_total_block, 'register_block' ) );
167
168        /** @var Bitcoin_Order_Payment_Amount_Received_Block $bitcoin_payment_amount_received_block */
169        $bitcoin_payment_amount_received_block = $this->container->get( Bitcoin_Order_Payment_Amount_Received_Block::class );
170        add_action( 'init', array( $bitcoin_payment_amount_received_block, 'register_block' ) );
171
172        /** @var Bitcoin_Order_Payment_Last_Checked_Block $bitcoin_payment_last_checked_block */
173        $bitcoin_payment_last_checked_block = $this->container->get( Bitcoin_Order_Payment_Last_Checked_Block::class );
174        add_action( 'init', array( $bitcoin_payment_last_checked_block, 'register_block' ) );
175    }
176
177    /**
178     * Hook into emails and send payment instructions / status for related orders.
179     */
180    protected function define_email_hooks(): void {
181
182        /** @var Email $email */
183        $email = $this->container->get( Email::class );
184
185        // TODO: Before table? best place?
186        add_action( 'woocommerce_email_before_order_table', array( $email, 'print_instructions' ), 10, 3 );
187    }
188
189    /**
190     * Add hooks to display the Bitcoin payment details on the single order view in my-account.
191     */
192    protected function define_my_account_hooks(): void {
193
194        /** @var My_Account_View_Order $my_account_order */
195        $my_account_order = $this->container->get( My_Account_View_Order::class );
196
197        add_action( 'woocommerce_view_order', array( $my_account_order, 'print_status_instructions' ), 9 );
198    }
199
200    /**
201     * Add hooks that trigger changes to the WooCommerce order object itself, fired by the bh-wp-bitcoin-gateway plugin!
202     */
203    protected function define_order_hooks(): void {
204        /** @var Order $order */
205        $order = $this->container->get( Order::class );
206
207        add_action( 'bh_wp_bitcoin_gateway_new_transactions_seen', array( $order, 'new_transactions_seen' ), 10, 4 );
208        add_action( 'bh_wp_bitcoin_gateway_payment_received', array( $order, 'payment_received' ), 10, 4 );
209    }
210
211    /**
212     * Add a meta box to the admin order view showing the Bitcoin total, address and transactions.
213     */
214    protected function define_admin_order_ui_hooks(): void {
215
216        /** @var Admin_Order_UI $admin_order_ui */
217        $admin_order_ui = $this->container->get( Admin_Order_UI::class );
218
219        add_action( 'add_meta_boxes', array( $admin_order_ui, 'register_address_transactions_meta_box' ) );
220    }
221
222    /**
223     * Declare compatibility with WooCommerce High Performance Order Storage.
224     *
225     * @see wp-admin/plugins.php?plugin_status=incompatible_with_feature
226     */
227    protected function define_woocommerce_features_hooks(): void {
228
229        /** @var HPOS $hpos */
230        $hpos = $this->container->get( HPOS::class );
231
232        add_action( 'before_woocommerce_init', array( $hpos, 'declare_compatibility' ) );
233    }
234
235    /**
236     * Filter the output of `wp-admin/edit.php?post_type=bh-bitcoin-address` to include links to WooCommerce gateways.
237     */
238    protected function define_address_list_table_hooks(): void {
239
240        /** @var Addresses_List_Table $address_list_table */
241        $address_list_table = $this->container->get( Addresses_List_Table::class );
242
243        add_filter(
244            'bh_wp_bitcoin_gateway_gateway_link',
245            $address_list_table->woocommerce_gateway_link( ... ),
246            10,
247            5
248        );
249    }
250}