Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions blueprint.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/blockparty-modal-demo/",
"landingPage": "/wp-admin/post.php?post=4&action=edit",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Landing page hardcodes fragile post ID assumption

Medium Severity

The landingPage is now /wp-admin/post.php?post=4&action=edit, which hardcodes the assumption that the created page will have post ID 4. The previous version used the post slug (/blockparty-modal-demo/) and explicitly set post_name. The new runPHP step doesn't set post_name, and the resulting post ID depends on WordPress's internal auto-increment state, which isn't guaranteed to be 4.

Fix in Cursor Fix in Web

"preferredVersions": {
"php": "8.1",
"wp": "latest"
Expand All @@ -26,7 +26,11 @@
},
{
"step": "runPHP",
"code": "<?php\nrequire_once '/wordpress/wp-load.php';\n$page_content = base64_decode( 'PCEtLSB3cDpidXR0b25zIC0tPgo8ZGl2IGNsYXNzPSJ3cC1ibG9jay1idXR0b25zIj48IS0tIHdwOmJ1dHRvbiB7ImxpbmtlZE1vZGFsSWQiOiJtLWUxNmRlM2ZlNzlmOSJ9IC0tPgo8ZGl2IGNsYXNzPSJ3cC1ibG9jay1idXR0b24iPjxhIGNsYXNzPSJ3cC1ibG9jay1idXR0b25fX2xpbmsgd3AtZWxlbWVudC1idXR0b24iPk9wZW4gbXkgbW9kYWwgd2luZG93PC9hPjwvZGl2Pgo8IS0tIC93cDpidXR0b24gLS0+PC9kaXY+CjwhLS0gL3dwOmJ1dHRvbnMgLS0+Cgo8IS0tIHdwOmJsb2NrcGFydHkvbW9kYWwgeyJ0aXRsZSI6Ik15IE1vZGFsIiwibW9kYWxJZCI6Im0tZTE2ZGUzZmU3OWY5IiwiZGlzcGxheUljb25Pbmx5Ijp0cnVlLCJzdHlsZSI6eyJzcGFjaW5nIjp7InBhZGRpbmciOnsidG9wIjoidmFyOnByZXNldHxzcGFjaW5nfDQwIiwiYm90dG9tIjoidmFyOnByZXNldHxzcGFjaW5nfDQwIiwibGVmdCI6InZhcjpwcmVzZXR8c3BhY2luZ3w0MCIsInJpZ2h0IjoidmFyOnByZXNldHxzcGFjaW5nfDQwIn19fX0gLS0+CjxkaWFsb2cgY2xhc3M9IndwLWJsb2NrLWJsb2NrcGFydHktbW9kYWwiIHN0eWxlPSJwYWRkaW5nLXRvcDp2YXIoLS13cC0tcHJlc2V0LS1zcGFjaW5nLS00MCk7cGFkZGluZy1yaWdodDp2YXIoLS13cC0tcHJlc2V0LS1zcGFjaW5nLS00MCk7cGFkZGluZy1ib3R0b206dmFyKC0td3AtLXByZXNldC0tc3BhY2luZy0tNDApO3BhZGRpbmctbGVmdDp2YXIoLS13cC0tcHJlc2V0LS1zcGFjaW5nLS00MCkiIGlkPSJtb2RhbC1tLWUxNmRlM2ZlNzlmOSIgYXJpYS1tb2RhbD0idHJ1ZSIgY2xvc2VkYnk9ImFueSI+PGRpdiBjbGFzcz0id3AtYmxvY2stYmxvY2twYXJ0eS1tb2RhbF9faGVhZGVyIj48aDIgY2xhc3M9IndwLWJsb2NrLWJsb2NrcGFydHktbW9kYWxfX3RpdGxlIj5NeSBNb2RhbDwvaDI+PC9kaXY+PGRpdiBjbGFzcz0id3AtYmxvY2stYmxvY2twYXJ0eS1tb2RhbF9fY29udGVudCI+PCEtLSB3cDpwYXJhZ3JhcGggLS0+CjxwPkJsb2NrcGFydHkgTW9kYWwgaXMgYSBXb3JkUHJlc3MgcGx1Z2luIHRoYXQgbGV0cyB5b3UgYWRkIGFjY2Vzc2libGUgbW9kYWwgZGlhbG9ncyB0byB5b3VyIGNvbnRlbnQgdmlhIHRoZSBHdXRlbmJlcmcgYmxvY2sgZWRpdG9yLiBZb3UgZGVmaW5lIHRoZSBtb2RhbCBjb250ZW50IGFuZCBiZWhhdmlvdXIgaW4gdGhlIGVkaXRvcjsgb24gdGhlIGZyb250ZW5kLCB0aGUgbW9kYWwgaXMgc2hvd24gd2hlbiB0aGUgdXNlciBhY3RpdmF0ZXMgYSBsaW5rZWQgdHJpZ2dlciAoc3VjaCBhcyBhIGJ1dHRvbiBibG9jaykuPC9wPgo8IS0tIC93cDpwYXJhZ3JhcGggLS0+PC9kaXY+PGJ1dHRvbiB0eXBlPSJidXR0b24iIGNsYXNzPSJ3cC1ibG9jay1ibG9ja3BhcnR5LW1vZGFsX19jbG9zZS1idXR0b24iPjxzcGFuIGNsYXNzPSJzci1vbmx5Ij5DbG9zZSB0aGlzIGRpYWxvZyB3aW5kb3c8L3NwYW4+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBhcmlhLWhpZGRlbj0idHJ1ZSI+PHBhdGggZD0ibTEzLjA2IDEyIDYuNDctNi40Ny0xLjA2LTEuMDZMMTIgMTAuOTQgNS41MyA0LjQ3IDQuNDcgNS41MyAxMC45NCAxMmwtNi40NyA2LjQ3IDEuMDYgMS4wNkwxMiAxMy4wNmw2LjQ3IDYuNDcgMS4wNi0xLjA2TDEzLjA2IDEyWiI+PC9wYXRoPjwvc3ZnPjwvYnV0dG9uPjwvZGlhbG9nPgo8IS0tIC93cDpibG9ja3BhcnR5L21vZGFsIC0tPg==' );\n$page_id = wp_insert_post( array(\n\t'post_title' => 'Blockparty Modal',\n\t'post_name' => 'blockparty-modal-demo',\n\t'post_content' => $page_content,\n\t'post_status' => 'publish',\n\t'post_type' => 'page',\n) );\necho 'Page created with ID: ' . $page_id;\n?>"
"code": "<?php\nrequire_once '/wordpress/wp-load.php';\n$dir = WP_CONTENT_DIR . '/mu-plugins';\nif ( ! is_dir( $dir ) ) {\n\twp_mkdir_p( $dir );\n}\n$file = $dir . '/blockparty-modal-playground-svg-kses.php';\nfile_put_contents( $file, base64_decode( 'PD9waHAKLyoqCiAqIFBsdWdpbiBOYW1lOiBCbG9ja3BhcnR5IE1vZGFsIOKAlCBQbGF5Z3JvdW5kIChhbGxvdyBTVkcgaW4gcG9zdCBjb250ZW50KQogKiBEZXNjcmlwdGlvbjogTXVzdC11c2UgcGx1Z2luIGZvciB0aGUgQmxvY2twYXJ0eSBNb2RhbCBXb3JkUHJlc3MgUGxheWdyb3VuZCBibHVlcHJpbnQgb25seS4KICogVmVyc2lvbjogMS4wCiAqLwoKYWRkX2ZpbHRlcigKCSd3cF9rc2VzX2FsbG93ZWRfaHRtbCcsCglzdGF0aWMgZnVuY3Rpb24gKCAkdGFncywgJGNvbnRleHQgKSB7CgkJaWYgKCAncG9zdCcgIT09ICRjb250ZXh0ICkgewoJCQlyZXR1cm4gJHRhZ3M7CgkJfQoJCSR0YWdzWydzdmcnXSA9IGFycmF5KAoJCQkneG1sbnMnICAgICAgID0+IHRydWUsCgkJCSd2aWV3Ym94JyAgICAgPT4gdHJ1ZSwKCQkJJ3dpZHRoJyAgICAgICA9PiB0cnVlLAoJCQknaGVpZ2h0JyAgICAgID0+IHRydWUsCgkJCSdmaWxsJyAgICAgICAgPT4gdHJ1ZSwKCQkJJ2NsYXNzJyAgICAgICA9PiB0cnVlLAoJCQknYXJpYS1oaWRkZW4nID0+IHRydWUsCgkJCSdyb2xlJyAgICAgICAgPT4gdHJ1ZSwKCQkJJ2ZvY3VzYWJsZScgICA9PiB0cnVlLAoJCSk7CgkJJHRhZ3NbJ3BhdGgnXSA9IGFycmF5KAoJCQknZCcgICAgID0+IHRydWUsCgkJCSdmaWxsJyAgPT4gdHJ1ZSwKCQkJJ2NsYXNzJyA9PiB0cnVlLAoJCSk7CgkJcmV0dXJuICR0YWdzOwoJfSwKCTEwLAoJMgopOwo=' ) );\necho file_exists( $file ) ? 'mu-plugin installed' : 'mu-plugin failed';\n?>"
},
{
"step": "runPHP",
"code": "<?php require_once '/wordpress/wp-load.php'; $page_content = '<?php require_once 'wordpress/wp-load.php'; $page_content = '<!-- wp:buttons -->\n<div class=\"wp-block-buttons\"><!-- wp:button {\"linkedModalId\":\"m-e16de3fe79f9\"} -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\">Open my modal window</a></div>\n<!-- /wp:button --></div>\n<!-- /wp:buttons -->\n\n<!-- wp:blockparty/modal {\"title\":\"My Modal\",\"modalId\":\"m-e16de3fe79f9\",\"displayIconOnly\":true,\"style\":{\"spacing\":{\"padding\":{\"top\":\"var:preset|spacing|40\",\"bottom\":\"var:preset|spacing|40\",\"left\":\"var:preset|spacing|40\",\"right\":\"var:preset|spacing|40\"}}}} -->\n<dialog class=\"wp-block-blockparty-modal\" style=\"padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--40)\" id=\"modal-m-e16de3fe79f9\" aria-modal=\"true\" closedby=\"any\"><div class=\"wp-block-blockparty-modal__header\"><h2 class=\"wp-block-blockparty-modal__title\">My Modal</h2></div><div class=\"wp-block-blockparty-modal__content\"><!-- wp:paragraph -->\n<p>Blockparty Modal is a WordPress plugin that lets you add accessible modal dialogs to your content via the Gutenberg block editor. You define the modal content and behaviour in the editor; on the frontend, the modal is shown when the user activates a linked trigger (such as a button block).</p>\n<!-- /wp:paragraph --></div><button type=\"button\" class=\"wp-block-blockparty-modal__close-button\"><span class=\"sr-only\">Close this dialog window</span><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" aria-hidden=\"true\"><path d=\"m13.06 12 6.47-6.47-1.06-1.06L12 10.94 5.53 4.47 4.47 5.53 10.94 12l-6.47 6.47 1.06 1.06L12 13.06l6.47 6.47 1.06-1.06L13.06 12Z\"></path></svg></button></dialog>\n<!-- /wp:blockparty/modal -->'; $page_id = wp_insert_post(array('post_title' => 'Blockparty Modal', 'post_content' => $page_content, 'post_status' => 'publish', 'post_type' => 'page')); echo 'Page created with ID: ' . $page_id; ?>'; $page_id = wp_insert_post(array('post_title' => 'Blockparty Modal', 'post_content' => $page_content, 'post_status' => 'publish', 'post_type' => 'page')); echo 'Page created with ID: ' . $page_id; ?>"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrupted PHP code with duplicated nested script

High Severity

The second runPHP step's code value contains a corrupted PHP script. The entire PHP script is accidentally duplicated/nested inside itself as the $page_content assignment value. This creates broken single-quote string delimiters — $page_content = '<?php require_once 'wordpress/wp-load.php' — where the quote before wordpress prematurely terminates the string, causing a PHP parse error. The wp_insert_post call and its arguments also appear duplicated at the end. The previous version correctly used base64_decode() to avoid quoting issues; this replacement inlines the content but fails to escape quotes and includes the wrapping script code inside itself.

Fix in Cursor Fix in Web

}
]
}
80 changes: 40 additions & 40 deletions src/blockparty-modal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ import {
addLinkedModalAttribute,
} from './utils';

