diff --git a/modules/ppcp-compat/src/PPEC/PPECHelper.php b/modules/ppcp-compat/src/PPEC/PPECHelper.php index 71e16e544..70e882457 100644 --- a/modules/ppcp-compat/src/PPEC/PPECHelper.php +++ b/modules/ppcp-compat/src/PPEC/PPECHelper.php @@ -67,8 +67,12 @@ class PPECHelper { * @return bool */ public static function site_has_ppec_subscriptions() { - global $wpdb; + $has_ppec_subscriptions = get_transient( 'ppcp_has_ppec_subscriptions' ); + if ( $has_ppec_subscriptions !== false ) { + return $has_ppec_subscriptions === 'true'; + } + global $wpdb; $result = $wpdb->get_var( $wpdb->prepare( "SELECT 1 FROM {$wpdb->posts} p JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID @@ -80,6 +84,12 @@ class PPECHelper { ) ); + set_transient( + 'ppcp_has_ppec_subscriptions', + ! empty( $result ) ? 'true' : 'false', + 3 * MONTH_IN_SECONDS + ); + return ! empty( $result ); } @@ -92,7 +102,9 @@ class PPECHelper { /** * The filter returning whether the compatibility layer for PPEC Subscriptions should be initialized. */ - return ( ! self::is_gateway_available() ) && self::site_has_ppec_subscriptions() && apply_filters( 'woocommerce_paypal_payments_process_legacy_subscriptions', true ); + return ( ! self::is_gateway_available() ) + && self::site_has_ppec_subscriptions() + && apply_filters( 'woocommerce_paypal_payments_process_legacy_subscriptions', true ); } } diff --git a/modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php b/modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php index 4a7631572..b228139e0 100644 --- a/modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php +++ b/modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php @@ -83,6 +83,14 @@ class IncomingWebhookEndpoint { */ private $last_webhook_event_storage; + /** + * Cached webhook verification results + * to avoid repeating requests when permission_callback is called multiple times. + * + * @var array + */ + private $verification_results = array(); + /** * IncomingWebhookEndpoint constructor. * @@ -160,7 +168,17 @@ class IncomingWebhookEndpoint { try { $event = $this->event_from_request( $request ); + } catch ( RuntimeException $exception ) { + $this->logger->error( 'Webhook parsing failed: ' . $exception->getMessage() ); + return false; + } + $cache_key = $event->id(); + if ( isset( $this->verification_results[ $cache_key ] ) ) { + return $this->verification_results[ $cache_key ]; + } + + try { if ( $this->simulation->is_simulation_event( $event ) ) { return true; } @@ -169,9 +187,11 @@ class IncomingWebhookEndpoint { if ( ! $result ) { $this->logger->error( 'Webhook verification failed.' ); } + $this->verification_results[ $cache_key ] = $result; return $result; } catch ( RuntimeException $exception ) { $this->logger->error( 'Webhook verification failed: ' . $exception->getMessage() ); + $this->verification_results[ $cache_key ] = false; return false; } } diff --git a/tests/PHPUnit/TestCase.php b/tests/PHPUnit/TestCase.php index 1efbdcec4..2289dbc20 100644 --- a/tests/PHPUnit/TestCase.php +++ b/tests/PHPUnit/TestCase.php @@ -33,6 +33,7 @@ class TestCase extends \PHPUnit\Framework\TestCase }); when('get_plugin_data')->justReturn(['Version' => '1.0']); when('plugin_basename')->justReturn('woocommerce-paypal-payments/woocommerce-paypal-payments.php'); + when('get_transient')->returnArg(); when('wc_clean')->returnArg(); when('get_transient')->returnArg();