$value) { if ($value === '' || $value === null) continue; $cssKey = isset($map[$key]) ? $map[$key] : strtolower(preg_replace('/([a-z])([A-Z])/', '$1-$2', $key)); $style .= $cssKey . ':' . esc_attr($value) . ' !important;'; } return $style; } } add_shortcode('als_form', 'als_forms_render_shortcode'); function als_forms_render_shortcode($atts) { $atts = shortcode_atts([ 'id' => 0, ], $atts, 'als_form'); $form_id = intval($atts['id']); if (!$form_id) { return '

' . esc_html__('Form not found.', 'als-forms') . '

'; } global $wpdb; $table = $wpdb->prefix . 'als_forms'; $form = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE id = %d", $form_id)); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is not user input, $form_id is parameterized if (!$form) { return '

' . esc_html__('Form not found.', 'als-forms') . '

'; } $form_fields = json_decode($form->fields ?? $form->form_data, true); if (empty($form_fields)) { return '

' . esc_html__('Form has no fields.', 'als-forms') . '

'; } $layoutSettings = []; if (!empty($form->form_json)) { $form_json = json_decode($form->form_json, true); if (is_array($form_json) && !empty($form_json['layoutSettings'])) { $layoutSettings = $form_json['layoutSettings']; } } $containerStyle = ''; $formStyle = ''; if (!empty($layoutSettings['bgType']) && $layoutSettings['bgType'] === 'linear' && !empty($layoutSettings['gradientColor1']) && !empty($layoutSettings['gradientColor2'])) { $formStyle .= 'background:linear-gradient(90deg, ' . esc_attr($layoutSettings['gradientColor1']) . ' 0%, ' . esc_attr($layoutSettings['gradientColor2']) . ' 100%);'; } elseif (!empty($layoutSettings['bgType']) && $layoutSettings['bgType'] === 'solid' && !empty($layoutSettings['solidColor'])) { $formStyle .= 'background:' . esc_attr($layoutSettings['solidColor']) . ';'; } if (!empty($layoutSettings['containerPadding'])) { $containerStyle .= 'padding:' . esc_attr($layoutSettings['containerPadding']) . ';'; } else { $containerStyle .= 'padding:40px 0;'; } $formStyle .= als_forms_array_to_style($layoutSettings, [ 'width' => 'width', 'maxWidth' => 'max-width', 'height' => 'height', 'padding' => 'padding', 'margin' => 'margin', 'borderRadius' => 'border-radius', 'fontSize' => 'font-size', 'alignment' => 'text-align', ]); $custom_class = ''; if (!empty($layoutSettings['customCss'])) { $customCss = trim($layoutSettings['customCss']); if (strpos($customCss, '.') === 0) { $custom_class = preg_replace('/\s+/', ' ', trim(str_replace('.', '', $customCss))); } elseif (preg_match('/^[a-zA-Z\-]+\s*:/', $customCss)) { $formStyle .= $customCss; } } if (!empty($form->design)) { $form_design = json_decode($form->design, true); if (is_array($form_design)) { $formStyle .= als_forms_array_to_style($form_design); } } $form_layout_class = !empty($form->layout) ? 'als-form-layout-' . esc_attr($form->layout) : ''; $form_layout_class .= $custom_class ? ' ' . esc_attr($custom_class) : ''; $elegant_image = ''; if (!empty($layoutSettings['elegantImage'])) { $elegant_image = esc_url($layoutSettings['elegantImage']); } elseif (!empty($form->elegant_image)) { $elegant_image = esc_url($form->elegant_image); } ob_start(); if ($form->layout === 'elegant-image'): $flexDirection = (wp_is_mobile() ? 'column' : 'row'); $alignItems = (wp_is_mobile() ? 'center' : 'stretch'); $imageMargin = (wp_is_mobile() ? '0 auto 32px auto' : '0 32px 0 0'); $imageMaxWidth = '220px'; $imageMaxHeight = '220px'; $formMaxWidth = (wp_is_mobile() ? '100%' : '600px'); $formWidth = '100%'; $containerBg = !empty($layoutSettings['containerBg']) ? esc_attr($layoutSettings['containerBg']) : 'linear-gradient(90deg, #6a82fb 0%, #fc5c7d 100%)'; $formBg = ''; if (!empty($layoutSettings['bgType']) && $layoutSettings['bgType'] === 'linear' && !empty($layoutSettings['gradientColor1']) && !empty($layoutSettings['gradientColor2'])) { $formBg = 'background:linear-gradient(90deg,' . esc_attr($layoutSettings['gradientColor1']) . ' 0%,' . esc_attr($layoutSettings['gradientColor2']) . ' 100%);'; } elseif (!empty($layoutSettings['bgType']) && $layoutSettings['bgType'] === 'solid' && !empty($layoutSettings['solidColor'])) { $formBg = 'background:' . esc_attr($layoutSettings['solidColor']) . ';'; } else { $formBg = 'background:#fff;'; } $containerPadding = !empty($layoutSettings['padding']) ? esc_attr($layoutSettings['padding']) : '40px'; $boxShadow = '0 0 0 1px #eee, 0 4px 24px 0 #0001'; ?>
Form Illustration
No image
'; foreach ($field['columns'] as $col) { echo '
'; if (!empty($col['fields'])) { foreach ($col['fields'] as $colField) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo als_forms_render_field($colField); } } echo '
'; } echo '
'; continue; } // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo als_forms_render_field($field); } ?>
'; foreach ($field['columns'] as $col) { echo '
'; if (!empty($col['fields'])) { foreach ($col['fields'] as $colField) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is safe HTML from als_forms_render_field echo als_forms_render_field($colField); } } echo '
'; } echo '
'; continue; } // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is safe HTML from als_forms_render_field echo als_forms_render_field($field); } ?>
✓
*' : ''; switch ($field['type']) { case 'text': case 'email': case 'number': $html .= '
'; if (!empty($field['label'])) { $html .= ''; } elseif (!empty($field['required'])) { $html .= '*'; } $html .= ''; $html .= '
'; break; case 'textarea': $html .= '
'; if (!empty($field['label'])) { $html .= ''; } elseif (!empty($field['required'])) { $html .= '*'; } $html .= ''; $html .= '
'; break; case 'dropdown': $html .= '
'; if (!empty($field['label'])) { $html .= ''; } elseif (!empty($field['required'])) { $html .= '*'; } $html .= '
'; break; case 'gdpr': $gdprStyle = ''; if (!empty($field['bgColor'])) $gdprStyle .= 'background:' . esc_attr($field['bgColor']) . ' !important;'; if (!empty($field['padding'])) $gdprStyle .= 'padding:' . esc_attr($field['padding']) . ' !important;'; $gdprStyle .= 'margin:0 0 24px 0 !important;'; $gdprClass = 'als-form-field' . (!empty($field['customClass']) ? ' ' . esc_attr($field['customClass']) : ''); $checkboxLabel = !empty($field['checkboxLabel']) ? $field['checkboxLabel'] : ''; $policyText = !empty($field['policyText']) ? $field['policyText'] : ''; $policyUrl = !empty($field['policyUrl']) ? $field['policyUrl'] : ''; $errorText = !empty($field['errorText']) ? $field['errorText'] : ''; $textColor = !empty($field['textColor']) ? esc_attr($field['textColor']) : '#222'; $html .= '
'; $html .= ''; $html .= ''; $html .= '
'; break; case 'radio': $html .= '
'; if (!empty($field['label'])) { $html .= ''; } elseif (!empty($field['required'])) { $html .= '*'; } if (!empty($field['options']) && is_array($field['options'])) { $html .= '
'; foreach ($field['options'] as $option) { $value = is_array($option) ? $option['label'] : $option; $html .= ''; } $html .= '
'; } $html .= '
'; break; case 'radio_image': $html .= '
'; if (!empty($field['label'])) { $html .= ''; } elseif (!empty($field['required'])) { $html .= '*'; } if (!empty($field['options']) && is_array($field['options'])) { $html .= '
'; foreach ($field['options'] as $option) { $value = is_array($option) ? $option['label'] : $option; $img = (is_array($option) && !empty($option['image'])) ? '' . esc_attr($value) . '' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- esc_url/esc_attr used for image output, rest is static HTML // PluginCheck: NonEnqueuedImage is a false positive here; image is not a WP attachment, esc_url is used $html .= ''; } $html .= '
'; } $html .= '
'; break; case 'checkbox': $html .= '
'; if (!empty($field['label'])) { $html .= ''; } elseif (!empty($field['required'])) { $html .= '*'; } if (!empty($field['options']) && is_array($field['options'])) { $html .= '
'; foreach ($field['options'] as $option) { $value = is_array($option) ? $option['label'] : $option; $html .= ''; } $html .= '
'; } else { $html .= ''; } $html .= '
'; break; case 'file': $html .= '
'; if (!empty($field['label'])) { $html .= ''; } elseif (!empty($field['required'])) { $html .= '*'; } $uploadLabelStyle = ''; if (!empty($field['borderType']) && !empty($field['borderColor'])) { $borderType = strtolower($field['borderType']); $borderColor = esc_attr($field['borderColor']); if (!empty($field['borderWidth']) && is_array($field['borderWidth'])) { $bw = $field['borderWidth']; $uploadLabelStyle .= "border-style:{$borderType} !important;"; $uploadLabelStyle .= "border-color:{$borderColor} !important;"; $uploadLabelStyle .= "border-width:{$bw['top']}px {$bw['right']}px {$bw['bottom']}px {$bw['left']}px !important;"; } else { $uploadLabelStyle .= "border:2px {$borderType} {$borderColor} !important;"; } } else { $uploadLabelStyle .= "border:2px dashed #cccccc !important;"; } if (isset($field['borderRadius'])) { $uploadLabelStyle .= "border-radius:" . intval($field['borderRadius']) . "px !important;"; } if (!empty($field['bgColor'])) { $uploadLabelStyle .= "background:" . esc_attr($field['bgColor']) . " !important;"; } if (!empty($field['padding'])) { $uploadLabelStyle .= "padding:" . esc_attr($field['padding']) . " !important;"; } else { $uploadLabelStyle .= "padding:16px 28px !important;"; } $html .= ''; $html .= ''; $html .= '
'; break; case 'hidden': $html .= ''; break; case 'header': $level = isset($field['level']) ? intval($field['level']) : 2; $html .= '' . esc_html($field['text'] ?? $field['label']) . ''; break; case 'separator': $html .= '
'; break; case 'submit': $btnStyle = ''; $btnStyle .= 'background:' . (!empty($field['bgColor']) ? esc_attr($field['bgColor']) : '#1976d2') . ' !important;'; $btnStyle .= 'color:' . (!empty($field['textColor']) ? esc_attr($field['textColor']) : '#fff') . ' !important;'; if (!empty($field['btnBlock'])) { $btnStyle .= 'width:100% !important;'; } else { $btnStyle .= 'width:auto !important;min-width:180px !important;'; } $btnStyle .= 'display:block !important;'; $btnStyle .= 'line-height:1.5 !important;'; $btnStyle .= 'text-decoration:none !important;'; $btnStyle .= 'font-family:inherit !important;'; $btnStyle .= 'cursor:pointer !important;'; $btnStyle .= 'font-weight:600 !important;'; $btnStyle .= 'text-align:center !important;'; if (!empty($field['borderRadius'])) { if (is_array($field['borderRadius'])) { $btnStyle .= 'border-radius:8px !important;'; } else { $btnStyle .= 'border-radius:' . intval($field['borderRadius']) . 'px !important;'; } } else { $btnStyle .= 'border-radius:8px !important;'; } $btnStyle .= 'padding:' . (!empty($field['padding']) ? esc_attr($field['padding']) : '12px 20px') . ' !important;'; $btnStyle .= 'margin:' . (!empty($field['margin']) ? esc_attr($field['margin']) : '24px auto 8px auto') . ' !important;'; if (!empty($field['btnSize'])) { if ($field['btnSize'] === 'sm') { $btnStyle .= 'font-size:14px !important;'; } else if ($field['btnSize'] === 'lg') { $btnStyle .= 'font-size:18px !important;'; } else { $btnStyle .= 'font-size:16px !important;'; } } else { $btnStyle .= 'font-size:16px !important;'; } $btnStyle .= 'transition:all 0.2s ease !important;'; $btnClass = $customClass; $html .= '
'; break; case 'anchor': $html .= '' . esc_html($field['text'] ?? $field['label']) . ''; break; case 'paragraph': $html .= '
' . esc_html($field['text'] ?? $field['label']) . '
'; break; default: $html .= '
'; if (!empty($field['label'])) { $html .= ''; } elseif (!empty($field['required'])) { $html .= '*'; } $html .= ''; $html .= '
'; break; } return $html; } /** * Sanitize field data to prevent XSS attacks * This is a second layer of defense, primary sanitization happens during form save * * @param array $field Field data * @return array Sanitized field data */ function als_forms_sanitize_field_data($field) { if (!is_array($field)) { return $field; } $sanitized = []; foreach ($field as $key => $value) { if (is_array($value)) { $sanitized[$key] = als_forms_sanitize_field_data($value); } elseif (is_string($value)) { switch ($key) { case 'type': case 'name': case 'label': case 'placeholder': case 'alignment': case 'borderType': case 'customClass': $sanitized[$key] = sanitize_text_field($value); break; case 'bgColor': case 'textColor': case 'borderColor': case 'padding': case 'margin': case 'width': $sanitized[$key] = sanitize_text_field($value); break; case 'text': case 'content': $sanitized[$key] = wp_kses_post($value); break; case 'value': $sanitized[$key] = sanitize_text_field($value); break; default: $sanitized[$key] = sanitize_text_field($value); } } else { $sanitized[$key] = $value; } } return $sanitized; }