| Server IP : 54.36.91.62 / Your IP : 216.73.217.112 Web Server : Apache System : Linux webm013.cluster127.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64 User : coopiak ( 151928) PHP Version : 8.3.23 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/coopiak/amisdesseniors-fr/aix/administrator/components/com_djcatalog2/models/ |
Upload File : |
<?php
/**
* @package DJ-Catalog2
* @copyright Copyright (C) DJ-Extensions.com, All rights reserved.
* @license http://www.gnu.org/licenses GNU/GPL
* @author url: http://dj-extensions.com
* @author email contact@dj-extensions.com
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Table\Table;
use Joomla\CMS\MVC\Model\AdminModel;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Language\LanguageHelper;
use Joomla\CMS\Language\Associations;
/**
* Private Message model.
*
* @since 1.6
*/
class DJCatalog2ModelTemplate extends AdminModel
{
/**
* Message
*/
protected $item;
protected $associationsContext = 'com_djcatalog2.template';
protected function storeAssociations(Table $table, array $data): void
{
// Multilang musi być włączony (Language Filter + Item Associations)
if (!Associations::isEnabled()) {
return;
}
$db = $this->getDbo();
$context = $this->associationsContext ?? 'com_djcatalog2.template';
// Id aktualnie zapisanego rekordu
$keyName = $table->getKeyName();
$id = (int) $table->$keyName;
// Znormalizuj wejście z formularza
$assoc = [];
if (!empty($data['associations']) && is_array($data['associations'])) {
foreach ($data['associations'] as $langCode => $assocId) {
if (is_numeric($assocId) && (int) $assocId > 0) {
$assoc[$langCode] = (int) $assocId;
}
}
}
// Dodaj bieżący rekord do zestawu (o ile ma konkretny język)
// Dzięki temu grupa asocjacyjna będzie kompletna.
if (!empty($table->language) && $table->language !== '*') {
$assoc[$table->language] = $id;
}
// Jeśli nie ma nic do powiązania — usuń stare wpisy i wyjdź
if (empty($assoc)) {
$query = $db->getQuery(true)
->delete($db->quoteName('#__associations'))
->where($db->quoteName('context') . ' = ' . $db->quote($context))
->where($db->quoteName('id') . ' = ' . (int) $id);
$db->setQuery($query)->execute();
return;
}
// Zbierz unikalne ID z całej mapy język -> ID
$ids = array_values(array_unique(array_map('intval', $assoc)));
// Wyczyść poprzednie powiązania dla wszystkich ID z tej grupy (w tym bieżącego)
$query = $db->getQuery(true)
->delete($db->quoteName('#__associations'))
->where($db->quoteName('context') . ' = ' . $db->quote($context))
->where($db->quoteName('id') . ' IN (' . implode(',', $ids) . ')');
$db->setQuery($query)->execute();
// Wspólny klucz grupy asocjacyjnej (może być dowolny stabilny hash)
$hash = md5(implode(',', $ids));
// Przygotuj listę kolumn z poprawnym quotingiem (uwaga na zarezerwowane `key`)
$columns = $db->quoteName(['id', 'context', 'key']);
// Wstaw powiązania dla całego zestawu
foreach ($ids as $assocId) {
$values = implode(',', [
(int) $assocId,
$db->quote($context),
$db->quote($hash),
]);
$query = $db->getQuery(true)
->insert($db->quoteName('#__associations'))
->columns($columns)
->values($values);
$db->setQuery($query)->execute();
}
}
/**
* Method to auto-populate the model state.
*
* This method should only be called once per instantiation and is designed
* to be called on the first call to the getState() method unless the model
* configuration flag to ignore the request is set.
*
* Note. Calling getState in this method will result in recursion.
*
* @return void
*
* @since 1.6
*/
protected function populateState()
{
parent::populateState();
$input = Factory::getApplication()->input;
$id = (int)$input->getInt('id');
$this->setState('template.id', $id);
}
/**
* Check that recipient user is the one trying to delete and then call parent delete method
*
* @param array &$pks An array of record primary keys.
*
* @return boolean True if successful, false if an error occurs.
*
* @since 3.1
*/
public function delete(&$pks)
{
return parent::delete($pks);
}
/**
* Returns a Table object, always creating it.
*
* @param type $type The table type to instantiate
* @param string $prefix A prefix for the table class name. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return Table A database object
*
* @since 1.6
*/
public function getTable($type = 'Template', $prefix = 'DJCatalog2Table', $config = array())
{
return Table::getInstance($type, $prefix, $config);
}
/**
* Method to get a single record.
*
* @param integer $pk The id of the primary key.
*
* @return mixed Object on success, false on failure.
*
* @since 1.6
*/
public function getItem($pk = null)
{
if ($item = parent::getItem($pk)) {
/*
* Multilang
*/
if (Associations::isEnabled())
{
$item->associations = array();
if ($item->id != null)
{
$associations = Associations::getAssociations('com_djcatalog2', '#__djc2_message_templates', 'com_djcatalog2.template', (int) $item->id, 'id', '', '');
foreach ($associations as $tag => $association)
{
$item->associations[$tag] = $association->id;
}
}
}
return $item;
} else {
return false;
}
}
/**
* Method to get the record form.
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
*
* @return JForm A JForm object on success, false on failure
*
* @since 1.6
*/
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_djmessages.template', 'template', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)) {
return false;
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
*
* @since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = Factory::getApplication()->getUserState('com_djmessages.edit.template.data', array());
if (empty($data)) {
$data = $this->getItem();
}
$this->preprocessData('com_djmessages.template', $data);
return $data;
}
protected function preprocessForm(Joomla\CMS\Form\Form $form, $data, $group = 'content')
{
if (Associations::isEnabled())
{
$languages = LanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc');
if (count($languages) > 1)
{
$addform = new SimpleXMLElement('<form />');
$fields = $addform->addChild('fields');
$fields->addAttribute('name', 'associations');
$fieldset = $fields->addChild('fieldset');
$fieldset->addAttribute('name', 'item_associations');
foreach ($languages as $language)
{
$field = $fieldset->addChild('field');
$field->addAttribute('name', $language->lang_code);
$field->addAttribute('type', 'djtemplatemodal');
$field->addAttribute('language', $language->lang_code);
$field->addAttribute('label', $language->title);
$field->addAttribute('translate_label', 'false');
}
$form->load($addform, false);
}
}
parent::preprocessForm($form, $data, $group);
if (!empty($data)) {
if (is_object($data) && (!empty($data->id) || !empty($data->type))) {
$form->setFieldAttribute('type', 'readonly', 'true');
} else if (is_array($data) && (!empty($data['id']) || !empty($data['type']))) {
$form->setFieldAttribute('type', 'readonly', 'true');
}
}
}
public function save($data)
{
$this->preProcessAttachments($data);
$dispatcher = Joomla\CMS\Factory::getApplication()->getDispatcher();
$table = $this->getTable();
$context = $this->option . '.' . $this->name;
$key = $table->getKeyName();
$pk = (!empty($data[$key])) ? $data[$key] : (int)$this->getState($this->getName() . '.id');
$isNew = true;
// Include the plugins for the save events.
PluginHelper::importPlugin($this->events_map['save']);
// Wyczyść puste asocjacje z $data['associations']
if (isset($data['associations']) && is_array($data['associations'])) {
foreach ($data['associations'] as $langCode => $assocId) {
// null
if ($assocId === null) {
unset($data['associations'][$langCode]);
continue;
}
// pusty string / białe znaki
if (is_string($assocId) && trim($assocId) === '') {
unset($data['associations'][$langCode]);
continue;
}
// wartości nienumeryczne lub <= 0 (ID musi być > 0)
if (!is_numeric($assocId) || (int) $assocId <= 0) {
unset($data['associations'][$langCode]);
continue;
}
// rzutuj ID na int dla porządku
$data['associations'][$langCode] = (int) $assocId;
}
// jeśli po czyszczeniu nic nie zostało — usuń klucz całkiem
if (empty($data['associations'])) {
unset($data['associations']);
}
}
// Allow an exception to be thrown.
try {
// Load the row if saving an existing record.
if ($pk > 0) {
$table->load($pk);
$isNew = false;
}
// Bind the data.
if (!$table->bind($data)) {
$this->setError($table->getError());
return false;
}
// Prepare the row for saving
$this->prepareTable($table);
// Check the data.
if (!$table->check()) {
$this->setError($table->getError());
return false;
}
// Trigger the before save event.
$result = Joomla\CMS\Factory::getApplication()->triggerEvent($this->event_before_save, array($context, $table, $isNew, $data));
if (in_array(false, $result, true)) {
$this->setError($table->getError());
return false;
}
$table->attachments = $this->processAttachments($data);
// Store the data.
if (!$table->store()) {
$this->setError($table->getError());
return false;
}
$this->storeAssociations($table, $data);
// Clean the cache.
$this->cleanCache();
// Trigger the after save event.
Joomla\CMS\Factory::getApplication()->triggerEvent($this->event_after_save, array($context, $table, $isNew, $data));
} catch (Exception $e) {
$this->setError($e->getMessage());
return false;
}
if (isset($table->$key)) {
$this->setState($this->getName() . '.id', $table->$key);
}
$this->setState($this->getName() . '.new', $isNew);
return true;
}
protected function preProcessAttachments($data)
{
if (empty($data['id'])) return;
$files = $beforeFiles = array();
if (!empty($data['attachments']) && $data['attachments'] != '[]') {
$files = json_decode((string)$data['attachments']);
}
$db = Factory::getDbo();
$db->setQuery($db->getQuery(true)->select('*')->from('#__djc2_message_templates')->where('id=' . (int)$data['id']));
$oldData = $db->loadObject();
if (!empty($oldData->attachments) && $oldData->attachments != '[]') {
$beforeFiles = json_decode((string)$oldData->attachments);
}
if (is_array($beforeFiles) && count($beforeFiles) > 0) {
foreach ($beforeFiles as $bk => $bfile) {
$found = false;
foreach ($files as $k => $file) {
if ($file->file_id == $bfile->file_id && $bfile->file_id > 0) {
$found = true;
break;
}
}
if (!$found) {
// image ($bfile) should be deleted in such case
if (!empty($bfile->fullpath) && File::exists(JPath::clean(JPATH_ROOT . '/' . $bfile->fullpath))) {
File::delete(JPath::clean(JPATH_ROOT . '/' . $bfile->fullpath));
}
}
}
}
return true;
}
protected function processAttachments($data)
{
$files = array();
if (!empty($data['attachments']) && $data['attachments'] != '[]') {
$files = json_decode((string)$data['attachments']);
}
if (is_array($files) && count($files) > 0) {
$destination = JPATH_ROOT . '/media/djcatalog2/messages/attachments';
if (!Folder::exists($destination)) {
Folder::create($destination, 0755);
}
foreach ($files as $k => $file) {
if (!empty($file->file_id)) {
// skipping already uploaded Files
continue;
}
$ext = DJCatalog2FileHelper::getExtension($file->fullname);
//$newName = $data['name']. '-' . $file->caption . '.' . $ext;
$newName = $file->caption . '.' . $ext;
$newName = \Joomla\String\StringHelper::strtolower(DJCatalog2FileHelper::createFileName($newName, $destination));
$newPath = $destination . '/' . $newName;
$source = JPath::clean(JPATH_ROOT . '/media/djcatalog2/tmp/' . $file->fullname);
if (File::move($source, $newPath)) {
$files[$k]->file_id = md5($data['id'] . ':' . $file->caption . ':' . $file->fullname);
$files[$k]->fullname = $newName;
$files[$k]->url = 'media/djcatalog2/messages/attachments/' . $newName;
$files[$k]->size = filesize($newPath);
$files[$k]->path = 'media/djcatalog2/messages/attachments';
$files[$k]->fullpath = $files[$k]->path . '/' . $files[$k]->fullname;
}
}
}
$newFiles = json_encode($files);
return $newFiles;
}
}