241 lines
7.5 KiB
PHP
241 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace KupShop\CatalogBundle\Parameters;
|
|
|
|
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
|
use Query\Operator;
|
|
|
|
class ParameterFinder
|
|
{
|
|
use \DatabaseCommunication;
|
|
|
|
protected $listParameter;
|
|
protected $listParameterValues;
|
|
protected $parameterInstancesCache = [];
|
|
|
|
protected function loadParametersCache()
|
|
{
|
|
if (is_null($this->listParameter)) {
|
|
$this->listParameter = sqlFetchAll(sqlQuery('SELECT par.*, LOWER(name) as name FROM parameters par'), 'id');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return \Parameter
|
|
*/
|
|
public function getParameter($id_parameter)
|
|
{
|
|
$this->loadParametersCache();
|
|
|
|
if (!($this->parameterInstancesCache[$id_parameter] ?? false)) {
|
|
$parameter = new \Parameter();
|
|
$parameter->createFromArray($this->listParameter[$id_parameter]);
|
|
|
|
$this->parameterInstancesCache[$id_parameter] = $parameter;
|
|
}
|
|
|
|
return $this->parameterInstancesCache[$id_parameter];
|
|
}
|
|
|
|
public function getParameterById(int $parameterId): ?\Parameter
|
|
{
|
|
$this->loadParametersCache();
|
|
|
|
if (!($this->listParameter[$parameterId] ?? false)) {
|
|
return null;
|
|
}
|
|
|
|
if (!($this->parameterInstancesCache[$parameterId] ?? false)) {
|
|
$parameter = new \Parameter();
|
|
$parameter->createFromArray($this->listParameter[$parameterId]);
|
|
|
|
$this->parameterInstancesCache[$parameterId] = $parameter;
|
|
}
|
|
|
|
return $this->parameterInstancesCache[$parameterId];
|
|
}
|
|
|
|
public function getParameterId(string $name): ?int
|
|
{
|
|
$this->loadParametersCache();
|
|
|
|
$nameLower = mb_strtolower($name);
|
|
foreach ($this->listParameter as $id => $parameter) {
|
|
if ($parameter['name'] == $nameLower) {
|
|
return (int) $id;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function findParameter($name, $type = 'list')
|
|
{
|
|
if ($name == '') {
|
|
return null;
|
|
}
|
|
|
|
$this->loadParametersCache();
|
|
|
|
if ($parameterId = $this->getParameterId($name)) {
|
|
return $parameterId;
|
|
}
|
|
|
|
$nameLower = mb_strtolower($name);
|
|
|
|
$max_position = returnSQLResult('SELECT MAX(position) FROM parameters');
|
|
try {
|
|
$index = sqlGetConnection()->transactional(function () use ($name, $max_position, $type) {
|
|
$this->insertSQL('parameters', ['name' => $name, 'position' => $max_position + 1, 'value_type' => $type]);
|
|
|
|
return sqlInsertId();
|
|
});
|
|
} catch (UniqueConstraintViolationException $e) {
|
|
$index = $this->selectSQL('parameters', ['name' => $name])->fetch()['id'];
|
|
}
|
|
|
|
$this->listParameter[$index] = ['id' => $index, 'name' => $nameLower, 'position' => $max_position + 1, 'value_type' => $type];
|
|
|
|
return $index;
|
|
}
|
|
|
|
public function getParameterValueId(int $parameterId, string $value): ?int
|
|
{
|
|
if ($index = array_search(mb_strtolower($value), $this->getListParametersValuesCache($parameterId))) {
|
|
return $index;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function findParameterValue($parameter_id, $value)
|
|
{
|
|
if ($value == '') {
|
|
return null;
|
|
}
|
|
|
|
$params = $this->getListParametersValuesCache($parameter_id);
|
|
|
|
if ($index = array_search(mb_strtolower($value), $params)) {
|
|
return $index;
|
|
}
|
|
|
|
try {
|
|
$index = sqlGetConnection()->transactional(function () use ($value, $parameter_id) {
|
|
$this->insertSQL('parameters_list', ['value' => $value, 'id_parameter' => $parameter_id]);
|
|
|
|
return sqlInsertId();
|
|
});
|
|
} catch (\Exception $e) {
|
|
$index = sqlFetchAssoc($this->selectSQL('parameters_list', ['value' => $value, 'id_parameter' => $parameter_id], ['id']))['id'];
|
|
}
|
|
|
|
$this->listParameterValues[$parameter_id][$index] = mb_strtolower($value);
|
|
|
|
return $index;
|
|
}
|
|
|
|
private function getListParametersValuesCache(int $parameterId): array
|
|
{
|
|
if (!isset($this->listParameterValues[$parameterId])) {
|
|
$values = sqlQuery('SELECT id, LOWER(value) as value
|
|
FROM parameters_list WHERE id_parameter=:id_parameter',
|
|
['id_parameter' => $parameterId]);
|
|
$this->listParameterValues[$parameterId] = sqlFetchAll($values, ['id' => 'value']);
|
|
}
|
|
|
|
return $this->listParameterValues[$parameterId] ?? [];
|
|
}
|
|
|
|
/**
|
|
* @param string $parameter Parameter name
|
|
* @param string $value Parameter value
|
|
* @param string $type Parameter type
|
|
*
|
|
* @return array array with keys "id_parameter" and "value"
|
|
*/
|
|
public function findParameterAndValue($parameter, $value, $type = 'list')
|
|
{
|
|
$id_parameter = $this->findParameter($parameter, $type);
|
|
|
|
if ($type == 'list') {
|
|
$value = $this->findParameterValue($id_parameter, $value);
|
|
}
|
|
|
|
return ['id_parameter' => $id_parameter, 'value' => $value];
|
|
}
|
|
|
|
/** Replace all product parameter values with new one.
|
|
*/
|
|
public function setProductParameters($id_product, $id_parameter, $values)
|
|
{
|
|
$parameter = $this->getParameter($id_parameter);
|
|
|
|
$data = ['id_parameter' => $id_parameter, 'id_product' => $id_product];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
foreach ($values as $value) {
|
|
if (empty($value)) {
|
|
continue;
|
|
}
|
|
$data['value'] = $value;
|
|
$parameter->setValue($data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Narozdil od `setProductParameters` neprovadi pokazde delete a insert, takze je mene narocna pro
|
|
* databazi a negeneruje tak velke mnozstvi dat do binlogu.
|
|
*/
|
|
public function updateProductParameters(int $productId, int $parameterId, array $values): void
|
|
{
|
|
if (!($parameter = $this->getParameterById($parameterId))) {
|
|
return;
|
|
}
|
|
|
|
$valueField = "value_{$parameter->value_type}";
|
|
|
|
// nactu si aktualni hodnoty parametru od produktu
|
|
$oldValues = sqlQueryBuilder()
|
|
->select('id', $valueField)
|
|
->from('parameters_products')
|
|
->where(Operator::equals(['id_parameter' => $parameterId, 'id_product' => $productId]))
|
|
->orderBy('id', 'ASC')
|
|
->execute()->fetchAllAssociative();
|
|
|
|
$oldValuesOnly = array_map(fn ($x) => $x[$valueField], $oldValues);
|
|
|
|
// najdu si hodnoty, ktere mam smazat
|
|
$deleteDiff = array_diff_assoc($oldValuesOnly, $values);
|
|
// najdu si hodnoty, ktere mam insertovat
|
|
$insertDiff = array_diff_assoc($values, $oldValuesOnly);
|
|
|
|
$deleteIds = [];
|
|
// chci to mazat podle ID, takze dohledam ID
|
|
foreach ($deleteDiff as $position => $value) {
|
|
$deleteIds[] = $oldValues[$position]['id'];
|
|
}
|
|
|
|
// provedu delete
|
|
if (!empty($deleteIds)) {
|
|
sqlQueryBuilder()
|
|
->delete('parameters_products')
|
|
->andWhere(Operator::inIntArray($deleteIds, 'id'))
|
|
->execute();
|
|
}
|
|
|
|
// provedu insert
|
|
foreach ($insertDiff as $value) {
|
|
sqlQueryBuilder()
|
|
->insert('parameters_products')
|
|
->directValues(
|
|
[
|
|
'id_parameter' => $parameterId,
|
|
'id_product' => $productId,
|
|
$valueField => $value,
|
|
]
|
|
)->execute();
|
|
}
|
|
}
|
|
}
|