Skip to content
Open
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
61 changes: 61 additions & 0 deletions assets/js/wpuf-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,65 @@ jQuery(function($) {
$('.wpuf-fields input[type="radio"][name="_downloadable"][value="no"]').prop('checked', true);
}
});

// AI Provider change event listener to filter AI Models
$('#wpuf_ai\\[ai_provider\\]').on('change', function() {
var selectedProvider = $(this).val();
var aiModelSelect = $('#wpuf_ai\\[ai_model\\]');
var allOptions = aiModelSelect.find('option').clone();

// Store all options for restoration if needed
if (!aiModelSelect.data('all-options')) {
aiModelSelect.data('all-options', allOptions);
}

// Clear current options
aiModelSelect.empty();

// Add default option
aiModelSelect.append('<option value="">Select AI Model</option>');

// 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();

// 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());
}
});

// Check if there's a pre-selected value from database
var currentDbValue = aiModelSelect.attr('data-current-value') || aiModelSelect.val();

// Set default model for the selected provider
var defaultModels = {
'openai': 'gpt-3.5-turbo',
'anthropic': 'claude-3-haiku',
'google': 'gemini-pro',
'others': 'llama'
};

// First try to keep the current DB value if it's valid for the selected provider
if (currentDbValue && aiModelSelect.find('option[value="' + currentDbValue + '"]').length > 0) {
aiModelSelect.val(currentDbValue);
} else if (defaultModels[selectedProvider]) {
// Fall back to default model for the provider
aiModelSelect.val(defaultModels[selectedProvider]);
}
});

// Trigger change event on page load to filter models based on pre-selected provider
$('#wpuf_ai\\[ai_provider\\]').trigger('change');
});
7 changes: 1 addition & 6 deletions includes/Admin/Posting.php
Original file line number Diff line number Diff line change
Expand Up @@ -460,10 +460,6 @@ public function render_form( $form_id, $post_id = null ) {
if ( typeof wpuf_map_items === 'undefined' ) {
wpuf_map_items = [];
}

// Test if field initialization script is loaded
console.log('Admin metabox script loaded');
console.log('WPUF_Field_Initializer available:', typeof WPUF_Field_Initializer !== 'undefined');
</script>

<?php
Expand Down Expand Up @@ -691,10 +687,9 @@ public function scripts_styles() {
// Initialize fields after the form is rendered with a delay to ensure DOM is ready
setTimeout(function() {
if (typeof WPUF_Field_Initializer !== 'undefined') {
console.log('Calling WPUF_Field_Initializer.init() from admin metabox');
WPUF_Field_Initializer.init();
} else {
console.log('WPUF_Field_Initializer is not defined');
// console.log('WPUF_Field_Initializer is not defined');
}
}, 500);
});
Expand Down
2 changes: 1 addition & 1 deletion includes/class-frontend-render-form.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

