| @@ -331,15 +331,23 @@ | ||
| 331 | 331 | if (isset($data['meta_keywords'])) { |
| 332 | 332 | $sanitized['meta_keywords'] = sanitize_text_field($data['meta_keywords']); |
| 333 | 333 | } |
| 334 | 334 | |
| 335 | - // Numeric fields | |
| 336 | - if (isset($data['original_price'])) { | |
| 337 | - $sanitized['original_price'] = (float)$data['original_price']; | |
| 335 | + // Numeric fields. | |
| 336 | + // Use array_key_exists (not isset) so an explicitly-sent null/empty | |
| 337 | + // price is written as SQL NULL — letting admins CLEAR a price. With | |
| 338 | + // isset(), a null was dropped and the old value lingered, so prices | |
| 339 | + // could never be emptied from the UI. | |
| 340 | + if (array_key_exists('original_price', $data)) { | |
| 341 | + $sanitized['original_price'] = ($data['original_price'] === null || $data['original_price'] === '') | |
| 342 | + ? null | |
| 343 | + : (float)$data['original_price']; | |
| 338 | 344 | } |
| 339 | 345 | |
| 340 | - if (isset($data['discounted_price'])) { | |
| 341 | - $sanitized['discounted_price'] = (float)$data['discounted_price']; | |
| 346 | + if (array_key_exists('discounted_price', $data)) { | |
| 347 | + $sanitized['discounted_price'] = ($data['discounted_price'] === null || $data['discounted_price'] === '') | |
| 348 | + ? null | |
| 349 | + : (float)$data['discounted_price']; | |
| 342 | 350 | } |
| 343 | 351 | |
| 344 | 352 | if (isset($data['duration_days'])) { |
| 345 | 353 | $sanitized['duration_days'] = (int)$data['duration_days']; |
| @@ -513,8 +521,30 @@ | ||
| 513 | 521 | if (isset($data['custom_fields'])) { |
| 514 | 522 | $sanitized['custom_fields'] = is_array($data['custom_fields']) |
| 515 | 523 | ? $data['custom_fields'] |
| 516 | 524 | : (array) $data['custom_fields']; |
| 525 | + } | |
| 526 | + | |
| 527 | + // Hour-based duration only applies to single-day tours. Clamp to a sane | |
| 528 | + // day-length range, and never let a multi-day / flexible trip carry | |
| 529 | + // hours — otherwise the front end would show "8 hours" for a multi-day | |
| 530 | + // trip and the Google Calendar module would build a short timed event | |
| 531 | + // instead of the correct multi-day span. | |
| 532 | + // | |
| 533 | + // `trip_type` settles it when the payload carries it (the trip form | |
| 534 | + // always sends both). A partial update that omits `trip_type` is caught | |
| 535 | + // by the duration_days fallback below, so hours can never be stored | |
| 536 | + // against a multi-day span. | |
| 537 | + if (array_key_exists('duration_hours', $sanitized)) { | |
| 538 | + $sanitized['duration_hours'] = max(0, min(24, (int) $sanitized['duration_hours'])); | |
| 539 | + $isMultiDayType = array_key_exists('trip_type', $sanitized) | |
| 540 | + && $sanitized['trip_type'] !== 'single_day'; | |
| 541 | + $isMultiDaySpan = array_key_exists('duration_days', $sanitized) | |
| 542 | + && (int) $sanitized['duration_days'] > 1; | |
| 543 | + | |
| 544 | + if ($isMultiDayType || $isMultiDaySpan) { | |
| 545 | + $sanitized['duration_hours'] = 0; | |
| 546 | + } | |
| 517 | 547 | } |
| 518 | 548 | |
| 519 | 549 | return apply_filters('yatra_trip_sanitize_data', $sanitized, $data); |
| 520 | 550 | } |