| @@ -3,9 +3,9 @@ | ||
| 3 | 3 | /** |
| 4 | 4 | * Plugin Name: ThinkRank |
| 5 | 5 | * Plugin URI: https://thinkrank.ai/ |
| 6 | 6 | * Description: AI-native SEO plugin for WordPress. Automate and enhance your SEO with cutting-edge AI while maintaining editorial control. |
| 7 | - * Version: 2.9.0 | |
| 7 | + * Version: 2.10.0 | |
| 8 | 8 | * Author: WPDeveloper |
| 9 | 9 | * Author URI: https://wpdeveloper.com/ |
| 10 | 10 | * License: GPL v2 or later |
| 11 | 11 | * License URI: https://www.gnu.org/licenses/gpl-2.0.html |
| @@ -14,9 +14,9 @@ | ||
| 14 | 14 | * Requires at least: 6.0 |
| 15 | 15 | * Requires PHP: 7.4 |
| 16 | 16 | * |
| 17 | 17 | * @package ThinkRank |
| 18 | - * @version 2.9.0 | |
| 18 | + * @version 2.10.0 | |
| 19 | 19 | * @since 1.0.0 |
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | 22 | declare(strict_types=1); |
| @@ -26,9 +26,9 @@ | ||
| 26 | 26 | exit; |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | 29 | // Define plugin constants |
| 30 | -define('THINKRANK_VERSION', '2.9.0'); | |
| 30 | +define('THINKRANK_VERSION', '2.10.0'); | |
| 31 | 31 | define('THINKRANK_PLUGIN_FILE', __FILE__); |
| 32 | 32 | define('THINKRANK_PLUGIN_DIR', plugin_dir_path(__FILE__)); |
| 33 | 33 | define('THINKRANK_PLUGIN_URL', plugin_dir_url(__FILE__)); |
| 34 | 34 | define('THINKRANK_PLUGIN_BASENAME', plugin_basename(__FILE__)); |
| @@ -234,8 +234,20 @@ | ||
| 234 | 234 | // core routes, both of which anonymous front-end traffic reaches — so |
| 235 | 235 | // without the logged-in test a visitor could still pay for the rebuild |
| 236 | 236 | // this method documents as never being theirs to pay for. WP-CLI has no |
| 237 | 237 | // user, and is trusted by definition. |
| 238 | + // | |
| 239 | + // An MCP call counts too. It is an admin-equivalent action, but it is | |
| 240 | + // dispatched from `parse_request` on the pretty /thinkrank/mcp route, | |
| 241 | + // so it is neither is_admin() nor REST_REQUEST and never qualified — | |
| 242 | + // which meant an agent could change sitemap settings on a site with no | |
| 243 | + // working cron and leave the served file stale indefinitely, having | |
| 244 | + // already reported success (#764). The logged-in test still applies: | |
| 245 | + // Mcp_Server sets the current user only after a credential validates, | |
| 246 | + // so an anonymous POST to that route is not eligible. | |
| 247 | + $is_mcp_request = class_exists('ThinkRank\Mcp\Mcp_Manager') | |
| 248 | + && ThinkRank\Mcp\Mcp_Manager::is_serving_request(); | |
| 249 | + | |
| 238 | 250 | $eligible = (defined('WP_CLI') && WP_CLI) |
| 239 | 251 | || ( |
| 240 | 252 | is_user_logged_in() |
| 241 | 253 | && ( |
| @@ -240,8 +252,9 @@ | ||
| 240 | 252 | is_user_logged_in() |
| 241 | 253 | && ( |
| 242 | 254 | is_admin() |
| 243 | 255 | || (defined('REST_REQUEST') && REST_REQUEST) |
| 256 | + || $is_mcp_request | |
| 244 | 257 | ) |
| 245 | 258 | ); |
| 246 | 259 | |
| 247 | 260 | if (!$eligible) { |
| @@ -370,8 +383,12 @@ | ||
| 370 | 383 | 'seo_analyzer' => new ThinkRank\SEO\SEO_Analyzer(), |
| 371 | 384 | // Bulk Snippets' persisted issue index: invalidation hooks must run |
| 372 | 385 | // on every request, since posts are edited everywhere but there. |
| 373 | 386 | 'snippet_index' => new ThinkRank\SEO\Snippet_Index(), |
| 387 | + // The thin content report's word counts: same reason, and a | |
| 388 | + // separate index because a word count and a snippet verdict go | |
| 389 | + // stale for different reasons (#565). | |
| 390 | + 'word_count_index' => new ThinkRank\SEO\Word_Count_Index(), | |
| 374 | 391 | 'email_report' => new ThinkRank\SEO\Email_Report_Manager(), |
| 375 | 392 | 'google_oauth' => new ThinkRank\Integrations\Google_OAuth_Proxy(), |
| 376 | 393 | 'multilingual' => new ThinkRank\Integrations\Multilingual_Manager(), |
| 377 | 394 | 'ai_traffic' => new ThinkRank\SEO\Ai_Traffic_Tracker(), |