Limit Pay Later Messaging block to only 1 per page. Fix Pay Later WC blocks messaging. Ensure proper config renders both in the editor and the page.

This commit is contained in:
Daniel Dudzic 2024-04-08 23:35:53 +02:00
parent d30b44d18e
commit 64bd0a2da8
No known key found for this signature in database
GPG key ID: 31B40D33E3465483
37 changed files with 3911 additions and 219 deletions

View file

@ -0,0 +1,14 @@
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": "3.25.0"
}
],
[
"@babel/preset-react"
]
]
}

View file

@ -0,0 +1,3 @@
node_modules
assets/js
assets/css

View file

@ -0,0 +1,17 @@
{
"name": "woocommerce/ppcp-paylater-wc-blocks",
"type": "dhii-mod",
"description": "Pay Later WooCommerce Blocks module for PPCP",
"license": "GPL-2.0",
"require": {
"php": "^7.2 | ^8.0",
"dhii/module-interface": "^0.3.0-alpha1"
},
"autoload": {
"psr-4": {
"WooCommerce\\PayPalCommerce\\PayLaterWCBlocks\\": "src"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}

View file

@ -0,0 +1,156 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "bbff959c846d515b5cfe39e6d175972b",
"packages": [
{
"name": "container-interop/service-provider",
"version": "v0.4.1",
"source": {
"type": "git",
"url": "https://github.com/container-interop/service-provider.git",
"reference": "e04441ca21ef03e10dce70b0af29269281eec6dc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/container-interop/service-provider/zipball/e04441ca21ef03e10dce70b0af29269281eec6dc",
"reference": "e04441ca21ef03e10dce70b0af29269281eec6dc",
"shasum": ""
},
"require": {
"psr/container": "^1.0 || ^2.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Interop\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Promoting container interoperability through standard service providers",
"homepage": "https://github.com/container-interop/service-provider",
"support": {
"issues": "https://github.com/container-interop/service-provider/issues",
"source": "https://github.com/container-interop/service-provider/tree/v0.4.1"
},
"time": "2023-12-14T14:50:12+00:00"
},
{
"name": "dhii/module-interface",
"version": "v0.3.0-alpha2",
"source": {
"type": "git",
"url": "https://github.com/Dhii/module-interface.git",
"reference": "0e39f167d7ed8990c82f5d2e6084159d1a502a5b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Dhii/module-interface/zipball/0e39f167d7ed8990c82f5d2e6084159d1a502a5b",
"reference": "0e39f167d7ed8990c82f5d2e6084159d1a502a5b",
"shasum": ""
},
"require": {
"container-interop/service-provider": "^0.4",
"php": "^7.1 | ^8.0",
"psr/container": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
"slevomat/coding-standard": "^6.0",
"vimeo/psalm": "^3.11.7 | ^4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-develop": "0.3.x-dev"
}
},
"autoload": {
"psr-4": {
"Dhii\\Modular\\Module\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dhii Team",
"email": "development@dhii.co"
}
],
"description": "Interfaces for modules",
"support": {
"issues": "https://github.com/Dhii/module-interface/issues",
"source": "https://github.com/Dhii/module-interface/tree/v0.3.0-alpha2"
},
"time": "2021-08-23T08:23:01+00:00"
},
{
"name": "psr/container",
"version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
"shasum": ""
},
"require": {
"php": ">=7.4.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
"source": "https://github.com/php-fig/container/tree/1.1.2"
},
"time": "2021-11-05T16:50:12+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^7.2 | ^8.0"
},
"platform-dev": [],
"plugin-api-version": "2.3.0"
}

View file

@ -0,0 +1,12 @@
<?php
/**
* The Pay Later WooCommerce Blocks module extensions.
*
* @package WooCommerce\PayPalCommerce\PayLaterWCBlocks
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\PayLaterWCBlocks;
return array();

View file

@ -0,0 +1,16 @@
<?php
/**
* The Pay Later WooCommerce Blocks module.
*
* @package WooCommerce\PayPalCommerce\PayLaterWCBlocks
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\PayLaterWCBlocks;
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
return static function (): ModuleInterface {
return new PayLaterWCBlocksModule();
};

View file

@ -0,0 +1,34 @@
{
"name": "ppcp-paylater-wc-blocks",
"version": "1.0.0",
"license": "GPL-3.0-or-later",
"browserslist": [
"> 0.5%",
"Safari >= 8",
"Chrome >= 41",
"Firefox >= 43",
"Edge >= 14"
],
"dependencies": {
"@paypal/react-paypal-js": "^8.2.0",
"core-js": "^3.25.0"
},
"devDependencies": {
"@babel/core": "^7.19",
"@babel/preset-env": "^7.19",
"@babel/preset-react": "^7.18.6",
"@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0",
"babel-loader": "^8.2",
"cross-env": "^7.0.3",
"file-loader": "^6.2.0",
"sass": "^1.42.1",
"sass-loader": "^12.1.0",
"webpack": "^5.76",
"webpack-cli": "^4.10"
},
"scripts": {
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
"watch": "cross-env BABEL_ENV=default NODE_ENV=production webpack --watch",
"dev": "cross-env BABEL_ENV=default webpack --watch"
}
}

View file

@ -0,0 +1,29 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "woocommerce-paypal-payments/cart-paylater-messages",
"title": "Cart - PayPal Pay Later messaging",
"category": "woocommerce",
"description": "PayPal Pay Later messaging will be displayed for eligible customers. Customers automatically see the most relevant Pay Later offering.",
"example": {},
"parent": [ "woocommerce/cart-totals-block" ],
"attributes": {
"id": {
"type": "string"
},
"lock": {
"type": "object",
"default": {
"remove": true,
"move": false
}
}
},
"supports": {
"html": false,
"inserter": false,
"multiple": false
},
"textdomain": "woocommerce-paypal-payments",
"editorScript": "ppcp-cart-paylater-block"
}

View file

@ -0,0 +1,138 @@
import { __ } from '@wordpress/i18n';
import { useState, useEffect } from '@wordpress/element';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { PanelBody, Spinner } from '@wordpress/components';
import { PayPalScriptProvider, PayPalMessages } from '@paypal/react-paypal-js';
import { useScriptParams } from '../../../../ppcp-paylater-block/resources/js/hooks/script-params';
export default function Edit({ attributes, clientId, setAttributes }) {
const { id } = attributes;
const [loaded, setLoaded] = useState(false);
let amount;
const postContent = String(wp.data.select('core/editor')?.getEditedPostContent());
if (postContent.includes('woocommerce/checkout') || postContent.includes('woocommerce/cart')) {
amount = 50.0;
}
const cartConfig = PcpCartPayLaterBlock.config.cart;
// Dynamically setting previewStyle based on the layout attribute
let previewStyle = {};
if (cartConfig.layout === 'flex') {
previewStyle = {
layout: cartConfig.layout,
color: cartConfig.color,
ratio: cartConfig.ratio,
};
} else {
previewStyle = {
layout: cartConfig.layout,
logo: {
position: cartConfig['logo-position'],
type: cartConfig['logo-type'],
},
text: {
color: cartConfig['text-color'],
size: cartConfig['text-size'],
},
};
}
let classes = ['ppcp-paylater-block-preview', 'ppcp-overlay-parent'];
if (PcpCartPayLaterBlock.vaultingEnabled || !PcpCartPayLaterBlock.placementEnabled) {
classes = [...classes, 'ppcp-paylater-unavailable', 'block-editor-warning'];
}
const props = useBlockProps({ className: classes.join(' ') });
useEffect(() => {
if (!id) {
setAttributes({ id: `ppcp-${clientId}` });
}
}, [id, clientId]);
if (PcpCartPayLaterBlock.vaultingEnabled) {
return (
<div {...props}>
<div className='block-editor-warning__contents'>
<p className='block-editor-warning__message'>
{__('Cart - Pay Later Messaging cannot be used while PayPal Vaulting is active. Disable PayPal Vaulting in the PayPal Payment settings to reactivate this block', 'woocommerce-paypal-payments')}
</p>
<div className='block-editor-warning__actions'>
<span className='block-editor-warning__action'>
<a href={PcpCartPayLaterBlock.settingsUrl}>
<button type='button' className='components-button is-primary'>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</button>
</a>
</span>
</div>
</div>
</div>
);
}
if (!PcpCartPayLaterBlock.placementEnabled) {
return (
<div {...props}>
<div className='block-editor-warning__contents'>
<p className='block-editor-warning__message'>
{__('Cart - Pay Later Messaging cannot be used while the “Cart” messaging placement is disabled. Enable the placement in the PayPal Payments Pay Later settings to reactivate this block.', 'woocommerce-paypal-payments')}
</p>
<div className='block-editor-warning__actions'>
<span className='block-editor-warning__action'>
<a href={PcpCartPayLaterBlock.payLaterSettingsUrl}>
<button type='button' className='components-button is-primary'>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</button>
</a>
</span>
</div>
</div>
</div>
);
}
const scriptParams = useScriptParams(PcpCartPayLaterBlock.ajax.cart_script_params);
if (scriptParams === null) {
return <div {...props}><Spinner /></div>;
}
const urlParams = {
...scriptParams.url_params,
components: 'messages',
dataNamespace: 'ppcp-block-editor-cart-paylater-message',
};
return (
<>
<InspectorControls>
<PanelBody title={__('Customize your messaging', 'woocommerce-paypal-payments')}>
<p>
{__('Choose the layout and color of your messaging in the PayPal Payments Pay Later settings for the “Cart” messaging placement.', 'woocommerce-paypal-payments')}
</p>
<a href={PcpCartPayLaterBlock.payLaterSettingsUrl}>
<button type='button' className='components-button is-primary'>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</button>
</a>
</PanelBody>
</InspectorControls>
<div {...props}>
<div className='ppcp-overlay-child'>
<PayPalScriptProvider options={urlParams}>
<PayPalMessages
style={previewStyle}
onRender={() => setLoaded(true)}
amount={amount}
/>
</PayPalScriptProvider>
</div>
<div className='ppcp-overlay-child ppcp-unclicable-overlay'> {/* make the message not clickable */}
{!loaded && <Spinner />}
</div>
</div>
</>
);
}

