|
|
@@ -498,6 +498,8 @@ class Product extends BaseProduct
|
|
|
'super_attributes',
|
|
|
'variants',
|
|
|
'price_indices',
|
|
|
+ 'flexibleVariants',
|
|
|
+
|
|
|
];
|
|
|
|
|
|
protected $appends = [
|
|
|
@@ -512,6 +514,7 @@ class Product extends BaseProduct
|
|
|
'index', 'combinations', 'super_attribute_options',
|
|
|
];
|
|
|
|
|
|
+
|
|
|
protected static array $systemAttributes = [
|
|
|
'sku' => ['id' => 1],
|
|
|
'name' => ['id' => 2],
|
|
|
@@ -742,6 +745,58 @@ class Product extends BaseProduct
|
|
|
$this->images = $value;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Flexible variants — overrides the parent's flexibleVariants() so that
|
|
|
+ * BagistoApi's ProductVariant wrapper (which has variant_images / values
|
|
|
+ * relations) is used instead of the bare Longyi\Core\Models\ProductVariant.
|
|
|
+ */
|
|
|
+ public function flexibleVariants(): HasMany
|
|
|
+ {
|
|
|
+ return $this->hasMany(ProductVariant::class, 'product_id')
|
|
|
+ ->orderBy('sort_order');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * snake_case alias of flexibleVariants().
|
|
|
+ *
|
|
|
+ * ApiPlatform's Laravel PropertyAccessor accesses Eloquent models directly
|
|
|
+ * via $model->{$snake_case_property} and bypasses Symfony's camelize logic.
|
|
|
+ * Eloquent's isRelation() uses method_exists() with a literal key match, so
|
|
|
+ * we need a method actually named 'flexible_variants' for the to-many
|
|
|
+ * property access to resolve to the relation Collection.
|
|
|
+ *
|
|
|
+ * Both methods return the same relation — ApiPlatform's Eloquent metadata
|
|
|
+ * factory deduplicates them into a single 'flexible_variants' property name.
|
|
|
+ */
|
|
|
+ public function flexible_variants(): HasMany // phpcs:ignore
|
|
|
+ {
|
|
|
+ return $this->flexibleVariants();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Mirror the camelCase-loaded relation into the snake_case slot so that
|
|
|
+ * $product->flexible_variants does not trigger a second DB query when
|
|
|
+ * $with = ['flexibleVariants'] has already eager-loaded the variants.
|
|
|
+ */
|
|
|
+ public function getRelationValue($key)
|
|
|
+ {
|
|
|
+ if ($key === 'flexible_variants'
|
|
|
+ && ! $this->relationLoaded('flexible_variants')
|
|
|
+ && $this->relationLoaded('flexibleVariants')
|
|
|
+ ) {
|
|
|
+ $collection = $this->getRelation('flexibleVariants');
|
|
|
+ $this->setRelation('flexible_variants', $collection);
|
|
|
+
|
|
|
+ if ($collection->isNotEmpty() && ! $collection->first()->relationLoaded('variant_images')) {
|
|
|
+ $collection->loadMissing(['variant_images', 'values.option']);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $collection;
|
|
|
+ }
|
|
|
+
|
|
|
+ return parent::getRelationValue($key);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* The videos that belong to the product.
|
|
|
*/
|