| @@ -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.10.0 | |
| 7 | + * Version: 2.12.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.10.0 | |
| 18 | + * @version 2.12.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.10.0'); | |
| 30 | +define('THINKRANK_VERSION', '2.12.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__)); |
| @@ -188,9 +188,10 @@ | ||
| 188 | 188 | } |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | 191 | /** |
| 192 | - * Register the sitemap regeneration WP-Cron listeners. | |
| 192 | + * Register the sitemap regeneration WP-Cron listeners, and the | |
| 193 | + * content-change listeners that queue them. | |
| 193 | 194 | * |
| 194 | 195 | * Runs on plugins_loaded (via init()), so the callbacks exist on every |
| 195 | 196 | * request — including WP-Cron, which never fires rest_api_init and therefore |
| 196 | 197 | * never builds the Sitemap REST endpoint (whose constructor would otherwise |
| @@ -197,11 +198,17 @@ | ||
| 197 | 198 | * be the only place the scheduled regeneration hooks get a listener). The |
| 198 | 199 | * generator is built lazily inside the callback so this stays cheap on the |
| 199 | 200 | * vast majority of requests where no regeneration is due. |
| 200 | 201 | * |
| 202 | + * The content-change listeners need the same treatment for the same | |
| 203 | + * reason: WP-Cron publishes scheduled posts, and Quick Edit, the classic | |
| 204 | + * editor and WP-CLI change content without REST either (#824). | |
| 205 | + * | |
| 201 | 206 | * @return void |
| 202 | 207 | */ |
| 203 | 208 | private function register_sitemap_cron_listeners(): void { |
| 209 | + ThinkRank\SEO\Sitemap_Generator::register_content_listeners(); | |
| 210 | + | |
| 204 | 211 | add_action('thinkrank_regenerate_sitemap', static function () { |
| 205 | 212 | (new ThinkRank\SEO\Sitemap_Generator())->auto_regenerate_sitemap(); |
| 206 | 213 | }); |
| 207 | 214 | add_action('thinkrank_regenerate_sitemap_settings', static function () { |
| @@ -233,9 +240,13 @@ | ||
| 233 | 240 | // is_admin() is true for admin-ajax.php and REST_REQUEST for public |
| 234 | 241 | // core routes, both of which anonymous front-end traffic reaches — so |
| 235 | 242 | // without the logged-in test a visitor could still pay for the rebuild |
| 236 | 243 | // this method documents as never being theirs to pay for. WP-CLI has no |
| 237 | - // user, and is trusted by definition. | |
| 244 | + // user, and is trusted by definition. A cron run is the process this | |
| 245 | + // work belongs to in the first place: a scheduled event that was | |
| 246 | + // consumed while another request held the generation lock is never | |
| 247 | + // re-queued, so without this a site whose admins see only failures | |
| 248 | + // could not recover through a (often memory-unlimited) system cron. | |
| 238 | 249 | // |
| 239 | 250 | // An MCP call counts too. It is an admin-equivalent action, but it is |
| 240 | 251 | // dispatched from `parse_request` on the pretty /thinkrank/mcp route, |
| 241 | 252 | // so it is neither is_admin() nor REST_REQUEST and never qualified — |
| @@ -247,8 +258,9 @@ | ||
| 247 | 258 | $is_mcp_request = class_exists('ThinkRank\Mcp\Mcp_Manager') |
| 248 | 259 | && ThinkRank\Mcp\Mcp_Manager::is_serving_request(); |
| 249 | 260 | |
| 250 | 261 | $eligible = (defined('WP_CLI') && WP_CLI) |
| 262 | + || wp_doing_cron() | |
| 251 | 263 | || ( |
| 252 | 264 | is_user_logged_in() |
| 253 | 265 | && ( |
| 254 | 266 | is_admin() |