Make SmartButton more reusable

This commit is contained in:
Alex P 2022-12-20 11:10:22 +02:00
parent 36fdfae960
commit 3b2f929df1
No known key found for this signature in database
GPG key ID: 54487A734A204D71
5 changed files with 84 additions and 41 deletions

View file

@ -6,7 +6,6 @@ import PayNowBootstrap from "./modules/ContextBootstrap/PayNowBootstrap";
import Renderer from './modules/Renderer/Renderer';
import ErrorHandler from './modules/ErrorHandler';
import CreditCardRenderer from "./modules/Renderer/CreditCardRenderer";
import dataClientIdAttributeHandler from "./modules/DataClientIdAttributeHandler";
import MessageRenderer from "./modules/Renderer/MessageRenderer";
import Spinner from "./modules/Helper/Spinner";
import {
@ -17,6 +16,7 @@ import {
import {hide, setVisible, setVisibleByClass} from "./modules/Helper/Hiding";
import {isChangePaymentPage} from "./modules/Helper/Subscriptions";
import FreeTrialHandler from "./modules/ActionHandler/FreeTrialHandler";
import {loadPaypalScript} from "./modules/Helper/ScriptLoading";
// TODO: could be a good idea to have a separate spinner for each gateway,
// but I think we care mainly about the script loading, so one spinner should be enough.
@ -240,24 +240,10 @@ document.addEventListener(
hideOrderButtonIfPpcpGateway();
});
const script = document.createElement('script');
script.addEventListener('load', (event) => {
loadPaypalScript(PayPalCommerceGateway, () => {
bootstrapped = true;
bootstrap();
});
script.setAttribute('src', PayPalCommerceGateway.button.url);
Object.entries(PayPalCommerceGateway.script_attributes).forEach(
(keyValue) => {
script.setAttribute(keyValue[0], keyValue[1]);
}
);
if (PayPalCommerceGateway.data_client_id.set_attribute) {
dataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);
return;
}
document.body.appendChild(script);
},
);

View file

@ -0,0 +1,24 @@
import dataClientIdAttributeHandler from "../DataClientIdAttributeHandler";
export const loadPaypalScript = (config, onLoaded) => {
if (typeof paypal !== 'undefined') {
onLoaded();
return;
}
const script = document.createElement('script');
script.addEventListener('load', onLoaded);
script.setAttribute('src', config.url);
Object.entries(config.script_attributes).forEach(
(keyValue) => {
script.setAttribute(keyValue[0], keyValue[1]);
}
);
if (config.data_client_id.set_attribute) {
dataClientIdAttributeHandler(script, config.data_client_id);
return;
}
document.body.appendChild(script);
}

View file

@ -24,12 +24,16 @@ class DisabledSmartButton implements SmartButtonInterface {
}
/**
* Enqueues necessary scripts.
*
* @return bool
* Whether the scripts should be loaded.
*/
public function enqueue(): bool {
return true;
public function should_load(): bool {
return false;
}
/**
* Enqueues necessary scripts.
*/
public function enqueue(): void {
}
/**
@ -41,4 +45,13 @@ class DisabledSmartButton implements SmartButtonInterface {
return false;
}
/**
* The configuration for the smart buttons.
*
* @return array
*/
public function script_data(): array {
return array();
}
}

View file

@ -493,17 +493,25 @@ class SmartButton implements SmartButtonInterface {
}
/**
* Enqueues the script.
*
* @return bool
* @throws NotFoundException When a setting was not found.
* Whether the scripts should be loaded.
*/
public function enqueue(): bool {
public function should_load(): bool {
$buttons_enabled = $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' );
if ( ! is_checkout() && ! $buttons_enabled ) {
return false;
}
return true;
}
/**
* Enqueues the scripts.
*/
public function enqueue(): void {
if ( ! $this->should_load() ) {
return;
}
$load_script = false;
if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
$load_script = true;
@ -541,10 +549,9 @@ class SmartButton implements SmartButtonInterface {
wp_localize_script(
'ppcp-smart-button',
'PayPalCommerceGateway',
$this->localize_script()
$this->script_data()
);
}
return true;
}
/**
@ -738,18 +745,22 @@ class SmartButton implements SmartButtonInterface {
}
/**
* The localized data for the smart button.
* The configuration for the smart buttons.
*
* @return array
* @throws NotFoundException If a setting hasn't been found.
*/
private function localize_script(): array {
public function script_data(): array {
global $wp;
$is_free_trial_cart = $this->is_free_trial_cart();
$url_params = $this->url_params();
$this->request_data->enqueue_nonce_fix();
$localize = array(
'url' => add_query_arg( $url_params, 'https://www.paypal.com/sdk/js' ),
'url_params' => $url_params,
'script_attributes' => $this->attributes(),
'data_client_id' => array(
'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(),
@ -788,7 +799,6 @@ class SmartButton implements SmartButtonInterface {
'wrapper' => '#ppc-button-' . PayPalGateway::ID,
'mini_cart_wrapper' => '#ppc-button-minicart',
'cancel_wrapper' => '#ppcp-cancel',
'url' => $this->url(),
'mini_cart_style' => array(
'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
'color' => $this->style_for_context( 'color', 'mini-cart' ),
@ -894,12 +904,12 @@ class SmartButton implements SmartButtonInterface {
}
/**
* The JavaScript SDK url to load.
* The JavaScript SDK url parameters.
*
* @return string
* @return array
* @throws NotFoundException If a setting was not found.
*/
private function url(): string {
private function url_params(): array {
$intent = ( $this->settings->has( 'intent' ) ) ? $this->settings->get( 'intent' ) : 'capture';
$product_intent = $this->subscription_helper->current_product_is_subscription() ? 'authorize' : $intent;
$other_context_intent = $this->subscription_helper->cart_contains_subscription() ? 'authorize' : $intent;
@ -971,8 +981,7 @@ class SmartButton implements SmartButtonInterface {
$params['enable-funding'] = implode( ',', array_unique( $enable_funding ) );
}
$smart_button_url = add_query_arg( $params, 'https://www.paypal.com/sdk/js' );
return $smart_button_url;
return $params;
}
/**
@ -1075,7 +1084,8 @@ class SmartButton implements SmartButtonInterface {
if ( is_cart() ) {
$context = 'cart';
}
if ( is_checkout() && ! $this->is_paypal_continuation() ) {
// TODO: refactor.
if ( is_checkout() && ! $this->is_paypal_continuation() || did_action( 'woocommerce_blocks_checkout_enqueue_data' ) ) {
$context = 'checkout';
}
if ( is_checkout_pay_page() ) {

View file

@ -22,11 +22,14 @@ interface SmartButtonInterface {
public function render_wrapper(): bool;
/**
* Enqueues the necessary scripts.
*
* @return bool
* Whether the scripts should be loaded.
*/
public function enqueue(): bool;
public function should_load(): bool;
/**
* Enqueues the necessary scripts.
*/
public function enqueue(): void;
/**
* Whether the running installation could save vault tokens or not.
@ -34,4 +37,11 @@ interface SmartButtonInterface {
* @return bool
*/
public function can_save_vault_token(): bool;
/**
* The configuration for the smart buttons.
*
* @return array
*/
public function script_data(): array;
}