all(); $fulfilmentType = Arr::get( $data, 'variants.fulfillment_type', Arr::get($data, 'variants.fulfillment_type', 'physical') ); $paymentType = Arr::get($data, 'variants.payment_type', 'onetime'); $manageCost = Arr::get($data, 'variants.manage_cost'); if (empty($manageCost)) { $manageCost = 'false'; } $data['variants']['fulfillment_type'] = $fulfilmentType; $data['variants']['manage_cost'] = $manageCost; $variantOtherInfo = Arr::wrap(Arr::get($data, 'variants.other_info')); // Ensure other_info is an array if (empty($variantOtherInfo)) { $variantOtherInfo = [ 'payment_type' => $paymentType, 'times' => '', 'trial_days' => '', 'repeat_interval' => 'yearly', 'billing_summary' => '', 'manage_setup_fee' => 'no', 'signup_fee_name' => '', 'signup_fee' => '', 'setup_fee_per_item' => 'no', //'purchasable' => 'yes', ]; } $data['variants']['other_info'] = $variantOtherInfo; if (Arr::get($variantOtherInfo, 'payment_type') === 'onetime') { $subscriptionFields = ['trial_days', 'times', 'repeat_interval', 'billing_summary', 'manage_setup_fee', 'signup_fee', 'signup_fee_name', 'setup_fee_per_item']; foreach ($subscriptionFields as $field) { unset($data['variants']['other_info'][$field]); } } return $data; } /** * @return array */ public function rules() { return [ 'variants.variation_title' => 'required|sanitizeText|maxLength:200', 'variants.sku' => 'nullable|sanitizeText|maxLength:30|unique:fct_product_variations,sku' . ($this->get('variants.id') ? ',' . $this->get('variants.id') : ''), 'variants.item_price' => 'nullable|numeric|min:0', 'variants.compare_price' => [ 'nullable', 'numeric', function ($attribute, $value) { $itemPrice = $this->get("variants.item_price"); if (empty($itemPrice)) { $itemPrice = 0; } if ($value !== null && $value < $itemPrice) { return sprintf(__("Compare price must be greater than or equal to item price.", 'fluent-cart')); } return null; }, ], 'variants.manage_cost' => 'nullable|sanitizeText|maxLength:10', 'variants.item_cost' => 'required_if:variants.manage_cost,true', 'variants.fulfillment_type' => 'required|sanitizeText|maxLength:100', 'variants.shipping_class' => function ($attr, $value) { if ($value && !(\FluentCart\App\Models\ShippingClass::find(intval($value)))) { return __('The selected shipping class does not exist.', 'fluent-cart'); } return null; }, 'variants.manage_stock' => 'nullable|numeric', 'variants.stock_status' => 'required_if:variants.manage_stock,1|sanitizeText|maxLength:50', 'variants.total_stock' => 'required|numeric', 'variants.available' => 'required|numeric', // 'variants.available' => [ // 'required', // 'numeric', // function ($attribute, $value, $fail) { // if ($this->variants['stock_status'] == 'in-stock' && $value <= 0) { // return __("The available stock must be greater than 0 when stock is set to in stock", 'fluent-cart'); // } // return null; // }, // ], 'variants.committed' => 'required|numeric', 'variants.on_hold' => 'required|numeric', 'variants.serial_index' => 'nullable|numeric', 'variants.other_info' => 'required|array', 'variants.other_info.description' => 'nullable|sanitizeTextArea|maxLength:255', 'variants.other_info.payment_type' => 'required|sanitizeText|in:onetime,subscription', 'variants.other_info.times' => [ function ($attribute, $value) { if ($this->get('variants.other_info.payment_type') !== 'subscription') { return null; } if (!empty($value) && !is_numeric($value)) { return __('Times must be a number.', 'fluent-cart'); } return null; }, ], 'variants.other_info.trial_days' => [ function ($attribute, $value) { if ($this->get('variants.other_info.payment_type') !== 'subscription') { return null; } if (!empty($value) && !is_numeric($value)) { return __('Trial days must be a number.', 'fluent-cart'); } if (!empty($value) && $value > 365) { return __('Trial period cannot exceed 365 days.', 'fluent-cart'); } return null; }, ], 'variants.other_info.repeat_interval' => 'required_if:variants.other_info.payment_type,subscription|sanitizeText|maxLength:100', 'variants.other_info.billing_summary' => 'nullable|sanitizeTextArea|maxLength:255', 'variants.other_info.manage_setup_fee' => 'required_if:variants.other_info.payment_type,subscription|sanitizeText|maxLength:100', 'variants.other_info.signup_fee' => 'required_if:variants.other_info.manage_setup_fee,yes', 'variants.other_info.signup_fee_name' => 'required_if:variants.other_info.manage_setup_fee,yes|sanitizeText|maxLength:100', 'variants.other_info.package_slug' => 'nullable|sanitizeText|maxLength:100', 'variants.other_info.weight' => 'nullable|numeric', 'variants.other_info.weight_unit' => 'nullable|sanitizeText|maxLength:10', 'variants.other_info.length' => 'nullable|numeric', 'variants.other_info.width' => 'nullable|numeric', 'variants.other_info.height' => 'nullable|numeric', 'variants.other_info.tax_class' => ['nullable', function ($attribute, $value) { if (empty($value)) { return null; } return empty(\FluentCart\App\Models\TaxClass::query()->where('slug', sanitize_text_field($value))->first()) ? __('Invalid Tax Class.', 'fluent-cart') : null; }], 'variants.other_info.tax_exempt' => 'nullable|sanitizeText|in:yes,no', 'variants.downloadable' => 'nullable|sanitizeText|maxLength:10', ]; } public function afterValidation($validator): array { $data = $this->get(); $price = $data['variants']['item_price']; if (empty($price)) { $data['variants']['item_price'] = 0; } return $data; } /** * @return array */ public function messages() { return [ 'variants.variation_title.required' => esc_html__('Title is required.', 'fluent-cart'), 'variants.variation_title.max' => esc_html__('Title may not be greater than 200 characters.', 'fluent-cart'), 'variants.sku.max' => esc_html__('SKU may not be greater than 30 characters.', 'fluent-cart'), 'variants.sku.unique' => esc_html__('The SKU must be unique.', 'fluent-cart'), 'variants.item_price.required' => esc_html__('Price is required.', 'fluent-cart'), 'variants.item_price.numeric' => esc_html__('Price must be a number.', 'fluent-cart'), 'variants.item_price.min' => esc_html__('Price must be a positive number greater than 0.', 'fluent-cart'), 'variants.stock_status.required_if' => esc_html__('Stock status is required.', 'fluent-cart'), 'variants.item_cost.required_if' => esc_html__('Item cost is required.', 'fluent-cart'), 'variants.fulfillment_type.required' => esc_html__('Fulfilment Type is required.', 'fluent-cart'), 'variants.other_info.description.max' => esc_html__('Description may not be greater than 255 characters.', 'fluent-cart'), 'variants.other_info.payment_type.required' => esc_html__('Payment Type is required.', 'fluent-cart'), 'variants.other_info.times.required_if' => esc_html__('Times is required.', 'fluent-cart'), 'variants.other_info.repeat_interval.required_if' => esc_html__('Interval is required.', 'fluent-cart'), 'variants.other_info.signup_fee.required_if' => esc_html__('Setup Fee Amount is required.', 'fluent-cart'), 'variants.other_info.signup_fee_name.required_if' => esc_html__('Setup Fee Name is required.', 'fluent-cart'), 'variants.other_info.trial_days.numeric' => esc_html__('Trial days must be a number.', 'fluent-cart'), 'variants.other_info.trial_days.max' => esc_html__('Trial period cannot exceed 365 days.', 'fluent-cart'), ]; } /** * @return array */ public function sanitize() { return [ 'variants.id' => 'intval', 'variants.rowId' => 'intval', 'variants.post_id' => 'intval', 'variants.variation_title' => 'sanitize_text_field', 'variants.sku' => 'sanitize_text_field', 'variants.item_price' => 'floatval', 'variants.compare_price' => 'floatval', 'variants.manage_cost' => 'sanitize_text_field', 'variants.fulfillment_type' => 'sanitize_text_field', 'variants.item_cost' => 'floatval', 'variants.total_stock' => 'intval', 'variants.available' => 'intval', 'variants.committed' => 'intval', 'variants.on_hold' => 'intval', 'variants.manage_stock' => 'intval', 'variants.shipping_class' => function ($value) { return $value ? intval($value) : null; }, 'variants.stock_status' => 'sanitize_key', 'variants.serial_index' => 'intval', 'variants.media.*.id' => 'intval', 'variants.media.*.url' => function ($value) { if (empty($value)) { return ''; } return sanitize_url($value); }, 'variants.media.*.title' => 'sanitize_text_field', 'variants.downloadable' => 'sanitize_text_field', 'variants.other_info' => function ($value) { return is_array($value) ? $value : []; }, 'variants.other_info.description' => 'sanitize_text_field', 'variants.other_info.payment_type' => 'sanitize_text_field', 'variants.other_info.times' => 'sanitize_text_field', 'variants.other_info.trial_days' => 'sanitize_text_field', 'variants.other_info.repeat_interval' => 'sanitize_text_field', 'variants.other_info.billing_summary' => 'sanitize_text_field', 'variants.other_info.manage_setup_fee' => 'sanitize_text_field', 'variants.other_info.signup_fee' => 'floatval', 'variants.other_info.signup_fee_name' => 'sanitize_text_field', 'variants.other_info.package_slug' => 'sanitize_text_field', 'variants.other_info.weight' => 'floatval', 'variants.other_info.weight_unit' => 'sanitize_text_field', 'variants.other_info.length' => 'floatval', 'variants.other_info.width' => 'floatval', 'variants.other_info.height' => 'floatval', 'variants.other_info.tax_class' => 'sanitize_text_field', 'variants.other_info.tax_exempt' => 'sanitize_text_field', //'variants.other_info.purchasable' => 'sanitize_text_field', ]; } }