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 / Services / ItemTypeService.php

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

307 lines 9.9 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 $data['icon'] = yatra_normalize_icon_picker_for_storage($data['icon']);
136 $data['icon'] = maybe_serialize($data['icon']);
137 } elseif (is_string($data['icon'])) {
138 // If it's already a string, sanitize it
139 $data['icon'] = sanitize_text_field($data['icon']);
140 }
141 }
142
143
144
145 return $data;
146 }
147
148 /**
149 * Process before update
150 */
151 protected function processBeforeUpdate(int $id, array $data): array
152 {
153 // Sanitize name
154 if (isset($data['name'])) {
155 $data['name'] = sanitize_text_field($data['name']);
156 }
157
158 // Handle slug: preserve manually edited slug, otherwise auto-generate from name
159 $preserveSlug = isset($data['preserve_slug']) && $data['preserve_slug'] === true;
160 unset($data['preserve_slug']); // Remove flag from data array
161
162 if ($preserveSlug && isset($data['slug']) && !empty($data['slug'])) {
163 // Slug was manually edited - preserve it but ensure uniqueness
164 $data['slug'] = SlugHelper::generateUniqueFromDatabase(
165 $data['slug'],
166 'yatra_item_types',
167 'slug',
168 $id // Exclude current record when checking uniqueness
169 );
170 } elseif (!empty($data['name'])) {
171 // Auto-generate slug from name if name is provided and slug not manually edited
172 $data['slug'] = SlugHelper::generateUniqueFromDatabase(
173 $data['name'],
174 'yatra_item_types',
175 'slug',
176 $id // Exclude current record when checking uniqueness
177 );
178 } elseif (isset($data['slug'])) {
179 // If name is not provided but slug is, sanitize the slug
180 $data['slug'] = SlugHelper::generate($data['slug']);
181 }
182
183 // Sanitize description
184 if (isset($data['description'])) {
185 $data['description'] = sanitize_textarea_field($data['description']);
186 }
187
188 // Sanitize status
189 if (isset($data['status'])) {
190 $allowed_statuses = ['draft', 'publish', 'trash'];
191 $data['status'] = in_array($data['status'], $allowed_statuses, true)
192 ? $data['status']
193 : 'draft';
194 }
195
196 // Sanitize color
197 if (isset($data['color'])) {
198 $allowed_colors = ['blue', 'green', 'purple', 'orange', 'red', 'yellow', 'gray'];
199 $data['color'] = in_array($data['color'], $allowed_colors, true)
200 ? $data['color']
201 : 'blue';
202 }
203
204 // Set updated_by to current user
205 $data['updated_by'] = absint(get_current_user_id());
206
207 // Sanitize and serialize icon if it's an array
208 if (isset($data['icon'])) {
209 if (is_array($data['icon'])) {
210 $data['icon'] = yatra_normalize_icon_picker_for_storage($data['icon']);
211 $data['icon'] = maybe_serialize($data['icon']);
212 } elseif (is_string($data['icon'])) {
213 // If it's already a string, sanitize it
214 $data['icon'] = sanitize_text_field($data['icon']);
215 }
216 }
217
218 return $data;
219 }
220
221 /**
222 * Get all items with search and filters
223 */
224 public function getAll(array $args = []): array
225 {
226 // Sanitize and handle search
227 if (!empty($args['search'])) {
228 $search = sanitize_text_field($args['search']);
229 return $this->repository->search($search, $args);
230 }
231
232 // Sanitize and handle status filter
233 if (!empty($args['status']) && $args['status'] !== 'all') {
234 $allowed_statuses = ['draft', 'publish', 'trash'];
235 $status = in_array($args['status'], $allowed_statuses, true)
236 ? $args['status']
237 : null;
238 if ($status) {
239 $args['where']['status'] = $status;
240 }
241 }
242
243 return $this->repository->all($args);
244 }
245
246 /**
247 * Get published item types
248 */
249 public function getPublished(array $args = []): array
250 {
251 return $this->repository->getPublished($args);
252 }
253
254 /**
255 * Count items
256 */
257 public function count(array $args = []): int
258 {
259 $args['where']['type']='item_type';
260 // Sanitize and handle search
261 if (!empty($args['search'])) {
262 $search = sanitize_text_field($args['search']);
263 $items = $this->repository->search($search, $args);
264 return count($items);
265 }
266
267 // Sanitize and handle status filter
268 if (!empty($args['status']) && $args['status'] !== 'all') {
269 $allowed_statuses = ['draft', 'publish', 'trash'];
270 $status = in_array($args['status'], $allowed_statuses, true)
271 ? $args['status']
272 : null;
273 if ($status) {
274 $args['where']['status'] = $status;
275 }
276 }
277
278
279 return $this->repository->count($args);
280 }
281
282 /**
283 * Get status counts for admin list views
284 *
285 * Provides stable counts for All / Published / Draft / Trash that
286 * do not change when filters (status/search) are applied in the UI.
287 */
288 public function getStatusCounts(): array
289 {
290 // All statuses combined (no status filter)
291 $all = $this->count([]);
292
293 // Individual statuses
294 $publish = $this->count(['status' => 'publish']);
295 $draft = $this->count(['status' => 'draft']);
296 $trash = $this->count(['status' => 'trash']);
297
298 return [
299 'all' => (int) $all,
300 'publish' => (int) $publish,
301 'draft' => (int) $draft,
302 'trash' => (int) $trash,
303 ];
304 }
305 }
306
307