$v === null || $v === '' ? $def : (bool) $v; $text = static fn($v, string $def): string => $v === null ? $def : (is_scalar($v) ? (string) $v : $def); $fields = Fields::normalize($settings['fields'] ?? []); $steps = Fields::steps($fields); $total = count($steps); $multi = $total > 1; $show_labels = $bool($settings['show_labels'] ?? null, true); $inline = $show_labels && ($settings['label_position'] ?? 'top') === 'inline'; $mark = $bool($settings['mark_required'] ?? null, true); $show_progress = $multi && $bool($settings['show_progress'] ?? null, true); $show_titles = $multi && $bool($settings['show_step_titles'] ?? null, true); $honeypot = $bool($settings['honeypot'] ?? null, true); $recaptcha = in_array($settings['recaptcha'] ?? 'off', ['v2', 'v3'], true) ? (string) $settings['recaptcha'] : 'off'; $site_key = ''; if ($recaptcha !== 'off' && function_exists('get_option')) { $opts = get_option('zadex_settings', []); $site_key = is_array($opts) && isset($opts['recaptcha_site_key']) && is_string($opts['recaptcha_site_key']) ? trim($opts['recaptcha_site_key']) : ''; } $step_text = $text($settings['step_text'] ?? null, 'Step {current} of {total}'); $button_text = $text($settings['button_text'] ?? null, 'Send'); $next_text = $text($settings['next_text'] ?? null, 'Next'); $prev_text = $text($settings['prev_text'] ?? null, 'Back'); $config = [ 'messages' => [ 'success' => $text($settings['success_message'] ?? null, ''), 'error' => $text($settings['error_message'] ?? null, ''), 'required' => $text($settings['required_message'] ?? null, ''), 'invalid' => $text($settings['invalid_message'] ?? null, ''), ], 'stepText' => $step_text, 'reset' => $bool($settings['reset_on_success'] ?? null, true), 'recaptcha' => $recaptcha === 'off' ? null : ['version' => $recaptcha, 'siteKey' => $site_key], ]; $classes = array_filter([ $multi ? 'zx-form--steps' : '', $show_labels ? '' : 'zx-form--no-labels', $inline ? 'zx-form--labels-inline' : '', $bool($settings['button_full'] ?? null, false) ? 'zx-form--button-full' : '', ]); if ($classes) { $attrs = preg_replace('/class="/', 'class="' . esc_attr(implode(' ', $classes)) . ' ', $attrs, 1) ?? $attrs; } $attrs .= ' data-zx-form="' . esc_attr($el_id) . '" data-post="' . esc_attr((string) $zx_post_id) . '" action="' . esc_url($zx_action) . '" method="post" enctype="multipart/form-data" novalidate'; $attrs .= ' data-zx-config="' . esc_attr((string) wp_json_encode($config)) . '"'; $icon = is_array($settings['button_icon'] ?? null) ? $settings['button_icon'] : []; $icon_html = ''; if (!empty($icon['svg']) && is_string($icon['svg'])) { $icon_html = ''; } elseif (!empty($icon['value']) && is_string($icon['value'])) { $icon_html = ''; } $inline_html = static fn(string $zx_s): string => function_exists('wp_kses') ? wp_kses($zx_s, ['a' => ['href' => true, 'target' => true, 'rel' => true], 'strong' => [], 'em' => [], 'b' => [], 'i' => [], 'br' => [], 'span' => ['class' => true]]) : esc_html($zx_s); $render_field = static function (array $f) use ($el_id, $mark, $inline_html): string { $zx_id = 'zx-' . $el_id . '-' . $f['id']; $zx_name = 'fields[' . $f['id'] . ']'; $zx_type = $f['type']; if ($zx_type === 'hidden') { return ''; } $cls = 'zx-form__field zx-form__field--' . $zx_type . ' zx-form__field--w' . $f['width'] . ($f['required'] ? ' is-required' : ''); if ($zx_type === 'html') { $html = function_exists('wp_kses_post') ? wp_kses_post($f['html']) : esc_html($f['html']); return '