punto 0
This commit is contained in:
@ -3,20 +3,29 @@ namespace Pcrt\Component\Circolari\Site\Controller;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
|
||||
class DisplayController extends BaseController
|
||||
{
|
||||
protected $default_view = 'circolare'; // default se manca ?view=
|
||||
|
||||
public function display($cachable = false, $urlparams = [])
|
||||
{
|
||||
// Se qualcuno forza un view strano, non rompiamo
|
||||
$view = $this->input->getCmd('view', $this->default_view);
|
||||
if (!in_array($view, ['circolare'], true)) {
|
||||
$view = $this->default_view;
|
||||
$this->input->set('view', $view);
|
||||
$app = Factory::getApplication();
|
||||
$in = $app->input;
|
||||
|
||||
$view = $in->getCmd('view', '');
|
||||
$id = $in->getInt('id', 0);
|
||||
|
||||
if ($id > 0) {
|
||||
// Singolo solo se c'è l'id
|
||||
$in->set('view', 'circolare');
|
||||
} else {
|
||||
// Nessun id: forziamo la lista (anche se il menu chiede "circolare")
|
||||
if ($view === '' || $view === 'circolare' || $view === 'category') {
|
||||
$in->set('view', 'circolari'); // <- lista
|
||||
}
|
||||
}
|
||||
|
||||
return parent::display($cachable, $urlparams);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,31 +3,56 @@ namespace Pcrt\Component\Circolari\Site\Model;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Model\ItemModel;
|
||||
use Joomla\CMS\Factory;
|
||||
|
||||
class CircolareModel extends ItemModel
|
||||
{
|
||||
protected function populateState(): void
|
||||
protected function populateState()
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
$this->setState('circolare.id', (int) $app->input->getInt('id'));
|
||||
$id = $app->input->getInt('id', 0);
|
||||
$this->setState('circolare.id', $id);
|
||||
|
||||
$catid = $app->input->getInt('catid', 0);
|
||||
$this->setState('filter.catid', $catid);
|
||||
parent::populateState();
|
||||
}
|
||||
|
||||
public function getItem($pk = null)
|
||||
{
|
||||
$pk = $pk ?: (int) $this->getState('circolare.id');
|
||||
if (!$pk) return null;
|
||||
$pk = (int) ($pk ?: $this->getState('circolare.id'));
|
||||
|
||||
$db = Factory::getContainer()->get('DatabaseDriver');
|
||||
if ($pk <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$db = $this->getDatabase();
|
||||
$q = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__circolari'))
|
||||
->where($db->quoteName('id') . ' = ' . (int) $pk)
|
||||
->where($db->quoteName('state') . ' = 1');
|
||||
$db->setQuery($q);
|
||||
->select('c.*') // <<< evita errori di colonne
|
||||
->from($db->quoteName('#__circolari') . ' AS c')
|
||||
->where('c.id = ' . (int) $pk);
|
||||
|
||||
return $db->loadObject();
|
||||
// Se esistono le colonne, applica filtri
|
||||
$cols = array_change_key_case(
|
||||
$db->getTableColumns($db->replacePrefix('#__circolari'), false),
|
||||
CASE_LOWER
|
||||
);
|
||||
|
||||
// catid (se impostato e colonna esiste)
|
||||
$catid = (int) $this->getState('filter.catid', 0);
|
||||
if ($catid > 0 && isset($cols['catid'])) {
|
||||
$q->where('c.catid = ' . $catid);
|
||||
}
|
||||
|
||||
// stato (se colonna esiste)
|
||||
if (isset($cols['state'])) {
|
||||
$q->where('COALESCE(c.state, 1) = 1');
|
||||
}
|
||||
|
||||
$db->setQuery($q);
|
||||
$row = $db->loadObject();
|
||||
|
||||
return $row ?: null;
|
||||
}
|
||||
}
|
||||
|
||||
119
site/src/Model/CircolariModel.php
Normal file
119
site/src/Model/CircolariModel.php
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
namespace Pcrt\Component\Circolari\Site\Model;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Model\ListModel;
|
||||
|
||||
class CircolariModel extends ListModel
|
||||
{
|
||||
protected $context = 'com_circolari.circolari';
|
||||
|
||||
// campi ammessi per sort
|
||||
protected $filter_fields = [
|
||||
'id', 'c.id',
|
||||
'title', 'c.title',
|
||||
'created', 'c.created',
|
||||
'hits', 'c.hits',
|
||||
'catid', 'c.catid',
|
||||
'state', 'c.state',
|
||||
];
|
||||
|
||||
protected function populateState($ordering = 'c.created', $direction = 'DESC')
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// paging
|
||||
$limit = $app->getUserStateFromRequest($this->context . '.list.limit', 'limit', $app->get('list_limit'), 'uint');
|
||||
$this->setState('list.limit', $limit);
|
||||
|
||||
$start = $app->getUserStateFromRequest($this->context . '.list.start', 'limitstart', 0, 'uint');
|
||||
$this->setState('list.start', $start);
|
||||
|
||||
// sorting
|
||||
$orderCol = $app->getUserStateFromRequest($this->context . '.list.ordering', 'filter_order', $ordering, 'cmd');
|
||||
if (!\in_array($orderCol, $this->filter_fields, true)) {
|
||||
$orderCol = $ordering;
|
||||
}
|
||||
$this->setState('list.ordering', $orderCol);
|
||||
|
||||
$orderDirn = strtoupper($app->getUserStateFromRequest($this->context . '.list.direction', 'filter_order_Dir', $direction, 'cmd'));
|
||||
$this->setState('list.direction', $orderDirn === 'ASC' ? 'ASC' : 'DESC');
|
||||
|
||||
// filtro testuale
|
||||
$search = $app->getUserStateFromRequest($this->context . '.list.filter', 'filter-search', '', 'string');
|
||||
$this->setState('list.filter', $search);
|
||||
|
||||
// categoria (se usi catid)
|
||||
$this->setState('filter.catid', $app->input->getInt('catid', 0));
|
||||
|
||||
parent::populateState($ordering, $direction);
|
||||
}
|
||||
|
||||
protected function getListQuery()
|
||||
{
|
||||
$db = $this->getDatabase();
|
||||
$q = $db->getQuery(true)
|
||||
->select('c.*')
|
||||
->from($db->quoteName('#__circolari', 'c'));
|
||||
|
||||
// colonne effettive in tabella
|
||||
$cols = array_change_key_case($db->getTableColumns($db->replacePrefix('#__circolari')));
|
||||
|
||||
// pubblicati
|
||||
if (isset($cols['state'])) {
|
||||
$q->where('COALESCE(c.state,1)=1');
|
||||
}
|
||||
|
||||
// catid
|
||||
$catid = (int) $this->getState('filter.catid', 0);
|
||||
if ($catid > 0 && isset($cols['catid'])) {
|
||||
$q->where('c.catid=' . $catid);
|
||||
}
|
||||
|
||||
// search su title
|
||||
$search = trim((string) $this->getState('list.filter', ''));
|
||||
if ($search !== '' && isset($cols['title'])) {
|
||||
$like = $db->quote('%' . $db->escape($search, true) . '%', false);
|
||||
$q->where('c.title LIKE ' . $like);
|
||||
}
|
||||
|
||||
// ordinamento
|
||||
$orderCol = $this->getState('list.ordering', 'c.created');
|
||||
$orderDir = $this->getState('list.direction', 'DESC');
|
||||
$q->order($db->escape($orderCol . ' ' . $orderDir));
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
// conteggio robusto (gestisce DISTINCT/GROUP BY)
|
||||
public function getTotal()
|
||||
{
|
||||
if (isset($this->total)) {
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
$db = $this->getDatabase();
|
||||
$sub = $this->getListQuery();
|
||||
$query = $db->getQuery(true)
|
||||
->select('COUNT(*)')
|
||||
->from('(' . $sub . ') AS x');
|
||||
|
||||
$db->setQuery($query);
|
||||
$this->total = (int) $db->loadResult();
|
||||
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
public function getItems()
|
||||
{
|
||||
$items = parent::getItems();
|
||||
if (!\is_array($items)) {
|
||||
return [];
|
||||
}
|
||||
return array_values(array_filter($items, static function ($it) {
|
||||
return \is_object($it) && !empty($it->id);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @version CVS: 1.0.0
|
||||
* @package Com_Circolari
|
||||
* @author Tommaso Cippitelli <tommaso.cippitelli@protocollicreativi.it>
|
||||
* @copyright 2025 Tommaso Cippitelli
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Pcrt\Component\Circolari\Site\Service;
|
||||
// No direct access
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use \Joomla\CMS\Categories\Categories;
|
||||
/**
|
||||
* Content Component Category Tree
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
@ -3,35 +3,50 @@ namespace Pcrt\Component\Circolari\Site\View\Circolare;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
protected $item;
|
||||
public $items = [];
|
||||
public $pagination;
|
||||
public $state;
|
||||
|
||||
public function display($tpl = null)
|
||||
{
|
||||
// Carica la singola
|
||||
$this->item = $this->get('Item');
|
||||
|
||||
// Se NON c'è l'item → mostra la lista
|
||||
if (!$this->item) {
|
||||
throw new \Exception(Text::_('COM_CIRCOLARI_ITEM_NOT_FOUND'), 404);
|
||||
}
|
||||
$app = \Joomla\CMS\Factory::getApplication();
|
||||
$factory = $app->bootComponent('com_circolari')->getMVCFactory();
|
||||
|
||||
// Se il layout non c'è, stampa un fallback minimale (debug-friendly)
|
||||
$tplPath = JPATH_COMPONENT_SITE . '/tmpl/circolare/default.php';
|
||||
if (!is_file($tplPath)) {
|
||||
$title = htmlspecialchars($this->item->title ?? 'Circolare');
|
||||
$body = $this->item->description ?? $this->item->testo ?? $this->item->descrizione ?? '';
|
||||
$html = '<article class="com-content-article item-page">'
|
||||
. '<header class="page-header"><h1 class="page-title">'.$title.'</h1></header>'
|
||||
. '<div class="article-body">'.$body.'</div>'
|
||||
. '</article>';
|
||||
/** @var \Pcrt\Component\Circolari\Site\Model\CircolariModel $model */
|
||||
$model = $factory->createModel('Circolari', 'Site', ['ignore_request' => true]);
|
||||
|
||||
$this->document->setBuffer($html, 'component');
|
||||
return;
|
||||
}
|
||||
// Imposta gli stati MANUALMENTE (niente populateState: è protected)
|
||||
$model->setState('filter.catid', 0); // nessun filtro categoria
|
||||
$model->setState('list.start', 0);
|
||||
$model->setState('list.limit', 0); // 0 = nessun limite (tutte)
|
||||
$model->setState('list.ordering', 'c.id'); // colonna di ordinamento
|
||||
$model->setState('list.direction', 'DESC'); // direzione
|
||||
|
||||
parent::display($tpl);
|
||||
// Recupera i dati
|
||||
$this->state = $model->getState();
|
||||
$this->items = $model->getItems();
|
||||
$this->pagination = $model->getPagination();
|
||||
|
||||
// Usa il layout della lista (tmpl/circolari/default.php)
|
||||
$this->setLayout('default');
|
||||
$this->addTemplatePath(JPATH_COMPONENT_SITE . '/tmpl/circolari');
|
||||
|
||||
return parent::display($tpl);
|
||||
}
|
||||
|
||||
// Rendering normale della singola
|
||||
return parent::display($tpl);
|
||||
}
|
||||
}
|
||||
|
||||
21
site/src/View/Circolari/HtmlView.php
Normal file
21
site/src/View/Circolari/HtmlView.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Pcrt\Component\Circolari\Site\View\Circolari;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
public $items;
|
||||
public $pagination;
|
||||
public $state;
|
||||
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->state = $this->get('State');
|
||||
$this->items = $this->get('Items');
|
||||
$this->pagination = $this->get('Pagination');
|
||||
return parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<metadata>
|
||||
<!-- titolo del tipo voce di menu, visibile nel backend -->
|
||||
<layout title="COM_CIRCOLARI_MENU_CATEGORY" option="com_circolari" />
|
||||
|
||||
<!-- campi che finiscono nella query dell'URL -->
|
||||
<fields name="request">
|
||||
<fieldset name="request">
|
||||
<!-- forza la view "category" -->
|
||||
<field name="view" type="hidden" default="category" />
|
||||
<!-- scegli la categoria di Joomla (com_content) che fa da base del percorso -->
|
||||
<field
|
||||
name="id"
|
||||
type="category"
|
||||
extension="com_content"
|
||||
label="JCATEGORY"
|
||||
description="Seleziona la categoria di com_content da usare come base del percorso URL."
|
||||
required="true"
|
||||
default="11"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
|
||||
<!-- parametri opzionali della voce (non obbligatori) -->
|
||||
<fields name="params">
|
||||
<fieldset name="basic" label="JOPTIONS">
|
||||
<field name="show_category_title" type="radio" label="COM_CIRCOLARI_SHOW_CATEGORY_TITLE" default="0">
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</metadata>
|
||||
67
site/tmpl/circolari/default.php
Normal file
67
site/tmpl/circolari/default.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
// ... intestazione invariata ...
|
||||
|
||||
// $listOrder / $listDirn / $filter già come li hai
|
||||
$Itemid = (int) ($input->getInt('Itemid') ?: 0);
|
||||
?>
|
||||
<form action="<?php echo htmlspecialchars(Uri::getInstance()->toString(), ENT_QUOTES, 'UTF-8'); ?>"
|
||||
method="post"
|
||||
name="adminForm"
|
||||
id="adminForm"
|
||||
class="com-content-category__articles">
|
||||
|
||||
<!-- filtro -->
|
||||
<!-- (invariato) -->
|
||||
|
||||
<!-- Limite per pagina -->
|
||||
<?php if ($pagination && \method_exists($pagination, 'getLimitBox')) : ?>
|
||||
<div class="com-content-category__pagination btn-group float-end">
|
||||
<label for="limit" class="visually-hidden"><?php echo Text::_('JGLOBAL_DISPLAY_NUM'); ?></label>
|
||||
<?php echo $pagination->getLimitBox(); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- tabella -->
|
||||
<table class="com-content-category__table category table table-striped table-bordered table-hover mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" id="circolari_header_title">
|
||||
<?php echo HTMLHelper::_('grid.sort', 'JGLOBAL_TITLE', 'c.title', $listDirn, $listOrder, null, 'asc', '', 'adminForm'); ?>
|
||||
</th>
|
||||
<th scope="col" id="circolari_header_date" class="small">
|
||||
<?php echo HTMLHelper::_('grid.sort', Text::_('JDATE'), 'c.created', $listDirn, $listOrder, null, 'asc', '', 'adminForm'); ?>
|
||||
</th>
|
||||
<th scope="col" id="circolari_header_attachment" class="text-center">
|
||||
<?php echo Text::_('COM_CIRCOLARI_ATTACHMENT') ?: 'Allegato'; ?>
|
||||
</th>
|
||||
<th scope="col" id="circolari_header_hits" class="text-end">
|
||||
<?php echo HTMLHelper::_('grid.sort', 'JGLOBAL_HITS', 'c.hits', $listDirn, $listOrder, null, 'asc', '', 'adminForm'); ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<!-- tbody invariato -->
|
||||
</table>
|
||||
|
||||
<!-- paginazione -->
|
||||
<?php if ($pagination && $pagination->pagesTotal > 1) : ?>
|
||||
<div class="com-content-category__navigation w-100">
|
||||
<p class="com-content-category__counter counter float-end pt-3 pe-2">
|
||||
<?php echo $pagination->getPagesCounter(); ?>
|
||||
</p>
|
||||
<div class="com-content-category__pagination">
|
||||
<?php echo $pagination->getPagesLinks(); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- hidden -->
|
||||
<div>
|
||||
<input type="hidden" name="option" value="com_circolari">
|
||||
<input type="hidden" name="view" value="circolari">
|
||||
<?php if ($Itemid) : ?><input type="hidden" name="Itemid" value="<?php echo $Itemid; ?>"><?php endif; ?>
|
||||
<input type="hidden" name="filter_order" value="<?php echo $listOrder; ?>">
|
||||
<input type="hidden" name="filter_order_Dir" value="<?php echo $listDirn; ?>">
|
||||
<input type="hidden" name="limitstart" value="<?php echo (int) ($pagination?->limitstart ?? 0); ?>">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</form>
|
||||
10
site/tmpl/circolari/default.xml
Normal file
10
site/tmpl/circolari/default.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_CIRCOLARI_MENU_LIST" option="com_circolari" />
|
||||
<fields name="request">
|
||||
<fieldset name="request">
|
||||
<field name="view" type="hidden" default="circolari" />
|
||||
<field name="catid" type="category" extension="com_content" label="JCATEGORY" required="false" />
|
||||
</fieldset>
|
||||
</fields>
|
||||
</metadata>
|
||||
Reference in New Issue
Block a user