class WPUF_Frontend_Render_Form {
private static $_instance;

Check warning on line 4 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Property name "$_instance" should not be prefixed with an underscore to indicate visibility

public static $meta_key = 'wpuf_form';

Expand Down Expand Up @@ -46,11 +46,11 @@
*
* @return array
*/
public function search( $array, $key, $value ) {

Check warning on line 49 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

It is recommended not to use reserved keyword "array" as function parameter name. Found: $array
$results = [];

if ( is_array( $array ) ) {
if ( isset( $array[ $key ] ) && $array[ $key ] == $value ) {

Check warning on line 53 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "==="; Found: "=="
$results[] = $array;
}

Expand Down Expand Up @@ -90,7 +90,7 @@
}

/**
* reCaptcha Validation

Check failure on line 93 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Doc comment short description must start with a capital letter
*
* @return void
*/
Expand All @@ -104,15 +104,15 @@
$remote_addr = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
$g_recaptcha_response = isset( $_POST['g-recaptcha-response'] ) ? sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ) : '';

if ( $no_captcha == 1 && 0 == $invisible ) {

Check warning on line 107 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "==="; Found: "=="

Check warning on line 107 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "==="; Found: "=="
if ( ! class_exists( 'WPUF_ReCaptcha' ) ) {
require_once WPUF_ROOT . '/lib/recaptchalib_noCaptcha.php';
}

$response = null;
$reCaptcha = new WPUF_ReCaptcha( $private_key );

Check failure on line 113 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Variable "$reCaptcha" is not in valid snake_case format, try "$re_captcha"

$resp = $reCaptcha->verifyResponse(

Check failure on line 115 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Variable "$reCaptcha" is not in valid snake_case format, try "$re_captcha"
$remote_addr,
$g_recaptcha_response
);
Expand All @@ -120,7 +120,7 @@
if ( ! $resp->success ) {
$this->send_error( __( 'noCaptcha reCAPTCHA validation failed', 'wp-user-frontend' ) );
}
} elseif ( $no_captcha == 0 && 0 == $invisible ) {

Check warning on line 123 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "==="; Found: "=="

Check warning on line 123 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "==="; Found: "=="
$recap_challenge = isset( $_POST['recaptcha_challenge_field'] ) ? sanitize_text_field( wp_unslash( $_POST['recaptcha_challenge_field'] ) ) : '';
$recap_response = isset( $_POST['recaptcha_response_field'] ) ? sanitize_text_field( wp_unslash( $_POST['recaptcha_response_field'] ) ) : '';

Expand All @@ -129,27 +129,27 @@
if ( ! $resp->is_valid ) {
$this->send_error( __( 'reCAPTCHA validation failed', 'wp-user-frontend' ) );
}
} elseif ( $no_captcha == 0 && 1 == $invisible ) {

Check warning on line 132 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "==="; Found: "=="

Check warning on line 132 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "==="; Found: "=="
$response = null;
$recaptcha = isset( $_POST['g-recaptcha-response'] ) ? sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ) : '';
$object = new Invisible_Recaptcha( $site_key, $private_key );

$response = $object->verifyResponse( $recaptcha );

if ( isset( $response['success'] ) and $response['success'] != true ) {

Check warning on line 139 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "!=="; Found: "!="

Check failure on line 139 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Logical operator "and" is prohibited; use "&&" instead
$this->send_error( __( 'Invisible reCAPTCHA validation failed', 'wp-user-frontend' ) );
}
}
}

/**
* render submit button

Check failure on line 146 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Doc comment short description must start with a capital letter
*
* @param [type] $form_id [description]
* @param [type] $form_settings [description]
* @param [type] $post_id [description]
*/
public function submit_button( $form_id, $form_settings, $post_id = null ) { ?>

Check failure on line 152 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Opening brace must be the last content on the line

<li class="wpuf-submit">
<div class="wpuf-label">
Expand Down Expand Up @@ -188,7 +188,7 @@
}

/**
* guest post field

Check failure on line 191 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Doc comment short description must start with a capital letter
*
* @param [type] $form_settings [description]
*/
Expand Down Expand Up @@ -275,7 +275,7 @@
}

/**
* render form

Check failure on line 278 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Doc comment short description must start with a capital letter
*
* @param [type] $form_id [description]
* @param [type] $post_id [description]
Expand Down Expand Up @@ -401,7 +401,7 @@
}

/**
* add post field setting on form builder

Check failure on line 404 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Doc comment short description must start with a capital letter
*
* @param array $field_settings
*/
Expand Down Expand Up @@ -489,7 +489,7 @@
$taxonomies = get_object_taxonomies( $post_type, 'object' );

