PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.6
Yatra – Travel Booking & Tour Operator Software v3.0.2.6
3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 All 83 releases
yatra / app / Validators / TripValidator.php

TripValidator.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.6, at app/Validators/TripValidator.php

482 lines 18.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Validators;
6
7 use Yatra\Exceptions\ValidationException;
8
9 /**
10 * Trip Validator
11 *
12 * Comprehensive validation for trip data
13 */
14 class TripValidator
15 {
16 /**
17 * Validate trip creation data
18 */
19 public static function validateCreate(array $data): void
20 {
21 $errors = [];
22
23 // Required fields
24 if (empty($data['title'])) {
25 $errors['title'][] = __('Title is required', 'yatra');
26 }
27
28 if (empty($data['status'])) {
29 $errors['status'][] = __('Status is required', 'yatra');
30 } elseif (!in_array($data['status'], ['draft', 'publish', 'private', 'trash'])) {
31 $errors['status'][] = __('Invalid status value', 'yatra');
32 }
33
34 // Validate pricing
35 if (isset($data['original_price'])) {
36 if (!is_numeric($data['original_price']) || (float)$data['original_price'] < 0) {
37 $errors['original_price'][] = __('Original price must be a valid positive number', 'yatra');
38 }
39 }
40
41 if (isset($data['sale_price'])) {
42 if (!is_numeric($data['sale_price']) || (float)$data['sale_price'] < 0) {
43 $errors['sale_price'][] = __('Sale price must be a valid positive number', 'yatra');
44 }
45 }
46
47 // Validate duration
48 if (isset($data['duration_days'])) {
49 if (!is_numeric($data['duration_days']) || (int)$data['duration_days'] < 0) {
50 $errors['duration_days'][] = __('Duration days must be a valid positive number', 'yatra');
51 }
52 }
53
54 if (isset($data['duration_nights'])) {
55 if (!is_numeric($data['duration_nights']) || (int)$data['duration_nights'] < 0) {
56 $errors['duration_nights'][] = __('Duration nights must be a valid positive number', 'yatra');
57 }
58 }
59
60 // Validate difficulty level
61 if (isset($data['difficulty_level'])) {
62 if (!is_numeric($data['difficulty_level']) || (int)$data['difficulty_level'] <= 0) {
63 $errors['difficulty_level'][] = __('Difficulty level must be a valid positive integer', 'yatra');
64 }
65 }
66
67 // Validate group size
68 if (isset($data['min_group_size'])) {
69 if (!is_numeric($data['min_group_size']) || (int)$data['min_group_size'] < 1) {
70 $errors['min_group_size'][] = __('Minimum group size must be at least 1', 'yatra');
71 }
72 }
73
74 if (isset($data['max_group_size'])) {
75 if (!is_numeric($data['max_group_size']) || (int)$data['max_group_size'] < 1) {
76 $errors['max_group_size'][] = __('Maximum group size must be at least 1', 'yatra');
77 }
78 }
79
80 // Validate min/max group size relationship
81 if (isset($data['min_group_size']) && isset($data['max_group_size'])) {
82 if ((int)$data['min_group_size'] > (int)$data['max_group_size']) {
83 $errors['max_group_size'][] = __('Maximum group size must be greater than or equal to minimum group size', 'yatra');
84 }
85 }
86
87 // Validate slug format
88 if (isset($data['slug']) && !empty($data['slug'])) {
89 if (!preg_match('/^[a-z0-9-]+$/', $data['slug'])) {
90 $errors['slug'][] = __('Slug can only contain lowercase letters, numbers, and hyphens', 'yatra');
91 }
92 }
93
94 if (!empty($errors)) {
95 throw new ValidationException('Trip validation failed', $errors);
96 }
97 }
98
99 /**
100 * Validate trip update data
101 */
102 public static function validateUpdate(array $data, int $tripId): void
103 {
104 $errors = [];
105
106 // ID validation
107 if ($tripId <= 0) {
108 $errors['id'][] = __('Invalid trip ID', 'yatra');
109 }
110
111 // Optional field validation (same rules as create, but fields are optional)
112 if (isset($data['status']) && !in_array($data['status'], ['draft', 'publish', 'private', 'trash'])) {
113 $errors['status'][] = __('Invalid status value', 'yatra');
114 }
115
116 if (isset($data['original_price']) && (!is_numeric($data['original_price']) || (float)$data['original_price'] < 0)) {
117 $errors['original_price'][] = __('Original price must be a valid positive number', 'yatra');
118 }
119
120 if (isset($data['sale_price']) && (!is_numeric($data['sale_price']) || (float)$data['sale_price'] < 0)) {
121 $errors['sale_price'][] = __('Sale price must be a valid positive number', 'yatra');
122 }
123
124 if (isset($data['duration_days']) && (!is_numeric($data['duration_days']) || (int)$data['duration_days'] < 0)) {
125 $errors['duration_days'][] = __('Duration days must be a valid positive number', 'yatra');
126 }
127
128 if (isset($data['duration_nights']) && (!is_numeric($data['duration_nights']) || (int)$data['duration_nights'] < 0)) {
129 $errors['duration_nights'][] = __('Duration nights must be a valid positive number', 'yatra');
130 }
131
132 if (isset($data['difficulty_level']) && (!is_numeric($data['difficulty_level']) || (int)$data['difficulty_level'] <= 0)) {
133 $errors['difficulty_level'][] = __('Difficulty level must be a valid positive integer', 'yatra');
134 }
135
136 if (isset($data['min_group_size']) && (!is_numeric($data['min_group_size']) || (int)$data['min_group_size'] < 1)) {
137 $errors['min_group_size'][] = __('Minimum group size must be at least 1', 'yatra');
138 }
139
140 if (isset($data['max_group_size']) && (!is_numeric($data['max_group_size']) || (int)$data['max_group_size'] < 1)) {
141 $errors['max_group_size'][] = __('Maximum group size must be at least 1', 'yatra');
142 }
143
144 if (isset($data['min_group_size']) && isset($data['max_group_size'])) {
145 if ((int)$data['min_group_size'] > (int)$data['max_group_size']) {
146 $errors['max_group_size'][] = __('Maximum group size must be greater than or equal to minimum group size', 'yatra');
147 }
148 }
149
150 if (isset($data['slug']) && !empty($data['slug']) && !preg_match('/^[a-z0-9-]+$/', $data['slug'])) {
151 $errors['slug'][] = __('Slug can only contain lowercase letters, numbers, and hyphens', 'yatra');
152 }
153
154 if (!empty($errors)) {
155 throw new ValidationException('Trip validation failed', $errors);
156 }
157 }
158
159 /**
160 * Sanitize trip data
161 */
162 public static function sanitize(array $data): array
163 {
164 $sanitized = [];
165
166 // Text fields
167 if (isset($data['title'])) {
168 $sanitized['title'] = sanitize_text_field($data['title']);
169 }
170
171 if (isset($data['slug'])) {
172 $sanitized['slug'] = sanitize_title($data['slug']);
173 }
174
175 if (isset($data['description'])) {
176 $sanitized['description'] = wp_kses_post($data['description']);
177 }
178
179 if (isset($data['short_description'])) {
180 $sanitized['short_description'] = wp_kses_post($data['short_description']);
181 }
182
183 if (isset($data['trip_details'])) {
184 $sanitized['trip_details'] = wp_kses_post($data['trip_details']);
185 }
186
187 if (isset($data['what_makes_special'])) {
188 $sanitized['what_makes_special'] = wp_kses_post($data['what_makes_special']);
189 }
190
191 if (isset($data['trip_story'])) {
192 $sanitized['trip_story'] = wp_kses_post($data['trip_story']);
193 }
194
195 if (isset($data['video_url'])) {
196 $sanitized['video_url'] = esc_url_raw($data['video_url']);
197 }
198
199 if (isset($data['virtual_tour_url'])) {
200 $sanitized['virtual_tour_url'] = esc_url_raw($data['virtual_tour_url']);
201 }
202
203 if (isset($data['starting_location'])) {
204 $sanitized['starting_location'] = sanitize_text_field($data['starting_location']);
205 }
206
207 if (isset($data['ending_location'])) {
208 $sanitized['ending_location'] = sanitize_text_field($data['ending_location']);
209 }
210
211 if (isset($data['starting_latitude'])) {
212 $sanitized['starting_latitude'] = is_numeric($data['starting_latitude']) ? (float) $data['starting_latitude'] : null;
213 }
214
215 if (isset($data['starting_longitude'])) {
216 $sanitized['starting_longitude'] = is_numeric($data['starting_longitude']) ? (float) $data['starting_longitude'] : null;
217 }
218
219 if (isset($data['ending_latitude'])) {
220 $sanitized['ending_latitude'] = is_numeric($data['ending_latitude']) ? (float) $data['ending_latitude'] : null;
221 }
222
223 if (isset($data['ending_longitude'])) {
224 $sanitized['ending_longitude'] = is_numeric($data['ending_longitude']) ? (float) $data['ending_longitude'] : null;
225 }
226
227 if (isset($data['seasonal_availability'])) {
228 $sanitized['seasonal_availability'] = sanitize_text_field($data['seasonal_availability']);
229 }
230
231 if (isset($data['best_season'])) {
232 $sanitized['best_season'] = sanitize_text_field($data['best_season']);
233 }
234
235 if (isset($data['peak_season'])) {
236 $sanitized['peak_season'] = sanitize_text_field($data['peak_season']);
237 }
238
239 if (isset($data['off_season'])) {
240 $sanitized['off_season'] = sanitize_text_field($data['off_season']);
241 }
242
243 if (isset($data['accommodation_type'])) {
244 $sanitized['accommodation_type'] = sanitize_text_field($data['accommodation_type']);
245 }
246
247 if (isset($data['meal_plan'])) {
248 $sanitized['meal_plan'] = sanitize_text_field($data['meal_plan']);
249 }
250
251 if (isset($data['accommodation_details'])) {
252 $sanitized['accommodation_details'] = wp_kses_post($data['accommodation_details']);
253 }
254
255 if (isset($data['pickup_location'])) {
256 $sanitized['pickup_location'] = sanitize_text_field($data['pickup_location']);
257 }
258
259 if (isset($data['dropoff_location'])) {
260 $sanitized['dropoff_location'] = sanitize_text_field($data['dropoff_location']);
261 }
262
263 if (isset($data['transportation_details'])) {
264 $sanitized['transportation_details'] = wp_kses_post($data['transportation_details']);
265 }
266
267 if (isset($data['transportation_included'])) {
268 $sanitized['transportation_included'] = (bool)$data['transportation_included'];
269 }
270
271 if (isset($data['payment_terms'])) {
272 $sanitized['payment_terms'] = wp_kses_post($data['payment_terms']);
273 }
274
275 if (isset($data['cancellation_policy'])) {
276 $sanitized['cancellation_policy'] = wp_kses_post($data['cancellation_policy']);
277 }
278
279 if (isset($data['physical_requirements'])) {
280 $sanitized['physical_requirements'] = wp_kses_post($data['physical_requirements']);
281 }
282
283 if (isset($data['visa_requirements'])) {
284 $sanitized['visa_requirements'] = wp_kses_post($data['visa_requirements']);
285 }
286
287 if (isset($data['vaccination_requirements'])) {
288 $sanitized['vaccination_requirements'] = wp_kses_post($data['vaccination_requirements']);
289 }
290
291 if (isset($data['meta_title'])) {
292 $sanitized['meta_title'] = sanitize_text_field($data['meta_title']);
293 }
294
295 if (isset($data['meta_description'])) {
296 $sanitized['meta_description'] = sanitize_textarea_field($data['meta_description']);
297 }
298
299 if (isset($data['meta_keywords'])) {
300 $sanitized['meta_keywords'] = sanitize_text_field($data['meta_keywords']);
301 }
302
303 // Numeric fields
304 if (isset($data['original_price'])) {
305 $sanitized['original_price'] = (float)$data['original_price'];
306 }
307
308 if (isset($data['discounted_price'])) {
309 $sanitized['discounted_price'] = (float)$data['discounted_price'];
310 }
311
312 if (isset($data['duration_days'])) {
313 $sanitized['duration_days'] = (int)$data['duration_days'];
314 }
315
316 if (isset($data['duration_nights'])) {
317 $sanitized['duration_nights'] = (int)$data['duration_nights'];
318 }
319
320 if (isset($data['duration_hours'])) {
321 $sanitized['duration_hours'] = (int)$data['duration_hours'];
322 }
323
324 if (isset($data['available_from'])) {
325 $sanitized['available_from'] = sanitize_text_field($data['available_from']);
326 }
327
328 if (isset($data['available_to'])) {
329 $sanitized['available_to'] = sanitize_text_field($data['available_to']);
330 }
331
332 if (isset($data['age_min'])) {
333 $sanitized['age_min'] = (int)$data['age_min'];
334 }
335
336 if (isset($data['age_max'])) {
337 $sanitized['age_max'] = (int)$data['age_max'];
338 }
339
340 if (isset($data['version'])) {
341 $sanitized['version'] = (int)$data['version'];
342 }
343
344 if (isset($data['updated_by'])) {
345 $sanitized['updated_by'] = (int)$data['updated_by'];
346 }
347
348 if (isset($data['updated_at'])) {
349 $sanitized['updated_at'] = sanitize_text_field($data['updated_at']);
350 }
351
352 if (isset($data['difficulty_level'])) {
353 $sanitized['difficulty_level'] = (int)$data['difficulty_level'];
354 }
355
356 if (isset($data['min_group_size'])) {
357 $sanitized['min_group_size'] = (int)$data['min_group_size'];
358 }
359
360 if (isset($data['max_group_size'])) {
361 $sanitized['max_group_size'] = (int)$data['max_group_size'];
362 }
363
364 // Booking fields
365 if (isset($data['min_travelers'])) {
366 $sanitized['min_travelers'] = (int)$data['min_travelers'];
367 }
368
369 if (isset($data['max_travelers'])) {
370 $sanitized['max_travelers'] = (int)$data['max_travelers'];
371 }
372
373 if (isset($data['booking_window_days'])) {
374 $sanitized['booking_window_days'] = (int)$data['booking_window_days'];
375 }
376
377 if (isset($data['booking_deadline_hours'])) {
378 $sanitized['booking_deadline_hours'] = (int)$data['booking_deadline_hours'];
379 }
380
381 // Time slot fields
382 if (isset($data['has_default_time_slots'])) {
383 $sanitized['has_default_time_slots'] = (bool)$data['has_default_time_slots'];
384 }
385
386 if (isset($data['default_time_slots'])) {
387 // Keep as string (already JSON encoded from controller)
388 $sanitized['default_time_slots'] = $data['default_time_slots'];
389 }
390
391 if (isset($data['departure_time'])) {
392 $sanitized['departure_time'] = sanitize_text_field($data['departure_time']);
393 }
394
395 // Enum fields
396 if (isset($data['status'])) {
397 $sanitized['status'] = in_array($data['status'], ['draft', 'publish', 'private', 'trash'])
398 ? $data['status']
399 : 'draft';
400 }
401
402 if (isset($data['trip_type'])) {
403 $sanitized['trip_type'] = in_array($data['trip_type'], ['single_day', 'multi_day', 'flexible'])
404 ? $data['trip_type']
405 : 'multi_day';
406 }
407
408 if (isset($data['pricing_type'])) {
409 $sanitized['pricing_type'] = in_array($data['pricing_type'], ['regular', 'traveler_based', 'dynamic', 'custom'])
410 ? $data['pricing_type']
411 : 'regular';
412 }
413
414 if (isset($data['featured_priority'])) {
415 $sanitized['featured_priority'] = in_array($data['featured_priority'], ['none', 'featured', 'new', 'limited', 'bestseller'])
416 ? $data['featured_priority']
417 : 'none';
418 }
419
420 if (isset($data['currency'])) {
421 $sanitized['currency'] = sanitize_text_field($data['currency']);
422 }
423
424 // Always include featured_image if it exists in the data, even if null
425 if (array_key_exists('featured_image', $data)) {
426 // Allow null or empty string to remove featured image
427 $sanitized['featured_image'] = empty($data['featured_image']) ? null : sanitize_text_field($data['featured_image']);
428 }
429
430 // JSON fields
431 if (isset($data['testimonials'])) {
432 $sanitized['testimonials'] = is_array($data['testimonials']) ? maybe_serialize($data['testimonials']) : $data['testimonials'];
433 }
434
435 if (isset($data['countries'])) {
436 $sanitized['countries'] = is_array($data['countries']) ? maybe_serialize($data['countries']) : $data['countries'];
437 }
438
439 if (isset($data['regions'])) {
440 $sanitized['regions'] = is_array($data['regions']) ? maybe_serialize($data['regions']) : $data['regions'];
441 }
442
443 if (isset($data['landmarks'])) {
444 $sanitized['landmarks'] = is_array($data['landmarks']) ? maybe_serialize($data['landmarks']) : $data['landmarks'];
445 }
446
447 if (isset($data['tags'])) {
448 $sanitized['tags'] = is_array($data['tags']) ? maybe_serialize($data['tags']) : $data['tags'];
449 }
450
451 if (isset($data['included_items'])) {
452 $sanitized['included_items'] = is_array($data['included_items']) ? maybe_serialize($data['included_items']) : $data['included_items'];
453 }
454
455 if (isset($data['excluded_items'])) {
456 $sanitized['excluded_items'] = is_array($data['excluded_items']) ? maybe_serialize($data['excluded_items']) : $data['excluded_items'];
457 }
458
459 if (isset($data['frontend_tabs'])) {
460 $sanitized['frontend_tabs'] = is_array($data['frontend_tabs']) ? maybe_serialize($data['frontend_tabs']) : $data['frontend_tabs'];
461 }
462
463 if (isset($data['testimonial_review_ids'])) {
464 $sanitized['testimonial_review_ids'] = is_array($data['testimonial_review_ids']) ? json_encode($data['testimonial_review_ids']) : $data['testimonial_review_ids'];
465 }
466
467 if (isset($data['features'])) {
468 $sanitized['features'] = is_array($data['features']) ? json_encode($data['features']) : $data['features'];
469 }
470
471 if (isset($data['includes'])) {
472 $sanitized['includes'] = is_array($data['includes']) ? json_encode($data['includes']) : $data['includes'];
473 }
474
475 if (isset($data['excludes'])) {
476 $sanitized['excludes'] = is_array($data['excludes']) ? json_encode($data['excludes']) : $data['excludes'];
477 }
478
479 return apply_filters('yatra_trip_sanitize_data', $sanitized, $data);
480 }
481 }
482