| @@ -4,8 +4,10 @@ | ||
| 4 | 4 | |
| 5 | 5 | use FluentCart\Framework\Foundation\RequestGuard; |
| 6 | 6 | use FluentCart\Framework\Support\Arr; |
| 7 | 7 | use FluentCart\App\Services\Permission\PermissionManager; |
| 8 | +use FluentCart\App\Services\Theme\ColorPalette; | |
| 9 | +use FluentCart\App\Services\Theme\RadiusPalette; | |
| 8 | 10 | |
| 9 | 11 | class FluentMetaRequest extends RequestGuard |
| 10 | 12 | { |
| 11 | 13 | |
| @@ -19,12 +21,20 @@ | ||
| 19 | 21 | $rulesMap = [ |
| 20 | 22 | 'store_setup' => [ |
| 21 | 23 | 'store_name' => 'required|sanitizeText|maxLength:200', |
| 22 | 24 | 'store_country' => 'required|sanitizeText|maxLength:200', |
| 25 | + 'seller_vat_id' => 'nullable|sanitizeText|maxLength:50', | |
| 26 | + 'seller_tax_id' => 'nullable|sanitizeText|maxLength:50', | |
| 23 | 27 | ] |
| 24 | 28 | ]; |
| 25 | 29 | |
| 26 | 30 | $rules = Arr::get($rulesMap, $this->get('settings_name'), []); |
| 31 | + | |
| 32 | + // The radius fields only show under Customize; a value hidden under | |
| 33 | + // another source is dropped by the sanitiser rather than blocking the save. | |
| 34 | + if ($this->get('settings_name') === 'appearance' && $this->get('appearance_source') === ColorPalette::SOURCE_CUSTOM) { | |
| 35 | + $rules = array_merge($rules, RadiusPalette::validationRules()); | |
| 36 | + } | |
| 27 | 37 | // $rules = [ |
| 28 | 38 | // 'object_id' => 'integer|min:1', |
| 29 | 39 | // 'object_type' => 'nullable|sanitizeText|max:50', |
| 30 | 40 | // 'meta_key' => 'nullable|sanitizeText|max:50', |
| @@ -59,8 +69,12 @@ | ||
| 59 | 69 | 'meta_key' => 'sanitize_text_field', |
| 60 | 70 | 'type' => 'sanitize_text_field', |
| 61 | 71 | 'default' => 'sanitize_text_field', |
| 62 | 72 | 'store_name' => 'sanitize_text_field', |
| 73 | + 'company_name' => 'sanitize_text_field', | |
| 74 | + 'legal_registration_id' => 'sanitize_text_field', | |
| 75 | + 'seller_vat_id' => 'sanitize_text_field', | |
| 76 | + 'seller_tax_id' => 'sanitize_text_field', | |
| 63 | 77 | 'store_logo' => function ($value) { |
| 64 | 78 | if (!is_array($value)) { |
| 65 | 79 | return ''; |
| 66 | 80 | } |
| @@ -86,13 +100,20 @@ | ||
| 86 | 100 | 'show_cart_icon_in_body' => 'sanitize_text_field', |
| 87 | 101 | 'additional_address_field' => 'sanitize_text_field', |
| 88 | 102 | 'hide_coupon_field' => 'sanitize_text_field', |
| 89 | 103 | 'user_account_creation_mode' => 'sanitize_text_field', |
| 104 | + 'require_customer_email_verification' => function ($value) { | |
| 105 | + return $value === 'no' ? 'no' : 'yes'; | |
| 106 | + }, | |
| 107 | + 'auto_login_after_account_creation' => function ($value) { | |
| 108 | + return $value === 'yes' ? 'yes' : 'no'; | |
| 109 | + }, | |
| 90 | 110 | 'force_ssl' => 'sanitize_text_field', |
| 91 | 111 | 'checkout_page_id' => 'intval', |
| 92 | 112 | 'custom_payment_page_id' => 'intval', |
| 93 | 113 | 'cart_page_id' => 'intval', |
| 94 | 114 | 'receipt_page_id' => 'intval', |
| 115 | + 'order_review_page_id' => 'intval', | |
| 95 | 116 | 'shop_page_id' => 'intval', |
| 96 | 117 | 'customer_profile_page_id' => 'intval', |
| 97 | 118 | 'customer_profile_page_slug' => 'sanitize_text_field', |
| 98 | 119 | 'registration_page_id' => 'intval', |
| @@ -108,10 +129,30 @@ | ||
| 108 | 129 | 'store_state' => 'sanitize_text_field', |
| 109 | 130 | 'template_settings_checkout_page_mode' => 'sanitize_text_field', |
| 110 | 131 | 'show_relevant_product_in_single_page' => 'sanitize_text_field', |
| 111 | 132 | 'show_relevant_product_in_modal' => 'sanitize_text_field', |
| 133 | + 'show_reviews_in_single_page' => 'sanitize_text_field', | |
| 134 | + 'show_rating_in_shop' => 'sanitize_text_field', | |
| 135 | + 'show_rating_in_relevant' => 'sanitize_text_field', | |
| 112 | 136 | 'enable_early_payment_for_installment' => 'sanitize_text_field', |
| 137 | + 'subscription_management_mode' => function ($value) { | |
| 138 | + $value = sanitize_text_field($value); | |
| 139 | + $allowed = ['gateway_managed', 'store_managed']; | |
| 140 | + return in_array($value, $allowed, true) ? $value : 'gateway_managed'; | |
| 141 | + }, | |
| 142 | + 'subscription_system_charge' => function ($value) { | |
| 143 | + $value = sanitize_text_field($value); | |
| 144 | + return in_array($value, ['yes', 'no'], true) ? $value : 'no'; | |
| 145 | + }, | |
| 146 | + 'subscription_manual_fallback' => function ($value) { | |
| 147 | + $value = sanitize_text_field($value); | |
| 148 | + return in_array($value, ['yes', 'no'], true) ? $value : 'no'; | |
| 149 | + }, | |
| 113 | 150 | 'order_mode' => 'sanitize_text_field', |
| 151 | + 'subscription_mode_guard' => function ($value) { | |
| 152 | + $value = sanitize_text_field($value); | |
| 153 | + return in_array($value, ['yes', 'no'], true) ? $value : 'yes'; | |
| 154 | + }, | |
| 114 | 155 | 'variation_view' => 'sanitize_text_field', |
| 115 | 156 | 'variation_columns' => 'sanitize_text_field', |
| 116 | 157 | 'modules_settings' => 'sanitize_text_field', |
| 117 | 158 | 'product_slug' => 'sanitize_text_field', |
| @@ -116,8 +157,16 @@ | ||
| 116 | 157 | 'modules_settings' => 'sanitize_text_field', |
| 117 | 158 | 'product_slug' => 'sanitize_text_field', |
| 118 | 159 | 'min_receipt_number' => 'sanitize_text_field', |
| 119 | 160 | 'inv_prefix' => 'sanitize_text_field', |
| 161 | + 'date_time_format_source' => function ($value) { | |
| 162 | + $value = sanitize_text_field($value); | |
| 163 | + return in_array($value, ['fluent_cart', 'wordpress'], true) ? $value : 'fluent_cart'; | |
| 164 | + }, | |
| 165 | + 'timezone_source' => function ($value) { | |
| 166 | + $value = sanitize_text_field($value); | |
| 167 | + return in_array($value, ['fluent_cart', 'wordpress'], true) ? $value : 'fluent_cart'; | |
| 168 | + }, | |
| 120 | 169 | 'weight_unit' => function ($value) { |
| 121 | 170 | if (!PermissionManager::hasPermission(['store/sensitive'])) { |
| 122 | 171 | $stored = get_option('fluent_cart_store_settings', []); |
| 123 | 172 | return $stored['weight_unit'] ?? 'kg'; |
| @@ -136,8 +185,44 @@ | ||
| 136 | 185 | return in_array($value, $allowed, true) ? $value : 'cm'; |
| 137 | 186 | }, |
| 138 | 187 | 'enable_image_zoom_in_single_product' => 'sanitize_text_field', |
| 139 | 188 | 'enable_image_zoom_in_modal' => 'sanitize_text_field', |
| 189 | + 'appearance_source' => function ($value) { | |
| 190 | + $value = sanitize_text_field($value); | |
| 191 | + | |
| 192 | + return in_array($value, ColorPalette::sources(), true) | |
| 193 | + ? $value | |
| 194 | + : ColorPalette::SOURCE_DEFAULT; | |
| 195 | + }, | |
| 196 | + 'appearance_colors' => function ($value) { | |
| 197 | + if (!is_array($value)) { | |
| 198 | + return []; | |
| 199 | + } | |
| 200 | + | |
| 201 | + // Driven off the registry rather than the submitted keys, so an | |
| 202 | + // unknown property can never reach the storefront stylesheet. | |
| 203 | + $colors = []; | |
| 204 | + | |
| 205 | + foreach (ColorPalette::globals() as $key => $definition) { | |
| 206 | + $hex = sanitize_hex_color((string)Arr::get($value, $key, '')); | |
| 207 | + | |
| 208 | + // sanitize_hex_color() returns null for anything malformed | |
| 209 | + // and '' for an empty picker; both mean "not set", which is | |
| 210 | + // how a colour falls back to FluentCart's own default. | |
| 211 | + if ($hex) { | |
| 212 | + $colors[$key] = $hex; | |
| 213 | + } | |
| 214 | + } | |
| 215 | + | |
| 216 | + return $colors; | |
| 217 | + }, | |
| 218 | + 'appearance_radius' => function ($value) { | |
| 219 | + // Registry-driven like the colours: only the known roles, each | |
| 220 | + // one length. A bare number means pixels; px, rem and em are | |
| 221 | + // kept as typed. An empty field means "not set", so the | |
| 222 | + // stylesheet's own fallback applies; 0 is a real value. | |
| 223 | + return RadiusPalette::sanitizeOwnerMap($value); | |
| 224 | + }, | |
| 140 | 225 | 'theme_setup' => function ($value) { |
| 141 | 226 | if (!is_array($value)) { |
| 142 | 227 | return []; |
| 143 | 228 | } |