-
Notifications
You must be signed in to change notification settings - Fork 97
Fix: WordPress Importer does not remap noteId in block metadata when reassigning comment IDs #254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 8 commits
0e19c14
d59679d
d7bc676
039fc9b
3f1980e
1033408
8db9ccf
ba2fdc8
dccc96b
91880cd
e86f185
244e627
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,7 @@ class WP_Import extends WP_Importer { | |
| public $author_mapping = array(); | ||
| public $processed_terms = array(); | ||
| public $processed_posts = array(); | ||
| public $processed_comments = array(); | ||
| public $post_orphans = array(); | ||
| public $processed_menu_items = array(); | ||
| public $menu_item_orphans = array(); | ||
|
|
@@ -818,6 +819,7 @@ public function process_posts() { | |
| if ( ! empty( $post['comments'] ) ) { | ||
| $this->process_post_comments( $post['comments'], (bool) $post_exists, $comment_post_id, $post ); | ||
| unset( $post['comments'] ); | ||
| $this->update_block_note_ids( $post_id ); | ||
| } | ||
|
|
||
| if ( ! isset( $post['postmeta'] ) ) { | ||
|
|
@@ -1095,6 +1097,10 @@ protected function process_post_comments( $comments, $post_exists, $comment_post | |
| do_action( 'wp_import_insert_comment', $inserted_comment_id, $comment, $comment_post_id, $post ); | ||
| $this->process_post_comment_metas( $inserted_comment_id, $comment['commentmeta'] ); | ||
| $inserted_comments[ $key ] = $inserted_comment_id; | ||
| // Store comment ID mapping for note-type comments to update noteId references in blocks. | ||
| if ( isset( $comment['comment_type'] ) && 'note' === $comment['comment_type'] ) { | ||
| $this->processed_comments[ $key ] = $inserted_comment_id; | ||
| } | ||
| ++$num_comments; | ||
| } | ||
| } | ||
|
|
@@ -1139,6 +1145,95 @@ protected function process_post_comment_metas( $comment_id, $commentmeta ) { | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Remaps noteId references in block metadata after note-type comments are imported. | ||
| * | ||
| * @param int $post_id ID of the post whose block content should be updated. | ||
| * @return void | ||
| */ | ||
| protected function update_block_note_ids( int $post_id = 0 ): void { | ||
| if ( empty( $this->processed_comments ) ) { | ||
| return; | ||
| } | ||
|
|
||
| $post = get_post( $post_id ); | ||
| if ( ! $post ) { | ||
| return; | ||
| } | ||
|
|
||
| $is_contain_notes = strpos( $post->post_content, '"noteId"' ); | ||
| if ( false === $is_contain_notes ) { | ||
| return; | ||
| } | ||
|
|
||
| // @todo Replace with WP_HTML_Tag_Processor or WP_Block_Processor once minimum version support is 6.2 or 6.9 respectively. | ||
| $parser = new WP_Block_Parser(); | ||
| $parser->document = $post->post_content; | ||
| $parser->offset = 0; | ||
| $replacements = array(); | ||
|
|
||
| do { | ||
| $next_token = $parser->next_token(); | ||
| list( $token_type, $block_name, $attrs, $start_offset, $token_length ) = $next_token; | ||
|
|
||
| if ( 'no-more-tokens' === $token_type ) { | ||
| break; | ||
| } | ||
|
|
||
| $parser->offset = $start_offset + $token_length; | ||
|
|
||
| if ( 'block-opener' !== $token_type && 'void-block' !== $token_type ) { | ||
| continue; | ||
| } | ||
|
|
||
| $old_note_id = $attrs['metadata']['noteId'] ?? null; | ||
|
|
||
| if ( | ||
| ! ( is_string( $old_note_id ) || is_int( $old_note_id ) ) || | ||
| ! isset( $this->processed_comments[ $old_note_id ] ) | ||
| ) { | ||
| continue; | ||
| } | ||
|
|
||
| $attribute_string = substr( $post->post_content, $start_offset, $token_length ); | ||
| $attribute_json_start = strcspn( $attribute_string, '{' ); | ||
| $attribute_json_end = strrpos( $attribute_string, '}' ); | ||
|
|
||
| if ( false === $attribute_json_end || $attribute_json_start >= $attribute_json_end ) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the parser returned these attributes then we shouldn’t need the bounds-checking. it’s already been performed. if we leave it in for the sake of explicitness, then there’s an error where the starting bound could be so I think it might be appropriate to either remove this step entirely (it should never trigger here) or add
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done Thanks,
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only when I linked to this as an example for another PR did I notice that so you had it right before and that was a review blunder on my part. it now makes more sense why the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, Have reverted the same. Probably I could have thought of more of that case and should have replied before addressing that! |
||
| continue; | ||
| } | ||
|
|
||
| $json_start = $start_offset + $attribute_json_start; | ||
| $json_length = $attribute_json_end - $attribute_json_start + 1; | ||
|
|
||
| $attrs['metadata']['noteId'] = $this->processed_comments[ $old_note_id ]; | ||
| $replacements[] = array( $json_start, $json_length, serialize_block_attributes( $attrs ) ); | ||
|
|
||
| } while ( 'no-more-tokens' !== $token_type ); | ||
|
hbhalodia marked this conversation as resolved.
Outdated
|
||
|
|
||
| if ( empty( $replacements ) ) { | ||
| return; | ||
| } | ||
|
|
||
| // Apply replacements in reverse order to avoid affecting offsets of later replacements. | ||
| $replacements = array_reverse( $replacements ); | ||
| $updated_content = $post->post_content; | ||
|
|
||
| // Loop through each replacement and update the content string with the new JSON attributes. | ||
| foreach ( $replacements as $replacement ) { | ||
| list( $offset, $length, $new_json ) = $replacement; | ||
| $updated_content = substr_replace( $updated_content, $new_json, $offset, $length ); | ||
| } | ||
|
dmsnell marked this conversation as resolved.
|
||
|
|
||
| wp_update_post( | ||
| // Cast to object to ensure wp_update_post() will add the required slashes. | ||
| (object) array( | ||
| 'ID' => $post_id, | ||
| 'post_content' => $updated_content, | ||
| ) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Process a single comment meta entry for an imported comment. | ||
| * | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.