PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.4
Yatra – Travel Booking & Tour Operator Software v3.0.4
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 2.0.1 2.0.10 All 83 releases
yatra / app / Controllers / TripCategoryController.php

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

307 lines 10.2 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\CategoryService;
11 use Yatra\Database\Tables\TripsTable;
12 use Yatra\Database\Tables\TripClassificationsTable;
13
14 /**
15 * Trip Category REST API Controller
16 *
17 * Endpoints:
18 * - GET /trip-categories - List categories
19 * - POST /trip-categories - Create category
20 * - GET /trip-categories/{id} - Get single category
21 * - PUT /trip-categories/{id} - Update category
22 * - DELETE /trip-categories/{id} - Delete category
23 * - GET /trip-categories/{id}/subcategories - Get subcategories
24 */
25 class TripCategoryController extends BaseController
26 {
27 protected string $rest_base = 'trip-categories';
28
29 private CategoryService $service;
30
31 public function __construct()
32 {
33 $this->service = new CategoryService();
34 }
35
36 public function register_routes(): void
37 {
38 // Register CRUD routes with additional args
39 $this->registerCrudRoutes(array_merge(
40 $this->getStatusArg(),
41 [
42 'hierarchical' => [
43 'default' => false,
44 'sanitize_callback' => 'rest_sanitize_boolean',
45 ],
46 'parent_id' => [
47 'default' => null,
48 'sanitize_callback' => 'absint',
49 ],
50 ]
51 ));
52
53 // Additional route: Get subcategories
54 $this->registerRoute('/' . $this->rest_base . '/(?P<id>[\d]+)/subcategories', [
55 [
56 'methods' => \WP_REST_Server::READABLE,
57 'callback' => [$this, 'get_subcategories'],
58 'permission_callback' => [$this, 'check_permission'],
59 ],
60 ]);
61 }
62
63 public function check_permission(?WP_REST_Request $request = null): bool
64 {
65 if ($request === null) {
66 return true;
67 }
68
69 if (!is_user_logged_in()) {
70 return false;
71 }
72
73 if (current_user_can('manage_options')) {
74 return true;
75 }
76
77 switch ($request->get_method()) {
78 case 'GET':
79 return current_user_can('yatra_view_trips');
80 case 'POST':
81 case 'PUT':
82 case 'PATCH':
83 case 'DELETE':
84 return current_user_can('yatra_edit_trips');
85 default:
86 return current_user_can('manage_options');
87 }
88 }
89
90 public function get_items(WP_REST_Request $request)
91 {
92
93 try {
94 $params = $this->getPaginationParams($request);
95
96 $args = [
97 'limit' => $params['per_page'],
98 'offset' => ($params['page'] - 1) * $params['per_page'],
99 'order_by' => $params['orderby'],
100 'order' => $params['order'],
101 ];
102
103 if (!empty($params['search'])) {
104 $args['search'] = $params['search'];
105 }
106
107 $status = $request->get_param('status');
108 if ($status && $status !== 'all') {
109 $args['status'] = sanitize_text_field($status);
110 }
111
112 // Handle hierarchical and parent_id with proper implementation
113 $hierarchical = $request->get_param('hierarchical');
114 if ($hierarchical) {
115 // Use proper hierarchical implementation
116 $items = $this->service->getHierarchical($args);
117 } else {
118 $parent_id = $request->get_param('parent_id');
119 if ($parent_id !== null) {
120 // Get subcategories for specific parent
121 $items = $this->service->getSubcategories((int) $parent_id, $args);
122 } else {
123 // Get all categories
124 $items = $this->service->getAll($args);
125 }
126 }
127
128 $total = $this->service->count($args);
129
130 // Attach trip counts for each category using service methods
131 if (!empty($items)) {
132 $attachCounts = function (&$categories) use (&$attachCounts) {
133 if (empty($categories) || !is_array($categories)) {
134 return;
135 }
136
137 foreach ($categories as &$cat) {
138 $categoryId = isset($cat->id) ? (int) $cat->id : 0;
139 if ($categoryId > 0) {
140 $tripCount = $this->service->getTripCount($categoryId);
141 $cat->trip_count = $tripCount;
142 }
143
144 // Recursively attach counts to subcategories
145 if (isset($cat->subcategories) && is_array($cat->subcategories)) {
146 $attachCounts($cat->subcategories);
147 }
148 }
149 };
150
151 $attachCounts($items);
152 }
153
154 // Prepare all items including nested subcategories
155 $prepareAllItems = function (&$items) use (&$prepareAllItems) {
156 if (empty($items) || !is_array($items)) {
157 return;
158 }
159
160 foreach ($items as &$item) {
161 $item = (object) $this->prepareItem($item);
162
163 // Recursively prepare subcategories
164 if (isset($item->subcategories) && is_array($item->subcategories)) {
165 $prepareAllItems($item->subcategories);
166 }
167 }
168 };
169
170 $prepareAllItems($items);
171
172 return $this->paginated_response($items, $total, $params['page'], $params['per_page']);
173 } catch (\Exception $e) {
174 return $this->error_response($e->getMessage(), 500);
175 }
176 }
177
178 public function get_item(WP_REST_Request $request)
179 {
180 try {
181 $item = $this->service->getById($this->getId($request));
182
183 if (!$item) {
184 return $this->not_found(__('Category not found', 'yatra'));
185 }
186
187 // Attach trip count for single category using service methods
188 $categoryId = isset($item->id) ? (int) $item->id : 0;
189 if ($categoryId > 0) {
190 $tripCount = $this->service->getTripCount($categoryId);
191 $item->trip_count = $tripCount;
192 }
193
194 return $this->success_response($this->prepareItem($item));
195 } catch (\Exception $e) {
196 return $this->error_response($e->getMessage(), 500);
197 }
198 }
199
200 public function get_subcategories(WP_REST_Request $request)
201 {
202 try {
203 $subcategories = $this->service->getSubcategories($this->getId($request));
204
205 $prepared = array_map([$this, 'prepareItem'], $subcategories);
206
207 return $this->success_response($prepared);
208 } catch (\Exception $e) {
209 return $this->error_response($e->getMessage(), 500);
210 }
211 }
212
213 public function create_item(WP_REST_Request $request)
214 {
215 try {
216 $id = $this->service->create($this->getBody($request));
217
218 return $this->success_response([
219 'id' => $id,
220 'message' => __('Category created successfully', 'yatra'),
221 ], 201);
222 } catch (\InvalidArgumentException $e) {
223 return $this->validation_error($e->getMessage());
224 } catch (\Exception $e) {
225 return $this->error_response($e->getMessage(), 500);
226 }
227 }
228
229 public function update_item(WP_REST_Request $request)
230 {
231 try {
232 $result = $this->service->update($this->getId($request), $this->getBody($request));
233 if (!$result) {
234 return $this->error_response(__('Failed to update category', 'yatra'), 500);
235 }
236
237 return $this->success_response([
238 'message' => __('Category updated successfully', 'yatra'),
239 ]);
240 } catch (\InvalidArgumentException $e) {
241 return $this->validation_error($e->getMessage());
242 } catch (\Exception $e) {
243 return $this->error_response($e->getMessage(), 500);
244 }
245 }
246
247 public function delete_item(WP_REST_Request $request)
248 {
249 try {
250 $result = $this->service->delete($this->getId($request));
251
252 if (!$result) {
253 return $this->error_response(__('Failed to delete category', 'yatra'), 500);
254 }
255
256 return $this->success_response([
257 'message' => __('Category deleted successfully', 'yatra'),
258 ]);
259 } catch (\InvalidArgumentException $e) {
260 return $this->validation_error($e->getMessage());
261 } catch (\Exception $e) {
262 return $this->error_response($e->getMessage(), 500);
263 }
264 }
265
266 private function prepareItem($item): array
267 {
268
269 $prepared = (array) $item;
270
271 if (isset($prepared['icon']) && is_string($prepared['icon'])) {
272 $prepared['icon'] = maybe_unserialize($prepared['icon']);
273 }
274 if (isset($prepared['icon'])) {
275 $prepared['icon'] = $this->convert_icon_attachment_id_to_url($prepared['icon']);
276 }
277
278 // Handle metadata
279 if (isset($prepared['metadata']) && is_string($prepared['metadata'])) {
280 $prepared['metadata'] = maybe_unserialize($prepared['metadata']);
281 }
282
283
284 // Add parent name
285 if (!empty($prepared['parent_id'])) {
286 $parent = $this->service->getById((int) $prepared['parent_id']);
287 $prepared['parent_name'] = $parent ? $parent->name : null;
288 }
289
290 if (!empty($prepared['created_by'])) {
291 $user = get_userdata((int) $prepared['created_by']);
292 $prepared['created_by_name'] = $user ? esc_html($user->display_name) : null;
293 }
294
295 if (!empty($prepared['updated_by'])) {
296 $user = get_userdata((int) $prepared['updated_by']);
297 $prepared['updated_by_name'] = $user ? esc_html($user->display_name) : null;
298 }
299
300 if (array_key_exists('is_featured', $prepared)) {
301 $prepared['is_featured'] = !empty($prepared['is_featured']) ? 1 : 0;
302 }
303
304 return $prepared;
305 }
306 }
307