generazione automatica alias

This commit is contained in:
2025-08-26 11:47:03 +02:00
parent edb8d4e873
commit 2f251bbfb0
7 changed files with 364 additions and 270 deletions

View File

@ -14,6 +14,10 @@
<field name="created_by" type="createdby" default="0" label="JGLOBAL_FIELD_CREATED_BY_LABEL" description="JGLOBAL_FIELD_CREATED_BY_DESC" hidden="true" hint="COM_CIRCOLARI_FORM_LBL_CIRCOLARE_CREATED_BY"/>
<field name="modified_by" type="modifiedby" default="0" label="JGLOBAL_FIELD_MODIFIED_BY_LABEL" description="JGLOBAL_FIELD_MODIFIED_BY_DESC" hidden="true" hint="COM_CIRCOLARI_FORM_LBL_CIRCOLARE_MODIFIED_BY"/>
<field name="title" filter="safehtml" type="text" label="JGLOBAL_TITLE" description="JFIELD_TITLE_DESC" hint="COM_CIRCOLARI_FORM_LBL_CIRCOLARE_TITLE"/>
<field name="alias"
type="text"
label="JFIELD_ALIAS_LABEL"
description="JFIELD_ALIAS_DESC" />
<field name="description" filter="safehtml" type="textarea" label="COM_CIRCOLARI_FORM_LBL_CIRCOLARE_DESCRIPTION" description="COM_CIRCOLARI_FORM_DESC_CIRCOLARE_DESCRIPTION" hint="COM_CIRCOLARI_FORM_LBL_CIRCOLARE_DESCRIPTION"/>
<field name="attachment" type="media"
label="COM_CIRCOLARI_FIELD_ATTACHMENT_LABEL"

View File

@ -1 +1,9 @@
/* Only premium users are allowed to update a component */
ALTER TABLE `#__circolari`
ADD COLUMN `alias` VARCHAR(255) NOT NULL DEFAULT '' AFTER `title`,
ADD INDEX `idx_alias` (`alias`);
-- (facoltativo) prima valorizzazione "grezza" per i record esistenti
UPDATE `#__circolari`
SET `alias` = LOWER(REPLACE(TRIM(`title`), ' ', '-'))
WHERE (`alias` = '' OR `alias` IS NULL) AND `title` IS NOT NULL;

View File

@ -0,0 +1 @@
/* Only premium users are allowed to update a component */

View File

