visualizzazione e gestione firme e lista firme con ACL
This commit is contained in:
@ -1,13 +1,49 @@
|
||||
<?php
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Session\Session;
|
||||
|
||||
/** @var \Pcrt\Component\Circolari\Site\View\Circolare\HtmlView $this */
|
||||
$app = Factory::getApplication();
|
||||
$user = $app->getIdentity();
|
||||
$model = method_exists($this, 'getModel') ? $this->getModel('Circolare') : null;
|
||||
$item = $this->item;
|
||||
|
||||
$canAdmin = $user->authorise('core.admin', 'com_circolari') || $user->authorise('core.manage', 'com_circolari');
|
||||
|
||||
// Firma dell'utente (se esiste)
|
||||
$firma = ($model && !$user->guest) ? $model->getFirmaUtente((int)$item->id, (int)$user->id) : null;
|
||||
$hasVoted = (bool) $firma;
|
||||
|
||||
// Helper per confrontare anche in caso di schema ENUM
|
||||
$slugify = function (string $s): string {
|
||||
$s = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
|
||||
$s = strtolower($s);
|
||||
$s = preg_replace('~[^a-z0-9]+~', '_', $s);
|
||||
return trim($s, '_');
|
||||
};
|
||||
|
||||
$selectedBtnId = isset($firma->firmatipo_bottone_id) ? (int)$firma->firmatipo_bottone_id : 0;
|
||||
$selectedEnum = isset($firma->firma_enum) ? (string)$firma->firma_enum : '';
|
||||
$buttons = $this->getModel()->getBottoniFirma((int)$item->tipologia_firma_id);
|
||||
|
||||
$firme = [];
|
||||
if ($canAdmin) {
|
||||
$model = method_exists($this, 'getModel') ? $this->getModel('Circolare') : null;
|
||||
if (!$model) {
|
||||
// fallback creazione model via MVCFactory se necessario
|
||||
try {
|
||||
$factory = $app->bootComponent('com_circolari')->getMVCFactory();
|
||||
$model = $factory->createModel('Circolare', 'Site', ['ignore_request' => true]);
|
||||
} catch (\Throwable $e) {
|
||||
$model = null;
|
||||
}
|
||||
}
|
||||
$firme = $model ? $model->getFirmeCircolare((int)$item->id) : [];
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="container my-5 mega-container">
|
||||
@ -23,11 +59,42 @@ $buttons = $this->getModel()->getBottoniFirma((int)$item->tipologia_firma_id);
|
||||
|
||||
<?php if ($item->firma_obbligatoria && $this->getModel()->userCanFirmare($item->id, $this->getModel()->currentUser->id) && !empty($buttons)) : ?>
|
||||
<div class="mt-4">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<?php foreach ($buttons as $btn) : ?>
|
||||
<button type="button" class="btn btn-primary btn-sm">
|
||||
<?php echo htmlspecialchars($btn->label, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</button>
|
||||
<div class="d-flex flex-wrap gap-2" data-sign-group="circolare-<?php echo (int)$item->id; ?>">
|
||||
<?php foreach ($buttons as $btn) :
|
||||
$btnId = (int) $btn->id;
|
||||
$isSelected =
|
||||
($selectedBtnId > 0 && $selectedBtnId === $btnId)
|
||||
|| ($selectedEnum !== '' && in_array($selectedEnum, [
|
||||
$slugify($btn->label),
|
||||
str_replace('-', '_', $slugify($btn->label)), // normalizza trattini→underscore
|
||||
], true));
|
||||
|
||||
// Classi bootstrap: selezionato = "success", altri disattivi = outline-secondary
|
||||
$btnClasses = 'btn btn-sm ' . ($isSelected ? 'btn-success' : ($hasVoted ? 'btn-outline-secondary' : 'btn-primary'));
|
||||
?>
|
||||
|
||||
<?php if ($hasVoted): ?>
|
||||
<button type="button"
|
||||
class="<?php echo $btnClasses; ?> opacity-75"
|
||||
disabled
|
||||
aria-disabled="true"
|
||||
title="<?php echo $isSelected ? $this->escape(Text::_('Hai già scelto questo')) : $this->escape(Text::_('Hai già firmato')); ?>">
|
||||
<?php echo htmlspecialchars($btn->label, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<form method="post"
|
||||
action="<?=
|
||||
Route::_('index.php?option=com_circolari&task=circolare.sign&id=' . (int)$item->id); ?>"
|
||||
class="d-inline-block">
|
||||
<input type="hidden" name="bottone_id" value="<?php echo $btnId; ?>">
|
||||
<button type="submit"
|
||||
class="<?php echo $btnClasses; ?> js-sign-btn">
|
||||
<?php echo htmlspecialchars($btn->label, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</button>
|
||||
<?= HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -37,4 +104,83 @@ $buttons = $this->getModel()->getBottoniFirma((int)$item->tipologia_firma_id);
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php 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"
|
||||
href="<?=
|
||||
\Joomla\CMS\Router\Route::_(
|
||||
'index.php?option=com_circolari&task=circolare.exportFirme&id='.(int)$item->id.'&'.\Joomla\CMS\Session\Session::getFormToken().'=1'
|
||||
); ?>"
|
||||
download
|
||||
>
|
||||
Scarica Excel
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm mb-0 align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nome</th>
|
||||
<th class="text-muted">Username</th>
|
||||
<th>Scelta</th>
|
||||
<th class="text-end">Data</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($firme)) : ?>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-muted py-3">Nessuna firma registrata.</td>
|
||||
</tr>
|
||||
<?php else : ?>
|
||||
<?php foreach ($firme as $r) : ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($r['user_name'], ENT_QUOTES, 'UTF-8'); ?></td>
|
||||
<td class="text-muted"><?php echo htmlspecialchars($r['username'], ENT_QUOTES, 'UTF-8'); ?></td>
|
||||
<td>
|
||||
<span class="badge bg-secondary"><?php echo htmlspecialchars($r['scelta_label'], ENT_QUOTES, 'UTF-8'); ?></span>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<?php echo htmlspecialchars(Factory::getDate($r['data_firma'])->format('d/m/Y H:i'), ENT_QUOTES, 'UTF-8'); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<?php if (!$hasVoted): ?>
|
||||
<script>
|
||||
(function() {
|
||||
var container = document.querySelector('[data-sign-group="circolare-<?php echo (int)$item->id; ?>"]');
|
||||
if (!container) return;
|
||||
container.addEventListener('submit', function(e) {
|
||||
var form = e.target.closest('form');
|
||||
if (!form) return;
|
||||
var clickedBtn = form.querySelector('button');
|
||||
var allBtns = container.querySelectorAll('button');
|
||||
allBtns.forEach(function(b) {
|
||||
b.classList.remove('btn-primary');
|
||||
b.classList.add('btn-outline-secondary');
|
||||
b.setAttribute('disabled', 'disabled');
|
||||
b.setAttribute('aria-disabled', 'true');
|
||||
b.classList.add('opacity-75');
|
||||
});
|
||||
if (clickedBtn) {
|
||||
clickedBtn.classList.remove('btn-outline-secondary', 'opacity-75');
|
||||
clickedBtn.classList.add('btn-success');
|
||||
}
|
||||
}, true); // usa capture per intercettare subito
|
||||
})();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
@ -1,44 +1,85 @@
|
||||
<?php
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var \Pcrt\Component\Circolari\Site\View\Circolare\HtmlView $this */
|
||||
$item = $this->item;
|
||||
dump($item);
|
||||
$app = Factory::getApplication();
|
||||
$input = $app->getInput();
|
||||
|
||||
$buttons = $this->getModel()->getBottoniFirma((int)$item->tipologia_firma_id);
|
||||
dump($this->getModel()->currentUser);
|
||||
// Prendo dati dalla view con fallback ai getter
|
||||
$items = $this->items ?? ($this->get('Items') ?? []);
|
||||
$pagination = $this->pagination ?? ($this->get('Pagination') ?? null);
|
||||
|
||||
// Normalizzo 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);
|
||||
?>
|
||||
<div class="circolari-list">
|
||||
|
||||
<div class="container my-5 mega-container">
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-3 col-12 text-md-end mt-2 mt-md-0">
|
||||
<a href="#" class="small text-decoration-none text-uppercase fw-bold">Condividi</a>
|
||||
<?php if (!count($items)) : ?>
|
||||
<div class="alert alert-info">
|
||||
<span class="icon-info-circle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
|
||||
<?php echo Text::_('COM_CIRCOLARI_NO_ITEMS') ?: 'Nessuna circolare'; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( $item->firma_obbligatoria && !empty($buttons)) : ?>
|
||||
<div class="mt-4">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<?php foreach ($buttons as $btn) : ?>
|
||||
<button type="button" class="btn btn-primary btn-sm">
|
||||
<?php echo htmlspecialchars($btn->label, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</button>
|
||||
<?php else : ?>
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<caption class="visually-hidden"><?php echo Text::_('COM_CIRCOLARI_ELENCO') ?: 'Elenco circolari'; ?></caption>
|
||||
<thead class="visually-hidden">
|
||||
<tr>
|
||||
<th scope="col">Titolo</th>
|
||||
<th scope="col" class="text-end">Visite</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($items as $i => $item) : ?>
|
||||
<?php
|
||||
$url = Route::_(
|
||||
'index.php?option=com_circolari&view=circolare'
|
||||
. '&id=' . (int) $item->id
|
||||
. '&catid=' . (int) ($item->catid ?? 0)
|
||||
. ($Itemid ? '&Itemid=' . $Itemid : '')
|
||||
);
|
||||
$title = $item->title ?? ('#' . (int) $item->id);
|
||||
$hits = isset($item->hits) ? (int) $item->hits : null;
|
||||
?>
|
||||
<tr class="cat-list-row<?php echo $i % 2; ?>">
|
||||
<th class="list-title" scope="row">
|
||||
<a href="<?php echo $url; ?>">
|
||||
<?php echo htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</a>
|
||||
</th>
|
||||
<td class="text-end">
|
||||
<?php if ($hits !== null) : ?>
|
||||
<span class="btn btn-secondary btn-sm disabled" aria-disabled="true">
|
||||
<?php echo Text::_('JGLOBAL_HITS') ?: 'Visite'; ?>: <?php echo $hits; ?>
|
||||
</span>
|
||||
<?php else : ?>
|
||||
<span class="text-muted">—</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="article-body mt-3">
|
||||
<?php echo $item->description ?: $item->testo ?: $item->descrizione ?: '<em>(Nessun testo)</em>'; ?>
|
||||
</div>
|
||||
</div>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
<?php if ($pagination && (int) $pagination->pagesTotal > 1) : ?>
|
||||
<div class="com-content-category__navigation w-100">
|
||||
<div class="d-flex align-items-center mt-2">
|
||||
<div class="flex-grow-1 d-flex justify-content-center">
|
||||
<?php echo $pagination->getPagesLinks(); ?>
|
||||
</div>
|
||||
<p class="com-content-category__counter counter mb-0 ps-3">
|
||||
<?php echo $pagination->getPagesCounter(); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user