PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.17
Yatra – Travel Booking & Tour Operator Software v3.0.17
3.0.17 3.0.16 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 All 85 releases
← All changes | app/Repositories/AvailabilityRepository.php +50 -10 3.0.4 → 3.0.17 View file →
@@ -28,8 +28,17 @@
28 28 return null;
29 29 }
30 30
31 31 /**
32 + * Clamp an alert threshold to the column's range (smallint unsigned: 0–65535)
33 + * so out-of-range input can't abort the write under MySQL strict mode.
34 + */
35 + private function clampAlertThreshold($value): int
36 + {
37 + return max(0, min(65535, (int) $value));
38 + }
39 +
40 + /**
32 41 * Get table name
33 42 */
34 43 protected function getTableName(): string
35 44 {
@@ -63,9 +72,15 @@
63 72 */
64 73 public function findByTripIdAndDate(int $tripId, string $departureDate): ?object
65 74 {
66 75 $table = esc_sql($this->table);
67 -
76 +
77 + // departure_date is a DATE column — strip any time component so a datetime
78 + // input still matches (avoids date-vs-datetime string-compare misses).
79 + if (preg_match('/^(\d{4}-\d{2}-\d{2})/', $departureDate, $m)) {
80 + $departureDate = $m[1];
81 + }
82 +
68 83 $result = $this->wpdb->get_row($this->wpdb->prepare(
69 84 "SELECT * FROM `{$table}`
70 85 WHERE trip_id = %d
71 86 AND departure_date = %s
@@ -169,21 +184,25 @@
169 184
170 185 return $results ?: [];
171 186 }
172 187
173 - public function existsForTripDateTime(int $tripId, string $departureDate, ?string $departureTime): bool
188 + public function existsForTripDateTime(int $tripId, string $departureDate, ?string $departureTime, ?int $excludeId = null): bool
174 189 {
175 190 $table = esc_sql($this->table);
176 191
192 + // Optional so update() can ignore the row it is editing; omitted, behaviour
193 + // is exactly as before for existing callers.
194 + $exclude = $excludeId !== null ? $this->wpdb->prepare(' AND id <> %d', $excludeId) : '';
195 +
177 196 if ($departureTime === null || $departureTime === '') {
178 197 $count = (int) $this->wpdb->get_var($this->wpdb->prepare(
179 - "SELECT COUNT(*) FROM `{$table}` WHERE trip_id = %d AND departure_date = %s AND departure_time IS NULL",
198 + "SELECT COUNT(*) FROM `{$table}` WHERE trip_id = %d AND departure_date = %s AND departure_time IS NULL{$exclude}",
180 199 $tripId,
181 200 $departureDate
182 201 ));
183 202 } else {
184 203 $count = (int) $this->wpdb->get_var($this->wpdb->prepare(
185 - "SELECT COUNT(*) FROM `{$table}` WHERE trip_id = %d AND departure_date = %s AND departure_time = %s",
204 + "SELECT COUNT(*) FROM `{$table}` WHERE trip_id = %d AND departure_date = %s AND departure_time = %s{$exclude}",
186 205 $tripId,
187 206 $departureDate,
188 207 $departureTime
189 208 ));
@@ -317,21 +336,36 @@
317 336 'to_longitude' => $this->sanitizeCoordinate($data['to_longitude'] ?? null),
318 337 'special_notes' => !empty($data['special_notes']) ? sanitize_textarea_field($data['special_notes']) : null,
319 338 'cutoff_date' => !empty($data['cutoff_date']) ? sanitize_text_field($data['cutoff_date']) : null,
320 339 'cutoff_hours' => (int) ($data['cutoff_hours'] ?? 24),
340 + 'is_blocked' => !empty($data['is_blocked']) ? 1 : 0,
341 + 'block_reason' => !empty($data['block_reason']) ? mb_substr(sanitize_textarea_field($data['block_reason']), 0, 255) : null,
342 + 'alert_threshold' => (isset($data['alert_threshold']) && $data['alert_threshold'] !== '' && $data['alert_threshold'] !== null) ? $this->clampAlertThreshold($data['alert_threshold']) : null,
321 343 ];
322 -
344 +
323 345 // Calculate discount percentage if not provided
324 346 if (!empty($insertData['original_price']) && !empty($insertData['discounted_price']) && empty($data['discount_percentage'])) {
325 347 $insertData['discount_percentage'] = round((($insertData['original_price'] - $insertData['discounted_price']) / $insertData['original_price']) * 100, 2);
326 348 }
327 -
328 - $this->wpdb->insert($table, $insertData, [
349 +
350 + $inserted = $this->wpdb->insert($table, $insertData, [
329 351 '%d', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%d',
330 352 '%s', '%f', '%f', '%f', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d',
353 + '%d', '%s', '%d',
331 354 ]);
332 -
333 - return $this->wpdb->insert_id;
355 +
356 + // A rejected insert used to be swallowed: insert_id stays 0, the caller
357 + // looks up row 0, gets null, and trips its own return type with a fatal
358 + // TypeError. Fail loudly instead so the caller can report something useful.
359 + if ($inserted === false) {
360 + throw new \RuntimeException(
361 + $this->wpdb->last_error !== ''
362 + ? $this->wpdb->last_error
363 + : 'Could not save the availability date.'
364 + );
365 + }
366 +
367 + return (int) $this->wpdb->insert_id;
334 368 }
335 369
336 370 /**
337 371 * Update availability date
@@ -374,9 +408,15 @@
374 408 }
375 409 if (isset($data['special_notes'])) $updateData['special_notes'] = !empty($data['special_notes']) ? sanitize_textarea_field($data['special_notes']) : null;
376 410 if (isset($data['cutoff_date'])) $updateData['cutoff_date'] = !empty($data['cutoff_date']) ? sanitize_text_field($data['cutoff_date']) : null;
377 411 if (isset($data['cutoff_hours'])) $updateData['cutoff_hours'] = (int) $data['cutoff_hours'];
378 -
412 + // array_key_exists (not isset) so an explicit null from the form — e.g.
413 + // clearing the block reason / threshold when a date is unblocked — is
414 + // honored instead of silently skipped (isset(null) === false).
415 + if (array_key_exists('is_blocked', $data)) $updateData['is_blocked'] = !empty($data['is_blocked']) ? 1 : 0;
416 + if (array_key_exists('block_reason', $data)) $updateData['block_reason'] = !empty($data['block_reason']) ? mb_substr(sanitize_textarea_field($data['block_reason']), 0, 255) : null;
417 + if (array_key_exists('alert_threshold', $data)) $updateData['alert_threshold'] = ($data['alert_threshold'] !== '' && $data['alert_threshold'] !== null) ? $this->clampAlertThreshold($data['alert_threshold']) : null;
418 +
379 419 // Calculate discount percentage if not provided
380 420 if (!empty($updateData['original_price']) && !empty($updateData['discounted_price']) && empty($updateData['discount_percentage'])) {
381 421 $updateData['discount_percentage'] = round((($updateData['original_price'] - $updateData['discounted_price']) / $updateData['original_price']) * 100, 2);
382 422 }