'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 $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(); } } }