269 lines
9.1 KiB
PHP
269 lines
9.1 KiB
PHP
<?php
|
|
|
|
namespace Pcrt\Component\Circolari\Site\Model;
|
|
|
|
\defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\MVC\Model\ItemModel;
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\User\UserHelper;
|
|
use Joomla\CMS\Language\Text;
|
|
|
|
class CircolareModel extends ItemModel
|
|
{
|
|
protected function populateState()
|
|
{
|
|
$app = Factory::getApplication();
|
|
$id = $app->input->getInt('id', 0);
|
|
$this->setState('circolare.id', $id);
|
|
|
|
$categoria_id = $app->input->getInt('categoria_id', 0);
|
|
$this->setState('filter.categoria_id', $categoria_id);
|
|
parent::populateState();
|
|
}
|
|
|
|
public function getItem($pk = null)
|
|
{
|
|
$pk = (int) ($pk ?: $this->getState('circolare.id'));
|
|
|
|
if ($pk <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$db = $this->getDatabase();
|
|
$q = $db->getQuery(true)
|
|
->select('c.*')
|
|
->from($db->quoteName('#__circolari') . ' AS c')
|
|
->where('c.id = ' . (int) $pk);
|
|
|
|
// Se esistono le colonne, applica filtri
|
|
$cols = array_change_key_case(
|
|
$db->getTableColumns($db->replacePrefix('#__circolari'), false),
|
|
CASE_LOWER
|
|
);
|
|
|
|
// categoria_id (se impostato e colonna esiste)
|
|
$categoria_id = (int) $this->getState('filter.categoria_id', 0);
|
|
if ($categoria_id > 0 && isset($cols['categoria_id'])) {
|
|
$q->where('c.categoria_id = ' . $categoria_id);
|
|
}
|
|
|
|
// stato (se colonna esiste)
|
|
if (isset($cols['state'])) {
|
|
$q->where('COALESCE(c.state, 1) = 1');
|
|
}
|
|
|
|
$db->setQuery($q);
|
|
$row = $db->loadObject();
|
|
|
|
return $row ?: null;
|
|
}
|
|
|
|
public function getBottoniFirma(int $firmatipoId): array
|
|
{
|
|
$buttons = []; // <- sempre inizializzato
|
|
|
|
if ($firmatipoId <= 0) {
|
|
return $buttons;
|
|
}
|
|
|
|
$db = Factory::getContainer()->get('DatabaseDriver');
|
|
|
|
// 1) Tabella relazionale
|
|
$q = $db->getQuery(true)
|
|
->select($db->quoteName(['id', 'label']))
|
|
->from($db->quoteName('#__circolari_firmetipi_bottoni'))
|
|
->where($db->quoteName('firmatipo_id') . ' = ' . (int) $firmatipoId)
|
|
->order($db->escape('ordering ASC, id ASC'));
|
|
$db->setQuery($q);
|
|
$buttons = (array) $db->loadObjectList();
|
|
|
|
// 2) Fallback JSON
|
|
if (!$buttons) {
|
|
$q2 = $db->getQuery(true)
|
|
->select($db->quoteName('bottoni_firma'))
|
|
->from($db->quoteName('#__circolari_firmetipi'))
|
|
->where($db->quoteName('id') . ' = ' . (int) $firmatipoId);
|
|
$db->setQuery($q2);
|
|
$json = (string) $db->loadResult();
|
|
|
|
if ($json) {
|
|
$rows = json_decode($json, true) ?: [];
|
|
foreach ($rows as $r) {
|
|
$label = trim((string) ($r['etichetta'] ?? ''));
|
|
if ($label !== '') {
|
|
$buttons[] = (object) ['id' => 0, 'label' => $label];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $buttons;
|
|
}
|
|
|
|
public function userCanFirmare(int $circolareId, ?int $userId = null): bool
|
|
{
|
|
$user = Factory::getUser($userId);
|
|
if ($user->guest) {
|
|
return false;
|
|
}
|
|
|
|
// Gruppi (inclusa ereditarietà). In J4/J5 puoi usare UserHelper::getUserGroups
|
|
$userGroups = array_map('intval', UserHelper::getUserGroups($user->id));
|
|
if (!$userGroups) {
|
|
return false;
|
|
}
|
|
|
|
$db = Factory::getContainer()->get('DatabaseDriver');
|
|
|
|
$q = $db->getQuery(true)
|
|
->select('COUNT(*)')
|
|
->from($db->quoteName('#__circolari_usergroups'))
|
|
->where($db->quoteName('circolare_id') . ' = ' . (int) $circolareId)
|
|
->where($db->quoteName('usergroup_id') . ' IN (' . implode(',', $userGroups) . ')');
|
|
|
|
$db->setQuery($q);
|
|
return ((int) $db->loadResult()) > 0;
|
|
}
|
|
|
|
|
|
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.
|
|
*/
|
|
public function hit($pk = null)
|
|
{
|
|
$pk = $pk ?: (int) $this->getState($this->getName() . '.id');
|
|
if (!$pk) {
|
|
return false;
|
|
}
|
|
$db = $this->getDatabase();
|
|
$query = $db->getQuery(true)
|
|
->update($db->quoteName('#__circolari'))
|
|
->set($db->quoteName('hits') . ' = ' . $db->quoteName('hits') . ' + 1')
|
|
->where($db->quoteName('id') . ' = ' . (int)$pk);
|
|
$db->setQuery($query)->execute();
|
|
return true;
|
|
}
|
|
}
|