PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / trunk
WCPOS – Point of Sale (POS) plugin for WooCommerce vtrunk
1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 1.9.13 1.9.12 1.9.11 1.9.10 1.9.9 All 158 releases
woocommerce-pos / includes / Gateways.php

Gateways.php in WCPOS – Point of Sale (POS) plugin for WooCommerce trunk, at includes/Gateways.php

171 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Loads the POS Payment Gateways.
4 *
5 * @author Paul Kilmurray <paul@kilbot.com>
6 *
7 * @see https://wcpos.com
8 * @package WCPOS\WooCommercePOS
9 */
10
11 namespace WCPOS\WooCommercePOS;
12
13 /**
14 * Gateways class.
15 */
16 class Gateways {
17 /**
18 * Constructor.
19 */
20 public function __construct() {
21 add_filter( 'woocommerce_payment_gateways', array( $this, 'payment_gateways' ) );
22 add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), 99 );
23 }
24
25 /**
26 * Add POS gateways
27 * BEWARE: some gateways/themes/plugins call this very early on every page!!
28 * We cannot guarantee that $wp is set, so we cannot use woocommerce_pos_request.
29 *
30 * @param array $gateways The registered payment gateways.
31 *
32 * @return array
33 */
34 public function payment_gateways( array $gateways ) {
35 global $plugin_page;
36
37 // Early exit for WooCommerce settings, ie: don't show POS gateways.
38 if ( self::should_suppress_pos_gateways( is_admin(), $plugin_page ) ) {
39 return $gateways;
40 }
41
42 // All other cases, the default POS gateways are added.
43 return array_merge(
44 $gateways,
45 array(
46 'WCPOS\WooCommercePOS\Gateways\Cash',
47 'WCPOS\WooCommercePOS\Gateways\Card',
48 )
49 );
50 }
51
52 /**
53 * Decide whether the POS gateways should be withheld from registration.
54 *
55 * Pure policy function: all ambient state is passed in, so it makes no
56 * WordPress calls and reads no globals.
57 *
58 * NOTE: the loose `==` comparison is carried over verbatim from the inline
59 * implementation this was extracted from. `$plugin_page` is a WordPress
60 * global that is commonly `null`, and on PHP 7.4 a loose comparison against
61 * a non-empty string behaves differently from PHP 8 for some falsy values,
62 * so the comparison operator is preserved rather than tightened.
63 *
64 * @param bool $is_admin Result of is_admin() for the current request.
65 * @param mixed $plugin_page The WordPress `$plugin_page` global.
66 *
67 * @return bool True when the POS gateways must not be registered.
68 */
69 public static function should_suppress_pos_gateways( bool $is_admin, $plugin_page ): bool {
70 return $is_admin && 'wc-settings' == $plugin_page;
71 }
72
73 /**
74 * Get available payment POS gateways,
75 * - Order and set default order
76 * - Also going to remove icons from the gateways.
77 *
78 * - NOTE: lots of plugins/themes call this filter and I can't guarantee that $gateways is an array
79 *
80 * @param null|array $gateways The available payment gateways.
81 *
82 * @return null|array The available payment gateways.
83 */
84 public function available_payment_gateways( ?array $gateways ): ?array {
85 // early exit.
86 if ( ! woocommerce_pos_request() ) {
87 return $gateways;
88 }
89
90 // use POS settings.
91 $settings = woocommerce_pos_get_settings( 'payment_gateways' );
92
93 /*
94 * Get all payment gateways.
95 *
96 * NOTE: this reads the public `payment_gateways` property directly rather
97 * than calling the `payment_gateways()` accessor. Preserved verbatim - the
98 * two are not interchangeable in every WooCommerce version.
99 */
100 $all_gateways = WC()->payment_gateways->payment_gateways;
101
102 return self::order_gateways( $all_gateways, $settings );
103 }
104
105 /**
106 * Apply the POS gateway availability, presentation and ordering policy.
107 *
108 * Selects the gateways enabled in the POS `payment_gateways` settings,
109 * overrides each one's title, blanks its icon, forces it enabled and marks the
110 * configured `default_gateway` as chosen, then sorts the result by the
111 * per-gateway `order` setting.
112 *
113 * Free of ambient state - it makes no WordPress calls and reads no globals, so
114 * it can be exercised directly in unit tests. It is NOT side-effect free: the
115 * gateway objects are mutated in place, which in production means the live
116 * `WC()->payment_gateways->payment_gateways` singletons. That is the existing
117 * mechanism (Admin\Orders\Single_Order::add_available_gateways() relies on the
118 * same singleton mutation) and is preserved deliberately.
119 *
120 * NOTE: neither parameter carries a native typehint. Lots of plugins/themes
121 * call the `woocommerce_available_payment_gateways` filter and neither the
122 * gateway list nor the settings shape is guaranteed; a native `array` here
123 * would turn today's warning into an uncatchable TypeError on the payment
124 * path. Behaviour for unexpected shapes is preserved exactly as it was inline.
125 *
126 * @param array $gateways All registered payment gateway objects.
127 * @param array $settings The POS `payment_gateways` settings blob.
128 *
129 * @return array The enabled gateways, keyed by gateway id, in settings order.
130 */
131 public static function order_gateways( $gateways, $settings ): array {
132 $_available_gateways = array();
133
134 foreach ( $gateways as $gateway ) {
135 if ( isset( $settings['gateways'][ $gateway->id ] ) && $settings['gateways'][ $gateway->id ]['enabled'] ) {
136 if ( isset( $settings['gateways'][ $gateway->id ]['title'] ) ) {
137 $gateway->title = $settings['gateways'][ $gateway->id ]['title'];
138 }
139
140 /*
141 * There is an issue over-writing the description field because some gateways use this for info,
142 * eg: Account Funds uses it to show the current balance.
143 */
144 // if ( isset( $settings['gateways'][ $gateway->id ]['description'] ) ) {
145 // $gateway->description = $settings['gateways'][ $gateway->id ]['description'];
146 // }.
147
148 $gateway->icon = '';
149 $gateway->enabled = 'yes';
150 $gateway->chosen = $gateway->id === $settings['default_gateway'];
151
152 $_available_gateways[ $gateway->id ] = $gateway;
153 }
154 }
155
156 /*
157 * Order the available gateways according to the settings.
158 *
159 * Gateways without an explicit order sort after configured gateways.
160 */
161 uksort(
162 $_available_gateways,
163 function ( $a, $b ) use ( $settings ) {
164 return ( $settings['gateways'][ $a ]['order'] ?? PHP_INT_MAX ) <=> ( $settings['gateways'][ $b ]['order'] ?? PHP_INT_MAX );
165 }
166 );
167
168 return $_available_gateways;
169 }
170 }
171