🔀 Merge branch 'trunk'

This commit is contained in:
Philipp Stracker 2024-10-21 15:46:27 +02:00
commit 32d870bd6b
No known key found for this signature in database
39 changed files with 11104 additions and 307 deletions

View file

@ -716,7 +716,6 @@ return array(
'FR' => $mastercard_visa_amex,
'GB' => $mastercard_visa_amex,
'GR' => $mastercard_visa_amex,
'HK' => $mastercard_visa_amex,
'HU' => $mastercard_visa_amex,
'IE' => $mastercard_visa_amex,
'IT' => $mastercard_visa_amex,
@ -746,7 +745,6 @@ return array(
'SE' => $mastercard_visa_amex,
'SI' => $mastercard_visa_amex,
'SK' => $mastercard_visa_amex,
'SG' => $mastercard_visa_amex,
'JP' => array(
'mastercard' => array(),
'visa' => array(),

View file

@ -191,7 +191,6 @@ return array(
'FR', // France
'DE', // Germany
'GR', // Greece
'HK', // Hong Kong
'HU', // Hungary
'IE', // Ireland
'IT', // Italy
@ -205,7 +204,6 @@ return array(
'PL', // Poland
'PT', // Portugal
'RO', // Romania
'SG', // Singapore
'SK', // Slovakia
'SI', // Slovenia
'ES', // Spain

View file

@ -174,9 +174,6 @@ $fast-transition-duration: 0.5s;
grid-area: watermark;
justify-self: end;
grid-column: 1;
}
&:not(.wc-block-axo-is-authenticated) .wc-block-checkout-axo-block-watermark-container {
margin-top: 0;
}
@ -259,8 +256,8 @@ a.wc-block-axo-change-link {
.wp-block-woocommerce-checkout-fields-block:not(.wc-block-axo-is-loaded) {
.wc-block-checkout-axo-block-watermark-container {
display: flex;
justify-content: left;
margin-left: 10px;
justify-content: right;
margin-right: 10px;
align-items: center;
position: relative;

View file

@ -1,6 +1,7 @@
import { useEffect, useCallback, useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { log } from '../../../../../ppcp-axo/resources/js/Helper/Debug';
import { Card } from '../Card';
import { STORE_NAME } from '../../stores/axoStore';
@ -16,27 +17,48 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => {
const [ isCardElementReady, setIsCardElementReady ] = useState( false );
// Select relevant states from the AXO store
const { isGuest, isEmailLookupCompleted } = useSelect(
const { isGuest, isEmailLookupCompleted, cardDetails } = useSelect(
( select ) => ( {
isGuest: select( STORE_NAME ).getIsGuest(),
isEmailLookupCompleted:
select( STORE_NAME ).getIsEmailLookupCompleted(),
cardDetails: select( STORE_NAME ).getCardDetails(),
} ),
[]
);
/**
* Loads and renders the Fastlane card fields component when necessary.
* This function is called for:
* 1. Guest users who have completed email lookup
* 2. Authenticated users who are missing card details
*
* The component allows users to enter new card details for payment.
*/
const loadPaymentComponent = useCallback( async () => {
if ( isGuest && isEmailLookupCompleted && isCardElementReady ) {
const paymentComponent = await fastlaneSdk.FastlaneCardComponent(
{}
);
paymentComponent.render( `#fastlane-card` );
onPaymentLoad( paymentComponent );
if (
( isGuest && isEmailLookupCompleted && isCardElementReady ) ||
( ! isGuest && ! cardDetails )
) {
try {
const paymentComponent =
await fastlaneSdk.FastlaneCardComponent( {} );
// Check if the container exists before rendering
const cardContainer =
document.querySelector( '#fastlane-card' );
if ( cardContainer ) {
paymentComponent.render( '#fastlane-card' );
onPaymentLoad( paymentComponent );
}
} catch ( error ) {
log( `Error loading payment component: ${ error }`, 'error' );
}
}
}, [
isGuest,
isEmailLookupCompleted,
isCardElementReady,
cardDetails,
fastlaneSdk,
onPaymentLoad,
] );
@ -48,27 +70,48 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => {
}
}, [ isGuest, isEmailLookupCompleted ] );
// Load payment component when dependencies change
// Load payment component when card element is ready
useEffect( () => {
loadPaymentComponent();
}, [ loadPaymentComponent ] );
// Conditional rendering based on user state:
// 1. If authenticated: Render the Card component
// 2. If guest with completed email lookup: Render the card fields
// 3. If guest without completed email lookup: Render a message to enter email
if ( isGuest ) {
if ( isEmailLookupCompleted ) {
return <div id="fastlane-card" key="fastlane-card" />;
if ( isCardElementReady ) {
loadPaymentComponent();
}
return (
<div id="ppcp-axo-block-radio-content">
{ __(
'Enter your email address above to continue.',
'woocommerce-paypal-payments'
) }
</div>
);
}
return <Card fastlaneSdk={ fastlaneSdk } showWatermark={ ! isGuest } />;
}, [ isCardElementReady, loadPaymentComponent ] );
/**
* Determines which component to render based on the current state.
*
* Rendering logic:
* 1. For guests without completed email lookup: Show message to enter email
* 2. For guests with completed email lookup: Render Fastlane card fields
* 3. For authenticated users without card details: Render Fastlane card fields
* 4. For authenticated users with card details: Render Card component
*
* @return {JSX.Element} The appropriate component based on the current state
*/
const renderPaymentComponent = () => {
// Case 1: Guest user without completed email lookup
if ( isGuest && ! isEmailLookupCompleted ) {
return (
<div id="ppcp-axo-block-radio-content">
{ __(
'Enter your email address above to continue.',
'woocommerce-paypal-payments'
) }
</div>
);
}
// Case 2 & 3: Guest with completed email lookup or authenticated user without card details
if (
( isGuest && isEmailLookupCompleted ) ||
( ! isGuest && ! cardDetails )
) {
return <div id="fastlane-card" />;
}
// Case 4: Authenticated user with card details
return <Card fastlaneSdk={ fastlaneSdk } showWatermark={ ! isGuest } />;
};
return renderPaymentComponent();
};

View file

@ -16,9 +16,6 @@ import {
*/
const WatermarkManager = ( { fastlaneSdk } ) => {
// Select relevant states from the AXO store
const isGuest = useSelect( ( select ) =>
select( STORE_NAME ).getIsGuest()
);
const isAxoActive = useSelect( ( select ) =>
select( STORE_NAME ).getIsAxoActive()
);
@ -34,7 +31,6 @@ const WatermarkManager = ( { fastlaneSdk } ) => {
isAxoActive,
isAxoScriptLoaded,
fastlaneSdk,
isGuest,
} );
} else {
// Remove watermark when AXO is inactive and not loading
@ -43,7 +39,7 @@ const WatermarkManager = ( { fastlaneSdk } ) => {
// Cleanup function to remove watermark on unmount
return removeWatermark;
}, [ fastlaneSdk, isGuest, isAxoActive, isAxoScriptLoaded ] );
}, [ fastlaneSdk, isAxoActive, isAxoScriptLoaded ] );
// This component doesn't render anything directly
return null;

View file

@ -112,13 +112,11 @@ export const renderWatermarkContent = ( content ) => {
* @param {boolean} params.isAxoActive - Whether AXO is active.
* @param {boolean} params.isAxoScriptLoaded - Whether AXO script is loaded.
* @param {Object} params.fastlaneSdk - The Fastlane SDK instance.
* @param {boolean} params.isGuest - Whether the user is a guest.
*/
export const updateWatermarkContent = ( {
isAxoActive,
isAxoScriptLoaded,
fastlaneSdk,
isGuest,
} ) => {
if ( ! isAxoActive && ! isAxoScriptLoaded ) {
// Show loading spinner
@ -134,7 +132,7 @@ export const updateWatermarkContent = ( {
createElement( Watermark, {
fastlaneSdk,
name: 'fastlane-watermark-email',
includeAdditionalInfo: isGuest,
includeAdditionalInfo: true,
} )
);
} else {

View file

@ -18,7 +18,8 @@ import useCustomerData from './useCustomerData';
*/
const useAxoCleanup = () => {
// Get dispatch functions from the AXO store
const { setIsAxoActive, setIsGuest } = useDispatch( STORE_NAME );
const { setIsAxoActive, setIsGuest, setIsEmailLookupCompleted } =
useDispatch( STORE_NAME );
// Get functions to update WooCommerce shipping and billing addresses
const {
@ -45,6 +46,7 @@ const useAxoCleanup = () => {
// Reset AXO state
setIsAxoActive( false );
setIsGuest( true );
setIsEmailLookupCompleted( false );
// Remove AXO UI elements
removeShippingChangeButton();

View file

@ -17,6 +17,7 @@ use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExtendingModule;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
/**
* Class BlocksModule
@ -69,8 +70,11 @@ class BlocksModule implements ServiceModule, ExtendingModule, ExecutableModule {
function( PaymentMethodRegistry $payment_method_registry ) use ( $c ): void {
$payment_method_registry->register( $c->get( 'blocks.method' ) );
$settings = $c->get( 'wcgateway.settings' );
assert( $settings instanceof Settings );
// Include ACDC in the Block Checkout only in case Axo doesn't exist or is not available or the user is logged in.
if ( ! $c->has( 'axoblock.available' ) || ! $c->get( 'axoblock.available' ) || is_user_logged_in() ) {
if ( ( $settings->has( 'axo_enabled' ) && ! $settings->get( 'axo_enabled' ) ) || is_user_logged_in() ) {
$payment_method_registry->register( $c->get( 'blocks.advanced-card-method' ) );
}
}

View file

@ -43,7 +43,6 @@ return array(
'FR',
'DE',
'GR',
'HK',
'HU',
'IE',
'IT',
@ -57,7 +56,6 @@ return array(
'PT',
'RO',
'SK',
'SG',
'SI',
'ES',
'SE',

View file

@ -0,0 +1,53 @@
import { useState, useEffect } from '@wordpress/element';
import useGooglepayApiToGenerateButton from '../hooks/useGooglepayApiToGenerateButton';
import usePayPalScript from '../hooks/usePayPalScript';
import useGooglepayScript from '../hooks/useGooglepayScript';
import useGooglepayConfig from '../hooks/useGooglepayConfig';
const GooglepayButton = ( { namespace, buttonConfig, ppcpConfig } ) => {
const [ buttonHtml, setButtonHtml ] = useState( '' );
const [ buttonElement, setButtonElement ] = useState( null );
const [ componentFrame, setComponentFrame ] = useState( null );
const isPayPalLoaded = usePayPalScript( namespace, ppcpConfig );
const isGooglepayLoaded = useGooglepayScript(
componentFrame,
buttonConfig,
isPayPalLoaded
);
const googlepayConfig = useGooglepayConfig( namespace, isGooglepayLoaded );
useEffect( () => {
if ( ! buttonElement ) {
return;
}
setComponentFrame( buttonElement.ownerDocument );
}, [ buttonElement ] );
const googlepayButton = useGooglepayApiToGenerateButton(
componentFrame,
namespace,
buttonConfig,
ppcpConfig,
googlepayConfig
);
useEffect( () => {
if ( googlepayButton ) {
const hideLoader =
'<style>.block-editor-iframe__html .gpay-card-info-animated-progress-bar-container {display:none !important}</style>';
setButtonHtml( googlepayButton.outerHTML + hideLoader );
}
}, [ googlepayButton ] );
return (
<div
ref={ setButtonElement }
dangerouslySetInnerHTML={ { __html: buttonHtml } }
/>
);
};
export default GooglepayButton;

View file

@ -0,0 +1,19 @@
import { useMemo } from '@wordpress/element';
import { combineStyles } from '../../../../../ppcp-button/resources/js/modules/Helper/PaymentButtonHelpers';
const useButtonStyles = ( buttonConfig, ppcpConfig ) => {
return useMemo( () => {
const styles = combineStyles(
ppcpConfig?.button || {},
buttonConfig?.button || {}
);
if ( styles.MiniCart && styles.MiniCart.type === 'buy' ) {
styles.MiniCart.type = 'pay';
}
return styles;
}, [ buttonConfig, ppcpConfig ] );
};
export default useButtonStyles;

View file

@ -0,0 +1,57 @@
import { useEffect, useState } from '@wordpress/element';
import useButtonStyles from './useButtonStyles';
const useGooglepayApiToGenerateButton = (
componentDocument,
namespace,
buttonConfig,
ppcpConfig,
googlepayConfig
) => {
const [ googlepayButton, setGooglepayButton ] = useState( null );
const buttonStyles = useButtonStyles( buttonConfig, ppcpConfig );
useEffect( () => {
if (
! componentDocument?.defaultView ||
! buttonConfig ||
! googlepayConfig
) {
return;
}
const api = componentDocument.defaultView.google?.payments?.api;
if ( ! api ) {
return;
}
const paymentsClient = new api.PaymentsClient( {
environment: 'TEST',
} );
const googlePayButtonOptions = {
allowedPaymentMethods: googlepayConfig.allowedPaymentMethods,
buttonColor: buttonConfig.buttonColor || 'black',
buttonType: buttonConfig.buttonType || 'pay',
buttonLocale: buttonConfig.buttonLocale || 'en',
buttonSizeMode: 'fill',
};
const button = paymentsClient.createButton( {
...googlePayButtonOptions,
onClick: ( event ) => {
event.preventDefault();
},
} );
setGooglepayButton( button );
return () => {
setGooglepayButton( null );
};
}, [ namespace, buttonConfig, ppcpConfig, googlepayConfig, buttonStyles ] );
return googlepayButton;
};
export default useGooglepayApiToGenerateButton;

View file

@ -0,0 +1,26 @@
import { useState, useEffect } from '@wordpress/element';
const useGooglepayConfig = ( namespace, isGooglepayLoaded ) => {
const [ googlePayConfig, setGooglePayConfig ] = useState( null );
useEffect( () => {
const fetchConfig = async () => {
if ( ! isGooglepayLoaded ) {
return;
}
try {
const config = await window[ namespace ].Googlepay().config();
setGooglePayConfig( config );
} catch ( error ) {
console.error( 'Failed to fetch Google Pay config:', error );
}
};
fetchConfig();
}, [ namespace, isGooglepayLoaded ] );
return googlePayConfig;
};
export default useGooglepayConfig;

View file

@ -0,0 +1,65 @@
import { useState, useEffect } from '@wordpress/element';
import { loadCustomScript } from '@paypal/paypal-js';
const useGooglepayScript = (
componentDocument,
buttonConfig,
isPayPalLoaded
) => {
const [ isGooglepayLoaded, setIsGooglepayLoaded ] = useState( false );
useEffect( () => {
if ( ! componentDocument ) {
return;
}
const injectScriptToFrame = ( scriptSrc ) => {
if ( document === componentDocument ) {
return;
}
const script = document.querySelector(
`script[src^="${ scriptSrc }"]`
);
if ( script ) {
const newScript = componentDocument.createElement( 'script' );
newScript.src = script.src;
newScript.async = script.async;
newScript.type = script.type;
componentDocument.head.appendChild( newScript );
} else {
console.error( 'Script not found in the document:', scriptSrc );
}
};
const loadGooglepayScript = async () => {
if ( ! isPayPalLoaded ) {
return;
}
if ( ! buttonConfig || ! buttonConfig.sdk_url ) {
console.error( 'Invalid buttonConfig or missing sdk_url' );
return;
}
try {
await loadCustomScript( { url: buttonConfig.sdk_url } ).then(
() => {
injectScriptToFrame( buttonConfig.sdk_url );
}
);
setIsGooglepayLoaded( true );
} catch ( error ) {
console.error( 'Failed to load Googlepay script:', error );
}
};
loadGooglepayScript();
}, [ componentDocument, buttonConfig, isPayPalLoaded ] );
return isGooglepayLoaded;
};
export default useGooglepayScript;

View file

@ -0,0 +1,25 @@
import { useState, useEffect } from '@wordpress/element';
import { loadPayPalScript } from '../../../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
const usePayPalScript = ( namespace, ppcpConfig ) => {
const [ isPayPalLoaded, setIsPayPalLoaded ] = useState( false );
ppcpConfig.url_params.components += ',googlepay';
useEffect( () => {
const loadScript = async () => {
try {
await loadPayPalScript( namespace, ppcpConfig );
setIsPayPalLoaded( true );
} catch ( error ) {
console.error( `Error loading PayPal script: ${ error }` );
}
};
loadScript();
}, [ namespace, ppcpConfig ] );
return isPayPalLoaded;
};
export default usePayPalScript;

View file

@ -1,62 +1,15 @@
import GooglepayButton from './GooglepayButton';
import ContextHandlerFactory from './Context/ContextHandlerFactory';
import GooglepayButton from './Block/components/GooglepayButton';
class GooglepayManagerBlockEditor {
constructor( namespace, buttonConfig, ppcpConfig ) {
this.namespace = namespace;
this.buttonConfig = buttonConfig;
this.ppcpConfig = ppcpConfig;
this.googlePayConfig = null;
this.transactionInfo = null;
this.contextHandler = null;
}
init() {
( async () => {
await this.config();
} )();
}
async config() {
try {
// Gets GooglePay configuration of the PayPal merchant.
this.googlePayConfig = await window[ this.namespace ]
.Googlepay()
.config();
// Fetch transaction information.
this.transactionInfo = await this.fetchTransactionInfo();
const button = new GooglepayButton(
this.ppcpConfig.context,
null,
this.buttonConfig,
this.ppcpConfig,
this.contextHandler
);
button.init( this.googlePayConfig, this.transactionInfo );
} catch ( error ) {
console.error( 'Failed to initialize Google Pay:', error );
}
}
async fetchTransactionInfo() {
try {
if ( ! this.contextHandler ) {
this.contextHandler = ContextHandlerFactory.create(
this.ppcpConfig.context,
this.buttonConfig,
this.ppcpConfig,
null
);
}
return null;
} catch ( error ) {
console.error( 'Error fetching transaction info:', error );
throw error;
}
}
}
const GooglepayManagerBlockEditor = ( {
namespace,
buttonConfig,
ppcpConfig,
} ) => (
<GooglepayButton
namespace={ namespace }
buttonConfig={ buttonConfig }
ppcpConfig={ ppcpConfig }
/>
);
export default GooglepayManagerBlockEditor;

View file

@ -1,4 +1,5 @@
import { useEffect, useState } from '@wordpress/element';
import { loadCustomScript } from '@paypal/paypal-js';
import {
registerExpressPaymentMethod,
registerPaymentMethod,
@ -6,7 +7,6 @@ import {
import { __ } from '@wordpress/i18n';
import { loadPayPalScript } from '../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
import GooglepayManager from './GooglepayManager';
import { loadCustomScript } from '@paypal/paypal-js';
import GooglepayManagerBlockEditor from './GooglepayManagerBlockEditor';
const ppcpData = wc.wcSettings.getSetting( 'ppcp-gateway_data' );
@ -20,56 +20,55 @@ if ( typeof window.PayPalCommerceGateway === 'undefined' ) {
window.PayPalCommerceGateway = ppcpConfig;
}
const GooglePayComponent = ( props ) => {
const [ bootstrapped, setBootstrapped ] = useState( false );
const GooglePayComponent = ( { isEditing } ) => {
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
const [ googlePayLoaded, setGooglePayLoaded ] = useState( false );
const [ manager, setManager ] = useState( null );
useEffect( () => {
// Load GooglePay SDK
loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => {
setGooglePayLoaded( true );
} );
ppcpConfig.url_params.components += ',googlepay';
// Load PayPal
loadPayPalScript( namespace, ppcpConfig )
.then( () => {
setPaypalLoaded( true );
} )
.catch( ( error ) => {
console.error( 'Failed to load PayPal script: ', error );
if ( ! isEditing ) {
loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => {
setGooglePayLoaded( true );
} );
}, [] );
ppcpConfig.url_params.components += ',googlepay';
loadPayPalScript( namespace, ppcpConfig )
.then( () => {
setPaypalLoaded( true );
} )
.catch( ( error ) => {
console.error( 'Failed to load PayPal script: ', error );
} );
}
}, [ isEditing, buttonConfig, ppcpConfig ] );
useEffect( () => {
if ( paypalLoaded && googlePayLoaded && ! manager ) {
const ManagerClass = props.isEditing
? GooglepayManagerBlockEditor
: GooglepayManager;
const newManager = new ManagerClass(
if ( ! isEditing && paypalLoaded && googlePayLoaded && ! manager ) {
const newManager = new GooglepayManager(
namespace,
buttonConfig,
ppcpConfig
);
setManager( newManager );
}
}, [ paypalLoaded, googlePayLoaded, props.isEditing ] );
}, [ paypalLoaded, googlePayLoaded, isEditing, manager ] );
useEffect( () => {
if ( manager && ! bootstrapped ) {
setBootstrapped( true );
manager.init();
}
}, [ manager, bootstrapped ] );
if ( isEditing ) {
return (
<GooglepayManagerBlockEditor
namespace={ namespace }
buttonConfig={ buttonConfig }
ppcpConfig={ ppcpConfig }
/>
);
}
return (
<div
id={ buttonConfig.button.wrapper.replace( '#', '' ) }
className="ppcp-button-apm ppcp-button-googlepay"
></div>
/>
);
};

View file

@ -106,7 +106,6 @@ return array(
'FR', // France
'DE', // Germany
'GR', // Greece
'HK', // Hong Kong
'HU', // Hungary
'IE', // Ireland
'IT', // Italy
@ -120,7 +119,6 @@ return array(
'PL', // Poland
'PT', // Portugal
'RO', // Romania
'SG', // Singapore
'SK', // Slovakia
'SI', // Slovenia
'ES', // Spain

View file

@ -72,7 +72,6 @@ return array(
'FR' => $default_currencies,
'DE' => $default_currencies,
'GR' => $default_currencies,
'HK' => $default_currencies,
'HU' => $default_currencies,
'IE' => $default_currencies,
'IT' => $default_currencies,
@ -87,7 +86,6 @@ return array(
'PT' => $default_currencies,
'RO' => $default_currencies,
'SK' => $default_currencies,
'SG' => $default_currencies,
'SI' => $default_currencies,
'ES' => $default_currencies,
'SE' => $default_currencies,

View file

@ -0,0 +1,16 @@
{
"name": "woocommerce/ppcp-settings",
"type": "inpsyde-module",
"description": "Settings module",
"license": "GPL-2.0",
"require": {
"php": "^7.4 | ^8.0"
},
"autoload": {
"psr-4": {
"WooCommerce\\PayPalCommerce\\Settings\\": "src"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}

View file

@ -0,0 +1,14 @@
<?php
/**
* The Settings module.
*
* @package WooCommerce\PayPalCommerce\Settings
*/
declare( strict_types = 1 );
namespace WooCommerce\PayPalCommerce\Settings;
return static function () : SettingsModule {
return new SettingsModule();
};

View file

@ -0,0 +1,12 @@
{
"name": "ppcp-settings",
"version": "1.0.0",
"license": "GPL-3.0-or-later",
"scripts": {
"watch": "wp-scripts start --webpack-src-dir=resources/js --output-path=assets",
"build": "wp-scripts build --webpack-src-dir=resources/js --output-path=assets"
},
"devDependencies": {
"@wordpress/scripts": "^30.3.0"
}
}

View file

@ -0,0 +1 @@
.red {color:red;}

View file

@ -0,0 +1,3 @@
export function App() {
return <div className="red">App</div>;
}

View file

@ -0,0 +1,7 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './App';
createRoot( document.getElementById( 'ppcp-settings-container' ) ).render(
<App />
);

View file

@ -0,0 +1,26 @@
<?php
/**
* The Settings module services.
*
* @package WooCommerce\PayPalCommerce\Settings
*/
declare( strict_types = 1 );
namespace WooCommerce\PayPalCommerce\Settings;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
return array(
'settings.url' => static function ( ContainerInterface $container ) : string {
/**
* The path cannot be false.
*
* @psalm-suppress PossiblyFalseArgument
*/
return plugins_url(
'/modules/ppcp-settings/',
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
);
},
);

View file

@ -0,0 +1,95 @@
<?php
/**
* The Settings module.
*
* @package WooCommerce\PayPalCommerce\AxoBlock
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Settings;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExecutableModule;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
/**
* Class SettingsModule
*/
class SettingsModule implements ServiceModule, ExecutableModule {
use ModuleClassNameIdTrait;
/**
* {@inheritDoc}
*/
public function services(): array {
return require __DIR__ . '/../services.php';
}
/**
* {@inheritDoc}
*/
public function run( ContainerInterface $container ): bool {
add_action(
'admin_enqueue_scripts',
/**
* Param types removed to avoid third-party issues.
*
* @psalm-suppress MissingClosureParamType
*/
static function( $hook_suffix ) use ( $container ) {
if ( 'woocommerce_page_wc-settings' !== $hook_suffix ) {
return;
}
/**
* Require resolves.
*
* @psalm-suppress UnresolvableInclude
*/
$script_asset_file = require dirname( realpath( __FILE__ ) ?: '', 2 ) . '/assets/index.asset.php';
$module_url = $container->get( 'settings.url' );
wp_register_script(
'ppcp-admin-settings',
$module_url . '/assets/index.js',
$script_asset_file['dependencies'],
$script_asset_file['version'],
true
);
wp_enqueue_script( 'ppcp-admin-settings' );
/**
* Require resolves.
*
* @psalm-suppress UnresolvableInclude
*/
$style_asset_file = require dirname( realpath( __FILE__ ) ?: '', 2 ) . '/assets/style.asset.php';
wp_register_style(
'ppcp-admin-settings',
$module_url . '/assets/style-style.css',
$style_asset_file['dependencies'],
$style_asset_file['version']
);
wp_enqueue_style( 'ppcp-admin-settings' );
}
);
add_action(
'woocommerce_paypal_payments_gateway_admin_options_wrapper',
static function(): void {
global $hide_save_button;
$hide_save_button = true;
echo '<div id="ppcp-settings-container"></div>';
}
);
return true;
}
}

View file

@ -0,0 +1,12 @@
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
const path = require( 'path' );
module.exports = {
...defaultConfig,
...{
entry: {
index: path.resolve( process.cwd(), 'resources/js', 'index.js' ),
style: path.resolve( process.cwd(), 'resources/css', 'style.scss' ),
},
},
};

File diff suppressed because it is too large Load diff

View file

@ -118,7 +118,8 @@ return array(
$container->get( 'wcgateway.place-order-button-text' ),
$container->get( 'api.endpoint.payment-tokens' ),
$container->get( 'vaulting.vault-v3-enabled' ),
$container->get( 'vaulting.wc-payment-tokens' )
$container->get( 'vaulting.wc-payment-tokens' ),
$container->get( 'wcgateway.settings.admin-settings-enabled' )
);
},
'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
@ -1914,4 +1915,8 @@ return array(
return $simple_redirect_tasks;
},
'wcgateway.settings.admin-settings-enabled' => static function( ContainerInterface $container ): bool {
return $container->has( 'settings.url' );
},
);

View file

@ -202,6 +202,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
*/
private $wc_payment_tokens;
/**
* Whether settings module is enabled.
*
* @var bool
*/
private $admin_settings_enabled;
/**
* PayPalGateway constructor.
*
@ -225,6 +232,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
* @param bool $vault_v3_enabled Whether Vault v3 module is enabled.
* @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens.
* @param bool $admin_settings_enabled Whether settings module is enabled.
*/
public function __construct(
SettingsRenderer $settings_renderer,
@ -246,7 +254,8 @@ class PayPalGateway extends \WC_Payment_Gateway {
string $place_order_button_text,
PaymentTokensEndpoint $payment_tokens_endpoint,
bool $vault_v3_enabled,
WooCommercePaymentTokens $wc_payment_tokens
WooCommercePaymentTokens $wc_payment_tokens,
bool $admin_settings_enabled
) {
$this->id = self::ID;
$this->settings_renderer = $settings_renderer;
@ -270,6 +279,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
$this->vault_v3_enabled = $vault_v3_enabled;
$this->wc_payment_tokens = $wc_payment_tokens;
$this->admin_settings_enabled = $admin_settings_enabled;
$default_support = array(
'products',
@ -745,6 +755,17 @@ class PayPalGateway extends \WC_Payment_Gateway {
return $ret;
}
/**
* Override the parent admin_options method.
*/
public function admin_options() {
if ( ! $this->admin_settings_enabled ) {
parent::admin_options();
}
do_action( 'woocommerce_paypal_payments_gateway_admin_options_wrapper', $this );
}
/**
* Returns the settings renderer.
*