View file

@ -0,0 +1,14 @@
/**
* External dependencies
*/
import { registerCheckoutBlock } from '@woocommerce/blocks-checkout';
/**
* Internal dependencies
*/
import metadata from './block.json';
registerCheckoutBlock({
metadata,
component: () => false,
});

View file

@ -0,0 +1,40 @@
/**
* External dependencies
*/
import { registerBlockType } from '@wordpress/blocks';
/**
* Internal dependencies
*/
import Edit from './edit';
import metadata from './block.json';
const paypalIcon = (
<svg width="584.798" height="720" viewBox="0 0 154.728 190.5">
<g transform="translate(898.192 276.071)">
<path
clipPath="none"
d="M-837.663-237.968a5.49 5.49 0 0 0-5.423 4.633l-9.013 57.15-8.281 52.514-.005.044.01-.044 8.281-52.514c.421-2.669 2.719-4.633 5.42-4.633h26.404c26.573 0 49.127-19.387 53.246-45.658.314-1.996.482-3.973.52-5.924v-.003h-.003c-6.753-3.543-14.683-5.565-23.372-5.565z"
fill="#001c64"
/>
<path
clipPath="none"
d="M-766.506-232.402c-.037 1.951-.207 3.93-.52 5.926-4.119 26.271-26.673 45.658-53.246 45.658h-26.404c-2.701 0-4.999 1.964-5.42 4.633l-8.281 52.514-5.197 32.947a4.46 4.46 0 0 0 4.405 5.153h28.66a5.49 5.49 0 0 0 5.423-4.633l7.55-47.881c.423-2.669 2.722-4.636 5.423-4.636h16.876c26.573 0 49.124-19.386 53.243-45.655 2.924-18.649-6.46-35.614-22.511-44.026z"
fill="#0070e0"
/>
<path
clipPath="none"
d="M-870.225-276.071a5.49 5.49 0 0 0-5.423 4.636l-22.489 142.608a4.46 4.46 0 0 0 4.405 5.156h33.351l8.281-52.514 9.013-57.15a5.49 5.49 0 0 1 5.423-4.633h47.782c8.691 0 16.621 2.025 23.375 5.563.46-23.917-19.275-43.666-46.412-43.666z"
fill="#003087"
/>
</g>
</svg>
);
registerBlockType(metadata, {
icon: paypalIcon,
edit: Edit,
save() {
return null;
},
});

