Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
28.57% covered (danger)
28.57%
2 / 7
14.29% covered (danger)
14.29%
1 / 7
20.00% covered (danger)
20.00%
1 / 5
33.33% covered (danger)
33.33%
1 / 3
CRAP
n/a
0 / 0
monokulo_init_gateway_class
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
monokulo_add_gateway_class
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
monokulo_render_reconnect_notice
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
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).
31if ( ! 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 */
68function 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}
81add_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 */
99function monokulo_add_gateway_class( $gateways ) {
100    $gateways[] = 'WC_Gateway_Monokulo';
101    return $gateways;
102}
103add_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 */
112function monokulo_render_reconnect_notice() {
113    if ( class_exists( 'WC_Gateway_Monokulo' ) ) {
114        WC_Gateway_Monokulo::render_reconnect_notice();
115    }
116}
117add_action( 'admin_notices', 'monokulo_render_reconnect_notice' );

Branches

Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once. Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

monokulo_add_gateway_class
99function monokulo_add_gateway_class( $gateways ) {
100    $gateways[] = 'WC_Gateway_Monokulo';
101    return $gateways;
102}
monokulo_init_gateway_class
69    if ( ! class_exists( 'WC_Payment_Gateway' ) ) {
76        return;
79    require_once __DIR__ . '/includes/class-wc-gateway-monokulo.php';
80}
monokulo_render_reconnect_notice
113    if ( class_exists( 'WC_Gateway_Monokulo' ) ) {
114        WC_Gateway_Monokulo::render_reconnect_notice();
115    }
116}
116}