|
|
@@ -503,6 +503,74 @@ class Product extends BaseProduct
|
|
|
return $this->hasMany(AttributeValue::class, 'product_id');
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Get all custom attribute values for this product.
|
|
|
+ *
|
|
|
+ * Aggregates every `attribute_values` row into a flat list of
|
|
|
+ * `{ code, label, value }` entries (resolved for the current
|
|
|
+ * locale/channel). Exposed to GraphQL/REST as `attributes` so any
|
|
|
+ * attribute added later in the Attributes table is surfaced
|
|
|
+ * automatically without code changes.
|
|
|
+ *
|
|
|
+ * @return \Webkul\BagistoApi\Dto\ProductDetail\ProductAttributeDto[]
|
|
|
+ */
|
|
|
+ public function getAttributesAttribute(): array
|
|
|
+ {
|
|
|
+ if (! $this->relationLoaded('attribute_values')) {
|
|
|
+ $this->load('attribute_values.attribute');
|
|
|
+ } elseif (! $this->attribute_values->first()?->relationLoaded('attribute')) {
|
|
|
+ $this->load('attribute_values.attribute');
|
|
|
+ }
|
|
|
+
|
|
|
+ $currentLocale = $this->locale ?? app()->getLocale();
|
|
|
+ $currentChannel = $this->channel ?? (core()->getCurrentChannel()->code ?? 'default');
|
|
|
+
|
|
|
+ $localeVariants = array_values(array_unique(array_filter([
|
|
|
+ $currentLocale,
|
|
|
+ core()->getCurrentChannel()->default_locale?->code,
|
|
|
+ null,
|
|
|
+ ])));
|
|
|
+
|
|
|
+ $channelVariants = [$currentChannel, null];
|
|
|
+
|
|
|
+ $seen = [];
|
|
|
+ $result = [];
|
|
|
+
|
|
|
+ foreach ($this->attribute_values as $av) {
|
|
|
+ $code = $av->attribute?->code;
|
|
|
+
|
|
|
+ if (! $code) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Only keep the best (most specific) match per attribute code.
|
|
|
+ if (isset($seen[$code])) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $locale = $av->locale;
|
|
|
+ $channel = $av->channel;
|
|
|
+
|
|
|
+ $localeRank = array_search($locale, $localeVariants, true);
|
|
|
+ $channelRank = array_search($channel, $channelVariants, true);
|
|
|
+
|
|
|
+ // Ignore rows that don't match the current locale/channel scope.
|
|
|
+ if ($localeRank === false || $channelRank === false) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $seen[$code] = true;
|
|
|
+
|
|
|
+ $result[] = new \Webkul\BagistoApi\Dto\ProductDetail\ProductAttributeDto(
|
|
|
+ code: $code,
|
|
|
+ label: $av->attribute?->admin_name ?? $av->attribute?->name ?? $code,
|
|
|
+ value: $av->value,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Get locale context.
|
|
|
*/
|