-
Notifications
You must be signed in to change notification settings - Fork 152
Add AI settings section #1691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Add AI settings section #1691
Conversation
Introduces a new 'AI Settings' section in the settings options, allowing selection of AI provider, model, and API key. Adds dynamic filtering of AI models in the admin UI based on the selected provider. Removes unnecessary debug console logs from admin posting scripts and makes a minor formatting fix in the frontend render form.
WalkthroughAdds AI configuration UI and backend: new settings (AI Provider, AI Model, API Key), provider/model helper functions and AJAX endpoint, admin JS to filter models by provider, AJAX action registration, many new admin CSS utilities, localization strings, and removal of a few admin debug console logs plus a trivial whitespace tweak. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
assets/js/wpuf-admin.js (2)
239-257: Avoid filtering by provider via display text; add a provider attribute.Relying on option text containing “(OpenAI)/(Anthropic)/...” is brittle (customizations, filters, localization). Prefer a data attribute (e.g., data-provider) or a value prefix to classify options.
Example minimal client-side indexing (no PHP changes), then filter on the indexed attribute:
- // Filter and add relevant options based on provider - aiModelSelect.data('all-options').each(function() { + // Index provider once from trailing "(Provider)" if not already set + if (!aiModelSelect.data('provider-indexed')) { + aiModelSelect.data('all-options').each(function () { + var $opt = $(this); + var m = $opt.text().match(/\(([^)]+)\)\s*$/); + if (m) { $opt.attr('data-provider', m[1].toLowerCase()); } + }); + aiModelSelect.data('provider-indexed', true); + } + // Filter and add relevant options based on provider + aiModelSelect.data('all-options').each(function() { var option = $(this); - var optionText = option.text(); - var optionValue = option.val(); + var optionValue = option.val(); // Skip empty value option if (!optionValue) return; - // Check if option belongs to selected provider - if (selectedProvider === 'openai' && optionText.includes('(OpenAI)')) { - aiModelSelect.append(option.clone()); - } else if (selectedProvider === 'anthropic' && optionText.includes('(Anthropic)')) { - aiModelSelect.append(option.clone()); - } else if (selectedProvider === 'google' && optionText.includes('(Google)')) { - aiModelSelect.append(option.clone()); - } else if (selectedProvider === 'others' && optionText.includes('(Others)')) { - aiModelSelect.append(option.clone()); - } + if (option.attr('data-provider') === selectedProvider) { + aiModelSelect.append(option.clone()); + } });
263-276: Guard defaults and prefer localized placeholder text.
- Ensure the default model exists before selecting; otherwise pick the first real option.
- “Select AI Model” should be localized (use wp_localize_script or wp.i18n).
Apply:
- aiModelSelect.append('<option value="">Select AI Model</option>'); + aiModelSelect.append('<option value="">' + (window.wpuf_admin_i18n?.select_ai_model || 'Select AI Model') + '</option>'); @@ - } else if (defaultModels[selectedProvider]) { - // Fall back to default model for the provider - aiModelSelect.val(defaultModels[selectedProvider]); + } else if (defaultModels[selectedProvider] && aiModelSelect.find('option[value="' + defaultModels[selectedProvider] + '"]').length) { + aiModelSelect.val(defaultModels[selectedProvider]); + } else { + // Fallback: select first available provider-specific model if present + var $first = aiModelSelect.find('option[value!=""]').first(); + if ($first.length) { aiModelSelect.val($first.val()); } }(Expose wpuf_admin_i18n.select_ai_model via wp_localize_script where this file is enqueued.)
includes/functions/settings-options.php (2)
640-707: Use password field for API key and consider stronger storage/handling.Displaying/storing API keys in plain text is risky in shared-admin contexts. Use a password-type field to mask input, and (optionally) avoid echoing the saved value back verbatim.
- [ - 'name' => 'ai_api_key', - 'label' => __( 'API Key', 'wp-user-frontend' ), - 'desc' => __( 'Enter your AI service API key. Keep this secure and never share it publicly.', 'wp-user-frontend' ), - 'type' => 'text', - 'default' => '', - ], + [ + 'name' => 'ai_api_key', + 'label' => __( 'API Key', 'wp-user-frontend' ), + 'desc' => __( 'Enter your AI service API key. Keep this secure and never share it publicly.', 'wp-user-frontend' ), + 'type' => 'password', + 'default' => '', + ],If feasible, add a sanitize callback to trim and store, and render a placeholder (e.g., ••••) when a key exists.
656-704: Facilitate robust provider filtering from JS.Since the admin JS needs to filter models by provider, expose a machine-readable provider key per option (e.g., value prefix
openai:gpt-4oor data-provider attribute rendered by the settings API). This avoids parsing human labels.If altering values is acceptable:
- 'gpt-4o' => 'GPT-4o (OpenAI)', + 'openai:gpt-4o' => 'GPT-4o (OpenAI)',Then update JS to split on
:and match provider reliably.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
assets/js/wpuf-admin.js(1 hunks)includes/Admin/Posting.php(1 hunks)includes/class-frontend-render-form.php(1 hunks)includes/functions/settings-options.php(2 hunks)
🔇 Additional comments (4)
includes/Admin/Posting.php (2)
688-695: Good removal of noisy console log.Swapping the console.log for a comment keeps admin console clean while preserving the initializer guard.
688-695: Confirm gmap “required” fix is actually in the PR.The PR description says it fixes issue #1086 (“gmap required” with multiple maps), but this file only removes a log. Please point to the commit/file that implements the validation fix, or add it to this PR.
includes/functions/settings-options.php (2)
52-56: AI Settings section inclusion looks good.Section id, title, and icon are consistent with existing sections.
656-704: Verify model identifiers and future-proof the list.Some slugs look hypothetical or umbrella (e.g., gpt-5, gpt-4.5, embeddings, tts). Please confirm identifiers you intend to support, and consider sourcing this list via a provider API or filter-only to avoid drift.
Would you like a small adapter that maps providers to models via a filterable registry, so the UI auto-populates from a single source?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix fatal sprintf/escaping misuse and broken selector for counter.
- wp_kses_post() is called with extra args (PHP ArgumentCountError). Also, sprintf args are passed to wp_kses_post instead of sprintf.
- The counter selector in JS looks for
.wpuf-message-box, but the span hasclass="wpuf-items-table-containermessage-box"→ the live counter won’t update.
Apply this diff to fix both issues and harden types:
- <span class="wpuf-items-table-containermessage-box" id="remaining-feature-item"> <?php echo sprintf(
- // translators: %1$s is Post type and %2$s is total feature item
- wp_kses_post(__( 'Mark the %1$s as featured (remaining %2$d)', 'wp-user-frontend' ), esc_html ($this->form_settings['post_type'] ), esc_html( $user_sub['total_feature_item'] ) )); ?></span>
+ <span class="wpuf-message-box" id="remaining-feature-item">
+ <?php
+ // translators: %1$s is Post type and %2$d is total feature item
+ printf(
+ esc_html__( 'Mark the %1$s as featured (remaining %2$d)', 'wp-user-frontend' ),
+ esc_html( $this->form_settings['post_type'] ),
+ absint( $user_sub['total_feature_item'] )
+ );
+ ?>
+ </span>📝 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.
| <input type="checkbox" class="wpuf_is_featured" name="is_featured_item" value="1" <?php echo $is_featured ? 'checked' : ''; ?> > | |
| <span class="wpuf-items-table-containermessage-box" id="remaining-feature-item"> <?php echo sprintf( | |
| <span class="wpuf-items-table-containermessage-box" id="remaining-feature-item"> <?php echo sprintf( | |
| // translators: %1$s is Post type and %2$s is total feature item | |
| wp_kses_post(__( 'Mark the %1$s as featured (remaining %2$d)', 'wp-user-frontend' ), esc_html ($this->form_settings['post_type'] ), esc_html( $user_sub['total_feature_item'] ) )); ?></span> | |
| </label> | |
| <input | |
| type="checkbox" | |
| class="wpuf_is_featured" | |
| name="is_featured_item" | |
| value="1" | |
| <?php echo $is_featured ? 'checked' : ''; ?> | |
| > | |
| <span class="wpuf-message-box" id="remaining-feature-item"> | |
| <?php | |
| // translators: %1$s is Post type and %2$d is total feature item | |
| printf( | |
| esc_html__( 'Mark the %1$s as featured (remaining %2$d)', 'wp-user-frontend' ), | |
| esc_html( $this->form_settings['post_type'] ), | |
| absint( $user_sub['total_feature_item'] ) | |
| ); | |
| ?> | |
| </span> | |
| </label> |
Introduces AJAX-based loading of AI models for selected providers in the admin UI. Adds a new AJAX endpoint for fetching provider configurations, updates the settings options to use dynamic provider/model lists, and enhances the form-builder CSS with new utility classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (5)
wpuf-functions.php (1)
5796-5796: Remove unused variable.The variable
$provider_keyis defined in the foreach loop but never used. Remove it to clean up the code.Apply this diff:
- foreach ( $configs as $provider_key => $config ) { + foreach ( $configs as $config ) { foreach ( $config['models'] as $model_key => $model_name ) {Based on learnings (static analysis hint).
assets/css/admin/form-builder.css (4)
1203-1214: Combine transition declarations to avoid overriding earlier oneSecond transition overrides the first; visibility no longer transitions. Combine into one.
Apply this diff:
.wpuf-collapse-content { - visibility: hidden; - grid-column-start: 1; - grid-row-start: 2; - min-height: 0px; - transition: visibility 0.2s; - transition: padding 0.2s ease-out, - background-color 0.2s ease-out; + visibility: hidden; + grid-column-start: 1; + grid-row-start: 2; + min-height: 0px; + transition: visibility 0.2s, padding 0.2s ease-out, background-color 0.2s ease-out; padding-left: 1rem; padding-right: 1rem; cursor: unset; }
2692-2730: Remove duplicated transition-timing-function/duration linesMultiple identical transition-timing-function and transition-duration declarations bloat CSS without effect.
Apply this diff to keep a single set per block:
.wpuf-collapse-arrow > .wpuf-collapse-title:after { - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); position: absolute; display: block; height: 0.5rem; width: 0.5rem; --tw-translate-y: -100%; --tw-rotate: 45deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); - transition-property: all; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); - transition-duration: 150ms; - transition-duration: 0.2s; + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 0.2s; top: 1.9rem; inset-inline-end: 1.4rem; content: ""; transform-origin: 75% 75%; box-shadow: 2px 2px; pointer-events: none; } .wpuf-collapse-plus > .wpuf-collapse-title:after { - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); position: absolute; display: block; height: 0.5rem; width: 0.5rem; - transition-property: all; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); - transition-duration: 300ms; + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 300ms; top: 0.9rem; inset-inline-end: 1.4rem; content: "+"; pointer-events: none; }
1331-1416: Excessively duplicated .wpuf-btn:hover blocks inflate CSSSame hover rule appears multiple times. Prefer dedupe at build time (e.g., cssnano mergeRules or Tailwind/DaisyUI config to avoid re-emission).
7071-7109: Use theme tokens instead of hardcoded “green” for range inputsAlign with the design system and ensure contrast/dark-mode consistency.
Apply this diff:
input[type="range"] { -webkit-appearance: none; width: 100%; height: 5px; - background: green; + background-color: var(--fallback-su, oklch(var(--su)/1)); outline: none; transition: background 0.3s; border-radius: 10px } input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; - background: green; + background-color: var(--fallback-su, oklch(var(--su)/1)); cursor: pointer; border-radius: 10px; } input[type="range"]::-moz-range-thumb { width: 20px; height: 20px; - background: green; + background-color: var(--fallback-su, oklch(var(--su)/1)); cursor: pointer; border-radius: 10px; } input[type="range"]:hover, input[type="range"]:active { - background: green; + background-color: var(--fallback-su, oklch(var(--su)/1)); } input[type="range"]::-webkit-slider-thumb:hover, input[type="range"]::-webkit-slider-thumb:active, input[type="range"]::-moz-range-thumb:hover, input[type="range"]::-moz-range-thumb:active { - background: green; + background-color: var(--fallback-su, oklch(var(--su)/1)); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
assets/css/admin/form-builder.css(67 hunks)assets/js/wpuf-admin.js(1 hunks)includes/Admin/Posting.php(1 hunks)includes/Ajax.php(1 hunks)includes/functions/settings-options.php(2 hunks)languages/wp-user-frontend.pot(27 hunks)wpuf-functions.php(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- includes/Admin/Posting.php
- assets/js/wpuf-admin.js
🧰 Additional context used
🧬 Code graph analysis (1)
includes/functions/settings-options.php (1)
wpuf-functions.php (2)
wpuf_get_ai_provider_options(5776-5785)wpuf_get_ai_model_options(5793-5803)
🪛 Biome (2.1.2)
assets/css/admin/form-builder.css
[error] 1077-1077: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
width is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
[error] 1209-1209: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
[error] 1234-1234: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
min-height is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
[error] 2694-2694: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition-timing-function is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
[error] 2717-2717: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition-timing-function is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
🪛 PHPMD (2.15.0)
wpuf-functions.php
5796-5796: Avoid unused local variables such as '$provider_key'. (undefined)
(UnusedLocalVariable)
🔇 Additional comments (5)
assets/css/admin/form-builder.css (5)
822-879: Namespaced form control styles look goodConsistent with base input styling and scoped under wpuf-*. No issues.
1056-1167: Chat UI utility block is coherentSemantic grid rows, bubble tail masks, and RTL variants are well-structured. No issues.
1222-1235: Verify :has() usage against supported browsersCollapse open state relies on :has(). Confirm this aligns with the plugin’s browser support baseline for WP admin.
4989-5007: Custom keyframes and animation utilities are fineScoped, simple, and consistent with Tailwind patterns.
Also applies to: 5005-5007
5611-5668: Color utility additions align with paletteEmerald/blue/purple variants consistent with existing tokens.
Also applies to: 5660-5673
| .wpuf-collapse { | ||
| visibility: collapse; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove visibility: collapse on .wpuf-collapse (can hide panels unexpectedly)
This conflicts with earlier visibility management and may cause collapses to be invisible depending on specificity/cascade. Remove it.
Apply this diff:
-.wpuf-collapse {
- visibility: collapse;
-}📝 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.
| .wpuf-collapse { | |
| visibility: collapse; | |
| } |
🤖 Prompt for AI Agents
In assets/css/admin/form-builder.css around lines 3899 to 3901, the
.wpuf-collapse rule sets "visibility: collapse" which can unintentionally hide
panels due to cascade/specificity; remove the "visibility: collapse" declaration
from that selector (delete the property line) so visibility is controlled only
by the earlier/intentional rules; if a hidden state is still needed, use a more
specific class or explicit display/visibility rule in the component-specific
stylesheet instead of this global collapse rule.
|
|
||
| /** | ||
| * Get AI provider configurations | ||
| * | ||
| * @since WPUF_SINCE | ||
| * | ||
| * @return array | ||
| */ | ||
| function wpuf_get_ai_provider_configs() { | ||
| $provider_configs = [ | ||
| 'openai' => [ | ||
| 'name' => 'OpenAI', | ||
| 'endpoint' => 'https://api.openai.com/v1/chat/completions', | ||
| 'models' => [ | ||
| 'gpt-4o' => 'GPT-4o - Most Capable Multimodal', | ||
| 'gpt-4o-mini' => 'GPT-4o Mini - Efficient & Fast', | ||
| 'gpt-4-turbo' => 'GPT-4 Turbo - High Performance', | ||
| 'gpt-4' => 'GPT-4 - Advanced Reasoning', | ||
| 'gpt-3.5-turbo' => 'GPT-3.5 Turbo - Fast & Affordable', | ||
| ], | ||
| 'requires_key' => true, | ||
| ], | ||
| 'anthropic' => [ | ||
| 'name' => 'Anthropic Claude', | ||
| 'endpoint' => 'https://api.anthropic.com/v1/messages', | ||
| 'models' => [ | ||
| 'claude-4.1-opus' => 'Claude 4.1 Opus - Most Capable', | ||
| 'claude-4-opus' => 'Claude 4 Opus - Best Coding Model', | ||
| 'claude-4-sonnet' => 'Claude 4 Sonnet - Advanced Reasoning', | ||
| 'claude-3.7-sonnet' => 'Claude 3.7 Sonnet - Hybrid Reasoning', | ||
| 'claude-3-5-sonnet-20241022' => 'Claude 3.5 Sonnet Latest', | ||
| 'claude-3-5-sonnet-20240620' => 'Claude 3.5 Sonnet', | ||
| 'claude-3-5-haiku-20241022' => 'Claude 3.5 Haiku', | ||
| 'claude-3-opus-20240229' => 'Claude 3 Opus', | ||
| 'claude-3-sonnet-20240229' => 'Claude 3 Sonnet', | ||
| 'claude-3-haiku-20240307' => 'Claude 3 Haiku', | ||
| ], | ||
| 'requires_key' => true, | ||
| ], | ||
| 'google' => [ | ||
| 'name' => 'Google Gemini', | ||
| 'endpoint' => 'https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent', | ||
| 'models' => [ | ||
| 'gemini-2.0-flash-exp' => 'Gemini 2.0 Flash Experimental - Latest', | ||
| 'gemini-2.0-flash' => 'Gemini 2.0 Flash - Stable', | ||
| 'gemini-2.0-flash-001' => 'Gemini 2.0 Flash 001 - Stable Version', | ||
| 'gemini-2.0-flash-lite-001' => 'Gemini 2.0 Flash-Lite 001 - Lightweight', | ||
| 'gemini-2.0-flash-lite' => 'Gemini 2.0 Flash-Lite - Lightweight', | ||
| 'gemini-2.5-flash' => 'Gemini 2.5 Flash - Latest Stable', | ||
| 'gemini-2.5-pro' => 'Gemini 2.5 Pro - Most Capable', | ||
| 'gemini-2.5-flash-lite' => 'Gemini 2.5 Flash-Lite - Efficient', | ||
| 'gemini-flash-latest' => 'Gemini Flash Latest - Auto-Updated', | ||
| 'gemini-pro-latest' => 'Gemini Pro Latest - Auto-Updated', | ||
| ], | ||
| 'requires_key' => true, | ||
| ], | ||
| ]; | ||
| return apply_filters( 'wpuf_ai_provider_configs', $provider_configs ); | ||
| } | ||
|
|
||
| /** | ||
| * Get AI provider options for settings | ||
| * | ||
| * @since WPUF_SINCE | ||
| * | ||
| * @return array | ||
| */ | ||
| function wpuf_get_ai_provider_options() { | ||
| $configs = wpuf_get_ai_provider_configs(); | ||
| $options = []; | ||
|
|
||
| foreach ( $configs as $key => $config ) { | ||
| $options[ $key ] = $config['name']; | ||
| } | ||
|
|
||
| return $options; | ||
| } | ||
|
|
||
| /** | ||
| * Get AI model options for settings | ||
| * | ||
| * @since WPUF_SINCE | ||
| * @return array | ||
| */ | ||
| function wpuf_get_ai_model_options() { | ||
| $configs = wpuf_get_ai_provider_configs(); | ||
| $all_models = []; | ||
| foreach ( $configs as $provider_key => $config ) { | ||
| foreach ( $config['models'] as $model_key => $model_name ) { | ||
| $all_models[ $model_key ] = $model_name; | ||
| } | ||
| } | ||
|
|
||
| return apply_filters( 'wpuf_ai_model_options', $all_models ); | ||
| } | ||
|
|
||
| /** | ||
| * AJAX handler to get AI provider configurations | ||
| * | ||
| * @since WPUF_SINCE | ||
| */ | ||
| function wpuf_get_ai_provider_configs_ajax() { | ||
| // Verify nonce for security | ||
| if ( ! wp_verify_nonce( $_POST['nonce'] ?? '', 'wpuf_nonce' ) ) { | ||
| wp_send_json_error( 'Invalid nonce' ); | ||
| } | ||
| // Check user capabilities | ||
| if ( ! current_user_can( 'manage_options' ) ) { | ||
| wp_send_json_error( 'Insufficient permissions' ); | ||
| } | ||
| // Get AI provider configurations | ||
| $configs = wpuf_get_ai_provider_configs(); | ||
| wp_send_json_success( $configs ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
** PR objectives mention unrelated issue #1086.**
The PR objectives state "Fixes issue #1086" which concerns Google Maps required validation on forms with multiple map fields. However, all code changes in this file relate to AI Settings functionality (provider configuration, model selection, AJAX handlers). This is a significant discrepancy that should be clarified.
Please verify:
- Is this PR intended to address issue gmap required doesnt work when multiple maps are on same form #1086, or should the PR description be updated?
- Are there additional files in this PR that address the Google Maps validation issue?
🧰 Tools
🪛 PHPMD (2.15.0)
5796-5796: Avoid unused local variables such as '$provider_key'. (undefined)
(UnusedLocalVariable)
🤖 Prompt for AI Agents
In wpuf-functions.php around lines 5709 to 5822 the PR description references
"Fixes issue #1086" (Google Maps validation) but the changes in this file are
only AI settings (provider/model configs and AJAX handler); update the PR so it
accurately reflects what is changed: either remove/replace the issue reference
with the correct issue (or no issue) or add the missing files/commits that
implement the Google Maps validation fix; if the Google Maps fix exists
elsewhere in the branch, list those files/commits in the PR description and
ensure they are included in this PR, otherwise open a separate issue/PR for
#1086 and remove the incorrect fix reference here.
| function wpuf_get_ai_provider_configs_ajax() { | ||
| // Verify nonce for security | ||
| if ( ! wp_verify_nonce( $_POST['nonce'] ?? '', 'wpuf_nonce' ) ) { | ||
| wp_send_json_error( 'Invalid nonce' ); | ||
| } | ||
| // Check user capabilities | ||
| if ( ! current_user_can( 'manage_options' ) ) { | ||
| wp_send_json_error( 'Insufficient permissions' ); | ||
| } | ||
| // Get AI provider configurations | ||
| $configs = wpuf_get_ai_provider_configs(); | ||
| wp_send_json_success( $configs ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify AJAX action registration and nonce action name.
Please confirm:
- Is the AJAX action
wpuf_get_ai_provider_configsproperly registered inincludes/Ajax.phpor another file? - Is
'wpuf_nonce'the correct nonce action for this endpoint? Typically, nonce actions are more specific (e.g.,'wpuf_get_ai_provider_configs').
Run this script to verify the AJAX registration:
🏁 Script executed:
#!/bin/bash
# Search for AJAX action registration
echo "Searching for AJAX action registration..."
rg -n "add_action.*wpuf_get_ai_provider_configs" --type=php
echo -e "\nSearching for nonce generation with 'wpuf_nonce'..."
rg -n "wp_create_nonce.*wpuf_nonce" --type=php -A2 -B2Length of output: 5955
Please verify the AJAX registration with:
🏁 Script executed:
#!/bin/bash
echo "Searching for AJAX action handlers for wpuf_get_ai_provider_configs..."
rg -n "add_action\\(\s*['\"]wp_ajax(_nopriv)?_wpuf_get_ai_provider_configs['\"]" --type=phpLength of output: 70
Register the AJAX handler & tighten the nonce
No add_action('wp_ajax[_nopriv]_wpuf_get_ai_provider_configs', …) exists—add:
add_action('wp_ajax_wpuf_get_ai_provider_configs', 'wpuf_get_ai_provider_configs_ajax');
add_action('wp_ajax_nopriv_wpuf_get_ai_provider_configs', 'wpuf_get_ai_provider_configs_ajax');And replace the generic 'wpuf_nonce' with a specific action (e.g. 'wpuf_get_ai_provider_configs') in both wp_create_nonce() and wp_verify_nonce().
🤖 Prompt for AI Agents
In wpuf-functions.php around lines 5810 to 5822, the AJAX handler is not
registered and the nonce action is too generic; register the handler by adding
both add_action('wp_ajax_wpuf_get_ai_provider_configs',
'wpuf_get_ai_provider_configs_ajax') and
add_action('wp_ajax_nopriv_wpuf_get_ai_provider_configs',
'wpuf_get_ai_provider_configs_ajax') (place these in the plugin’s initialization
area or where other AJAX actions are registered), and tighten nonce usage by
replacing the generic 'wpuf_nonce' with a specific action name such as
'wpuf_get_ai_provider_configs' in both the wp_create_nonce() call that generates
the nonce and the wp_verify_nonce() call that verifies it in this function.
Add request method check and internationalize error messages.
The AJAX handler should verify it's handling a POST request, and error messages should be translatable for internationalization.
Apply this diff:
function wpuf_get_ai_provider_configs_ajax() {
+ // Verify this is a POST request
+ if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
+ wp_send_json_error( __( 'Invalid request method', 'wp-user-frontend' ) );
+ }
+
// Verify nonce for security
- if ( ! wp_verify_nonce( $_POST['nonce'] ?? '', 'wpuf_nonce' ) ) {
- wp_send_json_error( 'Invalid nonce' );
+ $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
+ if ( ! wp_verify_nonce( $nonce, 'wpuf_nonce' ) ) {
+ wp_send_json_error( __( 'Invalid nonce', 'wp-user-frontend' ) );
}
// Check user capabilities
if ( ! current_user_can( 'manage_options' ) ) {
- wp_send_json_error( 'Insufficient permissions' );
+ wp_send_json_error( __( 'Insufficient permissions', 'wp-user-frontend' ) );
}📝 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.
| function wpuf_get_ai_provider_configs_ajax() { | |
| // Verify nonce for security | |
| if ( ! wp_verify_nonce( $_POST['nonce'] ?? '', 'wpuf_nonce' ) ) { | |
| wp_send_json_error( 'Invalid nonce' ); | |
| } | |
| // Check user capabilities | |
| if ( ! current_user_can( 'manage_options' ) ) { | |
| wp_send_json_error( 'Insufficient permissions' ); | |
| } | |
| // Get AI provider configurations | |
| $configs = wpuf_get_ai_provider_configs(); | |
| wp_send_json_success( $configs ); | |
| } | |
| function wpuf_get_ai_provider_configs_ajax() { | |
| // Verify this is a POST request | |
| if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { | |
| wp_send_json_error( __( 'Invalid request method', 'wp-user-frontend' ) ); | |
| } | |
| // Verify nonce for security | |
| $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; | |
| if ( ! wp_verify_nonce( $nonce, 'wpuf_nonce' ) ) { | |
| wp_send_json_error( __( 'Invalid nonce', 'wp-user-frontend' ) ); | |
| } | |
| // Check user capabilities | |
| if ( ! current_user_can( 'manage_options' ) ) { | |
| wp_send_json_error( __( 'Insufficient permissions', 'wp-user-frontend' ) ); | |
| } | |
| // Get AI provider configurations | |
| $configs = wpuf_get_ai_provider_configs(); | |
| wp_send_json_success( $configs ); | |
| } |
| if ( ! wp_verify_nonce( $_POST['nonce'] ?? '', 'wpuf_nonce' ) ) { | ||
| wp_send_json_error( 'Invalid nonce' ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sanitize nonce before verification.
The nonce value from $_POST['nonce'] is used directly in wp_verify_nonce() without sanitization. While wp_verify_nonce() is generally safe, it's a WordPress best practice to sanitize all user input before use.
Apply this diff:
- if ( ! wp_verify_nonce( $_POST['nonce'] ?? '', 'wpuf_nonce' ) ) {
+ $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
+ if ( ! wp_verify_nonce( $nonce, 'wpuf_nonce' ) ) {
wp_send_json_error( 'Invalid nonce' );
}🤖 Prompt for AI Agents
In wpuf-functions.php around lines 5812 to 5814, the POSTed nonce is passed
directly to wp_verify_nonce; sanitize it first (e.g. read $_POST['nonce'] into a
variable and run sanitize_text_field or equivalent on it, defaulting to an empty
string if not set), then pass the sanitized value to wp_verify_nonce and keep
the existing wp_send_json_error for failures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
languages/wp-user-frontend.pot (1)
2900-2902: Fix confirmed typos and grammar issues in source files, then regenerate POT.All mentioned issues have been verified as present in the codebase:
- Spelling errors: "Registraton", "email adress", "Chose", "Minimun", "Twillo" (×3), "neccessery", "Subcription" (×2)
- Grammar errors: "has been" → "have been" (3 instances), "Could not deleted"
- Phrasing issues: "get the these key", "Go to Setting", "Please add some more character"
- Formatting: trailing spaces in "Address Line 1 " and "Address Line 2 ", extra space before "?" in "subscription ?"
The POT file at
languages/wp-user-frontend.potcontains these errors. Correct all instances in their source files, then regenerate the POT file.
♻️ Duplicate comments (2)
wpuf-functions.php (1)
5810-5822: Previously identified security and i18n issues remain unaddressed.The issues flagged in previous reviews for this AJAX handler have not been resolved:
⚠️ Critical: AJAX action registration is still missing (noadd_actionforwp_ajax_wpuf_get_ai_provider_configs)⚠️ Critical: Nonce is not sanitized before verification (line 5812)⚠️ Major: No POST request method verification⚠️ Major: Error messages are not internationalized (lines 5813, 5817)⚠️ Major: Generic nonce action name 'wpuf_nonce' should be more specificPlease refer to the detailed fixes already provided in the previous review comments.
assets/css/admin/form-builder.css (1)
2838-2840: [DUPLICATE] Removevisibility: collapsefrom.wpuf-collapse(critical visibility regression).This is the same issue flagged in the prior review. The
visibility: collapseproperty at lines 2838-2840 directly conflicts with line 1111 which setsvisibility: visibleon the same selector, and can cause panels/collapses to become invisible due to CSS cascade. Remove thevisibility: collapsedeclaration entirely.-.wpuf-collapse { - visibility: collapse; -}
🧹 Nitpick comments (7)
languages/wp-user-frontend.pot (6)
1972-2079: New AI strings read clearly; add brief translator context where helpful.The AI errors/status (“Rate limit exceeded…”, “Form created successfully”, “Test Connection”, etc.) look good. Consider adding short translator notes (meaning/where shown) for “Test Connection”, “Update Form” button labels to reduce ambiguity across locales. Then regenerate the POT.
85-99: Add translator comments for curly‑brace placeholders to avoid breakage.Strings contain placeholders like {login}, {register}, {link}, {sitename}, {siteurl}, {post_title}, etc., but no “translators:” notes. Add comments such as “translators: keep {login} and {register} placeholders unchanged” so locales don’t alter tokens, then regenerate the POT.
Also applies to: 111-120, 126-137
36-37: Normalize “Select” placeholder styling for consistency.Three variants exist: “- Select -”, “— Select —”, and “— Select —”. Pick one style (WP commonly uses an em dash “— Select —”) and standardize across templates, then rebuild the POT.
Also applies to: 552-556, 2312-2315
69-71: Unify postal label terminology.You’re using “Zip Code”, “Postal Code/ZIP”, and “Postal/ZIP Code”. Choose one convention and reuse it (recommend “Postal/ZIP Code” in UI; “ZIP Code” for US‑specific contexts).
Also applies to: 2784-2789, 8362-8364
547-551: Standardize reCAPTCHA capitalization.Strings mix “reCaptcha”, “Recaptcha”, and “reCAPTCHA”. Consider normalizing to Google’s “reCAPTCHA” brand while keeping existing keys/IDs intact.
Also applies to: 1768-1775, 5155-5166
569-574: Disambiguate common single‑word labels with contexts.Labels like “Preview”, “Cancel”, “Update”, “Okay”, and “Select” appear in multiple contexts (button vs. field type). Where feasible, use
_x()with a context (e.g.,_x( 'Select', 'field type', 'textdomain' )) to help translators choose accurate terms.Also applies to: 626-635, 799-801, 2929-2931, 2967-2971
wpuf-functions.php (1)
5793-5803: Remove unused loop variable.The
$provider_keyvariable on line 5796 is not used within the loop body. Consider using an underscore to indicate it's intentionally unused.Apply this diff:
- foreach ( $configs as $provider_key => $config ) { + foreach ( $configs as $config ) { foreach ( $config['models'] as $model_key => $model_name ) { $all_models[ $model_key ] = $model_name; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
assets/css/admin/form-builder.css(70 hunks)languages/wp-user-frontend.pot(20 hunks)wpuf-functions.php(1 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
assets/css/admin/form-builder.css
[error] 1014-1014: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
width is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
[error] 1146-1146: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
[error] 1171-1171: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
min-height is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
[error] 1931-1931: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition-timing-function is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
[error] 1954-1954: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition-timing-function is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
🪛 PHPMD (2.15.0)
wpuf-functions.php
5796-5796: Avoid unused local variables such as '$provider_key'. (undefined)
(UnusedLocalVariable)
🔇 Additional comments (5)
wpuf-functions.php (2)
5717-5767: LGTM! Well-structured provider configuration function.The provider configuration is well-organized with appropriate model options for each AI provider and includes a filter hook for extensibility.
5776-5785: LGTM! Clean helper function.The function correctly extracts provider options for use in settings dropdowns.
assets/css/admin/form-builder.css (3)
822-879: New form input utility classes with solid foundation.The addition of
.wpuf-form-input,.wpuf-form-textarea,.wpuf-form-select, and.wpuf-form-multiselectclasses (lines 822–879) provides consistent form styling across components. The focus states, placeholder styling, and datetime field handling are well-structured. This aligns well with the AI settings form fields introduced in this PR.
993-1109: Chat UI classes provide comprehensive layout and RTL support.The
.wpuf-chat-*component classes (lines 993–1109) with grid-based layout, bubble styling, directional variants (.wpuf-chat-start,.wpuf-chat-end), and RTL mask-image handling ([dir="rtl"]selectors) are well-engineered for potential AI assistant messaging UI. Bubble arrow positioning and CSS masks are semantic.
862-878: Review comment is incorrect—nowidthproperty exists in the specified lines.The actual code at lines 862–878 contains only
padding,min-height,text-align, anddisplayproperties. Nowidthdeclaration is present, so there is no duplicate property to remove. Biome could not have flagged awidthproperty that does not exist in this code section.Likely an incorrect or invalid review comment.
| transition: visibility 0.2s; | ||
| transition: padding 0.2s ease-out, | ||
| background-color 0.2s ease-out; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate transition property in .wpuf-collapse-content (line ~1146).
Biome detects that transition is defined twice in this rule block. The second definition at line 1146 will override the first, leading to unintended behavior. Consolidate into a single transition declaration covering all properties.
🧰 Tools
🪛 Biome (2.1.2)
[error] 1146-1146: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
🤖 Prompt for AI Agents
In assets/css/admin/form-builder.css around lines 1145 to 1147, the
.wpuf-collapse-content rule declares transition twice causing the first to be
overridden; consolidate into a single transition declaration that lists all
properties and timings (e.g., visibility, padding, background-color) so all
intended transitions apply consistently.
| visibility: visible; | ||
| min-height: -moz-fit-content; | ||
| min-height: fit-content; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate min-height property in .wpuf-collapse[open]... selectors (line ~1171).
Biome detects duplicate min-height in the combined selector. Ensure only one min-height: fit-content declaration per selector to avoid override confusion.
🧰 Tools
🪛 Biome (2.1.2)
[error] 1171-1171: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
min-height is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
🤖 Prompt for AI Agents
In assets/css/admin/form-builder.css around lines 1169 to 1172, the combined
selector contains duplicate min-height declarations; remove the redundant one so
only a single min-height declaration remains (if you need vendor fallback keep
the -moz-fit-content line followed by a single min-height: fit-content) to avoid
override confusion.
| .wpuf-collapse-arrow > .wpuf-collapse-title:after { | ||
| transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | ||
| transition-timing-function: cubic-bezier(0, 0, 0.2, 1); | ||
| position: absolute; | ||
| display: block; | ||
| height: 0.5rem; | ||
| width: 0.5rem; | ||
| --tw-translate-y: -100%; | ||
| --tw-rotate: 45deg; | ||
| transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | ||
| transition-property: all; | ||
| transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | ||
| transition-timing-function: cubic-bezier(0, 0, 0.2, 1); | ||
| transition-duration: 150ms; | ||
| transition-duration: 0.2s; | ||
| top: 1.9rem; | ||
| inset-inline-end: 1.4rem; | ||
| content: ""; | ||
| transform-origin: 75% 75%; | ||
| box-shadow: 2px 2px; | ||
| pointer-events: none; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate transition-timing-function in .wpuf-collapse-arrow > .wpuf-collapse-title:after (line ~1931).
Lines 1930–1931 and 1940–1941 both define transition-timing-function: cubic-bezier(0, 0, 0.2, 1); Consolidate to a single declaration to avoid redundancy and potential cascade issues.
🧰 Tools
🪛 Biome (2.1.2)
[error] 1931-1931: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition-timing-function is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
🤖 Prompt for AI Agents
In assets/css/admin/form-builder.css around lines 1929 to 1950, there are
duplicate transition-timing-function declarations in .wpuf-collapse-arrow >
.wpuf-collapse-title:after; remove the redundant lines and keep a single
transition-timing-function (pick the intended cubic-bezier value) so the rule
has only one timing-function declaration and no conflicting duplicates.
| .wpuf-collapse-plus > .wpuf-collapse-title:after { | ||
| transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | ||
| transition-timing-function: cubic-bezier(0, 0, 0.2, 1); | ||
| position: absolute; | ||
| display: block; | ||
| height: 0.5rem; | ||
| width: 0.5rem; | ||
| transition-property: all; | ||
| transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | ||
| transition-timing-function: cubic-bezier(0, 0, 0.2, 1); | ||
| transition-duration: 300ms; | ||
| top: 0.9rem; | ||
| inset-inline-end: 1.4rem; | ||
| content: "+"; | ||
| pointer-events: none; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate transition-timing-function in .wpuf-collapse-plus > .wpuf-collapse-title:after (line ~1954).
Lines 1953–1954 and 1960–1961 both define transition-timing-function. Consolidate to avoid redundancy and clarify intent.
🧰 Tools
🪛 Biome (2.1.2)
[error] 1954-1954: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.
transition-timing-function is already defined here.
Remove or rename the duplicate property to ensure consistent styling.
(lint/suspicious/noDuplicateProperties)
🤖 Prompt for AI Agents
In assets/css/admin/form-builder.css around lines 1952 to 1967, the
.wpuf-collapse-plus > .wpuf-collapse-title:after block declares
transition-timing-function twice in two places (lines ~1953–1954 and
~1960–1961); remove the duplicate entries and keep a single
transition-timing-function with the intended cubic-bezier value (place it
alongside transition-property/transition-duration for clarity), so there is only
one timing-function declaration in that rule.
| .lg\:wpuf-p-9 { | ||
| padding: 2.25rem; | ||
| .lg\:wpuf-grid-cols-3 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Syntax error: missing closing brace before .lg\:wpuf-grid-cols-3 (line 7193).
Line 7191 declares .lg\:wpuf-p-9 but line 7192 is incomplete (ends with just }) and line 7193 begins a new rule without proper preceding brace closure. Add the missing closing brace and newline.
.lg\:wpuf-p-9 {
padding: 2.25rem;
+ }
.lg\:wpuf-grid-cols-3 {
grid-template-columns: repeat(3, minmax(0, 1fr));
}📝 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.
| .lg\:wpuf-p-9 { | |
| padding: 2.25rem; | |
| .lg\:wpuf-grid-cols-3 { | |
| .lg\:wpuf-p-9 { | |
| padding: 2.25rem; | |
| } | |
| .lg\:wpuf-grid-cols-3 { |
🤖 Prompt for AI Agents
In assets/css/admin/form-builder.css around lines 7191 to 7193, the
.lg\:wpuf-p-9 rule is missing its closing brace which causes the following
.lg\:wpuf-grid-cols-3 selector to be merged incorrectly; add a closing brace (})
and a newline immediately after the .lg\:wpuf-p-9 block so the
.lg\:wpuf-grid-cols-3 rule starts on its own line, preserving proper indentation
and CSS syntax.
fixes #1086
Introduces a new 'AI Settings' section in the settings options, allowing selection of AI provider, model, and API key. Adds dynamic filtering of AI models in the admin UI based on the selected provider. Removes unnecessary debug console logs from admin posting scripts and makes a minor formatting fix in the frontend render form.
Summary by CodeRabbit
New Features
Chores
Style
Documentation