Merge pull request #3167 from woocommerce/PCP-4261-uncheck-item-when-disabled-for-payment-methods

Do not render the button when it is disabled from Payment Methods (4261)
This commit is contained in:
Emili Castells 2025-02-28 15:18:49 +01:00 committed by GitHub
commit 4e000e2ae9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 160 additions and 46 deletions

View file

@ -94,6 +94,45 @@ function as_schedule_single_action( $timestamp, $hook, $args = array(), $group =
return 0;
}
/**
* Retrieves the number of times a filter has been applied during the current request.
*
* @since 6.1.0
*
* @global int[] $wp_filters Stores the number of times each filter was triggered.
*
* @param string $hook_name The name of the filter hook.
* @return int The number of times the filter hook has been applied.
*/
function did_filter( $hook_name ) {
return 0;
}
/**
* Returns whether or not a filter hook is currently being processed.
*
* The function current_filter() only returns the most recent filter being executed.
* did_filter() returns the number of times a filter has been applied during
* the current request.
*
* This function allows detection for any filter currently being executed
* (regardless of whether it's the most recent filter to fire, in the case of
* hooks called from hook callbacks) to be verified.
*
* @since 3.9.0
*
* @see current_filter()
* @see did_filter()
* @global string[] $wp_current_filter Current filter.
*
* @param string|null $hook_name Optional. Filter hook to check. Defaults to null,
* which checks if any filter is currently being run.
* @return bool Whether the filter is currently in the stack.
*/
function doing_filter( $hook_name = null ) {
return false;
}
/**
* HTML API: WP_HTML_Tag_Processor class
*/

View file

@ -172,6 +172,16 @@ return array(
$container->get( 'settings.data.settings' ),
$subscription_map_helper->map()
),
/**
* We need to pass the PaymentSettings model instance to use it in some helpers.
* Once the new settings module is permanently enabled,
* this model can be passed as a dependency to the appropriate helper classes.
* For now, we must pass it this way to avoid errors when the new settings module is disabled.
*/
new SettingsMap(
$container->get( 'settings.data.payment' ),
array()
),
);
},
'compat.settings.settings_map_helper' => static function( ContainerInterface $container ) : SettingsMapHelper {

View file

@ -10,7 +10,9 @@ declare( strict_types = 1 );
namespace WooCommerce\PayPalCommerce\Compat\Settings;
use RuntimeException;
use WooCommerce\PayPalCommerce\Settings\Data\AbstractDataModel;
use WooCommerce\PayPalCommerce\Settings\Data\GeneralSettings;
use WooCommerce\PayPalCommerce\Settings\Data\PaymentSettings;
use WooCommerce\PayPalCommerce\Settings\Data\SettingsModel;
use WooCommerce\PayPalCommerce\Settings\Data\StylingSettings;
@ -169,7 +171,11 @@ class SettingsMapHelper {
switch ( true ) {
case $model instanceof StylingSettings:
return $this->styling_settings_map_helper->mapped_value( $old_key, $this->model_cache[ $model_id ] );
return $this->styling_settings_map_helper->mapped_value(
$old_key,
$this->model_cache[ $model_id ],
$this->get_payment_settings_model()
);
case $model instanceof GeneralSettings:
return $this->general_settings_map_helper->mapped_value( $old_key, $this->model_cache[ $model_id ] );
@ -217,4 +223,23 @@ class SettingsMapHelper {
}
}
}
/**
* Retrieves the PaymentSettings model instance.
*
* Once the new settings module is permanently enabled,
* this model can be passed as a dependency to the appropriate helper classes.
* For now, we must pass it this way to avoid errors when the new settings module is disabled.
*
* @return AbstractDataModel|null
*/
protected function get_payment_settings_model() : ?AbstractDataModel {
foreach ( $this->settings_map as $settings_map_instance ) {
if ( $settings_map_instance->get_model() instanceof PaymentSettings ) {
return $settings_map_instance->get_model();
}
}
return null;
}
}

View file