View file

@ -0,0 +1,5 @@
import { useBlockProps } from '@wordpress/block-editor';
export default function save() {
return <div { ...useBlockProps.save() } />;
}

View file

@ -0,0 +1,29 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "woocommerce-paypal-payments/checkout-paylater-messages",
"title": "Checkout - PayPal Pay Later messaging",
"category": "woocommerce",
"description": "PayPal Pay Later messaging will be displayed for eligible customers. Customers automatically see the most relevant Pay Later offering.",
"example": {},
"parent": [ "woocommerce/checkout-totals-block" ],
"attributes": {
"id": {
"type": "string"
},
"lock": {
"type": "object",
"default": {
"remove": true,
"move": false
}
}
},
"supports": {
"html": false,
"inserter": false,
"multiple": false
},
"textdomain": "woocommerce-paypal-payments",
"editorScript": "ppcp-checkout-paylater-block"
}

View file

@ -0,0 +1,132 @@
import { __ } from '@wordpress/i18n';
import { useState, useEffect } from '@wordpress/element';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { PanelBody, Spinner } from '@wordpress/components';
import { PayPalScriptProvider, PayPalMessages } from '@paypal/react-paypal-js';
import { useScriptParams } from '../../../../ppcp-paylater-block/resources/js/hooks/script-params';
export default function Edit({ attributes, clientId, setAttributes }) {
const { id } = attributes;
const [loaded, setLoaded] = useState(false);
let amount = undefined;
const postContent = String(wp.data.select('core/editor')?.getEditedPostContent());
if (postContent.includes('woocommerce/checkout') || postContent.includes('woocommerce/cart')) {
amount = 50.0;
}
const checkoutConfig = PcpCheckoutPayLaterBlock.config.checkout;
// Dynamically setting previewStyle based on the layout attribute
let previewStyle = {};
if (checkoutConfig.layout === 'flex') {
previewStyle = {
layout: checkoutConfig.layout,
color: checkoutConfig.color,
ratio: checkoutConfig.ratio,
};
} else {
previewStyle = {
layout: checkoutConfig.layout,
logo: {
position: checkoutConfig['logo-position'],
type: checkoutConfig['logo-type'],
},
text: {
color: checkoutConfig['text-color'],
size: checkoutConfig['text-size'],
},
};
}
let classes = ['ppcp-paylater-block-preview', 'ppcp-overlay-parent'];
if (PcpCheckoutPayLaterBlock.vaultingEnabled || !PcpCheckoutPayLaterBlock.placementEnabled) {
classes = ['ppcp-paylater-block-preview', 'ppcp-paylater-unavailable', 'block-editor-warning'];
}
const props = useBlockProps({ className: classes });
useEffect(() => {
if (!id) {
setAttributes({ id: 'ppcp-' + clientId });
}
}, [id, clientId]);
if (PcpCheckoutPayLaterBlock.vaultingEnabled) {
return (
<div {...props}>
<div className={'block-editor-warning__contents'}>
<p className={'block-editor-warning__message'}>{__('Checkout - Pay Later Messaging cannot be used while PayPal Vaulting is active. Disable PayPal Vaulting in the PayPal Payment settings to reactivate this block', 'woocommerce-paypal-payments')}</p>
<div className={'block-editor-warning__actions'}>
<span className={'block-editor-warning__action'}>
<a href={PcpCheckoutPayLaterBlock.settingsUrl}>
<button type={'button'} className={'components-button is-primary'}>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</button>
</a>
</span>
</div>
</div>
</div>
);
}
if (!PcpCheckoutPayLaterBlock.placementEnabled) {
return (
<div {...props}>
<div className={'block-editor-warning__contents'}>
<p className={'block-editor-warning__message'}>{__('Checkout - Pay Later Messaging cannot be used while the “Checkout” messaging placement is disabled. Enable the placement in the PayPal Payments Pay Later settings to reactivate this block.', 'woocommerce-paypal-payments')}</p>
<div className={'block-editor-warning__actions'}>
<span className={'block-editor-warning__action'}>
<a href={PcpCheckoutPayLaterBlock.payLaterSettingsUrl}>
<button type={'button'} className={'components-button is-primary'}>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</button>
</a>
</span>
</div>
</div>
</div>
);
}
const scriptParams = useScriptParams(PcpCheckoutPayLaterBlock.ajax.cart_script_params);
if (scriptParams === null) {
return <div {...props}><Spinner/></div>;
}
const urlParams = {
...scriptParams.url_params,
components: 'messages',
dataNamespace: 'ppcp-block-editor-checkout-paylater-message',
};
return (
<>
<InspectorControls>
<PanelBody title={__('Customize your messaging', 'woocommerce-paypal-payments')}>
<p>{__('Choose the layout and color of your messaging in the PayPal Payments Pay Later settings for the “Checkout” messaging placement.', 'woocommerce-paypal-payments')}</p>
<a href={PcpCheckoutPayLaterBlock.payLaterSettingsUrl}>
<button type={'button'} className={'components-button is-primary'}>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</button>
</a>
</PanelBody>
</InspectorControls>
<div {...props}>
<div className={'ppcp-overlay-child'}>
<PayPalScriptProvider options={urlParams}>
<PayPalMessages
style={previewStyle}
onRender={() => setLoaded(true)}
amount={amount}
/>
</PayPalScriptProvider>
</div>
<div className={'ppcp-overlay-child ppcp-unclicable-overlay'}> {/* make the message not clickable */}
{!loaded && <Spinner/>}
</div>
</div>
</>
);
}

