Automatically hide unknown @mentions in the Friends plugin, add a setting to change this

This commit is contained in:
Alex Kirk 2022-12-10 09:33:48 +01:00
parent 6feac1be3b
commit a61f1168c3
2 changed files with 127 additions and 2 deletions

View file

@ -30,6 +30,10 @@ class Friends_Feed_Parser_ActivityPub extends \Friends\Feed_Parser {
\add_action( 'friends_feed_parser_activitypub_unfollow', array( $this, 'unfollow_user' ), 10, 2 ); \add_action( 'friends_feed_parser_activitypub_unfollow', array( $this, 'unfollow_user' ), 10, 2 );
\add_filter( 'friends_rewrite_incoming_url', array( $this, 'friends_rewrite_incoming_url' ), 10, 2 ); \add_filter( 'friends_rewrite_incoming_url', array( $this, 'friends_rewrite_incoming_url' ), 10, 2 );
\add_filter( 'friends_edit_friend_table_end', array( $this, 'activitypub_settings' ), 10 );
\add_filter( 'friends_edit_friend_after_form_submit', array( $this, 'activitypub_save_settings' ), 10 );
\add_filter( 'friends_modify_feed_item', array( $this, 'modify_incoming_item' ), 9, 3 );
\add_filter( 'the_content', array( $this, 'the_content' ), 99, 2 ); \add_filter( 'the_content', array( $this, 'the_content' ), 99, 2 );
\add_filter( 'activitypub_extract_mentions', array( $this, 'activitypub_extract_mentions' ), 10, 2 ); \add_filter( 'activitypub_extract_mentions', array( $this, 'activitypub_extract_mentions' ), 10, 2 );
} }
@ -462,4 +466,71 @@ class Friends_Feed_Parser_ActivityPub extends \Friends\Feed_Parser {
return $result[0]; return $result[0];
} }
public function activitypub_save_settings( \Friends\User $friend ) {
if ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'edit-friend-feeds-' . $friend->ID ) ) {
if ( isset( $_POST['friends_show_replies'] ) && $_POST['friends_show_replies'] ) {
$friend->update_user_option( 'activitypub_friends_show_replies', '1' );
} else {
$friend->delete_user_option( 'activitypub_friends_show_replies' );
}
}
}
public function activitypub_settings( \Friends\User $friend ) {
foreach ( $friend->get_active_feeds() as $feed ) {
if ( 'activitypub' === $feed->parser ) {
return;
}
}
$show_replies = $friend->get_user_option( 'activitypub_friends_show_replies' );
?>
<tr>
<th>ActivityPub</th>
<td>
<fieldset>
<div>
<input type="checkbox" name="friends_show_replies" id="friends_show_replies" value="1" <?php checked( '1', $show_replies ); ?> />
<label for="friends_show_replies"><?php esc_html_e( "Don't hide @mentions of others", 'activitypub' ); ?></label>
</div>
</fieldset>
<p class="description">
<?php
esc_html_e( 'If an incoming post from ActivityPub starts with an @mention of someone else, it will be not be hidden automatically.', 'activitypub' );
?>
</p>
</td>
</tr>
<?php
}
/**
* Apply the feed rules
*
* @param \Friends\Feed_Item $item The feed item.
* @param \Friends\User_Feed $feed The feed object.
* @param \Friends\User $friend_user The friend user.
* @return \Friends\Feed_Item The modified feed item.
*/
public function modify_incoming_item( \Friends\Feed_Item $item, \Friends\User_Feed $feed = null, \Friends\User $friend_user = null ) {
if ( ! $feed || 'activitypub' !== $feed->get_parser() ) {
return $item;
}
if ( ! $friend_user->get_user_option( 'activitypub_friends_show_replies' ) ) {
$plain_text_content = \wp_strip_all_tags( $item->post_content );
if ( preg_match( ' /^@(?:[a-zA-Z0-9_.-]+)/i', $plain_text_content, $m ) ) {
$users = $this->get_possible_mentions();
if ( ! isset( $users[ $m[0] ] ) ) {
$item->_feed_rule_transform = array(
'post_status' => 'trash',
);
}
}
}
return $item;
}
} }

