← All changes
|
includes/admin/importers/class-rankmath-exporter.php
+64
-2
2.2.0
→
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', |