@ -10,7 +10,11 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Compat\Settings;
use RuntimeException;
use WooCommerce\PayPalCommerce\Applepay\ApplePayGateway;
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
use WooCommerce\PayPalCommerce\Googlepay\GooglePayGateway;
use WooCommerce\PayPalCommerce\Settings\Data\AbstractDataModel;
use WooCommerce\PayPalCommerce\Settings\Data\PaymentSettings;
use WooCommerce\PayPalCommerce\Settings\DTO\LocationStylingDTO;
/**
@ -23,7 +27,7 @@ class StylingSettingsMapHelper {
use ContextTrait;
protected const BUTTON_NAMES = array( 'ppcp-googlepay', 'ppcp-applepay', 'pay-later' );
protected const BUTTON_NAMES = array( GooglePayGateway::ID, ApplePayGateway::ID, 'pay-later' );
/**
* Maps old setting keys to new setting style names.
@ -64,12 +68,13 @@ class StylingSettingsMapHelper {
/**
* Retrieves the value of a mapped key from the new settings.
*
* @param string $old_key The key from the legacy settings.
* @param LocationStylingDTO[] $styling_models The list of location styling models.
* @param string $old_key The key from the legacy settings.
* @param LocationStylingDTO[] $styling_models The list of location styling models.
* @param AbstractDataModel|null $payment_settings The payment settings model.
*
* @return mixed The value of the mapped setting, (null if not found).
*/
public function mapped_value( string $old_key, array $styling_models ) {
public function mapped_value( string $old_key, array $styling_models, ?AbstractDataModel $payment_settings ) {
switch ( $old_key ) {
case 'smart_button_locations':
return $this->mapped_smart_button_locations_value( $styling_models );
@ -81,16 +86,16 @@ class StylingSettingsMapHelper {
return $this->mapped_pay_later_button_locations_value( $styling_models );
case 'disable_funding':
return $this->mapped_disabled_funding_value( $styling_models );
return $this->mapped_disabled_funding_value( $styling_models, $payment_settings );
case 'googlepay_button_enabled':
return $this->mapped_button_enabled_value( $styling_models, 'ppcp-googlepay' );
return $this->mapped_button_enabled_value( $styling_models, GooglePayGateway::ID, $payment_settings );
case 'applepay_button_enabled':
return $this->mapped_button_enabled_value( $styling_models, 'ppcp-applepay' );
return $this->mapped_button_enabled_value( $styling_models, ApplePayGateway::ID, $payment_settings );
case 'pay_later_button_enabled':
return $this->mapped_button_enabled_value( $styling_models, 'pay-later' );
return $this->mapped_button_enabled_value( $styling_models, 'pay-later', $payment_settings );
default:
foreach ( $this->locations_map() as $old_location_name => $new_location_name ) {
@ -224,52 +229,80 @@ class StylingSettingsMapHelper {
/**
* Retrieves the mapped disabled funding value from the new settings.
*
* @param LocationStylingDTO[] $styling_models The list of location styling models.
* @param LocationStylingDTO[] $styling_models The list of location styling models.
* @param AbstractDataModel|null $payment_settings The payment settings model.
* @return array|null The list of disabled funding, or null if none are disabled.
*/
protected function mapped_disabled_funding_value( array $styling_models ): ?array {
protected function mapped_disabled_funding_value( array $styling_models, ?AbstractDataModel $payment_settings ): ?array {
if ( is_null( $payment_settings ) ) {
return null;
}
$disabled_funding = array();
$locations_to_context_map = $this->current_context_to_new_button_location_map();
$current_context = $locations_to_context_map[ $this->context() ] ?? '';
assert( $payment_settings instanceof PaymentSettings );
foreach ( $styling_models as $model ) {
if ( $model->location !== $current_context || in_array( 'venmo', $model->methods, true ) ) {
continue;
if ( $model->location === $current_context ) {
if ( ! in_array( 'venmo', $model->methods, true ) || ! $payment_settings->get_venmo_enabled() ) {
$disabled_funding[] = 'venmo';
}
}
$disabled_funding[] = 'venmo';
return $disabled_funding;
}
return null;
return $disabled_funding;
}
/**
* Retrieves the mapped enabled or disabled button value from the new settings.
*
* @param LocationStylingDTO[] $styling_models The list of location styling models.
* @param string $button_name The button name (see {@link self::BUTTON_NAMES}).
* @param LocationStylingDTO[] $styling_models The list of location styling models.
* @param string $button_name The button name (see {@link self::BUTTON_NAMES}).
* @param AbstractDataModel|null $payment_settings The payment settings model.
* @return int The enabled (1) or disabled (0) state.
* @throws RuntimeException If an invalid button name is provided.
*/
protected function mapped_button_enabled_value( array $styling_models, string $button_name ): ?int {
protected function mapped_button_enabled_value( array $styling_models, string $button_name, ?AbstractDataModel $payment_settings ): ?int {
if ( is_null( $payment_settings ) ) {
return null;
}
if ( ! in_array( $button_name, self::BUTTON_NAMES, true ) ) {
throw new RuntimeException( 'Wrong button name is provided.' );
}
$locations_to_context_map = $this->current_context_to_new_button_location_map();
$current_context = $locations_to_context_map[ $this->context() ] ?? '';
assert( $payment_settings instanceof PaymentSettings );
foreach ( $styling_models as $model ) {
if ( ! $model->enabled
|| $model->location !== $current_context
|| ! in_array( $button_name, $model->methods, true )
) {
continue;
if ( $model->enabled && $model->location === $current_context ) {
if ( in_array( $button_name, $model->methods, true ) && $payment_settings->is_method_enabled( $button_name ) ) {
return 1;
}
}
}
return 1;
if ( $current_context === 'classic_checkout' ) {
/**
* Outputs an inline CSS style that hides the Google Pay gateway (on Classic Checkout)
* In case if the button is disabled from the styling settings but the gateway itself is enabled.
*
* @return void
*/
add_action(
'woocommerce_paypal_payments_checkout_button_render',
static function (): void {
?>
<style data-hide-gateway='<?php echo esc_attr( GooglePayGateway::ID ); ?>'>
.wc_payment_method.payment_method_ppcp-googlepay {
display: none;
}
</style>
<?php
}
);
}
return 0;

View file

@ -81,22 +81,23 @@ const GooglePayComponent = ( { isEditing, buttonAttributes } ) => {
};
const features = [ 'products' ];
registerExpressPaymentMethod( {
name: buttonData.id,
title: `PayPal - ${ buttonData.title }`,
description: __(
'Eligible users will see the PayPal button.',
'woocommerce-paypal-payments'
),
gatewayId: 'ppcp-gateway',
label: <div dangerouslySetInnerHTML={ { __html: buttonData.title } } />,
content: <GooglePayComponent isEditing={ false } />,
edit: <GooglePayComponent isEditing={ true } />,
ariaLabel: buttonData.title,
canMakePayment: () => buttonData.enabled,
supports: {
features,
style: [ 'height', 'borderRadius' ],
},
} );
if ( buttonConfig?.is_enabled ) {
registerExpressPaymentMethod( {
name: buttonData.id,
title: `PayPal - ${ buttonData.title }`,
description: __(
'Eligible users will see the PayPal button.',
'woocommerce-paypal-payments'
),
gatewayId: 'ppcp-gateway',
label: <div dangerouslySetInnerHTML={ { __html: buttonData.title } } />,
content: <GooglePayComponent isEditing={ false } />,
edit: <GooglePayComponent isEditing={ true } />,
ariaLabel: buttonData.title,
canMakePayment: () => buttonData.enabled,
supports: {
features,
style: [ 'height', 'borderRadius' ],
},
} );
}

View file

@ -105,6 +105,12 @@ class PaymentSettings extends AbstractDataModel {
return $this->get_paylater_enabled();
default:
if (
! did_filter( 'woocommerce_payment_gateways' )
|| doing_filter( 'woocommerce_payment_gateways' )
) {
return true;
}
$gateway = $this->get_gateway( $method_id );
if ( $gateway ) {