Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
51.35% covered (warning)
51.35%
38 / 74
66.67% covered (warning)
66.67%
12 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
BH_WP_Bitcoin_Gateway
51.35% covered (warning)
51.35%
38 / 74
66.67% covered (warning)
66.67%
12 / 18
66.05
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
2
 set_locale
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 define_plugins_page_hooks
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 define_dependencies_admin_notice_hooks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 define_custom_post_type_hooks
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 define_frontend_hooks
100.00% covered (success)
100.00%
6 / 6
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%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 define_order_hooks
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 define_thank_you_hooks
0.00% covered (danger)
0.00%
0 / 2
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_action_scheduler_hooks
100.00% covered (success)
100.00%
4 / 4
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_wp_list_page_ui_hooks
100.00% covered (success)
100.00%
3 / 3
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_cli_commands
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 define_integration_woo_cancel_abandoned_order_hooks
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * The file that defines the core plugin class
4 *
5 * A class definition that includes attributes and functions used across both the
6 * frontend-facing side of the site and the admin area.
7 *
8 * @link       http://example.com
9 * @since      1.0.0
10 *
11 * @package    brianhenryie/bh-wp-bitcoin-gateway
12 */
13
14namespace BrianHenryIE\WP_Bitcoin_Gateway;
15
16use BrianHenryIE\WP_Bitcoin_Gateway\Admin\Dependencies_Notice;
17use BrianHenryIE\WP_Bitcoin_Gateway\Admin\Register_List_Tables;
18use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\Woo_Cancel_Abandoned_Order;
19use BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce\HPOS;
20use BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce\Order;
21use Exception;
22use BrianHenryIE\WP_Bitcoin_Gateway\Action_Scheduler\Background_Jobs;
23use BrianHenryIE\WP_Bitcoin_Gateway\Admin\Plugins_Page;
24use BrianHenryIE\WP_Bitcoin_Gateway\Admin\Wallets_List_Table;
25use BrianHenryIE\WP_Bitcoin_Gateway\Frontend\AJAX;
26use BrianHenryIE\WP_Bitcoin_Gateway\Frontend\Frontend_Assets;
27use BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce\Admin_Order_UI;
28use BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce\Email;
29use BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce\My_Account_View_Order;
30use BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce\Payment_Gateways;
31use BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce\Templates;
32use BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce\Thank_You;
33use BrianHenryIE\WP_Bitcoin_Gateway\WP_Includes\CLI;
34use BrianHenryIE\WP_Bitcoin_Gateway\WP_Includes\I18n;
35use BrianHenryIE\WP_Bitcoin_Gateway\WP_Includes\Post;
36use Psr\Log\LoggerInterface;
37use WP_CLI;
38
39/**
40 * The core plugin class.
41 *
42 * This is used to define internationalization, admin-specific hooks, and
43 * frontend-facing site hooks.
44 *
45 * Also maintains the unique identifier of this plugin as well as the current
46 * version of the plugin.
47 */
48class BH_WP_Bitcoin_Gateway {
49
50    /**
51     * A PSR logger for logging errors, events etc.
52     */
53    protected LoggerInterface $logger;
54
55    /**
56     * The plugin settings.
57     */
58    protected Settings_Interface $settings;
59
60    /**
61     * The main plugin functions.
62     */
63    protected API_Interface $api;
64
65    /**
66     * Define the core functionality of the plugin.
67     *
68     * Set the plugin name and the plugin version that can be used throughout the plugin.
69     * Load the dependencies, define the locale, and set the hooks for the admin area and
70     * the frontend-facing side of the site.
71     *
72     * @since    1.0.0
73     *
74     * @param API_Interface      $api The main plugin functions.
75     * @param Settings_Interface $settings The plugin settings.
76     * @param LoggerInterface    $logger A PSR logger.
77     */
78    public function __construct( API_Interface $api, Settings_Interface $settings, LoggerInterface $logger ) {
79
80        $this->logger   = $logger;
81        $this->settings = $settings;
82        $this->api      = $api;
83
84        $this->set_locale();
85
86        $this->define_plugins_page_hooks();
87        $this->define_dependencies_admin_notice_hooks();
88
89        $this->define_custom_post_type_hooks();
90
91        $this->define_frontend_hooks();
92        $this->define_template_hooks();
93
94        $this->define_payment_gateway_hooks();
95        $this->define_order_hooks();
96        $this->define_action_scheduler_hooks();
97
98        $this->define_thank_you_hooks();
99        $this->define_email_hooks();
100        $this->define_my_account_hooks();
101
102        $this->define_admin_order_ui_hooks();
103        $this->define_wp_list_page_ui_hooks();
104
105        $this->define_woocommerce_features_hooks();
106
107        $this->define_cli_commands();
108
109        $this->define_integration_woo_cancel_abandoned_order_hooks();
110    }
111
112    /**
113     * Define the locale for this plugin for internationalization.
114     *
115     * Uses the i18n class in order to set the domain and to register the hook
116     * with WordPress.
117     *
118     * @since    1.0.0
119     */
120    protected function set_locale(): void {
121
122        $plugin_i18n = new I18n();
123
124        add_action( 'init', array( $plugin_i18n, 'load_plugin_textdomain' ) );
125    }
126
127    /**
128     * Hooks to add a "Settings" link on plugins.php.
129     * And a link to an orders filter (where possible).
130     */
131    protected function define_plugins_page_hooks(): void {
132
133        $plugins_page = new Plugins_Page( $this->api, $this->settings );
134
135        $plugin_basename = $this->settings->get_plugin_basename();
136
137        add_filter( "plugin_action_links_{$plugin_basename}", array( $plugins_page, 'add_settings_action_link' ) );
138        add_filter( "plugin_action_links_{$plugin_basename}", array( $plugins_page, 'add_orders_action_link' ) );
139
140        add_filter( 'plugin_row_meta', array( $plugins_page, 'split_author_link_into_two_links' ), 10, 2 );
141    }
142
143    /**
144     * Add a hook to display an admin notice when the required PHP extensions are not present.
145     */
146    protected function define_dependencies_admin_notice_hooks(): void {
147
148        $dependencies_notices = new Dependencies_Notice( $this->api, $this->settings );
149
150        add_action( 'admin_notices', array( $dependencies_notices, 'print_dependencies_notice' ) );
151    }
152
153    /**
154     * Add hooks for defining post types for the wallets and destination addresses.
155     */
156    protected function define_custom_post_type_hooks(): void {
157
158        $post = new Post( $this->api );
159        add_action( 'init', array( $post, 'register_wallet_post_type' ) );
160        add_action( 'init', array( $post, 'register_address_post_type' ) );
161    }
162
163    /**
164     * Enqueue styles, scripts and AJAX to style and handle the templates.
165     *
166     * @since    1.0.0
167     */
168    protected function define_frontend_hooks(): void {
169
170        $plugin_frontend = new Frontend_Assets( $this->api, $this->settings, $this->logger );
171
172        add_action( 'wp_enqueue_scripts', array( $plugin_frontend, 'enqueue_styles' ) );
173        add_action( 'wp_enqueue_scripts', array( $plugin_frontend, 'enqueue_scripts' ) );
174
175        $ajax = new AJAX( $this->api, $this->logger );
176
177        add_action( 'wp_ajax_bh_wp_bitcoin_gateway_refresh_order_details', array( $ajax, 'get_order_details' ) );
178        add_action( 'wp_ajax_nopriv_bh_wp_bitcoin_gateway_refresh_order_details', array( $ajax, 'get_order_details' ) );
179    }
180
181    /**
182     * Hooks into WooCommerce templating system to provide the templates used to display the payment details
183     * after checkout, on the my-account order view, and in email.
184     */
185    protected function define_template_hooks(): void {
186
187        $templates = new Templates( $this->settings );
188
189        add_filter( 'wc_get_template', array( $templates, 'load_bitcoin_templates' ), 10, 5 );
190    }
191
192    /**
193     * Register the gateway class with WooCommerce.
194     * Add a filter for the WooCommerce Settings payment gateways view to filter to only Bitcoin gateways.
195     */
196    protected function define_payment_gateway_hooks(): void {
197
198        $payment_gateways = new Payment_Gateways( $this->api, $this->settings, $this->logger );
199
200        // Register the payment gateway with WooCommerce.
201        add_filter( 'woocommerce_payment_gateways', array( $payment_gateways, 'add_to_woocommerce' ) );
202
203        // Register the payment gateway with WooCommerce Blocks checkout.
204        add_action( 'woocommerce_blocks_payment_method_type_registration', array( $payment_gateways, 'register_woocommerce_block_checkout_support' ) );
205
206        add_filter( 'woocommerce_available_payment_gateways', array( $payment_gateways, 'add_logger_to_gateways' ) );
207    }
208
209    /**
210     * Handle order status changes.
211     */
212    protected function define_order_hooks(): void {
213
214        $order = new Order( $this->api, $this->logger );
215
216        add_action( 'woocommerce_order_status_changed', array( $order, 'schedule_check_for_transactions' ), 10, 3 );
217        add_action( 'woocommerce_order_status_changed', array( $order, 'unschedule_check_for_transactions' ), 10, 3 );
218    }
219
220    /**
221     * Hook into the Thank You page to display payment instructions / status.
222     */
223    protected function define_thank_you_hooks(): void {
224
225        $thank_you = new Thank_You( $this->api, $this->logger );
226
227        add_action( 'woocommerce_thankyou', array( $thank_you, 'print_instructions' ), 5 );
228    }
229
230    /**
231     * Hook into emails and send payment instructions / status for related orders.
232     */
233    protected function define_email_hooks(): void {
234
235        $email = new Email( $this->api, $this->logger );
236
237        // TODO: Before table? best place?
238        add_action( 'woocommerce_email_before_order_table', array( $email, 'print_instructions' ), 10, 3 );
239    }
240
241    /**
242     * Add hooks to display the Bitcoin payment details on the single order view in my-account.
243     */
244    protected function define_my_account_hooks(): void {
245
246        $my_account_order = new My_Account_View_Order( $this->api, $this->logger );
247
248        add_action( 'woocommerce_view_order', array( $my_account_order, 'print_status_instructions' ), 9 );
249    }
250
251    /**
252     * Handle Action Scheduler invoked actions to generate new addresses and check unpaid orders.
253     */
254    protected function define_action_scheduler_hooks(): void {
255
256        $background_jobs = new Background_Jobs( $this->api, $this->logger );
257
258        add_action( Background_Jobs::GENERATE_NEW_ADDRESSES_HOOK, array( $background_jobs, 'generate_new_addresses' ) );
259        add_action( Background_Jobs::CHECK_UNPAID_ORDER_HOOK, array( $background_jobs, 'check_unpaid_order' ) );
260        add_action( Background_Jobs::CHECK_NEW_ADDRESSES_TRANSACTIONS_HOOK, array( $background_jobs, 'check_new_addresses_for_transactions' ) );
261    }
262
263    /**
264     * Add a meta box to the admin order view showing the Bitcoin total, address and transactions.
265     */
266    protected function define_admin_order_ui_hooks(): void {
267
268        $admin_order_ui = new Admin_Order_UI( $this->api, $this->logger );
269
270        add_action( 'add_meta_boxes', array( $admin_order_ui, 'register_address_transactions_meta_box' ) );
271    }
272
273    /**
274     * Customize the columns and data shown in the WP_List_Table for bitcoin wallets and bitcoin addresses.
275     */
276    protected function define_wp_list_page_ui_hooks(): void {
277
278        $register_list_tables = new Register_List_Tables();
279
280        add_filter( 'wp_list_table_class_name', array( $register_list_tables, 'register_bitcoin_address_table' ), 10, 2 );
281        add_filter( 'wp_list_table_class_name', array( $register_list_tables, 'register_bitcoin_wallet_table' ), 10, 2 );
282    }
283
284    /**
285     * Declare compatibility with WooCommerce High Performance Order Storage.
286     */
287    protected function define_woocommerce_features_hooks(): void {
288
289        $hpos = new HPOS( $this->settings );
290
291        add_action( 'before_woocommerce_init', array( $hpos, 'declare_compatibility' ) );
292    }
293
294    /**
295     * Register WP CLI commands.
296     *
297     * `wp bh-bitcoin generate-new-addresses`
298     */
299    protected function define_cli_commands(): void {
300
301        if ( ! class_exists( WP_CLI::class ) ) {
302            return;
303        }
304
305        $cli = new CLI( $this->api, $this->settings, $this->logger );
306
307        try {
308            WP_CLI::add_command( 'bh-bitcoin generate-new-addresses', array( $cli, 'generate_new_addresses' ) );
309            WP_CLI::add_command( 'bh-bitcoin check-transactions', array( $cli, 'check_transactions' ) );
310        } catch ( Exception $e ) {
311            $this->logger->error( 'Failed to register WP CLI commands: ' . $e->getMessage(), array( 'exception' => $e ) );
312        }
313    }
314
315    /**
316     * Add filters to enable support for WooCommerce Cancel Abandoned Order plugin.
317     *
318     * @see https://wordpress.org/plugins/woo-cancel-abandoned-order/
319     */
320    protected function define_integration_woo_cancel_abandoned_order_hooks(): void {
321
322        $woo_cancel_abandoned_order = new Woo_Cancel_Abandoned_Order( $this->api );
323
324        add_filter( 'woo_cao_gateways', array( $woo_cancel_abandoned_order, 'enable_cao_for_bitcoin' ) );
325        add_filter( 'woo_cao_before_cancel_order', array( $woo_cancel_abandoned_order, 'abort_canceling_partially_paid_order' ), 10, 3 );
326    }
327}