| @@ -4,9 +4,8 @@ | ||
| 4 | 4 | |
| 5 | 5 | namespace Yatra; |
| 6 | 6 | |
| 7 | 7 | use Yatra\Core\Container; |
| 8 | -use Yatra\Core\Database; | |
| 9 | 8 | use Yatra\Providers\AppServiceProvider; |
| 10 | 9 | use Yatra\Providers\RouteServiceProvider; |
| 11 | 10 | use Yatra\Providers\AdminServiceProvider; |
| 12 | 11 | use Yatra\Providers\FrontendAssetsProvider; |
| @@ -109,10 +108,16 @@ | ||
| 109 | 108 | |
| 110 | 109 | // Set up WordPress hooks |
| 111 | 110 | $this->setupWordPressHooks(); |
| 112 | 111 | |
| 113 | - // Load text domain | |
| 114 | - $this->loadTextDomain(); | |
| 112 | + // Load text domain on `init` — calling load_(plugin_)textdomain before `init` | |
| 113 | + // triggers WP 6.7+ _doing_it_wrong notices (and Loco's "premature text domain" | |
| 114 | + // warning). Use priority 1 so it runs before code that translates on `init`. | |
| 115 | + if (did_action('init')) { | |
| 116 | + $this->loadTextDomain(); | |
| 117 | + } else { | |
| 118 | + add_action('init', [$this, 'loadTextDomain'], 1); | |
| 119 | + } | |
| 115 | 120 | |
| 116 | 121 | } catch (\Throwable $e) { |
| 117 | 122 | // Show admin notice if in admin area |
| 118 | 123 | if (is_admin()) { |
| @@ -248,11 +253,29 @@ | ||
| 248 | 253 | { |
| 249 | 254 | // Register activation/deactivation hooks |
| 250 | 255 | register_activation_hook(YATRA_PLUGIN_FILE, [$this, 'activate']); |
| 251 | 256 | register_deactivation_hook(YATRA_PLUGIN_FILE, [$this, 'deactivate']); |
| 252 | - | |
| 253 | - // Check for plugin upgrades | |
| 254 | - add_action('admin_init', [$this, 'upgrade']); | |
| 257 | + | |
| 258 | + if (class_exists(\Yatra\Upgrades\FreeUpgradeRunner::class)) { | |
| 259 | + \Yatra\Upgrades\FreeUpgradeRunner::register(); | |
| 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 | + } | |
| 255 | 278 | } |
| 256 | 279 | |
| 257 | 280 | /** |
| 258 | 281 | * Ensure database tables exist |
| @@ -321,28 +344,20 @@ | ||
| 321 | 344 | flush_rewrite_rules(); |
| 322 | 345 | } |
| 323 | 346 | |
| 324 | 347 | /** |
| 325 | - * Plugin upgrade logic | |
| 348 | + * Plugin deactivation | |
| 326 | 349 | */ |
| 327 | - public function upgrade(): void | |
| 350 | + public function deactivate(): void | |
| 328 | 351 | { |
| 329 | - $current_version = get_option('yatra_version', '1.0.0'); | |
| 330 | - | |
| 331 | - if (version_compare($current_version, YATRA_VERSION, '<')) { | |
| 332 | - Database::createTables(); | |
| 333 | - update_option('yatra_version', YATRA_VERSION); | |
| 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); | |
| 334 | 358 | } |
| 335 | 359 | |
| 336 | - \Yatra\Services\InstallerService::maybeBackfillEmailTemplateDefaults(); | |
| 337 | - \Yatra\Services\InstallerService::maybeNormalizeMigratedCouponDiscountStatuses(); | |
| 338 | - } | |
| 339 | - | |
| 340 | - /** | |
| 341 | - * Plugin deactivation | |
| 342 | - */ | |
| 343 | - public function deactivate(): void | |
| 344 | - { | |
| 345 | 360 | // Clean up if needed |
| 346 | 361 | flush_rewrite_rules(); |
| 347 | 362 | } |
| 348 | 363 | |
| @@ -363,10 +378,13 @@ | ||
| 363 | 378 | if (file_exists(WP_LANG_DIR . '/loco/plugins/yatra-' . $locale . '.mo')) { |
| 364 | 379 | load_textdomain('yatra', WP_LANG_DIR . '/loco/plugins/yatra-' . $locale . '.mo'); |
| 365 | 380 | } |
| 366 | 381 | |
| 367 | - // Load from plugin directory (fallback) | |
| 368 | - 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'); | |
| 369 | 387 | } |
| 370 | 388 | |
| 371 | 389 | /** |
| 372 | 390 | * Get container instance |