PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.9
Yatra – Travel Booking & Tour Operator Software v3.0.2.9
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 / Services / ItemTypeService.php

ItemTypeService.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.9, at app/Services/ItemTypeService.php

323 lines 10.5 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\Services;
6
7 use Yatra\Repositories\ItemTypeRepository;
8 use Yatra\Helpers\SlugHelper;
9
10 /**
11 * Item Type Service
12 * Contains business logic for item types
13 */
14 class ItemTypeService extends BaseService
15 {
16 /**
17 * @var ItemTypeRepository
18 */
19 private ItemTypeRepository $repository;
20
21 /**
22 * Constructor
23 */
24 public function __construct()
25 {
26 $this->repository = new ItemTypeRepository();
27 }
28
29 /**
30 * Get repository
31 */
32 protected function getRepository(): ItemTypeRepository
33 {
34 return $this->repository;
35 }
36
37 /**
38 * Get repository (public access for controllers)
39 */
40 public function getRepositoryInstance(): ItemTypeRepository
41 {
42 return $this->repository;
43 }
44
45 /**
46 * Validate item type data
47 */
48 protected function validate(array $data, ?int $id = null): void
49 {
50 if (empty($data['name'])) {
51 throw new \InvalidArgumentException('Item type name is required');
52 }
53
54 // Slug will be auto-generated from name, so we don't need to validate it here
55 // The SlugHelper will ensure uniqueness
56
57 // Validate status
58 $allowed_statuses = ['draft', 'publish', 'trash'];
59 if (isset($data['status']) && !in_array($data['status'], $allowed_statuses, true)) {
60 throw new \InvalidArgumentException('Invalid status. Must be one of: ' . implode(', ', $allowed_statuses));
61 }
62
63 // Validate color
64 $allowed_colors = ['blue', 'green', 'purple', 'orange', 'red', 'yellow', 'gray'];
65 if (isset($data['color']) && !in_array($data['color'], $allowed_colors, true)) {
66 throw new \InvalidArgumentException('Invalid color. Must be one of: ' . implode(', ', $allowed_colors));
67 }
68 }
69
70 /**
71 * Process before create
72 */
73 protected function processBeforeCreate(array $data): array
74 {
75 // Set type to item_type for ClassificationsTable
76 $data['type'] = \Yatra\Constants\ClassificationTypes::ITEM_TYPE;
77
78 // Sanitize name
79 if (isset($data['name'])) {
80 $data['name'] = sanitize_text_field($data['name']);
81 }
82
83 // Always auto-generate slug from name (backend ensures uniqueness)
84 if (!empty($data['name'])) {
85 // Use ClassificationsTable directly to avoid protected method issue
86 $tableName = \Yatra\Database\Tables\ClassificationsTable::getTableName();
87 // Remove WordPress prefix since SlugHelper adds it automatically
88 global $wpdb;
89 $tableNameWithoutPrefix = str_replace($wpdb->prefix, '', $tableName);
90
91
92 $data['slug'] = SlugHelper::generateUniqueFromDatabase(
93 $data['name'],
94 $tableNameWithoutPrefix,
95 'slug'
96 );
97 } elseif (isset($data['slug'])) {
98 // If name is empty but slug is provided, sanitize it
99 $data['slug'] = SlugHelper::generate($data['slug']);
100 }
101
102 // Sanitize description
103 if (isset($data['description'])) {
104 $data['description'] = sanitize_textarea_field($data['description']);
105 }
106
107 // Sanitize status
108 if (isset($data['status'])) {
109 $allowed_statuses = ['draft', 'publish', 'trash'];
110 $data['status'] = in_array($data['status'], $allowed_statuses, true)
111 ? $data['status']
112 : 'draft';
113 } else {
114 $data['status'] = 'draft';
115 }
116
117 // Sanitize color
118 if (isset($data['color'])) {
119 $allowed_colors = ['blue', 'green', 'purple', 'orange', 'red', 'yellow', 'gray'];
120 $data['color'] = in_array($data['color'], $allowed_colors, true)
121 ? $data['color']
122 : 'blue';
123 } else {
124 $data['color'] = 'blue';
125 }
126
127 // Set created_by and updated_by to current user
128 $current_user_id = get_current_user_id();
129 $data['created_by'] = absint($current_user_id);
130 $data['updated_by'] = absint($current_user_id);
131
132 // Sanitize and serialize icon if it's an array
133 if (isset($data['icon'])) {
134 if (is_array($data['icon'])) {
135 // Sanitize icon array
136 $icon = [
137 'type' => isset($data['icon']['type']) && in_array($data['icon']['type'], ['icon', 'image'], true)
138 ? $data['icon']['type']
139 : 'icon',
140 'value' => isset($data['icon']['value'])
141 ? sanitize_text_field($data['icon']['value'])
142 : '',
143 ];
144 $data['icon'] = maybe_serialize($icon);
145 } elseif (is_string($data['icon'])) {
146 // If it's already a string, sanitize it
147 $data['icon'] = sanitize_text_field($data['icon']);
148 }
149 }
150
151
152
153 return $data;
154 }
155
156 /**
157 * Process before update
158 */
159 protected function processBeforeUpdate(int $id, array $data): array
160 {
161 // Sanitize name
162 if (isset($data['name'])) {
163 $data['name'] = sanitize_text_field($data['name']);
164 }
165
166 // Handle slug: preserve manually edited slug, otherwise auto-generate from name
167 $preserveSlug = isset($data['preserve_slug']) && $data['preserve_slug'] === true;
168 unset($data['preserve_slug']); // Remove flag from data array
169
170 if ($preserveSlug && isset($data['slug']) && !empty($data['slug'])) {
171 // Slug was manually edited - preserve it but ensure uniqueness
172 $data['slug'] = SlugHelper::generateUniqueFromDatabase(
173 $data['slug'],
174 'yatra_item_types',
175 'slug',
176 $id // Exclude current record when checking uniqueness
177 );
178 } elseif (!empty($data['name'])) {
179 // Auto-generate slug from name if name is provided and slug not manually edited
180 $data['slug'] = SlugHelper::generateUniqueFromDatabase(
181 $data['name'],
182 'yatra_item_types',
183 'slug',
184 $id // Exclude current record when checking uniqueness
185 );
186 } elseif (isset($data['slug'])) {
187 // If name is not provided but slug is, sanitize the slug
188 $data['slug'] = SlugHelper::generate($data['slug']);
189 }
190
191 // Sanitize description
192 if (isset($data['description'])) {
193 $data['description'] = sanitize_textarea_field($data['description']);
194 }
195
196 // Sanitize status
197 if (isset($data['status'])) {
198 $allowed_statuses = ['draft', 'publish', 'trash'];
199 $data['status'] = in_array($data['status'], $allowed_statuses, true)
200 ? $data['status']
201 : 'draft';
202 }
203
204 // Sanitize color
205 if (isset($data['color'])) {
206 $allowed_colors = ['blue', 'green', 'purple', 'orange', 'red', 'yellow', 'gray'];
207 $data['color'] = in_array($data['color'], $allowed_colors, true)
208 ? $data['color']
209 : 'blue';
210 }
211
212 // Set updated_by to current user
213 $data['updated_by'] = absint(get_current_user_id());
214
215 // Sanitize and serialize icon if it's an array
216 if (isset($data['icon'])) {
217 if (is_array($data['icon'])) {
218 // Sanitize icon array
219 $icon = [
220 'type' => isset($data['icon']['type']) && in_array($data['icon']['type'], ['icon', 'image'], true)
221 ? $data['icon']['type']
222 : 'icon',
223 'value' => isset($data['icon']['value'])
224 ? sanitize_text_field($data['icon']['value'])
225 : '',
226 ];
227 $data['icon'] = maybe_serialize($icon);
228 } elseif (is_string($data['icon'])) {
229 // If it's already a string, sanitize it
230 $data['icon'] = sanitize_text_field($data['icon']);
231 }
232 }
233
234 return $data;
235 }
236
237 /**
238 * Get all items with search and filters
239 */
240 public function getAll(array $args = []): array
241 {
242 // Sanitize and handle search
243 if (!empty($args['search'])) {
244 $search = sanitize_text_field($args['search']);
245 return $this->repository->search($search, $args);
246 }
247
248 // Sanitize and handle status filter
249 if (!empty($args['status']) && $args['status'] !== 'all') {
250 $allowed_statuses = ['draft', 'publish', 'trash'];
251 $status = in_array($args['status'], $allowed_statuses, true)
252 ? $args['status']
253 : null;
254 if ($status) {
255 $args['where']['status'] = $status;
256 }
257 }
258
259 return $this->repository->all($args);
260 }
261
262 /**
263 * Get published item types
264 */
265 public function getPublished(array $args = []): array
266 {
267 return $this->repository->getPublished($args);
268 }
269
270 /**
271 * Count items
272 */
273 public function count(array $args = []): int
274 {
275 $args['where']['type']='item_type';
276 // Sanitize and handle search
277 if (!empty($args['search'])) {
278 $search = sanitize_text_field($args['search']);
279 $items = $this->repository->search($search, $args);
280 return count($items);
281 }
282
283 // Sanitize and handle status filter
284 if (!empty($args['status']) && $args['status'] !== 'all') {
285 $allowed_statuses = ['draft', 'publish', 'trash'];
286 $status = in_array($args['status'], $allowed_statuses, true)
287 ? $args['status']
288 : null;
289 if ($status) {
290 $args['where']['status'] = $status;
291 }
292 }
293
294
295 return $this->repository->count($args);
296 }
297
298 /**
299 * Get status counts for admin list views
300 *
301 * Provides stable counts for All / Published / Draft / Trash that
302 * do not change when filters (status/search) are applied in the UI.
303 */
304 public function getStatusCounts(): array
305 {
306 // All statuses combined (no status filter)
307 $all = $this->count([]);
308
309 // Individual statuses
310 $publish = $this->count(['status' => 'publish']);
311 $draft = $this->count(['status' => 'draft']);
312 $trash = $this->count(['status' => 'trash']);
313
314 return [
315 'all' => (int) $all,
316 'publish' => (int) $publish,
317 'draft' => (int) $draft,
318 'trash' => (int) $trash,
319 ];
320 }
321 }
322
323