Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
28.57% |
2 / 7 |
|
14.29% |
1 / 7 |
|
20.00% |
1 / 5 |
|
33.33% |
1 / 3 |
CRAP | n/a |
0 / 0 |
|
| monokulo_init_gateway_class | |
0.00% |
0 / 3 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| monokulo_add_gateway_class | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| monokulo_render_reconnect_notice | |
0.00% |
0 / 2 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Plugin Name: Monokulo for WooCommerce |
| 4 | * Plugin URI: https://github.com/monokulo/scanner |
| 5 | * Description: Accept Monero at checkout via Monokulo, the hosted, |
| 6 | * non-custodial payment gateway built on scanner. |
| 7 | * No spend key ever touches this server or ours - only a |
| 8 | * view key, used to watch for incoming payments. |
| 9 | * Version: 0.1.0 |
| 10 | * Requires at least: 6.4 |
| 11 | * Requires PHP: 8.1 |
| 12 | * Requires Plugins: woocommerce |
| 13 | * WC requires at least: 8.0 |
| 14 | * Author: Monokulo |
| 15 | * Author URI: https://github.com/monokulo |
| 16 | * License: GPL-2.0-or-later |
| 17 | * License URI: https://www.gnu.org/licenses/gpl-2.0.html |
| 18 | * Text Domain: monokulo |
| 19 | * Domain Path: /languages |
| 20 | * |
| 21 | * @package Monokulo |
| 22 | */ |
| 23 | |
| 24 | // Exit if accessed directly - this file is a WordPress plugin entry point, |
| 25 | // never meant to be loaded outside a WordPress bootstrap. Every other PHP |
| 26 | // file in this plugin repeats this same guard for the same reason: WordPress |
| 27 | // plugin directories are web-servable by default on many hosts, and without |
| 28 | // this guard a request straight to this file's URL would execute arbitrary |
| 29 | // plugin bootstrap code (harmless here, but the convention exists precisely |
| 30 | // because it *isn't* always harmless across the plugin ecosystem). |
| 31 | if ( ! defined( 'ABSPATH' ) ) { |
| 32 | exit; |
| 33 | } |
| 34 | |
| 35 | /** |
| 36 | * WBS 1.5.1 scope, deliberately: registration only. This bootstrap file's |
| 37 | * entire job is making "Monero (via Monokulo)" appear in WooCommerce's |
| 38 | * list of registered payment gateways - nothing here talks to the engine yet |
| 39 | * (that's 1.5.2's `process_payment()`), and nothing here makes the gateway |
| 40 | * enabled by default (also correct per the WBS's own stated outcome: "disabled |
| 41 | * state is fine at this step"). Every actual payment decision still lives in |
| 42 | * the Rust engine (`scanner`) per `docs/WOOCOMMERCE_ROADMAP.md` Stage 7's |
| 43 | * "PHP is a thin adapter, not a second implementation of anything" framing - |
| 44 | * this file, and the gateway class it loads, are deliberately the thinnest |
| 45 | * possible WordPress-side shim over that engine, not a growing PHP business |
| 46 | * layer. |
| 47 | */ |
| 48 | |
| 49 | /** |
| 50 | * Loads the gateway class and registers it with WooCommerce. |
| 51 | * |
| 52 | * Deferred to the `plugins_loaded` hook rather than run at the top level of |
| 53 | * this file for a concrete reason, not just convention: `WC_Gateway_Monokulo` |
| 54 | * (in includes/class-wc-gateway-monokulo.php) `extends WC_Payment_Gateway`, |
| 55 | * a class WooCommerce itself defines. WordPress loads plugins in an |
| 56 | * unspecified order relative to each other, so if this plugin happens to load |
| 57 | * before WooCommerce does, `class WC_Payment_Gateway` wouldn't exist yet and |
| 58 | * the `extends` would be a fatal error. `plugins_loaded` is the first hook |
| 59 | * every active plugin is guaranteed to have already been `require`d by, so by |
| 60 | * the time this callback runs, WooCommerce's own classes are available |
| 61 | * regardless of which plugin's row in `wp_options` happened to load first. |
| 62 | * The `Requires Plugins: woocommerce` header above (a WordPress 6.5+ |
| 63 | * mechanism) additionally stops this plugin from activating at all if |
| 64 | * WooCommerce isn't installed, but that only prevents *activation* - it |
| 65 | * doesn't reorder *load* order between two already-active plugins, so this |
| 66 | * hook is still the right guard even with that header present. |
| 67 | */ |
| 68 | function monokulo_init_gateway_class() { |
| 69 | if ( ! class_exists( 'WC_Payment_Gateway' ) ) { |
| 70 | // WooCommerce isn't active. Fail silently rather than fatal - the |
| 71 | // `Requires Plugins` header (WP 6.5+) already stops a fresh activation |
| 72 | // in this state, but an older WordPress core, or WooCommerce being |
| 73 | // deactivated *after* this plugin was already active, both reach this |
| 74 | // function without that guard having fired. Nothing downstream of this |
| 75 | // early return runs, so there's nothing left to register. |
| 76 | return; |
| 77 | } |
| 78 | |
| 79 | require_once __DIR__ . '/includes/class-wc-gateway-monokulo.php'; |
| 80 | } |
| 81 | add_action( 'plugins_loaded', 'monokulo_init_gateway_class' ); |
| 82 | |
| 83 | /** |
| 84 | * Adds `WC_Gateway_Monokulo` to WooCommerce's list of available gateway |
| 85 | * classes via the standard `woocommerce_payment_gateways` filter - this is |
| 86 | * the actual registration mechanism WooCommerce documents for third-party |
| 87 | * gateways (WooCommerce itself iterates this filter's return value and |
| 88 | * instantiates every class name / object in it), confirmed against |
| 89 | * WooCommerce's own `WC_Payment_Gateways::init()` source |
| 90 | * (`class-wc-payment-gateways.php`) rather than assumed from memory - see |
| 91 | * this plugin's `tests/GatewayRegistrationTest.php` for the reasoning |
| 92 | * behind exactly which of WooCommerce's own two gateway-listing methods this |
| 93 | * plugin's test asserts against, and why. |
| 94 | * |
| 95 | * @param string[] $gateways Fully-qualified class names (or gateway instances) |
| 96 | * WooCommerce will offer at checkout. |
| 97 | * @return string[] The same list, with this plugin's gateway appended. |
| 98 | */ |
| 99 | function monokulo_add_gateway_class( $gateways ) { |
| 100 | $gateways[] = 'WC_Gateway_Monokulo'; |
| 101 | return $gateways; |
| 102 | } |
| 103 | add_filter( 'woocommerce_payment_gateways', 'monokulo_add_gateway_class' ); |
| 104 | |
| 105 | /** |
| 106 | * Tells WooCommerce managers, on every admin screen, when this store was |
| 107 | * connected by an older plugin version and must reconnect before it can |
| 108 | * take Monero payments again (see `WC_Gateway_Monokulo::CONNECTION_VERSION`). |
| 109 | * Hooked here rather than in the gateway's constructor so it shows whether |
| 110 | * or not WooCommerce builds its gateways on the current request. |
| 111 | */ |
| 112 | function monokulo_render_reconnect_notice() { |
| 113 | if ( class_exists( 'WC_Gateway_Monokulo' ) ) { |
| 114 | WC_Gateway_Monokulo::render_reconnect_notice(); |
| 115 | } |
| 116 | } |
| 117 | add_action( 'admin_notices', 'monokulo_render_reconnect_notice' ); |
Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 99 | function monokulo_add_gateway_class( $gateways ) { |
| 100 | $gateways[] = 'WC_Gateway_Monokulo'; |
| 101 | return $gateways; |
| 102 | } |
| 69 | if ( ! class_exists( 'WC_Payment_Gateway' ) ) { |
| 76 | return; |
| 69 | if ( ! class_exists( 'WC_Payment_Gateway' ) ) { |
| 79 | require_once __DIR__ . '/includes/class-wc-gateway-monokulo.php'; |
| 80 | } |
| 113 | if ( class_exists( 'WC_Gateway_Monokulo' ) ) { |
| 114 | WC_Gateway_Monokulo::render_reconnect_notice(); |
| 115 | } |
| 116 | } |
| 116 | } |
| 113 | if ( class_exists( 'WC_Gateway_Monokulo' ) ) { |
| 116 | } |