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 / Core / Modules / ModuleManager.php

ModuleManager.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.6, at app/Core/Modules/ModuleManager.php

408 lines 17.8 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\Core\Modules;
6
7 /**
8 * Module Manager
9 * Handles module definitions and persistence via wp_options
10 */
11 class ModuleManager
12 {
13 private const OPTION_KEY = 'yatra_modules';
14 private const DEFAULT_VIDEO_URL = 'https://www.youtube.com/embed/2g811Eo7K8U';
15
16 /**
17 * Ensure option exists with defaults
18 */
19 public static function initializeDefaults(): void
20 {
21 if (get_option(self::OPTION_KEY) === false) {
22 $defaults = [];
23 $timestamp = current_time('mysql');
24
25 foreach (self::getDefaultModules() as $module) {
26 $defaults[$module['slug']] = [
27 'enabled' => !empty($module['enabled']),
28 'updated_at' => $timestamp,
29 ];
30 }
31
32 add_option(self::OPTION_KEY, $defaults);
33 }
34 }
35
36 /**
37 * Get default module definitions
38 */
39 public static function getDefaultModules(): array
40 {
41 $modules = [
42 [
43 'slug' => 'google_calendar',
44 'name' => __('Google Calendar Integration', 'yatra'),
45 'description' => __('Automatically sync bookings and departures to Google Calendar. Keep travelers informed with calendar invitations. Perfect integration for managing your travel schedule.', 'yatra'),
46 'category' => __('Integrations', 'yatra'),
47 'docs_url' => 'https://docs.yatra.com/modules/google-calendar',
48 'is_premium' => true,
49 'purchase_url' => 'https://wpyatra.com/pricing?module=google-calendar',
50 'is_core' => false,
51 'enabled' => false,
52 'tags' => ['integrations', 'calendar', 'automation'],
53 'video_url' => self::DEFAULT_VIDEO_URL,
54 'requires_pro' => true,
55 'settings_page' => 'yatra-google-calendar',
56 ],
57 [
58 'slug' => 'additional_services',
59 'name' => __('Additional Services', 'yatra'),
60 'description' => __('Offer optional add-ons like airport transfers, travel insurance, and equipment rental. Increase revenue per booking with valuable extras travelers want. Enhance complete trip experience for your customers.', 'yatra'),
61 'category' => __('Sales', 'yatra'),
62 'docs_url' => 'https://docs.yatra.com/modules/additional-services',
63 'is_premium' => true,
64 'purchase_url' => 'https://wpyatra.com/pricing?module=additional-services',
65 'is_core' => false,
66 'enabled' => false,
67 'tags' => ['upsell', 'services', 'add-ons', 'extras'],
68 'video_url' => self::DEFAULT_VIDEO_URL,
69 'requires_pro' => true,
70 'settings_page' => 'yatra-additional-services',
71 ],
72 [
73 'slug' => 'trip_consent',
74 'name' => __('Trip Consent', 'yatra'),
75 'description' => __('Collect digital consent forms and signatures from travelers before their trip. Includes liability waivers and health declarations. Ensure legal compliance and protect your business.', 'yatra'),
76 'category' => __('Operations', 'yatra'),
77 'docs_url' => 'https://docs.yatra.com/modules/trip-consent',
78 'is_premium' => true,
79 'purchase_url' => 'https://wpyatra.com/pricing?module=trip-consent',
80 'is_core' => false,
81 'enabled' => false,
82 'tags' => ['consent', 'waiver', 'signature', 'forms', 'legal'],
83 'video_url' => self::DEFAULT_VIDEO_URL,
84 'requires_pro' => true,
85 'settings_page' => 'yatra-trip-consent',
86 ],
87 [
88 'slug' => 'email_automation',
89 'name' => __('Email Automation', 'yatra'),
90 'description' => __('Adds the full automation template library (database), sequences, and send logs on the Email screen. Everyone already gets Delivery settings plus the four core customer templates (booking, payment, cancellation, reminder) without this module.', 'yatra'),
91 'category' => __('Marketing', 'yatra'),
92 'docs_url' => 'https://docs.yatra.com/modules/email-automation',
93 'is_premium' => true,
94 'purchase_url' => 'https://wpyatra.com/pricing?module=email-automation',
95 'is_core' => false,
96 'enabled' => false,
97 'tags' => ['email', 'automation', 'templates', 'marketing', 'notifications'],
98 'video_url' => self::DEFAULT_VIDEO_URL,
99 'requires_pro' => true,
100 'settings_page' => 'email-automation',
101 ],
102 [
103 'slug' => 'dynamic_form_field',
104 'name' => __('Dynamic Form Field', 'yatra'),
105 'description' => __('Customize booking form fields with drag-and-drop builder. Add custom fields for traveler information and emergency contacts. Create the perfect booking experience for your customers.', 'yatra'),
106 'category' => __('Bookings', 'yatra'),
107 'docs_url' => 'https://docs.yatra.com/modules/dynamic-form-field',
108 'is_premium' => true,
109 'purchase_url' => 'https://wpyatra.com/pricing?module=dynamic-form-field',
110 'is_core' => false,
111 'enabled' => false,
112 'tags' => ['form', 'booking', 'customization', 'fields', 'builder'],
113 'video_url' => self::DEFAULT_VIDEO_URL,
114 'requires_pro' => true,
115 'settings_page' => 'yatra-settings',
116 ],
117 [
118 'slug' => 'advanced_discount',
119 'name' => __('Advanced Discount', 'yatra'),
120 'description' => __('Create group discounts that auto-apply based on traveler count. Combine promo codes with group savings for maximum flexibility and conversion optimization.', 'yatra'),
121 'category' => __('Marketing', 'yatra'),
122 'docs_url' => 'https://docs.yatra.com/modules/advanced-discount',
123 'is_premium' => true,
124 'purchase_url' => 'https://wpyatra.com/pricing?module=advanced-discount',
125 'is_core' => false,
126 'enabled' => false,
127 'tags' => ['discount', 'group', 'promo', 'coupon', 'marketing'],
128 'video_url' => self::DEFAULT_VIDEO_URL,
129 'requires_pro' => true,
130 ],
131 [
132 'slug' => 'mailchimp',
133 'name' => __('Mailchimp Integration', 'yatra'),
134 'description' => __('Automatically sync customers to Mailchimp lists when they book. Add tags based on trips booked. Build targeted email campaigns and nurture leads effectively.', 'yatra'),
135 'category' => __('Marketing', 'yatra'),
136 'docs_url' => 'https://docs.yatra.com/modules/mailchimp',
137 'is_premium' => true,
138 'purchase_url' => 'https://wpyatra.com/pricing?module=mailchimp',
139 'is_core' => false,
140 'enabled' => false,
141 'tags' => ['email', 'marketing', 'mailchimp', 'automation', 'integration'],
142 'video_url' => self::DEFAULT_VIDEO_URL,
143 'requires_pro' => true,
144 'settings_page' => 'yatra-mailchimp',
145 ],
146 [
147 'slug' => 'facebook_pixel',
148 'name' => __('Facebook Pixel', 'yatra'),
149 'description' => __('Track booking conversions with Facebook Pixel. Retarget visitors who viewed trips. Optimize ad campaigns with accurate conversion data and build lookalike audiences.', 'yatra'),
150 'category' => __('Marketing', 'yatra'),
151 'docs_url' => 'https://docs.yatra.com/modules/facebook-pixel',
152 'is_premium' => true,
153 'purchase_url' => 'https://wpyatra.com/pricing?module=facebook-pixel',
154 'is_core' => false,
155 'enabled' => false,
156 'tags' => ['facebook', 'pixel', 'tracking', 'ads', 'retargeting', 'marketing'],
157 'video_url' => self::DEFAULT_VIDEO_URL,
158 'requires_pro' => true,
159 'settings_page' => 'yatra-facebook-pixel',
160 ],
161 [
162 'slug' => 'google_analytics',
163 'name' => __('Google Analytics 4 Enhanced', 'yatra'),
164 'description' => __('Enhanced e-commerce tracking for GA4. Track view_item, begin_checkout, and purchase events. Server-side tracking via Measurement Protocol for accurate conversion data.', 'yatra'),
165 'category' => __('Marketing', 'yatra'),
166 'docs_url' => 'https://docs.yatra.com/modules/google-analytics',
167 'is_premium' => true,
168 'purchase_url' => 'https://wpyatra.com/pricing?module=google-analytics',
169 'is_core' => false,
170 'enabled' => false,
171 'tags' => ['google', 'analytics', 'ga4', 'tracking', 'ecommerce', 'marketing'],
172 'video_url' => self::DEFAULT_VIDEO_URL,
173 'requires_pro' => true,
174 'settings_page' => 'yatra-google-analytics',
175 ],
176 [
177 'slug' => 'flexible_payments',
178 'name' => __('Flexible Payments', 'yatra'),
179 'description' => __('Enable deposit and partial payment options for bookings. Allow customers to pay a percentage upfront and the rest later. Perfect for high-value trips and improving conversion rates.', 'yatra'),
180 'category' => __('Payments', 'yatra'),
181 'docs_url' => 'https://docs.yatra.com/modules/flexible-payments',
182 'is_premium' => true,
183 'purchase_url' => 'https://wpyatra.com/pricing?module=flexible-payments',
184 'is_core' => false,
185 'enabled' => false,
186 'tags' => ['payments', 'deposit', 'partial', 'installments', 'booking'],
187 'video_url' => self::DEFAULT_VIDEO_URL,
188 'requires_pro' => true,
189 'settings_page' => 'yatra-settings',
190 ],
191 [
192 'slug' => 'dynamic_pricing',
193 'name' => __('Dynamic Pricing', 'yatra'),
194 'description' => __('Automatically adjust trip prices based on demand, seasonality, early bird discounts, and last-minute deals. Maximize revenue with intelligent pricing rules that respond to booking patterns.', 'yatra'),
195 'category' => __('Sales', 'yatra'),
196 'docs_url' => 'https://docs.yatra.com/modules/dynamic-pricing',
197 'is_premium' => true,
198 'purchase_url' => 'https://wpyatra.com/pricing?module=dynamic-pricing',
199 'is_core' => false,
200 'enabled' => false,
201 'tags' => ['pricing', 'revenue', 'automation', 'discounts', 'sales'],
202 'video_url' => self::DEFAULT_VIDEO_URL,
203 'requires_pro' => true,
204 'settings_page' => 'dynamic-pricing',
205 ],
206 [
207 'slug' => 'abandoned_booking_recovery',
208 'name' => __('Abandoned Booking Recovery', 'yatra'),
209 'description' => __('Recover lost sales by automatically tracking abandoned bookings and sending targeted email sequences. Win back customers who left before completing their purchase.', 'yatra'),
210 'category' => __('Marketing', 'yatra'),
211 'docs_url' => 'https://docs.yatra.com/modules/abandoned-booking-recovery',
212 'is_premium' => true,
213 'purchase_url' => 'https://wpyatra.com/pricing?module=abandoned-booking-recovery',
214 'is_core' => false,
215 'enabled' => false,
216 'tags' => ['recovery', 'email', 'automation', 'marketing', 'conversion'],
217 'video_url' => self::DEFAULT_VIDEO_URL,
218 'requires_pro' => true,
219 'settings_page' => 'abandoned-recovery',
220 ],
221 ];
222
223 return apply_filters('yatra_default_modules', $modules);
224 }
225
226 /**
227 * Get modules merged with stored option state
228 */
229 public static function getModules(): array
230 {
231 // Get enable/disable status ONLY from database
232 $stored_status = get_option(self::OPTION_KEY, []);
233 $stored_status = is_array($stored_status) ? $stored_status : [];
234
235 // Get module definitions ONLY from hardcoded array
236 $modules = self::getDefaultModules();
237
238 $result = [];
239 foreach ($modules as $module) {
240 $slug = $module['slug'];
241
242 // Get enable/disable status from database only
243 $enabled = isset($stored_status[$slug]['enabled'])
244 ? (bool) $stored_status[$slug]['enabled']
245 : (bool) ($module['enabled'] ?? false);
246
247 // Check if module is available (can be enabled)
248 $is_available = true;
249 if (!empty($module['requires_pro'])) {
250 $pro_active = apply_filters('yatra_is_pro_active', false);
251 if ($pro_active) {
252 // Check if this module is available in Pro
253 $available_modules = apply_filters('yatra_pro_available_modules', []);
254 $is_available = in_array($slug, $available_modules, true);
255 } else {
256 $is_available = false;
257 }
258 }
259
260 $result[] = array_merge($module, [
261 'enabled' => $enabled,
262 'updated_at' => $stored_status[$slug]['updated_at'] ?? null,
263 'is_available' => $is_available,
264 ]);
265 }
266
267 return $result;
268 }
269
270 /**
271 * Check if module is enabled
272 */
273 public static function isModuleEnabled(string $slug): bool
274 {
275 // Allow direct override for specific modules
276 $override = apply_filters('yatra_module_enabled_status', null, $slug);
277 if ($override !== null) {
278 return (bool) $override;
279 }
280
281 $modules = self::getModules();
282 foreach ($modules as $module) {
283 if ($module['slug'] === $slug) {
284 // Check if module requires Pro and if Pro is active
285 if (!empty($module['requires_pro'])) {
286 $pro_active = apply_filters('yatra_is_pro_active', false);
287 if (!$pro_active) {
288 return false;
289 }
290 }
291
292 return (bool) $module['enabled'];
293 }
294 }
295
296 return false;
297 }
298
299 /**
300 * Check if module is available (can be enabled)
301 */
302 public static function isModuleAvailable(string $slug): bool
303 {
304 // Allow direct override for specific modules
305 $override = apply_filters('yatra_module_is_available_' . $slug, null);
306 if ($override !== null) {
307 return (bool) $override;
308 }
309
310 $modules = self::getModules();
311 foreach ($modules as $module) {
312 if ($module['slug'] === $slug) {
313 // If module requires Pro, check if Pro is active
314 if (!empty($module['requires_pro'])) {
315 // Check if Pro is active
316 $pro_active = apply_filters('yatra_is_pro_active', false);
317 if (!$pro_active) {
318 return false;
319 }
320
321 // Check if this module is available in Pro
322 $available_modules = apply_filters('yatra_pro_available_modules', []);
323 return in_array($slug, $available_modules, true);
324 }
325
326 return true;
327 }
328 }
329
330 return false;
331 }
332
333 /**
334 * Update module enabled state
335 */
336 public static function setModuleStatus(string $slug, bool $enabled): array
337 {
338 $modules = get_option(self::OPTION_KEY, []);
339 $modules = is_array($modules) ? $modules : [];
340
341 $modules[$slug] = array_merge($modules[$slug] ?? [], [
342 'enabled' => $enabled,
343 'updated_at' => current_time('mysql'),
344 ]);
345
346 update_option(self::OPTION_KEY, $modules);
347
348 // Trigger module activation/deactivation hook
349 if ($enabled) {
350 do_action('yatra_module_active', $slug);
351 } else {
352 do_action('yatra_module_deactive', $slug);
353 }
354
355 return self::getModules();
356 }
357
358 /**
359 * Update multiple modules at once
360 *
361 * @param array<array{slug:string, enabled:bool}> $items
362 */
363 public static function setMultipleStatuses(array $items): array
364 {
365 if (empty($items)) {
366 return self::getModules();
367 }
368
369 $modules = get_option(self::OPTION_KEY, []);
370 $modules = is_array($modules) ? $modules : [];
371 $timestamp = current_time('mysql');
372
373 foreach ($items as $item) {
374 if (empty($item['slug'])) {
375 continue;
376 }
377
378 $slug = sanitize_key($item['slug']);
379 $enabled = (bool) ($item['enabled'] ?? false);
380
381 $modules[$slug] = array_merge($modules[$slug] ?? [], [
382 'enabled' => $enabled,
383 'updated_at' => $timestamp,
384 ]);
385 }
386
387 update_option(self::OPTION_KEY, $modules);
388
389 // Trigger module activation/deactivation hooks for bulk updates
390 foreach ($items as $item) {
391 if (empty($item['slug'])) {
392 continue;
393 }
394
395 $slug = sanitize_key($item['slug']);
396 $enabled = (bool) ($item['enabled'] ?? false);
397
398 if ($enabled) {
399 do_action('yatra_module_active', $slug);
400 } else {
401 do_action('yatra_module_deactive', $slug);
402 }
403 }
404
405 return self::getModules();
406 }
407 }
408