Modifica Circolare da frontend
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Pcrt\Component\Circolari\Site\Controller;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
@ -13,68 +14,53 @@ class FormController extends BaseController
|
||||
{
|
||||
public function display($cachable = false, $urlparams = [])
|
||||
{
|
||||
// Solo utenti autenticati + permesso admin/manage
|
||||
$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);
|
||||
}
|
||||
|
||||
$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();
|
||||
$this->input->set('view', 'form');
|
||||
return parent::display($cachable, $urlparams);
|
||||
}
|
||||
|
||||
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'))) {
|
||||
$user = Factory::getUser();
|
||||
|
||||
// Permessi: admin/gestione o edit
|
||||
if (!$user->id || (!$user->authorise('core.manage', 'com_circolari') && !$user->authorise('core.edit', '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 (!Session::checkToken()) {
|
||||
throw new \RuntimeException(Text::_('JINVALID_TOKEN'), 403);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
$in = $app->input;
|
||||
|
||||
$data = $in->get('jform', [], 'array');
|
||||
|
||||
// Il tuo form frontend invia campi "piatti"
|
||||
if (!$data) {
|
||||
$data = [
|
||||
'id' => $in->getInt('id', 0),
|
||||
'title' => $in->getString('title', ''),
|
||||
'alias' => $in->getString('alias', ''),
|
||||
'categoria_id' => $in->getInt('categoria_id', 0),
|
||||
'description' => $in->getRaw('description', ''),
|
||||
'state' => $in->getInt('state', 1),
|
||||
'firma_obbligatoria' => $in->getInt('firma_obbligatoria', 0),
|
||||
'tipologia_firma_id' => $in->getInt('tipologia_firma_id', 0),
|
||||
'scadenza' => $in->getString('scadenza', ''), // datetime-local
|
||||
];
|
||||
}
|
||||
|
||||
/** @var \Pcrt\Component\Circolari\Site\Model\FormModel $model */
|
||||
$model = $this->getModel('Form', 'Site');
|
||||
$model = $this->getModel('Form');
|
||||
|
||||
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));
|
||||
}
|
||||
$id = $model->saveData($data, (int) $user->id);
|
||||
|
||||
$this->setRedirect(
|
||||
Route::_('index.php?option=com_circolari&view=circolare&id=' . (int) $id, false),
|
||||
Text::_('JLIB_APPLICATION_SAVE_SUCCESS')
|
||||
);
|
||||
}
|
||||
|
||||
public function cancel()
|
||||
|
||||
@ -9,18 +9,6 @@ use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
||||
|
||||
class FormModel extends BaseDatabaseModel
|
||||
{
|
||||
public function getItem(int $id = 0): ?\stdClass
|
||||
{
|
||||
if ($id <= 0) return null;
|
||||
|
||||
$db = Factory::getContainer()->get('DatabaseDriver');
|
||||
$q = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from('#__circolari')
|
||||
->where('id = ' . (int)$id);
|
||||
$db->setQuery($q);
|
||||
return $db->loadObject() ?: null;
|
||||
}
|
||||
|
||||
public function getCategorie(): array
|
||||
{
|
||||
@ -66,49 +54,67 @@ class FormModel extends BaseDatabaseModel
|
||||
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');
|
||||
public function getItem(int $id = 0): \stdClass
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return (object) [];
|
||||
}
|
||||
$db = \Joomla\CMS\Factory::getContainer()->get('DatabaseDriver');
|
||||
$q = $db->getQuery(true)
|
||||
->select('*')->from('#__circolari')->where('id=' . (int) $id);
|
||||
$db->setQuery($q);
|
||||
return $db->loadObject() ?: (object) [];
|
||||
}
|
||||
|
||||
public function saveData(array $data, int $userId): int
|
||||
{
|
||||
$app = \Joomla\CMS\Factory::getApplication();
|
||||
|
||||
// 2) normalizza alias
|
||||
if (empty($data['alias'])) {
|
||||
$data['alias'] = $this->slugify($data['title']);
|
||||
// Alias di fallback
|
||||
if (empty($data['alias']) && !empty($data['title'])) {
|
||||
$alias = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $data['title']);
|
||||
$alias = preg_replace('~[^a-z0-9]+~i', '-', strtolower($alias));
|
||||
$alias = trim($alias, '-');
|
||||
$data['alias'] = $alias ?: ('circolare-' . uniqid());
|
||||
}
|
||||
|
||||
// 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'],
|
||||
];
|
||||
// JTable amministrativa per coerenza di check/store
|
||||
$factory = $app->bootComponent('com_circolari')->getMVCFactory();
|
||||
/** @var \Pcrt\Component\Circolari\Administrator\Table\CircolareTable $table */
|
||||
$table = $factory->createTable('Circolare', 'Administrator');
|
||||
|
||||
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;
|
||||
$id = (int) ($data['id'] ?? 0);
|
||||
if ($id > 0) {
|
||||
$table->load($id);
|
||||
$data['modified_by'] = $userId;
|
||||
} else {
|
||||
$row->created_by = $userId;
|
||||
$db->insertObject('#__circolari', $row);
|
||||
$id = (int)$db->insertid();
|
||||
$data['created_by'] = $userId;
|
||||
}
|
||||
|
||||
return $id;
|
||||
// Sblocca/normalizza
|
||||
$data['checked_out'] = 0;
|
||||
$data['checked_out_time'] = null;
|
||||
|
||||
if (!$table->bind($data)) { throw new \RuntimeException($table->getError() ?: 'Bind failed'); }
|
||||
if (!$table->check()) { throw new \RuntimeException($table->getError() ?: 'Check failed'); }
|
||||
|
||||
// ordering se nuovo
|
||||
if (empty($table->id) || (int) $table->ordering === 0) {
|
||||
$db = \Joomla\CMS\Factory::getContainer()->get('DatabaseDriver');
|
||||
$max = (int) $db->setQuery(
|
||||
$db->getQuery(true)->select('COALESCE(MAX(ordering),0)')
|
||||
->from('#__circolari')
|
||||
->where('categoria_id=' . (int) ($table->categoria_id ?? 0))
|
||||
)->loadResult();
|
||||
$table->ordering = $max + 1;
|
||||
}
|
||||
|
||||
if (!$table->store()) { throw new \RuntimeException($table->getError() ?: 'Store failed'); }
|
||||
|
||||
return (int) $table->id;
|
||||
}
|
||||
|
||||
|
||||
private function createNewFirmatipo(string $nome, string $bottoniRiga): int
|
||||
{
|
||||
$db = Factory::getContainer()->get('DatabaseDriver');
|
||||
|
||||
@ -17,102 +17,99 @@ class Router extends RouterView
|
||||
{
|
||||
public function __construct(SiteApplication $app, AbstractMenu $menu)
|
||||
{
|
||||
// 1) CATEGORIA (se la usi nei percorsi)
|
||||
|
||||
// 2) LISTA (nessuna key!)
|
||||
// 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)
|
||||
// DETTAGLIO (ha key id)
|
||||
$circolare = new RouterViewConfiguration('circolare');
|
||||
$circolare->setKey('id')->setParent($circolari);
|
||||
$this->registerView($circolare);
|
||||
|
||||
// 4) FORM (se presente)
|
||||
// FORM (nessuna key)
|
||||
$form = new RouterViewConfiguration('form');
|
||||
$form->setParent($circolari);
|
||||
$this->registerView($form);
|
||||
|
||||
parent::__construct($app, $menu);
|
||||
|
||||
// Regole: prima Menu, poi Standard, poi NoMenu
|
||||
$this->attachRule(new MenuRules($this));
|
||||
$this->attachRule(new StandardRules($this));
|
||||
$this->attachRule(new NomenuRules($this));
|
||||
}
|
||||
|
||||
/* ---------------- BUILD ---------------- */
|
||||
// Pulisci la query quando costruisci gli URL
|
||||
public function build(&$query)
|
||||
{
|
||||
// Se sto costruendo 'form', non agganciare Itemid di altre view del componente
|
||||
if (($query['view'] ?? '') === 'form' && isset($query['Itemid'])) {
|
||||
$item = $this->menu->getItem((int) $query['Itemid']);
|
||||
if ($item && $item->component === 'com_circolari') {
|
||||
$v = is_array($item->query ?? null) ? ($item->query['view'] ?? '') : '';
|
||||
if ($v !== 'form') {
|
||||
unset($query['Itemid']); // evita override della view
|
||||
}
|
||||
}
|
||||
}
|
||||
// Lista: non appendere categorie in querystring
|
||||
if (($query['view'] ?? '') === 'circolari') {
|
||||
unset($query['categoria_id'], $query['catid'], $query['categories'], $query['categorie'], $query['category_id']);
|
||||
}
|
||||
|
||||
// Segmento categoria = alias (fallback id)
|
||||
if (($query['view'] ?? '') === 'form' && isset($query['Itemid'])) {
|
||||
$item = $this->menu->getItem((int) $query['Itemid']);
|
||||
if ($item && $item->component === 'com_circolari') {
|
||||
$v = is_array($item->query ?? null) ? ($item->query['view'] ?? '') : '';
|
||||
if ($v !== 'form') {
|
||||
unset($query['Itemid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::build($query);
|
||||
}
|
||||
|
||||
// Segmento dettaglio = alias (fallback id se vuoto)
|
||||
// Segmento dettaglio = alias (fallback id)
|
||||
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();
|
||||
|
||||
return [$alias !== '' ? $alias : (string) (int) $id];
|
||||
}
|
||||
|
||||
/* ---------------- PARSE ---------------- */
|
||||
|
||||
|
||||
// Parse del dettaglio: alias -> id (opz. con categoria)
|
||||
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));
|
||||
|
||||
if ($categoria_id > 0) {
|
||||
$q->where('categoria_id = ' . $categoria_id);
|
||||
if (!empty($query['categoria_id'])) {
|
||||
$q->where('categoria_id = ' . (int) $query['categoria_id']);
|
||||
}
|
||||
|
||||
$db->setQuery($q);
|
||||
$id = (int) $db->loadResult();
|
||||
|
||||
// fallback numerico sull’ultimo segmento
|
||||
if ($id === 0 && ctype_digit((string)$segment)) {
|
||||
// fallback numerico
|
||||
if ($id === 0 && ctype_digit((string) $segment)) {
|
||||
$id = (int) $segment;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
// ⬇️ AGGIUNGI in Pcrt\Component\Circolari\Site\Service\Router
|
||||
|
||||
// Rimuove categoria_id (ecc.) dalla LISTA prima che Joomla costruisca l’URL.
|
||||
// Così sparisce anche se il link della voce di menu in DB lo contiene ancora.
|
||||
public function build(&$query)
|
||||
{
|
||||
if (isset($query['view']) && $query['view'] === 'circolari') {
|
||||
foreach (['categoria_id', 'catid', 'categorie', 'categories', 'category_id'] as $k) {
|
||||
if (array_key_exists($k, $query)) {
|
||||
unset($query[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Se vuoi essere ultra-clean, rimuovi anche id/Itemid “sporchi” (non necessario di solito)
|
||||
// if (isset($query['view']) && $query['view'] === 'circolari' && isset($query['id'])) unset($query['id']);
|
||||
|
||||
return parent::build($query);
|
||||
}
|
||||
|
||||
// (Opzionale) Non reintrodurre variabili categoria in parse: la lista si filtra da params del menu.
|
||||
// (Opzionale) Non reintrodurre categorie in parse per la lista
|
||||
public function parse(&$segments)
|
||||
{
|
||||
$vars = parent::parse($segments);
|
||||
|
||||
if (isset($vars['view']) && $vars['view'] === 'circolari') {
|
||||
if (($vars['view'] ?? '') === 'circolari') {
|
||||
unset($vars['categoria_id'], $vars['catid'], $vars['categorie'], $vars['category_id']);
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Pcrt\Component\Circolari\Site\View\Form;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
@ -16,24 +15,14 @@ class HtmlView extends BaseHtmlView
|
||||
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$model = $this->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);
|
||||
$id = $app->input->getInt('id', 0);
|
||||
$this->item = $model->getItem($id);
|
||||
$this->categorie = $model->getCategorie();
|
||||
$this->firmetipi = $model->getFirmetipi();
|
||||
$this->bottoniMap = $model->getBottoniByFirmatipo();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
@ -48,6 +48,13 @@ if ($canAdmin) {
|
||||
|
||||
<div class="container my-5 mega-container">
|
||||
|
||||
<?php if ($canAdmin): ?>
|
||||
<a class="btn btn-primary"
|
||||
href="<?php echo \Joomla\CMS\Router\Route::_('index.php?option=com_circolari&task=form.display&id=' . (int)$this->item->id, false); ?>">
|
||||
Modifica Circolare
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row mb-4 align-items-end">
|
||||
<div class="col-md-9 col-12">
|
||||
<h1 class="h2 mb-1"><?= $this->escape($item->title); ?></h1>
|
||||
@ -109,15 +116,14 @@ if ($canAdmin) {
|
||||
<div class="card mt-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<strong>Firme ricevute</strong>
|
||||
<a class="btn btn-outline-secondary btn-sm"
|
||||
<a class="btn btn-outline-secondary btn-sm"
|
||||
href="<?=
|
||||
\Joomla\CMS\Router\Route::_(
|
||||
'index.php?option=com_circolari&task=circolare.exportFirme&id='.(int)$item->id.'&'.\Joomla\CMS\Session\Session::getFormToken().'=1'
|
||||
'index.php?option=com_circolari&task=circolare.exportFirme&id=' . (int)$item->id . '&' . \Joomla\CMS\Session\Session::getFormToken() . '=1'
|
||||
); ?>"
|
||||
download
|
||||
>
|
||||
download>
|
||||
Scarica Excel
|
||||
</a>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ $cancelUrl = $cancelItemId
|
||||
<div class="container py-3">
|
||||
<h2 class="mb-3"><?php echo Text::_('Nuova circolare'); ?></h2>
|
||||
|
||||
<form action="<?php echo $action; ?>" method="post" class="form-validate">
|
||||
<form action="<?php echo Route::_('index.php?option=com_circolari&task=form.save'); ?>" method="post" class="form-validate">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="title"><?php echo Text::_('Titolo'); ?></label>
|
||||
@ -131,8 +131,8 @@ $cancelUrl = $cancelItemId
|
||||
<a href="<?php echo $cancelUrl; ?>" class="btn btn-outline-secondary"><?php echo Text::_('Annulla'); ?></a>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="id" value="<?php echo (int) ($item->id ?? 0); ?>">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
<input type="hidden" name="id" value="<?php echo (int) ($this->item->id ?? 0); ?>">
|
||||
<?php echo \Joomla\CMS\HTML\HTMLHelper::_('form.token'); ?>
|
||||
|
||||
<script type="application/json" id="bottoni-map"><?php
|
||||
echo json_encode($this->bottoniMap ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
Reference in New Issue
Block a user