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

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

362 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\Utils\Cache;
8 use Yatra\Utils\Logger;
9
10 /**
11 * Cache Service
12 *
13 * High-level caching operations for business entities
14 */
15 class CacheService
16 {
17 /**
18 * Cache trip with relationships
19 */
20 public static function cacheTrip(int $tripId, \stdClass $tripData): void
21 {
22 Cache::set(
23 Cache::PREFIX_TRIP_DATA . $tripId,
24 $tripData,
25 Cache::DURATION_TRIP_DATA
26 );
27
28 Logger::debug("Trip cached", ['trip_id' => $tripId]);
29 }
30
31 /**
32 * Get cached trip
33 */
34 public static function getCachedTrip(int $tripId): ?\stdClass
35 {
36 return Cache::get(Cache::PREFIX_TRIP_DATA . $tripId);
37 }
38
39 /**
40 * Cache booking data
41 */
42 public static function cacheBooking(int $bookingId, \stdClass $bookingData): void
43 {
44 Cache::set(
45 Cache::PREFIX_BOOKING_DATA . $bookingId,
46 $bookingData,
47 Cache::DURATION_BOOKING_DATA
48 );
49
50 Logger::debug("Booking cached", ['booking_id' => $bookingId]);
51 }
52
53 /**
54 * Get cached booking
55 */
56 public static function getCachedBooking(int $bookingId): ?\stdClass
57 {
58 return Cache::get(Cache::PREFIX_BOOKING_DATA . $bookingId);
59 }
60
61 /**
62 * Cache customer data
63 */
64 public static function cacheCustomer(int $customerId, \stdClass $customerData): void
65 {
66 Cache::set(
67 Cache::PREFIX_CUSTOMER_DATA . $customerId,
68 $customerData,
69 Cache::DURATION_CUSTOMER_DATA
70 );
71
72 Logger::debug("Customer cached", ['customer_id' => $customerId]);
73 }
74
75 /**
76 * Get cached customer
77 */
78 public static function getCachedCustomer(int $customerId): ?\stdClass
79 {
80 return Cache::get(Cache::PREFIX_CUSTOMER_DATA . $customerId);
81 }
82
83 /**
84 * Cache activity data
85 */
86 public static function cacheActivity(int $activityId, \stdClass $activityData): void
87 {
88 Cache::set(
89 Cache::PREFIX_ACTIVITY_DATA . $activityId,
90 $activityData,
91 Cache::DURATION_ACTIVITY_DATA
92 );
93
94 Logger::debug("Activity cached", ['activity_id' => $activityId]);
95 }
96
97 /**
98 * Get cached activity
99 */
100 public static function getCachedActivity(int $activityId): ?\stdClass
101 {
102 return Cache::get(Cache::PREFIX_ACTIVITY_DATA . $activityId);
103 }
104
105 /**
106 * Cache destination data
107 */
108 public static function cacheDestination(int $destinationId, \stdClass $destinationData): void
109 {
110 Cache::set(
111 Cache::PREFIX_DESTINATION_DATA . $destinationId,
112 $destinationData,
113 Cache::DURATION_DESTINATION_DATA
114 );
115
116 Logger::debug("Destination cached", ['destination_id' => $destinationId]);
117 }
118
119 /**
120 * Get cached destination
121 */
122 public static function getCachedDestination(int $destinationId): ?\stdClass
123 {
124 return Cache::get(Cache::PREFIX_DESTINATION_DATA . $destinationId);
125 }
126
127 /**
128 * Clear a single trip and listing/query caches (e.g. after attribute changes via {@see TripService}).
129 */
130 public static function clearTripCache(int $tripId): void
131 {
132 if ($tripId <= 0) {
133 return;
134 }
135 Cache::invalidateAfterTripWrite('update', $tripId);
136 }
137
138 /**
139 * Invalidate entity cache when data changes
140 */
141 public static function invalidateEntity(string $entityType, int $entityId): void
142 {
143 // Handle both entity types and service class names
144 $normalizedType = self::normalizeEntityType($entityType);
145
146 switch ($normalizedType) {
147 case 'trip':
148 $prefix = Cache::PREFIX_TRIP_DATA;
149 break;
150 case 'booking':
151 $prefix = Cache::PREFIX_BOOKING_DATA;
152 break;
153 case 'customer':
154 $prefix = Cache::PREFIX_CUSTOMER_DATA;
155 break;
156 case 'activity':
157 $prefix = Cache::PREFIX_ACTIVITY_DATA;
158 break;
159 case 'destination':
160 $prefix = Cache::PREFIX_DESTINATION_DATA;
161 break;
162 case 'difficulty':
163 $prefix = Cache::PREFIX_QUERY_RESULT; // For difficulty levels, use query cache
164 break;
165 default:
166 $prefix = null;
167 break;
168 }
169
170 if ($prefix) {
171 if ($normalizedType === 'difficulty') {
172 // For difficulty and other non-entity types, clear by prefix
173 Cache::clearByPrefix($prefix);
174 } else {
175 // For entities, clear specific entity cache
176 Cache::delete($prefix . $entityId);
177 }
178
179 // Also clear related query caches
180 Cache::clearByPrefix(Cache::PREFIX_QUERY_RESULT);
181 Cache::clearByPrefix(Cache::PREFIX_STATS);
182
183 Logger::info("Entity cache invalidated", [
184 'entity_type' => $entityType,
185 'normalized_type' => $normalizedType,
186 'entity_id' => $entityId
187 ]);
188 } else {
189 // If no specific prefix found, just clear query caches
190 Cache::clearByPrefix(Cache::PREFIX_QUERY_RESULT);
191 Cache::clearByPrefix(Cache::PREFIX_STATS);
192
193 Logger::debug("Generic cache invalidation", [
194 'entity_type' => $entityType,
195 'entity_id' => $entityId
196 ]);
197 }
198 }
199
200 /**
201 * Normalize entity type from service class names
202 */
203 private static function normalizeEntityType(string $entityType): string
204 {
205 // Convert service class names to entity types
206 $entityType = strtolower($entityType);
207
208 // Handle service class patterns
209 if (str_contains($entityType, 'trip')) {
210 return 'trip';
211 }
212 if (str_contains($entityType, 'booking')) {
213 return 'booking';
214 }
215 if (str_contains($entityType, 'customer')) {
216 return 'customer';
217 }
218 if (str_contains($entityType, 'activity')) {
219 return 'activity';
220 }
221 if (str_contains($entityType, 'destination')) {
222 return 'destination';
223 }
224 if (str_contains($entityType, 'difficulty')) {
225 return 'difficulty';
226 }
227
228 // Return as-is if no pattern matches
229 return $entityType;
230 }
231
232 /**
233 * Warm up cache for frequently accessed entities
234 */
235 public static function warmUpCache(): void
236 {
237 Logger::info("Starting cache warm-up");
238
239 // Warm up popular trips
240 $tripRepository = new \Yatra\Repositories\TripRepository();
241 $popularTrips = $tripRepository->getPopularTrips(20);
242
243 foreach ($popularTrips as $trip) {
244 // This would trigger cache population when the trip is next accessed
245 Logger::debug("Marked trip for cache warm-up", ['trip_id' => $trip->id]);
246 }
247
248 // Warm up recent bookings
249 $bookingRepository = new \Yatra\Repositories\BookingRepository();
250 $recentBookings = $bookingRepository->getRecentBookings(7, 50);
251
252 foreach ($recentBookings as $booking) {
253 Logger::debug("Marked booking for cache warm-up", ['booking_id' => $booking->id]);
254 }
255
256 Logger::info("Cache warm-up completed", [
257 'trips_marked' => count($popularTrips),
258 'bookings_marked' => count($recentBookings)
259 ]);
260 }
261
262 /**
263 * Get cache performance metrics
264 */
265 public static function getPerformanceMetrics(): array
266 {
267 return [
268 'cache_stats' => Cache::getCacheStats(),
269 'memory_usage' => [
270 'current' => memory_get_usage(true),
271 'peak' => memory_get_peak_usage(true),
272 'formatted_current' => self::formatBytes(memory_get_usage(true)),
273 'formatted_peak' => self::formatBytes(memory_get_peak_usage(true)),
274 ],
275 'cache_backends' => Cache::getAvailableBackends(),
276 ];
277 }
278
279 /**
280 * Format bytes for human reading
281 */
282 private static function formatBytes(int $bytes): string
283 {
284 $units = ['B', 'KB', 'MB', 'GB'];
285 $bytes = max($bytes, 0);
286 $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
287 $pow = min($pow, count($units) - 1);
288
289 $bytes /= (1 << (10 * $pow));
290
291 return round($bytes, 2) . ' ' . $units[$pow];
292 }
293
294 /**
295 * Remember pattern - get from cache or execute callback and cache result
296 *
297 * @return mixed
298 */
299 public static function remember(string $key, callable $callback, ?int $duration = null)
300 {
301 // Try to get from cache first
302 $cached = Cache::get($key);
303 if ($cached !== null) {
304 Logger::debug("Cache hit", ['key' => $key]);
305 return $cached;
306 }
307
308 // Execute callback to get fresh data
309 $startTime = microtime(true);
310 $result = $callback();
311 $executionTime = microtime(true) - $startTime;
312
313 // Cache the result if it's not null
314 if ($result !== null) {
315 $cacheDuration = $duration ?? Cache::DURATION_QUERY_RESULT;
316 Cache::set($key, $result, $cacheDuration);
317
318 Logger::debug("Cache miss - data cached", [
319 'key' => $key,
320 'execution_time' => round($executionTime * 1000, 2) . 'ms',
321 'duration' => $cacheDuration
322 ]);
323 } else {
324 Logger::debug("Cache miss - null result not cached", [
325 'key' => $key,
326 'execution_time' => round($executionTime * 1000, 2) . 'ms'
327 ]);
328 }
329
330 return $result;
331 }
332
333 /**
334 * Clear cache by prefix - delegates to Cache utility
335 */
336 public static function clearByPrefix(string $prefix): void
337 {
338 Cache::clearByPrefix($prefix);
339 Logger::debug("Cache cleared by prefix", ['prefix' => $prefix]);
340 }
341
342 /**
343 * Clear all entity caches
344 */
345 public static function clearAllEntityCaches(): void
346 {
347 $prefixes = [
348 Cache::PREFIX_TRIP_DATA,
349 Cache::PREFIX_BOOKING_DATA,
350 Cache::PREFIX_CUSTOMER_DATA,
351 Cache::PREFIX_ACTIVITY_DATA,
352 Cache::PREFIX_DESTINATION_DATA,
353 ];
354
355 foreach ($prefixes as $prefix) {
356 Cache::clearByPrefix($prefix);
357 }
358
359 Logger::info("All entity caches cleared");
360 }
361 }
362