View file

@ -0,0 +1,14 @@
/**
* External dependencies
*/
import { registerCheckoutBlock } from '@woocommerce/blocks-checkout';
/**
* Internal dependencies
*/
import metadata from './block.json';
registerCheckoutBlock({
metadata,
component: () => false,
});

View file

@ -0,0 +1,40 @@
/**
* External dependencies
*/
import { registerBlockType } from '@wordpress/blocks';
/**
* Internal dependencies
*/
import Edit from './edit';
import metadata from './block.json';
const paypalIcon = (
<svg width="584.798" height="720" viewBox="0 0 154.728 190.5">
<g transform="translate(898.192 276.071)">
<path
clipPath="none"
d="M-837.663-237.968a5.49 5.49 0 0 0-5.423 4.633l-9.013 57.15-8.281 52.514-.005.044.01-.044 8.281-52.514c.421-2.669 2.719-4.633 5.42-4.633h26.404c26.573 0 49.127-19.387 53.246-45.658.314-1.996.482-3.973.52-5.924v-.003h-.003c-6.753-3.543-14.683-5.565-23.372-5.565z"
fill="#001c64"
/>
<path
clipPath="none"
d="M-766.506-232.402c-.037 1.951-.207 3.93-.52 5.926-4.119 26.271-26.673 45.658-53.246 45.658h-26.404c-2.701 0-4.999 1.964-5.42 4.633l-8.281 52.514-5.197 32.947a4.46 4.46 0 0 0 4.405 5.153h28.66a5.49 5.49 0 0 0 5.423-4.633l7.55-47.881c.423-2.669 2.722-4.636 5.423-4.636h16.876c26.573 0 49.124-19.386 53.243-45.655 2.924-18.649-6.46-35.614-22.511-44.026z"
fill="#0070e0"
/>
<path
clipPath="none"
d="M-870.225-276.071a5.49 5.49 0 0 0-5.423 4.636l-22.489 142.608a4.46 4.46 0 0 0 4.405 5.156h33.351l8.281-52.514 9.013-57.15a5.49 5.49 0 0 1 5.423-4.633h47.782c8.691 0 16.621 2.025 23.375 5.563.46-23.917-19.275-43.666-46.412-43.666z"
fill="#003087"
/>
</g>
</svg>
);
registerBlockType(metadata, {
icon: paypalIcon,
edit: Edit,
save() {
return null;
},
});

