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

@ -44,7 +44,8 @@
}
},
"supports": {
"html": false
"html": false,
"multiple": false
},
"textdomain": "woocommerce-paypal-payments",
"editorScript": "ppcp-paylater-block",

View file

@ -1,29 +0,0 @@
import { useRef, useEffect } from '@wordpress/element';
export default function PayPalMessages({
amount,
style,
onRender,
}) {
const containerRef = useRef(null);
useEffect(() => {
const messages = paypal.Messages({
amount,
style,
onRender,
});
messages.render(containerRef.current)
.catch(err => {
// Ignore when component destroyed.
if (!containerRef.current || containerRef.current.children.length === 0) {
return;
}
console.error(err);
});
}, [amount, style, onRender]);
return <div ref={containerRef}/>
}

View file

@ -2,16 +2,16 @@ import { __ } from '@wordpress/i18n';
import { useState, useEffect } from '@wordpress/element';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { PanelBody, SelectControl, Spinner } from '@wordpress/components';
import { PayPalScriptProvider, PayPalMessages } from "@paypal/react-paypal-js";
import { useScriptParams } from "./hooks/script-params";
import { PayPalScriptProvider, PayPalMessages } from '@paypal/react-paypal-js';
import { useScriptParams } from './hooks/script-params';
export default function Edit( { attributes, clientId, setAttributes } ) {
export default function Edit({ attributes, clientId, setAttributes }) {
const { layout, logo, position, color, size, flexColor, flexRatio, placement, id } = attributes;
const isFlex = layout === 'flex';
const [loaded, setLoaded] = useState(false);
let amount = undefined;
let amount;
const postContent = String(wp.data.select('core/editor')?.getEditedPostContent());
if (postContent.includes('woocommerce/checkout') || postContent.includes('woocommerce/cart')) {
amount = 50.0;
@ -33,169 +33,191 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
let classes = ['ppcp-paylater-block-preview', 'ppcp-overlay-parent'];
if (PcpPayLaterBlock.vaultingEnabled || !PcpPayLaterBlock.placementEnabled) {
classes = ['ppcp-paylater-block-preview', 'ppcp-paylater-unavailable', 'block-editor-warning'];
classes.push('ppcp-paylater-unavailable', 'block-editor-warning');
}
const props = useBlockProps({className: classes});
const props = useBlockProps({ className: classes.join(' ') });
useEffect(() => {
if (!id) {
setAttributes({id: 'ppcp-' + clientId});
setAttributes({ id: `ppcp-${clientId}` });
}
}, []);
}, [id, clientId]);
if (PcpPayLaterBlock.vaultingEnabled) {
return <div {...props}>
<div className={'block-editor-warning__contents'}>
<h3>{__('PayPal Pay Later Messaging', 'woocommerce-paypal-payments')}</h3>
<p className={'block-editor-warning__message'}>{__('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={'class="block-editor-warning__actions"'}>
<span className={'block-editor-warning__action'}>
<a href={PcpPayLaterBlock.settingsUrl} className={'components-button is-primary'}>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</a>
</span>
<span className={'block-editor-warning__action'}>
<button onClick={() => wp.data.dispatch( 'core/block-editor' ).removeBlock(clientId)} type={'button'} className={'components-button is-secondary'}>
{__('Remove Block', 'woocommerce-paypal-payments')}
</button>
</span>
return (
<div {...props}>
<div className='block-editor-warning__contents'>
<p className='block-editor-warning__message'>
{__('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={PcpPayLaterBlock.payLaterSettingsUrl}>
<button type='button' className='components-button is-primary'>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</button>
</a>
</span>
<span className='block-editor-warning__action'>
<button
onClick={() => wp.data.dispatch('core/block-editor').removeBlock(clientId)}
type='button' className='components-button is-secondary'>
{__('Remove Block', 'woocommerce-paypal-payments')}
</button>
</span>
</div>
</div>
</div>
</div>
);
}
if (!PcpPayLaterBlock.placementEnabled) {
return <div {...props}>
<div className={'block-editor-warning__contents'}>
<h3>{__('PayPal Pay Later Messaging', 'woocommerce-paypal-payments')}</h3>
<p className={'block-editor-warning__message'}>{__('Pay Later Messaging cannot be used while the “WooCommerce Block” messaging placement is disabled. Enable the placement in the PayPal Payments Pay Later settings to reactivate this block.', 'woocommerce-paypal-payments')}</p>
<div className={'class="block-editor-warning__actions"'}>
<span className={'block-editor-warning__action'}>
<a href={PcpPayLaterBlock.payLaterSettingsUrl} className={'components-button is-primary'}>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</a>
</span>
<span className={'block-editor-warning__action'}>
<button onClick={() => wp.data.dispatch( 'core/block-editor' ).removeBlock(clientId)} type={'button'} className={'components-button is-secondary'}>
{__('Remove Block', 'woocommerce-paypal-payments')}
</button>
</span>
return (
<div {...props}>
<div className='block-editor-warning__contents'>
<p className='block-editor-warning__message'>
{__('Pay Later Messaging cannot be used while the “WooCommerce Block” 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={PcpPayLaterBlock.payLaterSettingsUrl}>
<button type='button' className='components-button is-primary'>
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
</button>
</a>
</span>
<span className='block-editor-warning__action'>
<button
onClick={() => wp.data.dispatch('core/block-editor').removeBlock(clientId)}
type='button' className='components-button is-secondary'>
{__('Remove Block', 'woocommerce-paypal-payments')}
</button>
</span>
</div>
</div>
</div>
</div>
);
}
const scriptParams = useScriptParams(PcpPayLaterBlock.ajax.cart_script_params);
if (scriptParams === null) {
return (<div {...props}><Spinner/></div>)
return <div {...props}><Spinner/></div>;
}
const urlParams = {
clientId: 'test',
...scriptParams.url_params,
...{
components: 'messages',
dataNamespace: 'ppcp-block-editor-paylater-message',
}
}
components: 'messages',
dataNamespace: 'ppcp-block-editor-paylater-message',
};
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'woocommerce-paypal-payments' ) }>
<PanelBody title={__('Settings', 'woocommerce-paypal-payments')}>
<SelectControl
label={ __( 'Layout', 'woocommerce-paypal-payments' ) }
options={ [
{ label: __( 'Text', 'woocommerce-paypal-payments' ), value: 'text' },
{ label: __( 'Banner', 'woocommerce-paypal-payments' ), value: 'flex' },
] }
value={ layout }
onChange={ ( value ) => setAttributes( { layout: value } ) }
label={__('Layout', 'woocommerce-paypal-payments')}
options={[
{ label: __('Text', 'woocommerce-paypal-payments'), value: 'text' },
{ label: __('Banner', 'woocommerce-paypal-payments'), value: 'flex' },
]}
value={layout}
onChange={(value) => setAttributes({ layout: value })}
/>
{ !isFlex && (<SelectControl
label={__('Logo', 'woocommerce-paypal-payments')}
options={[
{ label: __('Full logo', 'woocommerce-paypal-payments'), value: 'primary' },
{ label: __('Monogram', 'woocommerce-paypal-payments'), value: 'alternative' },
{ label: __('Inline', 'woocommerce-paypal-payments'), value: 'inline' },
{ label: __('Message only', 'woocommerce-paypal-payments'), value: 'none' },
]}
value={logo}
onChange={(value) => setAttributes({logo: value})}
/>)}
{ !isFlex && logo === 'primary' && (<SelectControl
label={__('Logo Position', 'woocommerce-paypal-payments')}
options={[
{ label: __( 'Left', 'woocommerce-paypal-payments' ), value: 'left' },
{ label: __( 'Right', 'woocommerce-paypal-payments' ), value: 'right' },
{ label: __( 'Top', 'woocommerce-paypal-payments' ), value: 'top' },
]}
value={position}
onChange={(value) => setAttributes({position: value})}
/>)}
{ !isFlex && (<SelectControl
label={__('Text Color', 'woocommerce-paypal-payments')}
options={[
{ label: __( 'Black / Blue logo', 'woocommerce-paypal-payments' ), value: 'black' },
{ label: __( 'White / White logo', 'woocommerce-paypal-payments' ), value: 'white' },
{ label: __( 'Monochrome', 'woocommerce-paypal-payments' ), value: 'monochrome' },
{ label: __( 'Black / Gray logo', 'woocommerce-paypal-payments' ), value: 'grayscale' },
]}
value={color}
onChange={(value) => setAttributes({color: value})}
/>)}
{ !isFlex && (<SelectControl
label={__('Text Size', 'woocommerce-paypal-payments')}
options={[
{ label: __( 'Small', 'woocommerce-paypal-payments' ), value: '12' },
{ label: __( 'Medium', 'woocommerce-paypal-payments' ), value: '14' },
{ label: __( 'Large', 'woocommerce-paypal-payments' ), value: '16' },
]}
value={size}
onChange={(value) => setAttributes({size: value})}
/>)}
{ isFlex && (<SelectControl
label={__('Color', 'woocommerce-paypal-payments')}
options={[
{ label: __( 'Blue', 'woocommerce-paypal-payments' ), value: 'blue' },
{ label: __( 'Black', 'woocommerce-paypal-payments' ), value: 'black' },
{ label: __( 'White', 'woocommerce-paypal-payments' ), value: 'white' },
{ label: __( 'White (no border)', 'woocommerce-paypal-payments' ), value: 'white-no-border' },
]}
value={flexColor}
onChange={(value) => setAttributes({flexColor: value})}
/>)}
{ isFlex && (<SelectControl
label={__('Ratio', 'woocommerce-paypal-payments')}
options={[
{ label: __( '8x1', 'woocommerce-paypal-payments' ), value: '8x1' },
{ label: __( '20x1', 'woocommerce-paypal-payments' ), value: '20x1' },
]}
value={flexRatio}
onChange={(value) => setAttributes({flexRatio: value})}
/>)}
{!isFlex && (
<SelectControl
label={__('Logo', 'woocommerce-paypal-payments')}
options={[
{ label: __('Full logo', 'woocommerce-paypal-payments'), value: 'primary' },
{ label: __('Monogram', 'woocommerce-paypal-payments'), value: 'alternative' },
{ label: __('Inline', 'woocommerce-paypal-payments'), value: 'inline' },
{ label: __('Message only', 'woocommerce-paypal-payments'), value: 'none' },
]}
value={logo}
onChange={(value) => setAttributes({ logo: value })}
/>
)}
{!isFlex && logo === 'primary' && (
<SelectControl
label={__('Logo Position', 'woocommerce-paypal-payments')}
options={[
{ label: __('Left', 'woocommerce-paypal-payments'), value: 'left' },
{ label: __('Right', 'woocommerce-paypal-payments'), value: 'right' },
{ label: __('Top', 'woocommerce-paypal-payments'), value: 'top' },
]}
value={position}
onChange={(value) => setAttributes({ position: value })}
/>
)}
{!isFlex && (
<SelectControl
label={__('Text Color', 'woocommerce-paypal-payments')}
options={[
{ label: __('Black / Blue logo', 'woocommerce-paypal-payments'), value: 'black' },
{ label: __('White / White logo', 'woocommerce-paypal-payments'), value: 'white' },
{ label: __('Monochrome', 'woocommerce-paypal-payments'), value: 'monochrome' },
{ label: __('Black / Gray logo', 'woocommerce-paypal-payments'), value: 'grayscale' },
]}
value={color}
onChange={(value) => setAttributes({ color: value })}
/>
)}
{!isFlex && (
<SelectControl
label={__('Text Size', 'woocommerce-paypal-payments')}
options={[
{ label: __('Small', 'woocommerce-paypal-payments'), value: '12' },
{ label: __('Medium', 'woocommerce-paypal-payments'), value: '14' },
{ label: __('Large', 'woocommerce-paypal-payments'), value: '16' },
]}
value={size}
onChange={(value) => setAttributes({ size: value })}
/>
)}
{isFlex && (
<SelectControl
label={__('Color', 'woocommerce-paypal-payments')}
options={[
{ label: __('Blue', 'woocommerce-paypal-payments'), value: 'blue' },
{ label: __('Black', 'woocommerce-paypal-payments'), value: 'black' },
{ label: __('White', 'woocommerce-paypal-payments'), value: 'white' },
{ label: __('White (no border)', 'woocommerce-paypal-payments'), value: 'white-no-border' },
]}
value={flexColor}
onChange={(value) => setAttributes({ flexColor: value })}
/>
)}
{isFlex && (
<SelectControl
label={__('Ratio', 'woocommerce-paypal-payments')}
options={[
{ label: __('8x1', 'woocommerce-paypal-payments'), value: '8x1' },
{ label: __('20x1', 'woocommerce-paypal-payments'), value: '20x1' },
]}
value={flexRatio}
onChange={(value) => setAttributes({ flexRatio: value })}
/>
)}
<SelectControl
label={ __( 'Placement page', 'woocommerce-paypal-payments' ) }
help={ __( 'Used for the analytics dashboard in the merchant account.', 'woocommerce-paypal-payments' ) }
options={ [
{ label: __( 'Detect automatically', 'woocommerce-paypal-payments' ), value: 'auto' },
{ label: __( 'Cart', 'woocommerce-paypal-payments' ), value: 'cart' },
{ label: __( 'Payment', 'woocommerce-paypal-payments' ), value: 'payment' },
{ label: __( 'Product', 'woocommerce-paypal-payments' ), value: 'product' },
{ label: __( 'Product list', 'woocommerce-paypal-payments' ), value: 'product-list' },
{ label: __( 'Home', 'woocommerce-paypal-payments' ), value: 'home' },
{ label: __( 'Category', 'woocommerce-paypal-payments' ), value: 'category' },
] }
value={ placement }
onChange={ ( value ) => setAttributes( { placement: value } ) }
label={__('Placement page', 'woocommerce-paypal-payments')}
help={__('Used for the analytics dashboard in the merchant account.', 'woocommerce-paypal-payments')}
options={[
{ label: __('Detect automatically', 'woocommerce-paypal-payments'), value: 'auto' },
{ label: __('Cart', 'woocommerce-paypal-payments'), value: 'cart' },
{ label: __('Payment', 'woocommerce-paypal-payments'), value: 'payment' },
{ label: __('Product', 'woocommerce-paypal-payments'), value: 'product' },
{ label: __('Product list', 'woocommerce-paypal-payments'), value: 'product-list' },
{ label: __('Home', 'woocommerce-paypal-payments'), value: 'home' },
{ label: __('Category', 'woocommerce-paypal-payments'), value: 'category' },
]}
value={placement}
onChange={(value) => setAttributes({ placement: value })}
/>
</PanelBody>
</InspectorControls>
<div {...props}>
<div className={'ppcp-overlay-child'}>
<PayPalScriptProvider
options={urlParams}
>
<div className='ppcp-overlay-child'>
<PayPalScriptProvider options={urlParams}>
<PayPalMessages
style={previewStyle}
forceReRender={[previewStyle]}
@ -204,8 +226,8 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
/>
</PayPalScriptProvider>
</div>
<div className={'ppcp-overlay-child ppcp-unclicable-overlay'}> {/* make the message not clickable */}
{!loaded && (<Spinner/>)}
<div className='ppcp-overlay-child ppcp-unclicable-overlay'> {/* make the message not clickable */}
{!loaded && <Spinner />}
</div>
</div>
</>

View file

@ -1,7 +1,6 @@
import { registerBlockType } from '@wordpress/blocks';
import Edit from './edit';
import save from './save';
const paypalIcon = (
<svg width="584.798" height="720" viewBox="0 0 154.728 190.5">

View file

@ -1,28 +0,0 @@
import { useBlockProps } from '@wordpress/block-editor';
export default function save( { attributes } ) {
const { layout, logo, position, color, size, flexColor, flexRatio, placement, id } = attributes;
const paypalAttributes = layout === 'flex' ? {
'data-pp-style-layout': 'flex',
'data-pp-style-color': flexColor,
'data-pp-style-ratio': flexRatio,
} : {
'data-pp-style-layout': 'text',
'data-pp-style-logo-type': logo,
'data-pp-style-logo-position': position,
'data-pp-style-text-color': color,
'data-pp-style-text-size': size,
};
if (placement && placement !== 'auto') {
paypalAttributes['data-pp-placement'] = placement;
}
const props = {
className: 'ppcp-paylater-message-block',
id,
...paypalAttributes,
};
return <div {...useBlockProps.save(props)}>
<div id="ppcp-messages" data-partner-attribution-id="Woo_PPCP"></div>
</div>;
}

View file

@ -9,9 +9,42 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\PayLaterBlock;
$attributes = get_block_wrapper_attributes()
?>
<div id="ppcp-paylater-message-block" <?php echo $attributes; ?>>
<?php echo do_action('ppcp-paylater-message-block', $attributes); ?>
</div>
// Early return if $attributes is not set or not an array.
if ( ! isset( $attributes ) || ! is_array( $attributes ) ) {
return;
}
// Escape the 'id' attribute to prevent XSS vulnerabilities.
$html = '<div id="' . esc_attr( $attributes['id'] ?? '' ) . '" class="ppcp-messages" data-partner-attribution-id="Woo_PPCP"></div>';
// Create an instance of WP_HTML_Tag_Processor with your HTML content.
$processor = new \WP_HTML_Tag_Processor( $html );
// Find the first div tag.
if ( $processor->next_tag( 'div' ) ) {
$layout = $attributes['layout'] ?? 'text'; // Default to 'text' layout if not set.
if ( 'flex' === $layout ) {
$processor->set_attribute( 'data-pp-style-layout', 'flex' );
$processor->set_attribute( 'data-pp-style-color', $attributes['flexColor'] ?? '' );
$processor->set_attribute( 'data-pp-style-ratio', $attributes['flexRatio'] ?? '' );
} else {
// Apply 'text' layout attributes.
$processor->set_attribute( 'data-pp-style-layout', 'text' );
$processor->set_attribute( 'data-pp-style-logo-type', $attributes['logo'] ?? '' );
$processor->set_attribute( 'data-pp-style-logo-position', $attributes['position'] ?? '' );
$processor->set_attribute( 'data-pp-style-text-color', $attributes['color'] ?? '' );
$processor->set_attribute( 'data-pp-style-text-size', $attributes['size'] ?? '' );
}
if ( ( $attributes['placement'] ?? 'auto' ) !== 'auto' ) {
$processor->set_attribute( 'data-pp-placement', $attributes['placement'] );
}
}
$updated_html = (string) $processor;
?>
<div id="ppcp-paylater-message-block" <?php echo get_block_wrapper_attributes(); ?>>
<?php echo $updated_html; ?>
</div>