Feature/post form gutenberg block (recover #1850)#1884
Conversation
…m_gutenberg_block
# Conflicts: # assets/css/admin/form-builder.css # assets/js/account.min.js # assets/js/ai-form-builder.min.js # package-lock.json
WalkthroughReplaces the legacy Changeswpuf/post-form Block Replacement
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Guards the get_editor_data() get_posts() query behind is_admin() so it no longer runs on every front-end request.
|
Review fix pushed: |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@includes/Blocks/PostForm.php`:
- Around line 117-119: The get_post_meta() call retrieving wpuf_form_settings
meta may return a non-array value, causing runtime warnings/errors when
accessing the enable_multistep array offset. In includes/Blocks/PostForm.php
(lines 117-119), normalize the $settings variable to guarantee it's an array
before accessing its offsets—use a method like casting to array or checking with
is_array(). Apply the same normalization fix in
includes/templates/blocks/post-form.php around line 213 onward where the
identical wpuf_form_settings meta retrieval and array-offset access occurs, to
prevent the same issue across both code paths.
- Line 350: Replace the `sanitize_text_field()` call for the `labelFontWeight`
attribute with a font-weight allowlist sanitizer that constrains the value to
known valid CSS font-weight values (such as normal, bold, or numeric values
100-900). This ensures consistency with sanitization patterns used for other
font-related fields and prevents malformed CSS values from being passed through.
In `@src/js/blocks/post-form/block.json`:
- Around line 12-82: The block schema in src/js/blocks/post-form/block.json
(lines 12-82) is missing errorMessageColor and successMessageColor attributes
that are already defined in the templates and PHP, which causes WordPress to
potentially filter or reject these attributes during block validation. Add two
new attributes to the attributes object in block.json after msInactiveBgColor:
errorMessageColor with type string and default empty string, and
successMessageColor with type string and default empty string. In
src/js/blocks/post-form/templates.js (lines 4-347), no change is needed as the
templates already correctly define these attributes; once the block.json schema
is updated, the templates will align properly with the schema.
In `@src/js/blocks/post-form/edit.js`:
- Around line 259-271: The loading overlay state gets set to true by the
attribute change handler in the useEffect hook but relies on cleanup at the
loading placeholder to reset it, which may not execute on fast responses. To fix
this, tie the isUpdating state directly to the API request lifecycle instead of
attribute changes. Find where the API request is initiated (likely after
setIsUpdating is called in the timeout) and ensure setIsUpdating is set to false
when the response completes or fails. This may involve capturing the loading
promise or request completion, and explicitly resetting isUpdating in the
response handler or catch block, rather than depending on the loading
placeholder cleanup mechanism.
In `@src/js/blocks/post-form/editor.css`:
- Around line 13-16: The CSS rules targeting .components-base-control
span.components-base-control__label and .components-base-control label in the
editor.css file are unscoped and leak margin styles globally across the block
editor. Wrap these selectors with the block wrapper scope (for example,
.wp-block-wpuf-post-form) to ensure the margin-top override only applies within
the post-form block context. After making this change, regenerate the compiled
CSS files in the assets/js/blocks/ directory by running your build process to
update post-form.css and post-form-rtl.css.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 25d0fa74-adcb-415d-a248-6f2792a2b806
⛔ Files ignored due to path filters (2)
assets/js/blocks/post-form.css.mapis excluded by!**/*.mapassets/js/blocks/post-form.js.mapis excluded by!**/*.map
📒 Files selected for processing (28)
assets/css/admin/gutenblock-editor.cssassets/css/admin/gutenblock.cssassets/css/frontend-form/layout2.cssassets/css/frontend-form/layout4.cssassets/css/frontend-forms.cssassets/js/admin/blockFrameSetup.jsassets/js/admin/gutenblock.jsassets/js/blocks/js/blocks/post-form/block.jsonassets/js/blocks/post-form-rtl.cssassets/js/blocks/post-form.asset.phpassets/js/blocks/post-form.cssassets/js/blocks/post-form.jsassets/less/frontend-forms.lessincludes/Admin.phpincludes/Blocks/PostForm.phpincludes/Frontend.phpincludes/Frontend/Form_Gutenberg_Block.phpincludes/Integrations/Events_Calendar/Compatibility/TEC_V6_Compatibility.phpincludes/templates/blocks/post-form.phppackage.jsonsrc/js/blocks/post-form/block.jsonsrc/js/blocks/post-form/edit.jssrc/js/blocks/post-form/editor.csssrc/js/blocks/post-form/index.jssrc/js/blocks/post-form/save.jssrc/js/blocks/post-form/templates.jswebpack.config.jswpuf.php
💤 Files with no reviewable changes (7)
- assets/css/admin/gutenblock.css
- assets/js/admin/blockFrameSetup.js
- assets/js/admin/gutenblock.js
- includes/Admin.php
- includes/Frontend/Form_Gutenberg_Block.php
- assets/css/frontend-form/layout4.css
- includes/Integrations/Events_Calendar/Compatibility/TEC_V6_Compatibility.php
| $settings = get_post_meta( $form->ID, 'wpuf_form_settings', true ); | ||
| $is_multistep = ! empty( $settings['enable_multistep'] ) && in_array( $settings['enable_multistep'], [ 'on', 'yes' ], true ); | ||
|
|
There was a problem hiding this comment.
Normalize wpuf_form_settings before array-offset access.
Line 118 assumes get_post_meta( ..., true ) always returns an array. If it returns a non-array value, multistep detection can emit runtime warnings/errors and break editor rendering paths. Apply the same normalization where this meta is read in includes/templates/blocks/post-form.php (Line 213 onward), since it shares the same assumption.
Suggested fix
- $settings = get_post_meta( $form->ID, 'wpuf_form_settings', true );
- $is_multistep = ! empty( $settings['enable_multistep'] ) && in_array( $settings['enable_multistep'], [ 'on', 'yes' ], true );
+ $settings = get_post_meta( $form->ID, 'wpuf_form_settings', true );
+ $settings = is_array( $settings ) ? $settings : [];
+ $is_multistep = ! empty( $settings['enable_multistep'] ) && in_array( $settings['enable_multistep'], [ 'on', 'yes' ], true );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@includes/Blocks/PostForm.php` around lines 117 - 119, The get_post_meta()
call retrieving wpuf_form_settings meta may return a non-array value, causing
runtime warnings/errors when accessing the enable_multistep array offset. In
includes/Blocks/PostForm.php (lines 117-119), normalize the $settings variable
to guarantee it's an array before accessing its offsets—use a method like
casting to array or checking with is_array(). Apply the same normalization fix
in includes/templates/blocks/post-form.php around line 213 onward where the
identical wpuf_form_settings meta retrieval and array-offset access occurs, to
prevent the same issue across both code paths.
| $block_config = [ | ||
| 'label_font_size' => $this->sanitize_css_length( $attributes['labelFontSize'] ), | ||
| 'label_color' => sanitize_hex_color( $attributes['labelColor'] ) ?? '', | ||
| 'label_font_weight' => sanitize_text_field( $attributes['labelFontWeight'] ), |
There was a problem hiding this comment.
Use the font-weight allowlist sanitizer for labelFontWeight.
Line 350 uses sanitize_text_field() for a CSS token that should be constrained to known valid values. This weakens sanitization consistency versus the rest of the font-related fields and can produce malformed CSS values.
Suggested fix
- 'label_font_weight' => sanitize_text_field( $attributes['labelFontWeight'] ),
+ 'label_font_weight' => $this->sanitize_font_weight( $attributes['labelFontWeight'] ),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@includes/Blocks/PostForm.php` at line 350, Replace the
`sanitize_text_field()` call for the `labelFontWeight` attribute with a
font-weight allowlist sanitizer that constrains the value to known valid CSS
font-weight values (such as normal, bold, or numeric values 100-900). This
ensures consistency with sanitization patterns used for other font-related
fields and prevents malformed CSS values from being passed through.
| "attributes": { | ||
| "blockId": { "type": "string", "default": "" }, | ||
| "formId": { "type": "number", "default": 0 }, | ||
| "activeTemplate": { "type": "string", "default": "default" }, | ||
| "labelPosition": { "type": "string", "default": "above" }, | ||
| "labelFontSize": { "type": "string", "default": "14px" }, | ||
| "labelColor": { "type": "string", "default": "" }, | ||
| "labelFontWeight": { "type": "string", "default": "normal" }, | ||
| "labelFontFamily": { "type": "string", "default": "" }, | ||
| "labelFontStyle": { "type": "string", "default": "" }, | ||
| "helpTextColor": { "type": "string", "default": "" }, | ||
| "helpTextFontFamily": { "type": "string", "default": "" }, | ||
| "helpTextFontSize": { "type": "string", "default": "12px" }, | ||
| "helpTextFontStyle": { "type": "string", "default": "" }, | ||
| "helpTextFontWeight": { "type": "string", "default": "" }, | ||
| "fieldBorder": { | ||
| "type": "object", | ||
| "default": { | ||
| "color": "#dddddd", | ||
| "style": "solid", | ||
| "width": "1px" | ||
| } | ||
| }, | ||
| "fieldBorderRadius": { "type": "string", "default": "4px" }, | ||
| "fieldPaddingV": { "type": "string", "default": "8px" }, | ||
| "fieldPaddingH": { "type": "string", "default": "12px" }, | ||
| "fieldBackgroundColor": { "type": "string", "default": "" }, | ||
| "fieldTextColor": { "type": "string", "default": "" }, | ||
| "fieldPlaceholderColor": { "type": "string", "default": "" }, | ||
| "fieldFontFamily": { "type": "string", "default": "" }, | ||
| "fieldFontSize": { "type": "string", "default": "14px" }, | ||
| "fieldFontStyle": { "type": "string", "default": "" }, | ||
| "fieldFontWeight": { "type": "string", "default": "" }, | ||
| "fieldMarginBottom": { "type": "string", "default": "16px" }, | ||
| "fieldFocusBorderColor": { "type": "string", "default": "" }, | ||
| "buttonBackgroundColor": { "type": "string", "default": "" }, | ||
| "buttonTextColor": { "type": "string", "default": "" }, | ||
| "buttonFontFamily": { "type": "string", "default": "" }, | ||
| "buttonFontStyle": { "type": "string", "default": "" }, | ||
| "buttonFontWeight": { "type": "string", "default": "" }, | ||
| "buttonBorderWidth": { "type": "string", "default": "0px" }, | ||
| "buttonBorderRadius": { "type": "string", "default": "4px" }, | ||
| "buttonFontSize": { "type": "string", "default": "14px" }, | ||
| "buttonPaddingV": { "type": "string", "default": "10px" }, | ||
| "buttonPaddingH": { "type": "string", "default": "20px" }, | ||
| "uploadButtonBackgroundColor": { "type": "string", "default": "" }, | ||
| "uploadButtonTextColor": { "type": "string", "default": "" }, | ||
| "uploadButtonFontFamily": { "type": "string", "default": "" }, | ||
| "uploadButtonFontStyle": { "type": "string", "default": "" }, | ||
| "uploadButtonFontWeight": { "type": "string", "default": "" }, | ||
| "uploadButtonBorderColor": { "type": "string", "default": "#dddddd" }, | ||
| "uploadButtonBorderWidth": { "type": "string", "default": "1px" }, | ||
| "uploadButtonBorderRadius": { "type": "string", "default": "4px" }, | ||
| "uploadButtonFontSize": { "type": "string", "default": "13px" }, | ||
| "uploadButtonPaddingV": { "type": "string", "default": "8px" }, | ||
| "uploadButtonPaddingH": { "type": "string", "default": "16px" }, | ||
| "msButtonBackgroundColor": { "type": "string", "default": "#1e1e1e" }, | ||
| "msButtonTextColor": { "type": "string", "default": "#ffffff" }, | ||
| "msButtonFontFamily": { "type": "string", "default": "" }, | ||
| "msButtonFontStyle": { "type": "string", "default": "" }, | ||
| "msButtonFontWeight": { "type": "string", "default": "" }, | ||
| "msButtonBorderColor": { "type": "string", "default": "" }, | ||
| "msButtonBorderWidth": { "type": "string", "default": "0px" }, | ||
| "msButtonBorderRadius": { "type": "string", "default": "4px" }, | ||
| "msButtonFontSize": { "type": "string", "default": "14px" }, | ||
| "msButtonPaddingV": { "type": "string", "default": "10px" }, | ||
| "msButtonPaddingH": { "type": "string", "default": "20px" }, | ||
| "msActiveBgColor": { "type": "string", "default": "" }, | ||
| "msActiveTextColor": { "type": "string", "default": "" }, | ||
| "msInactiveBgColor": { "type": "string", "default": "" } | ||
| }, |
There was a problem hiding this comment.
Block schema is missing two styling attributes defined in templates and PHP.
The root cause: block.json does not include errorMessageColor and successMessageColor in the attributes section, but templates.js defines these in every template preset (e.g., line 69–70 of default template) and PostForm::render() in PHP includes them in defaults. Without schema definition, WordPress may filter or reject these attributes during block save/validation, breaking error/success message styling.
src/js/blocks/post-form/block.json#L12-L82: AdderrorMessageColorandsuccessMessageColorto the attributes object before the closing}at line 82. Add these two lines aftermsInactiveTextColor:"errorMessageColor": { "type": "string", "default": "" }, "successMessageColor": { "type": "string", "default": "" },
src/js/blocks/post-form/templates.js#L4-L347: No change needed in this file; the templates correctly define these attributes. Once block.json is updated, the templates will align with the schema.
📍 Affects 2 files
src/js/blocks/post-form/block.json#L12-L82(this comment)src/js/blocks/post-form/templates.js#L4-L347
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/js/blocks/post-form/block.json` around lines 12 - 82, The block schema in
src/js/blocks/post-form/block.json (lines 12-82) is missing errorMessageColor
and successMessageColor attributes that are already defined in the templates and
PHP, which causes WordPress to potentially filter or reject these attributes
during block validation. Add two new attributes to the attributes object in
block.json after msInactiveBgColor: errorMessageColor with type string and
default empty string, and successMessageColor with type string and default empty
string. In src/js/blocks/post-form/templates.js (lines 4-347), no change is
needed as the templates already correctly define these attributes; once the
block.json schema is updated, the templates will align properly with the schema.
| useEffect(() => { | ||
| if (isFirstRender.current) { | ||
| isFirstRender.current = false; | ||
| return; | ||
| } | ||
| if (debounceTimerRef.current) { | ||
| clearTimeout(debounceTimerRef.current); | ||
| } | ||
| debounceTimerRef.current = setTimeout(() => { | ||
| setIsUpdating(true); | ||
| }, 150); | ||
| return () => clearTimeout(debounceTimerRef.current); | ||
| }, [attributes]); |
There was a problem hiding this comment.
Loading overlay state can get stuck after fast SSR responses
Line 267 sets isUpdating from an attribute-change timer, but reset happens only via the loading placeholder cleanup at Lines 807-811. When a response resolves quickly, that cleanup path may not run, leaving the overlay permanently visible.
Suggested fix (tie overlay state to loading lifecycle instead of raw attribute changes)
- // SSR loading overlay state
- const [isUpdating, setIsUpdating] = useState(false);
- const debounceTimerRef = useRef(null);
- const isFirstRender = useRef(true);
-
- useEffect(() => {
- if (isFirstRender.current) {
- isFirstRender.current = false;
- return;
- }
- if (debounceTimerRef.current) {
- clearTimeout(debounceTimerRef.current);
- }
- debounceTimerRef.current = setTimeout(() => {
- setIsUpdating(true);
- }, 150);
- return () => clearTimeout(debounceTimerRef.current);
- }, [attributes]);
+ // SSR loading overlay state
+ const [isUpdating, setIsUpdating] = useState(false);- LoadingResponsePlaceholder={() => {
- // eslint-disable-next-line react-hooks/rules-of-hooks
- useEffect(() => {
- return () => {
- setIsUpdating(false);
- };
- }, []);
- return null;
- }}
+ LoadingResponsePlaceholder={() => {
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ useEffect(() => {
+ const timer = setTimeout(() => setIsUpdating(true), 150);
+ return () => {
+ clearTimeout(timer);
+ setIsUpdating(false);
+ };
+ }, []);
+ return null;
+ }}Also applies to: 805-813
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/js/blocks/post-form/edit.js` around lines 259 - 271, The loading overlay
state gets set to true by the attribute change handler in the useEffect hook but
relies on cleanup at the loading placeholder to reset it, which may not execute
on fast responses. To fix this, tie the isUpdating state directly to the API
request lifecycle instead of attribute changes. Find where the API request is
initiated (likely after setIsUpdating is called in the timeout) and ensure
setIsUpdating is set to false when the response completes or fails. This may
involve capturing the loading promise or request completion, and explicitly
resetting isUpdating in the response handler or catch block, rather than
depending on the loading placeholder cleanup mechanism.
| .components-base-control span.components-base-control__label, | ||
| .components-base-control label { | ||
| margin-top: .5rem; | ||
| } |
There was a problem hiding this comment.
Unscoped selector leaks styles across the entire block editor
Lines 13-16 target .components-base-control globally, so this margin override can affect controls outside wpuf/post-form. Scope this rule to the block wrapper (for example, .wp-block-wpuf-post-form ...) and regenerate assets/js/blocks/post-form.css plus assets/js/blocks/post-form-rtl.css.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/js/blocks/post-form/editor.css` around lines 13 - 16, The CSS rules
targeting .components-base-control span.components-base-control__label and
.components-base-control label in the editor.css file are unscoped and leak
margin styles globally across the block editor. Wrap these selectors with the
block wrapper scope (for example, .wp-block-wpuf-post-form) to ensure the
margin-top override only applies within the post-form block context. After
making this change, regenerate the compiled CSS files in the assets/js/blocks/
directory by running your build process to update post-form.css and
post-form-rtl.css.
Recovered from #1850 (originally by @sapayth), rebased onto
developwith merge conflicts resolved. Functionality preserved.Supersedes #1850.
Summary by CodeRabbit
New Features
Bug Fixes
Chores