View file

@ -0,0 +1,5 @@
import { useBlockProps } from '@wordpress/block-editor';
export default function save() {
return <div { ...useBlockProps.save() } />;
}

View file

@ -0,0 +1,11 @@
/**
* External dependencies
*/
import { registerPlugin } from '@wordpress/plugins';
const render = () => {};
registerPlugin('ppcp-cart-paylater-messages-block', {
render,
scope: 'woocommerce-checkout',
});

View file

@ -0,0 +1,11 @@
/**
* External dependencies
*/
import { registerPlugin } from '@wordpress/plugins';
const render = () => {};
registerPlugin('ppcp-checkout-paylater-messages-block', {
render,
scope: 'woocommerce-checkout',
});

View file

@ -0,0 +1,30 @@
<?php
/**
* The Pay Later WooCommerce Blocks module services.
*
* @package WooCommerce\PayPalCommerce\PayLaterWCBlocks
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\PayLaterWCBlocks;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
return array(
'paylater-wc-blocks.url' => static function ( ContainerInterface $container ): string {
/**
* Cannot return false for this path.
*
* @psalm-suppress PossiblyFalseArgument
*/
return plugins_url(
'/modules/ppcp-paylater-wc-blocks/',
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
);
},
'paylater-wc-blocks.renderer' => static function (): PayLaterWCBlocksRenderer {
return new PayLaterWCBlocksRenderer();
},
);

View file

