Skip to content

Commit fbe5b88

Browse files
authored
Revalidate incompatible extensions when an extension is activated or deactivate (#6608)
1 parent 788bf41 commit fbe5b88

File tree

6 files changed

+243
-82
lines changed

6 files changed

+243
-82
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: add
3+
4+
Check for invalid extensions when one is activated or deactivated.

includes/admin/class-wc-rest-payments-settings-controller.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ public function get_settings(): WP_REST_Response {
386386
'is_saved_cards_enabled' => $this->wcpay_gateway->is_saved_cards_enabled(),
387387
'is_card_present_eligible' => $this->wcpay_gateway->is_card_present_eligible(),
388388
'is_woopay_enabled' => 'yes' === $this->wcpay_gateway->get_option( 'platform_checkout' ),
389-
'show_woopay_incompatibility_notice' => get_option( 'woopay_disabled_invalid_extensions', false ),
389+
'show_woopay_incompatibility_notice' => get_option( 'woopay_invalid_extension_found', false ),
390390
'woopay_custom_message' => $this->wcpay_gateway->get_option( 'platform_checkout_custom_message' ),
391391
'woopay_store_logo' => $this->wcpay_gateway->get_option( 'platform_checkout_store_logo' ),
392392
'woopay_enabled_locations' => $this->wcpay_gateway->get_option( 'platform_checkout_button_locations', [] ),

includes/class-wc-payments.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ public static function init() {
476476
self::$woopay_tracker = new WooPay_Tracker( self::get_wc_payments_http() );
477477
self::$incentives_service = new WC_Payments_Incentives_Service( self::$database_cache );
478478

479-
( new WooPay_Scheduler() )->init();
479+
( new WooPay_Scheduler( self::$api_client ) )->init();
480480

481481
self::$legacy_card_gateway = new CC_Payment_Gateway( self::$api_client, self::$account, self::$customer_service, self::$token_service, self::$action_scheduler_service, self::$failed_transaction_rate_limiter, self::$order_service );
482482

includes/wc-payment-api/class-wc-payments-api-client.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ class WC_Payments_API_Client {
3838

3939
const ACCOUNTS_API = 'accounts';
4040
const CAPABILITIES_API = 'accounts/capabilities';
41-
const WOOPAY_API = 'accounts/platform_checkout';
41+
const WOOPAY_ACCOUNTS_API = 'accounts/platform_checkout';
42+
const WOOPAY_COMPATIBILITY_API = 'woopay/compatibility';
4243
const APPLE_PAY_API = 'apple_pay';
4344
const CHARGES_API = 'charges';
4445
const CONN_TOKENS_API = 'terminal/connection_tokens';
@@ -838,7 +839,7 @@ public function get_woopay_eligibility() {
838839
[
839840
'test_mode' => WC_Payments::mode()->is_dev(), // only send a test mode request if in dev mode.
840841
],
841-
self::WOOPAY_API,
842+
self::WOOPAY_ACCOUNTS_API,
842843
self::GET
843844
);
844845
}
@@ -858,7 +859,7 @@ public function update_woopay( $data ) {
858859
[ 'test_mode' => WC_Payments::mode()->is_dev() ],
859860
$data
860861
),
861-
self::WOOPAY_API,
862+
self::WOOPAY_ACCOUNTS_API,
862863
self::POST
863864
);
864865
}
@@ -2390,4 +2391,19 @@ public function get_authorizations_summary() {
23902391
public function get_authorization( string $payment_intent_id ) {
23912392
return $this->request( [], self::AUTHORIZATIONS_API . '/' . $payment_intent_id, self::GET );
23922393
}
2394+
2395+
/**
2396+
* Gets the list of extensions that are incompatible with WooPay.
2397+
*
2398+
* @return array of extensions.
2399+
* @throws API_Exception When request fails.
2400+
*/
2401+
public function get_woopay_incompatible_extensions() {
2402+
return $this->request(
2403+
[],
2404+
self::WOOPAY_COMPATIBILITY_API,
2405+
self::GET,
2406+
false
2407+
);
2408+
}
23932409
}

includes/woopay/class-woopay-scheduler.php

Lines changed: 85 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace WCPay\WooPay;
99

10+
use WC_Payments_API_Client;
1011
use WCPay\Logger;
1112

1213
/**
@@ -15,12 +16,34 @@
1516
*/
1617
class WooPay_Scheduler {
1718

19+
const INVALID_EXTENSIONS_FOUND_OPTION_NAME = 'woopay_invalid_extension_found';
20+
const INCOMPATIBLE_EXTENSIONS_LIST_OPTION_NAME = 'woopay_incompatible_extensions';
21+
22+
/**
23+
* WC_Payments_API_Client instance.
24+
*
25+
* @var WC_Payments_API_Client
26+
*/
27+
private $payments_api_client;
28+
29+
/**
30+
* Constructor.
31+
*
32+
* @param WC_Payments_API_Client $payments_api_client The Payments API Client.
33+
* @return void
34+
*/
35+
public function __construct( WC_Payments_API_Client $payments_api_client ) {
36+
$this->payments_api_client = $payments_api_client;
37+
}
38+
1839
/**
1940
* Init the hooks.
2041
*/
2142
public function init() {
2243
add_action( 'init', [ $this, 'schedule' ] );
23-
add_action( 'validate_incompatible_extensions', [ $this, 'disable_woopay_if_incompatible_extension_active' ] );
44+
add_action( 'validate_incompatible_extensions', [ $this, 'update_incompatible_extensions_list_and_maybe_show_warning' ] );
45+
add_action( 'activated_plugin', [ $this, 'show_warning_when_incompatible_extension_is_enabled' ] );
46+
add_action( 'deactivated_plugin', [ $this, 'hide_warning_when_incompatible_extension_is_disabled' ] );
2447

2548
register_deactivation_hook( WCPAY_PLUGIN_FILE, [ $this, 'remove_scheduler' ] );
2649
}
@@ -42,29 +65,78 @@ public function schedule() {
4265
}
4366

4467
/**
45-
* Disables WooPay if an incompatible extension is active
68+
* Updates the list of incompatible extensions.
4669
*/
47-
public function disable_woopay_if_incompatible_extension_active() {
70+
public function update_incompatible_extensions_list_and_maybe_show_warning() {
4871
try {
4972
$incompatible_extensions = $this->get_incompatible_extensions();
73+
$active_plugins = get_option( 'active_plugins', [] );
5074

51-
$active_plugins = get_option( 'active_plugins' );
52-
delete_option( 'woopay_disabled_invalid_extensions' );
75+
update_option( self::INCOMPATIBLE_EXTENSIONS_LIST_OPTION_NAME, $incompatible_extensions );
76+
delete_option( self::INVALID_EXTENSIONS_FOUND_OPTION_NAME );
5377

5478
if ( ! empty( $active_plugins ) && is_array( $active_plugins ) ) {
55-
foreach ( $active_plugins as $plugin ) {
56-
$plugin = $this->format_extension_name( $plugin );
57-
58-
if ( in_array( $plugin, $incompatible_extensions, true ) ) {
59-
update_option( 'woopay_disabled_invalid_extensions', true );
60-
}
79+
if ( $this->contains_incompatible_extension( $active_plugins, $incompatible_extensions ) ) {
80+
update_option( self::INVALID_EXTENSIONS_FOUND_OPTION_NAME, true );
6181
}
6282
}
6383
} catch ( \Exception $e ) {
6484
Logger::error( 'Failed to decode WooPay incompatible extensions list. ' . $e );
6585
}
6686
}
6787

88+
/**
89+
* Adds a warning to the WC Payments settings page.
90+
*
91+
* @param string $plugin The plugin being enabled.
92+
*/
93+
public function show_warning_when_incompatible_extension_is_enabled( $plugin ) {
94+
$incompatible_extensions = get_option( self::INCOMPATIBLE_EXTENSIONS_LIST_OPTION_NAME, [] );
95+
$plugin = $this->format_extension_name( $plugin );
96+
97+
if ( $this->contains_incompatible_extension( [ $plugin ], $incompatible_extensions ) ) {
98+
update_option( self::INVALID_EXTENSIONS_FOUND_OPTION_NAME, true );
99+
}
100+
}
101+
102+
/**
103+
* Removes the warning when the last incompatible extension is removed.
104+
*
105+
* @param string $plugin_being_deactivated The plugin name.
106+
*/
107+
public function hide_warning_when_incompatible_extension_is_disabled( $plugin_being_deactivated ) {
108+
$incompatible_extensions = get_option( self::INCOMPATIBLE_EXTENSIONS_LIST_OPTION_NAME, [] );
109+
$active_plugins = get_option( 'active_plugins', [] );
110+
111+
// Needs to remove the plugin being deactivated because WordPress only updates the list after this hook runs.
112+
$active_plugins = array_diff( $active_plugins, [ $plugin_being_deactivated ] );
113+
114+
// Only deactivates the warning if there are no other incompatible extensions.
115+
if ( ! $this->contains_incompatible_extension( $active_plugins, $incompatible_extensions ) ) {
116+
delete_option( self::INVALID_EXTENSIONS_FOUND_OPTION_NAME );
117+
}
118+
}
119+
120+
/**
121+
* Checks if there is any incompatible extension in the list.
122+
*
123+
* @param mixed $active_plugins list of active plugins.
124+
* @param mixed $incompatible_extensions list of incompatible extensions.
125+
*
126+
* @return bool
127+
*/
128+
public function contains_incompatible_extension( $active_plugins, $incompatible_extensions ) {
129+
foreach ( $active_plugins as $plugin ) {
130+
$plugin = $this->format_extension_name( $plugin );
131+
132+
if ( in_array( $plugin, $incompatible_extensions, true ) ) {
133+
return true;
134+
}
135+
}
136+
137+
return false;
138+
}
139+
68140
/**
69141
* Removes the folder and file extension from the plugin name.
70142
*
@@ -83,34 +155,8 @@ private function format_extension_name( $plugin ) {
83155
* @return array
84156
*/
85157
public function get_incompatible_extensions() {
86-
$args = [
87-
'url' => WooPay_Utilities::get_woopay_rest_url( 'extensions/incompatible' ),
88-
'method' => 'GET',
89-
'timeout' => 30,
90-
'headers' => [
91-
'Content-Type' => 'application/json',
92-
],
93-
];
94-
95-
/**
96-
* Suppress psalm error from Jetpack Connection namespacing WP_Error.
97-
*
98-
* @psalm-suppress UndefinedDocblockClass
99-
*/
100-
$response = \Automattic\Jetpack\Connection\Client::remote_request( $args );
101-
$response_body = wp_remote_retrieve_body( $response );
102-
103-
// phpcs:ignore
104-
/**
105-
* @psalm-suppress UndefinedDocblockClass
106-
*/
107-
if ( is_wp_error( $response ) || ! is_array( $response ) || ( ! empty( $response['code'] ) && ( $response['code'] >= 300 || $response['code'] < 200 ) ) ) {
108-
Logger::error( 'HTTP_REQUEST_ERROR ' . var_export( $response, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
109-
return;
110-
}
111-
112-
$json = json_decode( $response_body, true );
158+
$incompatible_extensions = $this->payments_api_client->get_woopay_incompatible_extensions();
113159

114-
return isset( $json['incompatible_extensions'] ) ? $json['incompatible_extensions'] : [];
160+
return isset( $incompatible_extensions['incompatible_extensions'] ) ? $incompatible_extensions['incompatible_extensions'] : [];
115161
}
116162
}

0 commit comments

Comments
 (0)