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, ), ) );