From 9cdd11b3b3a0444f5fbfdea5cff2841630916ba6 Mon Sep 17 00:00:00 2001
From: Pedro Silva
Date: Thu, 27 Jul 2023 09:57:19 +0100
Subject: [PATCH] Refactor paylater and buttons filters for simplicity Add show
/ hide messages functionality on the frontend
---
.../modules/ContextBootstrap/CartBootstap.js | 3 +-
.../ContextBootstrap/SingleProductBootstap.js | 3 +
.../js/modules/Helper/BootstrapHelper.js | 34 ++++-
.../ppcp-button/src/Assets/SmartButton.php | 143 +++++++-----------
.../src/Endpoint/CartScriptParamsEndpoint.php | 1 +
.../src/Endpoint/SimulateCartEndpoint.php | 23 ++-
6 files changed, 104 insertions(+), 103 deletions(-)
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
index f55663b74..f02b628ee 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
@@ -49,8 +49,9 @@ class CartBootstrap {
}
// handle button status
- if (result.data.button) {
+ if (result.data.button || result.data.messages) {
this.gateway.button = result.data.button;
+ this.gateway.messages = result.data.messages;
this.handleButtonStatus();
}
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
index 611e9e3e8..81a875ab4 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
@@ -202,6 +202,9 @@ class SingleProductBootstap {
if (typeof data.button.is_disabled === 'boolean') {
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);
diff --git a/modules/ppcp-button/resources/js/modules/Helper/BootstrapHelper.js b/modules/ppcp-button/resources/js/modules/Helper/BootstrapHelper.js
index ba00e2c76..8ba3d0e09 100644
--- a/modules/ppcp-button/resources/js/modules/Helper/BootstrapHelper.js
+++ b/modules/ppcp-button/resources/js/modules/Helper/BootstrapHelper.js
@@ -1,4 +1,5 @@
import {disable, enable} from "./ButtonDisabler";
+import {hide, show} from "./Hiding";
/**
* Common Bootstrap methods to avoid code repetition.
@@ -11,20 +12,28 @@ export default class BootstrapHelper {
options.messagesWrapper = options.messagesWrapper || bs.gateway.messages.wrapper;
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);
disable(options.wrapper, options.formSelector || null);
if (!options.skipMessages) {
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()
&& 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;
+ }
}
diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php
index c3ea172c8..bd1577e09 100644
--- a/modules/ppcp-button/src/Assets/SmartButton.php
+++ b/modules/ppcp-button/src/Assets/SmartButton.php
@@ -383,7 +383,7 @@ class SmartButton implements SmartButtonInterface {
* @throws NotFoundException When a setting was not found.
*/
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;
}
@@ -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_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() ) {
case 'checkout':
@@ -658,7 +658,7 @@ class SmartButton implements SmartButtonInterface {
* @throws NotFoundException When a setting was not found.
*/
private function message_values(): array {
- if ( ! $this->is_pay_later_messaging_enabled() ) {
+ if ( ! $this->settings_status->is_pay_later_messaging_enabled() ) {
return array();
}
@@ -684,6 +684,7 @@ class SmartButton implements SmartButtonInterface {
return array(
'wrapper' => '#ppcp-messages',
+ 'is_hidden' => ! $this->is_pay_later_filter_enabled_for_location( $this->context() ),
'amount' => $amount,
'placement' => $placement,
'style' => array(
@@ -1334,18 +1335,6 @@ class SmartButton implements SmartButtonInterface {
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.
*
@@ -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.
*
* @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
*/
- 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 ) {
$context = $this->context();
}
if ( 'product' === $context ) {
- $product = wc_get_product();
-
- /**
- * Allows to decide if the button should be disabled for a given product
- */
- $is_disabled = apply_filters(
+ // Allows to decide if the button should be disabled for a given product.
+ return apply_filters(
'woocommerce_paypal_payments_product_buttons_disabled',
- null,
- $product
+ false,
+ $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
- */
- $is_disabled = apply_filters(
+ // Allows to decide if the button should be disabled globally or on a given context.
+ return apply_filters(
'woocommerce_paypal_payments_buttons_disabled',
- null,
- $context,
- null === $price_total ? $this->get_cart_price_total() : $price_total
+ false,
+ $context
);
-
- if ( $is_disabled !== null ) {
- return $is_disabled;
- }
-
- return false;
}
/**
* Checks a filter if pay_later/messages should be rendered on a given location / context.
*
- * @param string $location The location.
- * @param float|null $price_total The price total to be considered.
+ * @param string $location The location.
+ * @param array $context_data The context data for this filter
* @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 ) {
- $product = wc_get_product();
-
- if ( ! $product ) {
- return true;
- }
-
- /**
- * Allows to decide if the button should be disabled for a given product
- */
- $is_disabled = apply_filters(
+ // Allows to decide if the button should be disabled for a given product.
+ return ! apply_filters(
'woocommerce_paypal_payments_product_buttons_paylater_disabled',
- null,
- $product
+ false,
+ $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
- */
- $is_disabled = apply_filters(
+ // Allows to decide if the button should be disabled on a given context.
+ return ! apply_filters(
'woocommerce_paypal_payments_buttons_paylater_disabled',
- null,
- $location,
- null === $price_total ? $this->get_cart_price_total() : $price_total
+ false,
+ $location
);
-
- if ( $is_disabled !== null ) {
- return ! $is_disabled;
- }
-
- return true;
}
/**
* Check whether Pay Later button is enabled for a given location.
*
- * @param string $location The location.
- * @param float|null $price_total The price total to be considered.
+ * @param string $location The location.
+ * @param array $context_data The context data for this filter
* @return bool true if is enabled, otherwise false.
*/
- public function is_pay_later_button_enabled_for_location( string $location, float $price_total = null ): bool {
- return $this->is_pay_later_filter_enabled_for_location( $location, $price_total )
+ 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, $context_data )
&& $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.
*
* @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.
*/
- public function is_pay_later_messaging_enabled_for_location( string $location, float $price_total = null ): bool {
- return $this->is_pay_later_filter_enabled_for_location( $location, $price_total )
+ 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, $context_data )
&& $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.
*
diff --git a/modules/ppcp-button/src/Endpoint/CartScriptParamsEndpoint.php b/modules/ppcp-button/src/Endpoint/CartScriptParamsEndpoint.php
index 44449a761..58350f6f8 100644
--- a/modules/ppcp-button/src/Endpoint/CartScriptParamsEndpoint.php
+++ b/modules/ppcp-button/src/Endpoint/CartScriptParamsEndpoint.php
@@ -75,6 +75,7 @@ class CartScriptParamsEndpoint implements EndpointInterface {
array(
'url_params' => $script_data['url_params'],
'button' => $script_data['button'],
+ 'messages' => $script_data['messages'],
'amount' => WC()->cart->get_total( 'raw' ),
)
);
diff --git a/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php b/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php
index b99b69e8c..62defeec6 100644
--- a/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php
+++ b/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php
@@ -84,17 +84,34 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
WC()->cart = $active_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(
array(
'total' => $total,
'funding' => array(
'paylater' => array(
- 'enabled' => $this->smart_button->is_pay_later_button_enabled_for_location( 'cart', $total ),
- 'messaging_enabled' => $this->smart_button->is_pay_later_messaging_enabled_for_location( 'cart', $total ),
+ 'enabled' => $pay_later_enabled,
),
),
'button' => array(
- 'is_disabled' => $this->smart_button->is_button_disabled( 'cart', $total ),
+ 'is_disabled' => ! $button_enabled,
+ ),
+ 'messages' => array(
+ 'is_hidden' => ! $pay_later_messaging_enabled,
),
)
);