foreach ( $taxonomies as $tax_name => $taxonomy ) {
if ( ! in_array( $tax_name, $ignore_taxonomies ) ) {

Check failure on line 492 in includes/class-frontend-render-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Not using strict comparison for in_array; supply true for $strict argument.
$this->wp_post_types[ $post_type ][ $tax_name ] = [
'title' => $taxonomy->label,
'hierarchical' => $taxonomy->hierarchical,
Expand Down Expand Up @@ -930,7 +930,7 @@
<div >
<label >
<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>
Comment on lines 932 to 936
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

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 has class="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.

Suggested change
<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>

Expand Down
81 changes: 81 additions & 0 deletions includes/functions/settings-options.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ function wpuf_settings_sections() {
'title' => __( 'Privacy Options', 'wp-user-frontend' ),
'icon' => 'dashicons-shield-alt',
],
[
'id' => 'wpuf_ai',
'title' => __( 'AI Settings', 'wp-user-frontend' ),
'icon' => 'dashicons-admin-network',
],
];

return apply_filters( 'wpuf_settings_sections', $sections );
Expand Down Expand Up @@ -632,6 +637,82 @@ function wpuf_settings_fields() {
'options' => $post_types,
],
] ),
'wpuf_ai' => apply_filters( 'wpuf_ai_options', [
[
'name' => 'ai_provider',
'label' => __( 'AI Provider', 'wp-user-frontend' ),
'desc' => __( 'Select the AI service provider you want to use.', 'wp-user-frontend' ),
'type' => 'select',
'options' => [
'openai' => 'OpenAI',
'anthropic' => 'Anthropic',
'google' => 'Google',
'others' => 'Others',
],
'default' => 'openai',
'class' => 'ai-provider-select',
],
[
'name' => 'ai_model',
'label' => __( 'AI Model', 'wp-user-frontend' ),
'desc' => __( 'Select the AI model to use for content generation.', 'wp-user-frontend' ),
'type' => 'select',
'options' => apply_filters('wpuf_ai_model_options', [
// OpenAI Models
'gpt-5' => 'GPT-5 (OpenAI)',
'gpt-4.5' => 'GPT-4.5 (OpenAI)',
'gpt-4o' => 'GPT-4o (OpenAI)',
'gpt-4.1' => 'GPT-4.1 (OpenAI)',
'gpt-4' => 'GPT-4 (OpenAI)',
'gpt-3.5-turbo' => 'GPT-3.5 Turbo (OpenAI)',
'gpt-oss-20b' => 'GPT-OSS-20B (OpenAI)',
'gpt-oss-120b' => 'GPT-OSS-120B (OpenAI)',
'whisper' => 'Whisper (OpenAI)',
'dall-e' => 'DALL-E (OpenAI)',
'embeddings' => 'Embeddings (OpenAI)',
'tts' => 'TTS (OpenAI)',

// Anthropic Models
'claude-opus-4' => 'Claude Opus 4 (Anthropic)',
'claude-opus-4.1' => 'Claude Opus 4.1 (Anthropic)',
'claude-sonnet-4' => 'Claude Sonnet 4 (Anthropic)',
'claude-3-opus' => 'Claude 3 Opus (Anthropic)',
'claude-3-sonnet' => 'Claude 3 Sonnet (Anthropic)',
'claude-3-haiku' => 'Claude 3 Haiku (Anthropic)',

// Google Models
'gemini-pro' => 'Gemini Pro (Google)',
'gemini-ultra' => 'Gemini Ultra (Google)',
'gemini-flash' => 'Gemini Flash (Google)',
'gemma' => 'Gemma (Google)',
'medgemma' => 'MedGemma (Google)',
'codegemma' => 'CodeGemma (Google)',
'palm-2' => 'PaLM 2 (Google)',
'lamda' => 'LaMDA (Google)',
'imagen' => 'Imagen (Google)',
'codey' => 'Codey (Google)',
'medlm' => 'MedLM (Google)',
'learnlm' => 'LearnLM (Google)',

// Other AI Services
'llama' => 'LLaMA (Others)',
'code-llama' => 'Code-Llama (Others)',
'grok' => 'Grok (Others)',
'jamba' => 'Jamba (Others)',
'deepseek' => 'DeepSeek (Others)',
'mistral' => 'Mistral (Others)',
]),
'default' => 'gpt-3.5-turbo',
'class' => 'ai-model-select',
],
[
'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' => '',
],
] ),
];

return apply_filters( 'wpuf_settings_fields', $settings_fields );
Expand Down
Loading