♻️ Minor code cleanup and documentation

This commit is contained in:
Philipp Stracker 2024-07-23 17:36:10 +02:00
parent eb216425fb
commit a473459ddb
No known key found for this signature in database
8 changed files with 142 additions and 105 deletions

View file

@ -10,6 +10,23 @@ import ErrorHandler from '../../../ppcp-button/resources/js/modules/ErrorHandler
import widgetBuilder from '../../../ppcp-button/resources/js/modules/Renderer/WidgetBuilder';
import { apmButtonsInit } from '../../../ppcp-button/resources/js/modules/Helper/ApmButtons';
/**
* List of valid context values that the button can have.
*
* @type {Object}
*/
const CONTEXT = {
Product: 'product',
Cart: 'cart',
Checkout: 'checkout',
PayNow: 'pay-now',
MiniCart: 'mini-cart',
BlockCart: 'cart-block',
BlockCheckout: 'checkout-block',
Preview: 'preview',
Blocks: [ 'cart-block', 'checkout-block' ],
};
/**
* A payment button for Apple Pay.
*
@ -32,6 +49,20 @@ class ApplePayButton {
*/
context = '';
externalHandler = null;
buttonConfig = null;
ppcpConfig = null;
paymentsClient = null;
formData = null;
contextHandler = null;
updatedContactInfo = [];
selectedShippingMethod = [];
/**
* Stores initialization data sent to the button.
*/
initialPaymentRequest = null;
constructor( context, externalHandler, buttonConfig, ppcpConfig ) {
apmButtonsInit( ppcpConfig );
@ -39,8 +70,6 @@ class ApplePayButton {
this.externalHandler = externalHandler;
this.buttonConfig = buttonConfig;
this.ppcpConfig = ppcpConfig;
this.paymentsClient = null;
this.formData = null;
this.contextHandler = ContextHandlerFactory.create(
this.context,
@ -48,18 +77,6 @@ class ApplePayButton {
this.ppcpConfig
);
this.updatedContactInfo = [];
this.selectedShippingMethod = [];
this.nonce =
document.getElementById( 'woocommerce-process-checkout-nonce' )
?.value || buttonConfig.nonce;
// Stores initialization data sent to the button.
this.initialPaymentRequest = null;
// Default eligibility status.
this.isEligible = true;
this.log = function () {
if ( this.buttonConfig.is_debug ) {
//console.log('[ApplePayButton]', ...arguments);
@ -76,6 +93,39 @@ class ApplePayButton {
document.ppcpApplepayButtons[ this.context ] = this;
}
/**
* The nonce for ajax requests.
*
* @return {string} The nonce value
*/
get nonce() {
const input = document.getElementById(
'woocommerce-process-checkout-nonce'
);
return input?.value || this.buttonConfig.nonce;
}
/**
* Whether the current page qualifies to use the Apple Pay button.
*
* In admin, the button is always eligible, to display an accurate preview.
* On front-end, PayPal's response decides if customers can use Apple Pay.
*
* @return {boolean} True, if the button can be displayed.
*/
get isEligible() {
if ( ! this.isInitialized ) {
return true;
}
if ( this.buttonConfig.is_admin ) {
return true;
}
return !! ( this.applePayConfig.isEligible && window.ApplePaySession );
}
init( config ) {
if ( this.isInitialized ) {
return;
@ -90,9 +140,6 @@ class ApplePayButton {
this.isInitialized = true;
this.applePayConfig = config;
this.isEligible =
( this.applePayConfig.isEligible && window.ApplePaySession ) ||
this.buttonConfig.is_admin;
const idMinicart = this.buttonConfig.button.mini_cart_wrapper;
const idButton = this.buttonConfig.button.wrapper;
@ -118,7 +165,7 @@ class ApplePayButton {
this.fetchTransactionInfo().then( () => {
this.addButton();
if ( this.context === 'mini-cart' ) {
if ( CONTEXT.MiniCart === this.context ) {
setupButtonEvents( idMinicart );
} else {
setupButtonEvents( idButton );
@ -143,23 +190,22 @@ class ApplePayButton {
* Returns configurations relative to this button context.
*/
contextConfig() {
const config = {
wrapper: this.buttonConfig.button.wrapper,
ppcpStyle: this.ppcpConfig.button.style,
buttonStyle: this.buttonConfig.button.style,
ppcpButtonWrapper: this.ppcpConfig.button.wrapper,
};
const config = {};
if ( this.context === 'mini-cart' ) {
if ( CONTEXT.MiniCart === this.context ) {
config.wrapper = this.buttonConfig.button.mini_cart_wrapper;
config.ppcpStyle = this.ppcpConfig.button.mini_cart_style;
config.buttonStyle = this.buttonConfig.button.mini_cart_style;
config.ppcpButtonWrapper = this.ppcpConfig.button.mini_cart_wrapper;
} else {
config.wrapper = this.buttonConfig.button.wrapper;
config.ppcpStyle = this.ppcpConfig.button.style;
config.buttonStyle = this.buttonConfig.button.style;
config.ppcpButtonWrapper = this.ppcpConfig.button.wrapper;
}
if (
[ 'cart-block', 'checkout-block' ].indexOf( this.context ) !== -1
) {
// Block editor configuration.
if ( CONTEXT.Blocks.includes( this.context ) ) {
config.ppcpButtonWrapper =
'#express-payment-method-ppcp-gateway-paypal';
}
@ -203,8 +249,9 @@ class ApplePayButton {
}
/**
* Starts an ApplePay session.
* @param paymentRequest
* Starts an Apple Pay session.
*
* @param {Object} paymentRequest The payment request object.
*/
applePaySession( paymentRequest ) {
this.log( 'applePaySession', paymentRequest );
@ -269,7 +316,7 @@ class ApplePayButton {
window.ppcpFundingSource = 'apple_pay';
// Trigger woocommerce validation if we are in the checkout page.
if ( this.context === 'checkout' ) {
if ( CONTEXT.Checkout === this.context ) {
const checkoutFormSelector = 'form.woocommerce-checkout';
const errorHandler = new ErrorHandler(
PayPalCommerceGateway.labels.error.generic,
@ -323,13 +370,13 @@ class ApplePayButton {
/**
* If the button should show the shipping fields.
*
* @return {false|*}
* @return {boolean} True, if shipping fields should be captured by ApplePay.
*/
shouldRequireShippingInButton() {
return (
this.contextHandler.shippingAllowed() &&
this.buttonConfig.product.needShipping &&
( this.context !== 'checkout' ||
( CONTEXT.Checkout !== this.context ||
this.shouldUpdateButtonWithFormData() )
);
}
@ -337,10 +384,10 @@ class ApplePayButton {
/**
* If the button should be updated with the form addresses.
*
* @return {boolean}
* @return {boolean} True, when Apple Pay data should be submitted to WooCommerce.
*/
shouldUpdateButtonWithFormData() {
if ( this.context !== 'checkout' ) {
if ( CONTEXT.Checkout !== this.context ) {
return false;
}
return (
@ -353,7 +400,7 @@ class ApplePayButton {
* Indicates how payment completion should be handled if with the context handler default
* actions. Or with Apple Pay module specific completion.
*
* @return {boolean}
* @return {boolean} True, when the Apple Pay data should be submitted to WooCommerce.
*/
shouldCompletePaymentWithContextHandler() {
// Data already handled, ex: PayNow
@ -363,7 +410,7 @@ class ApplePayButton {
// Use WC form data mode in Checkout.
return (
this.context === 'checkout' &&
CONTEXT.Checkout === this.context &&
! this.shouldUpdateButtonWithFormData()
);
}
@ -371,7 +418,7 @@ class ApplePayButton {
/**
* Updates Apple Pay paymentRequest with form data.
*
* @param paymentRequest
* @param {Object} paymentRequest Object to extend with form data.
*/
updateRequestDataWithForm( paymentRequest ) {
if ( ! this.shouldUpdateButtonWithFormData() ) {
@ -481,11 +528,11 @@ class ApplePayButton {
}
refreshContextData() {
if ( 'product' === this.context ) {
// Refresh product data that makes the price change.
if ( CONTEXT.Product === this.context ) {
// Refresh product data that makes the price change.
this.productQuantity = document.querySelector( 'input.qty' )?.value;
this.products = this.contextHandler.products();
this.log( 'Products updated', this.products );
this.products = this.contextHandler.products();
this.log( 'Products updated', this.products );
}
}
@ -518,8 +565,9 @@ class ApplePayButton {
*
* @see https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778021-onvalidatemerchant
*
* @param session
* @return {(function(*): void)|*}
* @param {Object} session The ApplePaySession object.
*
* @return {(function(*): void)|*} Callback that runs after the merchant validation
*/
onValidateMerchant( session ) {
return ( applePayValidateMerchantEvent ) => {
@ -548,14 +596,14 @@ class ApplePayButton {
onShippingMethodSelected( session ) {
this.log( 'onshippingmethodselected', this.buttonConfig.ajax_url );
const ajax_url = this.buttonConfig.ajax_url;
const ajaxUrl = this.buttonConfig.ajax_url;
return ( event ) => {
this.log( 'onshippingmethodselected call' );
const data = this.getShippingMethodData( event );
jQuery.ajax( {
url: ajax_url,
url: ajaxUrl,
method: 'POST',
data,
success: (
@ -599,7 +647,7 @@ class ApplePayButton {
onShippingContactSelected( session ) {
this.log( 'onshippingcontactselected', this.buttonConfig.ajax_url );
const ajax_url = this.buttonConfig.ajax_url;
const ajaxUrl = this.buttonConfig.ajax_url;
return ( event ) => {
this.log( 'onshippingcontactselected call' );
@ -607,7 +655,7 @@ class ApplePayButton {
const data = this.getShippingContactData( event );
jQuery.ajax( {
url: ajax_url,
url: ajaxUrl,
method: 'POST',
data,
success: (
@ -637,15 +685,15 @@ class ApplePayButton {
}
getShippingContactData( event ) {
const product_id = this.buttonConfig.product.id;
const productId = this.buttonConfig.product.id;
this.refreshContextData();
switch ( this.context ) {
case 'product':
case CONTEXT.Product:
return {
action: 'ppcp_update_shipping_contact',
product_id,
product_id: productId,
products: JSON.stringify( this.products ),
caller_page: 'productDetail',
product_quantity: this.productQuantity,
@ -653,11 +701,12 @@ class ApplePayButton {
need_shipping: this.shouldRequireShippingInButton(),
'woocommerce-process-checkout-nonce': this.nonce,
};
case 'cart':
case 'checkout':
case 'cart-block':
case 'checkout-block':
case 'mini-cart':
case CONTEXT.Cart:
case CONTEXT.Checkout:
case CONTEXT.BlockCart:
case CONTEXT.BlockCheckout:
case CONTEXT.MiniCart:
return {
action: 'ppcp_update_shipping_contact',
simplified_contact: event.shippingContact,
@ -669,12 +718,12 @@ class ApplePayButton {
}
getShippingMethodData( event ) {
const product_id = this.buttonConfig.product.id;
const productId = this.buttonConfig.product.id;
this.refreshContextData();
switch ( this.context ) {
case 'product':
case CONTEXT.Product:
return {
action: 'ppcp_update_shipping_method',
shipping_method: event.shippingMethod,
@ -682,17 +731,18 @@ class ApplePayButton {
this.updatedContactInfo ||
this.initialPaymentRequest.shippingContact ||
this.initialPaymentRequest.billingContact,
product_id,
product_id: productId,
products: JSON.stringify( this.products ),
caller_page: 'productDetail',
product_quantity: this.productQuantity,
'woocommerce-process-checkout-nonce': this.nonce,
};
case 'cart':
case 'checkout':
case 'cart-block':
case 'checkout-block':
case 'mini-cart':
case CONTEXT.Cart:
case CONTEXT.Checkout:
case CONTEXT.BlockCart:
case CONTEXT.BlockCheckout:
case CONTEXT.MiniCart:
return {
action: 'ppcp_update_shipping_method',
shipping_method: event.shippingMethod,
@ -711,10 +761,6 @@ class ApplePayButton {
return async ( event ) => {
this.log( 'onpaymentauthorized call' );
function form() {
return document.querySelector( 'form.cart' );
}
const processInWooAndCapture = async ( data ) => {
return new Promise( ( resolve, reject ) => {
try {
@ -729,7 +775,7 @@ class ApplePayButton {
( this.initialPaymentRequest.shippingMethods ||
[] )[ 0 ];
const request_data = {
const requestData = {
action: 'ppcp_create_order',
caller_page: this.context,
product_id: this.buttonConfig.product.id ?? null,
@ -754,7 +800,7 @@ class ApplePayButton {
jQuery.ajax( {
url: this.buttonConfig.ajax_url,
method: 'POST',
data: request_data,
data: requestData,
complete: ( jqXHR, textStatus ) => {
this.log( 'onpaymentauthorized complete' );
},
@ -829,15 +875,15 @@ class ApplePayButton {
restart: () =>
new Promise(
( resolve, reject ) => {
approveFailed = true;
resolve();
approveFailed = true;
resolve();
}
),
order: {
get: () =>
new Promise(
( resolve, reject ) => {
resolve( null );
resolve( null );
}
),
},

View file

@ -1,7 +1,9 @@
import buttonModuleWatcher from '../../../ppcp-button/resources/js/modules/ButtonModuleWatcher';
import ApplepayButton from './ApplepayButton';
/* global paypal */
class ApplepayManager {
import buttonModuleWatcher from '../../../ppcp-button/resources/js/modules/ButtonModuleWatcher';
import ApplePayButton from './ApplepayButton';
class ApplePayManager {
constructor( buttonConfig, ppcpConfig ) {
this.buttonConfig = buttonConfig;
this.ppcpConfig = ppcpConfig;
@ -9,7 +11,7 @@ class ApplepayManager {
this.buttons = [];
buttonModuleWatcher.watchContextBootstrap( ( bootstrap ) => {
const button = new ApplepayButton(
const button = new ApplePayButton(
bootstrap.context,
bootstrap.handler,
buttonConfig,
@ -40,8 +42,7 @@ class ApplepayManager {
}
/**
* Gets ApplePay configuration of the PayPal merchant.
* @return {Promise<null>}
* Gets Apple Pay configuration of the PayPal merchant.
*/
async config() {
this.ApplePayConfig = await paypal.Applepay().config();
@ -49,4 +50,4 @@ class ApplepayManager {
}
}
export default ApplepayManager;
export default ApplePayManager;

View file

@ -1,6 +1,8 @@
import ApplepayButton from './ApplepayButton';
/* global paypal */
class ApplepayManagerBlockEditor {
import ApplePayButton from './ApplepayButton';
class ApplePayManagerBlockEditor {
constructor( buttonConfig, ppcpConfig ) {
this.buttonConfig = buttonConfig;
this.ppcpConfig = ppcpConfig;
@ -17,7 +19,7 @@ class ApplepayManagerBlockEditor {
try {
this.applePayConfig = await paypal.Applepay().config();
const button = new ApplepayButton(
const button = new ApplePayButton(
this.ppcpConfig.context,
null,
this.buttonConfig,
@ -31,4 +33,4 @@ class ApplepayManagerBlockEditor {
}
}
export default ApplepayManagerBlockEditor;
export default ApplePayManagerBlockEditor;

View file

@ -1,6 +1,5 @@
import ErrorHandler from '../../../../ppcp-button/resources/js/modules/ErrorHandler';
import CartActionHandler from '../../../../ppcp-button/resources/js/modules/ActionHandler/CartActionHandler';
import { isPayPalSubscription } from '../../../../ppcp-blocks/resources/js/Helper/Subscription';
class BaseHandler {
constructor( buttonConfig, ppcpConfig ) {
@ -76,13 +75,6 @@ class BaseHandler {
document.querySelector( '.woocommerce-notices-wrapper' )
);
}
errorHandler() {
return new ErrorHandler(
this.ppcpConfig.labels.error.generic,
document.querySelector( '.woocommerce-notices-wrapper' )
);
}
}
export default BaseHandler;

View file

@ -1,10 +1,6 @@
import BaseHandler from './BaseHandler';
class PreviewHandler extends BaseHandler {
constructor( buttonConfig, ppcpConfig, externalHandler ) {
super( buttonConfig, ppcpConfig, externalHandler );
}
transactionInfo() {
// We need to return something as ApplePay button initialization expects valid data.
return {
@ -19,7 +15,7 @@ class PreviewHandler extends BaseHandler {
throw new Error( 'Create order fail. This is just a preview.' );
}
approveOrder( data, actions ) {
approveOrder() {
throw new Error( 'Approve order fail. This is just a preview.' );
}

View file

@ -1,4 +1,4 @@
import ApplepayButton from './ApplepayButton';
import ApplePayButton from './ApplepayButton';
import PreviewButton from '../../../ppcp-button/resources/js/modules/Renderer/PreviewButton';
import PreviewButtonManager from '../../../ppcp-button/resources/js/modules/Renderer/PreviewButtonManager';
@ -86,7 +86,7 @@ class ApplePayPreviewButton extends PreviewButton {
}
createButton( buttonConfig ) {
const button = new ApplepayButton(
const button = new ApplePayButton(
'preview',
null,
buttonConfig,

View file

@ -4,8 +4,8 @@ import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Help
import { cartHasSubscriptionProducts } from '../../../ppcp-blocks/resources/js/Helper/Subscription';
import { loadCustomScript } from '@paypal/paypal-js';
import CheckoutHandler from './Context/CheckoutHandler';
import ApplepayManager from './ApplepayManager';
import ApplepayManagerBlockEditor from './ApplepayManagerBlockEditor';
import ApplePayManager from './ApplepayManager';
import ApplePayManagerBlockEditor from './ApplepayManagerBlockEditor';
const ppcpData = wc.wcSettings.getSetting( 'ppcp-gateway_data' );
const ppcpConfig = ppcpData.scriptData;
@ -24,8 +24,8 @@ const ApplePayComponent = ( props ) => {
const bootstrap = function () {
const ManagerClass = props.isEditing
? ApplepayManagerBlockEditor
: ApplepayManager;
? ApplePayManagerBlockEditor
: ApplePayManager;
const manager = new ManagerClass( buttonConfig, ppcpConfig );
manager.init();
};

View file

@ -1,13 +1,13 @@
import { loadCustomScript } from '@paypal/paypal-js';
import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading';
import ApplepayManager from './ApplepayManager';
import ApplePayManager from './ApplepayManager';
import { setupButtonEvents } from '../../../ppcp-button/resources/js/modules/Helper/ButtonRefreshHelper';
( function ( { buttonConfig, ppcpConfig, jQuery } ) {
let manager;
const bootstrap = function () {
manager = new ApplepayManager( buttonConfig, ppcpConfig );
manager = new ApplePayManager( buttonConfig, ppcpConfig );
manager.init();
};