| @@ -52,8 +52,9 @@ | ||
| 52 | 52 | // Both must precede set_default_options(): they read |
| 53 | 53 | // `thinkrank_version`, which that method creates. |
| 54 | 54 | $this->retire_sitemap_legacy_fallback(); |
| 55 | 55 | $this->seed_feed_defaults(); |
| 56 | + $this->skip_key_features_migration(); | |
| 56 | 57 | $this->set_default_options(); |
| 57 | 58 | $this->setup_indexnow_key(); |
| 58 | 59 | $this->schedule_cron_jobs(); |
| 59 | 60 | $this->restore_webroot_artifacts(); |
| @@ -160,10 +161,14 @@ | ||
| 160 | 161 | // install's dismissal is still on record. |
| 161 | 162 | delete_option(\ThinkRank\Admin\Webroot_Writable_Notice::OPT_DISMISSED); |
| 162 | 163 | |
| 163 | 164 | if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
| 165 | + // Not a fixed feature list: robots.txt, llms.txt and the Instant | |
| 166 | + // Indexing key all have a PHP path, so naming them as broken | |
| 167 | + // was untrue since #756. Webroot_Writable_Notice works out | |
| 168 | + // what, if anything, is actually affected. | |
| 164 | 169 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log |
| 165 | - error_log('ThinkRank: WordPress root directory is not writable. robots.txt, llms.txt and the Instant Indexing key file cannot be published; the sitemap falls back to dynamic delivery.'); | |
| 170 | + error_log('ThinkRank: WordPress root directory is not writable. Features on Automatic delivery are served from WordPress; any feature explicitly set to write files cannot publish them.'); | |
| 166 | 171 | } |
| 167 | 172 | } |
| 168 | 173 | } |
| 169 | 174 | |
| @@ -290,8 +295,35 @@ | ||
| 290 | 295 | [ |
| 291 | 296 | 'feed_source_link' => true, |
| 292 | 297 | 'feed_noindex' => true, |
| 293 | 298 | ] |
| 299 | + ); | |
| 300 | + } | |
| 301 | + | |
| 302 | + /** | |
| 303 | + * Mark the llms.txt Key Features migration done on a fresh install. | |
| 304 | + * | |
| 305 | + * {@see \ThinkRank\SEO\LLMs_Txt_Manager::maybe_migrate_legacy_key_features()} | |
| 306 | + * converts a value saved while commas separated features. A brand-new | |
| 307 | + * install never saved one, so anything it stores later follows the | |
| 308 | + * one-per-line rule and must not be split on its commas by a migration | |
| 309 | + * that runs after the user typed it. | |
| 310 | + * | |
| 311 | + * Same signal as {@see self::seed_feed_defaults()}: `thinkrank_version` is | |
| 312 | + * absent only on the very first activation. | |
| 313 | + * | |
| 314 | + * @since 2.10.0 | |
| 315 | + * | |
| 316 | + * @return void | |
| 317 | + */ | |
| 318 | + private function skip_key_features_migration(): void { | |
| 319 | + if (get_option('thinkrank_version') !== false) { | |
| 320 | + return; | |
| 321 | + } | |
| 322 | + | |
| 323 | + add_option( | |
| 324 | + \ThinkRank\SEO\LLMs_Txt_Manager::KEY_FEATURES_MIGRATION_OPTION, | |
| 325 | + \ThinkRank\SEO\LLMs_Txt_Manager::KEY_FEATURES_MIGRATION_VERSION | |
| 294 | 326 | ); |
| 295 | 327 | } |
| 296 | 328 | |
| 297 | 329 | /** |