PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.6
Yatra – Travel Booking & Tour Operator Software v3.0.2.6
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 / ItemController.php

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

276 lines 8.6 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\ItemService;
11 use Yatra\Repositories\ItemTypeRepository;
12 use Yatra\Repositories\ItemRepository;
13
14 /**
15 * Item REST API Controller
16 *
17 * Endpoints:
18 * - GET /items - List items
19 * - POST /items - Create item
20 * - GET /items/{id} - Get single item
21 * - PUT /items/{id} - Update item
22 * - DELETE /items/{id} - Delete item
23 */
24 class ItemController extends BaseController
25 {
26 protected string $rest_base = 'items';
27
28 private ItemService $service;
29 private ItemTypeRepository $itemTypeRepository;
30 private ItemRepository $repository;
31
32 public function __construct()
33 {
34 $this->service = new ItemService();
35 $this->itemTypeRepository = new ItemTypeRepository();
36 $this->repository = new ItemRepository();
37 }
38
39 public function register_routes(): void
40 {
41 $this->registerCrudRoutes(array_merge(
42 $this->getStatusArg(),
43 [
44 'type_id' => [
45 'default' => 'all',
46 'sanitize_callback' => 'absint',
47 ],
48 ]
49 ));
50
51 // Status statistics for admin views (All / Published / Draft / Trash)
52 register_rest_route($this->namespace, '/' . $this->rest_base . '/stats', [
53 [
54 'methods' => \WP_REST_Server::READABLE,
55 'callback' => [$this, 'getStats'],
56 'permission_callback' => [$this, 'check_permission'],
57 ],
58 ]);
59 }
60
61 /**
62 * GET /items/stats
63 * Return stable status counts for admin list views.
64 */
65 public function getStats(WP_REST_Request $request)
66 {
67 try {
68 $stats = $this->service->getStatusCounts();
69 return $this->success_response($stats);
70 } catch (\Exception $e) {
71 return $this->error_response($e->getMessage(), 500);
72 }
73 }
74
75 public function check_permission(?WP_REST_Request $request = null): bool
76 {
77 if ($request === null) {
78 return true;
79 }
80
81 if (!is_user_logged_in()) {
82 return false;
83 }
84
85 if (current_user_can('manage_options')) {
86 return true;
87 }
88
89 switch ($request->get_method()) {
90 case 'GET':
91 return current_user_can('yatra_view_trips');
92 case 'POST':
93 case 'PUT':
94 case 'PATCH':
95 case 'DELETE':
96 return current_user_can('yatra_edit_trips');
97 default:
98 return current_user_can('manage_options');
99 }
100 }
101
102 public function get_items(WP_REST_Request $request)
103 {
104 try {
105 $params = $this->getPaginationParams($request);
106
107 $args = [
108 'limit' => $params['per_page'],
109 'offset' => ($params['page'] - 1) * $params['per_page'],
110 'order_by' => $params['orderby'],
111 'order' => $params['order'],
112 ];
113
114 if (!empty($params['search'])) {
115 $args['search'] = $params['search'];
116 }
117
118 $type_id = $request->get_param('type_id');
119 if ($type_id && $type_id !== 'all') {
120 $args['type_id'] = absint($type_id);
121 }
122
123 $status = $request->get_param('status');
124 if ($status && $status !== 'all') {
125 $args['status'] = sanitize_text_field($status);
126 }
127
128 $items = $this->service->getAll($args);
129 $total = $this->service->count($args);
130
131 $prepared = array_map([$this, 'prepareItem'], $items);
132
133 // Get available item types for filter dropdown
134 $all_types = $this->itemTypeRepository->all(['where' => ['status' => 'publish']]);
135 $available_types = array_map(function ($type) {
136 return [
137 'id' => (int) $type->id,
138 'name' => esc_html($type->name),
139 ];
140 }, $all_types);
141
142 return new \WP_REST_Response([
143 'data' => $prepared,
144 'total' => $total,
145 'page' => $params['page'],
146 'per_page' => $params['per_page'],
147 'total_pages' => (int) ceil($total / $params['per_page']),
148 'meta' => [
149 'available_types' => array_values($available_types),
150 ],
151 ], 200);
152 } catch (\Exception $e) {
153 return $this->error_response($e->getMessage(), 500);
154 }
155 }
156
157 public function get_item(WP_REST_Request $request)
158 {
159 try {
160 $item = $this->service->getById($this->getId($request));
161
162 if (!$item) {
163 return $this->not_found(__('Item not found', 'yatra'));
164 }
165
166 return $this->success_response($this->prepareItem($item));
167 } catch (\Exception $e) {
168 return $this->error_response($e->getMessage(), 500);
169 }
170 }
171
172 public function create_item(WP_REST_Request $request)
173 {
174 try {
175 $id = $this->service->create($this->getBody($request));
176
177 // Get the created item to return full data
178 $item = $this->service->getById($id);
179
180 return $this->success_response([
181 'id' => $id,
182 'message' => __('Item created successfully', 'yatra'),
183 'data' => $item,
184 ], 201);
185 } catch (\InvalidArgumentException $e) {
186 return $this->validation_error($e->getMessage());
187 } catch (\Exception $e) {
188 return $this->error_response($e->getMessage(), 500);
189 }
190 }
191
192 public function update_item(WP_REST_Request $request)
193 {
194 try {
195 $result = $this->service->update($this->getId($request), $this->getBody($request));
196
197 if (!$result) {
198 return $this->error_response(__('Failed to update item', 'yatra'), 500);
199 }
200
201 return $this->success_response([
202 'message' => __('Item updated successfully', 'yatra'),
203 ]);
204 } catch (\InvalidArgumentException $e) {
205 return $this->validation_error($e->getMessage());
206 } catch (\Exception $e) {
207 return $this->error_response($e->getMessage(), 500);
208 }
209 }
210
211 public function delete_item(WP_REST_Request $request)
212 {
213 try {
214 $result = $this->service->delete($this->getId($request));
215
216 if (!$result) {
217 return $this->error_response(__('Failed to delete item', 'yatra'), 500);
218 }
219
220 return $this->success_response([
221 'message' => __('Item deleted successfully', 'yatra'),
222 ]);
223 } catch (\Exception $e) {
224 return $this->error_response($e->getMessage(), 500);
225 }
226 }
227
228 private function prepareItem($item): array
229 {
230 $prepared = (array) $item;
231
232 // For unified ClassificationsTable, items have parent_id = item type ID
233 if (!empty($prepared['parent_id'])) {
234 $prepared['type_id'] = (int) $prepared['parent_id'];
235 }
236
237 // Get item type info
238 if (!empty($prepared['type_id'])) {
239 $type = $this->itemTypeRepository->find((int) $prepared['type_id']);
240
241 if ($type) {
242 $prepared['type_name'] = esc_html($type->name);
243
244 if (!empty($type->icon)) {
245 $icon_data = maybe_unserialize($type->icon);
246 if (is_array($icon_data) && isset($icon_data['value'])) {
247 $prepared['type_icon'] = $icon_data['value'];
248 } elseif (is_string($type->icon)) {
249 $prepared['type_icon'] = $type->icon;
250 }
251 }
252 } else {
253 // If type not found, set unknown
254 $prepared['type_name'] = __('Unknown', 'yatra');
255 }
256 } else {
257 // If no type_id, set unknown
258 $prepared['type_name'] = __('Unknown', 'yatra');
259 }
260
261 if (!empty($prepared['created_by'])) {
262 $user = get_userdata((int) $prepared['created_by']);
263 $prepared['created_by_name'] = $user ? esc_html($user->display_name) : null;
264 }
265
266 if (!empty($prepared['updated_by'])) {
267 $user = get_userdata((int) $prepared['updated_by']);
268 $prepared['updated_by_name'] = $user ? esc_html($user->display_name) : null;
269 }
270
271 $prepared['usage_count'] = $this->repository->countUsage((int) $prepared['id']);
272
273 return $prepared;
274 }
275 }
276