View file

@ -8,6 +8,7 @@ class Test_Friends_Feed_Parser_ActivityPub extends ActivityPub_TestCase_Cache_HT
private $actor; private $actor;
public function test_incoming_post() { public function test_incoming_post() {
update_user_option( 'activitypub_friends_show_replies', '1', $this->friend_id );
$now = time() - 10; $now = time() - 10;
$status_id = 123; $status_id = 123;
@ -107,6 +108,60 @@ class Test_Friends_Feed_Parser_ActivityPub extends ActivityPub_TestCase_Cache_HT
$this->assertEquals( $content, $posts[0]->post_content ); $this->assertEquals( $content, $posts[0]->post_content );
$this->assertEquals( $this->friend_id, $posts[0]->post_author ); $this->assertEquals( $this->friend_id, $posts[0]->post_author );
$this->assertEquals( $this->friend_name, get_post_meta( $posts[0]->ID, 'author', true ) ); $this->assertEquals( $this->friend_name, get_post_meta( $posts[0]->ID, 'author', true ) );
delete_user_option( 'activitypub_friends_show_replies', $this->friend_id );
}
public function test_incoming_mention_of_others() {
$now = time() - 10;
$status_id = 123;
$posts = get_posts(
array(
'post_type' => \Friends\Friends::CPT,
'author' => $this->friend_id,
)
);
$post_count = count( $posts );
// Let's post a new Note through the REST API.
$date = gmdate( \DATE_W3C, $now++ );
$id = 'test' . $status_id;
$content = '<a rel="mention" class="u-url mention" href="https://example.org/users/abc">@<span>abc</span></a> Test ' . $date . ' ' . wp_rand();
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/' . get_current_user_id() . '/inbox' );
$request->set_param( 'type', 'Create' );
$request->set_param( 'id', $id );
$request->set_param( 'actor', $this->actor );
$request->set_param(
'object',
array(
'type' => 'Note',
'id' => $id,
'attributedTo' => $this->actor,
'content' => $content,
'url' => 'https://mastodon.local/users/akirk/statuses/' . ( $status_id++ ),
'published' => $date,
)
);
$response = $this->server->dispatch( $request );
$this->assertEquals( 202, $response->get_status() );
$posts = get_posts(
array(
'post_type' => \Friends\Friends::CPT,
'author' => $this->friend_id,
'post_status' => 'trash',
)
);
$this->assertEquals( $post_count + 1, count( $posts ) );
$this->assertStringStartsWith( $content, $posts[0]->post_content );
$this->assertEquals( $this->friend_id, $posts[0]->post_author );
} }
public function test_incoming_announce() { public function test_incoming_announce() {
@ -159,11 +214,10 @@ class Test_Friends_Feed_Parser_ActivityPub extends ActivityPub_TestCase_Cache_HT
$this->assertStringContainsString( 'Dezentrale Netzwerke', $posts[0]->post_content ); $this->assertStringContainsString( 'Dezentrale Netzwerke', $posts[0]->post_content );
$this->assertEquals( $this->friend_id, $posts[0]->post_author ); $this->assertEquals( $this->friend_id, $posts[0]->post_author );
$this->assertEquals( 'Matthias Pfefferle', get_post_meta( $posts[0]->ID, 'author', true ) ); $this->assertEquals( 'Matthias Pfefferle', get_post_meta( $posts[0]->ID, 'author', true ) );
} }
public function test_friend_mentions() { public function test_friend_mentions() {
add_filter( 'friends_cache_possible_mentions', '__return_false' ); add_filter( 'activitypub_cache_possible_friend_mentions', '__return_false' );
$post = \wp_insert_post( $post = \wp_insert_post(
array( array(
'post_author' => 1, 'post_author' => 1,