@ -0,0 +1,280 @@
<?php
/**
* The Pay Later WooCommerce Blocks integration.
*
* @package WooCommerce\PayPalCommerce\PayLaterWCBlocks
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\PayLaterWCBlocks;
use Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface;
/**
* Class for integrating with WooCommerce Blocks
*/
class PayLaterWCBlocksIntegration implements IntegrationInterface {
protected $paylater_wc_blocks_url;
protected $ppcp_asset_version;
/**
* Constructor
*
* @param string $paylater_wc_blocks_url The URL of the Pay Later WooCommerce Blocks plugin.
* @param string $ppcp_asset_version The version of the Pay Later WooCommerce Blocks plugin.
*/
public function __construct( string $paylater_wc_blocks_url, string $ppcp_asset_version ) {
$this->paylater_wc_blocks_url = $paylater_wc_blocks_url;
$this->ppcp_asset_version = $ppcp_asset_version;
}
/**
* The name of the integration.
*
* @return string
*/
public function get_name(): string {
return 'ppcp-paylater-wc-blocks';
}
/**
* The version of the integration.
*
* @return string
*/
public function get_version(): string {
return $this->ppcp_asset_version;
}
/**
* When called invokes any initialization/setup for the integration.
*
* @return void
*/
public function initialize(): void {
$this->register_paylater_wc_blocks_frontend_scripts();
$this->register_paylater_wc_blocks_editor_scripts();
$this->register_main_integration();
}
/**
* Registers the main JS files.
*
* @return void
*/
private function register_main_integration() : void {
$cart_block_script_path = 'assets/js/ppcp-cart-paylater-messages-block.js';
$checkout_block_script_path = 'assets/js/ppcp-checkout-paylater-messages-block.js';
$style_path = 'build/style-index.css';
$cart_block_script_url = $this->paylater_wc_blocks_url . $cart_block_script_path;
$checkout_block_script_url = $this->paylater_wc_blocks_url . $checkout_block_script_path;
$style_url = $this->paylater_wc_blocks_url . $style_path;
$cart_block_script_asset_path = $this->paylater_wc_blocks_url . 'assets/ppcp-cart-paylater-messages-block.asset.php';
$checkout_block_script_asset_path = $this->paylater_wc_blocks_url . 'assets/ppcp-checkout-paylater-messages-block.asset.php';
$cart_block_script_asset = file_exists( $cart_block_script_asset_path )
? require $cart_block_script_asset_path
: [
'dependencies' => [],
'version' => $this->get_file_version( $cart_block_script_asset_path ),
];
$checkout_block_script_asset = file_exists( $checkout_block_script_asset_path )
? require $checkout_block_script_asset_path
: [
'dependencies' => [],
'version' => $this->get_file_version( $checkout_block_script_asset_path ),
];
wp_register_script(
'ppcp-cart-paylater-messages-block',
$cart_block_script_url,
$cart_block_script_asset['dependencies'],
$cart_block_script_asset['version'],
true
);
wp_register_script(
'ppcp-checkout-paylater-messages-block',
$checkout_block_script_url,
$checkout_block_script_asset['dependencies'],
$checkout_block_script_asset['version'],
true
);
wp_set_script_translations(
'ppcp-cart-paylater-messages-block',
'woocommerce-paypal-payments',
$this->paylater_wc_blocks_url . 'languages'
);
wp_set_script_translations(
'ppcp-checkout-paylater-messages-block',
'woocommerce-paypal-payments',
$this->paylater_wc_blocks_url . 'languages'
);
}
/**
* Returns an array of script handles to enqueue in the frontend context.
*
* @return string[]
*/
public function get_script_handles(): array {
return [ 'ppcp-checkout-paylater-messages-block', 'ppcp-cart-paylater-messages-block', 'ppcp-cart-paylater-messages-block-frontend', 'ppcp-checkout-paylater-messages-block-frontend' ];
}
/**
* Returns an array of script handles to enqueue in the editor context.
*
* @return string[]
*/
public function get_editor_script_handles(): array {
return [ 'ppcp-cart-paylater-wc-blocks-editor', 'ppcp-checkout-paylater-wc-blocks-editor', 'ppcp-checkout-paylater-messages-block', 'ppcp-cart-paylater-messages-block' ];
}
/**
* An array of key, value pairs of data made available to the block on the client side.
*
* @return array
*/
public function get_script_data(): array {
return [
'ppcp-paylater-wc-blocks-active' => true,
];
}
/**
* Registers the editor scripts.
*
* @return void
*/
public function register_paylater_wc_blocks_editor_scripts(): void {
$cart_block_script_path = 'assets/js/cart-paylater-messages-block.js';
$checkout_block_script_path = 'assets/js/checkout-paylater-messages-block.js';
$cart_block_script_url = $this->paylater_wc_blocks_url . $cart_block_script_path;
$checkout_block_script_url = $this->paylater_wc_blocks_url . $checkout_block_script_path;
$cart_block_script_asset_path = $this->paylater_wc_blocks_url . 'assets/cart-paylater-messages-block.asset.php';
$checkout_block_script_asset_path = $this->paylater_wc_blocks_url . 'assets/checkout-paylater-messages-block.asset.php';
$cart_block_script_asset = file_exists( $cart_block_script_asset_path )
? require $cart_block_script_asset_path
: [
'dependencies' => [],
'version' => $this->get_file_version( $cart_block_script_asset_path ),
];
$checkout_block_script_asset = file_exists( $checkout_block_script_asset_path )
? require $checkout_block_script_asset_path
: [
'dependencies' => [],
'version' => $this->get_file_version( $checkout_block_script_asset_path ),
];
wp_register_script(
'ppcp-cart-paylater-wc-blocks-editor',
$cart_block_script_url,
$cart_block_script_asset['dependencies'],
$cart_block_script_asset['version'],
true
);
wp_register_script(
'ppcp-checkout-paylater-wc-blocks-editor',
$checkout_block_script_url,
$checkout_block_script_asset['dependencies'],
$checkout_block_script_asset['version'],
true
);
wp_set_script_translations(
'ppcp-cart-paylater-wc-blocks-editor',
'woocommerce-paypal-payments',
$this->paylater_wc_blocks_url . '/languages'
);
wp_set_script_translations(
'ppcp-checkout-paylater-wc-blocks-editor',
'woocommerce-paypal-payments',
$this->paylater_wc_blocks_url . '/languages'
);
}
/**
* Registers the frontend scripts.
*
* @return void
*/
public function register_paylater_wc_blocks_frontend_scripts(): void {
$cart_block_script_path = 'assets/js/cart-paylater-messages-block-frontend.js';
$checkout_block_script_path = 'assets/js/checkout-paylater-messages-block-frontend.js';
$cart_block_script_url = $this->paylater_wc_blocks_url . $cart_block_script_path;
$checkout_block_script_url = $this->paylater_wc_blocks_url . $checkout_block_script_path;
$cart_block_script_asset_path = $this->paylater_wc_blocks_url . 'assets/cart-paylater-messages-block-frontend.asset.php';
$checkout_block_script_asset_path = $this->paylater_wc_blocks_url . 'assets/checkout-paylater-messages-block-frontend.asset.php';
$cart_block_script_asset = file_exists( $cart_block_script_asset_path )
? require $cart_block_script_asset_path
: [
'dependencies' => [],
'version' => $this->get_file_version( $cart_block_script_asset_path ),
];
$checkout_block_script_asset = file_exists( $checkout_block_script_asset_path )
? require $checkout_block_script_asset_path
: [
'dependencies' => [],
'version' => $this->get_file_version( $checkout_block_script_asset_path ),
];
wp_register_script(
'ppcp-cart-paylater-messages-block-frontend',
$cart_block_script_url,
$cart_block_script_asset['dependencies'],
$cart_block_script_asset['version'],
true
);
wp_register_script(
'ppcp-checkout-paylater-messages-block-frontend',
$checkout_block_script_url,
$checkout_block_script_asset['dependencies'],
$checkout_block_script_asset['version'],
true
);
wp_set_script_translations(
'ppcp-cart-paylater-messages-block-frontend',
'woocommerce-paypal-payments',
$this->paylater_wc_blocks_url . '/languages'
);
wp_set_script_translations(
'ppcp-checkout-paylater-messages-block-frontend',
'woocommerce-paypal-payments',
$this->paylater_wc_blocks_url . '/languages'
);
}
/**
* Get the file modified time as a cache buster if we're in dev mode.
*
* @param string $file Local path to the file.
* @return string The cache buster value to use for the given file.
*/
protected function get_file_version( string $file ): string {
if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG && file_exists( $file ) ) {
$filemtime = filemtime( $file );
if ( $filemtime ) {
return (string) $filemtime;
}
}
return $this->get_version();
}
}

