PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.8.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.8.0
1.8.0 1.7.1 1.7.0 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 All 52 releases
fluent-cart / app / Models / ProductDetail.php

ProductDetail.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.8.0, at app/Models/ProductDetail.php

198 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Models;
4
5 use FluentCart\App\Helpers\Helper;
6 use FluentCart\App\Models\Concerns\CanSearch;
7 use FluentCart\App\Models\Concerns\CanUpdateBatch;
8 use FluentCart\Framework\Database\Orm\Relations\BelongsTo;
9 use FluentCart\Framework\Database\Orm\Relations\HasMany;
10 use FluentCart\Framework\Database\Orm\Relations\HasOne;
11 use FluentCart\App\Models\WpModels\PostMeta;
12 use FluentCart\Framework\Support\Arr;
13
14 /**
15 * Product Details Model - DB Model for Product Details
16 *
17 * Database Model
18 *
19 *
20 * @package FluentCart\App\Models
21 *
22 * @version 1.0.0
23 */
24 class ProductDetail extends Model
25 {
26
27 use CanSearch, CanUpdateBatch;
28
29 protected $table = 'fct_product_details';
30
31 protected $guarded = [
32 'id',
33 ];
34
35 protected $fillable = [
36 'post_id',
37 'fulfillment_type',
38 'min_price',
39 'max_price',
40 'default_variation_id',
41 'variation_type',
42 'stock_availability',
43 'other_info',
44 'default_media',
45 'manage_stock',
46 'manage_downloadable'
47 ];
48
49 /**
50 * The attributes that should be cast.
51 *
52 * @var array
53 */
54 protected $casts = [
55 'post_id' => 'integer',
56 'min_price' => 'double',
57 'max_price' => 'double',
58 ];
59
60 protected $appends = ['featured_media', 'formatted_min_price', 'formatted_max_price'];
61
62 public function setOtherInfoAttribute($value)
63 {
64 if (is_array($value) || is_object($value)) {
65 $this->attributes['other_info'] = json_encode($value);
66 } else {
67 $this->attributes['other_info'] = $value;
68 }
69 }
70
71 public function getOtherInfoAttribute($value)
72 {
73 return !empty($value) ? json_decode($value, true) : null;
74 }
75
76
77 protected function getFormattedMinPriceAttribute()
78 {
79 return Helper::toDecimal($this->min_price);
80 }
81
82 protected function getFormattedMaxPriceAttribute()
83 {
84 return Helper::toDecimal($this->max_price);
85 }
86
87
88 /**
89 * Products whose own reviews switch is off; a missing key counts as on.
90 * Raw because the connection turns the double quotes of JSON selectors
91 * (other_info->reviews_enabled) into backticks. Table-qualified so it holds
92 * inside correlated subqueries on this table.
93 */
94 public function scopeReviewsDisabled($query)
95 {
96 $otherInfo = $query->getQuery()->getGrammar()->wrap($this->getTable() . '.other_info');
97
98 return $query->whereRaw("JSON_UNQUOTE(JSON_EXTRACT({$otherInfo}, '$.reviews_enabled')) = 'no'");
99 }
100
101 /**
102 * One2One: Product Details belongs to one Product
103 *
104 * @return BelongsTo
105 */
106 public function product(): BelongsTo
107 {
108 return $this->belongsTo(Product::class, 'post_id', 'ID');
109 }
110
111 /**
112 * One2One: Product Details belongs to one Gallery Image
113 * @return HasOne
114 */
115 public function galleryImage(): HasOne
116 {
117 return $this->hasOne(PostMeta::class, 'post_id', 'post_id')
118 ->where('postmeta.meta_key', 'fluent-products-gallery-image');
119 }
120
121 // First element of Gallery Image which is considered as featured image
122 public function getFeaturedMediaAttribute()
123 {
124 $meta = $this->galleryImage;
125
126 if ($meta && is_array($meta->meta_value) && !empty($meta->meta_value)) {
127 return Arr::first($meta->meta_value); // Return the first element
128 }
129
130 return null;
131 }
132
133 public function variants(): HasMany
134 {
135 return $this->hasMany(ProductVariation::class, 'post_id', 'post_id')->orderBy('serial_index', 'asc');
136 }
137
138 public function setDefaultMediaAttribute($value)
139 {
140 if (is_array($value) || is_object($value)) {
141 $this->attributes['default_media'] = json_encode($value);
142 } else {
143 $this->attributes['default_media'] = $value;
144 }
145 }
146
147 public function getDefaultMediaAttribute($value)
148 {
149 return !empty($value) ? json_decode($value, true) : null;
150 }
151
152 public function hasPriceVariation()
153 {
154 return $this->variation_type === 'simple' && $this->max_price !== $this->min_price;
155 }
156
157 public function getStockAvailability($variationId = null)
158 {
159
160 if (!$this->manage_stock) {
161 $availability = [
162 'manage_stock' => false,
163 'availability' => __('In Stock', 'fluent-cart'),
164 'class' => 'in-stock',
165 'available_quantity' => null
166 ];
167 } else if ($this->stock_availability === 'in-stock') {
168 $availability = [
169 'manage_stock' => true,
170 'availability' => __('In Stock', 'fluent-cart'),
171 'class' => 'in-stock',
172 'available_quantity' => $this->stock_availability
173 ];
174 } else {
175 $availability = [
176 'manage_stock' => true,
177 'availability' => __('Out of Stock', 'fluent-cart'),
178 'class' => 'out-of-stock',
179 'available_quantity' => $this->stock_availability
180 ];
181 }
182
183 return apply_filters('fluent_cart/product_stock_availability', $availability, [
184 'detail' => $this,
185 'variation_id' => $variationId
186 ]);
187 }
188 public function getMinPriceAttribute()
189 {
190 return $this->variants()->min('item_price');
191 }
192
193 public function getMaxPriceAttribute()
194 {
195 return $this->variants()->max('item_price');
196 }
197 }
198