From e94316aecd784abe33f7ea84d3aca1a2845018e0 Mon Sep 17 00:00:00 2001
From: Pedro Silva
Date: Mon, 3 Jul 2023 08:25:35 +0100
Subject: [PATCH 1/6] Add filter
woocommerce_paypal_payments_product_button_disabled to disable PayPal buttons
on single product page.
---
.../ContextBootstrap/SingleProductBootstap.js | 3 ++-
.../js/modules/Helper/ButtonDisabler.js | 5 ++++-
modules/ppcp-button/src/Assets/SmartButton.php | 18 ++++++++++++++++++
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
index 540b085c1..8e88d0a2b 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
@@ -96,7 +96,8 @@ class SingleProductBootstap {
return this.shouldRender()
&& !this.priceAmountIsZero()
- && ((null === addToCartButton) || !addToCartButton.classList.contains('disabled'));
+ && ((null === addToCartButton) || !addToCartButton.classList.contains('disabled'))
+ && this.gateway.button.is_disabled !== true;
}
priceAmount() {
diff --git a/modules/ppcp-button/resources/js/modules/Helper/ButtonDisabler.js b/modules/ppcp-button/resources/js/modules/Helper/ButtonDisabler.js
index 9e4bf51ee..ae7f3665c 100644
--- a/modules/ppcp-button/resources/js/modules/Helper/ButtonDisabler.js
+++ b/modules/ppcp-button/resources/js/modules/Helper/ButtonDisabler.js
@@ -36,7 +36,10 @@ export const setEnabled = (selectorOrElement, enable, form = null) => {
if (form) {
// Trigger form submit to show the error message
- jQuery(form).find(':submit').trigger('click');
+ let $form = jQuery(form);
+ if ($form.find('.single_add_to_cart_button').hasClass('disabled')) {
+ $form.find(':submit').trigger('click');
+ }
}
})
.find('> *')
diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php
index 4625fab5a..4ba295547 100644
--- a/modules/ppcp-button/src/Assets/SmartButton.php
+++ b/modules/ppcp-button/src/Assets/SmartButton.php
@@ -860,6 +860,7 @@ class SmartButton implements SmartButtonInterface {
'wrapper' => '#ppc-button-' . PayPalGateway::ID,
'mini_cart_wrapper' => '#ppc-button-minicart',
'cancel_wrapper' => '#ppcp-cancel',
+ 'is_disabled' => $this->is_button_disabled(),
'mini_cart_style' => array(
'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
'color' => $this->style_for_context( 'color', 'mini-cart' ),
@@ -1350,6 +1351,23 @@ class SmartButton implements SmartButtonInterface {
);
}
+ protected function is_button_disabled(): bool {
+ if ( 'product' !== $this->context() ) {
+ return false;
+ }
+
+ $product = wc_get_product();
+
+ /**
+ * Allows to decide if the button should be disabled for a given product
+ */
+ return apply_filters(
+ 'woocommerce_paypal_payments_product_button_disabled',
+ false,
+ $product
+ );
+ }
+
/**
* Retrieves all payment tokens for the user, via API or cached if already queried.
*
From cdd4a69bf572e0e290133e7fa27e41725f0cdccb Mon Sep 17 00:00:00 2001
From: Pedro Silva
Date: Mon, 3 Jul 2023 08:31:27 +0100
Subject: [PATCH 2/6] Fix lint
---
modules/ppcp-button/src/Assets/SmartButton.php | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php
index 4ba295547..68583f793 100644
--- a/modules/ppcp-button/src/Assets/SmartButton.php
+++ b/modules/ppcp-button/src/Assets/SmartButton.php
@@ -860,7 +860,7 @@ class SmartButton implements SmartButtonInterface {
'wrapper' => '#ppc-button-' . PayPalGateway::ID,
'mini_cart_wrapper' => '#ppc-button-minicart',
'cancel_wrapper' => '#ppcp-cancel',
- 'is_disabled' => $this->is_button_disabled(),
+ 'is_disabled' => $this->is_button_disabled(),
'mini_cart_style' => array(
'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
'color' => $this->style_for_context( 'color', 'mini-cart' ),
@@ -1351,6 +1351,11 @@ class SmartButton implements SmartButtonInterface {
);
}
+ /**
+ * Checks if PayPal buttons/messages should be rendered for the current page.
+ *
+ * @return bool
+ */
protected function is_button_disabled(): bool {
if ( 'product' !== $this->context() ) {
return false;
From 74f28ca921a39e36d65c6fbf543693ebb7751370 Mon Sep 17 00:00:00 2001
From: Pedro Silva
Date: Mon, 3 Jul 2023 11:40:37 +0100
Subject: [PATCH 3/6] Add filter
woocommerce_paypal_payments__button_disabled to disable PayPal
buttons on a given context.
---
.../modules/ContextBootstrap/CartBootstap.js | 13 ++++++
.../ContextBootstrap/CheckoutBootstap.js | 13 ++++++
.../ContextBootstrap/MiniCartBootstap.js | 13 ++++++
.../ppcp-button/src/Assets/SmartButton.php | 45 ++++++++++++++-----
4 files changed, 73 insertions(+), 11 deletions(-)
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
index 72d28932b..cc613da83 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
@@ -1,5 +1,6 @@
import CartActionHandler from '../ActionHandler/CartActionHandler';
import {setVisible} from "../Helper/Hiding";
+import {disable} from "../Helper/ButtonDisabler";
class CartBootstrap {
constructor(gateway, renderer, errorHandler) {
@@ -15,6 +16,13 @@ class CartBootstrap {
this.render();
+ if (!this.shouldEnable()) {
+ this.renderer.disableSmartButtons();
+ disable(this.gateway.button.wrapper);
+ disable(this.gateway.messages.wrapper);
+ return;
+ }
+
jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
this.render();
@@ -44,6 +52,11 @@ class CartBootstrap {
return document.querySelector(this.gateway.button.wrapper) !== null;
}
+ shouldEnable() {
+ return this.shouldRender()
+ && this.gateway.button.is_disabled !== true;
+ }
+
render() {
const actionHandler = new CartActionHandler(
PayPalCommerceGateway,
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
index 59c6197a3..a42902d9b 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
@@ -5,6 +5,7 @@ import {
isSavedCardSelected, ORDER_BUTTON_SELECTOR,
PaymentMethods
} from "../Helper/CheckoutMethodState";
+import {disable} from "../Helper/ButtonDisabler";
class CheckoutBootstap {
constructor(gateway, renderer, messages, spinner, errorHandler) {
@@ -20,6 +21,13 @@ class CheckoutBootstap {
init() {
this.render();
+ if (!this.shouldEnable()) {
+ this.renderer.disableSmartButtons();
+ disable(this.gateway.button.wrapper);
+ disable(this.gateway.messages.wrapper);
+ return;
+ }
+
// Unselect saved card.
// WC saves form values, so with our current UI it would be a bit weird
// if the user paid with saved, then after some time tries to pay again,
@@ -51,6 +59,11 @@ class CheckoutBootstap {
return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;
}
+ shouldEnable() {
+ return this.shouldRender()
+ && this.gateway.button.is_disabled !== true;
+ }
+
render() {
if (!this.shouldRender()) {
return;
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
index 443c9afe4..a391ee7cd 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
@@ -1,4 +1,5 @@
import CartActionHandler from '../ActionHandler/CartActionHandler';
+import {disable} from "../Helper/ButtonDisabler";
class MiniCartBootstap {
constructor(gateway, renderer, errorHandler) {
@@ -16,6 +17,13 @@ class MiniCartBootstap {
);
this.render();
+ if (!this.shouldEnable()) {
+ this.renderer.disableSmartButtons();
+ disable(this.gateway.button.wrapper);
+ disable(this.gateway.messages.wrapper);
+ return;
+ }
+
jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {
this.render();
});
@@ -26,6 +34,11 @@ class MiniCartBootstap {
|| document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;
}
+ shouldEnable() {
+ return this.shouldRender()
+ && this.gateway.button.is_disabled !== true;
+ }
+
render() {
if (!this.shouldRender()) {
return;
diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php
index 68583f793..5a7341e77 100644
--- a/modules/ppcp-button/src/Assets/SmartButton.php
+++ b/modules/ppcp-button/src/Assets/SmartButton.php
@@ -1357,20 +1357,43 @@ class SmartButton implements SmartButtonInterface {
* @return bool
*/
protected function is_button_disabled(): bool {
- if ( 'product' !== $this->context() ) {
- return false;
+ $context = $this->context();
+
+ if ( 'product' === $context ) {
+ $product = wc_get_product();
+
+ /**
+ * Allows to decide if the button should be disabled for a given product
+ */
+ if ( ( $isDisabled = apply_filters(
+ 'woocommerce_paypal_payments_product_button_disabled',
+ null,
+ $product )
+ ) !== null) {
+ return $isDisabled;
+ }
+ } else {
+ $filterName = 'woocommerce_paypal_payments_'
+ . str_replace('-', '_', $context)
+ . '_button_disabled';
+
+ /**
+ * Allows to decide if the button should be disabled in a given context
+ */
+ if ( ( $isDisabled = apply_filters( $filterName, null ) ) !== null ) {
+ return $isDisabled;
+ }
}
- $product = wc_get_product();
+ if ( ( $isDisabled = apply_filters(
+ 'woocommerce_paypal_payments_button_disabled',
+ null,
+ $context
+ ) ) !== null ) {
+ return $isDisabled;
+ }
- /**
- * Allows to decide if the button should be disabled for a given product
- */
- return apply_filters(
- 'woocommerce_paypal_payments_product_button_disabled',
- false,
- $product
- );
+ return false;
}
/**
From 6b03960de78e257723091e0ca96e79a8eacf5080 Mon Sep 17 00:00:00 2001
From: Pedro Silva
Date: Mon, 3 Jul 2023 17:35:01 +0100
Subject: [PATCH 4/6] Refactor button renderer and filter
woocommerce_paypal_payments__button_disabled
---
modules/ppcp-button/resources/js/button.js | 15 +-----
.../modules/ContextBootstrap/CartBootstap.js | 27 +++++++---
.../ContextBootstrap/CheckoutBootstap.js | 27 +++++++---
.../ContextBootstrap/MiniCartBootstap.js | 27 ++++++----
.../ContextBootstrap/SingleProductBootstap.js | 16 +++---
.../resources/js/modules/Renderer/Renderer.js | 51 +++++++++++++++----
.../ppcp-button/src/Assets/SmartButton.php | 51 ++++++++++---------
7 files changed, 131 insertions(+), 83 deletions(-)
diff --git a/modules/ppcp-button/resources/js/button.js b/modules/ppcp-button/resources/js/button.js
index 0fbccd095..17fcf1bfd 100644
--- a/modules/ppcp-button/resources/js/button.js
+++ b/modules/ppcp-button/resources/js/button.js
@@ -122,21 +122,10 @@ const bootstrap = () => {
}
};
- let smartButtonsOptions = {
- onInit: null,
- init: function (actions) {
- this.actions = actions;
- if (typeof this.onInit === 'function') {
- this.onInit();
- }
- }
- };
-
- const onSmartButtonsInit = (data, actions) => {
+ const onSmartButtonsInit = () => {
buttonsSpinner.unblock();
- smartButtonsOptions.init(actions);
};
- const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit, smartButtonsOptions);
+ const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit);
const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages);
const context = PayPalCommerceGateway.context;
if (context === 'mini-cart' || context === 'product') {
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
index cc613da83..978ee2578 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
@@ -1,12 +1,16 @@
import CartActionHandler from '../ActionHandler/CartActionHandler';
import {setVisible} from "../Helper/Hiding";
-import {disable} from "../Helper/ButtonDisabler";
+import {disable, enable} from "../Helper/ButtonDisabler";
class CartBootstrap {
constructor(gateway, renderer, errorHandler) {
this.gateway = gateway;
this.renderer = renderer;
this.errorHandler = errorHandler;
+
+ this.renderer.onButtonsInit(this.gateway.button.wrapper, () => {
+ this.handleButtonStatus();
+ }, true);
}
init() {
@@ -15,16 +19,11 @@ class CartBootstrap {
}
this.render();
-
- if (!this.shouldEnable()) {
- this.renderer.disableSmartButtons();
- disable(this.gateway.button.wrapper);
- disable(this.gateway.messages.wrapper);
- return;
- }
+ this.handleButtonStatus();
jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
this.render();
+ this.handleButtonStatus();
fetch(
this.gateway.ajax.cart_script_params.endpoint,
@@ -48,6 +47,18 @@ class CartBootstrap {
});
}
+ handleButtonStatus() {
+ if (!this.shouldEnable()) {
+ this.renderer.disableSmartButtons(this.gateway.button.wrapper);
+ disable(this.gateway.button.wrapper);
+ disable(this.gateway.messages.wrapper);
+ return;
+ }
+ this.renderer.enableSmartButtons(this.gateway.button.wrapper);
+ enable(this.gateway.button.wrapper);
+ enable(this.gateway.messages.wrapper);
+ }
+
shouldRender() {
return document.querySelector(this.gateway.button.wrapper) !== null;
}
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
index a42902d9b..551baa75b 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
@@ -5,7 +5,7 @@ import {
isSavedCardSelected, ORDER_BUTTON_SELECTOR,
PaymentMethods
} from "../Helper/CheckoutMethodState";
-import {disable} from "../Helper/ButtonDisabler";
+import {disable, enable} from "../Helper/ButtonDisabler";
class CheckoutBootstap {
constructor(gateway, renderer, messages, spinner, errorHandler) {
@@ -16,17 +16,15 @@ class CheckoutBootstap {
this.errorHandler = errorHandler;
this.standardOrderButtonSelector = ORDER_BUTTON_SELECTOR;
+
+ this.renderer.onButtonsInit(this.gateway.button.wrapper, () => {
+ this.handleButtonStatus();
+ }, true);
}
init() {
this.render();
-
- if (!this.shouldEnable()) {
- this.renderer.disableSmartButtons();
- disable(this.gateway.button.wrapper);
- disable(this.gateway.messages.wrapper);
- return;
- }
+ this.handleButtonStatus();
// Unselect saved card.
// WC saves form values, so with our current UI it would be a bit weird
@@ -36,6 +34,7 @@ class CheckoutBootstap {
jQuery(document.body).on('updated_checkout', () => {
this.render()
+ this.handleButtonStatus();
});
jQuery(document.body).on('updated_checkout payment_method_selected', () => {
@@ -51,6 +50,18 @@ class CheckoutBootstap {
this.updateUi();
}
+ handleButtonStatus() {
+ if (!this.shouldEnable()) {
+ this.renderer.disableSmartButtons(this.gateway.button.wrapper);
+ disable(this.gateway.button.wrapper);
+ disable(this.gateway.messages.wrapper);
+ return;
+ }
+ this.renderer.enableSmartButtons(this.gateway.button.wrapper);
+ enable(this.gateway.button.wrapper);
+ enable(this.gateway.messages.wrapper);
+ }
+
shouldRender() {
if (document.querySelector(this.gateway.button.cancel_wrapper)) {
return false;
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
index a391ee7cd..c993f3be0 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
@@ -1,5 +1,5 @@
import CartActionHandler from '../ActionHandler/CartActionHandler';
-import {disable} from "../Helper/ButtonDisabler";
+import {disable, enable} from "../Helper/ButtonDisabler";
class MiniCartBootstap {
constructor(gateway, renderer, errorHandler) {
@@ -16,17 +16,26 @@ class MiniCartBootstap {
this.errorHandler,
);
this.render();
-
- if (!this.shouldEnable()) {
- this.renderer.disableSmartButtons();
- disable(this.gateway.button.wrapper);
- disable(this.gateway.messages.wrapper);
- return;
- }
+ this.handleButtonStatus();
jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {
this.render();
+ this.handleButtonStatus();
});
+
+ this.renderer.onButtonsInit(this.gateway.button.mini_cart_wrapper, () => {
+ this.handleButtonStatus();
+ }, true);
+ }
+
+ handleButtonStatus() {
+ if (!this.shouldEnable()) {
+ this.renderer.disableSmartButtons(this.gateway.button.mini_cart_wrapper);
+ disable(this.gateway.button.mini_cart_wrapper);
+ return;
+ }
+ this.renderer.enableSmartButtons(this.gateway.button.mini_cart_wrapper);
+ enable(this.gateway.button.mini_cart_wrapper);
}
shouldRender() {
@@ -36,7 +45,7 @@ class MiniCartBootstap {
shouldEnable() {
return this.shouldRender()
- && this.gateway.button.is_disabled !== true;
+ && this.gateway.button.is_mini_cart_disabled !== true;
}
render() {
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
index 8e88d0a2b..b7addb4a5 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
@@ -12,11 +12,9 @@ class SingleProductBootstap {
this.mutationObserver = new MutationObserver(this.handleChange.bind(this));
this.formSelector = 'form.cart';
- if (this.renderer && this.renderer.smartButtonsOptions) {
- this.renderer.smartButtonsOptions.onInit = () => {
- this.handleChange();
- };
- }
+ this.renderer.onButtonsInit(this.gateway.button.wrapper, () => {
+ this.handleChange();
+ }, true);
}
form() {
@@ -25,7 +23,7 @@ class SingleProductBootstap {
handleChange() {
if (!this.shouldRender()) {
- this.renderer.disableSmartButtons();
+ this.renderer.disableSmartButtons(this.gateway.button.wrapper);
hide(this.gateway.button.wrapper, this.formSelector);
hide(this.gateway.messages.wrapper);
return;
@@ -33,7 +31,7 @@ class SingleProductBootstap {
this.render();
- this.renderer.enableSmartButtons();
+ this.renderer.enableSmartButtons(this.gateway.button.wrapper);
show(this.gateway.button.wrapper);
show(this.gateway.messages.wrapper);
@@ -42,12 +40,12 @@ class SingleProductBootstap {
handleButtonStatus() {
if (!this.shouldEnable()) {
- this.renderer.disableSmartButtons();
+ this.renderer.disableSmartButtons(this.gateway.button.wrapper);
disable(this.gateway.button.wrapper, this.formSelector);
disable(this.gateway.messages.wrapper);
return;
}
- this.renderer.enableSmartButtons();
+ this.renderer.enableSmartButtons(this.gateway.button.wrapper);
enable(this.gateway.button.wrapper);
enable(this.gateway.messages.wrapper);
}
diff --git a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js
index efd3c0bfa..1f0e3d31a 100644
--- a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js
+++ b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js
@@ -1,12 +1,14 @@
import merge from "deepmerge";
class Renderer {
- constructor(creditCardRenderer, defaultSettings, onSmartButtonClick, onSmartButtonsInit, smartButtonsOptions) {
+ constructor(creditCardRenderer, defaultSettings, onSmartButtonClick, onSmartButtonsInit) {
this.defaultSettings = defaultSettings;
this.creditCardRenderer = creditCardRenderer;
this.onSmartButtonClick = onSmartButtonClick;
this.onSmartButtonsInit = onSmartButtonsInit;
- this.smartButtonsOptions = smartButtonsOptions;
+
+ this.buttonsOptions = {};
+ this.onButtonsInitListeners = {};
this.renderedSources = new Set();
}
@@ -78,7 +80,10 @@ class Renderer {
style,
...contextConfig,
onClick: this.onSmartButtonClick,
- onInit: this.onSmartButtonsInit,
+ onInit: (data, actions) => {
+ this.onSmartButtonsInit(data, actions);
+ this.handleOnButtonsInit(wrapper, data, actions);
+ },
});
if (!btn.isEligible()) {
return;
@@ -108,18 +113,42 @@ class Renderer {
this.creditCardRenderer.enableFields();
}
- disableSmartButtons() {
- if (!this.smartButtonsOptions || !this.smartButtonsOptions.actions) {
- return;
- }
- this.smartButtonsOptions.actions.disable();
+ onButtonsInit(wrapper, handler, reset) {
+ this.onButtonsInitListeners[wrapper] = reset ? [] : (this.onButtonsInitListeners[wrapper] || []);
+ this.onButtonsInitListeners[wrapper].push(handler);
}
- enableSmartButtons() {
- if (!this.smartButtonsOptions || !this.smartButtonsOptions.actions) {
+ handleOnButtonsInit(wrapper, data, actions) {
+
+ this.buttonsOptions[wrapper] = {
+ data: data,
+ actions: actions
+ }
+
+ if (this.onButtonsInitListeners[wrapper]) {
+ for (let handler of this.onButtonsInitListeners[wrapper]) {
+ if (typeof handler === 'function') {
+ handler({
+ wrapper: wrapper,
+ ...this.buttonsOptions[wrapper]
+ });
+ }
+ }
+ }
+ }
+
+ disableSmartButtons(wrapper) {
+ if (!this.buttonsOptions[wrapper]) {
return;
}
- this.smartButtonsOptions.actions.enable();
+ this.buttonsOptions[wrapper].actions.disable();
+ }
+
+ enableSmartButtons(wrapper) {
+ if (!this.buttonsOptions[wrapper]) {
+ return;
+ }
+ this.buttonsOptions[wrapper].actions.enable();
}
}
diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php
index 5a7341e77..e64633d1f 100644
--- a/modules/ppcp-button/src/Assets/SmartButton.php
+++ b/modules/ppcp-button/src/Assets/SmartButton.php
@@ -857,11 +857,12 @@ class SmartButton implements SmartButtonInterface {
'bn_codes' => $this->bn_codes(),
'payer' => $this->payerData(),
'button' => array(
- 'wrapper' => '#ppc-button-' . PayPalGateway::ID,
- 'mini_cart_wrapper' => '#ppc-button-minicart',
- 'cancel_wrapper' => '#ppcp-cancel',
- 'is_disabled' => $this->is_button_disabled(),
- 'mini_cart_style' => array(
+ 'wrapper' => '#ppc-button-' . PayPalGateway::ID,
+ 'is_disabled' => $this->is_button_disabled(),
+ 'mini_cart_wrapper' => '#ppc-button-minicart',
+ 'is_mini_cart_disabled' => $this->is_button_disabled( 'mini-cart' ),
+ 'cancel_wrapper' => '#ppcp-cancel',
+ 'mini_cart_style' => array(
'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
'color' => $this->style_for_context( 'color', 'mini-cart' ),
'shape' => $this->style_for_context( 'shape', 'mini-cart' ),
@@ -869,7 +870,7 @@ class SmartButton implements SmartButtonInterface {
'tagline' => $this->style_for_context( 'tagline', 'mini-cart' ),
'height' => $this->settings->has( 'button_mini-cart_height' ) && $this->settings->get( 'button_mini-cart_height' ) ? $this->normalize_height( (int) $this->settings->get( 'button_mini-cart_height' ) ) : 35,
),
- 'style' => array(
+ 'style' => array(
'layout' => $this->style_for_context( 'layout', $this->context() ),
'color' => $this->style_for_context( 'color', $this->context() ),
'shape' => $this->style_for_context( 'shape', $this->context() ),
@@ -1354,10 +1355,14 @@ class SmartButton implements SmartButtonInterface {
/**
* 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.
+ *
* @return bool
*/
- protected function is_button_disabled(): bool {
- $context = $this->context();
+ protected function is_button_disabled( string $context = null ): bool {
+ if ( null === $context ) {
+ $context = $this->context();
+ }
if ( 'product' === $context ) {
$product = wc_get_product();
@@ -1365,32 +1370,28 @@ class SmartButton implements SmartButtonInterface {
/**
* Allows to decide if the button should be disabled for a given product
*/
- if ( ( $isDisabled = apply_filters(
+ $is_disabled = apply_filters(
'woocommerce_paypal_payments_product_button_disabled',
null,
- $product )
- ) !== null) {
- return $isDisabled;
- }
- } else {
- $filterName = 'woocommerce_paypal_payments_'
- . str_replace('-', '_', $context)
- . '_button_disabled';
+ $product
+ );
- /**
- * Allows to decide if the button should be disabled in a given context
- */
- if ( ( $isDisabled = apply_filters( $filterName, null ) ) !== null ) {
- return $isDisabled;
+ if ( $is_disabled !== null ) {
+ return $is_disabled;
}
}
- if ( ( $isDisabled = apply_filters(
+ /**
+ * Allows to decide if the button should be disabled globally or on a given context
+ */
+ $is_disabled = apply_filters(
'woocommerce_paypal_payments_button_disabled',
null,
$context
- ) ) !== null ) {
- return $isDisabled;
+ );
+
+ if ( $is_disabled !== null ) {
+ return $is_disabled;
}
return false;
From 87665401e5ea83213b3160dfcb205bcd2b50ba38 Mon Sep 17 00:00:00 2001
From: Pedro Silva
Date: Tue, 4 Jul 2023 08:29:48 +0100
Subject: [PATCH 5/6] Change filter names to plural
woocommerce_paypal_payments_buttons_disabled and
woocommerce_paypal_payments_product_buttons_disabled
---
modules/ppcp-button/src/Assets/SmartButton.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php
index e64633d1f..1516843b5 100644
--- a/modules/ppcp-button/src/Assets/SmartButton.php
+++ b/modules/ppcp-button/src/Assets/SmartButton.php
@@ -1371,7 +1371,7 @@ class SmartButton implements SmartButtonInterface {
* Allows to decide if the button should be disabled for a given product
*/
$is_disabled = apply_filters(
- 'woocommerce_paypal_payments_product_button_disabled',
+ 'woocommerce_paypal_payments_product_buttons_disabled',
null,
$product
);
@@ -1385,7 +1385,7 @@ class SmartButton implements SmartButtonInterface {
* Allows to decide if the button should be disabled globally or on a given context
*/
$is_disabled = apply_filters(
- 'woocommerce_paypal_payments_button_disabled',
+ 'woocommerce_paypal_payments_buttons_disabled',
null,
$context
);
From f6e625718ea2de64096f2953557171d4bde704e0 Mon Sep 17 00:00:00 2001
From: Pedro Silva
Date: Tue, 4 Jul 2023 14:43:55 +0100
Subject: [PATCH 6/6] Refactor handleButtonStatus and shouldEnable methods in
buttons bootstraps
---
.../modules/ContextBootstrap/CartBootstap.js | 15 ++-----
.../ContextBootstrap/CheckoutBootstap.js | 14 ++-----
.../ContextBootstrap/MiniCartBootstap.js | 18 ++++-----
.../ContextBootstrap/SingleProductBootstap.js | 19 +++------
.../js/modules/Helper/BootstrapHelper.js | 40 +++++++++++++++++++
5 files changed, 60 insertions(+), 46 deletions(-)
create mode 100644 modules/ppcp-button/resources/js/modules/Helper/BootstrapHelper.js
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
index 978ee2578..504fc4c42 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js
@@ -1,6 +1,6 @@
import CartActionHandler from '../ActionHandler/CartActionHandler';
+import BootstrapHelper from "../Helper/BootstrapHelper";
import {setVisible} from "../Helper/Hiding";
-import {disable, enable} from "../Helper/ButtonDisabler";
class CartBootstrap {
constructor(gateway, renderer, errorHandler) {
@@ -48,15 +48,7 @@ class CartBootstrap {
}
handleButtonStatus() {
- if (!this.shouldEnable()) {
- this.renderer.disableSmartButtons(this.gateway.button.wrapper);
- disable(this.gateway.button.wrapper);
- disable(this.gateway.messages.wrapper);
- return;
- }
- this.renderer.enableSmartButtons(this.gateway.button.wrapper);
- enable(this.gateway.button.wrapper);
- enable(this.gateway.messages.wrapper);
+ BootstrapHelper.handleButtonStatus(this);
}
shouldRender() {
@@ -64,8 +56,7 @@ class CartBootstrap {
}
shouldEnable() {
- return this.shouldRender()
- && this.gateway.button.is_disabled !== true;
+ return BootstrapHelper.shouldEnable(this);
}
render() {
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
index 551baa75b..b426ac3ee 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
@@ -5,6 +5,7 @@ import {
isSavedCardSelected, ORDER_BUTTON_SELECTOR,
PaymentMethods
} from "../Helper/CheckoutMethodState";
+import BootstrapHelper from "../Helper/BootstrapHelper";
import {disable, enable} from "../Helper/ButtonDisabler";
class CheckoutBootstap {
@@ -51,15 +52,7 @@ class CheckoutBootstap {
}
handleButtonStatus() {
- if (!this.shouldEnable()) {
- this.renderer.disableSmartButtons(this.gateway.button.wrapper);
- disable(this.gateway.button.wrapper);
- disable(this.gateway.messages.wrapper);
- return;
- }
- this.renderer.enableSmartButtons(this.gateway.button.wrapper);
- enable(this.gateway.button.wrapper);
- enable(this.gateway.messages.wrapper);
+ BootstrapHelper.handleButtonStatus(this);
}
shouldRender() {
@@ -71,8 +64,7 @@ class CheckoutBootstap {
}
shouldEnable() {
- return this.shouldRender()
- && this.gateway.button.is_disabled !== true;
+ return BootstrapHelper.shouldEnable(this);
}
render() {
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
index c993f3be0..4b4e3efd6 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
@@ -1,5 +1,5 @@
import CartActionHandler from '../ActionHandler/CartActionHandler';
-import {disable, enable} from "../Helper/ButtonDisabler";
+import BootstrapHelper from "../Helper/BootstrapHelper";
class MiniCartBootstap {
constructor(gateway, renderer, errorHandler) {
@@ -29,13 +29,10 @@ class MiniCartBootstap {
}
handleButtonStatus() {
- if (!this.shouldEnable()) {
- this.renderer.disableSmartButtons(this.gateway.button.mini_cart_wrapper);
- disable(this.gateway.button.mini_cart_wrapper);
- return;
- }
- this.renderer.enableSmartButtons(this.gateway.button.mini_cart_wrapper);
- enable(this.gateway.button.mini_cart_wrapper);
+ BootstrapHelper.handleButtonStatus(this, {
+ wrapper: this.gateway.button.mini_cart_wrapper,
+ skipMessages: true
+ });
}
shouldRender() {
@@ -44,8 +41,9 @@ class MiniCartBootstap {
}
shouldEnable() {
- return this.shouldRender()
- && this.gateway.button.is_mini_cart_disabled !== true;
+ return BootstrapHelper.shouldEnable(this, {
+ isDisabled: !!this.gateway.button.is_mini_cart_disabled
+ });
}
render() {
diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
index b7addb4a5..231460642 100644
--- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
+++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
@@ -1,7 +1,7 @@
import UpdateCart from "../Helper/UpdateCart";
import SingleProductActionHandler from "../ActionHandler/SingleProductActionHandler";
import {hide, show} from "../Helper/Hiding";
-import {disable, enable} from "../Helper/ButtonDisabler";
+import BootstrapHelper from "../Helper/BootstrapHelper";
class SingleProductBootstap {
constructor(gateway, renderer, messages, errorHandler) {
@@ -39,15 +39,9 @@ class SingleProductBootstap {
}
handleButtonStatus() {
- if (!this.shouldEnable()) {
- this.renderer.disableSmartButtons(this.gateway.button.wrapper);
- disable(this.gateway.button.wrapper, this.formSelector);
- disable(this.gateway.messages.wrapper);
- return;
- }
- this.renderer.enableSmartButtons(this.gateway.button.wrapper);
- enable(this.gateway.button.wrapper);
- enable(this.gateway.messages.wrapper);
+ BootstrapHelper.handleButtonStatus(this, {
+ formSelector: this.formSelector
+ });
}
init() {
@@ -92,10 +86,9 @@ class SingleProductBootstap {
const form = this.form();
const addToCartButton = form ? form.querySelector('.single_add_to_cart_button') : null;
- return this.shouldRender()
+ return BootstrapHelper.shouldEnable(this)
&& !this.priceAmountIsZero()
- && ((null === addToCartButton) || !addToCartButton.classList.contains('disabled'))
- && this.gateway.button.is_disabled !== true;
+ && ((null === addToCartButton) || !addToCartButton.classList.contains('disabled'));
}
priceAmount() {
diff --git a/modules/ppcp-button/resources/js/modules/Helper/BootstrapHelper.js b/modules/ppcp-button/resources/js/modules/Helper/BootstrapHelper.js
new file mode 100644
index 000000000..ba00e2c76
--- /dev/null
+++ b/modules/ppcp-button/resources/js/modules/Helper/BootstrapHelper.js
@@ -0,0 +1,40 @@
+import {disable, enable} from "./ButtonDisabler";
+
+/**
+ * Common Bootstrap methods to avoid code repetition.
+ */
+export default class BootstrapHelper {
+
+ static handleButtonStatus(bs, options) {
+ options = options || {};
+ options.wrapper = options.wrapper || bs.gateway.button.wrapper;
+ options.messagesWrapper = options.messagesWrapper || bs.gateway.messages.wrapper;
+ options.skipMessages = options.skipMessages || false;
+
+ if (!bs.shouldEnable()) {
+ 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);
+ }
+ }
+
+ static shouldEnable(bs, options) {
+ options = options || {};
+ if (typeof options.isDisabled === 'undefined') {
+ options.isDisabled = bs.gateway.button.is_disabled;
+ }
+
+ return bs.shouldRender()
+ && options.isDisabled !== true;
+ }
+}