Skip to content

Commit 24e17f9

Browse files
authored
Import: Convert to blocks and add reply (#1591)
1 parent dbd2747 commit 24e17f9

File tree

4 files changed

+82
-2
lines changed

4 files changed

+82
-2
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: changed
3+
4+
Mastodon imports now support blocks, with automatic reply embedding for conversations.

includes/class-blocks.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public static function init() {
2727
// Add editor plugin.
2828
\add_action( 'enqueue_block_editor_assets', array( self::class, 'enqueue_editor_assets' ) );
2929
\add_action( 'init', array( self::class, 'register_postmeta' ), 11 );
30+
31+
\add_filter( 'activitypub_import_mastodon_post_data', array( self::class, 'filter_import_mastodon_post_data' ), 10, 2 );
3032
}
3133

3234
/**
@@ -412,4 +414,33 @@ public static function render_follower( $follower ) {
412414
$external_svg
413415
);
414416
}
417+
418+
/**
419+
* Converts content to blocks before saving to the database.
420+
*
421+
* @param array $data The post data to be inserted.
422+
* @param object $post The Mastodon Create activity.
423+
*
424+
* @return array
425+
*/
426+
public static function filter_import_mastodon_post_data( $data, $post ) {
427+
// Convert paragraphs to blocks.
428+
\preg_match_all( '#<p>.*?</p>#is', $data['post_content'], $matches );
429+
$blocks = \array_map(
430+
function ( $paragraph ) {
431+
return '<!-- wp:paragraph -->' . PHP_EOL . $paragraph . PHP_EOL . '<!-- /wp:paragraph -->' . PHP_EOL;
432+
},
433+
$matches[0] ?? array()
434+
);
435+
436+
$data['post_content'] = \rtrim( \implode( PHP_EOL, $blocks ), PHP_EOL );
437+
438+
// Add reply block if it's a reply.
439+
if ( null !== $post->object->inReplyTo ) {
440+
$reply_block = \sprintf( '<!-- wp:activitypub/reply {"url":"%1$s","embedPost":true} /-->' . PHP_EOL, \esc_url( $post->object->inReplyTo ) );
441+
$data['post_content'] = $reply_block . $data['post_content'];
442+
}
443+
444+
return $data;
445+
}
415446
}

includes/wp-admin/import/class-mastodon.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,10 @@ function ( $tag ) {
312312
/**
313313
* Filter the post data before inserting it into the database.
314314
*
315-
* @param array $post_data The post data to be inserted.
315+
* @param array $post_data The post data to be inserted.
316+
* @param object $post The Mastodon Create activity.
316317
*/
317-
$post_data = \apply_filters( 'activitypub_import_mastodon_post_data', $post_data );
318+
$post_data = \apply_filters( 'activitypub_import_mastodon_post_data', $post_data, $post );
318319

319320
$post_exists = \post_exists( '', $post_data['post_content'], $post_data['post_date'], $post_data['post_type'] );
320321

tests/includes/class-test-blocks.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,48 @@ public function test_render_reply_block_with_no_embed() {
133133
$this->assertStringContainsString( 'u-in-reply-to', $output, 'Output should contain the reply link.' );
134134
$this->assertStringContainsString( 'example.com/no-embed', $output, 'Output should contain the formatted URL.' );
135135
}
136+
137+
/**
138+
* Test filter_import_mastodon_post_data with regular paragraphs.
139+
*
140+
* @covers ::filter_import_mastodon_post_data
141+
*/
142+
public function test_filter_import_mastodon_post_data_with_paragraphs() {
143+
$data = array(
144+
'post_content' => '<p>First paragraph</p><p>Second paragraph</p>',
145+
);
146+
147+
$post = (object) array(
148+
'object' => (object) array(
149+
'inReplyTo' => null,
150+
),
151+
);
152+
153+
$result = Blocks::filter_import_mastodon_post_data( $data, $post );
154+
155+
$this->assertSame( "<!-- wp:paragraph -->\n<p>First paragraph</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Second paragraph</p>\n<!-- /wp:paragraph -->", $result['post_content'] );
156+
}
157+
158+
/**
159+
* Test filter_import_mastodon_post_data with a reply post.
160+
*
161+
* @covers ::filter_import_mastodon_post_data
162+
*/
163+
public function test_filter_import_mastodon_post_data_with_reply() {
164+
$data = array(
165+
'post_content' => '<p>This is a reply</p>',
166+
);
167+
168+
$reply_url = 'https://mastodon.social/@user/123456';
169+
$post = (object) array(
170+
'object' => (object) array(
171+
'inReplyTo' => $reply_url,
172+
),
173+
);
174+
175+
$result = Blocks::filter_import_mastodon_post_data( $data, $post );
176+
177+
$this->assertStringContainsString( '<!-- wp:activitypub/reply {"url":"https://mastodon.social/@user/123456","embedPost":true} /-->', $result['post_content'] );
178+
$this->assertStringContainsString( "<!-- wp:paragraph -->\n<p>This is a reply</p>\n<!-- /wp:paragraph -->", $result['post_content'] );
179+
}
136180
}

0 commit comments

Comments
 (0)