Este lote de trabalho (BATCH-051) define a migração do escape de HTML para comportamento padrão no html-editor (quando html e html_extra_head são informados), implementa a divisão de value e label para os campos do tipo select no renderizador público, e adiciona suporte completo a campos do tipo radio e checkbox no módulo Forms (com exibição condicional do campo Opções no CRUD, placeholder instrutivo e suporte nos templates).
1. Modificações no html-editor e forms (Escape HTML por Padrão)
1.1 Modificar gestor/bibliotecas/html-editor.php
-
Localizar a função
html_editor_componente(). -
Modificar o trecho inserido no BATCH-050 para que o escape das tags HTML ocorra automaticamente sempre que as variáveis estiverem presentes no array
$params(mesmo se o parâmetro explícitohtml_specialcharsnão estiver definido). -
Implementação recomendada:
$html_val = isset($html) ? $html : null; $html_extra_head_val = isset($html_extra_head) ? $html_extra_head : null; if (!is_null($html_val)) { $html_editor = modelo_var_troca_tudo($html_editor, '#pagina-html#', htmlspecialchars($html_val, ENT_QUOTES, 'UTF-8')); } if (!is_null($html_extra_head_val)) { $html_editor = modelo_var_troca_tudo($html_editor, '#pagina-html-extra-head#', htmlspecialchars($html_extra_head_val, ENT_QUOTES, 'UTF-8')); }
1.2 Modificar gestor/modulos/forms/forms.php
-
Na função
forms_prepare_editor_page, remover a linha'html_specialchars' => trueda chamada parahtml_editor_componente($params). Os parâmetros'html' => $htmle'html_extra_head' => $html_extra_headdevem ser mantidos, pois sua presença agora é o que ativa o escape por padrão.
2. Divisão de Opções e Suporte a Radio/Checkbox (Forms)
2.1 Modificar gestor/modulos/forms/forms.widget.php
-
Atualizar a função
forms_widget_options_html($field)para:-
Recuperar a chave de idioma ou tipo de campo
$field['type']. -
No loop
foreach ($options as $option)do blocoelse(quando processa opções declaradas via string de linha), validar a presença dos separadores:ou|para separar a chave (value) da descrição (label). -
Se o tipo de campo for
radiooucheckbox, renderizar elementos HTML do tipo<input>dentro de um wrapper<label>em vez de tags<option>.
-
-
Implementação recomendada:
function forms_widget_options_html($field) { $options = $field['options'] ?? []; $type = $field['type'] ?? 'select'; $name = $field['name'] ?? ''; $required = forms_widget_bool($field['required'] ?? false) ? 'required' : ''; if (is_string($options)) { $options = array_filter(array_map('trim', preg_split('/\r\n|\r|\n|,/', $options))); } if (!is_array($options)) return ''; $html = ''; foreach ($options as $option) { if (is_array($option)) { $value = $option['value'] ?? ($option['label'] ?? ''); $label = $option['label'] ?? $value; } else { if (strpos($option, '|') !== false) { $parts = explode('|', $option, 2); $value = trim($parts[0]); $label = trim($parts[1]); } else if (strpos($option, ':') !== false) { $parts = explode(':', $option, 2); $value = trim($parts[0]); $label = trim($parts[1]); } else { $value = $option; $label = $option; } } if ($type === 'radio' || $type === 'checkbox') { $input_name = htmlspecialchars((string)$name, ENT_QUOTES, 'UTF-8') . ($type === 'checkbox' ? '[]' : ''); $html .= '<label class="inline-flex items-center mr-4 mb-2 cursor-pointer">' . '<input type="'.$type.'" name="'.$input_name.'" value="'.htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8').'" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" '.$required.'>' . '<span class="ml-2 text-sm text-gray-700">'.htmlspecialchars((string)$label, ENT_QUOTES, 'UTF-8').'</span>' . '</label>'; } else { $html .= '<option value="'.htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8').'">'.htmlspecialchars((string)$label, ENT_QUOTES, 'UTF-8').'</option>'; } } return $html; } -
Na função
forms_widget_render_field(), atualizar as condicionais de bloco para suportartype-radioetype-checkbox, e isolar a condicional detype-input:$html = forms_widget_block($html, 'type-select', $type === 'select'); $html = forms_widget_block($html, 'type-textarea', $type === 'textarea'); $html = forms_widget_block($html, 'type-radio', $type === 'radio'); $html = forms_widget_block($html, 'type-checkbox', $type === 'checkbox'); $html = forms_widget_block($html, 'type-input', $type !== 'select' && $type !== 'textarea' && $type !== 'radio' && $type !== 'checkbox');
3. Melhorias na Interface Administrativa (CRUD de Campos)
3.1 Modificar gestor/modulos/forms/forms.js
-
Adicionar
radioecheckboxnas opções do dropdown de tipos na funçãobuildFieldRow(). -
Ocultar ou exibir a
.forms-field-optionsno carregamento e dinamicamente no eventochangese o tipo forselect,radiooucheckbox. -
Adicionar placeholder instrutivo localizado na textarea.
Trecho modificado na buildFieldRow:
var optionsStyle = (type === 'select' || type === 'radio' || type === 'checkbox') ? '' : ' style="display:none;"';
var placeholder = isPtBr()
? 'valor:Rótulo\nEx: sp:São Paulo'
: 'value:Label\nEx: ny:New York';
// HTML da linha:
// ...
// + '<td><select class="forms-field-type ui dropdown">'
// + option('text', 'Text', type) + option('email', 'E-mail', type) + option('tel', 'Phone', type) + option('number', 'Number', type) + option('textarea', 'Textarea', type) + option('select', 'Select', type) + option('radio', 'Radio', type) + option('checkbox', 'Checkbox', type)
// + '</select></td>'
// ...
// + '<td><textarea class="forms-field-options" rows="2" placeholder="' + escapeAttr(placeholder) + '"' + optionsStyle + '>' + escapeHtml(options) + '</textarea></td>'Adicionar ou atualizar o listener de mudança do dropdown de tipos:
$(document).on('change', '.forms-field-type', function () {
var $row = $(this).closest('tr');
var $options = $row.find('.forms-field-options');
var val = $(this).val();
if (val === 'select' || val === 'radio' || val === 'checkbox') {
$options.show();
} else {
$options.hide().val('');
}
updateFieldsFromTable();
schedulePreview(false);
});4. Atualização nos Templates Físicos de Formulário
Adicione os marcadores condicionais type-radio e type-checkbox nos 5 templates (10 arquivos no total, abrangendo pt-br e en):
-
forms-contato-basico(2 arquivos) -
forms-newsletter-newsletter(2 arquivos) -
forms-registro-usuario(2 arquivos) -
forms-pesquisa-satisfacao(2 arquivos) -
forms-suporte-tecnico(2 arquivos)
Estrutura de bloco a ser adicionada em cada template HTML:
<!-- type-radio < -->
<div class="flex flex-wrap mt-1">
@[[item#options]]@
</div>
<!-- type-radio > -->
<!-- type-checkbox < -->
<div class="flex flex-wrap mt-1">
@[[item#options]]@
</div>
<!-- type-checkbox > -->(Nota: Ajustar as classes Tailwind conforme a identidade visual de cada template, usando flex flex-wrap gap-4 mt-1 ou similar).
5. Verificação de Funcionamento (Tests & Check)
5.1 Testes Automatizados
-
Rodar a suíte de testes locais:
-
Comando:
composer test -
Comando:
npm run test
-