Campi obbligatori & fix

This commit is contained in:
2025-09-08 17:38:47 +02:00
parent cbcbcc6f8e
commit 5dec036e78
13 changed files with 711 additions and 114 deletions

View File

@ -3,8 +3,8 @@ namespace Pcrt\Component\Circolari\Administrator\Field;
\defined('_JEXEC') or die;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
class CalSafeField extends FormField
{
@ -16,11 +16,14 @@ class CalSafeField extends FormField
$id = $this->id;
$value = (string) $this->value;
if (!empty($value)) {
// Normalizza il valore DB in formato datetime-local (YYYY-MM-DDTHH:MM)
if ($value !== '' && $value !== '0000-00-00 00:00:00') {
$value = preg_replace('/\s+/', ' ', $value);
$value = str_replace('T', ' ', $value);
if (preg_match('/^(\d{4}-\d{2}-\d{2})\s(\d{2}:\d{2})(?::\d{2})?$/', $value, $m)) {
$value = $m[1] . 'T' . $m[2];
if (preg_match('/^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}(:\d{2})?$/', $value)) {
// "YYYY-MM-DD HH:MM(:SS)" -> "YYYY-MM-DDTHH:MM"
$value = str_replace(' ', 'T', substr($value, 0, 16));
} else {
try {
$dt = Factory::getDate($value);
@ -29,20 +32,43 @@ class CalSafeField extends FormField
$value = '';
}
}
} else {
$value = '';
}
$attrs = [];
$attrs = [];
$attrs[] = 'type="datetime-local"';
$attrs[] = 'name="' . htmlspecialchars($name, ENT_COMPAT, 'UTF-8') . '"';
$attrs[] = 'id="' . htmlspecialchars($id, ENT_COMPAT, 'UTF-8') . '"';
$attrs[] = 'name="' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '"';
$attrs[] = 'id="' . htmlspecialchars($id, ENT_QUOTES, 'UTF-8') . '"';
if ($value !== '') {
$attrs[] = 'value="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"';
$attrs[] = 'value="' . htmlspecialchars($value, ENT_QUOTES, 'UTF-8') . '"';
}
if ($this->required) { $attrs[] = 'required'; }
// readonly/disabled da XML o proprietà
$readonly = (string) ($this->element['readonly'] ?? '');
if ($readonly === 'true' || $readonly === 'readonly' || $this->readonly) {
$attrs[] = 'readonly';
}
$disabled = (string) ($this->element['disabled'] ?? '');
if ($disabled === 'true' || $disabled === 'disabled' || $this->disabled) {
$attrs[] = 'disabled';
}
// Pass-through opzionali: min/max/step/placeholder
foreach (['min','max','step','placeholder'] as $p) {
if (isset($this->element[$p]) && (string)$this->element[$p] !== '') {
$attrs[] = $p . '="' . htmlspecialchars((string)$this->element[$p], ENT_QUOTES, 'UTF-8') . '"';
}
}
// Classe CSS
$class = trim((string) ($this->element['class'] ?? 'form-control'));
if ($class !== '') {
$attrs[] = 'class="' . htmlspecialchars($class, ENT_QUOTES, 'UTF-8') . '"';
}
if ($this->required) $attrs.append('required');
if ($this->readonly) $attrs.append('readonly');
if ($this->disabled) $attrs.append('disabled');
$class = $this->element['class'] ? (string) $this->element['class'] : 'form-control';
$attrs[] = 'class="' . htmlspecialchars($class, ENT_COMPAT, 'UTF-8') . '"';
return '<input ' . implode(' ', $attrs) . ' />';
}

View File

@ -114,7 +114,7 @@ class CircolareModel extends AdminModel
*
* @since 1.0.0
*/
protected function loadFormData()
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = Factory::getApplication()->getUserState('com_circolari.edit.circolare.data', array());
@ -149,6 +149,7 @@ class CircolareModel extends AdminModel
return $data;
}
/**
* Method to get a single record.
*
@ -282,6 +283,16 @@ class CircolareModel extends AdminModel
public function check()
{
// Se firma obbligatoria, scadenza deve esserci
$isObbl = (int) ($this->firma_obbligatoria ?? 0);
if ($isObbl === 1 && empty($this->scadenza)) {
$this->setError(\Joomla\CMS\Language\Text::_('COM_CIRCOLARI_ERR_SCADENZA_REQUIRED'));
return false;
}
// ordering per nuovi record
if (property_exists($this, 'ordering') && (int) $this->id === 0) {
$this->ordering = self::getNextOrder();

View File

@ -240,19 +240,49 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
// Default gruppo utenti
// Default gruppo utenti
$this->usergroup_id = (int)($this->usergroup_id ?? 0);
$this->hits = max(0, (int)($this->hits ?? 0));
// Normalize scadenza from datetime-local (YYYY-MM-DDTHH:MM)
if (!empty($this->scadenza)) {
$this->scadenza = str_replace('T', ' ', (string) $this->scadenza);
if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', (string) $this->scadenza)) {
$this->scadenza .= ':00';
}
}
// Normalize scadenza from datetime-local (YYYY-MM-DDTHH:MM)
if (!empty($this->scadenza)) {
$this->scadenza = str_replace('T', ' ', (string) $this->scadenza);
if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', (string) $this->scadenza)) {
$this->scadenza .= ':00';
}
}
return parent::check();
$raw = isset($this->scadenza) ? trim((string) $this->scadenza) : '';
if ($raw === '' || $raw === '0000-00-00 00:00:00') {
// Se non è obbligatoria, salva NULL
if ((int) ($this->firma_obbligatoria ?? 0) === 1) {
$this->setError(\Joomla\CMS\Language\Text::_('Campo Data Scadenza Firma Mancante'));
return false;
}
$this->scadenza = null;
} else {
// Accetta vari formati e salva in SQL
$clean = str_replace('T', ' ', substr($raw, 0, 19));
$dt = \DateTime::createFromFormat('Y-m-d H:i', $clean)
?: \DateTime::createFromFormat('Y-m-d H:i:s', $clean)
?: \DateTime::createFromFormat('d-m-Y H:i', $clean)
?: \DateTime::createFromFormat('d-m-Y H:i:s', $clean);
if ($dt === false) {
$this->setError(\Joomla\CMS\Language\Text::_('Campo Data Scadenza Firma Mancante'));
return false;
}
$this->scadenza = $dt->format('Y-m-d H:i:s');
}
// (2) Se firma è obbligatoria, la scadenza deve esserci
if ((int) ($this->firma_obbligatoria ?? 0) === 1 && empty($this->scadenza)) {
$this->setError(\Joomla\CMS\Language\Text::_('Campo Data Scadenza Firma Mancante'));
return false;
}
return parent::check();
}
/**

View File

@ -25,7 +25,7 @@ HTMLHelper::_('bootstrap.tooltip');
<form
action="<?php echo Route::_('index.php?option=com_circolari&layout=edit&id=' . (int) $this->item->id); ?>"
method="post" enctype="multipart/form-data" name="adminForm" id="adminForm" class="form-validate" class="form-validate form-horizontal">
method="post" enctype="multipart/form-data" name="adminForm" id="adminForm" class="form-validate form-horizontal">
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', array('active' => 'Circolari')); ?>
@ -37,7 +37,6 @@ HTMLHelper::_('bootstrap.tooltip');
<?php echo $this->form->renderField('title'); ?>
<?php echo $this->form->renderField('alias'); ?>
<?php echo $this->form->renderField('categoria_id'); ?>
<?php echo $this->form->renderField('usergroup_id'); ?>
<?php echo $this->form->renderField('hits'); ?>
<?php echo $this->form->renderField('description'); ?>
<?php echo $this->form->renderField('attachment'); ?>
@ -56,4 +55,65 @@ HTMLHelper::_('bootstrap.tooltip');
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
<input type="hidden" name="task" value="" />
<?php echo HTMLHelper::_('form.token'); ?>
</form>
</form>
<?php
Factory::getDocument()->addScriptDeclaration(<<<'JS'
(function(){
// Supporta sia select che radio per jform_firma_obbligatoria
function getFirmaObbligatoriaValue(){
var radios = document.querySelectorAll('input[name="jform[firma_obbligatoria]"]');
if (radios.length){
var r = Array.prototype.find.call(radios, function(x){ return x.checked; });
return r ? r.value : '0';
}
var sel = document.getElementById('jform_firma_obbligatoria');
return sel ? sel.value : '0';
}
function toggleScadenzaRequired(){
var need = getFirmaObbligatoriaValue() === '1';
var input = document.getElementById('jform_scadenza');
var label = document.getElementById('jform_scadenza-lbl');
if (input){
if (need){
input.setAttribute('required','required');
input.setAttribute('aria-required','true');
} else {
input.removeAttribute('required');
input.removeAttribute('aria-required');
input.classList.remove('invalid');
}
}
if (label){
if (need){
label.classList.add('required');
if (!label.querySelector('.star')){
var s = document.createElement('span');
s.className = 'star';
s.setAttribute('aria-hidden','true');
s.innerHTML = '&nbsp;*';
label.appendChild(s);
}
} else {
label.classList.remove('required');
var star = label.querySelector('.star');
if (star){ star.remove(); }
}
}
}
// Bind change su select/radio
document.addEventListener('change', function(e){
if (e.target && (e.target.id === 'jform_firma_obbligatoria' || e.target.name === 'jform[firma_obbligatoria]')){
toggleScadenzaRequired();
}
});
// Init
document.addEventListener('DOMContentLoaded', toggleScadenzaRequired);
})();
JS);