feature: account page elementor widget#1826
feature: account page elementor widget#1826sapayth wants to merge 3 commits intoweDevsOfficial:developfrom
Conversation
make UX better by removing common settings between container and Advance tab
WalkthroughThis PR introduces comprehensive Elementor integration for WPUF, adding two new widget classes for displaying forms and account dashboards, registering an Elementor integration module, updating frontend initialization to support Elementor contexts, and refining account template rendering with filter hooks for template argument customization. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
includes/Integrations/Elementor/Elementor.php (2)
83-97: Redundant function existence check.The check
if ( function_exists( 'wp_enqueue_script' ) )on line 87 is unnecessary sincewp_enqueue_scriptis a core WordPress function that is always available at this stage of the request lifecycle.♻️ Suggested simplification
if ( function_exists( 'wp_enqueue_editor' ) ) { wp_enqueue_editor(); // Also explicitly enqueue TinyMCE scripts if available - if ( function_exists( 'wp_enqueue_script' ) ) { - // Check if these scripts exist and enqueue them - global $wp_scripts; - if ( isset( $wp_scripts->registered['tinymce'] ) ) { - wp_enqueue_script( 'tinymce' ); - } - if ( isset( $wp_scripts->registered['wp-tinymce'] ) ) { - wp_enqueue_script( 'wp-tinymce' ); - } + global $wp_scripts; + if ( isset( $wp_scripts->registered['tinymce'] ) ) { + wp_enqueue_script( 'tinymce' ); + } + if ( isset( $wp_scripts->registered['wp-tinymce'] ) ) { + wp_enqueue_script( 'wp-tinymce' ); } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@includes/Integrations/Elementor/Elementor.php` around lines 83 - 97, Remove the redundant function_exists check for wp_enqueue_script and simplify the block: after calling wp_enqueue_editor() keep the global $wp_scripts and directly check isset($wp_scripts->registered['tinymce']) and isset($wp_scripts->registered['wp-tinymce']) and call wp_enqueue_script('tinymce') and wp_enqueue_script('wp-tinymce') as needed; reference wp_enqueue_editor, wp_enqueue_script, $wp_scripts, 'tinymce' and 'wp-tinymce' to locate the code to change.
55-58: Scripts enqueued in a styles callback may not be registered yet.Enqueueing scripts (
wpuf-conditional-logic,wpuf-frontend-form) insideenqueue_styles()which is hooked toelementor/frontend/after_enqueue_stylescould fail if these scripts aren't yet registered at that point. Also,wpuf-frontend-formis enqueued again unconditionally inenqueue_wpuf_form_assets()(line 126), causing redundancy.♻️ Suggested improvement
Move the Pro script enqueue logic to
enqueue_scripts()where other scripts are handled:public function enqueue_styles() { // ... style dequeuing and enqueueing ... - - if ( wpuf_is_pro_active() ) { - wp_enqueue_script( 'wpuf-conditional-logic' ); - wp_enqueue_script( 'wpuf-frontend-form' ); - } - /** * Fires after WPUF has enqueued its styles in Elementor context.Then in
enqueue_scripts():public function enqueue_scripts() { // Enqueue all required WPUF form assets $this->enqueue_wpuf_form_assets(); + + // Conditionally enqueue Pro scripts + if ( wpuf_is_pro_active() ) { + wp_enqueue_script( 'wpuf-conditional-logic' ); + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@includes/Integrations/Elementor/Elementor.php` around lines 55 - 58, Move the Pro script enqueue logic out of enqueue_styles() and into enqueue_scripts() so scripts are enqueued at the proper hook; specifically, remove the wp_enqueue_script('wpuf-conditional-logic') and wp_enqueue_script('wpuf-frontend-form') calls from enqueue_styles() and add them under the wpuf_is_pro_active() check inside enqueue_scripts() instead, ensuring you keep the wpuf_is_pro_active() guard and avoid double-enqueue with enqueue_wpuf_form_assets() by deleting the unconditional wpuf-frontend-form enqueue in enqueue_wpuf_form_assets() or by checking is_script_enqueued before adding it.includes/Integrations/Elementor/Widget.php (3)
1116-1117: Usingwp_kses_post()on render attribute string is unconventional.Elementor's
get_render_attribute_string()already returns properly escaped attribute strings. Wrapping it withwp_kses_post()(which is designed for post content) is redundant and could theoretically strip valid attribute values in edge cases.Consider using the standard Elementor pattern
- echo '<div ' . wp_kses_post( $this->get_render_attribute_string( 'wrapper' ) ) . '>'; + ?> + <div <?php $this->print_render_attribute_string( 'wrapper' ); ?>> + <?php🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@includes/Integrations/Elementor/Widget.php` around lines 1116 - 1117, The render attribute string is being double-escaped by wrapping Elementor's get_render_attribute_string('wrapper') with wp_kses_post; remove wp_kses_post and output the attribute string directly so Elementor's own escaping is preserved. Update the echo line that builds the wrapper (where get_render_attribute_string and 'wrapper' are used) to use $this->get_render_attribute_string('wrapper') without wp_kses_post, keeping the existing echo $output comment and phpcs ignore as-is.
1067-1067: Sanitizeform_idbefore use in shortcode.The
form_idvalue should be cast to an integer before being used in the shortcode string. While the value comes from a SELECT control with predefined options, defensive coding ensures robustness against unexpected input.Proposed fix
- $form_id = isset( $settings['form_id'] ) ? $settings['form_id'] : null; + $form_id = isset( $settings['form_id'] ) ? absint( $settings['form_id'] ) : 0; - if ( empty( $form_id ) ) { + if ( ! $form_id ) { return; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@includes/Integrations/Elementor/Widget.php` at line 1067, The $form_id pulled from settings is not sanitized; update the assignment in the Widget class so $form_id is cast to an integer (e.g., via (int) or intval) when reading $settings['form_id'] and use that sanitized integer in the shortcode construction/usage (references: the $form_id variable and the shortcode invocation where it is embedded) to ensure only an integer is passed to the shortcode.
1126-1141: Global error handler override may mask legitimate errors.Overriding
window.onerrorto suppress specific errors during Elementor preview could inadvertently hide real issues during development. While the handler is restored after 2 seconds, this window may not be sufficient for slower environments, and it could interfere with other error monitoring tools.Consider a more targeted approach, such as wrapping specific initialization calls in try-catch blocks instead of globally intercepting all errors.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@includes/Integrations/Elementor/Widget.php` around lines 1126 - 1141, The global override of window.onerror (and the originalErrorHandler assignment) can mask real errors; remove the temporary window.onerror override and instead wrap the specific third-party initialization calls that trigger "google is not defined" or "barrating is not a function" in targeted try-catch blocks (or check for the existence of google/barrating before calling) inside the Elementor preview initialization code (the same area where window.onerror was set); if you must log/suppress only those messages, catch the exceptions locally and handle/log them there rather than replacing window.onerror, and ensure any original error handler is left untouched (do not modify originalErrorHandler/window.onerror globally).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@includes/Integrations/Elementor/Elementor.php`:
- Line 40: Update the used style handle to the registered one: replace
occurrences of 'wpuf-elementor-frontend-forms' with the existing registered
handle 'wpuf-frontend-forms' (in includes/Integrations/Elementor/Elementor.php
where $style_handles is defined and in Widget.php where the non-existent handle
is referenced, e.g., the enqueue call or any variable referencing that handle)
so wp_enqueue_style() uses a registered style handle and styles load in
Elementor context.
In `@includes/Integrations/Elementor/Widget.php`:
- Around line 1143-1145: The DOM selector for TinyMCE is not scoped and uses
document.querySelector('.wpuf-elementor-widget-wrapper') which picks only the
first widget; update the widget rendering to output a unique wrapper identifier
(e.g. in the render method set a unique_id like 'wpuf-widget-' + $this->get_id()
via add_render_attribute('wrapper', 'id', $unique_id')) and change the JS that
sets wrapper (the variable named wrapper in the script that currently calls
document.querySelector) to select by that unique id (or scope via the script
element context) so each instance targets its own textarea.wp-editor-area
elements; ensure references include the same unique_id used in render and the
wrapper variable in the JS.
---
Nitpick comments:
In `@includes/Integrations/Elementor/Elementor.php`:
- Around line 83-97: Remove the redundant function_exists check for
wp_enqueue_script and simplify the block: after calling wp_enqueue_editor() keep
the global $wp_scripts and directly check
isset($wp_scripts->registered['tinymce']) and
isset($wp_scripts->registered['wp-tinymce']) and call
wp_enqueue_script('tinymce') and wp_enqueue_script('wp-tinymce') as needed;
reference wp_enqueue_editor, wp_enqueue_script, $wp_scripts, 'tinymce' and
'wp-tinymce' to locate the code to change.
- Around line 55-58: Move the Pro script enqueue logic out of enqueue_styles()
and into enqueue_scripts() so scripts are enqueued at the proper hook;
specifically, remove the wp_enqueue_script('wpuf-conditional-logic') and
wp_enqueue_script('wpuf-frontend-form') calls from enqueue_styles() and add them
under the wpuf_is_pro_active() check inside enqueue_scripts() instead, ensuring
you keep the wpuf_is_pro_active() guard and avoid double-enqueue with
enqueue_wpuf_form_assets() by deleting the unconditional wpuf-frontend-form
enqueue in enqueue_wpuf_form_assets() or by checking is_script_enqueued before
adding it.
In `@includes/Integrations/Elementor/Widget.php`:
- Around line 1116-1117: The render attribute string is being double-escaped by
wrapping Elementor's get_render_attribute_string('wrapper') with wp_kses_post;
remove wp_kses_post and output the attribute string directly so Elementor's own
escaping is preserved. Update the echo line that builds the wrapper (where
get_render_attribute_string and 'wrapper' are used) to use
$this->get_render_attribute_string('wrapper') without wp_kses_post, keeping the
existing echo $output comment and phpcs ignore as-is.
- Line 1067: The $form_id pulled from settings is not sanitized; update the
assignment in the Widget class so $form_id is cast to an integer (e.g., via
(int) or intval) when reading $settings['form_id'] and use that sanitized
integer in the shortcode construction/usage (references: the $form_id variable
and the shortcode invocation where it is embedded) to ensure only an integer is
passed to the shortcode.
- Around line 1126-1141: The global override of window.onerror (and the
originalErrorHandler assignment) can mask real errors; remove the temporary
window.onerror override and instead wrap the specific third-party initialization
calls that trigger "google is not defined" or "barrating is not a function" in
targeted try-catch blocks (or check for the existence of google/barrating before
calling) inside the Elementor preview initialization code (the same area where
window.onerror was set); if you must log/suppress only those messages, catch the
exceptions locally and handle/log them there rather than replacing
window.onerror, and ensure any original error handler is left untouched (do not
modify originalErrorHandler/window.onerror globally).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e5231e67-865a-427f-b1c9-3e74ed19564f
📒 Files selected for processing (9)
includes/Frontend/Frontend_Account.phpincludes/Integrations.phpincludes/Integrations/Elementor/Account_Widget.phpincludes/Integrations/Elementor/Elementor.phpincludes/Integrations/Elementor/Widget.phpsrc/css/frontend/account.csstemplates/account.phptemplates/dashboard/posts.phpwpuf.php
| wp_dequeue_style('wpuf-layout4'); | ||
| wp_dequeue_style('wpuf-layout5'); | ||
|
|
||
| $style_handles = [ 'wpuf-elementor-frontend-forms', 'wpuf-account' ]; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for style registrations containing 'elementor-frontend-forms'
rg -n "elementor-frontend-forms" --type=php
# Check all registered styles in Assets.php
rg -n "wp_register_style" includes/Assets.php -A 3
# Show the context around line 40 in Elementor.php
cat -n includes/Integrations/Elementor/Elementor.php | head -80Repository: weDevsOfficial/wp-user-frontend
Length of output: 3606
🏁 Script executed:
# Search for the styles array definition in Assets.php
rg -n "get_styles|'elementor-frontend-forms'|\"elementor-frontend-forms\"" includes/Assets.php -B 2 -A 50 | head -150
# Also search for 'frontend-forms' to see what styles are actually registered
rg -n "'frontend-forms'|\"frontend-forms\"" includes/Assets.php -B 2 -A 2Repository: weDevsOfficial/wp-user-frontend
Length of output: 4546
🏁 Script executed:
# Continue viewing the rest of get_styles() method to find 'account' and 'elementor-frontend-forms'
rg -n "get_styles" -A 200 includes/Assets.php | grep -E "(account|elementor-frontend-forms|'[a-z-]+'.*=>)"Repository: weDevsOfficial/wp-user-frontend
Length of output: 6327
Missing style handle: wpuf-elementor-frontend-forms is not registered.
The style handle wpuf-elementor-frontend-forms used in line 40 (and referenced in Widget.php:75) is not registered in includes/Assets.php. The available style handles are wpuf-frontend-forms, wpuf-account, and others. This will cause wp_enqueue_style() to fail silently and styles won't load in Elementor context.
Proposed fix
Use the existing wpuf-frontend-forms handle:
- $style_handles = [ 'wpuf-elementor-frontend-forms', 'wpuf-account' ];
+ $style_handles = [ 'wpuf-frontend-forms', 'wpuf-account' ];Also update Widget.php:75 if it references the non-existent handle.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $style_handles = [ 'wpuf-elementor-frontend-forms', 'wpuf-account' ]; | |
| $style_handles = [ 'wpuf-frontend-forms', 'wpuf-account' ]; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@includes/Integrations/Elementor/Elementor.php` at line 40, Update the used
style handle to the registered one: replace occurrences of
'wpuf-elementor-frontend-forms' with the existing registered handle
'wpuf-frontend-forms' (in includes/Integrations/Elementor/Elementor.php where
$style_handles is defined and in Widget.php where the non-existent handle is
referenced, e.g., the enqueue call or any variable referencing that handle) so
wp_enqueue_style() uses a registered style handle and styles load in Elementor
context.
| var wrapper = document.querySelector('.wpuf-elementor-widget-wrapper'); | ||
| if (wrapper) { | ||
| var textareas = wrapper.querySelectorAll('textarea.wp-editor-area'); |
There was a problem hiding this comment.
DOM selector is not scoped to current widget instance.
Using document.querySelector('.wpuf-elementor-widget-wrapper') will only select the first matching element on the page. If multiple WPUF form widgets are added to the same page, the TinyMCE initialization will only target the first widget's textareas, leaving others uninitialized.
Consider scoping the selector to the current widget's wrapper element.
Proposed fix using script element context
- var wrapper = document.querySelector('.wpuf-elementor-widget-wrapper');
+ // Get wrapper relative to this script's position
+ var scripts = document.querySelectorAll('script');
+ var currentScript = scripts[scripts.length - 1];
+ var wrapper = currentScript.previousElementSibling;
+ while (wrapper && !wrapper.classList.contains('wpuf-elementor-widget-wrapper')) {
+ wrapper = wrapper.previousElementSibling;
+ }Alternatively, you could output a unique ID for each widget instance:
// In the render method, before the script:
$unique_id = 'wpuf-widget-' . $this->get_id();
$this->add_render_attribute( 'wrapper', 'id', $unique_id );Then in the JavaScript:
var wrapper = document.getElementById('<?php echo esc_js( $unique_id ); ?>');🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@includes/Integrations/Elementor/Widget.php` around lines 1143 - 1145, The DOM
selector for TinyMCE is not scoped and uses
document.querySelector('.wpuf-elementor-widget-wrapper') which picks only the
first widget; update the widget rendering to output a unique wrapper identifier
(e.g. in the render method set a unique_id like 'wpuf-widget-' + $this->get_id()
via add_render_attribute('wrapper', 'id', $unique_id')) and change the JS that
sets wrapper (the variable named wrapper in the script that currently calls
document.querySelector) to select by that unique id (or scope via the script
element context) so each instance targets its own textarea.wp-editor-area
elements; ensure references include the same unique_id used in render and the
wrapper variable in the JS.
closes #1411
Summary
This PR adds a new Elementor widget for the WPUF Account page, allowing site builders to embed and customize the user account dashboard directly within the Elementor editor.
Technical Notes
Account_Widgetand baseWidgetElementor classes underWeDevs\Wpuf\Integrations\Elementorwith full style controls (typography, colors, spacing, borders).Integrations.phpviaelementor/inithook.wpuf_elementor_styles_to_enqueueallows customizing which styles load in the Elementor context.$recurring_desvalue instead of a hardcoded "/year" string.Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Improvements