Refactor paylater and buttons filters for simplicity

Add show / hide messages functionality on the frontend
This commit is contained in:
Pedro Silva 2023-07-27 09:57:19 +01:00
parent 9434a84301
commit 9cdd11b3b3
No known key found for this signature in database
GPG key ID: E2EE20C0669D24B3
6 changed files with 104 additions and 103 deletions

View file

@ -49,8 +49,9 @@ class CartBootstrap {
} }
// handle button status // handle button status
if (result.data.button) { if (result.data.button || result.data.messages) {
this.gateway.button = result.data.button; this.gateway.button = result.data.button;
this.gateway.messages = result.data.messages;
this.handleButtonStatus(); this.handleButtonStatus();
} }

View file

@ -202,6 +202,9 @@ class SingleProductBootstap {
if (typeof data.button.is_disabled === 'boolean') { if (typeof data.button.is_disabled === 'boolean') {
this.gateway.button.is_disabled = data.button.is_disabled; this.gateway.button.is_disabled = data.button.is_disabled;
} }
if (typeof data.messages.is_hidden === 'boolean') {
this.gateway.messages.is_hidden = data.messages.is_hidden;
}
this.handleButtonStatus(false); this.handleButtonStatus(false);

View file

@ -1,4 +1,5 @@
import {disable, enable} from "./ButtonDisabler"; import {disable, enable} from "./ButtonDisabler";
import {hide, show} from "./Hiding";
/** /**
* Common Bootstrap methods to avoid code repetition. * Common Bootstrap methods to avoid code repetition.
@ -11,20 +12,28 @@ export default class BootstrapHelper {
options.messagesWrapper = options.messagesWrapper || bs.gateway.messages.wrapper; options.messagesWrapper = options.messagesWrapper || bs.gateway.messages.wrapper;
options.skipMessages = options.skipMessages || false; options.skipMessages = options.skipMessages || false;
if (!bs.shouldEnable()) { // Handle messages hide / show
if (this.shouldShowMessages(bs, options)) {
show(options.messagesWrapper);
} else {
hide(options.messagesWrapper);
}
// Handle enable / disable
if (bs.shouldEnable()) {
bs.renderer.enableSmartButtons(options.wrapper);
enable(options.wrapper);
if (!options.skipMessages) {
enable(options.messagesWrapper);
}
} else {
bs.renderer.disableSmartButtons(options.wrapper); bs.renderer.disableSmartButtons(options.wrapper);
disable(options.wrapper, options.formSelector || null); disable(options.wrapper, options.formSelector || null);
if (!options.skipMessages) { if (!options.skipMessages) {
disable(options.messagesWrapper); disable(options.messagesWrapper);
} }
return;
}
bs.renderer.enableSmartButtons(options.wrapper);
enable(options.wrapper);
if (!options.skipMessages) {
enable(options.messagesWrapper);
} }
} }
@ -37,4 +46,13 @@ export default class BootstrapHelper {
return bs.shouldRender() return bs.shouldRender()
&& options.isDisabled !== true; && options.isDisabled !== true;
} }
static shouldShowMessages(bs, options) {
options = options || {};
if (typeof options.isMessagesHidden === 'undefined') {
options.isMessagesHidden = bs.gateway.messages.is_hidden;
}
return options.isMessagesHidden !== true;
}
} }

View file

@ -383,7 +383,7 @@ class SmartButton implements SmartButtonInterface {
* @throws NotFoundException When a setting was not found. * @throws NotFoundException When a setting was not found.
*/ */
private function render_message_wrapper_registrar(): bool { private function render_message_wrapper_registrar(): bool {
if ( ! $this->is_pay_later_messaging_enabled() ) { if ( ! $this->settings_status->is_pay_later_messaging_enabled() ) {
return false; return false;
} }
@ -549,7 +549,7 @@ class SmartButton implements SmartButtonInterface {
$smart_button_enabled_for_current_location = $this->settings_status->is_smart_button_enabled_for_location( $this->context() ); $smart_button_enabled_for_current_location = $this->settings_status->is_smart_button_enabled_for_location( $this->context() );
$smart_button_enabled_for_mini_cart = $this->settings_status->is_smart_button_enabled_for_location( 'mini-cart' ); $smart_button_enabled_for_mini_cart = $this->settings_status->is_smart_button_enabled_for_location( 'mini-cart' );
$messaging_enabled_for_current_location = $this->is_pay_later_messaging_enabled_for_location( $this->context() ); $messaging_enabled_for_current_location = $this->settings_status->is_pay_later_messaging_enabled_for_location( $this->context() );
switch ( $this->context() ) { switch ( $this->context() ) {
case 'checkout': case 'checkout':
@ -658,7 +658,7 @@ class SmartButton implements SmartButtonInterface {
* @throws NotFoundException When a setting was not found. * @throws NotFoundException When a setting was not found.
*/ */
private function message_values(): array { private function message_values(): array {
if ( ! $this->is_pay_later_messaging_enabled() ) { if ( ! $this->settings_status->is_pay_later_messaging_enabled() ) {
return array(); return array();
} }
@ -684,6 +684,7 @@ class SmartButton implements SmartButtonInterface {
return array( return array(
'wrapper' => '#ppcp-messages', 'wrapper' => '#ppcp-messages',
'is_hidden' => ! $this->is_pay_later_filter_enabled_for_location( $this->context() ),
'amount' => $amount, 'amount' => $amount,
'placement' => $placement, 'placement' => $placement,
'style' => array( 'style' => array(
@ -1334,18 +1335,6 @@ class SmartButton implements SmartButtonInterface {
return WC()->cart && WC()->cart->get_total( 'numeric' ) == 0; return WC()->cart && WC()->cart->get_total( 'numeric' ) == 0;
} }
/**
* Returns the cart total.
*
* @return ?float
*/
protected function get_cart_price_total(): ?float {
if ( ! WC()->cart ) {
return null;
}
return (float) WC()->cart->get_total( 'numeric' );
}
/** /**
* Checks if PayPal buttons/messages can be rendered for the given product. * Checks if PayPal buttons/messages can be rendered for the given product.
* *
@ -1380,108 +1369,90 @@ class SmartButton implements SmartButtonInterface {
); );
} }
/**
* Fills and returns the product context_data array to be used in filters.
*
* @param array $context_data
* @return array
*/
private function product_filter_context_data( array $context_data = [] ): array {
if ( ! isset( $context_data['product'] ) ) {
$context_data['product'] = wc_get_product();
}
if ( ! $context_data['product'] ) {
return [];
}
if ( ! isset( $context_data['order_total'] ) && ( $context_data['product'] instanceof WC_Product ) ) {
$context_data['order_total'] = (float) $context_data['product']->get_price( 'raw' );
}
return $context_data;
}
/** /**
* Checks if PayPal buttons/messages should be rendered for the current page. * Checks if PayPal buttons/messages should be rendered for the current page.
* *
* @param string|null $context The context that should be checked, use default otherwise. * @param string|null $context The context that should be checked, use default otherwise.
* @param float|null $price_total The price total to be considered. * @param array $context_data The context data for this filter
* @return bool * @return bool
*/ */
public function is_button_disabled( string $context = null, float $price_total = null ): bool { public function is_button_disabled( string $context = null, array $context_data = [] ): bool {
if ( null === $context ) { if ( null === $context ) {
$context = $this->context(); $context = $this->context();
} }
if ( 'product' === $context ) { if ( 'product' === $context ) {
$product = wc_get_product(); // Allows to decide if the button should be disabled for a given product.
return apply_filters(
/**
* Allows to decide if the button should be disabled for a given product
*/
$is_disabled = apply_filters(
'woocommerce_paypal_payments_product_buttons_disabled', 'woocommerce_paypal_payments_product_buttons_disabled',
null, false,
$product $this->product_filter_context_data($context_data)
); );
if ( $is_disabled !== null ) {
return $is_disabled;
}
} }
/** // Allows to decide if the button should be disabled globally or on a given context.
* Allows to decide if the button should be disabled globally or on a given context return apply_filters(
*/
$is_disabled = apply_filters(
'woocommerce_paypal_payments_buttons_disabled', 'woocommerce_paypal_payments_buttons_disabled',
null, false,
$context, $context
null === $price_total ? $this->get_cart_price_total() : $price_total
); );
if ( $is_disabled !== null ) {
return $is_disabled;
}
return false;
} }
/** /**
* Checks a filter if pay_later/messages should be rendered on a given location / context. * Checks a filter if pay_later/messages should be rendered on a given location / context.
* *
* @param string $location The location. * @param string $location The location.
* @param float|null $price_total The price total to be considered. * @param array $context_data The context data for this filter
* @return bool * @return bool
*/ */
private function is_pay_later_filter_enabled_for_location( string $location, float $price_total = null ): bool { private function is_pay_later_filter_enabled_for_location( string $location, array $context_data = [] ): bool {
if ( 'product' === $location ) { if ( 'product' === $location ) {
$product = wc_get_product(); // Allows to decide if the button should be disabled for a given product.
return ! apply_filters(
if ( ! $product ) {
return true;
}
/**
* Allows to decide if the button should be disabled for a given product
*/
$is_disabled = apply_filters(
'woocommerce_paypal_payments_product_buttons_paylater_disabled', 'woocommerce_paypal_payments_product_buttons_paylater_disabled',
null, false,
$product $this->product_filter_context_data($context_data)
); );
if ( $is_disabled !== null ) {
return ! $is_disabled;
}
} }
/** // Allows to decide if the button should be disabled on a given context.
* Allows to decide if the button should be disabled globally or on a given context return ! apply_filters(
*/
$is_disabled = apply_filters(
'woocommerce_paypal_payments_buttons_paylater_disabled', 'woocommerce_paypal_payments_buttons_paylater_disabled',
null, false,
$location, $location
null === $price_total ? $this->get_cart_price_total() : $price_total
); );
if ( $is_disabled !== null ) {
return ! $is_disabled;
}
return true;
} }
/** /**
* Check whether Pay Later button is enabled for a given location. * Check whether Pay Later button is enabled for a given location.
* *
* @param string $location The location. * @param string $location The location.
* @param float|null $price_total The price total to be considered. * @param array $context_data The context data for this filter
* @return bool true if is enabled, otherwise false. * @return bool true if is enabled, otherwise false.
*/ */
public function is_pay_later_button_enabled_for_location( string $location, float $price_total = null ): bool { public function is_pay_later_button_enabled_for_location( string $location, array $context_data = [] ): bool {
return $this->is_pay_later_filter_enabled_for_location( $location, $price_total ) return $this->is_pay_later_filter_enabled_for_location( $location, $context_data )
&& $this->settings_status->is_pay_later_button_enabled_for_location( $location ); && $this->settings_status->is_pay_later_button_enabled_for_location( $location );
} }
@ -1490,24 +1461,14 @@ class SmartButton implements SmartButtonInterface {
* Check whether Pay Later message is enabled for a given location. * Check whether Pay Later message is enabled for a given location.
* *
* @param string $location The location setting name. * @param string $location The location setting name.
* @param float|null $price_total The price total to be considered. * @param array $context_data The context data for this filter
* @return bool true if is enabled, otherwise false. * @return bool true if is enabled, otherwise false.
*/ */
public function is_pay_later_messaging_enabled_for_location( string $location, float $price_total = null ): bool { public function is_pay_later_messaging_enabled_for_location( string $location, array $context_data = [] ): bool {
return $this->is_pay_later_filter_enabled_for_location( $location, $price_total ) return $this->is_pay_later_filter_enabled_for_location( $location, $context_data )
&& $this->settings_status->is_pay_later_messaging_enabled_for_location( $location ); && $this->settings_status->is_pay_later_messaging_enabled_for_location( $location );
} }
/**
* Check whether Pay Later message is enabled
*
* @return bool true if is enabled, otherwise false.
*/
private function is_pay_later_messaging_enabled(): bool {
return $this->is_pay_later_filter_enabled_for_location( $this->context() )
&& $this->settings_status->is_pay_later_messaging_enabled();
}
/** /**
* Retrieves all payment tokens for the user, via API or cached if already queried. * Retrieves all payment tokens for the user, via API or cached if already queried.
* *

View file

@ -75,6 +75,7 @@ class CartScriptParamsEndpoint implements EndpointInterface {
array( array(
'url_params' => $script_data['url_params'], 'url_params' => $script_data['url_params'],
'button' => $script_data['button'], 'button' => $script_data['button'],
'messages' => $script_data['messages'],
'amount' => WC()->cart->get_total( 'raw' ), 'amount' => WC()->cart->get_total( 'raw' ),
) )
); );

View file

@ -84,17 +84,34 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
WC()->cart = $active_cart; WC()->cart = $active_cart;
unset( $this->cart ); unset( $this->cart );
// Process filters.
$pay_later_enabled = true;
$pay_later_messaging_enabled = true;
$button_enabled = true;
foreach ( $products as $product ) {
$context_data = [
'product' => $product['product'],
'order_total' => $total,
];
$pay_later_enabled = $pay_later_enabled && $this->smart_button->is_pay_later_button_enabled_for_location( 'product', $context_data );
$pay_later_messaging_enabled = $pay_later_messaging_enabled && $this->smart_button->is_pay_later_messaging_enabled_for_location( 'product', $context_data );
$button_enabled = $button_enabled && ! $this->smart_button->is_button_disabled( 'product', $context_data );
}
wp_send_json_success( wp_send_json_success(
array( array(
'total' => $total, 'total' => $total,
'funding' => array( 'funding' => array(
'paylater' => array( 'paylater' => array(
'enabled' => $this->smart_button->is_pay_later_button_enabled_for_location( 'cart', $total ), 'enabled' => $pay_later_enabled,
'messaging_enabled' => $this->smart_button->is_pay_later_messaging_enabled_for_location( 'cart', $total ),
), ),
), ),
'button' => array( 'button' => array(
'is_disabled' => $this->smart_button->is_button_disabled( 'cart', $total ), 'is_disabled' => ! $button_enabled,
),
'messages' => array(
'is_hidden' => ! $pay_later_messaging_enabled,
), ),
) )
); );