Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix QIT errors reported by PHPStan #8845

Merged
merged 25 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
faefc81
avoid unnecessary recursion for the update_account_data method
timur27 May 21, 2024
e7aaf6c
check for class existence before using it
timur27 May 21, 2024
541f663
[phpstan-ignore] ignore checks in Blocks_Data_Extractor
timur27 May 21, 2024
a31fcc4
add class variable in WC_Payments_Email_Failed_Authentication_Retry
timur27 May 23, 2024
53a8480
replace the logger
timur27 May 23, 2024
f0c8120
Merge branch 'develop' of github.com:Automattic/woocommerce-payments …
timur27 May 23, 2024
21917c5
another round of fixes
timur27 May 23, 2024
f96fc04
ignore static class creation notice from PHPStan
timur27 May 24, 2024
88c928c
over Name Your Price compatibility class by resolving PHPStan notices…
timur27 May 24, 2024
0686b33
product add-ons fixes
timur27 May 24, 2024
c96082c
fix notices in WooPay package
timur27 May 24, 2024
d26ae4b
fix PHPStan errors in the newer src directory
timur27 May 24, 2024
ceff2ed
replace an inner named function with a static class method
timur27 May 24, 2024
a628eda
replace an inner named function with a static class method
timur27 May 24, 2024
bbae881
Merge branch 'develop' into fix/phpstan-errors
timur27 May 24, 2024
9a12f98
add changelog entry and small lint fixes
timur27 May 24, 2024
1bd87b0
more linting fixes
timur27 May 24, 2024
e0f96bf
misc
timur27 May 24, 2024
5a62032
Merge branch 'develop' into fix/phpstan-errors
timur27 May 24, 2024
760e0e5
Merge branch 'develop' into fix/phpstan-errors
timur27 May 28, 2024
888b7de
Merge branch 'develop' into fix/phpstan-errors
timur27 Jun 3, 2024
6eee3a6
update QIT docs
timur27 Jun 3, 2024
cec51f7
fix typo
timur27 Jun 3, 2024
a606708
Merge branch 'develop' of github.com:Automattic/woocommerce-payments …
timur27 Jun 3, 2024
50b6290
resolve conflicts
timur27 Jun 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/fix-phpstan-errors
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: dev

