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>
|
||||||
@ -10,9 +10,8 @@
|
|||||||
<version>1.1.7</version>
|
<version>1.1.7</version>
|
||||||
<description></description>
|
<description></description>
|
||||||
<namespace path="src">Pcrt\Component\Circolari</namespace>
|
<namespace path="src">Pcrt\Component\Circolari</namespace>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<install> <!-- Runs on install -->
|
<install> <!-- Runs on install -->
|
||||||
<sql>
|
<sql>
|
||||||
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
|
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
|
||||||
@ -29,7 +28,6 @@
|
|||||||
</sql>
|
</sql>
|
||||||
</uninstall>
|
</uninstall>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<files folder="site">
|
<files folder="site">
|
||||||
<folder>src</folder>
|
<folder>src</folder>
|
||||||
@ -42,18 +40,22 @@
|
|||||||
<filename>joomla.asset.json</filename>
|
<filename>joomla.asset.json</filename>
|
||||||
</media>
|
</media>
|
||||||
<languages folder="site/languages">
|
<languages folder="site/languages">
|
||||||
|
|
||||||
<language tag="en-GB">en-GB/com_circolari.ini</language>
|
<language tag="en-GB">en-GB/com_circolari.ini</language>
|
||||||
<language tag="it-IT">it-IT/com_circolari.ini</language>
|
<language tag="it-IT">it-IT/com_circolari.ini</language>
|
||||||
</languages>
|
</languages>
|
||||||
<administration>
|
<administration>
|
||||||
|
|
||||||
<menu>COM_CIRCOLARI</menu>
|
<menu>COM_CIRCOLARI</menu>
|
||||||
<submenu>
|
<submenu>
|
||||||
<menu link="option=com_circolari&view=circolares" view="circolares" alt="Circolari/Circolares">COM_CIRCOLARI_TITLE_CIRCOLARES</menu>
|
<menu link="option=com_circolari&view=circolares" view="circolares"
|
||||||
<menu link="option=com_circolari&view=firmetipi" view="firmetipi" alt="Circolari/Firmetipi">COM_CIRCOLARI_TITLE_FIRMETIPI</menu>
|
alt="Circolari/Circolares">COM_CIRCOLARI_TITLE_CIRCOLARES</menu>
|
||||||
<menu link="option=com_circolari&view=categorie">COM_CIRCOLARI_TITLE_CATEGORIE</menu>
|
<menu link="option=com_circolari&view=firmetipi" view="firmetipi"
|
||||||
</submenu>
|
alt="Circolari/Firmetipi">COM_CIRCOLARI_TITLE_FIRMETIPI</menu>
|
||||||
|
<menu link="option=com_circolari&view=categorie">COM_CIRCOLARI_TITLE_CATEGORIE</menu>
|
||||||
|
<menu link="option=com_circolari&view=reportfirme" view="reportfirme">Report Firme</menu>
|
||||||
|
|
||||||
|
</submenu>
|
||||||
|
|
||||||
<files folder="administrator">
|
<files folder="administrator">
|
||||||
<filename>access.xml</filename>
|
<filename>access.xml</filename>
|
||||||
@ -66,11 +68,11 @@
|
|||||||
<folder>sql</folder>
|
<folder>sql</folder>
|
||||||
</files>
|
</files>
|
||||||
<languages folder="administrator/languages">
|
<languages folder="administrator/languages">
|
||||||
|
|
||||||
<language tag="en-GB">en-GB/com_circolari.ini</language>
|
<language tag="en-GB">en-GB/com_circolari.ini</language>
|
||||||
<language tag="en-GB">en-GB/com_circolari.sys.ini</language>
|
<language tag="en-GB">en-GB/com_circolari.sys.ini</language>
|
||||||
<language tag="it-IT">it-IT/com_circolari.ini</language>
|
<language tag="it-IT">it-IT/com_circolari.ini</language>
|
||||||
<language tag="it-IT">it-IT/com_circolari.sys.ini</language>
|
<language tag="it-IT">it-IT/com_circolari.sys.ini</language>
|
||||||
</languages>
|
</languages>
|
||||||
</administration>
|
</administration>
|
||||||
<config>
|
<config>
|
||||||
@ -82,11 +84,12 @@
|
|||||||
</config>
|
</config>
|
||||||
<plugins>
|
<plugins>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
|
|
||||||
<updateservers>
|
<updateservers>
|
||||||
<server type="extension" priority="1" name="com_circolari">https://nocdn.component-creator.com/index.php?task=builder.preupdatecheckhook&option=com_combuilder&component=NzY0NjYtMjE1NzU5</server>
|
<server type="extension" priority="1" name="com_circolari">
|
||||||
|
https://nocdn.component-creator.com/index.php?task=builder.preupdatecheckhook&option=com_combuilder&component=NzY0NjYtMjE1NzU5</server>
|
||||||
</updateservers>
|
</updateservers>
|
||||||
</extension>
|
</extension>
|
||||||
<!-- Component built by the Joomla Component Creator -->
|
<!-- Component built by the Joomla Component Creator -->
|
||||||
<!-- http://www.component-creator.com/ -->
|
<!-- http://www.component-creator.com/ -->
|
||||||
Reference in New Issue
Block a user