Logic improvements

- Add getAttributeValueByAttributeId() to assist in comparing the value
- Corrected Business logic
- Added attribute_helper.php
- Simplified logic to store attribute values
- Removed duplicate call to save attribute link

Signed-off-by: objec <objecttothis@gmail.com>
This commit is contained in:
objec
2026-03-05 17:13:51 +04:00
parent f731711846
commit 855f08c4df
4 changed files with 64 additions and 21 deletions

View File

@@ -100,6 +100,7 @@ const CHECKBOX = 'CHECKBOX';
const NO_DEFINITION_ID = 0;
const CATEGORY_DEFINITION_ID = -1;
const DEFINITION_TYPES = [GROUP, DROPDOWN, DECIMAL, TEXT, DATE, CHECKBOX];
const ATTRIBUTE_VALUE_TYPES = ['attribute_value', 'attribute_decimal', 'attribute_date'];
/**
* Item Related Constants.

View File

@@ -1200,9 +1200,8 @@ class Items extends Secure_Controller
*/
private function saveAttributeData(array $row, array $itemData, array $definitions): bool
{
helper('attribute');
foreach ($definitions as $definition) {
$attribute_name = $definition['definition_name'];
$attribute_value = $row["attribute_$attribute_name"];
$attributeName = $definition['definition_name'];
$attributeValue = $row["attribute_$attributeName"];
@@ -1245,10 +1244,6 @@ class Items extends Secure_Controller
$this->attribute->deleteAttributeLinks($itemId, $attributeData['definition_id']);
if (!$attribute_id) {
$attribute_id = $this->attribute->saveAttributeValue($value, $attribute_data['definition_id'], $item_id, false, $attribute_data['definition_type']);
} elseif (!$this->attribute->saveAttributeLink($item_id, $attribute_data['definition_id'], $attribute_id)) {
return false;
if (!$attributeId) {
$attributeId = $this->attribute->saveAttributeValue($value, $attributeData['definition_id'], $itemId, false, $attributeData['definition_type']);
} else {
@@ -1378,16 +1373,15 @@ class Items extends Secure_Controller
switch ($definitionType) {
case DROPDOWN:
$attributeId = $attributeValue;
$this->attribute->saveAttributeLink($itemId, $definitionId, $attributeId);
break;
case DECIMAL:
$attributeValue = parse_decimals($attributeValue);
// Fall through to save the attribute value
// no break
default:
$attributeId = $this->attribute->saveAttributeValue($attributeValue, $definitionId, $itemId, $attributeIds[$definitionId], $definitionType);
break;
}
$this->attribute->saveAttributeLink($itemId, $definitionId, $attributeId);
}
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Translates the attribute type to the corresponding database column name.
*
* Maps attribute type constants to their corresponding attribute_values table columns.
* Defaults to 'attribute_value' for TEXT, DROPDOWN and CHECKBOX attribute types.
*
* @param string $input The attribute type constant (DATE, DECIMAL, etc.)
* @return string The database column name for storing this attribute type
*/
function getAttributeDataType(string $input): string
{
$columnMap = [
DATE => 'attribute_date',
DECIMAL => 'attribute_decimal',
];
return $columnMap[$input] ?? 'attribute_value';
}
/**
* Validates that the provided data type is an allowed attribute value type.
*
* @param string $dataType
* @return void
*/
function validateAttributeValueType(string $dataType): void
{
if (!in_array($dataType, ATTRIBUTE_VALUE_TYPES, true)) {
throw new InvalidArgumentException('Invalid data type');
}
}

View File

@@ -708,6 +708,31 @@ class Attribute extends Model
return $this->getEmptyObject('attribute_values');
}
/**
* Gets a single attribute value by attribute ID.
*
* @param int $attributeId The attribute ID to look up
* @param string $dataType The column name to retrieve (attribute_value, attribute_date, or attribute_decimal)
* @return string|float|null The attribute value. Note: MySQL returns values as follows:
* - attribute_value (TEXT): string
* - attribute_date (DATE): string in 'Y-m-d' format
* - attribute_decimal (DECIMAL): string or float depending on CodeIgniter configuration
* Returns null if the attribute_id is not found.
*/
public function getAttributeValueByAttributeId(int $attributeId, string $dataType): string|float|null
{
helper('attribute');
validateAttributeValueType($dataType);
$builder = $this->db->table('attribute_values');
$builder->select($dataType);
$builder->where('attribute_id', $attributeId);
$builder->limit(1);
$row = $builder->get()->getRow();
return $row ? $row->$dataType : null;
}
/**
* Initializes an empty object based on database definitions
* @param string $table_name
@@ -816,20 +841,10 @@ class Attribute extends Model
$existingAttributeId = $this->attributeValueExists($attributeValue, $definitionType);
// New Attribute
if (empty($attribute_id) || empty($item_id) || $attribute_id == -1) {
$attribute_id = $this->attributeValueExists($attribute_value, $definition_type);
// Update
if ($existingAttributeId) {
if (!$attribute_id) {
$builder = $this->db->table('attribute_values');
$builder->set(["attribute_$data_type" => $attribute_value]);
$builder->insert();
$attribute_id = $this->db->insertID();
}
$attributeId = $existingAttributeId;
$storedValue = $this->getAttributeValueByAttributeId($attributeId, $dataType);
if ($dataType === 'attribute_value'
&& is_string($storedValue)