PluginProbe
Yatra – Travel Booking & Tour Operator Software / trunk
Yatra – Travel Booking & Tour Operator Software vtrunk
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 / DestinationController.php

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

294 lines 9.4 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\DestinationService;
11 use Yatra\Database\Tables\TripsTable;
12 use Yatra\Database\Tables\TripClassificationsTable;
13
14 /**
15 * Destination REST API Controller
16 *
17 * Endpoints:
18 * - GET /destinations - List destinations
19 * - POST /destinations - Create destination
20 * - GET /destinations/{id} - Get single destination
21 * - PUT /destinations/{id} - Update destination
22 * - DELETE /destinations/{id} - Delete destination
23 */
24 class DestinationController extends BaseController
25 {
26 protected string $rest_base = 'destinations';
27
28 private DestinationService $service;
29
30 public function __construct()
31 {
32 $this->service = new DestinationService();
33 }
34
35 public function register_routes(): void
36 {
37 $this->registerCrudRoutes($this->getStatusArg());
38
39 // Bulk operations
40 register_rest_route($this->namespace, '/' . $this->rest_base . '/bulk', [
41 'methods' => \WP_REST_Server::CREATABLE,
42 'callback' => [$this, 'bulkAction'],
43 'permission_callback' => [$this, 'check_permission'],
44 ]);
45
46 // Stats endpoint
47 register_rest_route($this->namespace, '/' . $this->rest_base . '/stats', [
48 'methods' => \WP_REST_Server::READABLE,
49 'callback' => [$this, 'getStats'],
50 'permission_callback' => [$this, 'check_permission'],
51 ]);
52 }
53
54 public function check_permission(?WP_REST_Request $request = null): bool
55 {
56 if ($request === null) {
57 return true;
58 }
59
60 if (!is_user_logged_in()) {
61 return false;
62 }
63
64 if (current_user_can('manage_options')) {
65 return true;
66 }
67
68 switch ($request->get_method()) {
69 case 'GET':
70 return current_user_can('yatra_view_trips');
71 case 'POST':
72 case 'PUT':
73 case 'PATCH':
74 case 'DELETE':
75 return current_user_can('yatra_edit_trips');
76 default:
77 // Unknown HTTP method — deny explicitly. The earlier
78 // fallback to `manage_options` was a regression that
79 // silently broadened admin-only access for any verb not
80 // in the explicit switch.
81 return false;
82 }
83 }
84
85 public function get_items(WP_REST_Request $request)
86 {
87 try {
88 $params = $this->getPaginationParams($request);
89
90 $args = [
91 'limit' => $params['per_page'],
92 'offset' => ($params['page'] - 1) * $params['per_page'],
93 'order_by' => $params['orderby'],
94 'order' => $params['order'],
95 ];
96
97 if (!empty($params['search'])) {
98 $args['search'] = $params['search'];
99 }
100
101 $status = $request->get_param('status');
102 if ($status && $status !== 'all') {
103 $args['status'] = sanitize_text_field($status);
104 }
105
106 $items = $this->service->getAll($args);
107 $total = $this->service->count($args);
108
109 // Attach trip counts to items
110 if (!empty($items)) {
111 foreach ($items as $item) {
112 $destinationId = isset($item->id) ? (int) $item->id : 0;
113 if ($destinationId <= 0) {
114 continue;
115 }
116
117 $tripCount = $this->service->getTripCount($destinationId);
118 $item->trip_count = $tripCount;
119 }
120 }
121
122 $prepared = array_map([$this, 'prepareItem'], $items);
123
124 return $this->paginated_response($prepared, $total, $params['page'], $params['per_page']);
125 } catch (\Exception $e) {
126 return $this->error_response($e->getMessage(), 500);
127 }
128 }
129
130 public function get_item(WP_REST_Request $request)
131 {
132 try {
133 $item = $this->service->getById($this->getId($request));
134
135 if (!$item) {
136 return $this->not_found(__('Destination not found', 'yatra'));
137 }
138
139 // Attach trip count for single destination
140 $destinationId = isset($item->id) ? (int) $item->id : 0;
141 if ($destinationId > 0) {
142 $tripCount = $this->service->getTripCount($destinationId);
143 $item->trip_count = $tripCount;
144 }
145
146 return $this->success_response($this->prepareItem($item));
147 } catch (\Exception $e) {
148 return $this->error_response($e->getMessage(), 500);
149 }
150 }
151
152 public function create_item(WP_REST_Request $request)
153 {
154 try {
155 $id = $this->service->create($this->getBody($request));
156
157 return $this->success_response([
158 'id' => $id,
159 'message' => __('Destination created successfully', 'yatra'),
160 ], 201);
161 } catch (\InvalidArgumentException $e) {
162 return $this->validation_error($e->getMessage());
163 } catch (\Exception $e) {
164 return $this->error_response($e->getMessage(), 500);
165 }
166 }
167
168 public function update_item(WP_REST_Request $request)
169 {
170 try {
171 $body = $this->getBody($request);
172
173 $result = $this->service->update($this->getId($request), $body);
174
175 if (!$result) {
176 return $this->error_response(__('Failed to update destination', 'yatra'), 500);
177 }
178
179 return $this->success_response([
180 'message' => __('Destination updated successfully', 'yatra'),
181 ]);
182 } catch (\InvalidArgumentException $e) {
183 return $this->validation_error($e->getMessage());
184 } catch (\Exception $e) {
185 return $this->error_response($e->getMessage(), 500);
186 }
187 }
188
189 public function delete_item(WP_REST_Request $request)
190 {
191 try {
192 $result = $this->service->delete($this->getId($request));
193
194 if (!$result) {
195 return $this->error_response(__('Failed to delete destination', 'yatra'), 500);
196 }
197
198 return $this->success_response([
199 'message' => __('Destination deleted successfully', 'yatra'),
200 ]);
201 } catch (\Exception $e) {
202 return $this->error_response($e->getMessage(), 500);
203 }
204 }
205
206 private function prepareItem($item): array
207 {
208 $prepared = (array) $item;
209
210
211 if (isset($prepared['icon']) && is_string($prepared['icon'])) {
212 $prepared['icon'] = maybe_unserialize($prepared['icon']);
213 }
214 if (isset($prepared['icon'])) {
215 $prepared['icon'] = $this->convert_icon_attachment_id_to_url($prepared['icon']);
216 }
217
218 // Handle metadata
219 if (isset($prepared['metadata']) && is_string($prepared['metadata'])) {
220 $prepared['metadata'] = maybe_unserialize($prepared['metadata']);
221 }
222
223 if (!empty($prepared['created_by'])) {
224 $user = get_userdata((int) $prepared['created_by']);
225 $prepared['created_by_name'] = $user ? esc_html($user->display_name) : null;
226 }
227
228 if (!empty($prepared['updated_by'])) {
229 $user = get_userdata((int) $prepared['updated_by']);
230 $prepared['updated_by_name'] = $user ? esc_html($user->display_name) : null;
231 }
232
233 return $prepared;
234 }
235
236 /**
237 * Handle bulk operations
238 */
239 public function bulkAction(WP_REST_Request $request)
240 {
241 try {
242 $action = sanitize_text_field($request->get_param('action'));
243 $ids = $request->get_param('ids');
244
245 if (empty($action)) {
246 return $this->validation_error(__('Action is required', 'yatra'));
247 }
248
249 if (empty($ids)) {
250 return $this->validation_error(__('No destinations selected', 'yatra'));
251 }
252
253 switch ($action) {
254 case 'trash':
255 $result = $this->service->bulkUpdateStatus($ids, 'trash');
256 break;
257 case 'publish':
258 $result = $this->service->bulkUpdateStatus($ids, 'publish');
259 break;
260 case 'draft':
261 $result = $this->service->bulkUpdateStatus($ids, 'draft');
262 break;
263 case 'restore':
264 $result = $this->service->bulkUpdateStatus($ids, 'publish');
265 break;
266 case 'delete':
267 $result = $this->service->bulkDelete($ids);
268 break;
269 default:
270 throw new \InvalidArgumentException(__('Invalid action', 'yatra'));
271 }
272
273 return $this->success_response($result);
274 } catch (\InvalidArgumentException $e) {
275 return $this->validation_error($e->getMessage());
276 } catch (\Exception $e) {
277 return $this->error_response($e->getMessage(), 500);
278 }
279 }
280
281 /**
282 * Get statistics for admin views
283 */
284 public function getStats(WP_REST_Request $request)
285 {
286 try {
287 $stats = $this->service->getStatusCounts();
288 return $this->success_response($stats);
289 } catch (\Exception $e) {
290 return $this->error_response($e->getMessage(), 500);
291 }
292 }
293 }
294