462 lines
16 KiB
PHP
462 lines
16 KiB
PHP
<?php
|
|
|
|
use KupShop\AdminBundle\Util\AdminSectionTree;
|
|
use KupShop\CatalogBundle\Section\SectionFilter;
|
|
use KupShop\CatalogBundle\Util\FilterUtil;
|
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
|
use KupShop\KupShopBundle\Util\Functional\Mapping;
|
|
use Query\Operator;
|
|
|
|
$main_class = 'Parameters';
|
|
|
|
class Parameters extends Window
|
|
{
|
|
private AdminSectionTree $adminSectionTree;
|
|
|
|
protected $nameField = 'name';
|
|
|
|
protected $defaults = [
|
|
'figure' => 'Y',
|
|
];
|
|
|
|
public function __construct()
|
|
{
|
|
$this->adminSectionTree = ServiceContainer::getService(AdminSectionTree::class);
|
|
}
|
|
|
|
public function getTemplate()
|
|
{
|
|
if ($this->getAction() == 'merge') {
|
|
return 'window/parameters.merge.tpl';
|
|
}
|
|
|
|
return parent::getTemplate();
|
|
}
|
|
|
|
public function get_vars()
|
|
{
|
|
$vars = parent::get_vars();
|
|
$ID = $this->getID();
|
|
|
|
$pageVars = getVal('body', $vars);
|
|
|
|
$pageVars['tree'] = $this->adminSectionTree->getCategories();
|
|
$pageVars['category0'] = $this->adminSectionTree->getCategory0();
|
|
|
|
$this->selected = $pageVars['selected'] = Mapping::mapKeys(
|
|
sqlQueryBuilder()
|
|
->select('id_section, filter, required')
|
|
->from('parameters_sections')
|
|
->where(Operator::equals(['id_parameter' => $this->getID()]))
|
|
->execute()->fetchAllAssociative(),
|
|
function ($k, $v) {
|
|
return [$v['id_section'], ['filter' => $v['filter'] === 'Y', 'required' => $v['required'] === 'Y']];
|
|
}
|
|
);
|
|
|
|
$this->adminSectionTree->getSelected($ID, 'parameters_sections', 'id_parameter');
|
|
$this->adminSectionTree->getOpened($pageVars['tree']);
|
|
$pageVars['opened'] = $this->adminSectionTree->opened;
|
|
|
|
$pageVars['producers'] = sqlFetchAll(sqlQueryBuilder()
|
|
->select('id, name')
|
|
->from('producers')
|
|
->execute(), 'id');
|
|
|
|
if (findModule(Modules::PRODUCERS)) {
|
|
$pageVars['producersSel'] = sqlFetchAll(sqlQueryBuilder()
|
|
->select('id_producer')
|
|
->from('parameters_producers')
|
|
->where(Operator::equals(['id_parameter' => $ID]))
|
|
->execute(), ['id_producer' => 'id_producer']);
|
|
}
|
|
|
|
// Values
|
|
$parameter = new Parameter($ID);
|
|
$pageVars['values'] = $parameter->fetchListValues();
|
|
$pageVars['data']['searchTerm'] = getVal('searchTerm');
|
|
|
|
$vars['body'] = $pageVars;
|
|
|
|
return $vars;
|
|
}
|
|
|
|
public function getData()
|
|
{
|
|
$data = parent::getData();
|
|
|
|
if (!empty($data['unit'])) {
|
|
$data['unit'] = join('|', array_map(function ($value) {
|
|
return trim($value);
|
|
}, explode(',', $data['unit'])));
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
protected function getObject()
|
|
{
|
|
$data = parent::getObject();
|
|
|
|
$data['unit'] = str_replace('|', ', ', $data['unit']);
|
|
|
|
return $data;
|
|
}
|
|
|
|
protected function createObject()
|
|
{
|
|
$data = parent::createObject();
|
|
|
|
$data['data_type'] = 'float';
|
|
|
|
return $data;
|
|
}
|
|
|
|
public function handleUpdate()
|
|
{
|
|
$parameter = new Parameter();
|
|
$parameter->createFromDB($this->getID());
|
|
|
|
$SQL = parent::handleUpdate();
|
|
|
|
$ID = $this->getID();
|
|
|
|
if ($SQL) {
|
|
$data = $this->getData();
|
|
if ($parameter->unit && ($diff = array_diff($parameter->unit, explode('|', $data['unit'])))) {
|
|
sqlQueryBuilder()->update('parameters_products')
|
|
->set('unit', 'NULL')
|
|
->where(Operator::findInSet($diff, 'unit', 'OR'))
|
|
->andWhere(Operator::equals(['id_parameter' => $ID]))
|
|
->execute();
|
|
}
|
|
// ############################################
|
|
// # ZARAZENI DO SEKCI
|
|
if (findModule('products_sections')) {
|
|
$sec = getVal('sec', null, []);
|
|
$secloaded = getVal('secloaded', null, false);
|
|
|
|
if ($secloaded !== false) {
|
|
$this->saveParametersInSections($sec);
|
|
}
|
|
}
|
|
// ############################################
|
|
|
|
// ############################################
|
|
// # ZARAZENI K VYROBCUM
|
|
if (findModule('producers')) {
|
|
$this->saveProducersParameters(getVal('producers', default: []));
|
|
}
|
|
|
|
// ############################################
|
|
// # Hodnoty
|
|
$object = $this->getObject();
|
|
$data = $this->getData();
|
|
|
|
if ($object['value_type'] == 'list') {
|
|
$values = getVal('values', $data, []);
|
|
|
|
$this->createSQLFields('parameters_list');
|
|
foreach ($values as $id => $value) {
|
|
$value['id_parameter'] = $ID;
|
|
|
|
if (!empty($value['delete']) || !$id) {
|
|
unset($value['delete']);
|
|
|
|
if ($id > 0) {
|
|
$this->handleDeleteValue($id);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (empty($value['value'])) {
|
|
continue;
|
|
}
|
|
|
|
$value = $this->getSQLFields($value);
|
|
|
|
$value['data'] = empty($values[$id]['data']) ? null : json_encode($values[$id]['data']);
|
|
|
|
if ($id < 0 || $this->isDuplicate()) {
|
|
$this->handleAddValue($value);
|
|
} else {
|
|
$this->handleUpdateValue($id, $value);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($parameter->value_type != $data['value_type']) {
|
|
$conversion = new \KupShop\CatalogBundle\Parameters\TypeConversion();
|
|
$conversion->convert($parameter, $data['value_type']);
|
|
|
|
$this->returnOK('Změna typu proběhla úspěšně');
|
|
}
|
|
|
|
if (findModule(Modules::INDEXED_FILTER)) {
|
|
\KupShop\IndexedFilterBundle\Util\FilterUrlDefaultValue::upgrade_filter_url('parameters_list');
|
|
}
|
|
}
|
|
|
|
return $SQL;
|
|
}
|
|
|
|
public function handleDeleteValue($id)
|
|
{
|
|
$this->deleteSQL('parameters_list', ['id' => $id]);
|
|
writeDownActivity(translate('logDeleteValue', 'parameters').': '.$id);
|
|
}
|
|
|
|
public function handleAddValue($values)
|
|
{
|
|
$this->insertSQL('parameters_list', $values, ['id']);
|
|
}
|
|
|
|
public function handleUpdateValue($id, $values)
|
|
{
|
|
$this->updateSQL('parameters_list', $values, ['id' => $id], ['id', 'id_parameter']);
|
|
}
|
|
|
|
public function handleMerge()
|
|
{
|
|
if (!getVal('Submit')) {
|
|
return;
|
|
}
|
|
|
|
$merge_with = getVal('merge_with');
|
|
|
|
if (empty($merge_with)) {
|
|
$this->returnError('Musíte vybrat hodnotu/hodnoty, se kterými se má tato hodnota sloučit');
|
|
}
|
|
|
|
$id_value = getVal('id_value');
|
|
|
|
foreach ($merge_with as $merge_id) {
|
|
sqlQuery('INSERT INTO parameters_products (id_parameter, id_product, value_list, unit, weight)
|
|
SELECT id_parameter, id_product, :merge_id, unit, weight
|
|
FROM parameters_products WHERE value_list = :id_value', ['id_value' => $id_value, 'merge_id' => $merge_id]);
|
|
}
|
|
|
|
sqlQuery('DELETE FROM parameters_products WHERE value_list = :id_value', ['id_value' => $id_value]);
|
|
|
|
$this->returnOK();
|
|
}
|
|
|
|
public function handleSortAlphabet()
|
|
{
|
|
$ID = $this->getID();
|
|
|
|
$parameters = sqlQueryBuilder()->select('id, value')
|
|
->from('parameters_list', 'pl')
|
|
->where(Operator::equals(['id_parameter' => $ID]))
|
|
->execute()->fetchAll();
|
|
|
|
$collator = new Collator(\KupShop\KupShopBundle\Util\Contexts::get(LanguageContext::class)->getActive()->getLocale());
|
|
$collator->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON);
|
|
|
|
usort($parameters, function ($a, $b) use ($collator) {
|
|
$valueA = $a['value'];
|
|
$valueB = $b['value'];
|
|
|
|
$numericValueA = str_replace(',', '.', $valueA);
|
|
$numericValueB = str_replace(',', '.', $valueB);
|
|
|
|
if (is_numeric($numericValueA) && is_numeric($numericValueB)) {
|
|
return (float) $numericValueA <=> (float) $numericValueB;
|
|
}
|
|
|
|
return $collator->compare((string) $valueA, (string) $valueB);
|
|
});
|
|
|
|
$i = 0;
|
|
foreach ($parameters as $parameter) {
|
|
sqlQueryBuilder()->update('parameters_list', 'pl')
|
|
->directValues(['position' => ++$i])
|
|
->where(Operator::equals(['id' => $parameter['id']]))
|
|
->execute();
|
|
}
|
|
$this->returnOK();
|
|
}
|
|
|
|
/**
|
|
* @param array<int, array{ required?: 'on', filter?: 'on' }> $sections
|
|
*/
|
|
private function saveParametersInSections(array $sections): void
|
|
{
|
|
$ID = $this->getID();
|
|
|
|
if (FilterUtil::useOrderableFilters()) {
|
|
$sectionFilters = [];
|
|
|
|
$existingIdsMap = sqlQueryBuilder()
|
|
->select('sf.id_source_section', 'sf.id')
|
|
->from('sections_filters', 'sf')
|
|
->andWhere(Operator::equals(['sf.id_parameter' => $ID]))
|
|
->andWhere('sf.id_source_section IS NOT NULL')
|
|
->execute()
|
|
->fetchAllKeyValue();
|
|
|
|
// to delete
|
|
$relationsToDelete = sqlQueryBuilder()->select('ps.id_parameter', 'ps.id_section')
|
|
->from('parameters_sections', 'ps')
|
|
->andWhere(Operator::equals(['ps.id_parameter' => $ID]));
|
|
|
|
if (!empty($sections)) {
|
|
$relationsToDelete->andWhere(Operator::not(
|
|
Operator::inIntArray(array_keys($sections), 'ps.id_section'),
|
|
));
|
|
}
|
|
|
|
foreach ($relationsToDelete->execute() as $parameter) {
|
|
$id = $existingIdsMap[$parameter['id_section']] ?? null;
|
|
|
|
if ($id === null) {
|
|
continue;
|
|
}
|
|
|
|
$sectionFilters[] = SectionFilter::deleteParameter(
|
|
id: $id,
|
|
parameterId: (int) $parameter['id_parameter'],
|
|
sectionId: (int) $parameter['id_section'],
|
|
producerId: null,
|
|
);
|
|
}
|
|
|
|
// to update
|
|
foreach ($sections as $sectionId => $section) {
|
|
if (empty($sectionId) && $sectionId !== 0) {
|
|
continue;
|
|
}
|
|
|
|
$id = $existingIdsMap[$sectionId] ?? null;
|
|
|
|
$sectionFilters[] = SectionFilter::parameter(
|
|
id: $id,
|
|
parameterId: (int) $ID,
|
|
sectionId: (int) $sectionId,
|
|
producerId: null,
|
|
enabled: (bool) ($section['filter'] ?? false),
|
|
position: FilterUtil::POSITION_LAST,
|
|
required: (bool) ($section['required'] ?? false),
|
|
);
|
|
}
|
|
|
|
if (count($sectionFilters) > 0) {
|
|
$filterUtil = ServiceContainer::getService(FilterUtil::class);
|
|
$filterUtil->updateSectionFilters($sectionFilters);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
sqlQueryBuilder()->delete('parameters_sections')
|
|
->where(Operator::equals(['id_parameter' => $ID]))
|
|
->andWhere(Operator::not(Operator::inIntArray(array_keys($sections), 'id_section')))
|
|
->execute();
|
|
|
|
foreach ($sections as $key => $value) {
|
|
if (!empty($key) || $key === 0) {
|
|
sqlQuery(
|
|
'INSERT INTO parameters_sections (id_parameter, id_section, filter, required)
|
|
VALUES (:id_parameter, :id_section, :filter, :required)
|
|
ON DUPLICATE KEY UPDATE filter=VALUES(filter), required=VALUES(required)',
|
|
[
|
|
'id_parameter' => $ID,
|
|
'id_section' => $key,
|
|
'filter' => ($value['filter'] ?? false) ? 'Y' : 'N',
|
|
'required' => ($value['required'] ?? false) ? 'Y' : 'N',
|
|
]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function saveProducersParameters(array $producers): void
|
|
{
|
|
$producers = array_filter($producers, static fn ($producerId) => intval($producerId) > 0);
|
|
|
|
$ID = (int) $this->getID();
|
|
|
|
if (FilterUtil::useOrderableFilters()) {
|
|
$sectionFilters = [];
|
|
|
|
$existingIdsMap = sqlQueryBuilder()
|
|
->select('sf.id_source_producer', 'sf.id')
|
|
->from('sections_filters', 'sf')
|
|
->andWhere(Operator::equals(['sf.id_parameter' => $ID]))
|
|
->andWhere('sf.id_source_producer IS NOT NULL')
|
|
->execute()
|
|
->fetchAllKeyValue();
|
|
|
|
$producerParametersToDelete = sqlQueryBuilder()
|
|
->select('pp.id_producer', 'pp.id_parameter')
|
|
->from('parameters_producers', 'pp')
|
|
->andWhere(Operator::equals(['pp.id_parameter' => $ID]));
|
|
|
|
if (!empty($producers)) {
|
|
$producerParametersToDelete->andWhere(Operator::not(
|
|
Operator::inIntArray($producers, 'pp.id_producer'),
|
|
));
|
|
}
|
|
|
|
foreach ($producerParametersToDelete->execute() as $producer) {
|
|
$id = $existingIdsMap[$producer['id_producer']] ?? null;
|
|
|
|
$sectionFilters[] = SectionFilter::deleteParameter(
|
|
id: $id,
|
|
parameterId: $producer['id_parameter'],
|
|
sectionId: null,
|
|
producerId: (int) $producer['id_producer'],
|
|
);
|
|
}
|
|
|
|
foreach ($producers as $producerId) {
|
|
$id = $existingIdsMap[$producerId] ?? null;
|
|
|
|
$sectionFilters[] = SectionFilter::parameter(
|
|
id: $id,
|
|
parameterId: $ID,
|
|
sectionId: null,
|
|
producerId: (int) $producerId,
|
|
enabled: true,
|
|
position: FilterUtil::POSITION_LAST,
|
|
);
|
|
}
|
|
|
|
if (count($sectionFilters) > 0) {
|
|
$filterUtil = ServiceContainer::getService(FilterUtil::class);
|
|
$filterUtil->updateSectionFilters($sectionFilters);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// delete old relations that are no longer present
|
|
sqlQueryBuilder()->delete('parameters_producers')
|
|
->andWhere(Operator::equals(['id_parameter' => $ID]))
|
|
->andWhere(Operator::not(Operator::inIntArray(array_values($producers), 'id_producer')))
|
|
->execute();
|
|
|
|
// fetch existing relations (no matter if invalid ones are still present because of maxscale lag)
|
|
$existingProducerIDs = sqlQueryBuilder()->select('id_producer')->from('parameters_producers')
|
|
->where(Operator::equals(['id_parameter' => $ID]))->execute()->fetchFirstColumn();
|
|
|
|
$insertNewParams = sqlQueryBuilder()->insert('parameters_producers');
|
|
$hasNewRelations = false;
|
|
foreach ($producers as $IDProd) {
|
|
if (in_array($IDProd, $existingProducerIDs)) {
|
|
continue; // skip existing relations
|
|
}
|
|
$hasNewRelations = true;
|
|
$insertNewParams->multiDirectValues([
|
|
'id_parameter' => $ID,
|
|
'id_producer' => $IDProd,
|
|
]);
|
|
}
|
|
|
|
if ($hasNewRelations) {
|
|
$insertNewParams->execute();
|
|
}
|
|
}
|
|
}
|