@ -1,4 +1,5 @@
<?php
/**
* @version CVS: 1.0.0
* @package Com_Circolari
@ -20,6 +21,7 @@ use \Joomla\CMS\Helper\TagsHelper;
use \Joomla\CMS\Filter\OutputFilter;
use \Joomla\CMS\Event\Model;
use Joomla\CMS\Event\AbstractEvent;
use Joomla\CMS\Application\ApplicationHelper;
/**
@ -96,8 +98,7 @@ class CircolareModel extends AdminModel
if (empty($form))
{
if (empty($form)) {
return false;
}
@ -118,15 +119,12 @@ class CircolareModel extends AdminModel
// Check the session for previously entered form data.
$data = Factory::getApplication()->getUserState('com_circolari.edit.circolare.data', array());
if (empty($data))
{
if ($this->item === null)
{
if (empty($data)) {
if ($this->item === null) {
$this->item = $this->getItem();
}
$data = $this->item;
}
return $data;
@ -144,10 +142,8 @@ class CircolareModel extends AdminModel
public function getItem($pk = null)
{
if ($item = parent::getItem($pk))
{
if (isset($item->params))
{
if ($item = parent::getItem($pk)) {
if (isset($item->params)) {
$item->params = json_encode($item->params);
}
@ -155,7 +151,6 @@ class CircolareModel extends AdminModel
}
return $item;
}
/**
@ -174,8 +169,7 @@ class CircolareModel extends AdminModel
$dispatcher = $this->getDispatcher();
// Access checks.
if (!$user->authorise('core.create', 'com_circolari'))
{
if (!$user->authorise('core.create', 'com_circolari')) {
throw new \Exception(Text::_('JERROR_CORE_CREATE_NOT_PERMITTED'));
}
@ -186,16 +180,13 @@ class CircolareModel extends AdminModel
$table = $this->getTable();
foreach ($pks as $pk)
{
foreach ($pks as $pk) {
if ($table->load($pk, true))
{
if ($table->load($pk, true)) {
// Reset the id to create a new record.
$table->id = 0;
if (!$table->check())
{
if (!$table->check()) {
throw new \Exception($table->getError());
}
@ -235,12 +226,9 @@ class CircolareModel extends AdminModel
]
)
);
}
else
{
} else {
throw new \Exception($table->getError());
}
}
// Clean cache
@ -262,11 +250,9 @@ class CircolareModel extends AdminModel
{
jimport('joomla.filter.output');
if (empty($table->id))
{
if (empty($table->id)) {
// Set ordering to the last item if not set
if (@$table->ordering === '')
{
if (@$table->ordering === '') {
$db = $this->getDbo();
$db->setQuery('SELECT MAX(ordering) FROM #__circolari');
$max = $db->loadResult();
@ -274,4 +260,60 @@ class CircolareModel extends AdminModel
}
}
}
public function check()
{
// ordering per nuovi record
if (property_exists($this, 'ordering') && (int) $this->id === 0) {
$this->ordering = self::getNextOrder();
}
// Titolo obbligatorio (se vuoi forzarlo)
$this->title = trim((string) ($this->title ?? ''));
if ($this->title === '') {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE'));
return false;
}
// --- ALIAS: genera se vuoto, ripulisci, evita "solo numeri", garantisci univocità ---
$this->alias = trim((string) ($this->alias ?? ''));
// Se mancante → dal titolo
if ($this->alias === '') {
$this->alias = ApplicationHelper::stringURLSafe($this->title);
} else {
$this->alias = ApplicationHelper::stringURLSafe($this->alias);
}
// Evita alias vuoto o numerico puro
if ($this->alias === '' || ctype_digit($this->alias)) {
$seed = (int) ($this->id ?: time());
$this->alias = ApplicationHelper::stringURLSafe($this->title . '-' . $seed);
}
// Unicità alias nel contesto tabella
$base = $this->alias;
$i = 2;
while ($this->aliasExists($this->alias, (int) $this->id)) {
$this->alias = $base . '-' . $i;
$i++;
}
return parent::check();
}
protected function aliasExists(string $alias, int $excludeId = 0): bool
{
$q = $this->_db->getQuery(true)
->select('COUNT(*)')
->from($this->_db->quoteName('#__circolari'))
->where($this->_db->quoteName('alias') . ' = ' . $this->_db->quote($alias));
if ($excludeId > 0) {
$q->where($this->_db->quoteName('id') . ' != ' . (int) $excludeId);
}
$this->_db->setQuery($q);
return ((int) $this->_db->loadResult()) > 0;
}
}

View File

@ -1,4 +1,5 @@
<?php
/**
* @version CVS: 1.0.0
* @package Com_Circolari
@ -25,6 +26,7 @@ use \Joomla\CMS\Filesystem\File;
use \Joomla\Registry\Registry;
use \Pcrt\Component\Circolari\Administrator\Helper\CircolariHelper;
use \Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\Application\ApplicationHelper;
/**
@ -55,7 +57,6 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
$this->typeAlias = 'com_circolari.circolare';
parent::__construct('#__circolari', 'id', $db);
$this->setColumnAlias('published', 'state');
}
/**
@ -91,37 +92,31 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
$input = Factory::getApplication()->input;
$task = $input->getString('task', '');
if ($array['id'] == 0 && empty($array['created_by']))
{
if ($array['id'] == 0 && empty($array['created_by'])) {
$array['created_by'] = Factory::getUser()->id;
}
if ($array['id'] == 0 && empty($array['modified_by']))
{
if ($array['id'] == 0 && empty($array['modified_by'])) {
$array['modified_by'] = Factory::getUser()->id;
}
if ($task == 'apply' || $task == 'save')
{
if ($task == 'apply' || $task == 'save') {
$array['modified_by'] = Factory::getUser()->id;
}
if (isset($array['params']) && is_array($array['params']))
{
if (isset($array['params']) && is_array($array['params'])) {
$registry = new Registry;
$registry->loadArray($array['params']);
$array['params'] = (string) $registry;
}
if (isset($array['metadata']) && is_array($array['metadata']))
{
if (isset($array['metadata']) && is_array($array['metadata'])) {
$registry = new Registry;
$registry->loadArray($array['metadata']);
$array['metadata'] = (string) $registry;
}
if (!$user->authorise('core.admin', 'com_circolari.circolare.' . $array['id']))
{
if (!$user->authorise('core.admin', 'com_circolari.circolare.' . $array['id'])) {
$actions = Access::getActionsFromFile(
JPATH_ADMINISTRATOR . '/components/com_circolari/access.xml',
"/access/section[@name='circolare']/"
@ -129,10 +124,8 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
$default_actions = Access::getAssetRules('com_circolari.circolare.' . $array['id'])->getData();
$array_jaccess = array();
foreach ($actions as $action)
{
if (key_exists($action->name, $default_actions))
{
foreach ($actions as $action) {
if (key_exists($action->name, $default_actions)) {
$array_jaccess[$action->name] = $default_actions[$action->name];
}
}
@ -141,8 +134,7 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
}
// Bind the rules for ACL where supported.
if (isset($array['rules']) && is_array($array['rules']))
{
if (isset($array['rules']) && is_array($array['rules'])) {
$this->setRules($array['rules']);
}
@ -179,14 +171,11 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
{
$rules = array();
foreach ($jaccessrules as $action => $jaccess)
{
foreach ($jaccessrules as $action => $jaccess) {
$actions = array();
if ($jaccess)
{
foreach ($jaccess->getData() as $group => $allow)
{
if ($jaccess) {
foreach ($jaccess->getData() as $group => $allow) {
$actions[$group] = ((bool)$allow);
}
}
@ -205,11 +194,45 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
public function check()
{
// If there is an ordering column and this is a new row then get the next ordering value
if (property_exists($this, 'ordering') && $this->id == 0)
{
if (property_exists($this, 'ordering') && $this->id == 0) {
$this->ordering = self::getNextOrder();
}
// Ordering per nuovi record
if (property_exists($this, 'ordering') && (int) $this->id === 0) {
$this->ordering = self::getNextOrder();
}
// Titolo obbligatorio (se preferisci non forzarlo, rimuovi questo blocco)
$this->title = trim((string) ($this->title ?? ''));
if ($this->title === '') {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE'));
return false;
}
// --- ALIAS: genera se vuoto, pulisci, evita solo-numeri, rendilo unico ---
$this->alias = trim((string) ($this->alias ?? ''));
// Se non presente → dal titolo
if ($this->alias === '') {
$this->alias = ApplicationHelper::stringURLSafe($this->title);
} else {
$this->alias = ApplicationHelper::stringURLSafe($this->alias);
}
// Evita alias vuoto o numerico puro
if ($this->alias === '' || ctype_digit($this->alias)) {
$seed = (int) ($this->id ?: time());
$this->alias = ApplicationHelper::stringURLSafe($this->title . '-' . $seed);
}
// Unicità alias nella tabella
$base = $this->alias;
$i = 2;
while ($this->aliasExists($this->alias, (int) $this->id)) {
$this->alias = $base . '-' . $i;
$i++;
}
return parent::check();
@ -251,8 +274,7 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
$assetParent->loadByName('com_circolari');
// Return the found asset-parent-id
if ($assetParent->id)
{
if ($assetParent->id) {
$assetParentId = $assetParent->id;
}
@ -276,4 +298,20 @@ class CircolareTable extends Table implements VersionableTableInterface, Taggabl
return $result;
}
protected function aliasExists(string $alias, int $excludeId = 0): bool
{
$q = $this->_db->getQuery(true)
->select('COUNT(*)')
->from($this->_db->quoteName('#__circolari'))
->where($this->_db->quoteName('alias') . ' = ' . $this->_db->quote($alias));
if ($excludeId > 0) {
$q->where($this->_db->quoteName('id') . ' != ' . (int) $excludeId);
}
$this->_db->setQuery($q);
return ((int) $this->_db->loadResult()) > 0;
}
}

View File

@ -35,6 +35,7 @@ HTMLHelper::_('bootstrap.tooltip');
<fieldset class="adminform">
<legend><?php echo Text::_('COM_CIRCOLARI_FIELDSET_CIRCOLARI'); ?></legend>
<?php echo $this->form->renderField('title'); ?>
<?php echo $this->form->renderField('alias'); ?>
<?php echo $this->form->renderField('description'); ?>
<?php echo $this->form->renderField('attachment'); ?>
<?php echo $this->form->renderField('image'); ?>

View File

@ -7,7 +7,7 @@
<author>Tommaso Cippitelli</author>
<authorEmail>tommaso.cippitelli@protocollicreativi.it</authorEmail>
<authorUrl>http://</authorUrl>
<version>CVS: 1.0.0</version>
<version>CVS: 1.1.0</version>
<description></description>
<namespace path="src">Pcrt\Component\Circolari</namespace>