View file

@ -0,0 +1,237 @@
<?php
/**
* The Pay Later WooCommerce Blocks module.
*
* @package WooCommerce\PayPalCommerce\PayLaterWCBlocks
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\PayLaterWCBlocks;
use WooCommerce\PayPalCommerce\Button\Endpoint\CartScriptParamsEndpoint;
use WooCommerce\PayPalCommerce\PayLaterConfigurator\Factory\ConfigFactory;
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
/**
* Class PayLaterWCBlocksModule
*/
class PayLaterWCBlocksModule implements ModuleInterface {
/**
* Returns whether the block module should be loaded.
*
* @return bool true if the module should be loaded, otherwise false.
*/
public static function is_module_loading_required(): bool {
return apply_filters(
// phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
'woocommerce.feature-flags.woocommerce_paypal_payments.paylater_wc_blocks_enabled',
getenv( 'PCP_PAYLATER_WC_BLOCKS' ) !== '0'
);
}
/**
* Returns whether the block is enabled.
*
* @param SettingsStatus $settings_status The Settings status helper.
* @param string $location The location to check.
* @return bool true if the block is enabled, otherwise false.
*/
public static function is_block_enabled( SettingsStatus $settings_status, string $location ): bool {
return self::is_module_loading_required() && $settings_status->is_pay_later_messaging_enabled_for_location( $location );
}
/**
* Returns whether the placement is enabled.
*
* @param SettingsStatus $settings_status The Settings status helper.
* @param string $location The location to check.
* @return bool true if the placement is enabled, otherwise false.
*/
public static function is_placement_enabled( SettingsStatus $settings_status, string $location ) : bool {
return self::is_block_enabled( $settings_status, $location );
}
/**
* {@inheritDoc}
*/
public function setup(): ServiceProviderInterface {
return new ServiceProvider(
require __DIR__ . '/../services.php',
require __DIR__ . '/../extensions.php'
);
}
/**
* {@inheritDoc}
*/
public function run( ContainerInterface $c ): void {
$messages_apply = $c->get( 'button.helper.messages-apply' );
assert( $messages_apply instanceof MessagesApply );
if ( ! $messages_apply->for_country() ) {
return;
}
$settings = $c->get( 'wcgateway.settings' );
assert( $settings instanceof Settings );
add_action( 'woocommerce_blocks_loaded', function() use ( $c ): void {
add_action(
'woocommerce_blocks_checkout_block_registration',
function( $integration_registry ) use ( $c ): void {
$integration_registry->register( new PayLaterWCBlocksIntegration(
$c->get( 'paylater-wc-blocks.url' ),
$c->get( 'ppcp.asset-version' )
) );
}
);
});
add_action(
'init',
function () use ( $c, $settings ): void {
$config_factory = $c->get( 'paylater-configurator.factory.config' );
assert( $config_factory instanceof ConfigFactory );
$script_handle = 'ppcp-cart-paylater-messages-block';
wp_register_script(
$script_handle,
$c->get( 'paylater-wc-blocks.url' ) . '/assets/js/paylater-block.js',
array(),
$c->get( 'ppcp.asset-version' ),
true
);
wp_localize_script(
$script_handle,
'PcpCartPayLaterBlock',
array(
'ajax' => array(
'cart_script_params' => array(
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
),
),
'config' => $config_factory->from_settings( $settings ),
'settingsUrl' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway' ),
'vaultingEnabled' => $settings->has( 'vault_enabled' ) && $settings->get( 'vault_enabled' ),
'placementEnabled' => self::is_placement_enabled( $c->get( 'wcgateway.settings.status' ), 'cart' ),
'payLaterSettingsUrl' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway&ppcp-tab=ppcp-pay-later' ),
)
);
$script_handle = 'ppcp-checkout-paylater-messages-block';
wp_register_script(
$script_handle,
$c->get( 'paylater-wc-blocks.url' ) . '/assets/js/paylater-block.js',
array(),
$c->get( 'ppcp.asset-version' ),
true
);
wp_localize_script(
$script_handle,
'PcpCheckoutPayLaterBlock',
array(
'ajax' => array(
'cart_script_params' => array(
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
),
),
'config' => $config_factory->from_settings( $settings ),
'settingsUrl' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway' ),
'vaultingEnabled' => $settings->has( 'vault_enabled' ) && $settings->get( 'vault_enabled' ),
'placementEnabled' => self::is_placement_enabled( $c->get( 'wcgateway.settings.status' ), 'checkout' ),
'payLaterSettingsUrl' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway&ppcp-tab=ppcp-pay-later' ),
)
);
/**
* Cannot return false for this path.
*
* @psalm-suppress PossiblyFalseArgument
*/
register_block_type( dirname( realpath( __FILE__ ), 2 ) );
},
20
);
/**
* Registers slugs as block categories with WordPress.
*/
add_action(
'block_categories_all',
function( $categories ): array {
return array_merge(
$categories,
[
[
'slug' => 'ppcp-cart-paylater-messages-block',
'title' => __( 'PayPal Cart Pay Later Messages Blocks', 'woocommerce-paypal-payments' ),
],
[
'slug' => 'ppcp-checkout-paylater-messages-block',
'title' => __( 'PayPal Checkout Pay Later Messages Blocks', 'woocommerce-paypal-payments' ),
],
]
);
},
10,
2
);
/**
* Cannot return false for this path.
*
* @psalm-suppress PossiblyFalseArgument
*/
register_block_type(
dirname( realpath( __FILE__ ), 2) . '/resources/js/CartPayLaterMessagesBlock',
[
'render_callback' => function ( $attributes ) use ( $c ) {
$renderer = $c->get( 'paylater-wc-blocks.renderer' );
ob_start();
echo $renderer->render(
$attributes, 'cart', $c
);
return ob_get_clean();
}
]
);
/**
* Cannot return false for this path.
*
* @psalm-suppress PossiblyFalseArgument
*/
register_block_type(
dirname( realpath( __FILE__ ), 2) . '/resources/js/CheckoutPayLaterMessagesBlock',
[
'render_callback' => function ( $attributes ) use ( $c ) {
$renderer = $c->get( 'paylater-wc-blocks.renderer' );
ob_start();
echo $renderer->render(
$attributes, 'checkout', $c
);
return ob_get_clean();
}
]
);
}
/**
* Returns the key for the module.
*
* @return void
*/
public function getKey() {
}
}

