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/ai/class-metadata-generator.php +32 -14 2.1.1 → 2.9.0 View file →
@@ -96,30 +96,47 @@
96 96 * @return array Generated metadata
97 97 * @throws \Exception If generation fails
98 98 */
99 99 public function generate_for_post(int $post_id, array $options = []): array {
100 + $metadata = $this->suggest_for_post($post_id, $options);
101 +
102 + // Save metadata to post meta
103 + $this->save_post_metadata($post_id, $metadata);
104 +
105 + return $metadata;
106 + }
107 +
108 + /**
109 + * Generate metadata for a post without writing anything.
110 + *
111 + * The same generation as {@see self::generate_for_post()}, minus the save.
112 + * Bulk Snippets shows the result for review and writes only when the user
113 + * clicks Save, so it must never persist as a side effect (#727).
114 + *
115 + * @since 2.8.0
116 + *
117 + * @param int $post_id Post ID.
118 + * @param array $options Generation options.
119 + * @return array Generated metadata.
120 + * @throws \Exception If the post is missing or generation fails.
121 + */
122 + public function suggest_for_post(int $post_id, array $options = []): array {
100 123 $post = get_post($post_id);
101 -
124 +
102 125 if (!$post) {
103 126 throw new \Exception('Post not found');
104 127 }
105 -
128 +
106 129 // Extract content from post
107 130 $content = $this->extract_post_content($post);
108 -
131 +
109 132 // Add post-specific options
110 133 $options = array_merge($options, [
111 134 'content_type' => $this->determine_content_type($post),
112 135 'post_id' => $post_id,
113 136 ]);
114 -
115 - // Generate metadata
116 - $metadata = $this->generate_for_content($content, $options);
117 -
118 - // Save metadata to post meta
119 - $this->save_post_metadata($post_id, $metadata);
120 -
121 - return $metadata;
137 +
138 + return $this->generate_for_content($content, $options);
122 139 }
123 140
124 141 /**
125 142 * Generate multiple variations of metadata
@@ -202,11 +219,12 @@
202 219 // Trim and limit length for AI processing
203 220 $content = trim($content);
204 221 $max_length = 4000; // Reasonable limit for AI processing
205 222
206 - if (strlen($content) > $max_length) {
207 - $content = substr($content, 0, $max_length) . '...';
208 - }
223 + // strlen()/substr() count BYTES: on Thai or CJK this handed the model a
224 + // third of the intended content, and cut the last character in half so
225 + // the payload carried an invalid UTF-8 sequence (#687).
226 + $content = \ThinkRank\Core\Seo_Text::trim_to_length($content, $max_length);
209 227
210 228 return $content;
211 229 }
212 230