PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.9
Yatra – Travel Booking & Tour Operator Software v3.0.9
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 2.0.11 All 82 releases
yatra / app / Controllers / AvailabilityRecurringRulesController.php

AvailabilityRecurringRulesController.php in Yatra – Travel Booking & Tour Operator Software 3.0.9, at app/Controllers/AvailabilityRecurringRulesController.php

602 lines 18.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yatra\Controllers;
4
5 use Yatra\Services\AvailabilityRecurringRulesService;
6 use Yatra\Helpers\FormatHelper;
7 use Yatra\Helpers\ValidationHelper;
8
9 /**
10 * Availability Recurring Rules Controller Class
11 *
12 * Handles HTTP requests for recurring availability rules management.
13 * Provides REST API endpoints for CRUD operations and rule management.
14 *
15 * @package Yatra\Controllers
16 * @since 2.0.0
17 */
18 class AvailabilityRecurringRulesController
19 {
20 /**
21 * @var AvailabilityRecurringRulesService Service instance
22 */
23 private $service;
24
25 /**
26 * Constructor
27 */
28 public function __construct()
29 {
30 $this->service = new AvailabilityRecurringRulesService();
31 }
32
33 /**
34 * Register REST API routes
35 */
36 public function registerRoutes()
37 {
38 register_rest_route('yatra/v1', '/availability/recurring-rules', [
39 [
40 'methods' => 'GET',
41 'callback' => [$this, 'getItems'],
42 'permission_callback' => [$this, 'checkPermission'],
43 ],
44 [
45 'methods' => 'POST',
46 'callback' => [$this, 'createItem'],
47 'permission_callback' => [$this, 'checkPermission'],
48 ],
49 ]);
50
51 register_rest_route('yatra/v1', '/availability/recurring-rules/(?P<id>\d+)', [
52 [
53 'methods' => 'GET',
54 'callback' => [$this, 'getItem'],
55 'permission_callback' => [$this, 'checkPermission'],
56 ],
57 [
58 'methods' => 'PUT',
59 'callback' => [$this, 'updateItem'],
60 'permission_callback' => [$this, 'checkPermission'],
61 ],
62 [
63 'methods' => 'DELETE',
64 'callback' => [$this, 'deleteItem'],
65 'permission_callback' => [$this, 'checkPermission'],
66 ],
67 ]);
68
69 register_rest_route('yatra/v1', '/availability/recurring-rules/trip/(?P<tripId>\d+)', [
70 [
71 'methods' => 'GET',
72 'callback' => [$this, 'getRulesForTrip'],
73 'permission_callback' => [$this, 'checkPermission'],
74 ],
75 ]);
76
77 register_rest_route('yatra/v1', '/availability/recurring-rules/trip/(?P<tripId>\d+)/active', [
78 [
79 'methods' => 'GET',
80 'callback' => [$this, 'getActiveRulesForTrip'],
81 'permission_callback' => [$this, 'checkPermission'],
82 ],
83 ]);
84
85 register_rest_route('yatra/v1', '/availability/recurring-rules/trip/(?P<tripId>\d+)/date/(?P<date>[^/]+)', [
86 [
87 'methods' => 'GET',
88 'callback' => [$this, 'getRulesForDate'],
89 'permission_callback' => [$this, 'checkPermission'],
90 ],
91 ]);
92
93 register_rest_route('yatra/v1', '/availability/recurring-rules/(?P<id>\d+)/status', [
94 [
95 'methods' => 'PUT',
96 'callback' => [$this, 'updateStatus'],
97 'permission_callback' => [$this, 'checkPermission'],
98 ],
99 ]);
100
101 register_rest_route('yatra/v1', '/availability/recurring-rules/(?P<id>\d+)/exceptions', [
102 [
103 'methods' => 'POST',
104 'callback' => [$this, 'addException'],
105 'permission_callback' => [$this, 'checkPermission'],
106 ],
107 ]);
108
109 register_rest_route('yatra/v1', '/availability/recurring-rules/(?P<id>\d+)/exceptions/(?P<date>[^/]+)', [
110 [
111 'methods' => 'DELETE',
112 'callback' => [$this, 'removeException'],
113 'permission_callback' => [$this, 'checkPermission'],
114 ],
115 ]);
116
117 register_rest_route('yatra/v1', '/availability/recurring-rules/(?P<id>\d+)/generate-dates', [
118 [
119 'methods' => 'POST',
120 'callback' => [$this, 'generateDates'],
121 'permission_callback' => [$this, 'checkPermission'],
122 ],
123 ]);
124
125 register_rest_route('yatra/v1', '/availability/recurring-rules/trip/(?P<tripId>\d+)/exceptions', [
126 [
127 'methods' => 'GET',
128 'callback' => [$this, 'getRulesWithExceptions'],
129 'permission_callback' => [$this, 'checkPermission'],
130 ],
131 ]);
132
133 register_rest_route('yatra/v1', '/availability/recurring-rules/trip/(?P<tripId>\d+)/delete-all', [
134 [
135 'methods' => 'DELETE',
136 'callback' => [$this, 'deleteRulesForTrip'],
137 'permission_callback' => [$this, 'checkPermission'],
138 ],
139 ]);
140 }
141
142 /**
143 * Get recurring rules list
144 *
145 * @param \WP_REST_Request $request REST request object
146 * @return \WP_REST_Response REST response
147 */
148 public function getItems(\WP_REST_Request $request): \WP_REST_Response
149 {
150 try {
151 $tripId = $request->get_param('trip_id');
152 $status = $request->get_param('status');
153 $recurrenceType = $request->get_param('recurrence_type');
154 $page = $request->get_param('page') ?: 1;
155 $perPage = $request->get_param('per_page') ?: 20;
156
157 $args = [];
158 if ($tripId) {
159 $args['trip_id'] = (int) $tripId;
160 }
161 if ($status) {
162 $args['status'] = $status;
163 }
164 if ($recurrenceType) {
165 $args['recurrence_type'] = $recurrenceType;
166 }
167 $args['page'] = $page;
168 $args['per_page'] = $perPage;
169
170 $result = $this->service->getAll($args);
171
172 return new \WP_REST_Response([
173 'success' => true,
174 'data' => $result['data'],
175 'pagination' => $result['pagination'],
176 ], 200);
177
178 } catch (\Exception $e) {
179 return new \WP_REST_Response([
180 'success' => false,
181 'message' => $e->getMessage(),
182 ], 400);
183 }
184 }
185
186 /**
187 * Get recurring rule by ID
188 *
189 * @param \WP_REST_Request $request REST request object
190 * @return \WP_REST_Response REST response
191 */
192 public function getItem(\WP_REST_Request $request): \WP_REST_Response
193 {
194 try {
195 $id = (int) $request->get_param('id');
196 $item = $this->service->getById($id);
197
198 if (!$item) {
199 return new \WP_REST_Response([
200 'success' => false,
201 'message' => 'Recurring rule not found.',
202 ], 404);
203 }
204
205 return new \WP_REST_Response([
206 'success' => true,
207 'data' => $item,
208 ], 200);
209
210 } catch (\Exception $e) {
211 return new \WP_REST_Response([
212 'success' => false,
213 'message' => $e->getMessage(),
214 ], 400);
215 }
216 }
217
218 /**
219 * Create new recurring rule
220 *
221 * @param \WP_REST_Request $request REST request object
222 * @return \WP_REST_Response REST response
223 */
224 public function createItem(\WP_REST_Request $request): \WP_REST_Response
225 {
226 try {
227 $data = $request->get_json_params();
228
229 if (empty($data)) {
230 throw new \InvalidArgumentException('No data provided.');
231 }
232
233 $id = $this->service->create($data);
234
235 if (!$id) {
236 throw new \RuntimeException('Failed to create recurring rule.');
237 }
238
239 $item = $this->service->getById($id);
240
241 return new \WP_REST_Response([
242 'success' => true,
243 'data' => $item,
244 'message' => 'Recurring rule created successfully.',
245 ], 201);
246
247 } catch (\Exception $e) {
248 return new \WP_REST_Response([
249 'success' => false,
250 'message' => $e->getMessage(),
251 ], 400);
252 }
253 }
254
255 /**
256 * Update recurring rule
257 *
258 * @param \WP_REST_Request $request REST request object
259 * @return \WP_REST_Response REST response
260 */
261 public function updateItem(\WP_REST_Request $request): \WP_REST_Response
262 {
263 try {
264 $id = (int) $request->get_param('id');
265 $data = $request->get_json_params();
266
267 if (empty($data)) {
268 throw new \InvalidArgumentException('No data provided.');
269 }
270
271 $success = $this->service->update($id, $data);
272
273 if (!$success) {
274 throw new \RuntimeException('Failed to update recurring rule.');
275 }
276
277 $item = $this->service->getById($id);
278
279 return new \WP_REST_Response([
280 'success' => true,
281 'data' => $item,
282 'message' => 'Recurring rule updated successfully.',
283 ], 200);
284
285 } catch (\Exception $e) {
286 return new \WP_REST_Response([
287 'success' => false,
288 'message' => $e->getMessage(),
289 ], 400);
290 }
291 }
292
293 /**
294 * Delete recurring rule
295 *
296 * @param \WP_REST_Request $request REST request object
297 * @return \WP_REST_Response REST response
298 */
299 public function deleteItem(\WP_REST_Request $request): \WP_REST_Response
300 {
301 try {
302 $id = (int) $request->get_param('id');
303 $success = $this->service->delete($id);
304
305 if (!$success) {
306 throw new \RuntimeException('Failed to delete recurring rule.');
307 }
308
309 return new \WP_REST_Response([
310 'success' => true,
311 'message' => 'Recurring rule deleted successfully.',
312 ], 200);
313
314 } catch (\Exception $e) {
315 return new \WP_REST_Response([
316 'success' => false,
317 'message' => $e->getMessage(),
318 ], 400);
319 }
320 }
321
322 /**
323 * Get rules for a trip
324 *
325 * @param \WP_REST_Request $request REST request object
326 * @return \WP_REST_Response REST response
327 */
328 public function getRulesForTrip(\WP_REST_Request $request): \WP_REST_Response
329 {
330 try {
331 $tripId = (int) $request->get_param('tripId');
332 $rules = $this->service->getRulesForTrip($tripId);
333
334 return new \WP_REST_Response([
335 'success' => true,
336 'data' => $rules,
337 ], 200);
338
339 } catch (\Exception $e) {
340 return new \WP_REST_Response([
341 'success' => false,
342 'message' => $e->getMessage(),
343 ], 400);
344 }
345 }
346
347 /**
348 * Get active rules for a trip
349 *
350 * @param \WP_REST_Request $request REST request object
351 * @return \WP_REST_Response REST response
352 */
353 public function getActiveRulesForTrip(\WP_REST_Request $request): \WP_REST_Response
354 {
355 try {
356 $tripId = (int) $request->get_param('tripId');
357 $startDate = $request->get_param('start_date') ?: date('Y-m-d');
358 $endDate = $request->get_param('end_date') ?: date('Y-m-d', strtotime('+1 year'));
359
360 $rules = $this->service->getActiveRulesForTrip($tripId, $startDate, $endDate);
361
362 return new \WP_REST_Response([
363 'success' => true,
364 'data' => $rules,
365 ], 200);
366
367 } catch (\Exception $e) {
368 return new \WP_REST_Response([
369 'success' => false,
370 'message' => $e->getMessage(),
371 ], 400);
372 }
373 }
374
375 /**
376 * Get rules for a specific date
377 *
378 * @param \WP_REST_Request $request REST request object
379 * @return \WP_REST_Response REST response
380 */
381 public function getRulesForDate(\WP_REST_Request $request): \WP_REST_Response
382 {
383 try {
384 $tripId = (int) $request->get_param('tripId');
385 $date = $request->get_param('date');
386
387 $rules = $this->service->getRulesForDate($tripId, $date);
388
389 return new \WP_REST_Response([
390 'success' => true,
391 'data' => $rules,
392 ], 200);
393
394 } catch (\Exception $e) {
395 return new \WP_REST_Response([
396 'success' => false,
397 'message' => $e->getMessage(),
398 ], 400);
399 }
400 }
401
402 /**
403 * Update rule status
404 *
405 * @param \WP_REST_Request $request REST request object
406 * @return \WP_REST_Response REST response
407 */
408 public function updateStatus(\WP_REST_Request $request): \WP_REST_Response
409 {
410 try {
411 $id = (int) $request->get_param('id');
412 $data = $request->get_json_params();
413
414 if (!isset($data['status'])) {
415 throw new \InvalidArgumentException('Status is required.');
416 }
417
418 $success = $this->service->updateStatus($id, $data['status']);
419
420 if (!$success) {
421 throw new \RuntimeException('Failed to update rule status.');
422 }
423
424 return new \WP_REST_Response([
425 'success' => true,
426 'message' => 'Rule status updated successfully.',
427 ], 200);
428
429 } catch (\Exception $e) {
430 return new \WP_REST_Response([
431 'success' => false,
432 'message' => $e->getMessage(),
433 ], 400);
434 }
435 }
436
437 /**
438 * Add exception date to rule
439 *
440 * @param \WP_REST_Request $request REST request object
441 * @return \WP_REST_Response REST response
442 */
443 public function addException(\WP_REST_Request $request): \WP_REST_Response
444 {
445 try {
446 $id = (int) $request->get_param('id');
447 $data = $request->get_json_params();
448
449 if (!isset($data['date'])) {
450 throw new \InvalidArgumentException('Date is required.');
451 }
452
453 $success = $this->service->addException($id, $data['date']);
454
455 if (!$success) {
456 throw new \RuntimeException('Failed to add exception date.');
457 }
458
459 return new \WP_REST_Response([
460 'success' => true,
461 'message' => 'Exception date added successfully.',
462 ], 200);
463
464 } catch (\Exception $e) {
465 return new \WP_REST_Response([
466 'success' => false,
467 'message' => $e->getMessage(),
468 ], 400);
469 }
470 }
471
472 /**
473 * Remove exception date from rule
474 *
475 * @param \WP_REST_Request $request REST request object
476 * @return \WP_REST_Response REST response
477 */
478 public function removeException(\WP_REST_Request $request): \WP_REST_Response
479 {
480 try {
481 $id = (int) $request->get_param('id');
482 $date = $request->get_param('date');
483
484 $success = $this->service->removeException($id, $date);
485
486 if (!$success) {
487 throw new \RuntimeException('Failed to remove exception date.');
488 }
489
490 return new \WP_REST_Response([
491 'success' => true,
492 'message' => 'Exception date removed successfully.',
493 ], 200);
494
495 } catch (\Exception $e) {
496 return new \WP_REST_Response([
497 'success' => false,
498 'message' => $e->getMessage(),
499 ], 400);
500 }
501 }
502
503 /**
504 * Generate recurring dates for a rule
505 *
506 * @param \WP_REST_Request $request REST request object
507 * @return \WP_REST_Response REST response
508 */
509 public function generateDates(\WP_REST_Request $request): \WP_REST_Response
510 {
511 try {
512 $id = (int) $request->get_param('id');
513 $data = $request->get_json_params();
514
515 $startDate = $data['start_date'] ?? date('Y-m-d');
516 $endDate = $data['end_date'] ?? date('Y-m-d', strtotime('+1 year'));
517
518 $dates = $this->service->generateRecurringDates($id, $startDate, $endDate);
519
520 return new \WP_REST_Response([
521 'success' => true,
522 'data' => [
523 'dates' => $dates,
524 'count' => count($dates),
525 ],
526 ], 200);
527
528 } catch (\Exception $e) {
529 return new \WP_REST_Response([
530 'success' => false,
531 'message' => $e->getMessage(),
532 ], 400);
533 }
534 }
535
536 /**
537 * Get rules with exceptions for a trip
538 *
539 * @param \WP_REST_Request $request REST request object
540 * @return \WP_REST_Response REST response
541 */
542 public function getRulesWithExceptions(\WP_REST_Request $request): \WP_REST_Response
543 {
544 try {
545 $tripId = (int) $request->get_param('tripId');
546 $rules = $this->service->getRulesWithExceptions($tripId);
547
548 return new \WP_REST_Response([
549 'success' => true,
550 'data' => $rules,
551 ], 200);
552
553 } catch (\Exception $e) {
554 return new \WP_REST_Response([
555 'success' => false,
556 'message' => $e->getMessage(),
557 ], 400);
558 }
559 }
560
561 /**
562 * Delete all rules for a trip
563 *
564 * @param \WP_REST_Request $request REST request object
565 * @return \WP_REST_Response REST response
566 */
567 public function deleteRulesForTrip(\WP_REST_Request $request): \WP_REST_Response
568 {
569 try {
570 $tripId = (int) $request->get_param('tripId');
571 $deletedCount = $this->service->deleteRulesForTrip($tripId);
572
573 return new \WP_REST_Response([
574 'success' => true,
575 'message' => "Deleted {$deletedCount} recurring rules.",
576 'deleted_count' => $deletedCount,
577 ], 200);
578
579 } catch (\Exception $e) {
580 return new \WP_REST_Response([
581 'success' => false,
582 'message' => $e->getMessage(),
583 ], 400);
584 }
585 }
586
587 /**
588 * Check user permissions
589 *
590 * @param \WP_REST_Request $request REST request object
591 * @return bool Permission status
592 */
593 public function checkPermission(\WP_REST_Request $request): bool
594 {
595 // Trip-writes cap covers every endpoint on this controller —
596 // creating, editing, status-toggling, and generating dates from
597 // a recurring rule all mutate trip availability. WP admins pass
598 // automatically via the Team module's admin-fallback filter.
599 return current_user_can('yatra_edit_trips');
600 }
601 }
602