Fix PHPStan warnings.
12 changes: 1 addition & 11 deletions includes/class-wc-payments-account.php
Original file line number Diff line number Diff line change
Expand Up @@ -1675,7 +1675,7 @@ function () {
*
* @return void
*/
public function update_cached_account_data( $property, $data ) {
public function update_account_data( $property, $data ) {
$account_data = $this->database_cache->get( Database_Cache::ACCOUNT_KEY );

$account_data[ $property ] = is_array( $data ) ? array_merge( $account_data[ $property ] ?? [], $data ) : $data;
Expand All @@ -1692,16 +1692,6 @@ public function refresh_account_data() {
return $this->get_cached_account_data( true );
}

/**
* Updates the account data.
*
* @param string $property Property to update.
* @param mixed $data Data to update.
*/
public function update_account_data( $property, $data ) {
return $this->update_cached_account_data( $property, $data );
}

/**
* Checks if the cached account can be used in the current plugin state.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ public function get_product_price( $product, ?bool $is_deposit = null, int $depo
}

// If WooCommerce Deposits is active, we need to get the correct price for the product.
if ( class_exists( 'WC_Deposits_Product_Manager' ) && WC_Deposits_Product_Manager::deposits_enabled( $product->get_id() ) ) {
if ( class_exists( 'WC_Deposits_Product_Manager' ) && class_exists( 'WC_Deposits_Plans_Manager' ) && WC_Deposits_Product_Manager::deposits_enabled( $product->get_id() ) ) {
// If is_deposit is null, we use the default deposit type for the product.
if ( is_null( $is_deposit ) ) {
$is_deposit = 'deposit' === WC_Deposits_Product_Manager::get_deposit_selected_type( $product->get_id() );
Expand Down
52 changes: 26 additions & 26 deletions includes/class-wc-payments.php
Original file line number Diff line number Diff line change
Expand Up @@ -1437,37 +1437,37 @@ public static function add_woo_admin_notes() {
}

if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '7.5', '<' ) && get_woocommerce_currency() === 'NOK' ) {
/**
* Shows an alert notice for Norwegian merchants on WooCommerce 7.4 and below
*/
function wcpay_show_old_woocommerce_for_norway_notice() {
?>
<div class="notice wcpay-notice notice-error">
<p>
<?php
echo WC_Payments_Utils::esc_interpolated_html( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
sprintf(
/* translators: %1$s: WooCommerce, %2$s: WooPayments, a1: documentation URL */
__( 'The %1$s version you have installed is not compatible with %2$s for a Norwegian business. Please update %1$s to version 7.5 or above. You can do that via the <a1>the plugins page.</a1>', 'woocommerce-payments' ),
'WooCommerce',
'WooPayments'
),
[
'a1' => '<a href="' . esc_url( admin_url( 'plugins.php' ) ) . '">',
]
)
?>
</p>
</div>
<?php
}

add_filter( 'admin_notices', 'wcpay_show_old_woocommerce_for_norway_notice' );
add_filter( 'admin_notices', [ __CLASS__, 'wcpay_show_old_woocommerce_for_norway_notice' ] );
}

add_filter( 'admin_notices', [ __CLASS__, 'wcpay_show_old_woocommerce_for_hungary_sweden_and_czech_republic' ] );
}

/**
* Shows an alert notice for Norwegian merchants on WooCommerce 7.4 and below
*/
public static function wcpay_show_old_woocommerce_for_norway_notice() {
?>
<div class="notice wcpay-notice notice-error">
<p>
<?php
echo WC_Payments_Utils::esc_interpolated_html( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
sprintf(
/* translators: %1$s: WooCommerce, %2$s: WooPayments, a1: documentation URL */
__( 'The %1$s version you have installed is not compatible with %2$s for a Norwegian business. Please update %1$s to version 7.5 or above. You can do that via the <a1>the plugins page.</a1>', 'woocommerce-payments' ),
'WooCommerce',
'WooPayments'
),
[
'a1' => '<a href="' . esc_url( admin_url( 'plugins.php' ) ) . '">',
]
)
?>
</p>
</div>
<?php
}

/**
* Removes WCPay notes from the WC-Admin inbox.
*/
Expand Down
4 changes: 4 additions & 0 deletions includes/compat/blocks/class-blocks-data-extractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ private function get_available_blocks() {
// phpcs:ignore
/**
* @psalm-suppress UndefinedClass
* @phpstan-ignore-next-line
*/
$blocks[] = new \Automatewoo\Blocks\Marketing_Optin_Block();
}
Expand All @@ -53,6 +54,7 @@ private function get_available_blocks() {
// phpcs:ignore
/**
* @psalm-suppress UndefinedClass
* @phpstan-ignore-next-line
*/
$blocks[] = new \Mailchimp_Woocommerce_Newsletter_Blocks_Integration();
}
Expand Down Expand Up @@ -96,11 +98,13 @@ private function get_mailpoet_data() {
* We check whether relevant MailPoet classes exists before invoking this method.
*
* @psalm-suppress UndefinedClass
* @phpstan-ignore-next-line
*/
$mailpoet_wc_subscription = \MailPoet\DI\ContainerWrapper::getInstance()->get( \MailPoet\WooCommerce\Subscription::class );
// phpcs:ignore
/**
* @psalm-suppress UndefinedClass
* @phpstan-ignore-next-line
*/
$settings_instance = \MailPoet\Settings\SettingsController::getInstance();
$settings = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* @package WooCommerce\Payments
*/

use WCPay\Logger;

if ( ! defined( 'ABSPATH' ) ) {
exit;
}
Expand All @@ -18,6 +20,13 @@
*/
class WC_Payments_Email_Failed_Authentication_Retry extends WC_Email_Failed_Order {

/**
* The details of the last retry (if any) recorded for a given order
*
* @var WCS_Retry
*/
private $retry;

/**
* Constructor
*/
Expand Down Expand Up @@ -71,7 +80,7 @@ public function trigger( $order_id, $order = null ) {
$this->retry = WCS_Retry_Manager::store()->get_last_retry_for_order( wcs_get_objects_property( $order, 'id' ) );
$this->replace['retry-time'] = wcs_get_human_time_diff( $this->retry->get_time() );
} else {
WC_Stripe_Logger::log( 'WCS_Retry_Manager class or does not exist. Not able to send admin email about customer notification for authentication required for renewal payment.' );
Logger::log( 'WCS_Retry_Manager class or does not exist. Not able to send admin email about customer notification for authentication required for renewal payment.' );
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ abstract protected function prepare_payment_information( $order );
*/
private static $has_attached_integration_hooks = false;

/**
* Used to temporary keep the state of the order_pay value on the Pay for order page with the SCA authorization flow.
* For more details, see remove_order_pay_var and restore_order_pay_var hooks.
*
* @var string|int
*/
private $order_pay_var;

/**
* Initialize subscription support and hooks.
*/
Expand Down Expand Up @@ -941,7 +949,9 @@ public function get_mandate_params_for_order( WC_Order $order ): array {
if ( 1 < count( $subscriptions ) ) {
$result['card']['mandate_options']['amount_type'] = 'maximum';
$result['card']['mandate_options']['interval'] = 'sporadic';
unset( $result['card']['mandate_options']['interval_count'] );
if ( isset( $result['card']['mandate_options']['interval_count'] ) ) {
unset( $result['card']['mandate_options']['interval_count'] );
}
}

return $result;
Expand Down
2 changes: 2 additions & 0 deletions includes/constants/class-base-constant.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ public static function search( string $value ) {
*/
public static function __callStatic( $name, $arguments ) {
if ( ! isset( static::$object_cache[ $name ] ) ) {
// Instantiating constants by class name using the 'new static($name)' approach is integral to this method's functionality.
// @phpstan-ignore-next-line.
static::$object_cache[ $name ] = new static( $name );
}
return static::$object_cache[ $name ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ public function get_product_price( $product, ?bool $is_deposit = null, int $depo
}

// If WooCommerce Deposits is active, we need to get the correct price for the product.
if ( class_exists( 'WC_Deposits_Product_Manager' ) && WC_Deposits_Product_Manager::deposits_enabled( $product->get_id() ) ) {
if ( class_exists( 'WC_Deposits_Product_Manager' ) && class_exists( 'WC_Deposits_Plans_Manager' ) && WC_Deposits_Product_Manager::deposits_enabled( $product->get_id() ) ) {
if ( is_null( $is_deposit ) ) {
/**
* If is_deposit is null, we use the default deposit type for the product.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function add_initial_currency( $cart_item, $product_id, $variation_id ) {

$nyp_id = $variation_id ? $variation_id : $product_id;

if ( \WC_Name_Your_Price_Helpers::is_nyp( $nyp_id ) && isset( $cart_item['nyp'] ) ) {
if ( class_exists( '\WC_Name_Your_Price_Helpers' ) && \WC_Name_Your_Price_Helpers::is_nyp( $nyp_id ) && isset( $cart_item['nyp'] ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check makes sense since we were assuming the Name Your Price plugin would always have the helper class when it may not.

$currency = $this->multi_currency->get_selected_currency();
$cart_item['nyp_currency'] = $currency->get_code();
$cart_item['nyp_original'] = $cart_item['nyp'];
Expand Down Expand Up @@ -102,6 +102,7 @@ public function convert_cart_currency( $cart_item, $values ) {
$cart_item['nyp'] = $this->multi_currency->get_raw_conversion( $raw_price, $selected_currency->get_code(), $from_currency );
}

// @phpstan-ignore-next-line.
$cart_item = WC_Name_Your_Price()->cart->set_cart_item( $cart_item );
}

Expand Down Expand Up @@ -130,7 +131,7 @@ public function should_convert_product_price( bool $return, $product ): bool {
}

// Check to see if the product is a NYP product.
if ( \WC_Name_Your_Price_Helpers::is_nyp( $product ) ) {
if ( class_exists( '\WC_Name_Your_Price_Helpers' ) && \WC_Name_Your_Price_Helpers::is_nyp( $product ) ) {
return false;
}

Expand Down
20 changes: 12 additions & 8 deletions includes/multi-currency/Compatibility/WooCommerceProductAddOns.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,10 @@ public function get_item_data( $addon_data, $addon, $cart_item ): array {
// Quantity/multiplier add on needs to be split, calculated, then multiplied by input value.
$price = $this->multi_currency->get_price( $addon['price'] / $addon['value'], 'product' ) * $addon['value'];
}
$price = \WC_Product_Addons_Helper::get_product_addon_price_for_display( $price, $cart_item['data'] );
$name .= ' (' . wc_price( $price ) . ')';
if ( class_exists( '\WC_Product_Addons_Helper' ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check makes sense since we were assuming the Product Addons plugin would always have the helper class when it may not.

$price = \WC_Product_Addons_Helper::get_product_addon_price_for_display( $price, $cart_item['data'] );
$name .= ' (' . wc_price( $price ) . ')';
}
} else {
// Get the percentage cost in the currency in use, and set the meta data on the product that the value was converted.
$_product = wc_get_product( $cart_item['product_id'] );
Expand Down Expand Up @@ -245,12 +247,14 @@ public function order_line_item_meta( array $meta_data, array $addon, \WC_Order_
// Convert all others.
$addon_price = $this->multi_currency->get_price( $addon['price'], 'product' );
}
$price = html_entity_decode(
wp_strip_all_tags( wc_price( \WC_Product_Addons_Helper::get_product_addon_price_for_display( $addon_price, $values['data'] ) ) ),
ENT_QUOTES,
get_bloginfo( 'charset' )
);
$addon['name'] .= ' (' . $price . ')';
if ( class_exists( '\WC_Product_Addons_Helper' ) ) {
$price = html_entity_decode(
wp_strip_all_tags( wc_price( \WC_Product_Addons_Helper::get_product_addon_price_for_display( $addon_price, $values['data'] ) ) ),
ENT_QUOTES,
get_bloginfo( 'charset' )
);
$addon['name'] .= ' (' . $price . ')';
}
}

if ( 'custom_price' === $addon['field_type'] ) {
Expand Down
23 changes: 14 additions & 9 deletions includes/woopay/class-woopay-adapted-extensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public function get_extension_data() {
];
}

if ( $this->is_affiliate_for_woocommerce_enabled() ) {
if ( $this->is_affiliate_for_woocommerce_enabled() && function_exists( 'afwc_get_referrer_id' ) ) {
/**
* Suppress psalm warning.
*
Expand Down Expand Up @@ -207,12 +207,14 @@ public function update_order_extension_data( $order_id ) {
) {
$affiliate_id = (int) wc_clean( wp_unslash( $_GET['affiliate'] ) ); // phpcs:ignore WordPress.Security.NonceVerification

// phpcs:ignore
/**
* @psalm-suppress UndefinedClass
*/
$affiliate_api = \AFWC_API::get_instance();
$affiliate_api->track_conversion( $order_id, $affiliate_id, '', [ 'is_affiliate_eligible' => true ] );
if ( class_exists( '\AFWC_API' ) ) {
// phpcs:ignore
/**
* @psalm-suppress UndefinedClass
*/
$affiliate_api = \AFWC_API::get_instance();
$affiliate_api->track_conversion( $order_id, $affiliate_id, '', [ 'is_affiliate_eligible' => true ] );
}
}
}

Expand Down Expand Up @@ -272,7 +274,10 @@ class_exists( '\AutomateWoo\Referrals\Referral_Manager' ) &&
* @return string|null
*/
private function get_automate_woo_advocate_id_from_cookie() {
$advocate_from_key_cookie = \AutomateWoo\Referrals\Referral_Manager::get_advocate_key_from_cookie();
return $advocate_from_key_cookie ? $advocate_from_key_cookie->get_advocate_id() : null;
if ( class_exists( '\AutomateWoo\Referrals\Referral_Manager' ) ) {
$advocate_from_key_cookie = \AutomateWoo\Referrals\Referral_Manager::get_advocate_key_from_cookie();
return $advocate_from_key_cookie ? $advocate_from_key_cookie->get_advocate_id() : null;
}
return null;
}
}
1 change: 1 addition & 0 deletions includes/woopay/class-woopay-store-api-token.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public function get_args() {
* @psalm-suppress UndefinedMethod
*/
public function get_cart_token() {
// @phpstan-ignore-next-line.
return parent::get_cart_token();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine to ignore 👍.

LGTM.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ricardo

}
}
Expand Down
10 changes: 6 additions & 4 deletions src/Internal/Payment/State/AbstractPaymentState.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public function get_context(): PaymentContext {
* @throws PaymentRequestException When data is not available or invalid.
*/
public function start_processing( PaymentRequest $request ) {
// @phpstan-ignore-next-line
$this->throw_unavailable_method_exception( __METHOD__ );
}

Expand All @@ -92,6 +93,7 @@ public function start_processing( PaymentRequest $request ) {
* @throws StateTransitionException
*/
public function complete_processing() {
// @phpstan-ignore-next-line
$this->throw_unavailable_method_exception( __METHOD__ );
}
// phpcs:enable Squiz.Commenting.FunctionComment.InvalidNoReturn
Expand All @@ -103,15 +105,15 @@ public function complete_processing() {
* This method should only be called whenever the process is ready to transition
* to the next state, as each new state will be considered the payment's latest one.
*
* @template ConcreteState
* @param class-string<ConcreteState> | string $state_class The class of the state to crate.
* @template ConcreteState of AbstractPaymentState
* @param class-string<ConcreteState> $state_class The class of the state to create.
*
* @return AbstractPaymentState | ConcreteState
* @return ConcreteState The generated payment state instance.
*
* @throws StateTransitionException In case the new state could not be created.
* @throws ContainerException When the dependency container cannot instantiate the state.
*/
protected function create_state( string $state_class ) {
protected function create_state( /*class-string<ConcreteState>*/ $state_class ): AbstractPaymentState {
$state = $this->state_factory->create_state( $state_class, $this->context );

// This is where logging will be added.
Expand Down
10 changes: 5 additions & 5 deletions src/Internal/Payment/State/StateFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ public function __construct( Container $container ) {
/**
* Creates a new state based on class name.
*
* @template ConcreteState
* @param class-string<ConcreteState> | string $state_class Name of the state class.
* @param PaymentContext $context Context for the new state.
* @template ConcreteState of AbstractPaymentState
* @param class-string<ConcreteState> $state_class Name of the state class.
* @param PaymentContext $context Context for the new state.
*
* @return AbstractPaymentState | ConcreteState The generated payment state instance.
* @return ConcreteState The generated payment state instance.
* @throws ContainerException When the dependency container cannot instantiate the state.
* @throws StateTransitionException When the class name is not a state.
*/
public function create_state( string $state_class, PaymentContext $context ): AbstractPaymentState {
public function create_state( /*class-string<ConcreteState>*/ $state_class, PaymentContext $context ): AbstractPaymentState {
if ( ! is_subclass_of( $state_class, AbstractPaymentState::class ) ) {
throw new StateTransitionException(
esc_html(
Expand Down
Loading
Loading