From 5dec036e78480a5f5548c404b918f94e2cb33c81 Mon Sep 17 00:00:00 2001 From: tommaso Date: Mon, 8 Sep 2025 17:38:47 +0200 Subject: [PATCH] Campi obbligatori & fix --- administrator/src/Field/CalSafeField.php | 52 +++-- administrator/src/Model/CircolareModel.php | 13 +- administrator/src/Table/CircolareTable.php | 48 ++++- administrator/tmpl/circolare/edit.php | 66 ++++++- circolari.xml | 1 + site/src/Controller/DisplayController.php | 5 + site/src/Controller/FormController.php | 84 +++++++++ site/src/Model/FormModel.php | 148 +++++++++++++++ site/src/Service/Router.php | 99 ++++------ site/src/View/Form/HtmlView.php | 40 ++++ site/tmpl/circolari/default.php | 53 +++--- site/tmpl/form/default.php | 209 +++++++++++++++++++++ site/views/form/metadata.xml | 7 + 13 files changed, 711 insertions(+), 114 deletions(-) create mode 100644 site/src/Controller/FormController.php create mode 100644 site/src/Model/FormModel.php create mode 100644 site/src/View/Form/HtmlView.php create mode 100644 site/tmpl/form/default.php create mode 100644 site/views/form/metadata.xml diff --git a/administrator/src/Field/CalSafeField.php b/administrator/src/Field/CalSafeField.php index 5cb3cfe..875b6cf 100644 --- a/administrator/src/Field/CalSafeField.php +++ b/administrator/src/Field/CalSafeField.php @@ -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 ''; } diff --git a/administrator/src/Model/CircolareModel.php b/administrator/src/Model/CircolareModel.php index ab1f402..e8e5a0c 100644 --- a/administrator/src/Model/CircolareModel.php +++ b/administrator/src/Model/CircolareModel.php @@ -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(); diff --git a/administrator/src/Table/CircolareTable.php b/administrator/src/Table/CircolareTable.php index 11f38c7..1675201 100644 --- a/administrator/src/Table/CircolareTable.php +++ b/administrator/src/Table/CircolareTable.php @@ -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(); } /** diff --git a/administrator/tmpl/circolare/edit.php b/administrator/tmpl/circolare/edit.php index bece210..2e3f030 100644 --- a/administrator/tmpl/circolare/edit.php +++ b/administrator/tmpl/circolare/edit.php @@ -25,7 +25,7 @@ HTMLHelper::_('bootstrap.tooltip');
+ method="post" enctype="multipart/form-data" name="adminForm" id="adminForm" class="form-validate form-horizontal"> 'Circolari')); ?> @@ -37,7 +37,6 @@ HTMLHelper::_('bootstrap.tooltip'); form->renderField('title'); ?> form->renderField('alias'); ?> form->renderField('categoria_id'); ?> - form->renderField('usergroup_id'); ?> form->renderField('hits'); ?> form->renderField('description'); ?> form->renderField('attachment'); ?> @@ -56,4 +55,65 @@ HTMLHelper::_('bootstrap.tooltip'); -
\ No newline at end of file + + +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 = ' *'; + 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); diff --git a/circolari.xml b/circolari.xml index 7444a36..f3de7ea 100644 --- a/circolari.xml +++ b/circolari.xml @@ -33,6 +33,7 @@ src services tmpl + views css diff --git a/site/src/Controller/DisplayController.php b/site/src/Controller/DisplayController.php index 898aa0e..c8234db 100644 --- a/site/src/Controller/DisplayController.php +++ b/site/src/Controller/DisplayController.php @@ -1,4 +1,5 @@ input->set('view', $this->default_view); + } + return parent::display($cachable, $urlparams); } } diff --git a/site/src/Controller/FormController.php b/site/src/Controller/FormController.php new file mode 100644 index 0000000..6eb49ce --- /dev/null +++ b/site/src/Controller/FormController.php @@ -0,0 +1,84 @@ +getIdentity(); + if ($user->guest || (!$user->authorise('core.manage', 'com_circolari') && !$user->authorise('core.admin', 'com_circolari'))) { + throw new \RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + $view = $this->input->getCmd('view', 'form'); + $layout = $this->input->getCmd('layout', 'edit'); + $id = $this->input->getInt('id'); + + $this->input->set('view', $view); + $this->input->set('layout', $layout); + $this->input->set('id', $id); + + return parent::display(); + } + + public function save() + { + if (!Session::checkToken('post')) { + throw new \RuntimeException(Text::_('JINVALID_TOKEN'), 403); + } + + $app = Factory::getApplication(); + $user = $app->getIdentity(); + if ($user->guest || (!$user->authorise('core.manage', 'com_circolari') && !$user->authorise('core.admin', 'com_circolari'))) { + throw new \RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + $data = [ + 'id' => $this->input->getInt('id', 0), + 'title' => trim($this->input->getString('title', '')), + 'alias' => trim($this->input->getString('alias', '')), + 'description' => $this->input->get('description', '', 'raw'), + 'categoria_id' => $this->input->getInt('categoria_id', 0), + 'tipologia_firma_id' => $this->input->getInt('tipologia_firma_id', 0), + 'firma_obbligatoria' => $this->input->getInt('firma_obbligatoria', 0), + 'scadenza' => $this->input->getString('scadenza', ''), // 'YYYY-MM-DD HH:MM' + 'state' => $this->input->getInt('state', 1), + // nuovi campi per creare tipologia al volo + 'nuova_tipologia_nome' => trim($this->input->getString('nuova_tipologia_nome', '')), + 'nuovi_bottoni' => trim($this->input->getString('nuovi_bottoni', '')), + ]; + + if ($data['title'] === '') { + $app->enqueueMessage(Text::_('COM_CIRCOLARI_ERR_TITLE_REQUIRED'), 'error'); + $this->setRedirect(Route::_('index.php?option=com_circolari&view=form&layout=edit&id=' . (int)$data['id'], false)); + return; + } + + /** @var \Pcrt\Component\Circolari\Site\Model\FormModel $model */ + $model = $this->getModel('Form', 'Site'); + + try { + $id = $model->saveData($data, $user->id); + $app->enqueueMessage(Text::_('COM_CIRCOLARI_MSG_SAVED_OK'), 'message'); + $this->setRedirect(Route::_('index.php?option=com_circolari&view=circolare&id=' . (int)$id, false)); + } catch (\Throwable $e) { + $app->enqueueMessage($e->getMessage(), 'error'); + $this->setRedirect(Route::_('index.php?option=com_circolari&view=form&layout=edit&id=' . (int)$data['id'], false)); + } + } + + public function cancel() + { + $this->setRedirect(Route::_('index.php?option=com_circolari&view=circolari', false)); + } +} diff --git a/site/src/Model/FormModel.php b/site/src/Model/FormModel.php new file mode 100644 index 0000000..6c9c7e4 --- /dev/null +++ b/site/src/Model/FormModel.php @@ -0,0 +1,148 @@ +get('DatabaseDriver'); + $q = $db->getQuery(true) + ->select('*') + ->from('#__circolari') + ->where('id = ' . (int)$id); + $db->setQuery($q); + return $db->loadObject() ?: null; + } + + public function getCategorie(): array + { + $db = Factory::getContainer()->get('DatabaseDriver'); + $q = $db->getQuery(true) + ->select('id, title, state') + ->from('#__circolari_categorie') + ->where('state = 1') + ->order('title ASC'); + $db->setQuery($q); + return $db->loadAssocList() ?: []; + } + public function getFirmetipi(): array + { + $db = \Joomla\CMS\Factory::getContainer()->get('DatabaseDriver'); + $q = $db->getQuery(true) + ->select('id, nome') + ->from('#__circolari_firmetipi') + ->where('state = 1') + ->order('nome ASC'); + $db->setQuery($q); + return $db->loadAssocList() ?: []; + } + + public function getBottoniByFirmatipo(): array + { + $db = \Joomla\CMS\Factory::getContainer()->get('DatabaseDriver'); + $q = $db->getQuery(true) + ->select('f.id AS firmatipo_id, b.label') + ->from('#__circolari_firmetipi AS f') + ->leftJoin('#__circolari_firmetipi_bottoni AS b ON b.firmatipo_id = f.id') + ->where('f.state = 1') + ->order('f.id ASC, b.ordering ASC, b.id ASC'); + $db->setQuery($q); + $rows = $db->loadAssocList() ?: []; + + $map = []; + foreach ($rows as $r) { + $fid = (int) $r['firmatipo_id']; + if (!isset($map[$fid])) $map[$fid] = []; + if (!empty($r['label'])) $map[$fid][] = $r['label']; + } + return $map; + } + + /** + * Salva/aggiorna la circolare; crea anche una nuova tipologia e bottoni se richiesto. + * Ritorna l'ID della circolare salvata. + */ + public function saveData(array $data, int $userId): int + { + $db = Factory::getContainer()->get('DatabaseDriver'); + + + // 2) normalizza alias + if (empty($data['alias'])) { + $data['alias'] = $this->slugify($data['title']); + } + + // 3) INSERT o UPDATE su #__circolari + $now = Factory::getDate()->toSql(); + $row = (object) [ + 'id' => (int)($data['id'] ?? 0), + 'title' => $data['title'], + 'alias' => $data['alias'], + 'description' => $data['description'], + 'categoria_id' => (int)$data['categoria_id'], + 'tipologia_firma_id' => (int)$data['tipologia_firma_id'], + 'firma_obbligatoria' => (int)$data['firma_obbligatoria'], + 'scadenza' => $data['scadenza'] ?: null, + 'state' => (int)$data['state'], + ]; + + if ($row->id > 0) { + $row->modified_by = $userId; + $row->checked_out = 0; + $row->checked_out_time = null; + $db->updateObject('#__circolari', $row, ['id']); + $id = $row->id; + } else { + $row->created_by = $userId; + $db->insertObject('#__circolari', $row); + $id = (int)$db->insertid(); + } + + return $id; + } + + private function createNewFirmatipo(string $nome, string $bottoniRiga): int + { + $db = Factory::getContainer()->get('DatabaseDriver'); + + // crea tipologia + $tipo = (object) [ + 'nome' => $nome, + 'descrizione' => '', + 'state' => 1, + ]; + $db->insertObject('#__circolari_firmetipi', $tipo); + $id = (int) $db->insertid(); + + // crea bottoni (uno per riga) + $labels = array_filter(array_map('trim', preg_split('/\R+/', $bottoniRiga ?: ''))); + $ordering = 1; + foreach ($labels as $label) { + $btn = (object) [ + 'firmatipo_id' => $id, + 'label' => $label, + 'ordering' => $ordering++, + ]; + $db->insertObject('#__circolari_firmetipi_bottoni', $btn); + } + + return $id; + } + + private function slugify(string $s): string + { + $t = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); + $t = strtolower($t); + $t = preg_replace('~[^a-z0-9]+~', '-', $t); + $t = trim($t, '-'); + return $t ?: 'circolare'; + } +} diff --git a/site/src/Service/Router.php b/site/src/Service/Router.php index a994bf7..6074737 100644 --- a/site/src/Service/Router.php +++ b/site/src/Service/Router.php @@ -1,4 +1,5 @@ setKey('id')->setNestable(); $this->registerView($category); - // Child: circolare (lega la category tramite categoria_id) - $circolare = new RouterViewConfiguration('circolari'); - $circolare->setKey('id')->setParent($category, 'categoria_id', 'id'); + // 2) LISTA (nessuna key!) + $circolari = new RouterViewConfiguration('circolari'); + // Se vuoi, puoi lasciarla senza parent, oppure solo setParent($category) SENZA variabili + // $circolari->setParent($category); // opzionale, ma senza 2° e 3° argomento + $this->registerView($circolari); + + // DETTAGLIO (ha la key id) + $circolare = new RouterViewConfiguration('circolare'); + $circolare->setKey('id')->setParent($circolari); $this->registerView($circolare); + // 4) FORM (se presente) + $form = new RouterViewConfiguration('form'); + $form->setParent($circolari); + $this->registerView($form); + parent::__construct($app, $menu); - // Regole standard di routing - $this->attachRule(new StandardRules($this)); + // Regole: prima Menu, poi Standard, poi NoMenu $this->attachRule(new MenuRules($this)); + $this->attachRule(new StandardRules($this)); $this->attachRule(new NomenuRules($this)); } /* ---------------- BUILD ---------------- */ - // Segmenti categoria = path completo (parent1/parent2/figlia) + // Segmento categoria = alias (fallback id) public function getCategorySegment($id, $query) { - $id = (int) ($id ?: 0); - if ($id <= 0) { - return []; - } - - $db = Factory::getContainer()->get('DatabaseDriver'); - $path = (string) $db->setQuery( - $db->getQuery(true) - ->select('path') - ->from('#__circolari_categorie') - ->where('id = ' . $id) - ->where("extension = 'com_content'") + $db = Factory::getContainer()->get('DatabaseDriver'); + $alias = (string) $db->setQuery( + $db->getQuery(true)->select('alias')->from('#__circolari_categorie')->where('id=' . (int)$id) )->loadResult(); - return $path !== '' ? array_filter(explode('/', $path)) : [(string) $id]; + return $alias !== '' ? [$alias] : [(string) (int) $id]; } - // Ultimo segmento = SOLO alias della circolare + // Segmento dettaglio = alias (fallback id se vuoto) public function getCircolareSegment($id, $query) { $db = Factory::getContainer()->get('DatabaseDriver'); $alias = (string) $db->setQuery( - $db->getQuery(true) - ->select('alias') - ->from('#__circolari') - ->where('id = ' . (int) $id) + $db->getQuery(true)->select('alias')->from('#__circolari')->where('id=' . (int)$id) )->loadResult(); - // Nessun fallback numerico: imponiamo l'alias - return [$alias]; + return [$alias !== '' ? $alias : (string) (int) $id]; } /* ---------------- PARSE ---------------- */ - // Ricava categoria_id accumulando i segmenti e risolvendo per PATH completo public function getCategoryId($segment, $query) { - static $segments = []; - $segments[] = $segment; - $path = implode('/', $segments); - $db = Factory::getContainer()->get('DatabaseDriver'); - - // match per path (univoco in com_content) $id = (int) $db->setQuery( - $db->getQuery(true) - ->select('id') - ->from('#__circolari_categorie') - ->where('path = ' . $db->quote($path)) - ->where("extension = 'com_content'") + $db->getQuery(true)->select('id')->from('#__circolari_categorie')->where('alias=' . $db->quote($segment)) )->loadResult(); - if ($id > 0) { - return $id; - } - - // fallback (singolo alias) se si visita direttamente un livello intermedio - $id = (int) $db->setQuery( - $db->getQuery(true) - ->select('id') - ->from('#__circolari_categorie') - ->where('alias = ' . $db->quote($segment)) - ->where("extension = 'com_content'") - ->order('level DESC') - )->loadResult(); - - return $id ?: 0; + return $id > 0 ? $id : (ctype_digit((string)$segment) ? (int)$segment : 0); } - // Alias circolare (+ categoria_id già risolto) → id public function getCircolareId($segment, $query) { $categoria_id = (int) ($query['categoria_id'] ?? 0); $db = Factory::getContainer()->get('DatabaseDriver'); $q = $db->getQuery(true) - ->select('id') - ->from('#__circolari') - ->where('alias = ' . $db->quote($segment)); + ->select('id') + ->from('#__circolari') + ->where('alias = ' . $db->quote($segment)); if ($categoria_id > 0) { $q->where('categoria_id = ' . $categoria_id); } $db->setQuery($q); + $id = (int) $db->loadResult(); - return (int) $db->loadResult() ?: 0; + // fallback numerico sull’ultimo segmento + if ($id === 0 && ctype_digit((string)$segment)) { + $id = (int) $segment; + } + + return $id; } } diff --git a/site/src/View/Form/HtmlView.php b/site/src/View/Form/HtmlView.php new file mode 100644 index 0000000..d8024b3 --- /dev/null +++ b/site/src/View/Form/HtmlView.php @@ -0,0 +1,40 @@ +getModel(); + $this->item = $model->getItem((int) \Joomla\CMS\Factory::getApplication()->input->getInt('id', 0)); + $this->categorie = $model->getCategorie(); + $this->firmetipi = $model->getFirmetipi(); + $this->bottoniMap = $model->getBottoniByFirmatipo(); + $app = Factory::getApplication(); + $user = $app->getIdentity(); + if ($user->guest || (!$user->authorise('core.manage', 'com_circolari') && !$user->authorise('core.admin', 'com_circolari'))) { + throw new \RuntimeException(\Joomla\CMS\Language\Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + /** @var \Pcrt\Component\Circolari\Site\Model\FormModel $model */ + $model = $this->getModel(); + + $id = (int) $app->input->getInt('id', 0); + $this->item = $model->getItem($id); + $this->categorie = $model->getCategorie(); + $this->firmetipi = $model->getFirmetipi(); + + parent::display($tpl); + } +} diff --git a/site/tmpl/circolari/default.php b/site/tmpl/circolari/default.php index eacaf23..35ca8d2 100644 --- a/site/tmpl/circolari/default.php +++ b/site/tmpl/circolari/default.php @@ -13,7 +13,9 @@ $items = $this->items ?? ($this->get('Items') ?? []); $pagination = $this->pagination ?? ($this->get('Pagination') ?? null); // Normalizzo items -if (!is_array($items)) { $items = (array) $items; } +if (!is_array($items)) { + $items = (array) $items; +} $items = array_values(array_filter($items, static fn($it) => is_object($it) && !empty($it->id))); $Itemid = (int) $input->getInt('Itemid', 0); @@ -37,34 +39,29 @@ $Itemid = (int) $input->getInt('Itemid', 0); - $item) : ?> - id - . '&catid=' . (int) ($item->catid ?? 0) - . ($Itemid ? '&Itemid=' . $Itemid : '') - ); + $item) : ?> + id); $title = $item->title ?? ('#' . (int) $item->id); $hits = isset($item->hits) ? (int) $item->hits : null; - ?> - - - - - - - - - - : - - - - - - - + ?> + + + + + + + + + + : + + + + + + + @@ -82,4 +79,4 @@ $Itemid = (int) $input->getInt('Itemid', 0); - + \ No newline at end of file diff --git a/site/tmpl/form/default.php b/site/tmpl/form/default.php new file mode 100644 index 0000000..9172712 --- /dev/null +++ b/site/tmpl/form/default.php @@ -0,0 +1,209 @@ +item ?: (object) []; +$action = Route::_('index.php?option=com_circolari&task=form.save'); + +// Trova un Itemid valido per la lista (per il link "Annulla") +$menu = Factory::getApplication()->getMenu(); +$component = ComponentHelper::getComponent('com_circolari'); +$cancelItemId = 0; +foreach ((array) $menu->getItems('component_id', (int) $component->id) as $mi) { + $q = is_array($mi->query ?? null) ? $mi->query : []; + if (($q['option'] ?? '') === 'com_circolari' && ($q['view'] ?? '') === 'circolari') { + $cancelItemId = (int) $mi->id; + break; + } +} +$cancelUrl = $cancelItemId + ? Route::_('index.php?Itemid=' . $cancelItemId) + : Uri::root() . 'index.php?option=com_circolari&view=circolari'; +?> +
+

+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+
+ + +
+ +
+ + firma_obbligatoria ?? 0); ?> + +
+ + +
+ + + +
+ + +
+ + + + + + + +
+
diff --git a/site/views/form/metadata.xml b/site/views/form/metadata.xml new file mode 100644 index 0000000..249c3df --- /dev/null +++ b/site/views/form/metadata.xml @@ -0,0 +1,7 @@ + + + + Pubblica Circolare + edit + +