PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.8
Yatra – Travel Booking & Tour Operator Software v3.0.2.8
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 / ItineraryController.php

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

344 lines 11.7 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\Controllers;
6
7 use WP_REST_Request;
8 use WP_REST_Response;
9 use WP_Error;
10 use Yatra\Services\ItineraryService;
11 use Yatra\Repositories\ItineraryRepository;
12
13 /**
14 * Itinerary REST API Controller
15 * API endpoints for itinerary entries management
16 */
17 class ItineraryController extends BaseController
18 {
19 private ItineraryService $service;
20
21 public function __construct()
22 {
23 $this->service = new ItineraryService(new ItineraryRepository());
24 }
25
26 /**
27 * Register routes
28 */
29 public function register_routes(): void
30 {
31 $namespace = 'yatra/v1';
32 $base = 'itinerary';
33
34 // Collection routes
35 register_rest_route($namespace, '/' . $base, [
36 [
37 'methods' => \WP_REST_Server::CREATABLE,
38 'callback' => [$this, 'create_item'],
39 'permission_callback' => [$this, 'check_permission'],
40 ],
41 [
42 'methods' => \WP_REST_Server::DELETABLE,
43 'callback' => [$this, 'bulk_delete_items'],
44 'permission_callback' => [$this, 'check_permission'],
45 ],
46 [
47 'methods' => \WP_REST_Server::READABLE,
48 'callback' => [$this, 'get_items_by_trip'],
49 'permission_callback' => [$this, 'check_permission'],
50 ],
51 ]);
52
53 // Single item routes
54 register_rest_route($namespace, '/' . $base . '/(?P<id>[\d]+)', [
55 [
56 'methods' => \WP_REST_Server::READABLE,
57 'callback' => [$this, 'get_item'],
58 'permission_callback' => [$this, 'check_permission'],
59 ],
60 [
61 'methods' => \WP_REST_Server::EDITABLE,
62 'callback' => [$this, 'update_item'],
63 'permission_callback' => [$this, 'check_permission'],
64 ],
65 [
66 'methods' => \WP_REST_Server::DELETABLE,
67 'callback' => [$this, 'delete_item'],
68 'permission_callback' => [$this, 'check_permission'],
69 ],
70 ]);
71
72 // Get day entry ID by day_id
73 register_rest_route($namespace, '/' . $base . '/day-entry-by-day-id/(?P<day_id>[\d]+)', [
74 [
75 'methods' => \WP_REST_Server::READABLE,
76 'callback' => [$this, 'get_day_entry_id_by_day_id'],
77 'permission_callback' => [$this, 'check_permission'],
78 ],
79 ]);
80 }
81
82 /**
83 * Get items by trip ID
84 */
85 public function get_items_by_trip(WP_REST_Request $request)
86 {
87 try {
88 $trip_id = (int) $request->get_param('trip_id');
89
90 if (!$trip_id) {
91 return $this->error_response('Trip ID is required', 400);
92 }
93
94 $items = $this->service->getByTripId($trip_id);
95
96 // Debug logging
97 $prepared_items = array_map(function ($item) use ($request) {
98 $prepared = $this->prepare_item_for_response($item, $request);
99 return $prepared;
100 }, $items);
101
102 $response = $this->success_response($prepared_items);
103 return $response;
104 } catch (\Exception $e) {
105 return $this->error_response($e->getMessage(), 500);
106 }
107 }
108
109 /**
110 * Get item
111 */
112 public function get_item(WP_REST_Request $request)
113 {
114 try {
115 $id = (int) $request->get_param('id');
116 $mode = $request->get_param('mode') ?: 'activity'; // Default to activity mode
117
118 // Use mode to determine which method to call
119 if ($mode === 'day') {
120 // Get day entry (from days table)
121 $item = $this->service->find($id);
122 } else {
123 // Get activity entry (from entries table)
124 $item = $this->service->findActivity($id);
125 }
126
127 if (!$item) {
128 return $this->error_response('Itinerary entry not found', 404);
129 }
130
131 $prepared = $this->prepare_item_for_response($item, $request);
132 return $this->success_response($prepared);
133 } catch (\Exception $e) {
134 return $this->error_response($e->getMessage(), 500);
135 }
136 }
137
138 /**
139 * Create item
140 */
141 public function create_item(WP_REST_Request $request)
142 {
143 try {
144 $data = $request->get_json_params();
145 $id = $this->service->create($data);
146
147 return $this->success_response([
148 'id' => $id,
149 'message' => __('Itinerary entry created successfully', 'yatra'),
150 ], 201);
151 } catch (\InvalidArgumentException $e) {
152 return $this->error_response($e->getMessage(), 400);
153 } catch (\Exception $e) {
154 return $this->error_response($e->getMessage(), 500);
155 }
156 }
157
158 /**
159 * Update item
160 */
161 public function update_item(WP_REST_Request $request)
162 {
163 try {
164 $id = (int) $request->get_param('id');
165 $mode = $request->get_param('mode') ?: 'activity'; // Default to activity mode
166 $data = $request->get_json_params();
167 $result = $this->service->update($id, $data, $mode);
168
169 if (!$result) {
170 return $this->error_response('Failed to update itinerary entry', 500);
171 }
172
173 return $this->success_response([
174 'message' => __('Itinerary entry updated successfully', 'yatra'),
175 ]);
176 } catch (\InvalidArgumentException $e) {
177 return $this->error_response($e->getMessage(), 400);
178 } catch (\Exception $e) {
179 return $this->error_response($e->getMessage(), 500);
180 }
181 }
182
183 /**
184 * Delete item
185 */
186 public function delete_item(WP_REST_Request $request)
187 {
188 try {
189 $id = (int) $request->get_param('id');
190 $mode = $request->get_param('mode') ?: 'activity'; // Default to activity mode
191 $result = $this->service->delete($id, $mode);
192
193 if (!$result) {
194 return $this->error_response('Failed to delete itinerary entry', 500);
195 }
196
197 return $this->success_response([
198 'message' => __('Itinerary entry deleted successfully', 'yatra'),
199 ]);
200 } catch (\Exception $e) {
201 return $this->error_response($e->getMessage(), 500);
202 }
203 }
204
205 /**
206 * Bulk delete items
207 */
208 public function bulk_delete_items(WP_REST_Request $request)
209 {
210 try {
211 $data = $request->get_json_params();
212 $ids = $data['ids'] ?? [];
213
214 if (empty($ids) || !is_array($ids)) {
215 return $this->error_response('No IDs provided for bulk delete', 400);
216 }
217
218 $result = $this->service->bulkDelete($ids);
219
220 return $this->success_response([
221 'deleted' => $result['deleted'],
222 'failed' => $result['failed'],
223 'message' => sprintf(
224 __('%d item(s) deleted successfully. %d item(s) failed to delete.', 'yatra'),
225 $result['deleted'],
226 $result['failed']
227 ),
228 ]);
229 } catch (\Exception $e) {
230 return $this->error_response($e->getMessage(), 500);
231 }
232 }
233
234 /**
235 * Get day entry ID by day_id
236 */
237 public function get_day_entry_id_by_day_id(WP_REST_Request $request)
238 {
239 try {
240 $dayId = (int) $request->get_param('day_id');
241 $repository = new ItineraryRepository();
242 $dayEntryId = $repository->getDayEntryIdByDayId($dayId);
243
244 return $this->success_response([
245 'day_entry_id' => $dayEntryId,
246 ]);
247 } catch (\Exception $e) {
248 return $this->error_response($e->getMessage(), 500);
249 }
250 }
251
252 /**
253 * Prepare item for response
254 */
255 protected function prepare_item_for_response($item, WP_REST_Request $request): array
256 {
257 // Parse included_items and excluded_items from JSON if they're strings
258 $includedItems = $item->included_items ?? [];
259 if (is_string($includedItems)) {
260 $decoded = json_decode($includedItems, true);
261 $includedItems = is_array($decoded) ? $decoded : [];
262 }
263
264 $excludedItems = $item->excluded_items ?? [];
265 if (is_string($excludedItems)) {
266 $decoded = json_decode($excludedItems, true);
267 $excludedItems = is_array($decoded) ? $decoded : [];
268 }
269
270 return [
271 'id' => (int) $item->id,
272 'trip_id' => (int) $item->trip_id,
273 'day_id' => (int) $item->day_id,
274 'day' => isset($item->day_number) ? (int) $item->day_number : null,
275 'day_title' => $item->day_title ?? null,
276 'day_description' => $item->day_description ?? null,
277 'title' => $item->title ?? '',
278 'description' => $item->description ?? '',
279 'time' => $item->time ?? null,
280 'start_time' => $item->start_time ?? null,
281 'end_time' => $item->end_time ?? null,
282 'time_type' => $item->time_type ?? 'exact',
283 'location' => $item->location ?? null,
284 'location_latitude' => $item->location_latitude ?? null,
285 'location_longitude' => $item->location_longitude ?? null,
286 'duration' => $item->duration ?? null,
287 'cost' => isset($item->cost) ? (float) $item->cost : null,
288 'cost_per_person' => isset($item->cost_per_person) ? (bool) $item->cost_per_person : false,
289 'notes' => $item->notes ?? null,
290 'item_type_id' => ($item->item_type_id !== null && $item->item_type_id !== '') ? (int) $item->item_type_id : null,
291 'item_id' => ($item->item_id !== null && $item->item_id !== '') ? (int) $item->item_id : null,
292 'item_type_name' => $item->item_type_name ?? null,
293 'item_name' => $item->item_name ?? null,
294 'item_type_icon' => $item->item_type_icon ?? null,
295 'included_items' => $includedItems,
296 'excluded_items' => $excludedItems,
297 'status' => $item->status ?? 'draft',
298 'images' => $item->images ?? [],
299 'gallery' => $this->decodeGallery($item->gallery ?? null),
300 'video_url' => $item->video_url ?? null,
301 'order' => (int) ($item->order ?? 0),
302 'created_at' => $item->created_at ?? null,
303 'updated_at' => $item->updated_at ?? null,
304 ];
305 }
306
307 /**
308 * Decode gallery JSON from database and convert attachment IDs to URLs
309 */
310 private function decodeGallery(?string $galleryJson): array
311 {
312 if (empty($galleryJson)) {
313 return [];
314 }
315
316 $gallery = json_decode($galleryJson, true);
317 if (!is_array($gallery)) {
318 return [];
319 }
320
321 // Convert attachment IDs to URLs for frontend compatibility
322 foreach ($gallery as &$item) {
323 if (isset($item['attachment_id']) && $item['attachment_id'] > 0) {
324 // Get attachment URL from WordPress
325 $attachment_url = wp_get_attachment_url($item['attachment_id']);
326 if ($attachment_url) {
327 $item['url'] = $attachment_url;
328 }
329
330 // Get thumbnail URL for images
331 if (isset($item['type']) && $item['type'] === 'image') {
332 $thumbnail_url = wp_get_attachment_image_src($item['attachment_id'], 'medium');
333 if ($thumbnail_url) {
334 $item['thumbnail_url'] = $thumbnail_url[0];
335 }
336 }
337 }
338 }
339
340 return $gallery;
341 }
342 }
343
344