View file

@ -0,0 +1,32 @@
<?php
/**
* The Pay Later WooCommerce Blocks Renderer.
*
* @package WooCommerce\PayPalCommerce\PayLaterWCBlocks
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\PayLaterWCBlocks;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
/**
* Class PayLaterWCBlocksRenderer
*/
class PayLaterWCBlocksRenderer {
/**
* Renders the WC Pay Later Messaging blocks.
*
* @param array $attributes
* @param string $location
* @param ContainerInterface $c
* @return string|void
*/
public function render( array $attributes, string $location, ContainerInterface $c ) {
if ( PayLaterWCBlocksModule::is_placement_enabled( $c->get( 'wcgateway.settings.status' ), $location ) ) {
return '<div id="' . htmlspecialchars($attributes['id'] ?? '') . '" class="ppcp-messages" data-partner-attribution-id="Woo_PPCP"></div>';
}
}
}

View file

@ -0,0 +1,82 @@
const path = require("path");
const isProduction = process.env.NODE_ENV === "production";
const DependencyExtractionWebpackPlugin = require("@woocommerce/dependency-extraction-webpack-plugin");
module.exports = {
devtool: isProduction ? "source-map" : "eval-source-map",
mode: isProduction ? "production" : "development",
target: "web",
plugins: [new DependencyExtractionWebpackPlugin()],
entry: {
"ppcp-cart-paylater-messages-block": path.resolve(
process.cwd(),
"resources",
"js",
"ppcp-cart-paylater-messages-block.js"
),
"ppcp-checkout-paylater-messages-block": path.resolve(
process.cwd(),
"resources",
"js",
"ppcp-checkout-paylater-messages-block.js"
),
"cart-paylater-messages-block": path.resolve(
process.cwd(),
"resources",
"js",
"CartPayLaterMessagesBlock",
"index.js"
),
"checkout-paylater-messages-block": path.resolve(
process.cwd(),
"resources",
"js",
"CheckoutPayLaterMessagesBlock",
"index.js"
),
"cart-paylater-messages-block-frontend": path.resolve(
process.cwd(),
"resources",
"js",
"CartPayLaterMessagesBlock",
"frontend.js"
),
"checkout-paylater-messages-block-frontend": path.resolve(
process.cwd(),
"resources",
"js",
"CheckoutPayLaterMessagesBlock",
"frontend.js"
),
},
output: {
path: path.resolve(__dirname, "assets/"),
filename: "js/[name].js",
},
module: {
rules: [
{
test: /\.js?$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
{
loader: "file-loader",
options: {
name: "css/[name].css",
},
},
{ loader: "sass-loader" },
],
},
],
},
};

File diff suppressed because it is too large Load diff