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.11.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 All 52 releases
← All changes | includes/abilities/settings/class-update-sitemap-settings.php +65 -12 2.4.0 → 2.10.0 View file →
@@ -38,9 +38,16 @@
38 38 */
39 39 public function get_annotations() {
40 40 return [
41 41 'readonly' => false,
42 - 'destructive' => true,
42 + // Settings writes are recoverable: the matching get-* ability reads
43 + // the previous value, so nothing is lost that cannot be put back.
44 + // `destructive` is reserved for calls that lose data or reach
45 + // outside the site, and marking routine configuration with it made
46 + // MCP clients demand a human approval for every save — which users
47 + // reported as a permission bug, because the client's refusal reads
48 + // as "No approval received" (#675).
49 + 'destructive' => false,
43 50 'idempotent' => true,
44 51 'priority' => 2.0,
45 52 'openWorldHint' => false,
46 53 ];
@@ -55,13 +62,18 @@
55 62 return [
56 63 'type' => 'object',
57 64 'additionalProperties' => false,
58 65 'properties' => [
59 - 'settings' => [
66 + 'settings' => [
60 67 'type' => 'object',
61 68 'description' => __( 'Sitemap settings to update.', 'thinkrank' ),
62 69 'properties' => Settings_Key_Map::sitemap(),
63 70 ],
71 + 'regenerate' => [
72 + 'type' => 'boolean',
73 + 'default' => true,
74 + 'description' => __( 'Rebuild the served sitemap before returning, so the change is live when this call reports success. Leave it on unless you are making several changes in a row and want to rebuild once at the end, in which case the last call should set it to true.', 'thinkrank' ),
75 + ],
64 76 ],
65 77 'required' => [ 'settings' ],
66 78 ];
67 79 }
@@ -74,10 +86,19 @@
74 86 public function get_output_schema() {
75 87 return [
76 88 'type' => 'object',
77 89 'properties' => [
78 - 'success' => [ 'type' => 'boolean' ],
79 - 'message' => [ 'type' => 'string' ],
90 + 'success' => [ 'type' => 'boolean' ],
91 + 'message' => [ 'type' => 'string' ],
92 + // Whether the SERVED sitemap reflects the change yet. Saving and
93 + // serving are separate steps, and reporting only the save let an
94 + // agent state the exclusion had taken effect while the static
95 + // file still listed the page (#764).
96 + 'rebuilt' => [ 'type' => 'boolean' ],
97 + 'pending_since' => [
98 + 'type' => [ 'integer', 'null' ],
99 + 'description' => __( 'Unix time a rebuild has been outstanding since, when the served sitemap has not caught up.', 'thinkrank' ),
100 + ],
80 101 ],
81 102 ];
82 103 }
83 104
@@ -112,18 +133,50 @@
112 133 }
113 134
114 135 $result = $gen->save_settings( 'site', null, $merged );
115 136
116 - // Rebuild the served sitemap so the change takes effect instead of going
117 - // stale until an unrelated content edit (debounced).
118 - if ( $result ) {
119 - $gen->schedule_regeneration();
137 + if ( ! $result ) {
138 + return [
139 + 'success' => false,
140 + 'message' => __( 'Failed to update sitemap settings.', 'thinkrank' ),
141 + 'rebuilt' => false,
142 + ];
120 143 }
121 144
145 + // Mark the rebuild outstanding either way, so a caller that opts out of
146 + // the synchronous rebuild still converges via cron or the request-time
147 + // takeover, and so a failed rebuild below is retried rather than lost.
148 + $gen->schedule_regeneration();
149 +
150 + $regenerate = ! isset( $input['regenerate'] ) || (bool) $input['regenerate'];
151 +
152 + // Rebuild inline rather than leaving it to WP-Cron. The sitemap is a
153 + // static file on most installs, so nothing re-runs PHP for it; where
154 + // cron does not fire, the old debounced-only path left the served file
155 + // stale indefinitely while this ability had already reported success
156 + // (#764). A settings change is deliberate and infrequent, and the
157 + // rebuild is lock-guarded, so doing it now is the honest thing.
158 + $rebuilt = $regenerate ? $gen->regenerate_sitemap_from_settings() : false;
159 +
160 + $pending_since = Sitemap_Generator::regeneration_pending_since();
161 +
162 + if ( $rebuilt && 0 === $pending_since ) {
163 + return [
164 + 'success' => true,
165 + 'message' => __( 'Sitemap settings updated and the served sitemap was rebuilt.', 'thinkrank' ),
166 + 'rebuilt' => true,
167 + 'pending_since' => null,
168 + ];
169 + }
170 +
171 + // Saved, but the file a crawler fetches does not reflect it yet. Say so
172 + // rather than report a success the caller cannot verify.
122 173 return [
123 - 'success' => (bool) $result,
124 - 'message' => (bool) $result
125 - ? __( 'Sitemap settings updated.', 'thinkrank' )
126 - : __( 'Failed to update sitemap settings.', 'thinkrank' ),
174 + 'success' => true,
175 + 'message' => $regenerate
176 + ? __( 'Sitemap settings updated, but the served sitemap could not be rebuilt yet and still shows the previous contents. It will be retried automatically; purge-caches with the "sitemap" scope forces another attempt.', 'thinkrank' )
177 + : __( 'Sitemap settings updated. The served sitemap has not been rebuilt, as requested; run purge-caches with the "sitemap" scope when you are ready to publish the change.', 'thinkrank' ),
178 + 'rebuilt' => false,
179 + 'pending_since' => $pending_since > 0 ? $pending_since : null,
127 180 ];
128 181 }
129 182 }