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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions Lib/WeDevs_Settings_API.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
function admin_enqueue_scripts() {
wp_enqueue_script( 'jquery' );

if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'wpuf-settings' || $_GET['page'] == 'wpuf-post-forms' || $_GET['page'] == 'wpuf-modules' || $_GET['page'] == 'wpuf-profile-forms' ) ) {

Check warning on line 39 in Lib/WeDevs_Settings_API.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

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

Check warning on line 39 in Lib/WeDevs_Settings_API.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Processing form data without nonce verification.

Check warning on line 39 in Lib/WeDevs_Settings_API.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

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

Check warning on line 39 in Lib/WeDevs_Settings_API.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Processing form data without nonce verification.

Check warning on line 39 in Lib/WeDevs_Settings_API.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

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

Check warning on line 39 in Lib/WeDevs_Settings_API.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Processing form data without nonce verification.

Check warning on line 39 in Lib/WeDevs_Settings_API.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Processing form data without nonce verification.
wp_enqueue_media();
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'wp-color-picker' );
Expand Down Expand Up @@ -518,7 +518,20 @@
$html .= wpuf_get_pro_preview_html();
}

echo wp_kses_post( $html );
// Allow input tags with necessary attributes for color picker fields
// wp_kses_post() strips <input> tags by default, so we need to explicitly allow them
$allowed_html = wp_kses_allowed_html( 'post' );
$allowed_html['input'] = [
'type' => true,
'class' => true,
'id' => true,
'name' => true,
'value' => true,
'data-default-color' => true,
'disabled' => true,
];

echo wp_kses( $html, $allowed_html );
}

/**
Expand Down Expand Up @@ -720,8 +733,8 @@
?>
<script>
jQuery(document).ready(function($) {
//Initiate Color Picker
$('.wp-color-picker-field').wpColorPicker();
//Initiate Color Picker (skip disabled fields for pro preview)
$('.wp-color-picker-field:not([disabled])').wpColorPicker();

// Switches option sections
$('.group').hide();
Expand Down
22 changes: 22 additions & 0 deletions assets/css/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -1549,3 +1549,25 @@ body.wpuf-modal-open {
.wpuf-subscription-pack-settings .subscription-nav-content section .form-table td {
padding: 15px 0;
}
/* Disabled color picker for pro preview */
.wp-picker-container input[type="text"].wp-color-picker-field[disabled] {
cursor: not-allowed !important;
opacity: 0.5 !important;
background-color: #f0f0f0 !important;
pointer-events: none !important;
}
.wp-picker-container .wp-color-result[disabled],
.wp-picker-container input[disabled] ~ .wp-picker-input-wrap .wp-color-result {
cursor: not-allowed !important;
opacity: 0.5 !important;
pointer-events: none !important;
}
.wp-picker-container .wp-color-result[disabled]:hover,
.wp-picker-container input[disabled] ~ .wp-picker-input-wrap .wp-color-result:hover {
background-color: inherit !important;
border-color: inherit !important;
}
.wp-picker-container .wp-color-result[disabled]:active,
.wp-picker-container input[disabled] ~ .wp-picker-input-wrap .wp-color-result:active {
transform: none !important;
}
109 changes: 109 additions & 0 deletions assets/css/login-form-settings.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* Login Form Settings - Admin Styles
*
* Static styles for the login form settings page in admin area.
* Radio image selection styles for layout chooser.
*
* @package WP User Frontend
* @subpackage Assets/CSS
*/

.wpuf-radio-image-wrapper {
display: flex;
flex-wrap: wrap;
gap: 15px;
}

.wpuf-radio-image-option {
flex: 0 0 calc(25% - 12px);
min-width: 200px;
}

.wpuf-radio-image-option input[type='radio'] {
position: absolute;
opacity: 0;
}

