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');
\ 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';
+?>
+
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
+
+