PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.9.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.9.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 1.0.2 All 50 releases
← All changes | includes/api/class-seo-score-endpoint.php +31 -3 1.32.0 → 2.9.0 View file →
@@ -119,8 +119,23 @@
119 119 'required' => false,
120 120 'type' => 'string',
121 121 'sanitize_callback' => 'sanitize_text_field',
122 122 ],
123 + // The permalink field as it stands in the editor, so an unsaved
124 + // slug edit scores immediately instead of matching the old URL.
125 + 'live_slug' => [
126 + 'required' => false,
127 + 'type' => 'string',
128 + // NOT sanitize_title: REST calls a sanitize_callback as
129 + // ($value, $request, $param), and sanitize_title()'s second
130 + // parameter is $fallback_title — so an empty slug returned
131 + // the WP_REST_Request object, which fataled on the string
132 + // cast below. The editor sends an empty slug whenever the
133 + // permalink field is blank (every draft), so this fired on
134 + // ordinary use. Sanitized with a single-argument
135 + // sanitize_title() where it is consumed instead.
136 + 'sanitize_callback' => 'sanitize_text_field',
137 + ],
123 138 'readability_score' => [
124 139 'required' => false,
125 140 'type' => 'string',
126 141 'sanitize_callback' => 'sanitize_text_field',
@@ -224,8 +239,17 @@
224 239 // nothing about the field, which keeps the saved value.
225 240 $live_title = $request->get_param('live_title');
226 241 $live_description = $request->get_param('live_description');
227 242
243 + // Score the slug the editor is showing. Omitted (null) keeps the
244 + // saved slug; an empty string means the field was cleared, which
245 + // falls back to the title-derived slug exactly as an unsaved draft
246 + // does inside the calculator.
247 + $live_slug = $request->get_param('live_slug');
248 + if ($live_slug !== null) {
249 + $content_data['slug'] = sanitize_title((string) $live_slug);
250 + }
251 +
228 252 $raw_title = $live_title !== null
229 253 ? (string) $live_title
230 254 : get_post_meta($post_id, '_thinkrank_seo_title', true);
231 255 $raw_description = $live_description !== null
@@ -262,13 +286,17 @@
262 286 $metadata,
263 287 $score_options
264 288 );
265 289
266 - // Add readability_score and content_quality from frontend if provided
267 - if (!empty($readability_score)) {
290 + // Add readability_score and content_quality from frontend if
291 + // provided. `!== null`, not `!empty()`: 0 is a legitimate score and
292 + // empty() discarded it, so a post the editor scored as 0 kept
293 + // whatever the calculator had produced instead (#394). Both params
294 + // already default to null above, so null means "not sent".
295 + if (null !== $readability_score) {
268 296 $score_data['readability_score'] = $readability_score;
269 297 }
270 - if (!empty($content_quality)) {
298 + if (null !== $content_quality) {
271 299 $score_data['content_quality'] = $content_quality;
272 300 }
273 301
274 302 // Save score if requested