.wpuf-radio-image-option label {
position: relative;
display: block;
cursor: pointer;
border: 2px solid #ddd;
border-radius: 8px;
padding: 10px;
transition: all 0.3s ease;
background: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.wpuf-radio-image-option label:hover {
border-color: #0073aa;
box-shadow: 0 4px 8px rgba(0, 115, 170, 0.2);
transform: translateY(-2px);
}

.wpuf-radio-image-option input[type='radio']:checked + label {
border-color: #0073aa;
background-color: #f0f8ff;
box-shadow: 0 4px 8px rgba(0, 115, 170, 0.3);
}

.wpuf-radio-image-option input[type='radio']:checked + label::after {
content: '✓';
position: absolute;
top: 12px;
right: 12px;
background: #0073aa;
color: white;
width: 20px;
height: 20px;
border-radius: 100%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 12px;
line-height: 24px;
text-align: center;
}

.wpuf-radio-image-option img {
max-width: 100%;
height: auto;
display: block;
border-radius: 4px;
}

/* Free plugin specific: Fix WordPress Settings API table layout */
/* Force horizontal flex layout inside form tables */

/* Override fieldset constraints */
.form-table fieldset {
max-width: none !important;
}

.form-table td fieldset {
max-width: 100% !important;
width: 100% !important;
}

/* Force flex display on wrapper - works in all browsers */
.form-table .wpuf-radio-image-wrapper,
.form-table fieldset .wpuf-radio-image-wrapper,
.form-table td .wpuf-radio-image-wrapper {
display: flex !important;
flex-wrap: wrap !important;
flex-direction: row !important;
width: 100% !important;
gap: 15px !important;
}

/* Ensure each option displays inline */
.form-table .wpuf-radio-image-option {
flex: 0 0 calc(25% - 12px) !important;
min-width: 200px !important;
display: inline-flex !important;
vertical-align: top !important;
}


24 changes: 24 additions & 0 deletions assets/images/login-layouts/layout1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions assets/images/login-layouts/layout2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions assets/images/login-layouts/layout3.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions assets/images/login-layouts/layout4.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions assets/images/login-layouts/layout5.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions assets/images/login-layouts/layout6.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions assets/images/login-layouts/layout7.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
88 changes: 88 additions & 0 deletions includes/functions/settings-options.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function wpuf_settings_sections() {
}

function wpuf_settings_fields() {
$crown_icon = WPUF_ROOT . '/assets/images/crown.svg';
$pages = wpuf_get_pages();
$users = wpuf_list_users();
$post_types = get_post_types();
Expand Down Expand Up @@ -470,6 +471,93 @@ function wpuf_settings_fields() {
'default' => 'off',
'depends_on' => 'enable_turnstile',
],
[
'name' => 'wpuf_login_form_layout',
'label' => __( 'Login Form Layout', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'desc' => __( 'Choose a layout style for your login forms.', 'wp-user-frontend' ),
'type' => 'radio',
'options' => wpuf_get_login_layout_options(),
'default' => 'layout1',
'is_pro_preview' => ! wpuf_is_pro_active(),
'callback' => 'wpuf_render_login_layout_field',
],
[
'name' => 'wpuf_login_form_bg_color',
'label' => __( 'Form Background Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => 'transparent',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_form_border_color',
'label' => __( 'Form Border Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => 'transparent',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_field_border_color',
'label' => __( 'Field Border Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => '#D1D5DB',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_field_bg_color',
'label' => __( 'Field Background Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => 'transparent',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_label_text_color',
'label' => __( 'Label Text Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => '#333333',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_placeholder_color',
'label' => __( 'Placeholder Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => '#9CA3AF',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_input_text_color',
'label' => __( 'Input Text Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => '#111827',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_help_text_color',
'label' => __( 'Help Text Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => '#6B7280',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_button_bg_color',
'label' => __( 'Button Background Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => '#3B82F6',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_button_border_color',
'label' => __( 'Button Border Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => '',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
[
'name' => 'wpuf_login_button_text_color',
'label' => __( 'Button Text Color', 'wp-user-frontend' ) . '<span class="pro-icon"> ' . file_get_contents( $crown_icon ) . '</span>',
'type' => 'color',
'default' => '#ffffff',
'is_pro_preview' => ! wpuf_is_pro_active(),
],
] ),
'wpuf_payment' => apply_filters( 'wpuf_options_payment', [
[
Expand Down
13 changes: 9 additions & 4 deletions templates/login-form.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/*
If you would like to edit this file, copy it to your current theme's directory and edit it there.

Check warning on line 3 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 2 spaces.
WPUF will always look in your theme's directory first, before using this default template.

Check warning on line 4 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Found precision alignment of 2 spaces.
*/
?>
Expand All @@ -10,7 +10,7 @@

$message = apply_filters( 'login_message', '' );

if ( !empty( $message ) ) {

Check failure on line 13 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Expected 1 space after "!"; 0 found
echo wp_kses_post( $message ) . "\n";
}
?>
Expand Down Expand Up @@ -39,17 +39,17 @@
<?php if ( $recaptcha === 'on' ) { ?>
<p>
<div class="wpuf-fields">
<?php echo wp_kses( recaptcha_get_html( wpuf_get_option( 'recaptcha_public', 'wpuf_general' ), true, null, is_ssl() ),[

Check failure on line 42 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

No space found after comma in argument list

Check failure on line 42 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Opening parenthesis of a multi-line function call must be the last content on the line

Check failure on line 42 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Opening PHP tag must be on a line by itself
'div' => [

Check failure on line 43 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 4 spaces but found 24
'class' => [],

Check failure on line 44 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Multi-line array item not aligned correctly; expected 8 spaces, but found 28
'data-sitekey' => [],
],

'script' => [

Check failure on line 48 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 4 spaces but found 24
'src' => []

Check failure on line 49 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

There should be a comma after the last array item in a multi-line array.

Check failure on line 49 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Multi-line array item not aligned correctly; expected 8 spaces, but found 28
],

'noscript' => [],

Check failure on line 52 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array item not aligned correctly; expected 4 spaces but found 24

'iframe' => [
'src' => [],
Expand Down Expand Up @@ -89,9 +89,14 @@
</script>
<?php } ?>

<p class="forgetmenot">
<input name="rememberme" type="checkbox" id="wpuf-rememberme" value="forever" />
<label for="wpuf-rememberme"><?php esc_html_e( 'Remember Me', 'wp-user-frontend' ); ?></label>
<p class="forgetmenot wpuf-remember-forgot-wrapper">
<span class="wpuf-remember-me">
<input name="rememberme" type="checkbox" id="wpuf-rememberme" value="forever" />
<label for="wpuf-rememberme"><?php esc_html_e( 'Remember Me', 'wp-user-frontend' ); ?></label>
</span>
<span class="wpuf-lost-password">
<a href="<?php echo esc_url( wp_lostpassword_url() ); ?>"><?php esc_html_e( 'Lost Password', 'wp-user-frontend' ); ?></a>
</span>
</p>

<p class="submit">
Expand All @@ -106,5 +111,5 @@
</p>
</form>

<?php echo wp_kses_post( wpuf()->frontend->simple_login->get_action_links( [ 'login' => false ] ) ); ?>
<?php echo wp_kses_post( wpuf()->frontend->simple_login->get_action_links( [ 'login' => false, 'lostpassword' => false ] ) ); ?>

Check warning on line 114 in templates/login-form.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

When a multi-item array uses associative keys, each value should start on a new line.
</div>
90 changes: 90 additions & 0 deletions wpuf-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5704,3 +5704,93 @@ function wpuf_field_profile_photo_allowed_mimes() {
return apply_filters( 'wpuf_field_profile_photo_allowed_mimes', $profile_photo_mimes );
}
}

/**
* Get login layout options for settings
*
* @since 4.1.0
*
* @return array Layout options with labels and image URLs
*/
function wpuf_get_login_layout_options() {
$image_url = WPUF_ASSET_URI . '/images/login-layouts/';

$layouts = [
'layout1' => __( 'Layout 1 - Classic', 'wp-user-frontend' ),
'layout2' => __( 'Layout 2 - Modern Dark', 'wp-user-frontend' ),
'layout3' => __( 'Layout 3 - Minimal', 'wp-user-frontend' ),
'layout4' => __( 'Layout 4 - Bordered', 'wp-user-frontend' ),
'layout5' => __( 'Layout 5 - Rounded', 'wp-user-frontend' ),
'layout6' => __( 'Layout 6 - Clean', 'wp-user-frontend' ),
'layout7' => __( 'Layout 7 - Premium', 'wp-user-frontend' ),
];

$options = [];
foreach ( $layouts as $key => $label ) {
$options[ $key ] = [
'label' => $label,
'image' => $image_url . $key . '.svg',
];
}

return $options;
}

/**
* Render login layout radio image field
*
* @since 4.1.0
*
* @param array $args Field arguments
*/
function wpuf_render_login_layout_field( $args ) {
if ( empty( $args['section'] ) || empty( $args['id'] ) || empty( $args['options'] ) ) {
return;
}

$value = get_option( $args['section'] );
$current = $value[ $args['id'] ] ?? $args['std'] ?? '';
$disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'disabled' : '';
$wrapper_class = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'pro-preview-html' : '';

echo '<fieldset>';

printf( '<div class="wpuf-radio-image-wrapper %s">', esc_attr( $wrapper_class ) );

foreach ( $args['options'] as $key => $option ) {
$checked = checked( $current, $key, false );
$label = esc_html( $option['label'] ?? $key );
$image = esc_url( $option['image'] ?? '' );

printf(
'<div class="wpuf-radio-image-option">
<input type="radio" id="%1$s_%2$s" name="%3$s[%1$s]" value="%2$s" %4$s %5$s>
<label for="%1$s_%2$s" title="%6$s">',
esc_attr( $args['id'] ),
esc_attr( $key ),
esc_attr( $args['section'] ),
$checked,
$disabled,
$label
);

if ( $image ) {
printf( '<img src="%s" alt="%s">', $image, $label );
}

echo '</label></div>';
}

// Add pro preview overlay inside the wrapper
if ( ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ) {
echo wpuf_get_pro_preview_html();
}

echo '</div>';

if ( ! empty( $args['desc'] ) ) {
printf( '<p class="description">%s</p>', wp_kses_post( $args['desc'] ) );
}

echo '</fieldset>';
}
Comment on lines +5746 to +5796
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Fix default fallback and attribute escaping in renderer

Two issues:

  • Default: you read $args['std'] but the field uses default. Initial selection may be empty.
  • Escaping: title and alt should use esc_attr(). Currently $label is esc_html only.

Apply:

 function wpuf_render_login_layout_field( $args ) {
@@
-    $value   = get_option( $args['section'] );
-    $current = $value[ $args['id'] ] ?? $args['std'] ?? '';
-    $disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'disabled' : '';
+    $value    = get_option( $args['section'] );
+    $current  = isset( $value[ $args['id'] ] )
+        ? $value[ $args['id'] ]
+        : ( $args['default'] ?? ( $args['std'] ?? '' ) );
+    $is_disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'];
@@
-    foreach ( $args['options'] as $key => $option ) {
+    foreach ( (array) $args['options'] as $key => $option ) {
         $checked = checked( $current, $key, false );
-        $label   = esc_html( $option['label'] ?? $key );
+        $label   = $option['label'] ?? $key;
+        $label_attr = esc_attr( $label );
+        $label_text = esc_html( $label );
         $image   = esc_url( $option['image'] ?? '' );
 
         printf(
             '<div class="wpuf-radio-image-option">
-                <input type="radio" id="%1$s_%2$s" name="%3$s[%1$s]" value="%2$s" %4$s %5$s>
-                <label for="%1$s_%2$s" title="%6$s">',
+                <input type="radio" id="%1$s_%2$s" name="%3$s[%1$s]" value="%2$s" %4$s %5$s>
+                <label for="%1$s_%2$s" title="%6$s">',
             esc_attr( $args['id'] ),
             esc_attr( $key ),
             esc_attr( $args['section'] ),
             $checked,
-            $disabled,
-            $label
+            $is_disabled ? 'disabled="disabled"' : '',
+            $label_attr
         );
 
         if ( $image ) {
-            printf( '<img src="%s" alt="%s">', $image, $label );
+            printf( '<img src="%s" alt="%s">', $image, $label_attr );
         }
 
-        echo '</label></div>';
+        echo wp_kses_post( '</label></div>' );
     }
@@
-    if ( ! empty( $args['desc'] ) ) {
-        printf( '<p class="description">%s</p>', wp_kses_post( $args['desc'] ) );
-    }
+    if ( ! empty( $args['desc'] ) ) {
+        printf( '<p class="description">%s</p>', wp_kses_post( $args['desc'] ) );
+    }

I'll help you verify the issues raised in this review comment. Let me search the codebase to understand the calling context and field definitions.


🏁 Script executed:

#!/bin/bash
# Find the wpuf-functions.php file and verify the function exists
find . -name "wpuf-functions.php" -type f | head -5

Length of output: 20


🏁 Script executed:

#!/bin/bash
# Search for calls to wpuf_render_login_layout_field to understand how $args is constructed
rg -n "wpuf_render_login_layout_field" --type=php -B 3 -A 3

Length of output: 1027


🏁 Script executed:

#!/bin/bash
# Search for where 'std' and 'default' keys are set in field definitions
rg -n "(\['std'\]|\['default'\])" --type=php -B 2 -A 2 | head -100

Length of output: 5511


🏁 Script executed:

#!/bin/bash
# Search for field option definitions to understand the parameter structure
rg -n "'id'\s*=>" --type=php -B 1 -A 5 | grep -E "(std|default)" | head -30

Length of output: 758


🏁 Script executed:

#!/bin/bash
# Look for field definitions specific to login layout rendering
rg -n "login.*layout.*field|login.*layout.*option" --type=php -i -B 2 -A 5 | head -50

Length of output: 2579


🏁 Script executed:

#!/bin/bash
# Check if options is ever passed as non-array to this function
rg -n "\['options'\]\s*=" --type=php -B 1 -A 1 | head -30

Length of output: 531


🏁 Script executed:

#!/bin/bash
# Verify current code escaping practices in the file - look for esc_attr usage
rg -n "esc_attr|esc_html" wpuf-functions.php --type=php -C 2 | head -60

Length of output: 3859


🏁 Script executed:

#!/bin/bash
# Search for where this rendering function is registered/hooked
rg -n "add_action.*wpuf_render|register.*wpuf_render" --type=php -B 1 -A 1

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Look for the specific function definition to confirm line numbers and current state
sed -n '5748,5798p' wpuf-functions.php

Length of output: 1696


🏁 Script executed:

#!/bin/bash
# Check if there are any admin field definitions using 'std' or 'default' keys
rg -n "'std'|'default'" --type=php -B 3 -A 1 | grep -E "(login|layout|radio)" -i | head -40

Length of output: 3269


🏁 Script executed:

#!/bin/bash
# Search for option defaults specifically in admin or field setup
rg -n "render_login_layout_field" --type=php -B 10 -A 10 | head -80

Length of output: 3278


🏁 Script executed:

#!/bin/bash
# Look for args array construction that might use 'std' or other keys
rg -n "\['options'\]|'section'|'is_pro_preview'" --type=php -B 3 -A 2 | head -80

Length of output: 5117


🏁 Script executed:

#!/bin/bash
# Search for where get_option might be used with field config
rg -n "get_option.*section" --type=php -B 2 -A 3 | head -40

Length of output: 2524


🏁 Script executed:

#!/bin/bash
# Look for sanitize/validate callbacks that might reveal field structure
rg -n "sanitize.*login|login.*sanitize" --type=php -i -B 2 -A 3 | head -40

Length of output: 2954


🏁 Script executed:

#!/bin/bash
# Check for actual field configuration arrays that call wpuf_render_login_layout_field
ast-grep --pattern $'[
  $$$
  "callback" => "wpuf_render_login_layout_field"
  $$$
]'

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for register_setting or do_settings_fields context
rg -n "register_setting|do_settings_fields" --type=php -B 3 -A 5 | head -60

Length of output: 566


🏁 Script executed:

#!/bin/bash
# Look for where the radio image options are defined
rg -n "'image'|'label'|'options'" --type=php -B 2 -A 2 | grep -E "(login|layout)" -i | head -50

Length of output: 6138


🏁 Script executed:

#!/bin/bash
# Check for test files or examples that show how this function is called
find . -name "*test*.php" -o -name "*example*.php" | xargs grep -l "wpuf_render_login_layout_field" 2>/dev/null | head -5

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for where field args are built with 'std' or 'default'
rg -n "std.*=>|default.*=>" --type=php -B 5 | grep -E "(login|field|render)" -i -A 3 | head -80

Length of output: 7307


🏁 Script executed:

#!/bin/bash
# Look at the field definitions more carefully around line 5748
rg -n "function wpuf_render_login_layout_field" --type=php -B 30 -A 60 | head -100

Length of output: 4538


🏁 Script executed:

#!/bin/bash
# Check for array casting patterns in the codebase
rg -n "\(array\)" --type=php | head -20

Length of output: 1512


🏁 Script executed:

#!/bin/bash
# Verify escaping best practices - search for esc_attr usage with title/alt
rg -n "title=|alt=" --type=php -B 1 -A 1 | grep "esc_" | head -20

Length of output: 3352


🏁 Script executed:

#!/bin/bash
# Check if disabled attribute is used elsewhere and how it's formatted
rg -n "disabled.*disabled|disabled=\"disabled\"" --type=php | head -15

Length of output: 1735


🏁 Script executed:

#!/bin/bash
# Look for wp_kses_post usage on closing tags
rg -n "wp_kses_post.*</" --type=php | head -10

Length of output: 1202


🏁 Script executed:

#!/bin/bash
# Check context around the function to understand the broader pattern
wc -l wpuf-functions.php
sed -n '5740,5810p' wpuf-functions.php

Length of output: 1830


🏁 Script executed:

#!/bin/bash
# Search for field definitions array that passes options to this callback
rg -n "callback.*render_login_layout_field" --type=php -B 50 | tail -80

Length of output: 5108


🏁 Script executed:

#!/bin/bash
# Look for the complete field definition context
rg -n "'id'\s*=>.*'section'\s*=>" --type=php -B 5 -A 15 | grep -A 20 "login.*layout" -i | head -60

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Final check - search for actual field hook/filter that provides these arguments
rg -n "apply_filters.*login.*layout|do_action.*login.*layout" --type=php -i -B 2 -A 5

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search entire codebase for how this function args are passed
grep -rn "wpuf_render_login_layout_field" . --include="*.php" | head -20

Length of output: 192


🏁 Script executed:

#!/bin/bash
# Get the actual implementation by line range
head -5798 wpuf-functions.php | tail -51

Length of output: 1696


🏁 Script executed:

#!/bin/bash
# Look for field definitions in settings or admin pages
find . -name "*.php" -exec grep -l "login.*layout\|layout.*login" {} \; | head -10

Length of output: 62


🏁 Script executed:

#!/bin/bash
# Check if std vs default is documented or used consistently
grep -rn "'std'" . --include="*.php" | wc -l
grep -rn "'default'" . --include="*.php" | wc -l

Length of output: 6


🏁 Script executed:

#!/bin/bash
# Search for where field arguments are constructed for this specific callback
grep -rn "wpuf_render_login_layout_field" . --include="*.php" -B 30 | grep -E "(std|default|options|section)" | head -40

Length of output: 3342


🏁 Script executed:

#!/bin/bash
# Look at admin settings where this might be used
find . -path "*/admin*" -name "*.php" | xargs grep -l "login.*layout" -i 2>/dev/null | head -5

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Final comprehensive search for the field definition
rg -n "render_login_layout_field|login-layout|login_layout" --type=php -B 10 -A 10 | head -150

Length of output: 4794


🏁 Script executed:

#!/bin/bash
# Check the actual arguments passed by finding the field registration
grep -rn "'callback'.*'wpuf_render_login_layout_field'" . --include="*.php" -B 20 -A 5 | head -100

Length of output: 2717


Address default parameter mismatch and attribute escaping vulnerabilities

The review comment correctly identifies two critical issues:

  1. Default parameter mismatch: The field definition (includes/functions/settings-options.php:475) provides 'default' => 'layout1', but the function (wpuf-functions.php:5754) reads $args['std'] which doesn't exist in this context. Initial selection will be empty.

  2. Attribute escaping: The title and alt attributes (lines 5770, 5780) use esc_html() for $label, but HTML attributes require esc_attr() per WordPress security standards.

  3. Disabled attribute format: The disabled attribute should be 'disabled="disabled"' (consistent with other fields at line 3722), not just 'disabled'.

Apply these fixes:

 function wpuf_render_login_layout_field( $args ) {
     if ( empty( $args['section'] ) || empty( $args['id'] ) || empty( $args['options'] ) ) {
         return;
     }
 
     $value   = get_option( $args['section'] );
-    $current = $value[ $args['id'] ] ?? $args['std'] ?? '';
-    $disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'disabled' : '';
+    $current = isset( $value[ $args['id'] ] )
+        ? $value[ $args['id'] ]
+        : ( $args['default'] ?? ( $args['std'] ?? '' ) );
+    $is_disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'];
 
     foreach ( $args['options'] as $key => $option ) {
         $checked = checked( $current, $key, false );
-        $label   = esc_html( $option['label'] ?? $key );
+        $label   = $option['label'] ?? $key;
+        $label_attr = esc_attr( $label );
+        $label_text = esc_html( $label );
         $image   = esc_url( $option['image'] ?? '' );
 
         printf(
             '<div class="wpuf-radio-image-option">
                 <input type="radio" id="%1$s_%2$s" name="%3$s[%1$s]" value="%2$s" %4$s %5$s>
                 <label for="%1$s_%2$s" title="%6$s">',
             esc_attr( $args['id'] ),
             esc_attr( $key ),
             esc_attr( $args['section'] ),
             $checked,
-            $disabled,
-            $label
+            $is_disabled ? 'disabled="disabled"' : '',
+            $label_attr
         );
 
         if ( $image ) {
-            printf( '<img src="%s" alt="%s">', $image, $label );
+            printf( '<img src="%s" alt="%s">', $image, $label_attr );
         }
 
         echo '</label></div>';
     }
📝 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
function wpuf_render_login_layout_field( $args ) {
if ( empty( $args['section'] ) || empty( $args['id'] ) || empty( $args['options'] ) ) {
return;
}
$value = get_option( $args['section'] );
$current = $value[ $args['id'] ] ?? $args['std'] ?? '';
$disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'disabled' : '';
$wrapper_class = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'pro-preview-html' : '';
echo '<fieldset>';
printf( '<div class="wpuf-radio-image-wrapper %s">', esc_attr( $wrapper_class ) );
foreach ( $args['options'] as $key => $option ) {
$checked = checked( $current, $key, false );
$label = esc_html( $option['label'] ?? $key );
$image = esc_url( $option['image'] ?? '' );
printf(
'<div class="wpuf-radio-image-option">
<input type="radio" id="%1$s_%2$s" name="%3$s[%1$s]" value="%2$s" %4$s %5$s>
<label for="%1$s_%2$s" title="%6$s">',
esc_attr( $args['id'] ),
esc_attr( $key ),
esc_attr( $args['section'] ),
$checked,
$disabled,
$label
);
if ( $image ) {
printf( '<img src="%s" alt="%s">', $image, $label );
}
echo '</label></div>';
}
// Add pro preview overlay inside the wrapper
if ( ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ) {
echo wpuf_get_pro_preview_html();
}
echo '</div>';
if ( ! empty( $args['desc'] ) ) {
printf( '<p class="description">%s</p>', wp_kses_post( $args['desc'] ) );
}
echo '</fieldset>';
}
function wpuf_render_login_layout_field( $args ) {
if ( empty( $args['section'] ) || empty( $args['id'] ) || empty( $args['options'] ) ) {
return;
}
$value = get_option( $args['section'] );
$current = isset( $value[ $args['id'] ] )
? $value[ $args['id'] ]
: ( $args['default'] ?? ( $args['std'] ?? '' ) );
$is_disabled = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'];
$wrapper_class = ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ? 'pro-preview-html' : '';
echo '<fieldset>';
printf( '<div class="wpuf-radio-image-wrapper %s">', esc_attr( $wrapper_class ) );
foreach ( $args['options'] as $key => $option ) {
$checked = checked( $current, $key, false );
$label = $option['label'] ?? $key;
$label_attr = esc_attr( $label );
$label_text = esc_html( $label );
$image = esc_url( $option['image'] ?? '' );
printf(
'<div class="wpuf-radio-image-option">
<input type="radio" id="%1$s_%2$s" name="%3$s[%1$s]" value="%2$s" %4$s %5$s>
<label for="%1$s_%2$s" title="%6$s">',
esc_attr( $args['id'] ),
esc_attr( $key ),
esc_attr( $args['section'] ),
$checked,
$is_disabled ? 'disabled="disabled"' : '',
$label_attr
);
if ( $image ) {
printf( '<img src="%s" alt="%s">', $image, $label_attr );
}
echo '</label></div>';
}
// Add pro preview overlay inside the wrapper
if ( ! empty( $args['is_pro_preview'] ) && $args['is_pro_preview'] ) {
echo wpuf_get_pro_preview_html();
}
echo '</div>';
if ( ! empty( $args['desc'] ) ) {
printf( '<p class="description">%s</p>', wp_kses_post( $args['desc'] ) );
}
echo '</fieldset>';
}
🤖 Prompt for AI Agents
In wpuf-functions.php around lines 5748-5798, fix three issues: replace the
non-existent $args['std'] fallback when determining $current with
$args['default'] (i.e. $current = $value[$args['id']] ?? $args['default'] ??
''), change the disabled marker to the full attribute disabled="disabled" when
is_pro_preview is true (and ensure it's passed through esc_attr when printed),
and use esc_attr() (not esc_html()) for $label when outputting it into HTML
attributes (title and img alt). Ensure all inserted attribute values are
properly escaped with esc_attr() and image URL remains esc_url().

Loading