registerBlockType(metadata.name, {
registerBlockType( metadata.name, {
icon: modal,
edit: Edit,
save,
});
} );

/**
* Returns the list of block names allowed as modal triggers (same as filter blockparty_modal_trigger_allowed_blocks).
Expand All @@ -41,99 +41,99 @@ registerBlockType(metadata.name, {
*/
function getModalTriggerAllowedBlocks() {
try {
const settings = select('core/block-editor').getSettings();
const settings = select( 'core/block-editor' ).getSettings();
const list = settings?.blockpartyModalTriggerAllowedBlocks;
return Array.isArray(list) ? list : ['core/button'];
return Array.isArray( list ) ? list : [ 'core/button' ];
} catch {
return ['core/button'];
return [ 'core/button' ];
}
}

// Add linkedModalId attribute only to blocks allowed as modal triggers.
addFilter(
'blocks.registerBlockType',
'blockparty-modal/add-linked-modal-attribute',
(settings, blockName) => {
( settings, blockName ) => {
const allowedBlocks = getModalTriggerAllowedBlocks();
if (!allowedBlocks.includes(blockName)) {
if ( ! allowedBlocks.includes( blockName ) ) {
return settings;
}
return addLinkedModalAttribute(settings);
return addLinkedModalAttribute( settings );
}
);

// Blocks registered before our script loaded (e.g. core blocks) didn't get the
// filter — re-register only allowed blocks so linkedModalId is persisted on save.
const allowedBlocks = getModalTriggerAllowedBlocks();
const blockTypes = getBlockTypes();
blockTypes.forEach((blockType) => {
blockTypes.forEach( ( blockType ) => {
if (
allowedBlocks.includes(blockType.name) &&
!blockType.attributes?.[LINKED_MODAL_ATTR]
allowedBlocks.includes( blockType.name ) &&
! blockType.attributes?.[ LINKED_MODAL_ATTR ]
) {
registerBlockType(
blockType.name,
addLinkedModalAttribute(blockType)
addLinkedModalAttribute( blockType )
);
}
});
} );

// Add "Attached modal" panel with Combobox only to blocks allowed as modal triggers (see filter blockparty_modal_trigger_allowed_blocks).
addFilter(
'editor.BlockEdit',
'blockparty-modal/with-modal-trigger-control',
(BlockEdit) => (props) => {
( BlockEdit ) => ( props ) => {
const { name, attributes, setAttributes } = props;

if (name === MODAL_BLOCK_NAME) {
return <BlockEdit {...props} />;
if ( name === MODAL_BLOCK_NAME ) {
return <BlockEdit { ...props } />;
}

const triggerAllowedBlocks = useSelect((storeSelect) => {
const settings = storeSelect('core/block-editor').getSettings();
const triggerAllowedBlocks = useSelect( ( storeSelect ) => {
const settings = storeSelect( 'core/block-editor' ).getSettings();
const list = settings?.blockpartyModalTriggerAllowedBlocks;
return Array.isArray(list) ? list : ['core/button'];
}, []);
return Array.isArray( list ) ? list : [ 'core/button' ];
}, [] );

if (!triggerAllowedBlocks.includes(name)) {
return <BlockEdit {...props} />;
if ( ! triggerAllowedBlocks.includes( name ) ) {
return <BlockEdit { ...props } />;
}

const modalOptions = useSelect((storeSelect) => {
return getModalOptionsFromEditor(storeSelect);
}, []);
const modalOptions = useSelect( ( storeSelect ) => {
return getModalOptionsFromEditor( storeSelect );
}, [] );

const options = [
{ value: '', label: __('None', 'blockparty-modal') },
{ value: '', label: __( 'None', 'blockparty-modal' ) },
...modalOptions,
];

const value = attributes[LINKED_MODAL_ATTR] || '';
const value = attributes[ LINKED_MODAL_ATTR ] || '';

return (
<>
<BlockEdit {...props} />
<BlockEdit { ...props } />
<InspectorControls key="blockparty-modal-trigger">
<PanelBody
title={__('Attached modal', 'blockparty-modal')}
initialOpen={false}
title={ __( 'Attached modal', 'blockparty-modal' ) }
initialOpen={ false }
>
<ComboboxControl
label={__(
label={ __(
'Modal to open when block is clicked',
'blockparty-modal'
)}
value={value}
options={options}
onChange={(newValue) =>
setAttributes({
[LINKED_MODAL_ATTR]: newValue || '',
})
) }
value={ value }
options={ options }
onChange={ ( newValue ) =>
setAttributes( {
[ LINKED_MODAL_ATTR ]: newValue || '',
} )
}
placeholder={__(
placeholder={ __(
'Select a modal…',
'blockparty-modal'
)}
) }
/>
</PanelBody>
</InspectorControls>
Expand Down
Loading