| @@ -334,8 +334,20 @@ | ||
| 334 | 334 | * @var string |
| 335 | 335 | */ |
| 336 | 336 | public const ROBOTS_RESYNC_OPTION = 'thinkrank_robots_txt_resync_pending'; |
| 337 | 337 | |
| 338 | + /** | |
| 339 | + * Flag set when a plugin change may have altered the sitemap index. | |
| 340 | + * | |
| 341 | + * Separate from ROBOTS_RESYNC_OPTION because the two files exist | |
| 342 | + * independently: that flag is only set when a physical robots.txt exists, | |
| 343 | + * and the sitemap index needs rebuilding whether or not it does. | |
| 344 | + * | |
| 345 | + * @since 2.15.0 | |
| 346 | + * @var string | |
| 347 | + */ | |
| 348 | + public const SITEMAP_RESYNC_OPTION = 'thinkrank_sitemap_contributors_changed'; | |
| 349 | + | |
| 338 | 350 | public function __construct() { |
| 339 | 351 | parent::__construct('site_identity'); |
| 340 | 352 | |
| 341 | 353 | if (!self::$icon_sizes_listener_registered) { |
| @@ -357,8 +369,17 @@ | ||
| 357 | 369 | // HTML to anything that followed it. |
| 358 | 370 | add_action('activated_plugin', [self::class, 'flag_robots_txt_resync']); |
| 359 | 371 | add_action('deactivated_plugin', [self::class, 'flag_robots_txt_resync']); |
| 360 | 372 | add_action('init', [self::class, 'maybe_resync_robots_txt'], 99); |
| 373 | + | |
| 374 | + // The sitemap index is a second static file listing the same | |
| 375 | + // contributors, with its own rebuild path. #835 / #859 resynced | |
| 376 | + // robots.txt only, so after Pro was deactivated the index kept | |
| 377 | + // advertising news-sitemap.xml, which then served the home page | |
| 378 | + // as HTML (#920). | |
| 379 | + add_action('activated_plugin', [self::class, 'flag_sitemap_resync']); | |
| 380 | + add_action('deactivated_plugin', [self::class, 'flag_sitemap_resync']); | |
| 381 | + add_action('init', [self::class, 'maybe_resync_sitemap'], 99); | |
| 361 | 382 | } |
| 362 | 383 | } |
| 363 | 384 | |
| 364 | 385 | /** |
| @@ -405,8 +426,57 @@ | ||
| 405 | 426 | return; |
| 406 | 427 | } |
| 407 | 428 | |
| 408 | 429 | (new self())->sync_robots_txt_file(); |
| 430 | + } | |
| 431 | + | |
| 432 | + /** | |
| 433 | + * Note that the set of sitemap contributors may have changed. | |
| 434 | + * | |
| 435 | + * Unconditional, unlike flag_robots_txt_resync(): the sitemap files exist | |
| 436 | + * whether or not robots.txt does. The rebuild waits for the next request | |
| 437 | + * for the same reason as the robots.txt one, since `deactivated_plugin` | |
| 438 | + * still runs with the outgoing plugin's `thinkrank_additional_sitemaps` | |
| 439 | + * callback attached. | |
| 440 | + * | |
| 441 | + * @since 2.15.0 | |
| 442 | + * @return void | |
| 443 | + */ | |
| 444 | + public static function flag_sitemap_resync(): void { | |
| 445 | + update_option(self::SITEMAP_RESYNC_OPTION, 1, false); | |
| 446 | + } | |
| 447 | + | |
| 448 | + /** | |
| 449 | + * Queue a sitemap rebuild once, on the request after a contributor change. | |
| 450 | + * | |
| 451 | + * Goes through schedule_regeneration(), the debounced and lock-protected | |
| 452 | + * path a sitemap settings save uses, so a burst of plugin changes (a bulk | |
| 453 | + * deactivate, say) still produces one rebuild. That path also drops the | |
| 454 | + * cached dynamic documents, so sites serving the sitemap from PHP drop the | |
| 455 | + * entry as well. | |
| 456 | + * | |
| 457 | + * @since 2.15.0 | |
| 458 | + * @return void | |
| 459 | + */ | |
| 460 | + public static function maybe_resync_sitemap(): void { | |
| 461 | + if (!get_option(self::SITEMAP_RESYNC_OPTION)) { | |
| 462 | + return; | |
| 463 | + } | |
| 464 | + | |
| 465 | + // Cleared first, so a rebuild that fatals cannot be retried on every | |
| 466 | + // request for the rest of the site's life. | |
| 467 | + delete_option(self::SITEMAP_RESYNC_OPTION); | |
| 468 | + | |
| 469 | + $generator = new Sitemap_Generator(false); | |
| 470 | + $settings = $generator->get_settings('site'); | |
| 471 | + | |
| 472 | + // A disabled sitemap has no files to correct. Enabling it later builds | |
| 473 | + // from the contributors present at that time. | |
| 474 | + if (empty($settings['enabled'])) { | |
| 475 | + return; | |
| 476 | + } | |
| 477 | + | |
| 478 | + $generator->schedule_regeneration(); | |
| 409 | 479 | } |
| 410 | 480 | |
| 411 | 481 | /** |
| 412 | 482 | * Save settings, then refresh what a new canonical scheme invalidates. |