| 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/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
*/
// No direct access.
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Model\AdminModel;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
class Djcatalog2ModelCombination extends AdminModel
{
protected $text_prefix = 'COM_DJCATALOG2';
public function __construct($config = array())
{
parent::__construct($config);
}
public function getTable($type = 'Combinations', $prefix = 'Djcatalog2Table', $config = array())
{
return Table::getInstance($type, $prefix, $config);
}
public function getForm($data = array(), $loadData = true)
{
// Initialise variables.
$app = Factory::getApplication();
// Get the form.
$form = $this->loadForm('com_djcatalog2.combination', 'combination', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)) {
return false;
}
return $form;
}
protected function loadFormData()
{
$data = Factory::getApplication()->getUserState('com_djcatalog2.edit.combination.data', array());
if (empty($data)) {
$data = (array) $this->getItem();
}
if ($data['id']) {
// Load options
$db = Factory::getDbo();
$query = $db->getQuery(true);
$query
->select(['f.field_id', 'f.value'])
->from($db->quoteName('#__djc2_items_combinations_fields', 'f'))
->where('f.combination_id = ' . $data['id']);
$db->setQuery($query);
$fieldsValues = $db->loadObjectList();
$data['fields'] = [];
foreach ($fieldsValues as $fieldsValue) {
$data['fields'][$fieldsValue->field_id] = $fieldsValue->value;
}
}
if (!$data['item_id']) {
$app = Factory::getApplication();
$parent = $app->getUserStateFromRequest('com_djcatalog2.items.filter.parent', 'filter_parent', 0);
$data['item_id'] = $parent;
}
return $data;
}
protected function getReorderConditions($table = null)
{
$condition = array();
return $condition;
}
public function delete(&$pks)
{
return parent::delete($pks);
}
/**
* Method to test whether a record can be deleted.
*
* @param object $record A record object.
*
* @return boolean True if allowed to delete the record. Defaults to the permission for the component.
*
* @since 1.6
*/
protected function canDelete($record)
{
return Factory::getUser()->authorise('core.delete', $this->option) || Factory::getUser()->authorise('djcatalog2.admin.catalogue', $this->option);
}
/**
* Method to test whether a record can have its state changed.
*
* @param object $record A record object.
*
* @return boolean True if allowed to change the state of the record. Defaults to the permission for the component.
*
* @since 1.6
*/
protected function canEditState($record)
{
return Factory::getUser()->authorise('core.edit.state', $this->option) || Factory::getUser()->authorise('djcatalog2.admin.catalogue', $this->option);
}
private function getHiddenFieldsForCombo(int $combinationId): array {
$db = Factory::getDbo();
$q = $db->getQuery(true)
->select($db->quoteName('hidden_fields'))
->from($db->quoteName('#__djc2_items_combinations'))
->where($db->quoteName('id') . ' = ' . (int)$combinationId);
$db->setQuery($q);
$json = (string)$db->loadResult();
if (!$json) return [];
$arr = json_decode($json, true);
return is_array($arr) ? array_map('intval', $arr) : [];
}
private function setHiddenFieldsForCombo(int $combinationId, array $fieldIds): void {
$db = Factory::getDbo();
$fieldIds = array_values(array_unique(array_map('intval', $fieldIds)));
$json = json_encode($fieldIds);
$q = $db->getQuery(true)
->update($db->quoteName('#__djc2_items_combinations'))
->set($db->quoteName('hidden_fields') . ' = ' . $db->quote($json))
->where($db->quoteName('id') . ' = ' . (int)$combinationId);
$db->setQuery($q)->execute();
}
protected function preprocessForm(JForm $form, $data, $group = 'helloworld')
{
$db = Factory::getDbo();
$app = Factory::getApplication();
$parent = (int) $app->getUserStateFromRequest('com_djcatalog2.items.filter.parent', 'filter_parent', 0);
$comboId = 0;
if (is_array($data) && !empty($data['id'])) {
$comboId = (int)$data['id'];
} else {
// ewentualnie: $comboId = (int)$this->getState($this->getName().'.id');
}
// pobierz ukryte pola tej kombinacji
$hidden = $comboId ? $this->getHiddenFieldsForCombo($comboId) : [];
$itemModel = BaseDatabaseModel::getInstance('Item', 'Djcatalog2Model', ['ignore_request' => true]);
$item = $itemModel->getItem($parent);
if (isset($item->language)) {
// 1) pobierz definicje pól (cart_variant = 1)
$q = $db->getQuery(true);
$q->select('f.*')
->from('#__djc2_items_extra_fields AS f')
->where('f.cart_variant = 1')
->where('(f.language = ' . $db->quote('*') . ' OR f.language = ' . $db->quote($item->language) . ')')
->order('f.ordering');
$db->setQuery($q);
$extraFields = $db->loadObjectList('id');
if (!$extraFields) {
parent::preprocessForm($form, $data, $group);
return;
}
// 2) pobierz opcje
$ids = array_keys($extraFields);
$q = $db->getQuery(true);
$q->select(['o.id','o.value','o.field_id'])
->from('#__djc2_items_extra_fields_options AS o')
->where('o.field_id IN ('.implode(',', $ids).')');
$db->setQuery($q);
$options = $db->loadObjectList();
foreach ($options as $opt) {
if (isset($extraFields[$opt->field_id])) {
$extraFields[$opt->field_id]->options[$opt->id] = $opt;
}
}
$query = $db->getQuery(true);
$query
->select('DISTINCT v.field_id')
->from($db->quoteName('#__djc2_items_combinations_fields', 'v'))
->join('INNER', $db->quoteName('#__djc2_items_combinations', 'c') . ' ON c.id = v.combination_id')
->where('c.item_id = ' . (int) $parent);
$db->setQuery($query);
$assignedFields = $db->loadColumn();
// 4) budowa dynamicznego formularza z ominięciem pól ukrytych
$addform = new SimpleXMLElement('<form />');
$fields = $addform->addChild('fields');
$fields->addAttribute('name', 'fields');
$fieldset = $fields->addChild('fieldset');
$fieldset->addAttribute('name', 'fields');
$requiredCheck = static function($fieldId) use ($assignedFields) {
return in_array((int) $fieldId, $assignedFields, true);
};
uasort($extraFields, function($a, $b) use ($requiredCheck) {
$aReq = $requiredCheck($a->id);
$bReq = $requiredCheck($b->id);
if ($aReq !== $bReq) {
// required first
return $bReq <=> $aReq;
}
// fall back to DB ordering (or any secondary criteria you prefer)
return (int) $a->ordering <=> (int) $b->ordering;
});
foreach ($extraFields as $ef) {
if (in_array((int)$ef->id, $hidden, true)) {
// to pole ma być niewidoczne dla tej kombinacji
continue;
}
$field = $fieldset->addChild('field');
$field->addAttribute('name', $ef->id);
$field->addAttribute('type', 'list');
$field->addAttribute('label', $ef->name);
// required tylko jeśli było już przypisane dla tej kombinacji (unikniemy wymuszania przy ukrytych)
if (in_array((int)$ef->id, $assignedFields, true)) {
$field->addAttribute('required', 'true');
}
if(in_array($ef->id, $assignedFields)) {
$field->addAttribute('required', true);
}
// placeholder „wybierz”
$opt = $field->addChild('option', Text::_('COM_DJCATALOG2_SELECT_VALUE'));
$opt->addAttribute('value', '');
// opcje
foreach (($ef->options ?? []) as $optId => $optRow) {
$o = $field->addChild('option', $optRow->value);
$o->addAttribute('value', (string) $optRow->id);
}
}
$form->load($addform, false);
}
parent::preprocessForm($form, $data, $group);
}
public function validate($form, $data, $group = null)
{
$app = Factory::getApplication();
$jform = $app->input->post->get('jform', [], 'array');
$toRemove = array_map('intval', $jform['fields_remove'] ?? []);
// zdejmij required dla usuwanych pól (gdyby jednak były w form)
foreach ($toRemove as $fid) {
if ($form->getField((string)$fid, 'fields')) {
$form->setFieldAttribute((string)$fid, 'required', 'false', 'fields');
}
}
return parent::validate($form, $data, $group);
}
public function save($data)
{
$fieldsToRemove = [];
if (!empty($data['fields_remove'])) {
$fieldsToRemove = array_map('intval', (array)$data['fields_remove']);
unset($data['fields_remove']);
}
// wyrzuć z payloadu wartości usuwanych pól
foreach ($fieldsToRemove as $fid) {
if (isset($data['fields'][$fid])) unset($data['fields'][$fid]);
}
$res = parent::save($data);
if (!$res) return false;
// Ustal ID kombinacji
$comboId = !empty($data['id']) ? (int)$data['id'] : (int)$this->getState($this->getName().'.id');
if ($comboId && $fieldsToRemove) {
// 1) dopisz do hidden_fields
$currentHidden = $this->getHiddenFieldsForCombo($comboId);
$this->setHiddenFieldsForCombo($comboId, array_unique(array_merge($currentHidden, $fieldsToRemove)));
// 2) wyczyść relacje dla tych pól
$db = $this->getDbo();
$q = $db->getQuery(true)
->delete('#__djc2_items_combinations_fields')
->where('combination_id = '.(int)$comboId)
->where('field_id IN ('.implode(',', $fieldsToRemove).')');
$db->setQuery($q)->execute();
}
return true;
}
/**
* Usuń definitywnie powiązania pól z kombinacją.
* Dostosuj do swojej struktury (nazwa tabeli/kolumn).
*/
protected function removeFieldsFromCombination(int $combinationId, array $fieldNames): void
{
$db = $this->getDbo();
// Przykład 1: jeśli masz tabelę relacyjną z nazwą pola (aliasem)
// #__djc2_combinations_fields: combination_id, field_name, field_value, ...
try {
$quoted = array_map([$db, 'quote'], array_map(function($fname){
// wyciągamy ostatni segment w [] jako "klucz" pola
if (preg_match('#\[([^\[\]]+)\]$#', $fname, $m)) return $m[1];
return $fname;
}, $fieldNames));
if (!empty($quoted)) {
$query = $db->getQuery(true)
->delete($db->quoteName('#__djc2_combinations_fields'))
->where($db->quoteName('combination_id') . ' = ' . (int) $combinationId)
->where($db->quoteName('field_name') . ' IN (' . implode(',', $quoted) . ')');
$db->setQuery($query)->execute();
}
} catch (\Throwable $e) {
// Możesz zalogować: Factory::getApplication()->enqueueMessage($e->getMessage(), 'warning');
}
// Przykład 2: jeśli trzymasz pola w JSON w kolumnie combinations.fields
// wówczas sam `unset` powyżej + zapis rekordu wystarczy i tej sekcji nie potrzebujesz.
}
}