diff --git a/classes/index/ProductEntry.php b/classes/index/ProductEntry.php index 1ea8d68f..f89dce04 100644 --- a/classes/index/ProductEntry.php +++ b/classes/index/ProductEntry.php @@ -90,7 +90,19 @@ protected function mapProps(?Collection $input): Collection } return $input->groupBy('property_id')->map(function ($value) { - return $value->pluck('index_value')->unique()->filter()->values(); + return $value->pluck('index_value') + ->unique() + ->filter() + ->flatMap(function ($indexValue) { + // Handle checkboxlist values stored as dot-separated string + if (strpos($indexValue, '.') !== false) { + return explode('.', $indexValue); + } + return [$indexValue]; + }) + ->unique() + ->filter() + ->values(); })->filter(); } } diff --git a/classes/index/VariantEntry.php b/classes/index/VariantEntry.php index 7db3b193..1170b819 100644 --- a/classes/index/VariantEntry.php +++ b/classes/index/VariantEntry.php @@ -98,7 +98,19 @@ protected function mapProps(?Collection $input): Collection } return $input->groupBy('property_id')->map(function ($value) { - return $value->pluck('index_value')->unique()->filter()->values(); + return $value->pluck('index_value') + ->unique() + ->filter() + ->flatMap(function ($indexValue) { + // Handle checkboxlist values stored as dot-separated string + if (strpos($indexValue, '.') !== false) { + return explode('.', $indexValue); + } + return [$indexValue]; + }) + ->unique() + ->filter() + ->values(); })->filter(); } } diff --git a/classes/queries/UniquePropertyValuesInCategoriesQuery.php b/classes/queries/UniquePropertyValuesInCategoriesQuery.php index c2b7d05b..fc799ab5 100644 --- a/classes/queries/UniquePropertyValuesInCategoriesQuery.php +++ b/classes/queries/UniquePropertyValuesInCategoriesQuery.php @@ -74,4 +74,63 @@ public function query() 'winter_mall_property_values.product_id' ); } + + /** + * Get all unique property values, properly handling checkboxlist JSON arrays. + * + * @return Collection + */ + public function get() + { + $raw = $this->query()->get(); + + // Process the results to expand checkboxlist JSON values into individual entries + $processed = collect(); + foreach ($raw as $row) { + $propertyId = $row->property_id; + $value = $row->value; + $indexValue = $row->index_value; + + // Check if this value is a JSON array (checkboxlist with multiple values) + $decoded = json_decode($value, true); + if (is_array($decoded) && !$this->isAssoc($decoded)) { + // This is a checkboxlist JSON array - create individual entries for each value + foreach ($decoded as $singleValue) { + $sluggedValue = str_slug($singleValue); + // Avoid duplicates + $key = $propertyId . '_' . $sluggedValue; + if (!$processed->has($key)) { + $processed->put($key, (object)[ + 'id' => $row->id, + 'value' => $singleValue, + 'index_value' => $sluggedValue, + 'property_id' => $propertyId, + ]); + } + } + } else { + // Regular value - keep as is + $key = $propertyId . '_' . $indexValue; + if (!$processed->has($key)) { + $processed->put($key, $row); + } + } + } + + return $processed->values(); + } + + /** + * Check if an array is associative (not a sequential list). + * + * @param array $arr + * @return bool + */ + private function isAssoc(array $arr) + { + if (empty($arr)) { + return false; + } + return array_keys($arr) !== range(0, count($arr) - 1); + } } diff --git a/formwidgets/PropertyFields.php b/formwidgets/PropertyFields.php index f59fe8ce..7b40fdad 100644 --- a/formwidgets/PropertyFields.php +++ b/formwidgets/PropertyFields.php @@ -273,7 +273,11 @@ private function dropdown($property, PropertyValue $value) private function checkboxlist($property, PropertyValue $value) { - $escapedValue = json_decode($value->value, true); + $rawValue = $value->getAttributeTranslated('value') ?? $value->attributes['value'] ?? ''; + $escapedValue = is_string($rawValue) ? json_decode($rawValue, true) : $rawValue; + if (!is_array($escapedValue)) { + $escapedValue = []; + } $formField = $this->newFormField($property); $formField->value = $escapedValue; diff --git a/models/Property.php b/models/Property.php index 92d5dcc3..680efa78 100644 --- a/models/Property.php +++ b/models/Property.php @@ -94,7 +94,7 @@ public function getSortOrderAttribute() public static function getValuesForCategory($categories) { - $raw = (new UniquePropertyValuesInCategoriesQuery($categories))->query()->get(); + $raw = (new UniquePropertyValuesInCategoriesQuery($categories))->get(); $values = PropertyValue::hydrate($raw->toArray())->load(['property.translations', 'translations']); $values = $values->groupBy('property_id')->map(function ($values) { // if this property has options make sure to restore the original order @@ -106,7 +106,11 @@ public static function getValuesForCategory($categories) $order = collect($firstProp->options)->flatten()->flip(); return $values->sortBy(function ($value) use ($order) { - return $order[$value->value] ?? 0; + $sortValue = $value->value; + if (is_array($sortValue)) { + $sortValue = reset($sortValue); + } + return $order[$sortValue] ?? 0; }); }); diff --git a/models/PropertyValue.php b/models/PropertyValue.php index 12a22e0b..004e5e6e 100644 --- a/models/PropertyValue.php +++ b/models/PropertyValue.php @@ -56,7 +56,19 @@ public function beforeSave() if ($this->isColor()) { $value = $this->jsonDecodeValue()['name'] ?? ''; } - $this->index_value = str_slug($value); + $type = optional($this->property)->type; + if ($type === 'checkboxlist') { + $decoded = json_decode($value, true); + if (is_array($decoded)) { + $this->index_value = implode('.', array_map(function($item) { + return str_slug($item); + }, $decoded)); + } else { + $this->index_value = str_slug($value); + } + } else { + $this->index_value = str_slug($value); + } } public function setValueAttribute($value) @@ -90,6 +102,11 @@ public function getValueAttribute() return $this->jsonDecodeValue($value); } + if ($type === 'checkboxlist') { + $decoded = json_decode($value, true); + return is_array($decoded) ? $decoded : [$value]; + } + return $value; } @@ -125,6 +142,14 @@ public function getDisplayValueAttribute() return trans('winter.mall::lang.common.' . $key); } + if ($type === 'checkboxlist') { + $decoded = json_decode($value, true); + if (is_array($decoded)) { + return e(implode(', ', $decoded)); + } + return e($value); + } + return e($value); }