PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.10.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.10.0
2.10.0 2.9.0 2.8.0 2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 All 51 releases
← All changes | includes/core/class-activator.php +57 -6 2.7.0 → 2.10.0 View file →
@@ -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();
@@ -136,15 +137,38 @@
136 137 throw new \Exception(sprintf("Required PHP extension '%s' is not loaded", esc_html($extension)));
137 138 }
138 139 }
139 140
140 - // Check if we can write to WordPress root directory (for robots.txt, llms.txt, sitemaps)
141 - if (!wp_is_writable(ABSPATH)) {
142 - // Log warning but don't block activation — some hosts restrict ABSPATH writes
143 - // and file-writing features will gracefully degrade via WP_Filesystem checks
141 + // Check if we can write to WordPress root directory (for robots.txt, llms.txt,
142 + // the Instant Indexing key file). Never blocks activation — some hosts restrict
143 + // ABSPATH writes by design.
144 + //
145 + // The result is recorded rather than only logged. It used to reach error_log()
146 + // and only under WP_DEBUG, so on a production site nobody was ever told, and the
147 + // features that need it failed later with messages describing the symptom rather
148 + // than the cause (#753). Webroot_Writable_Notice re-evaluates the condition live —
149 + // permissions change without a reactivation — and this value only distinguishes
150 + // "never worked here" from "worked until the host changed something".
151 + $writable = wp_is_writable(ABSPATH);
152 +
153 + update_option(
154 + \ThinkRank\Admin\Webroot_Writable_Notice::OPT_ACTIVATION_STATE,
155 + $writable ? 'writable' : 'not-writable',
156 + false
157 + );
158 +
159 + if (!$writable) {
160 + // A fresh activation on a broken root should warn even if a previous
161 + // install's dismissal is still on record.
162 + delete_option(\ThinkRank\Admin\Webroot_Writable_Notice::OPT_DISMISSED);
163 +
144 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.
145 169 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
146 - error_log('ThinkRank: WordPress root directory is not writable. Some features (robots.txt, llms.txt, sitemaps) may not work.');
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.');
147 171 }
148 172 }
149 173 }
150 174
@@ -275,8 +299,35 @@
275 299 );
276 300 }
277 301
278 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
326 + );
327 + }
328 +
329 + /**
279 330 * Set default plugin options
280 331 *
281 332 * @return void
282 333 */
@@ -285,9 +336,9 @@
285 336 'thinkrank_version' => THINKRANK_VERSION,
286 337
287 338 'thinkrank_ai_provider' => \ThinkRank\Core\Settings::AI_PROVIDER_NONE,
288 339 'thinkrank_cache_duration' => 3600, // 1 hour
289 - 'thinkrank_max_requests_per_minute' => 10,
340 + 'thinkrank_max_requests_per_minute' => 0,
290 341 'thinkrank_enable_logging' => true,
291 342 'thinkrank_auto_optimize' => false,
292 343 'thinkrank_seo_score_threshold' => 70,
293 344 ];