Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
57.75% covered (warning)
57.75%
41 / 71
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2/**
3 * Bitcoin payment gateway for WordPress – WooCommerce.
4 *
5 * @package           brianhenryie/bh-wp-bitcoin-gateway
6 *
7 * @wordpress-plugin
8 * Plugin Name:            Bitcoin Gateway
9 * Plugin URI:             http://github.com/BrianHenryIE/bh-wp-bitcoin-gateway/
10 * Description:            Accept Bitcoin payments using self-custodied wallets, and no external account. Calculates wallet addresses locally and uses open APIs to verify payments. For an emphasis on privacy & sovereignty.
11 * Version:                2.0.0-beta-8
12 * Requires at least:      5.9
13 * Requires PHP:           8.4
14 * Author:                 Nullcorps, BrianHenryIE
15 * Author URI:             https://bhwp.ie
16 * License:                GNU General Public License v3.0
17 * License URI:            http://www.gnu.org/licenses/gpl-3.0.html
18 * Text Domain:            bh-wp-bitcoin-gateway
19 * Domain Path:            /languages
20 * WC requires at least:   10.1.2
21 * WC tested up to:        10.1.2
22 */
23
24namespace BrianHenryIE\WP_Bitcoin_Gateway;
25
26use BrianHenryIE\WP_Bitcoin_Gateway\Action_Scheduler\API_Background_Jobs_Interface;
27use BrianHenryIE\WP_Bitcoin_Gateway\Action_Scheduler\Background_Jobs_Actions_Handler;
28use BrianHenryIE\WP_Bitcoin_Gateway\Action_Scheduler\Background_Jobs_Actions_Interface;
29use BrianHenryIE\WP_Bitcoin_Gateway\Action_Scheduler\Background_Jobs_Scheduler;
30use BrianHenryIE\WP_Bitcoin_Gateway\Action_Scheduler\Background_Jobs_Scheduler_Interface;
31use BrianHenryIE\WP_Bitcoin_Gateway\API\Helpers\JsonMapper\JsonMapper_Helper;
32use BrianHenryIE\WP_Bitcoin_Gateway\API\Helpers\Wallet\Nimq_API;
33use BrianHenryIE\WP_Bitcoin_Gateway\API\API;
34use BrianHenryIE\WP_Bitcoin_Gateway\API\Clients\Blockchain\Blockchain_Info_Api;
35use BrianHenryIE\WP_Bitcoin_Gateway\API\Clients\Blockchain\Blockstream_Info_API;
36use BrianHenryIE\WP_Bitcoin_Gateway\API\Clients\Blockchain_API_Interface;
37use BrianHenryIE\WP_Bitcoin_Gateway\API\Clients\Exchange_Rate\Bitfinex_API;
38use BrianHenryIE\WP_Bitcoin_Gateway\API\Clients\Exchange_Rate_API_Interface;
39use BrianHenryIE\WP_Bitcoin_Gateway\API\Helpers\Generate_Address_API_Interface;
40use BrianHenryIE\WP_Bitcoin_Gateway\API\Settings;
41use BrianHenryIE\WP_Bitcoin_Gateway\Art4\Requests\Psr\HttpClient;
42use BrianHenryIE\WP_Bitcoin_Gateway\BlockchainInfo\BlockchainInfoApi;
43use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\Woo_Cancel_Abandoned_Order\Woo_Cancel_Abandoned_Order_Integration;
44use BrianHenryIE\WP_Bitcoin_Gateway\Integrations\WooCommerce\WooCommerce_Integration;
45use BrianHenryIE\WP_Bitcoin_Gateway\JsonMapper\JsonMapperInterface;
46use BrianHenryIE\WP_Bitcoin_Gateway\lucatume\DI52\Container;
47use BrianHenryIE\WP_Bitcoin_Gateway\WC_Logger\WC_Logger_Settings_Interface;
48use BrianHenryIE\WP_Bitcoin_Gateway\WC_Logger\WC_PSR_Logger;
49use BrianHenryIE\WP_Bitcoin_Gateway\WP_Includes\Activator;
50use BrianHenryIE\WP_Bitcoin_Gateway\WP_Includes\Deactivator;
51use BrianHenryIE\WP_Bitcoin_Gateway\WP_Logger\Logger;
52use BrianHenryIE\WP_Bitcoin_Gateway\WP_Logger\Logger_Settings_Interface;
53use Exception;
54use Psr\Http\Client\ClientInterface;
55use Psr\Http\Message\RequestFactoryInterface;
56use Psr\Log\LoggerInterface;
57use Psr\Log\LogLevel;
58use Throwable;
59
60// If this file is called directly, abort.
61if ( ! defined( 'WPINC' ) ) {
62    throw new Exception( 'WPINC not defined' );
63}
64
65// If the GitHub repo was installed without running `composer install` to add the dependencies, the autoload will fail.
66try {
67    require_once plugin_dir_path( __FILE__ ) . 'autoload.php';
68} catch ( Throwable $error ) {
69    $display_download_from_releases_error_notice = function () {
70        echo '<div class="notice notice-error"><p><b>Bitcoin Gateway missing dependencies.</b> Please <a href="https://github.com/BrianHenryIE/bh-wp-bitcoin-gateway/releases">install the distribution archive from the GitHub Releases page</a>. It appears you downloaded the GitHub repo and installed that as the plugin.</p></div>';
71    };
72    add_action( 'admin_notices', $display_download_from_releases_error_notice );
73    return;
74}
75
76/**
77 * Current plugin version.
78 * Start at version 1.0.0 and use SemVer - https://semver.org
79 * Rename this for your plugin and update it as you release new versions.
80 */
81define( 'BH_WP_BITCOIN_GATEWAY_VERSION', '2.0.0' );
82
83define( 'BH_WP_BITCOIN_GATEWAY_BASENAME', plugin_basename( __FILE__ ) );
84define( 'BH_WP_BITCOIN_GATEWAY_PATH', trailingslashit( __DIR__ ) );
85define( 'BH_WP_BITCOIN_GATEWAY_URL', trailingslashit( plugins_url( plugin_basename( __DIR__ ) ) ) );
86
87register_activation_hook( __FILE__, array( Activator::class, 'activate' ) );
88register_deactivation_hook( __FILE__, array( Deactivator::class, 'deactivate' ) );
89
90$container = new Container();
91
92$container->bind( Background_Jobs_Scheduler_Interface::class, Background_Jobs_Scheduler::class );
93$container->bind( Background_Jobs_Actions_Interface::class, Background_Jobs_Actions_Handler::class );
94
95$container->bind( API_Background_Jobs_Interface::class, API::class );
96$container->bind( API_Interface::class, API::class );
97
98$container->bind( Settings_Interface::class, Settings::class );
99$container->bind( LoggerInterface::class, Logger::class );
100$container->bind( Logger_Settings_Interface::class, Settings::class );
101// BH WP Logger doesn't add its own hooks unless we use its singleton.
102$container->singleton(
103    LoggerInterface::class,
104    static function ( Container $_container ) {
105        return new WC_PSR_Logger(
106            new class() implements WC_Logger_Settings_Interface {
107                /**
108                 * Get the plugin slug for logging.
109                 */
110                public function get_plugin_slug(): string {
111                    return 'bh-wp-bitcoin-gateway';
112                }
113
114                /**
115                 * Record all logs from this level and above.
116                 */
117                public function get_log_level(): string {
118                    return LogLevel::DEBUG;
119                }
120            }
121        );
122    }
123);
124
125$container->singleton(
126    JsonMapperInterface::class,
127    static function ( Container $container ) {
128        /** @var JsonMapper_Helper $json_mapper_helper */
129        $json_mapper_helper = $container->get( JsonMapper_Helper::class );
130        return $json_mapper_helper->build();
131    }
132);
133
134// $container->bind( RequestFactoryInterface::class, HttpClient::class );
135// $container->bind( ClientInterface::class, HttpClient::class );
136// $container->bind( Blockchain_API_Interface::class, Blockchain_Info_Api::class );
137$container->bind( Blockchain_API_Interface::class, Blockstream_Info_API::class );
138
139$container->bind( Generate_Address_API_Interface::class, Nimq_API::class );
140$container->bind( Exchange_Rate_API_Interface::class, Bitfinex_API::class );
141
142/** @var BH_WP_Bitcoin_Gateway $app */
143$app = $container->get( BH_WP_Bitcoin_Gateway::class );
144$app->register_hooks();
145
146$GLOBALS['bh_wp_bitcoin_gateway'] = $container->get( API_Interface::class );
147
148/**
149 * @hooked plugins_loaded
150 */
151$boot_integrations = function () use ( $container ): void {
152    /** @var LoggerInterface $logger */
153    $logger = $container->get( LoggerInterface::class );
154
155    /** @var class-string[] $integrations */
156    $integrations = apply_filters(
157        // TODO: How to annotate this to generate documentation?
158        'bh_wp_bitcoin_gateway_integrations',
159        array(
160            WooCommerce_Integration::class,
161            // This relies on the container bindings from the WooCommerce_Integration so is ordered after it, if it
162            // were to fail when being instantiated below, it would fail with a logged warning.
163            Woo_Cancel_Abandoned_Order_Integration::class,
164        )
165    );
166
167    foreach ( $integrations as $integration ) {
168        try {
169            /** @var object $instance */
170            $instance = $container->get( $integration );
171            if ( method_exists( $instance, 'register_hooks' ) ) {
172                $instance->register_hooks();
173            }
174        } catch ( Exception $e ) {
175            $logger->warning(
176                'Error booting {integration} – {error_message}.',
177                array(
178                    'integration'   => $integration,
179                    'error_message' => $e->getMessage(),
180                    'exception'     => $e,
181                )
182            );
183        }
184    }
185};
186add_action( 'plugins_loaded', $boot_integrations, 0 );