Start adding support for outgoing mentions
This commit is contained in:
parent
ddbcd44b6f
commit
b5c4f473de
4 changed files with 159 additions and 3 deletions
|
@ -23,17 +23,36 @@ class Activity_Dispatcher {
|
||||||
*
|
*
|
||||||
* @param \Activitypub\Model\Post $activitypub_post
|
* @param \Activitypub\Model\Post $activitypub_post
|
||||||
*/
|
*/
|
||||||
public static function send_post_activity( $activitypub_post ) {
|
public static function send_post_activity( Model\Post $activitypub_post ) {
|
||||||
// get latest version of post
|
// get latest version of post
|
||||||
$user_id = $activitypub_post->get_post_author();
|
$user_id = $activitypub_post->get_post_author();
|
||||||
|
|
||||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL );
|
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL );
|
||||||
$activitypub_activity->from_post( $activitypub_post->to_array() );
|
$activitypub_activity->from_post( $activitypub_post );
|
||||||
|
|
||||||
|
$sent = array();
|
||||||
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
|
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
|
||||||
|
$sent[ $to ] = true;
|
||||||
$activitypub_activity->set_to( $to );
|
$activitypub_activity->set_to( $to );
|
||||||
$activity = $activitypub_activity->to_json(); // phpcs:ignore
|
$activity = $activitypub_activity->to_json(); // phpcs:ignore
|
||||||
|
|
||||||
|
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
||||||
|
}
|
||||||
|
$followers_url = \get_rest_url( null, '/activitypub/1.0/users/' . intval( $user_id ) . '/followers' );
|
||||||
|
foreach ( $activitypub_activity->get_cc() as $cc ) {
|
||||||
|
if ( $cc === $followers_url ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$inbox = \Activitypub\get_inbox_by_actor( $cc );
|
||||||
|
if ( ! $inbox || \is_wp_error( $inbox ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( isset( $sent[ $cc ] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$sent[ $cc ] = true;
|
||||||
|
$activity = $activitypub_activity->to_json(); // phpcs:ignore
|
||||||
|
|
||||||
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,16 +45,24 @@ class Activity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function from_post( $object ) {
|
public function from_post( Post $post ) {
|
||||||
|
$object = apply_filters( 'activitypub_from_post_array', $post->to_array() );
|
||||||
$this->object = $object;
|
$this->object = $object;
|
||||||
|
|
||||||
if ( isset( $object['published'] ) ) {
|
if ( isset( $object['published'] ) ) {
|
||||||
$this->published = $object['published'];
|
$this->published = $object['published'];
|
||||||
}
|
}
|
||||||
|
$this->cc = array( \get_rest_url( null, '/activitypub/1.0/users/' . intval( $post->get_post_author() ) . '/followers' ) );
|
||||||
|
|
||||||
if ( isset( $object['attributedTo'] ) ) {
|
if ( isset( $object['attributedTo'] ) ) {
|
||||||
$this->actor = $object['attributedTo'];
|
$this->actor = $object['attributedTo'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$mentions = apply_filters( 'activitypub_extract_mentions', array(), $post );
|
||||||
|
foreach ( $mentions as $mention ) {
|
||||||
|
$this->cc[] = $mention;
|
||||||
|
}
|
||||||
|
|
||||||
$type = \strtolower( $this->type );
|
$type = \strtolower( $this->type );
|
||||||
|
|
||||||
if ( isset( $object['id'] ) ) {
|
if ( isset( $object['id'] ) ) {
|
||||||
|
|
97
tests/test-class-activitypub-activity-dispatcher.php
Normal file
97
tests/test-class-activitypub-activity-dispatcher.php
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
<?php
|
||||||
|
class Test_Activitypub_Activity_Dispatcher extends WP_UnitTestCase {
|
||||||
|
public static $users = array();
|
||||||
|
public function test_dispatch_mentions() {
|
||||||
|
$post = \wp_insert_post(
|
||||||
|
array(
|
||||||
|
'post_author' => 1,
|
||||||
|
'post_content' => '@alex hello',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
self::$users['https://example.com/alex'] = array(
|
||||||
|
'url' => 'https://example.com/alex',
|
||||||
|
'inbox' => 'https://example.com/alex/inbox',
|
||||||
|
'name' => 'alex',
|
||||||
|
);
|
||||||
|
|
||||||
|
add_filter(
|
||||||
|
'activitypub_extract_mentions',
|
||||||
|
function( $mentions ) {
|
||||||
|
$mentions[] = 'https://example.com/alex';
|
||||||
|
return $mentions;
|
||||||
|
},
|
||||||
|
10
|
||||||
|
);
|
||||||
|
|
||||||
|
$pre_http_request = new MockAction();
|
||||||
|
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||||
|
|
||||||
|
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||||
|
\Activitypub\Activity_Dispatcher::send_post_activity( $activitypub_post );
|
||||||
|
|
||||||
|
$this->assertSame( 1, $pre_http_request->get_call_count() );
|
||||||
|
$all_args = $pre_http_request->get_args();
|
||||||
|
$first_call_args = $all_args[0];
|
||||||
|
$this->assertEquals( 'https://example.com/alex/inbox', $first_call_args[2] );
|
||||||
|
|
||||||
|
remove_all_filters( 'activitypub_from_post_object' );
|
||||||
|
remove_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_up() {
|
||||||
|
parent::set_up();
|
||||||
|
|
||||||
|
add_filter( 'pre_http_request', array( get_called_class(), 'pre_http_request' ), 10, 3 );
|
||||||
|
add_filter( 'http_response', array( get_called_class(), 'http_response' ), 10, 3 );
|
||||||
|
add_filter( 'http_request_host_is_external', array( get_called_class(), 'http_request_host_is_external' ), 10, 2 );
|
||||||
|
add_filter( 'http_request_args', array( get_called_class(), 'http_request_args' ), 10, 2 );
|
||||||
|
add_filter( 'pre_get_remote_metadata_by_actor', array( get_called_class(), 'pre_get_remote_metadata_by_actor' ), 10, 2 );
|
||||||
|
|
||||||
|
_delete_all_posts();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tear_down() {
|
||||||
|
remove_filter( 'pre_http_request', array( get_called_class(), 'pre_http_request' ) );
|
||||||
|
remove_filter( 'http_response', array( get_called_class(), 'http_response' ) );
|
||||||
|
remove_filter( 'http_request_host_is_external', array( get_called_class(), 'http_request_host_is_external' ) );
|
||||||
|
remove_filter( 'http_request_args', array( get_called_class(), 'http_request_args' ) );
|
||||||
|
remove_filter( 'pre_get_remote_metadata_by_actor', array( get_called_class(), 'pre_get_remote_metadata_by_actor' ) );
|
||||||
|
parent::tear_down();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function pre_get_remote_metadata_by_actor( $pre, $actor ) {
|
||||||
|
if ( isset( self::$users[ $actor ] ) ) {
|
||||||
|
return self::$users[ $actor ];
|
||||||
|
}
|
||||||
|
return $pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function http_request_host_is_external( $in, $host ) {
|
||||||
|
if ( in_array( $host, array( 'example.com', 'example.org' ), true ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return $in;
|
||||||
|
}
|
||||||
|
public static function http_request_args( $args, $url ) {
|
||||||
|
if ( in_array( parse_url( $url, PHP_URL_HOST ), array( 'example.com', 'example.org' ), true ) ) {
|
||||||
|
$args['reject_unsafe_urls'] = false;
|
||||||
|
}
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
public static function pre_http_request( $preempt, $request, $url ) {
|
||||||
|
return array(
|
||||||
|
'headers' => array(
|
||||||
|
'content-type' => 'text/json',
|
||||||
|
),
|
||||||
|
'body' => '',
|
||||||
|
'response' => array(
|
||||||
|
'code' => 202,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function http_response( $response, $args, $url ) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
32
tests/test-class-activitypub-activity.php
Normal file
32
tests/test-class-activitypub-activity.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
class Test_Activitypub_Activity extends WP_UnitTestCase {
|
||||||
|
public function test_activity_mentions() {
|
||||||
|
$post = \wp_insert_post(
|
||||||
|
array(
|
||||||
|
'post_author' => 1,
|
||||||
|
'post_content' => '@alex hello',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
add_filter(
|
||||||
|
'activitypub_extract_mentions',
|
||||||
|
function( $mentions, $post ) {
|
||||||
|
$mentions[] = 'https://example.com/alex';
|
||||||
|
return $mentions;
|
||||||
|
},
|
||||||
|
10,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
|
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||||
|
|
||||||
|
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL );
|
||||||
|
$activitypub_activity->from_post( $activitypub_post );
|
||||||
|
|
||||||
|
$this->assertContains( \get_rest_url( null, '/activitypub/1.0/users/1/followers' ), $activitypub_activity->get_cc() );
|
||||||
|
$this->assertContains( 'https://example.com/alex', $activitypub_activity->get_cc() );
|
||||||
|
|
||||||
|
remove_all_filters( 'activitypub_from_post_object' );
|
||||||
|
\wp_trash_post( $post );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue