PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.11.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.11.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/admin/importers/class-rankmath-exporter.php +64 -2 2.0.2 → 2.11.0 View file →
@@ -182,8 +182,17 @@
182 182 if ($log_count > 0) {
183 183 $types['404_logs'] = $log_count;
184 184 }
185 185
186 + // FAQ / HowTo blocks live in post_content, not in any meta table, so
187 + // they are invisible to every count above. Without this type they were
188 + // never migrated at all and simply broke when Rank Math went away
189 + // (#777).
190 + $block_count = Block_Converter::count_posts();
191 + if ($block_count > 0) {
192 + $types[Block_Converter::TYPE] = $block_count;
193 + }
194 +
186 195 foreach ($this->option_keys as $key) {
187 196 if (get_option($key, null) !== null) {
188 197 $types['settings'] = 1;
189 198 break;
@@ -276,8 +285,14 @@
276 285 'twitter_description' => $this->convert_template_variables($meta['rank_math_twitter_description'] ?? '', $post_id),
277 286 'twitter_image' => $meta['rank_math_twitter_image'] ?? '',
278 287 'primary_category' => (int) ($meta['rank_math_primary_category'] ?? 0),
279 288 'schema_type' => $this->resolve_schema_type($meta),
289 + // WooCommerce product identifier. Rank Math keeps it in its
290 + // own per-post meta; ThinkRank Pro reads the canonical field
291 + // this maps to, so a migrating store keeps the identifier
292 + // Google asks for instead of collecting a "missing
293 + // identifier" warning on every product (#715).
294 + 'product_identifier' => (string) ($meta['rank_math_gtin_code'] ?? ''),
280 295 // Rank Math pillar content maps directly to ThinkRank pillar content.
281 296 'pillar_content' => $this->normalize_pillar_content($meta['rank_math_pillar_content'] ?? ''),
282 297 ],
283 298 'extended' => [
@@ -750,8 +765,40 @@
750 765
751 766 /**
752 767 * {@inheritDoc}
753 768 *
769 + * `content_blocks` records carry post ids only. The blocks themselves stay
770 + * in `post_content` and are rewritten in place at migrate time — copying
771 + * the content into the snapshot would mean holding a second copy of every
772 + * FAQ page in `wp_options`, which is where snapshots live.
773 + */
774 + protected function export_custom_type_page(string $type, int $page): array {
775 + if (Block_Converter::TYPE !== $type) {
776 + return parent::export_custom_type_page($type, $page);
777 + }
778 +
779 + $post_ids = Block_Converter::get_post_ids($page, $this->chunk_size);
780 +
781 + // export_chunk() decides whether another page follows from the number
782 + // of rows the query returned, so report it even when nothing is emitted.
783 + $this->last_page_row_count = count($post_ids);
784 +
785 + $records = [];
786 + foreach ($post_ids as $post_id) {
787 + $records[] = [
788 + 'object_id' => $post_id,
789 + 'object_type' => 'post',
790 + 'source_plugin' => $this->plugin_slug,
791 + 'data' => ['post_id' => $post_id],
792 + ];
793 + }
794 +
795 + return $records;
796 + }
797 +
798 + /**
799 + * {@inheritDoc}
800 + *
754 801 * Rank Math's 404 monitor keeps one row per URI in `rank_math_404_logs`,
755 802 * which lines up with ThinkRank Pro's `thinkrank_404_logs`.
756 803 */
757 804 protected function export_404_logs_page(int $page): array {
@@ -1002,9 +1049,12 @@
1002 1049 if ($post_id) {
1003 1050 $post = get_post($post_id);
1004 1051 if ($post) {
1005 1052 $replacements['%title%'] = $post->post_title;
1006 - $replacements['%excerpt%'] = wp_trim_words($post->post_excerpt ?: wp_trim_words(wp_strip_all_tags($post->post_content), 55), 55);
1053 + $replacements['%excerpt%'] = \ThinkRank\Core\Seo_Text::trim_words(
1054 + $post->post_excerpt ?: \ThinkRank\Core\Seo_Text::trim_words(wp_strip_all_tags($post->post_content), 55),
1055 + 55
1056 + );
1007 1057 $replacements['%date%'] = get_the_date('', $post);
1008 1058 $replacements['%modified%'] = get_the_modified_date('', $post);
1009 1059 $replacements['%id%'] = (string) $post_id;
1010 1060 $replacements['%name%'] = get_the_author_meta('display_name', (int) $post->post_author);
@@ -1057,13 +1107,25 @@
1057 1107
1058 1108 // Rank Math token => ThinkRank Global SEO token (structure preserved).
1059 1109 $token_map = [
1060 1110 '%name%' => '%author%', // Rank Math author display name token
1111 + // WooCommerce product variables. Rank Math lets a product title or
1112 + // description carry the price, SKU and stock status; every one of
1113 + // them used to be stripped by the pass below, so "Buy %title% for
1114 + // %wc_price%" imported as "Buy %title% for" (#715).
1115 + '%wc_price%' => '%price%',
1116 + '%wc_sku%' => '%sku%',
1117 + '%wc_shortdesc%' => '%short_description%',
1118 + '%wc_brand%' => '%brand%',
1061 1119 ];
1062 1120 $template = str_replace(array_keys($token_map), array_values($token_map), $template);
1063 1121
1064 1122 // Tokens ThinkRank's Global SEO engine resolves natively — keep as-is.
1065 - $supported = ['%title%', '%sitename%', '%sep%', '%excerpt%', '%date%', '%modified%', '%author%', '%category%'];
1123 + $supported = [
1124 + '%title%', '%sitename%', '%sep%', '%excerpt%', '%date%', '%modified%', '%author%', '%category%',
1125 + // Resolved by Pattern_Resolver on a product, empty elsewhere.
1126 + '%price%', '%sale_price%', '%sku%', '%stock_status%', '%short_description%', '%brand%',
1127 + ];
1066 1128
1067 1129 // Strip any token ThinkRank cannot resolve so it does not render literally.
1068 1130 $template = preg_replace_callback(
1069 1131 '/%[a-z0-9_]+%/i',