| @@ -253,12 +253,29 @@ | ||
| 253 | 253 | { |
| 254 | 254 | // Register activation/deactivation hooks |
| 255 | 255 | register_activation_hook(YATRA_PLUGIN_FILE, [$this, 'activate']); |
| 256 | 256 | register_deactivation_hook(YATRA_PLUGIN_FILE, [$this, 'deactivate']); |
| 257 | - | |
| 257 | + | |
| 258 | 258 | if (class_exists(\Yatra\Upgrades\FreeUpgradeRunner::class)) { |
| 259 | 259 | \Yatra\Upgrades\FreeUpgradeRunner::register(); |
| 260 | 260 | } |
| 261 | + | |
| 262 | + // On user registration, link any guest bookings made under | |
| 263 | + // the same email. Otherwise a customer who booked as guest | |
| 264 | + // first and then created an account would lose visibility of | |
| 265 | + // that earlier booking from My Account (the rows live with | |
| 266 | + // user_id=0 and the customer page filters by user_id). | |
| 267 | + if (class_exists('\\Yatra\\Services\\CustomerService')) { | |
| 268 | + add_action('user_register', static function ($user_id): void { | |
| 269 | + try { | |
| 270 | + (new \Yatra\Services\CustomerService())->linkGuestBookingsToUser((int) $user_id); | |
| 271 | + } catch (\Throwable $e) { | |
| 272 | + // Never block registration on a reconciliation | |
| 273 | + // failure. The booking remains accessible via the | |
| 274 | + // confirmation email link either way. | |
| 275 | + } | |
| 276 | + }, 20, 1); | |
| 277 | + } | |
| 261 | 278 | } |
| 262 | 279 | |
| 263 | 280 | /** |
| 264 | 281 | * Ensure database tables exist |
| @@ -331,8 +348,16 @@ | ||
| 331 | 348 | * Plugin deactivation |
| 332 | 349 | */ |
| 333 | 350 | public function deactivate(): void |
| 334 | 351 | { |
| 352 | + // Clear the booking maintenance sweeps so a deactivated plugin leaves no | |
| 353 | + // orphan events behind in WP-Cron. They are re-scheduled on `init` when | |
| 354 | + // the plugin is active again; the expiry activation floor is an option, | |
| 355 | + // so it survives and still protects pre-existing bookings. | |
| 356 | + foreach (['yatra_booking_expiry', 'yatra_booking_reminder', 'yatra_booking_completion'] as $hook) { | |
| 357 | + wp_clear_scheduled_hook($hook); | |
| 358 | + } | |
| 359 | + | |
| 335 | 360 | // Clean up if needed |
| 336 | 361 | flush_rewrite_rules(); |
| 337 | 362 | } |
| 338 | 363 | |
| @@ -353,10 +378,13 @@ | ||
| 353 | 378 | if (file_exists(WP_LANG_DIR . '/loco/plugins/yatra-' . $locale . '.mo')) { |
| 354 | 379 | load_textdomain('yatra', WP_LANG_DIR . '/loco/plugins/yatra-' . $locale . '.mo'); |
| 355 | 380 | } |
| 356 | 381 | |
| 357 | - // Load from plugin directory (fallback) | |
| 358 | - load_plugin_textdomain('yatra', false, 'i18n/languages'); | |
| 382 | + // Load from the plugin's own i18n/languages folder (fallback). The 3rd | |
| 383 | + // arg is relative to WP_PLUGIN_DIR, so it MUST include the plugin folder | |
| 384 | + // name — a bare 'i18n/languages' resolves to wp-content/plugins/i18n/ | |
| 385 | + // languages (which doesn't exist), so bundled translations never load. | |
| 386 | + load_plugin_textdomain('yatra', false, dirname(YATRA_PLUGIN_BASENAME) . '/i18n/languages'); | |
| 359 | 387 | } |
| 360 | 388 | |
| 361 | 389 | /** |
| 362 | 390 | * Get container instance |