visualizzazione e gestione firme e lista firme con ACL

This commit is contained in:
2025-09-05 15:35:03 +02:00
parent 835e123444
commit 9b7f845414
5 changed files with 606 additions and 39 deletions

View File

@ -7,6 +7,7 @@ namespace Pcrt\Component\Circolari\Site\Model;
use Joomla\CMS\MVC\Model\ItemModel;
use Joomla\CMS\Factory;
use Joomla\CMS\User\UserHelper;
use Joomla\CMS\Language\Text;
class CircolareModel extends ItemModel
{
@ -31,7 +32,7 @@ class CircolareModel extends ItemModel
$db = $this->getDatabase();
$q = $db->getQuery(true)
->select('c.*') // <<< evita errori di colonne
->select('c.*')
->from($db->quoteName('#__circolari') . ' AS c')
->where('c.id = ' . (int) $pk);
@ -126,6 +127,127 @@ class CircolareModel extends ItemModel
}
public function bottoneValidoPerCircolare(int $circolareId, int $bottoneId): bool
{
$db = Factory::getContainer()->get('DatabaseDriver');
$q = $db->getQuery(true)
->select('1')
->from($db->quoteName('#__circolari', 'c'))
->join('INNER', $db->quoteName('#__circolari_firmetipi_bottoni', 'b')
. ' ON ' . $db->quoteName('b.firmatipo_id') . ' = ' . $db->quoteName('c.tipologia_firma_id'))
->where($db->quoteName('c.id') . ' = ' . (int) $circolareId)
->where($db->quoteName('b.id') . ' = ' . (int) $bottoneId);
$db->setQuery($q, 0, 1);
return (bool) $db->loadResult();
}
public function insertFirma(int $circolareId, int $userId, int $bottoneId): bool
{
$db = Factory::getContainer()->get('DatabaseDriver');
$now = Factory::getDate()->toSql();
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
$columns = ['circolare_id', 'user_id', 'firmatipo_bottone_id', 'signed_at', 'ip'];
$values = [
(int) $circolareId,
(int) $userId,
(int) $bottoneId,
$db->quote($now),
$db->quote($ip)
];
$q = $db->getQuery(true)
->insert($db->quoteName('#__circolari_firme'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
try {
$db->setQuery($q)->execute();
} catch (\RuntimeException $e) {
// 1062 = duplicate key (violazione UNIQUE circolare_id+user_id)
if ((int) $e->getCode() === 1062 || stripos($e->getMessage(), 'Duplicate') !== false) {
throw new \RuntimeException(Text::_('COM_CIRCOLARI_ERR_ALREADY_SIGNED'), 409);
}
throw $e;
}
return true;
}
public function getFirmaUtente(int $circolareId, int $userId): ?object
{
if ($circolareId <= 0 || $userId <= 0) {
return null;
}
$db = Factory::getContainer()->get('DatabaseDriver');
// Schema compatibile con entrambe le versioni (ENUM "firma" oppure nuovo schema con firmatipo_bottone_id/firma_label)
$q = $db->getQuery(true)
->select($db->quoteName(['id', 'circolare_id', 'user_id']))
->select('' . $db->quoteName('firmatipo_bottone_id') . ' AS firmatipo_bottone_id')
->select('' . $db->quoteName('firma_label') . ' AS firma_label')
//->select('' . $db->quoteName('firma') . ' AS firma_enum')
->from($db->quoteName('#__circolari_firme'))
->where($db->quoteName('circolare_id') . ' = ' . (int)$circolareId)
->where($db->quoteName('user_id') . ' = ' . (int)$userId);
$db->setQuery($q, 0, 1);
$row = $db->loadObject();
return $row ?: null;
}
public function getFirmeCircolare(int $circolareId): array
{
if ($circolareId <= 0) {
return [];
}
$db = Factory::getContainer()->get('DatabaseDriver');
// Rileva le colonne della tabella firme (schema nuovo vs enum)
$cols = array_change_key_case($db->getTableColumns('#__circolari_firme', false));
$hasBtn = isset($cols['firmatipo_bottone_id']);
$hasLabel = isset($cols['firma_label']);
$hasEnum = isset($cols['firma']);
$q = $db->getQuery(true)
->select([
'f.id',
'f.circolare_id',
'f.user_id',
'f.data_firma',
($hasLabel ? 'f.firma_label' : 'NULL') . ' AS firma_label',
($hasEnum ? 'f.firma' : 'NULL') . ' AS firma_enum'
])
->from($db->quoteName('#__circolari_firme', 'f'))
->join('INNER', $db->quoteName('#__users', 'u') . ' ON u.id = f.user_id')
->select('u.name AS user_name, u.username, u.email')
->where('f.circolare_id = ' . (int) $circolareId)
->order('f.data_firma DESC');
if ($hasBtn) {
$q->select('b.label AS bottone_label')
->join('LEFT', $db->quoteName('#__circolari_firmetipi_bottoni', 'b') . ' ON b.id = f.firmatipo_bottone_id');
} else {
$q->select('NULL AS bottone_label');
}
$db->setQuery($q);
$rows = (array) $db->loadAssocList();
// Post-processing: normalizza la label scelta
foreach ($rows as &$r) {
$label = $r['firma_label'] ?: $r['bottone_label'] ?: $r['firma_enum'];
if ($label && $label === $r['firma_enum']) {
$label = ucwords(str_replace('_', ' ', $label)); // enum -> "Presa Visione"
}
$r['scelta_label'] = $label ?: '-';
}
unset($r);
return $rows;
}
/**
* Incrementa gli hits della circolare.
*/