Report & excel frontend & admin
This commit is contained in:
43
administrator/forms/filter_reportfirme.xml
Normal file
43
administrator/forms/filter_reportfirme.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<form>
|
||||
<!-- Gruppo FILTRI -->
|
||||
<fields name="filter">
|
||||
<field name="search" type="text"
|
||||
label="JSEARCH_FILTER"
|
||||
description="JSEARCH_FILTER_DESC"
|
||||
hint="Ricerca per utente/email/titolo" />
|
||||
<field name="circolare_id" type="sql"
|
||||
label="Circolare"
|
||||
query="SELECT id AS value, title AS text FROM #__circolari ORDER BY title ASC"
|
||||
key_field="value" value_field="text"
|
||||
default="0" >
|
||||
<option value="0">- Tutte -</option>
|
||||
</field>
|
||||
<field name="scelta" type="sql"
|
||||
label="Scelta"
|
||||
query="SELECT DISTINCT COALESCE(f.firma_label, b.label) AS value
|
||||
FROM #__circolari_firme f
|
||||
LEFT JOIN #__circolari_firmetipi_bottoni b ON b.id = f.firmatipo_bottone_id
|
||||
WHERE COALESCE(f.firma_label, b.label) IS NOT NULL
|
||||
ORDER BY value ASC"
|
||||
key_field="value" value_field="value"
|
||||
default="">
|
||||
<option value="">- Tutte -</option>
|
||||
</field>
|
||||
<field name="date_from" type="calendar" label="Dalla data" format="%Y-%m-%d"/>
|
||||
<field name="date_to" type="calendar" label="Alla data" format="%Y-%m-%d"/>
|
||||
</fields>
|
||||
|
||||
<!-- Gruppo LIST (ordinamento/paginazione) -->
|
||||
<fields name="list">
|
||||
<field name="fullordering" type="list" label="JGLOBAL_SORT_BY" default="f.data_firma DESC">
|
||||
<option value="f.data_firma DESC">Data ↓</option>
|
||||
<option value="f.data_firma ASC">Data ↑</option>
|
||||
<option value="u.name ASC">Nome ↑</option>
|
||||
<option value="u.name DESC">Nome ↓</option>
|
||||
<option value="c.title ASC">Circolare ↑</option>
|
||||
<option value="c.title DESC">Circolare ↓</option>
|
||||
</field>
|
||||
<field name="limit" type="limitbox" default="20"/>
|
||||
</fields>
|
||||
</form>
|
||||
75
administrator/src/Controller/ReportfirmeController.php
Normal file
75
administrator/src/Controller/ReportfirmeController.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
namespace Pcrt\Component\Circolari\Administrator\Controller;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
|
||||
class ReportfirmeController extends BaseController
|
||||
{
|
||||
public function exportCsv()
|
||||
{
|
||||
if (!\Joomla\CMS\Session\Session::checkToken('get')) {
|
||||
throw new \RuntimeException(\Joomla\CMS\Language\Text::_('JINVALID_TOKEN'), 403);
|
||||
}
|
||||
|
||||
$app = \Joomla\CMS\Factory::getApplication();
|
||||
$user = $app->getIdentity();
|
||||
|
||||
if (!$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\Administrator\Model\ReportfirmeModel $model */
|
||||
$model = $this->getModel('Reportfirme', 'Administrator');
|
||||
|
||||
// ✅ Inizializza lo state (richiama internamente populateState())
|
||||
$model->getState();
|
||||
|
||||
// ✅ Esporta TUTTI i risultati che rispettano i filtri correnti (niente paginazione)
|
||||
$model->setState('list.start', 0);
|
||||
$model->setState('list.limit', 0);
|
||||
|
||||
// Prendi i dati
|
||||
$rows = $model->getItems();
|
||||
|
||||
// Pulisci output e invia header per download
|
||||
while (ob_get_level() > 0) { @ob_end_clean(); }
|
||||
|
||||
$filename = 'report_firme_' . date('Ymd_His') . '.csv';
|
||||
$app->clearHeaders();
|
||||
$app->setHeader('Content-Description', 'File Transfer', true);
|
||||
$app->setHeader('Content-Type', 'application/vnd.ms-excel; charset=utf-8', true);
|
||||
$app->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"', true);
|
||||
$app->setHeader('Content-Transfer-Encoding', 'binary', true);
|
||||
$app->setHeader('Expires', '0', true);
|
||||
$app->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true);
|
||||
$app->setHeader('Pragma', 'public', true);
|
||||
$app->sendHeaders();
|
||||
|
||||
// CSV con BOM UTF-8, separatore ';'
|
||||
$out = fopen('php://output', 'w');
|
||||
fwrite($out, chr(0xEF).chr(0xBB).chr(0xBF));
|
||||
fputcsv($out, ['ID','Circolare','ID Utente','Nome','Username','Email','Scelta','Data firma'], ';');
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$date = \Joomla\CMS\Factory::getDate($r->data_firma)->format('d/m/Y H:i');
|
||||
fputcsv($out, [
|
||||
$r->id,
|
||||
$r->circolare_title,
|
||||
$r->user_id,
|
||||
$r->user_name,
|
||||
$r->username,
|
||||
$r->email,
|
||||
$r->scelta_label, // ✅ nessun uso di f.firma
|
||||
$date,
|
||||
], ';');
|
||||
}
|
||||
|
||||
fclose($out);
|
||||
$app->close();
|
||||
}
|
||||
|
||||
}
|
||||
92
administrator/src/Model/ReportfirmeModel.php
Normal file
92
administrator/src/Model/ReportfirmeModel.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
namespace Pcrt\Component\Circolari\Administrator\Model;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Model\ListModel;
|
||||
|
||||
class ReportfirmeModel extends ListModel
|
||||
{
|
||||
protected $filter_fields = ['f.data_firma','u.name','c.title','f.id','scelta_label'];
|
||||
|
||||
protected function populateState($ordering = 'f.data_firma', $direction = 'DESC')
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
$this->setState('filter.search', $app->getUserStateFromRequest($this->context.'.filter.search', 'filter_search', '', 'string'));
|
||||
$this->setState('filter.circolare_id', $app->getUserStateFromRequest($this->context.'.filter.circolare_id', 'filter_circolare_id', 0, 'int'));
|
||||
$this->setState('filter.scelta', $app->getUserStateFromRequest($this->context.'.filter.scelta', 'filter_scelta', '', 'string'));
|
||||
$this->setState('filter.date_from', $app->getUserStateFromRequest($this->context.'.filter.date_from', 'filter_date_from', '', 'string'));
|
||||
$this->setState('filter.date_to', $app->getUserStateFromRequest($this->context.'.filter.date_to', 'filter_date_to', '', 'string'));
|
||||
|
||||
parent::populateState($ordering, $direction);
|
||||
}
|
||||
|
||||
protected function getListQuery()
|
||||
{
|
||||
$db = $this->getDatabase();
|
||||
$q = $db->getQuery(true);
|
||||
|
||||
$q->select([
|
||||
'f.id','f.circolare_id','f.user_id','f.data_firma',
|
||||
'u.name AS user_name','u.username','u.email',
|
||||
'c.title AS circolare_title',
|
||||
'f.firma_label',
|
||||
'b.label AS bottone_label',
|
||||
// scelta normalizzata: prima firma_label (copia al momento della firma), altrimenti label del bottone
|
||||
'COALESCE(f.firma_label, b.label) AS scelta_label',
|
||||
])
|
||||
->from($db->quoteName('#__circolari_firme','f'))
|
||||
->join('INNER', $db->quoteName('#__users','u') . ' ON u.id = f.user_id')
|
||||
->join('INNER', $db->quoteName('#__circolari','c') . ' ON c.id = f.circolare_id')
|
||||
->join('LEFT', $db->quoteName('#__circolari_firmetipi_bottoni','b') . ' ON b.id = f.firmatipo_bottone_id');
|
||||
|
||||
// Filtri
|
||||
$search = (string) $this->getState('filter.search', '');
|
||||
if ($search !== '') {
|
||||
$like = $db->quote('%' . $db->escape($search, true) . '%');
|
||||
$q->where('('
|
||||
. 'u.name LIKE ' . $like
|
||||
. ' OR u.username LIKE ' . $like
|
||||
. ' OR u.email LIKE ' . $like
|
||||
. ' OR c.title LIKE ' . $like
|
||||
. ')');
|
||||
}
|
||||
|
||||
$circolareId = (int) $this->getState('filter.circolare_id', 0);
|
||||
if ($circolareId > 0) {
|
||||
$q->where('f.circolare_id = ' . (int)$circolareId);
|
||||
}
|
||||
|
||||
$scelta = (string) $this->getState('filter.scelta', '');
|
||||
if ($scelta !== '') {
|
||||
$q->where('(f.firma_label = ' . $db->quote($scelta) . ' OR b.label = ' . $db->quote($scelta) . ')');
|
||||
}
|
||||
|
||||
$from = (string) $this->getState('filter.date_from', '');
|
||||
if ($from !== '') {
|
||||
$q->where('f.data_firma >= ' . $db->quote($from . ' 00:00:00'));
|
||||
}
|
||||
$to = (string) $this->getState('filter.date_to', '');
|
||||
if ($to !== '') {
|
||||
$q->where('f.data_firma <= ' . $db->quote($to . ' 23:59:59'));
|
||||
}
|
||||
|
||||
// Ordinamento
|
||||
$orderCol = $this->state->get('list.ordering', 'f.data_firma');
|
||||
$orderDirn = $this->state->get('list.direction', 'DESC');
|
||||
$q->order($db->escape($orderCol . ' ' . $orderDirn));
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
public function getItems()
|
||||
{
|
||||
$rows = parent::getItems();
|
||||
foreach ($rows as $r) {
|
||||
$r->scelta_label = $r->scelta_label ?: '-';
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
27
administrator/src/View/Reportfirme/HtmlView.php
Normal file
27
administrator/src/View/Reportfirme/HtmlView.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace Pcrt\Component\Circolari\Administrator\View\Reportfirme;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
// DEVONO essere public perché i layout core vi accedono direttamente
|
||||
public $items;
|
||||
public $state;
|
||||
public $pagination;
|
||||
public $filterForm;
|
||||
public $activeFilters;
|
||||
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->state = $this->get('State');
|
||||
$this->items = $this->get('Items');
|
||||
$this->pagination = $this->get('Pagination');
|
||||
$this->filterForm = $this->get('FilterForm'); // JForm dei filtri (forms/filter_reportfirme.xml)
|
||||
$this->activeFilters = $this->get('ActiveFilters');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
58
administrator/tmpl/reportfirme/default.php
Normal file
58
administrator/tmpl/reportfirme/default.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Session\Session;
|
||||
|
||||
$listOrder = $this->state->get('list.ordering', 'f.data_firma');
|
||||
$listDirn = $this->state->get('list.direction', 'DESC');
|
||||
|
||||
// Carica CSS base
|
||||
HTMLHelper::_('bootstrap.tooltip');
|
||||
HTMLHelper::_('behavior.multiselect');
|
||||
HTMLHelper::_('formbehavior.chosen', 'select');
|
||||
?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_circolari&view=reportfirme'); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<div id="j-main-container" class="j-main-container">
|
||||
<?php echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this]); ?>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo HTMLHelper::_('grid.sort', 'ID', 'f.id', $listDirn, $listOrder); ?></th>
|
||||
<th><?php echo HTMLHelper::_('grid.sort', 'Circolare', 'c.title', $listDirn, $listOrder); ?></th>
|
||||
<th><?php echo HTMLHelper::_('grid.sort', 'Nome', 'u.name', $listDirn, $listOrder); ?></th>
|
||||
<th>Username</th>
|
||||
<th>Email</th>
|
||||
<th><?php echo HTMLHelper::_('grid.sort', 'Scelta', 'scelta_label', $listDirn, $listOrder); ?></th>
|
||||
<th><?php echo HTMLHelper::_('grid.sort', 'Data firma', 'f.data_firma', $listDirn, $listOrder); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($this->items)) : ?>
|
||||
<tr><td colspan="7" class="text-center text-muted">Nessun risultato</td></tr>
|
||||
<?php else : ?>
|
||||
<?php foreach ($this->items as $i => $item) : ?>
|
||||
<tr>
|
||||
<td><?php echo (int) $item->id; ?></td>
|
||||
<td><?php echo $this->escape($item->circolare_title); ?></td>
|
||||
<td><?php echo $this->escape($item->user_name); ?></td>
|
||||
<td><?php echo $this->escape($item->username); ?></td>
|
||||
<td><?php echo $this->escape($item->email); ?></td>
|
||||
<td><span class="badge bg-secondary"><?php echo $this->escape($item->scelta_label); ?></span></td>
|
||||
<td><?php echo HTMLHelper::_('date', $item->data_firma, 'd/m/Y H:i'); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php echo $this->pagination->getListFooter(); ?>
|
||||
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</form>
|
||||
Reference in New Issue
Block a user