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 +70 -59 2.1.0 → 2.10.0 View file →
@@ -22,34 +22,14 @@
22 22 * Sitemap settings are persisted through the Sitemap_Generator SEO manager.
23 23 */
24 24 class Update_Sitemap_Settings extends Ability_Base {
25 25 /**
26 - * Boolean-typed sitemap keys.
27 - */
28 - private const BOOL_KEYS = [
29 - 'enabled',
30 - 'include_images',
31 - 'include_posts',
32 - 'include_pages',
33 - 'include_categories',
34 - 'include_tags',
35 - ];
36 -
37 - /**
38 - * String-typed sitemap keys.
39 - */
40 - private const STRING_KEYS = [
41 - 'exclude_posts',
42 - 'exclude_terms',
43 - ];
44 -
45 - /**
46 26 * Constructor.
47 27 */
48 28 public function __construct() {
49 29 $this->id = 'thinkrank/update-sitemap-settings';
50 30 $this->label = __( 'Update ThinkRank Sitemap Settings', 'thinkrank' );
51 - $this->description = __( 'Update ThinkRank XML sitemap settings, including per-type inclusion toggles and exclusion lists.', 'thinkrank' );
31 + $this->description = __( 'Update ThinkRank XML sitemap settings: per-type inclusion toggles, exclusion lists, and the index/splitting, styling, filename and search-engine ping options. Read the current values with get-sitemap-settings first; only the keys you pass are changed.', 'thinkrank' );
52 32 }
53 33
54 34 /**
55 35 * {@inheritDoc}
@@ -58,9 +38,16 @@
58 38 */
59 39 public function get_annotations() {
60 40 return [
61 41 'readonly' => false,
62 - '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,
63 50 'idempotent' => true,
64 51 'priority' => 2.0,
65 52 'openWorldHint' => false,
66 53 ];
@@ -75,22 +62,18 @@
75 62 return [
76 63 'type' => 'object',
77 64 'additionalProperties' => false,
78 65 'properties' => [
79 - 'settings' => [
66 + 'settings' => [
80 67 'type' => 'object',
81 68 'description' => __( 'Sitemap settings to update.', 'thinkrank' ),
82 - 'properties' => [
83 - 'enabled' => [ 'type' => 'boolean' ],
84 - 'include_images' => [ 'type' => 'boolean' ],
85 - 'include_posts' => [ 'type' => 'boolean' ],
86 - 'include_pages' => [ 'type' => 'boolean' ],
87 - 'include_categories' => [ 'type' => 'boolean' ],
88 - 'include_tags' => [ 'type' => 'boolean' ],
89 - 'exclude_posts' => [ 'type' => 'string' ],
90 - 'exclude_terms' => [ 'type' => 'string' ],
91 - ],
69 + 'properties' => Settings_Key_Map::sitemap(),
92 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 + ],
93 76 ],
94 77 'required' => [ 'settings' ],
95 78 ];
96 79 }
@@ -103,10 +86,19 @@
103 86 public function get_output_schema() {
104 87 return [
105 88 'type' => 'object',
106 89 'properties' => [
107 - 'success' => [ 'type' => 'boolean' ],
108 - '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 + ],
109 101 ],
110 102 ];
111 103 }
112 104
@@ -128,25 +120,12 @@
128 120 }
129 121
130 122 $gen = new Sitemap_Generator();
131 123 $merged = $gen->get_settings( 'site', null );
132 - $found = false;
124 + $patch = Settings_Key_Map::coerce( Settings_Key_Map::sitemap(), $settings );
125 + $merged = array_merge( $merged, $patch );
133 126
134 - foreach ( self::BOOL_KEYS as $key ) {
135 - if ( array_key_exists( $key, $settings ) ) {
136 - $merged[ $key ] = (bool) $settings[ $key ];
137 - $found = true;
138 - }
139 - }
140 -
141 - foreach ( self::STRING_KEYS as $key ) {
142 - if ( array_key_exists( $key, $settings ) ) {
143 - $merged[ $key ] = sanitize_text_field( (string) $settings[ $key ] );
144 - $found = true;
145 - }
146 - }
147 -
148 - if ( ! $found ) {
127 + if ( empty( $patch ) ) {
149 128 return new \WP_Error(
150 129 'thinkrank_no_valid_sitemap_setting_keys',
151 130 __( 'No valid sitemap setting keys were provided.', 'thinkrank' ),
152 131 [ 'status' => 400 ]
@@ -154,18 +133,50 @@
154 133 }
155 134
156 135 $result = $gen->save_settings( 'site', null, $merged );
157 136
158 - // Rebuild the served sitemap so the change takes effect instead of going
159 - // stale until an unrelated content edit (debounced).
160 - if ( $result ) {
161 - $gen->schedule_regeneration();
137 + if ( ! $result ) {
138 + return [
139 + 'success' => false,
140 + 'message' => __( 'Failed to update sitemap settings.', 'thinkrank' ),
141 + 'rebuilt' => false,
142 + ];
162 143 }
163 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.
164 173 return [
165 - 'success' => (bool) $result,
166 - 'message' => (bool) $result
167 - ? __( 'Sitemap settings updated.', 'thinkrank' )
168 - : __( '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,
169 180 ];
170 181 }
171 182 }