PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.26
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.26
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 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / app / Http / Requests / ProductVariationRequest.php

ProductVariationRequest.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.26, at app/Http/Requests/ProductVariationRequest.php

275 lines 13.0 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\Http\Requests;
4
5 use FluentCart\Framework\Foundation\RequestGuard;
6 use FluentCart\Framework\Support\Arr;
7
8 class ProductVariationRequest extends RequestGuard
9 {
10 /**
11 * Normalize variant data before validation.
12 *
13 * This method is primarily used to ensure that the `variants` array contains
14 * the required structure, especially during data migration or when
15 * optional fields like `other_info` are not provided.
16 *
17 * Key operations:
18 * - Sets a default `fulfillment_type` (fallback to 'physical') if missing.
19 * - Sets a default `payment_type` (fallback to 'onetime') if missing.
20 * - Ensures `other_info` exists and assigns default billing/setup fee-related values if it's empty.
21 *
22 * This helps avoid issues during validation or processing by guaranteeing a consistent data structure.
23 *
24 * @return array The normalized data ready for validation.
25 */
26 public function beforeValidation()
27 {
28 $data = $this->all();
29 $fulfilmentType = Arr::get(
30 $data,
31 'variants.fulfillment_type',
32 Arr::get($data, 'variants.fulfillment_type', 'physical')
33 );
34 $paymentType = Arr::get($data, 'variants.payment_type', 'onetime');
35 $manageCost = Arr::get($data, 'variants.manage_cost');
36 if (empty($manageCost)) {
37 $manageCost = 'false';
38 }
39 $data['variants']['fulfillment_type'] = $fulfilmentType;
40 $data['variants']['manage_cost'] = $manageCost;
41
42 $variantOtherInfo = Arr::wrap(Arr::get($data, 'variants.other_info'));
43
44 // Ensure other_info is an array
45 if (empty($variantOtherInfo)) {
46 $variantOtherInfo = [
47 'payment_type' => $paymentType,
48 'times' => '',
49 'trial_days' => '',
50 'repeat_interval' => 'yearly',
51 'billing_summary' => '',
52 'manage_setup_fee' => 'no',
53 'signup_fee_name' => '',
54 'signup_fee' => '',
55 'setup_fee_per_item' => 'no',
56 //'purchasable' => 'yes',
57
58 ];
59 }
60 $data['variants']['other_info'] = $variantOtherInfo;
61
62 if (Arr::get($variantOtherInfo, 'payment_type') === 'onetime') {
63 $subscriptionFields = ['trial_days', 'times', 'repeat_interval', 'billing_summary', 'manage_setup_fee', 'signup_fee', 'signup_fee_name', 'setup_fee_per_item'];
64 foreach ($subscriptionFields as $field) {
65 unset($data['variants']['other_info'][$field]);
66 }
67 }
68
69 return $data;
70 }
71
72 /**
73 * @return array
74 */
75 public function rules()
76 {
77 return [
78 'variants.variation_title' => 'required|sanitizeText|maxLength:200',
79 'variants.sku' => 'nullable|sanitizeText|maxLength:30|unique:fct_product_variations,sku' . ($this->get('variants.id') ? ',' . $this->get('variants.id') : ''),
80 'variants.item_price' => 'nullable|numeric|min:0',
81 'variants.compare_price' => [
82 'nullable',
83 'numeric',
84 function ($attribute, $value) {
85 $itemPrice = $this->get("variants.item_price");
86 if (empty($itemPrice)) {
87 $itemPrice = 0;
88 }
89 if ($value !== null && $value < $itemPrice) {
90 return sprintf(__("Compare price must be greater than or equal to item price.", 'fluent-cart'));
91 }
92 return null;
93 },
94 ],
95 'variants.manage_cost' => 'nullable|sanitizeText|maxLength:10',
96 'variants.item_cost' => 'required_if:variants.manage_cost,true',
97 'variants.fulfillment_type' => 'required|sanitizeText|maxLength:100',
98 'variants.shipping_class' => function ($attr, $value) {
99 if ($value && !(\FluentCart\App\Models\ShippingClass::find(intval($value)))) {
100 return __('The selected shipping class does not exist.', 'fluent-cart');
101 }
102 return null;
103 },
104
105 'variants.manage_stock' => 'nullable|numeric',
106 'variants.stock_status' => 'required_if:variants.manage_stock,1|sanitizeText|maxLength:50',
107 'variants.total_stock' => 'required|numeric',
108 'variants.available' => 'required|numeric',
109 // 'variants.available' => [
110 // 'required',
111 // 'numeric',
112 // function ($attribute, $value, $fail) {
113 // if ($this->variants['stock_status'] == 'in-stock' && $value <= 0) {
114 // return __("The available stock must be greater than 0 when stock is set to in stock", 'fluent-cart');
115 // }
116 // return null;
117 // },
118 // ],
119 'variants.committed' => 'required|numeric',
120 'variants.on_hold' => 'required|numeric',
121
122 'variants.serial_index' => 'nullable|numeric',
123
124 'variants.other_info' => 'required|array',
125 'variants.other_info.description' => 'nullable|sanitizeTextArea|maxLength:255',
126 'variants.other_info.payment_type' => 'required|sanitizeText|in:onetime,subscription',
127 'variants.other_info.times' => [
128 function ($attribute, $value) {
129 if ($this->get('variants.other_info.payment_type') !== 'subscription') {
130 return null;
131 }
132 if (!empty($value) && !is_numeric($value)) {
133 return __('Times must be a number.', 'fluent-cart');
134 }
135 return null;
136 },
137 ],
138 'variants.other_info.trial_days' => [
139 function ($attribute, $value) {
140 if ($this->get('variants.other_info.payment_type') !== 'subscription') {
141 return null;
142 }
143 if (!empty($value) && !is_numeric($value)) {
144 return __('Trial days must be a number.', 'fluent-cart');
145 }
146 if (!empty($value) && $value > 365) {
147 return __('Trial period cannot exceed 365 days.', 'fluent-cart');
148 }
149 return null;
150 },
151 ],
152 'variants.other_info.repeat_interval' => 'required_if:variants.other_info.payment_type,subscription|sanitizeText|maxLength:100',
153 'variants.other_info.billing_summary' => 'nullable|sanitizeTextArea|maxLength:255',
154 'variants.other_info.manage_setup_fee' => 'required_if:variants.other_info.payment_type,subscription|sanitizeText|maxLength:100',
155 'variants.other_info.signup_fee' => 'required_if:variants.other_info.manage_setup_fee,yes',
156 'variants.other_info.signup_fee_name' => 'required_if:variants.other_info.manage_setup_fee,yes|sanitizeText|maxLength:100',
157 'variants.other_info.package_slug' => 'nullable|sanitizeText|maxLength:100',
158 'variants.other_info.weight' => 'nullable|numeric',
159 'variants.other_info.weight_unit' => 'nullable|sanitizeText|maxLength:10',
160 'variants.other_info.length' => 'nullable|numeric',
161 'variants.other_info.width' => 'nullable|numeric',
162 'variants.other_info.height' => 'nullable|numeric',
163
164 'variants.downloadable' => 'nullable|sanitizeText|maxLength:10',
165 ];
166 }
167
168
169 public function afterValidation($validator): array
170 {
171
172 $data = $this->get();
173
174 $price = $data['variants']['item_price'];
175
176 if (empty($price)) {
177 $data['variants']['item_price'] = 0;
178 }
179
180 return $data;
181 }
182
183
184 /**
185 * @return array
186 */
187 public function messages()
188 {
189 return [
190 'variants.variation_title.required' => esc_html__('Title is required.', 'fluent-cart'),
191 'variants.variation_title.max' => esc_html__('Title may not be greater than 200 characters.', 'fluent-cart'),
192 'variants.sku.max' => esc_html__('SKU may not be greater than 30 characters.', 'fluent-cart'),
193 'variants.sku.unique' => esc_html__('The SKU must be unique.', 'fluent-cart'),
194 'variants.item_price.required' => esc_html__('Price is required.', 'fluent-cart'),
195 'variants.item_price.numeric' => esc_html__('Price must be a number.', 'fluent-cart'),
196 'variants.item_price.min' => esc_html__('Price must be a positive number greater than 0.', 'fluent-cart'),
197 'variants.stock_status.required_if' => esc_html__('Stock status is required.', 'fluent-cart'),
198 'variants.item_cost.required_if' => esc_html__('Item cost is required.', 'fluent-cart'),
199 'variants.fulfillment_type.required' => esc_html__('Fulfilment Type is required.', 'fluent-cart'),
200
201 'variants.other_info.description.max' => esc_html__('Description may not be greater than 255 characters.', 'fluent-cart'),
202 'variants.other_info.payment_type.required' => esc_html__('Payment Type is required.', 'fluent-cart'),
203 'variants.other_info.times.required_if' => esc_html__('Times is required.', 'fluent-cart'),
204 'variants.other_info.repeat_interval.required_if' => esc_html__('Interval is required.', 'fluent-cart'),
205 'variants.other_info.signup_fee.required_if' => esc_html__('Setup Fee Amount is required.', 'fluent-cart'),
206 'variants.other_info.signup_fee_name.required_if' => esc_html__('Setup Fee Name is required.', 'fluent-cart'),
207 'variants.other_info.trial_days.numeric' => esc_html__('Trial days must be a number.', 'fluent-cart'),
208 'variants.other_info.trial_days.max' => esc_html__('Trial period cannot exceed 365 days.', 'fluent-cart'),
209 ];
210 }
211
212
213 /**
214 * @return array
215 */
216 public function sanitize()
217 {
218
219 return [
220 'variants.id' => 'intval',
221 'variants.rowId' => 'intval',
222 'variants.post_id' => 'intval',
223 'variants.variation_title' => 'sanitize_text_field',
224 'variants.sku' => 'sanitize_text_field',
225 'variants.item_price' => 'floatval',
226 'variants.compare_price' => 'floatval',
227 'variants.manage_cost' => 'sanitize_text_field',
228 'variants.fulfillment_type' => 'sanitize_text_field',
229 'variants.item_cost' => 'floatval',
230 'variants.total_stock' => 'intval',
231 'variants.available' => 'intval',
232 'variants.committed' => 'intval',
233 'variants.on_hold' => 'intval',
234 'variants.manage_stock' => 'intval',
235 'variants.shipping_class' => function ($value) {
236 return $value ? intval($value) : null;
237 },
238 'variants.stock_status' => 'sanitize_key',
239 'variants.serial_index' => 'intval',
240 'variants.media.*.id' => 'intval',
241 'variants.media.*.url' => function ($value) {
242 if (empty($value)) {
243 return '';
244 }
245
246 return sanitize_url($value);
247 },
248 'variants.media.*.title' => 'sanitize_text_field',
249
250 'variants.downloadable' => 'sanitize_text_field',
251
252 'variants.other_info' => function ($value) {
253 return is_array($value) ? $value : [];
254 },
255 'variants.other_info.description' => 'sanitize_text_field',
256 'variants.other_info.payment_type' => 'sanitize_text_field',
257 'variants.other_info.times' => 'sanitize_text_field',
258 'variants.other_info.trial_days' => 'sanitize_text_field',
259 'variants.other_info.repeat_interval' => 'sanitize_text_field',
260 'variants.other_info.billing_summary' => 'sanitize_text_field',
261 'variants.other_info.manage_setup_fee' => 'sanitize_text_field',
262 'variants.other_info.signup_fee' => 'floatval',
263 'variants.other_info.signup_fee_name' => 'sanitize_text_field',
264 'variants.other_info.package_slug' => 'sanitize_text_field',
265 'variants.other_info.weight' => 'floatval',
266 'variants.other_info.weight_unit' => 'sanitize_text_field',
267 'variants.other_info.length' => 'floatval',
268 'variants.other_info.width' => 'floatval',
269 'variants.other_info.height' => 'floatval',
270 //'variants.other_info.purchasable' => 'sanitize_text_field',
271 ];
272
273 }
274 }
275