Skip to content

Commit f36f8c5

Browse files
committed
fix: resolve all PHPStan type safety errors
- Fix subscription handlers: static to instance calls, parameter types, undefined methods - Fix gateway classes: exception handling, PHPDoc tags, method signatures, null checks - Fix blocks support: null checks for WC()->cart and wc()->session - Add missing YITH subscription stub methods - Use PaymentStatus constants instead of string literals - Add @phpstan-ignore comments for third-party PHPDoc inconsistencies - Update .gitignore to exclude .phpcs.cache All PHPStan errors resolved.
1 parent 837b0d7 commit f36f8c5

11 files changed

+93
-39
lines changed

src/Features/Subscriptions/WooCommerceSubscriptionsHandler.php

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,18 @@ public function subscription_after_payment_success( $confirm_payload, $confirm_p
8888
/**
8989
* Refund that cent.
9090
*/
91-
MoneiPaymentServices::refund_payment( $confirm_payment->getId(), 1 );
91+
$this->moneiPaymentServices->refund_payment( $confirm_payment->getId(), 1 );
9292
}
9393

9494
/**
9595
* It adds subscription configuration to the payload.
9696
*
97-
* @param $order_id
97+
* @param $order
9898
* @param $payment_method
9999
*
100100
* @return array
101101
*/
102-
public function create_subscription_payload( WC_Order $order_id, $payment_method, $payload ): array {
103-
$order = new WC_Order( $order_id );
102+
public function create_subscription_payload( WC_Order $order, $payment_method, $payload ): array {
104103
$payload['sequence'] = array(
105104
'type' => 'recurring',
106105
'recurring' => array(
@@ -112,7 +111,7 @@ public function create_subscription_payload( WC_Order $order_id, $payment_method
112111
* If there is a free trial, (first payment for free) and user has selected a tokenized card,
113112
* We hit a monei limitation, so we need to charge the customer 1 cent, that will be refunded afterwards.
114113
*/
115-
if ( 0 === monei_price_format( $order->get_total() ) && $this->get_payment_token_id_if_selected() ) {
114+
if ( 0 === monei_price_format( $order->get_total() ) && isset( $payload['paymentToken'] ) ) {
116115
$payload['amount'] = 1;
117116
}
118117

@@ -213,7 +212,7 @@ public function update_subscription_meta_data($subscriptions, $payment): void
213212

214213
public function init_subscriptions( array $supports, string $gateway_id ): array {
215214
add_action( 'wc_gateway_monei_create_payment_success', array( $this, 'subscription_after_payment_success' ), 1, 3 );
216-
add_action( 'woocommerce_scheduled_subscription_payment_' . $gateway_id, array( $this, 'scheduled_subscription_payment' ), 1, 3 );
215+
add_action( 'woocommerce_scheduled_subscription_payment_' . $gateway_id, array( $this, 'scheduled_subscription_payment' ), 1, 2 );
217216

218217
// Add Payment information to Payment method name in "Subscription" Tab.
219218
add_filter( 'woocommerce_my_subscriptions_payment_method', array( $this, 'add_extra_info_to_subscriptions_payment_method_title' ), 10, 2 );
@@ -270,7 +269,7 @@ public function get_parent_for_renewal_order_id( $renewal_order ) {
270269
$subscriptions = wcs_get_subscriptions_for_renewal_order( $renewal_order );
271270
$subscription = array_pop( $subscriptions );
272271

273-
if ( false === $subscription->get_parent_id() ) {
272+
if ( 0 === $subscription->get_parent_id() ) {
274273
$parent_order = null;
275274
} else {
276275
$parent_order = $subscription->get_parent();
@@ -280,9 +279,9 @@ public function get_parent_for_renewal_order_id( $renewal_order ) {
280279
/**
281280
* Retrieves parent order from a subscription order.
282281
*
283-
* @param WC_Subscription $subscription_order
282+
* @param \WCS_Subscription $subscription_order
284283
*
285-
* @return mixed WC_Order|bool
284+
* @return \WC_Order|false
286285
*/
287286
public function get_parent_for_subscription_id( $subscription_order ) {
288287
return $subscription_order->get_parent();
@@ -322,6 +321,6 @@ public function cart_has_subscription() {
322321
if (!$this->is_subscriptions_addon_enabled()) {
323322
return false;
324323
}
325-
return is_array( WC()->cart->recurring_carts ) ? count( WC()->cart->recurring_carts ) : 0;
324+
return is_array( WC()->cart->recurring_carts ) && count( WC()->cart->recurring_carts ) > 0;
326325
}
327326
}

src/Features/Subscriptions/YithSubscriptionPluginHandler.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ public function update_subscription_meta_data( $subscriptions, $payment ): void
8181
*/
8282
foreach ( $subscriptions as $subscription ) {
8383
$subscription = ywsbs_get_subscription( $subscription );
84+
// @phpstan-ignore-next-line
85+
if ( ! $subscription ) {
86+
continue;
87+
}
88+
// @phpstan-ignore-next-line
8489
$meta = array(
8590
'_monei_sequence_id' => $payment->getSequenceId(),
8691
'_monei_payment_method_brand' => $payment->getPaymentMethod()->getCard()->getBrand(),
@@ -131,19 +136,18 @@ public function subscription_after_payment_success( $confirm_payload, $confirm_p
131136
/**
132137
* Refund that cent.
133138
*/
134-
MoneiPaymentServices::refund_payment( $confirm_payment->getId(), 1 );
139+
$this->moneiPaymentServices->refund_payment( $confirm_payment->getId(), 1 );
135140
}
136141

137142
/**
138143
* It adds subscription configuration to the payload.
139144
*
140-
* @param $order_id
145+
* @param $order
141146
* @param $payment_method
142147
*
143148
* @return array
144149
*/
145-
public function create_subscription_payload( WC_Order $order_id, $payment_method, $payload ): array {
146-
$order = new WC_Order( $order_id );
150+
public function create_subscription_payload( WC_Order $order, $payment_method, $payload ): array {
147151
$payload['sequence'] = array(
148152
'type' => 'recurring',
149153
'recurring' => array(
@@ -155,7 +159,7 @@ public function create_subscription_payload( WC_Order $order_id, $payment_method
155159
* If there is a free trial, (first payment for free) and user has selected a tokenized card,
156160
* We hit a monei limitation, so we need to charge the customer 1 cent, that will be refunded afterwards.
157161
*/
158-
if ( 0 === monei_price_format( $order->get_total() ) && $this->get_payment_token_id_if_selected() ) {
162+
if ( 0 === monei_price_format( $order->get_total() ) && isset( $payload['paymentToken'] ) ) {
159163
$payload['amount'] = 1;
160164
}
161165

@@ -250,18 +254,20 @@ public function scheduled_subscription_payment( $amount_to_charge, $renewal_orde
250254
* Get subscription object from renew order
251255
*
252256
* @param \WC_Order $renewal_order The WooCommerce order.
253-
* @return YWSBS_Subscription|bool
257+
* @return \YWSBS_Subscription|false
254258
*/
259+
// @phpstan-ignore-next-line
255260
private function get_subscription_from_renew_order( \WC_Order $renewal_order ) {
256261
$subscriptions = $renewal_order->get_meta( 'subscriptions' );
257262
$subscription_id = ! empty( $subscriptions ) ? array_shift( $subscriptions ) : false; // $subscriptions is always an array of 1 element.
258263

264+
// @phpstan-ignore-next-line
259265
return $subscription_id ? ywsbs_get_subscription( $subscription_id ) : false;
260266
}
261267

262268
public function init_subscriptions( array $supports, string $gateway_id ): array {
263269
add_action( 'wc_gateway_monei_create_payment_success', array( $this, 'subscription_after_payment_success' ), 1, 3 );
264-
add_action( 'woocommerce_scheduled_subscription_payment_' . $gateway_id, array( $this, 'scheduled_subscription_payment' ), 1, 3 );
270+
add_action( 'woocommerce_scheduled_subscription_payment_' . $gateway_id, array( $this, 'scheduled_subscription_payment' ), 1, 2 );
265271

266272
// Add Payment information to Payment method name in "Subscription" Tab.
267273
add_filter( 'woocommerce_my_subscriptions_payment_method', array( $this, 'add_extra_info_to_subscriptions_payment_method_title' ), 10, 2 );

src/Gateways/Abstracts/WCMoneiPaymentGateway.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Monei\Gateways\Abstracts;
44

55
use Exception;
6+
use Monei\Model\PaymentStatus;
67
use Monei\Services\ApiKeyService;
78
use Monei\Services\payment\MoneiPaymentServices;
89
use Monei\Services\PaymentMethodsService;
@@ -18,8 +19,6 @@
1819
/**
1920
* Abstract class that will be inherited by all payment methods.
2021
*
21-
* @extends WC_Payment_Gateway
22-
*
2322
* @since 5.0
2423
*/
2524
abstract class WCMoneiPaymentGateway extends WC_Payment_Gateway {
@@ -160,7 +159,7 @@ protected function is_valid_for_use() {
160159

161160
public function is_available() {
162161
$isEnabled = $this->enabled === 'yes' && $this->is_valid_for_use();
163-
$billingCountry = WC()->customer && ! empty( WC()->customer->get_billing_country() )
162+
$billingCountry = WC()->customer !== null && ! empty( WC()->customer->get_billing_country() )
164163
? WC()->customer->get_billing_country()
165164
: wc_get_base_location()['country'];
166165

@@ -199,7 +198,7 @@ public function admin_options() {
199198
}
200199
return;
201200
}
202-
$methodAvailability = $this->paymentMethodsService->getMethodAvailability( $this->id, $this->getAccountId() );
201+
$methodAvailability = $this->paymentMethodsService->getMethodAvailability( $this->id );
203202
if ( ! $methodAvailability ) {
204203
$template = $this->templateManager->getTemplate( 'notice-admin-gateway-not-enabled-monei' );
205204
if ( $template ) {
@@ -228,7 +227,7 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) {
228227
return false;
229228
}
230229

231-
if ( ! $amount ) {
230+
if ( null === $amount ) {
232231
$amount = $order->get_total();
233232
}
234233

@@ -238,7 +237,9 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) {
238237

239238
$result = $this->moneiPaymentServices->refund_payment( $payment_id, monei_price_format( $amount ) );
240239

241-
if ( 'REFUNDED' === $result->getStatus() || 'PARTIALLY_REFUNDED' === $result->getStatus() ) {
240+
// SDK PHPDoc is misleading - getStatus() returns string, not PaymentStatus object
241+
// @phpstan-ignore-next-line
242+
if ( PaymentStatus::REFUNDED === $result->getStatus() || PaymentStatus::PARTIALLY_REFUNDED === $result->getStatus() ) {
242243

243244
$this->log( $amount . ' Refund approved.', 'debug' );
244245

@@ -296,7 +297,7 @@ protected function get_save_payment_card_checkbox() {
296297
* @return array
297298
*/
298299
protected function add_cart_total_fragments( $fragments ) {
299-
if ( ! WC()->cart ) {
300+
if ( null === WC()->cart ) {
300301
return $fragments;
301302
}
302303

src/Gateways/Abstracts/WCMoneiPaymentGatewayComponent.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Monei\Gateways\Abstracts;
44

55
use Exception;
6+
use Monei\ApiException;
67
use WC_Geolocation;
78
use MoneiPaymentServices;
89
use WC_Order;
@@ -17,7 +18,6 @@
1718
* Abstract class that will be inherited by all integrated components payment methods.
1819
* Class WC_Monei_Payment_Gateway_Component
1920
*
20-
* @extends WCMoneiPaymentGateway
2121
* @since 5.0
2222
*/
2323
abstract class WCMoneiPaymentGatewayComponent extends WCMoneiPaymentGateway {
@@ -97,7 +97,7 @@ public function process_payment( $order_id, $allowed_payment_method = null ) {
9797
'redirect' => $next_action_redirect,
9898
);
9999

100-
} catch ( Exception $e ) {
100+
} catch ( ApiException $e ) {
101101
do_action( 'wc_gateway_monei_process_payment_error', $e, $order );
102102
// Extract and log the responseBody message
103103
$response_body = json_decode( $e->getResponseBody(), true );
@@ -113,6 +113,13 @@ public function process_payment( $order_id, $allowed_payment_method = null ) {
113113
return array(
114114
'result' => 'failure',
115115
);
116+
} catch ( Exception $e ) {
117+
do_action( 'wc_gateway_monei_process_payment_error', $e, $order );
118+
WC_Monei_Logger::log( $e->getMessage(), 'error' );
119+
wc_add_notice( $e->getMessage(), 'error' );
120+
return array(
121+
'result' => 'failure',
122+
);
116123
}
117124
}
118125

src/Gateways/Abstracts/WCMoneiPaymentGatewayHosted.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
* Abstract class that will be inherited by all Hosted payment methods.
1717
* Class WC_Monei_Payment_Gateway_Hosted
1818
*
19-
* @extends WCMoneiPaymentGateway
2019
* @since 5.0
2120
*/
2221
abstract class WCMoneiPaymentGatewayHosted extends WCMoneiPaymentGateway {
@@ -82,7 +81,7 @@ public function process_payment( $order_id, $allowed_payment_method = null ) {
8281
'city' => ( $order->get_billing_city() ) ?: null,
8382
'line1' => ( $order->get_billing_address_1() ) ?: null,
8483
'line2' => ( $order->get_billing_address_2() ) ?: null,
85-
'zip' => ( $order->get_billing_postcode() ) ?? null,
84+
'zip' => ( $order->get_billing_postcode() ) ?: null,
8685
'state' => ( $order->get_billing_state() ) ?: null,
8786
),
8887
),

src/Gateways/Blocks/MoneiAppleGoogleBlocksSupport.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@
44

55
use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
66
use Monei\Gateways\Abstracts\WCMoneiPaymentGateway;
7+
use Monei\Gateways\PaymentMethods\WCGatewayMoneiAppleGoogle;
78

89
final class MoneiAppleGoogleBlocksSupport extends AbstractPaymentMethodType {
910

1011
protected $name = 'monei_apple_google';
12+
/**
13+
* @var WCGatewayMoneiAppleGoogle
14+
*/
1115
public WCMoneiPaymentGateway $gateway;
1216

17+
/**
18+
* @param WCGatewayMoneiAppleGoogle $gateway
19+
*/
1320
public function __construct( WCMoneiPaymentGateway $gateway ) {
1421
$this->gateway = $gateway;
1522
}
@@ -64,7 +71,7 @@ public function get_payment_method_script_handles() {
6471

6572
public function get_payment_method_data() {
6673
$supports = $this->gateway->supports;
67-
$total = isset( WC()->cart ) ? WC()->cart->get_total( false ) : 0;
74+
$total = WC()->cart !== null ? WC()->cart->get_total( false ) : 0;
6875
$isGoogleEnabled = $this->gateway->isGoogleAvailable();
6976
$isAppleEnabled = $this->gateway->isAppleAvailable();
7077
$logoApple = WC_Monei()->plugin_url() . '/public/images/apple-logo.svg';
@@ -81,7 +88,7 @@ public function get_payment_method_data() {
8188
// no: live,
8289
'test_mode' => $this->gateway->getTestmode(),
8390
'accountId' => $this->gateway->getAccountId() ?? false,
84-
'sessionId' => ( wc()->session ) ? wc()->session->get_customer_id() : '',
91+
'sessionId' => wc()->session !== null ? wc()->session->get_customer_id() : '',
8592
'currency' => get_woocommerce_currency(),
8693
'total' => $total,
8794
'language' => locale_iso_639_1_code(),

src/Gateways/Blocks/MoneiMBWayBlocksSupport.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function is_active() {
5858
}
5959

6060
public function get_payment_method_data() {
61-
$total = isset( WC()->cart ) ? WC()->cart->get_total( false ) : 0;
61+
$total = WC()->cart !== null ? WC()->cart->get_total( false ) : 0;
6262
$data = array(
6363

6464
'title' => $this->gateway->title,
@@ -73,10 +73,11 @@ public function get_payment_method_data() {
7373
// no: live,
7474
'test_mode' => $this->gateway->getTestmode() ?? false,
7575
'accountId' => $this->gateway->getAccountId() ?? false,
76-
'sessionId' => ( wc()->session ) ? wc()->session->get_customer_id() : '',
76+
'sessionId' => wc()->session !== null ? wc()->session->get_customer_id() : '',
7777
);
7878

79-
if ( 'yes' === $this->get_setting( 'hide_logo' ) ?? 'no' ) {
79+
$hide_logo = $this->get_setting( 'hide_logo' ) ?? 'no';
80+
if ( 'yes' === $hide_logo ) {
8081

8182
unset( $data['logo'] );
8283

src/Gateways/Blocks/MoneiMultibancoBlocksSupport.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function is_active() {
5959
}
6060

6161
public function get_payment_method_data() {
62-
$total = isset( WC()->cart ) ? WC()->cart->get_total( false ) : 0;
62+
$total = WC()->cart !== null ? WC()->cart->get_total( false ) : 0;
6363
$data = array(
6464

6565
'title' => $this->gateway->title,
@@ -74,10 +74,11 @@ public function get_payment_method_data() {
7474
// no: live,
7575
'test_mode' => $this->gateway->getTestmode() ?? false,
7676
'accountId' => $this->gateway->getAccountId() ?? false,
77-
'sessionId' => ( wc()->session ) ? wc()->session->get_customer_id() : '',
77+
'sessionId' => wc()->session !== null ? wc()->session->get_customer_id() : '',
7878
);
7979

80-
if ( 'yes' === $this->get_setting( 'hide_logo' ) ?? 'no' ) {
80+
$hide_logo = $this->get_setting( 'hide_logo' ) ?? 'no';
81+
if ( 'yes' === $hide_logo ) {
8182

8283
unset( $data['logo'] );
8384

src/Services/MoneiApplePayVerificationService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function expose_on_domain_association_request( $wp ) {
6161
$path = WC_Monei()->plugin_url() . '/' . self::DOMAIN_ASSOCIATION_FILE_NAME;
6262
$args = array( 'headers' => array( 'Content-Type' => 'text/plain;charset=utf-8' ) );
6363
$response = wp_remote_get( $path, $args );
64-
if ( is_array( $response ) && ! is_wp_error( $response ) ) {
64+
if ( ! is_wp_error( $response ) && is_array( $response ) ) {
6565
$body = $response['body'];
6666
echo esc_html( $response['body'] );
6767
}

tests/phpstan-bootstrap.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,14 @@ function locale_iso_639_1_code() {
6161
if ( ! class_exists( 'WC_Monei_IPN' ) ) {
6262
/**
6363
* Mock WC_Monei_IPN class for PHPStan
64+
*
65+
* @param bool $logging
6466
*/
6567
class WC_Monei_IPN {
66-
public function __construct( bool $logging = false ) {}
68+
public function __construct( bool $logging = false ) {
69+
// Stub implementation - parameter kept for signature compatibility
70+
unset( $logging );
71+
}
6772
}
6873
}
6974

0 commit comments

Comments
 (0)