From e015da7f8f258d193ce1950e14be3123a44aee5a Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Feb 2023 01:42:15 +0100 Subject: [PATCH 01/14] optimize publishing --- includes/class-activity-dispatcher.php | 78 +++++++++----------------- includes/class-activitypub.php | 2 +- includes/functions.php | 5 +- includes/model/class-activity.php | 17 +++++- includes/model/class-post.php | 2 +- 5 files changed, 48 insertions(+), 56 deletions(-) diff --git a/includes/class-activity-dispatcher.php b/includes/class-activity-dispatcher.php index f8abd38..09fca79 100644 --- a/includes/class-activity-dispatcher.php +++ b/includes/class-activity-dispatcher.php @@ -13,7 +13,10 @@ class Activity_Dispatcher { * Initialize the class, registering WordPress hooks. */ public static function init() { - \add_action( 'activitypub_send_post_activity', array( '\Activitypub\Activity_Dispatcher', 'send_post_activity' ) ); + // legacy + \add_action( 'activitypub_send_post_activity', array( '\Activitypub\Activity_Dispatcher', 'send_create_activity' ) ); + + \add_action( 'activitypub_send_create_activity', array( '\Activitypub\Activity_Dispatcher', 'send_create_activity' ) ); \add_action( 'activitypub_send_update_activity', array( '\Activitypub\Activity_Dispatcher', 'send_update_activity' ) ); \add_action( 'activitypub_send_delete_activity', array( '\Activitypub\Activity_Dispatcher', 'send_delete_activity' ) ); } @@ -23,38 +26,8 @@ class Activity_Dispatcher { * * @param \Activitypub\Model\Post $activitypub_post */ - public static function send_post_activity( Model\Post $activitypub_post ) { - // get latest version of post - $user_id = $activitypub_post->get_post_author(); - - $activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL ); - $activitypub_activity->from_post( $activitypub_post ); - - $inboxes = \Activitypub\get_follower_inboxes( $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; - } - // init array if empty - if ( ! isset( $inboxes[ $inbox ] ) ) { - $inboxes[ $inbox ] = array(); - } - $inboxes[ $inbox ][] = $cc; - } - - foreach ( $inboxes as $inbox => $to ) { - $to = array_values( array_unique( $to ) ); - $activitypub_activity->set_to( $to ); - $activity = $activitypub_activity->to_json(); - - \Activitypub\safe_remote_post( $inbox, $activity, $user_id ); - } + public static function send_create_activity( Model\Post $activitypub_post ) { + self::send_activity( $activitypub_post, 'Create' ); } /** @@ -62,19 +35,8 @@ class Activity_Dispatcher { * * @param \Activitypub\Model\Post $activitypub_post */ - public static function send_update_activity( $activitypub_post ) { - // get latest version of post - $user_id = $activitypub_post->get_post_author(); - - $activitypub_activity = new \Activitypub\Model\Activity( 'Update', \Activitypub\Model\Activity::TYPE_FULL ); - $activitypub_activity->from_post( $activitypub_post ); - - foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) { - $activitypub_activity->set_to( $to ); - $activity = $activitypub_activity->to_json(); // phpcs:ignore - - \Activitypub\safe_remote_post( $inbox, $activity, $user_id ); - } + public static function send_update_activity( Model\Post $activitypub_post ) { + self::send_activity( $activitypub_post, 'Update' ); } /** @@ -82,16 +44,30 @@ class Activity_Dispatcher { * * @param \Activitypub\Model\Post $activitypub_post */ - public static function send_delete_activity( $activitypub_post ) { + public static function send_delete_activity( Model\Post $activitypub_post ) { + self::send_activity( $activitypub_post, 'Delete' ); + } + + /** + * Undocumented function + * + * @param [type] $activitypub_post + * @param [type] $activity_type + * @return void + */ + public function send_activity( Model\Post $activitypub_post, $activity_type ) { // get latest version of post $user_id = $activitypub_post->get_post_author(); - $activitypub_activity = new \Activitypub\Model\Activity( 'Delete', \Activitypub\Model\Activity::TYPE_FULL ); + $activitypub_activity = new \Activitypub\Model\Activity( $activity_type, \Activitypub\Model\Activity::TYPE_FULL ); $activitypub_activity->from_post( $activitypub_post ); - foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) { - $activitypub_activity->set_to( $to ); - $activity = $activitypub_activity->to_json(); // phpcs:ignore + $inboxes = \Activitypub\get_follower_inboxes( $user_id, $activitypub_activity->get_cc() ); + + foreach ( $inboxes as $inbox => $cc ) { + $cc = array_values( array_unique( $cc ) ); + $activitypub_activity->add_cc( $cc ); + $activity = $activitypub_activity->to_json(); \Activitypub\safe_remote_post( $inbox, $activity, $user_id ); } diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index c04aedc..4a60915 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -117,7 +117,7 @@ class Activitypub { $activitypub_post = new \Activitypub\Model\Post( $post ); if ( 'publish' === $new_status && 'publish' !== $old_status ) { - \wp_schedule_single_event( \time(), 'activitypub_send_post_activity', array( $activitypub_post ) ); + \wp_schedule_single_event( \time(), 'activitypub_send_create_activity', array( $activitypub_post ) ); } elseif ( 'publish' === $new_status ) { \wp_schedule_single_event( \time(), 'activitypub_send_update_activity', array( $activitypub_post ) ); } elseif ( 'trash' === $new_status ) { diff --git a/includes/functions.php b/includes/functions.php index 8f2e5d9..77508c5 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -219,8 +219,11 @@ function get_publickey_by_actor( $actor, $key_id ) { return new \WP_Error( 'activitypub_no_public_key', \__( 'No "Public-Key" found', 'activitypub' ), $metadata ); } -function get_follower_inboxes( $user_id ) { +function get_follower_inboxes( $user_id, $cc = array() ) { $followers = \Activitypub\Peer\Followers::get_followers( $user_id ); + $followers = array_merge( $followers, $cc ); + $followers = array_unique( $followers ); + $inboxes = array(); foreach ( $followers as $follower ) { diff --git a/includes/model/class-activity.php b/includes/model/class-activity.php index f865d6d..c95e6ff 100644 --- a/includes/model/class-activity.php +++ b/includes/model/class-activity.php @@ -43,6 +43,18 @@ class Activity { if ( \strncasecmp( $method, 'set', 3 ) === 0 ) { $this->$var = $params[0]; } + + if ( \strncasecmp( $method, 'add', 3 ) === 0 ) { + if ( ! is_array( $this->$var ) ) { + $this->$var = $params[0]; + } + + if ( is_array( $params[0] ) ) { + $this->$var = array_merge( $this->$var, $params[0] ); + } else { + array_push( $this->$var, $params[0] ); + } + } } public function from_post( Post $post ) { @@ -51,7 +63,8 @@ class Activity { if ( isset( $object['published'] ) ) { $this->published = $object['published']; } - $this->cc = array( \get_rest_url( null, '/activitypub/1.0/users/' . intval( $post->get_post_author() ) . '/followers' ) ); + + $this->add_to( \get_rest_url( null, '/activitypub/1.0/users/' . intval( $post->get_post_author() ) . '/followers' ) ); if ( isset( $this->object['attributedTo'] ) ) { $this->actor = $this->object['attributedTo']; @@ -59,7 +72,7 @@ class Activity { foreach ( $post->get_tags() as $tag ) { if ( 'Mention' === $tag['type'] ) { - $this->cc[] = $tag['href']; + $this->add_cc( $tag['href'] ); } } diff --git a/includes/model/class-post.php b/includes/model/class-post.php index 543a890..5d2ac48 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -386,7 +386,7 @@ class Post { $filtered_content = \apply_filters( 'activitypub_the_content', $content, $post ); $decoded_content = \html_entity_decode( $filtered_content, \ENT_QUOTES, 'UTF-8' ); - $content = \trim( \preg_replace( '/[\n\r]/', '', $content ) ); + $content = \trim( \preg_replace( '/[\n\r\t]/', '', $content ) ); $this->content = $content; From 472ee27849c561b241caac44cb04bdb827768abf Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Feb 2023 01:47:12 +0100 Subject: [PATCH 02/14] fix unit tests --- tests/test-class-activitypub-activity-dispatcher.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-class-activitypub-activity-dispatcher.php b/tests/test-class-activitypub-activity-dispatcher.php index 6693ba1..ec62b2d 100644 --- a/tests/test-class-activitypub-activity-dispatcher.php +++ b/tests/test-class-activitypub-activity-dispatcher.php @@ -28,7 +28,7 @@ class Test_Activitypub_Activity_Dispatcher extends ActivityPub_TestCase_Cache_HT 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 ); + \Activitypub\Activity_Dispatcher::send_create_activity( $activitypub_post ); $this->assertSame( 2, $pre_http_request->get_call_count() ); $all_args = $pre_http_request->get_args(); @@ -67,7 +67,7 @@ class Test_Activitypub_Activity_Dispatcher extends ActivityPub_TestCase_Cache_HT 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 ); + \Activitypub\Activity_Dispatcher::send_create_activity( $activitypub_post ); $this->assertSame( 1, $pre_http_request->get_call_count() ); $all_args = $pre_http_request->get_args(); From 3c84be1691b7388e57d942911c0973671a0309c4 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Feb 2023 01:50:20 +0100 Subject: [PATCH 03/14] fix unit tests --- includes/class-activity-dispatcher.php | 2 +- tests/test-class-activitypub-activity.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-activity-dispatcher.php b/includes/class-activity-dispatcher.php index 09fca79..221e2b0 100644 --- a/includes/class-activity-dispatcher.php +++ b/includes/class-activity-dispatcher.php @@ -55,7 +55,7 @@ class Activity_Dispatcher { * @param [type] $activity_type * @return void */ - public function send_activity( Model\Post $activitypub_post, $activity_type ) { + public static function send_activity( Model\Post $activitypub_post, $activity_type ) { // get latest version of post $user_id = $activitypub_post->get_post_author(); diff --git a/tests/test-class-activitypub-activity.php b/tests/test-class-activitypub-activity.php index 254d860..74d0727 100644 --- a/tests/test-class-activitypub-activity.php +++ b/tests/test-class-activitypub-activity.php @@ -22,7 +22,7 @@ class Test_Activitypub_Activity extends WP_UnitTestCase { $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( \get_rest_url( null, '/activitypub/1.0/users/1/followers' ), $activitypub_activity->get_to() ); $this->assertContains( 'https://example.com/alex', $activitypub_activity->get_cc() ); remove_all_filters( 'activitypub_extract_mentions' ); From e52181fd3733b6b9b126f5ce046bbe10207ea312 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Feb 2023 02:04:06 +0100 Subject: [PATCH 04/14] fix tests --- includes/model/class-activity.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/includes/model/class-activity.php b/includes/model/class-activity.php index c95e6ff..220541e 100644 --- a/includes/model/class-activity.php +++ b/includes/model/class-activity.php @@ -15,7 +15,7 @@ class Activity { private $type = 'Create'; private $actor = ''; private $to = array( 'https://www.w3.org/ns/activitystreams#Public' ); - private $cc = array( 'https://www.w3.org/ns/activitystreams#Public' ); + private $cc = array(); private $object = null; const TYPE_SIMPLE = 'simple'; @@ -54,6 +54,8 @@ class Activity { } else { array_push( $this->$var, $params[0] ); } + + $this->$var = array_unique( $this->$var ); } } From 365d5dd4997c22d7e6c2ef14a8e68e5a0bd36f7d Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Feb 2023 02:35:57 +0100 Subject: [PATCH 05/14] fix outbox --- includes/rest/class-outbox.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/rest/class-outbox.php b/includes/rest/class-outbox.php index 7eec5ac..677e2ff 100644 --- a/includes/rest/class-outbox.php +++ b/includes/rest/class-outbox.php @@ -102,8 +102,8 @@ class Outbox { foreach ( $posts as $post ) { $activitypub_post = new \Activitypub\Model\Post( $post ); - $activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_NONE ); - $activitypub_activity->from_post( $activitypub_post->to_array() ); + $activitypub_activity = new \Activitypub\Model\Activity( 'Create', false ); + $activitypub_activity->from_post( $activitypub_post ); $json->orderedItems[] = $activitypub_activity->to_array(); // phpcs:ignore } } From de32cb7b7320bfa6fac5603ea7978059c1e83579 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Feb 2023 02:36:29 +0100 Subject: [PATCH 06/14] add changes also to the object --- includes/class-activity-dispatcher.php | 2 +- includes/model/class-activity.php | 32 ++++++++++++++++------- includes/model/class-post.php | 22 ++++++++++++++-- includes/rest/class-inbox.php | 2 +- tests/test-class-activitypub-activity.php | 2 +- 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/includes/class-activity-dispatcher.php b/includes/class-activity-dispatcher.php index 221e2b0..6df83e7 100644 --- a/includes/class-activity-dispatcher.php +++ b/includes/class-activity-dispatcher.php @@ -59,7 +59,7 @@ class Activity_Dispatcher { // get latest version of post $user_id = $activitypub_post->get_post_author(); - $activitypub_activity = new \Activitypub\Model\Activity( $activity_type, \Activitypub\Model\Activity::TYPE_FULL ); + $activitypub_activity = new \Activitypub\Model\Activity( $activity_type ); $activitypub_activity->from_post( $activitypub_post ); $inboxes = \Activitypub\get_follower_inboxes( $user_id, $activitypub_activity->get_cc() ); diff --git a/includes/model/class-activity.php b/includes/model/class-activity.php index 220541e..34f6146 100644 --- a/includes/model/class-activity.php +++ b/includes/model/class-activity.php @@ -9,7 +9,27 @@ namespace Activitypub\Model; * @see https://www.w3.org/TR/activitypub/ */ class Activity { - private $context = array( 'https://www.w3.org/ns/activitystreams' ); + private $context = array( + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + array( + 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', + 'PropertyValue' => 'schema:PropertyValue', + 'schema' => 'http://schema.org#', + 'pt' => 'https://joinpeertube.org/ns#', + 'toot' => 'http://joinmastodon.org/ns#', + 'value' => 'schema:value', + 'Hashtag' => 'as:Hashtag', + 'featured' => array( + '@id' => 'toot:featured', + '@type' => '@id', + ), + 'featuredTags' => array( + '@id' => 'toot:featuredTags', + '@type' => '@id', + ), + ), + ); private $published = ''; private $id = ''; private $type = 'Create'; @@ -18,15 +38,9 @@ class Activity { private $cc = array(); private $object = null; - const TYPE_SIMPLE = 'simple'; - const TYPE_FULL = 'full'; - const TYPE_NONE = 'none'; - - public function __construct( $type = 'Create', $context = self::TYPE_SIMPLE ) { - if ( 'none' === $context ) { + public function __construct( $type = 'Create', $context = true ) { + if ( true !== $context ) { $this->context = null; - } elseif ( 'full' === $context ) { - $this->context = \Activitypub\get_context(); } $this->type = \ucfirst( $type ); diff --git a/includes/model/class-post.php b/includes/model/class-post.php index 5d2ac48..90f19ef 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -87,6 +87,9 @@ class Post { ), ); + private $to = array( 'https://www.w3.org/ns/activitystreams#Public' ); + private $cc = array(); + /** * Constructor * @@ -94,6 +97,7 @@ class Post { */ public function __construct( $post ) { $this->post = \get_post( $post ); + $this->add_to( \get_rest_url( null, '/activitypub/1.0/users/' . intval( $this->get_post_author() ) . '/followers' ) ); } /** @@ -117,6 +121,20 @@ class Post { if ( \strncasecmp( $method, 'set', 3 ) === 0 ) { $this->$var = $params[0]; } + + if ( \strncasecmp( $method, 'add', 3 ) === 0 ) { + if ( ! is_array( $this->$var ) ) { + $this->$var = $params[0]; + } + + if ( is_array( $params[0] ) ) { + $this->$var = array_merge( $this->$var, $params[0] ); + } else { + array_push( $this->$var, $params[0] ); + } + + $this->$var = array_unique( $this->$var ); + } } /** @@ -138,8 +156,8 @@ class Post { 'contentMap' => array( \strstr( \get_locale(), '_', true ) => $this->get_content(), ), - 'to' => array( 'https://www.w3.org/ns/activitystreams#Public' ), - 'cc' => array( 'https://www.w3.org/ns/activitystreams#Public' ), + 'to' => $this->get_to(), + 'cc' => $this->get_cc(), 'attachment' => $this->get_attachments(), 'tag' => $this->get_tags(), ); diff --git a/includes/rest/class-inbox.php b/includes/rest/class-inbox.php index 5c21f43..1eab8a5 100644 --- a/includes/rest/class-inbox.php +++ b/includes/rest/class-inbox.php @@ -356,7 +356,7 @@ class Inbox { $inbox = \Activitypub\get_inbox_by_actor( $object['actor'] ); // send "Accept" activity - $activity = new \Activitypub\Model\Activity( 'Accept', \Activitypub\Model\Activity::TYPE_SIMPLE ); + $activity = new \Activitypub\Model\Activity( 'Accept' ); $activity->set_object( $object ); $activity->set_actor( \get_author_posts_url( $user_id ) ); $activity->set_to( $object['actor'] ); diff --git a/tests/test-class-activitypub-activity.php b/tests/test-class-activitypub-activity.php index 74d0727..7fe6551 100644 --- a/tests/test-class-activitypub-activity.php +++ b/tests/test-class-activitypub-activity.php @@ -19,7 +19,7 @@ class Test_Activitypub_Activity extends WP_UnitTestCase { $activitypub_post = new \Activitypub\Model\Post( $post ); - $activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL ); + $activitypub_activity = new \Activitypub\Model\Activity( 'Create' ); $activitypub_activity->from_post( $activitypub_post ); $this->assertContains( \get_rest_url( null, '/activitypub/1.0/users/1/followers' ), $activitypub_activity->get_to() ); From 73ae47e37729047088bb34dbff618ca76468b3c8 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Feb 2023 07:24:27 +0100 Subject: [PATCH 07/14] PHPDoc --- includes/model/class-post.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/includes/model/class-post.php b/includes/model/class-post.php index 90f19ef..0929277 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -87,7 +87,22 @@ class Post { ), ); + /** + * List of audience + * + * Also used for visibility + * + * @var array + */ private $to = array( 'https://www.w3.org/ns/activitystreams#Public' ); + + /** + * List of audience + * + * Also used for visibility + * + * @var array + */ private $cc = array(); /** From 3c367f8eb19b421b61799217b1aa2db97a6857f7 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Wed, 15 Mar 2023 17:50:22 +0100 Subject: [PATCH 08/14] remove shortcodes that might confuse people --- templates/settings.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/templates/settings.php b/templates/settings.php index 97e7e4d..2bfaed4 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -65,8 +65,6 @@
  • [ap_permalink] -
  • [ap_shortlink] - Hum.', 'activitypub' ), 'default' ); ?>
  • [ap_hashtags] -
  • -
  • [ap_hashcats] -
  • -
  • [ap_image] -
  • From becef59452405424db02af0e56579e9fce39f0c5 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Sat, 18 Mar 2023 21:59:09 +0100 Subject: [PATCH 09/14] improve readme thanks a lot @cavalierlife --- README.md | 62 ++++++++++++++++++++++++++++++++++++++---------------- readme.txt | 62 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 969f562..7b394c1 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ The ActivityPub protocol is a decentralized social networking protocol based upo ## Description ## -This is **BETA** software, see the FAQ to see the current feature set or rather what is still planned. +This is BETA software, see the FAQ to see the current feature set or rather what is still planned. -The plugin implements the ActivityPub protocol for your blog. Your readers will be able to follow your blogposts on Mastodon and other federated platforms that support ActivityPub. +The plugin implements the ActivityPub protocol for your blog, which means that your readers will be able to follow your blog posts on Mastodon and other federated platforms that support ActivityPub. In addition, replies to your posts on Mastodon and related platforms will automatically become comments on your blog post. -The plugin works with the following federated platforms: +The plugin works with the following tested federated platforms, but there may be more that it works with as well: * [Mastodon](https://joinmastodon.org/) * [Pleroma](https://pleroma.social/) @@ -26,8 +26,44 @@ The plugin works with the following federated platforms: * [SocialHome](https://socialhome.network/) * [Misskey](https://join.misskey.page/) +Here’s what that means and what you can expect. + +Once the ActivityPub plugin is installed, each author’s page on your WordPress blog will become its own federated instance. In other words, if you have two authors, Jane and Bob, on your website, `example.com`, then your authors would have their own author pages at `example.com/author/jane` and `example.com/author/bob`. Each of those author pages would now be available to Mastodon users (and all other federated platform users) as a profile that can be followed. Let’s break that down further. Let’s say you have a friend on Mastodon who tells you to follow them and they give you their profile name `@janelivesheresomeofthetime@mastodon.social`. You search for her name, see her profile, and click the follow button, right? From then on, everything Jane posts on her profile shows up in your Home feed. Okay, similarly, now that Jane has installed the ActivityPub plugin on her `example.com` site, her friends can also follow her on Mastodon by searching for `@jane@example.com` and clicking the Follow button on that profile. + +From now on, every blog post Jane publishes on example.com will show up on your Home feed because you follow her `@jane@example.com` profile. +Of course, if no one follows your author instance, then no one will ever see the posts - including you! So the easiest way to even know if the plugin is working is to follow your new profile yourself. If you already have a Mastodon profile, just follow your new one from there. + +Some things to note: + + 1. Many single-author blogs have chosen to turn off or redirect their author profile pages, usually via an SEO plugin like Yoast or Rank Math. This is usually done to avoid duplicate content with your blog’s home page. If your author page has been deactivated in this way, then ActivityPub won’t work for you. Instead, you can turn your author profile page back on, and then use the option in your SEO plugin to noindex the author page. This will enable the page to be live and ActivityPub will now work, but the live page won’t cause any duplicate content issues with search engines. + 2. Once ActivityPub is installed, only new posts going forward will be available in the fediverse. Likewise, even if you’ve been using ActivityPub for a while, anyone who follows your site, will only see new posts you publish from that moment on. They will never see previously-published posts in their Home feed. This process is very similar to subscribing to a newsletter. If you subscribe to a newsletter, you will only receive future emails, but not the old archived ones. With ActivityPub, if someone follows your site, they will only receive new blog posts you publish from then on. + +So what’s the process? + + 1. Install the ActivityPub plugin. + 2. Go to the plugin’s settings page and adjust the settings to your liking. Click the Save button when ready. + 3. Make sure your blog’s author profile page is active. + 4. Go to Mastodon or any other federated platform, search for your author’s new federated profile, and follow it. Your new profile will be in the form of @yourauthorname@yourwebsite.com, so that is what you’ll search for. + 5. On your blog, publish a new post. + 6. From Mastodon, check to see if the new post appears in your Home feed. + +Please note that it may take up to 15 minutes or so for the new post to show up in your federated feed. This is because the messages are sent to the federated platforms using a delayed cron. This avoids breaking the publishing process for those cases where users might have lots of followers. So please don’t assume that just because you didn’t see it show up right away that something is broken. Give it some time. In most cases, it will show up within a few minutes, and you’ll know everything is working as expected. + ## Frequently Asked Questions ## +### tl;dr ### + +This plugin connects your WordPress blog to popular social platforms like Mastodon, making your posts more accessible to a wider audience. Once installed, your blog's author pages can be followed by users on these platforms, allowing them to receive your new posts in their feeds. + +Here's how it works: + + 1. Install the plugin and adjust settings as needed. + 2. Ensure your blog's author profile page is active. + 3. On Mastodon or other supported platforms, search for and follow your author's new profile (e.g., `@yourauthorname@yourwebsite.com`). + 4. Publish a new post on your blog and check if it appears in your Mastodon feed. + +Please note that it may take up to 15 minutes for a new post to appear in your feed, as messages are sent on a delay to avoid overwhelming your followers. Be patient and give it some time. + ### What is the status of this plugin? ### Implemented: @@ -50,16 +86,6 @@ To implement: *ActivityPub for WordPress* extends WordPress with some Fediverse features, but it does not compete with platforms like Friendica or Mastodon. If you want to run a **decentralized social network**, please use [Mastodon](https://joinmastodon.org/) or [GNU social](https://gnusocial.network/). -### What are the differences between this plugin and Pterotype? ### - -**Compatibility** - -*ActivityPub for WordPress* is compatible with OStatus and IndieWeb plugin suites. *Pterotype* is incompatible with the standalone [WebFinger plugin](https://wordpress.org/plugins/webfinger/), so it can't be run together with OStatus. - -**Custom tables** - -*Pterotype* creates/uses a bunch of custom tables, *ActivityPub for WordPress* only uses the native tables and adds as little meta data as possible. - ### What if you are running your blog in a subdirectory? ### In order for webfinger to work, it must be mapped to the root directory of the URL on which your blog resides. @@ -356,12 +382,12 @@ Follow the normal instructions for [installing WordPress plugins](https://wordpr To add a WordPress Plugin using the [built-in plugin installer](https://codex.wordpress.org/Administration_Screens#Add_New_Plugins): 1. Go to [Plugins](https://codex.wordpress.org/Administration_Screens#Plugins) > [Add New](https://codex.wordpress.org/Plugins_Add_New_Screen). -1. Type "`activitypub`" into the **Search Plugins** box. -1. Find the WordPress Plugin you wish to install. +2. Type "`activitypub`" into the **Search Plugins** box. +3. Find the WordPress Plugin you wish to install. 1. Click **Details** for more information about the Plugin and instructions you may wish to print or save to help setup the Plugin. - 1. Click **Install Now** to install the WordPress Plugin. -1. The resulting installation screen will list the installation as successful or note any problems during the install. -1. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. + 2. Click **Install Now** to install the WordPress Plugin. +4. The resulting installation screen will list the installation as successful or note any problems during the install. +5. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. ### Manual Plugin Installation ### diff --git a/readme.txt b/readme.txt index 63e1f6a..d47f644 100644 --- a/readme.txt +++ b/readme.txt @@ -12,11 +12,11 @@ The ActivityPub protocol is a decentralized social networking protocol based upo == Description == -This is **BETA** software, see the FAQ to see the current feature set or rather what is still planned. +This is BETA software, see the FAQ to see the current feature set or rather what is still planned. -The plugin implements the ActivityPub protocol for your blog. Your readers will be able to follow your blogposts on Mastodon and other federated platforms that support ActivityPub. +The plugin implements the ActivityPub protocol for your blog, which means that your readers will be able to follow your blog posts on Mastodon and other federated platforms that support ActivityPub. In addition, replies to your posts on Mastodon and related platforms will automatically become comments on your blog post. -The plugin works with the following federated platforms: +The plugin works with the following tested federated platforms, but there may be more that it works with as well: * [Mastodon](https://joinmastodon.org/) * [Pleroma](https://pleroma.social/) @@ -26,8 +26,44 @@ The plugin works with the following federated platforms: * [SocialHome](https://socialhome.network/) * [Misskey](https://join.misskey.page/) +Here’s what that means and what you can expect. + +Once the ActivityPub plugin is installed, each author’s page on your WordPress blog will become its own federated instance. In other words, if you have two authors, Jane and Bob, on your website, `example.com`, then your authors would have their own author pages at `example.com/author/jane` and `example.com/author/bob`. Each of those author pages would now be available to Mastodon users (and all other federated platform users) as a profile that can be followed. Let’s break that down further. Let’s say you have a friend on Mastodon who tells you to follow them and they give you their profile name `@janelivesheresomeofthetime@mastodon.social`. You search for her name, see her profile, and click the follow button, right? From then on, everything Jane posts on her profile shows up in your Home feed. Okay, similarly, now that Jane has installed the ActivityPub plugin on her `example.com` site, her friends can also follow her on Mastodon by searching for `@jane@example.com` and clicking the Follow button on that profile. + +From now on, every blog post Jane publishes on example.com will show up on your Home feed because you follow her `@jane@example.com` profile. +Of course, if no one follows your author instance, then no one will ever see the posts - including you! So the easiest way to even know if the plugin is working is to follow your new profile yourself. If you already have a Mastodon profile, just follow your new one from there. + +Some things to note: + + 1. Many single-author blogs have chosen to turn off or redirect their author profile pages, usually via an SEO plugin like Yoast or Rank Math. This is usually done to avoid duplicate content with your blog’s home page. If your author page has been deactivated in this way, then ActivityPub won’t work for you. Instead, you can turn your author profile page back on, and then use the option in your SEO plugin to noindex the author page. This will enable the page to be live and ActivityPub will now work, but the live page won’t cause any duplicate content issues with search engines. + 2. Once ActivityPub is installed, only new posts going forward will be available in the fediverse. Likewise, even if you’ve been using ActivityPub for a while, anyone who follows your site, will only see new posts you publish from that moment on. They will never see previously-published posts in their Home feed. This process is very similar to subscribing to a newsletter. If you subscribe to a newsletter, you will only receive future emails, but not the old archived ones. With ActivityPub, if someone follows your site, they will only receive new blog posts you publish from then on. + +So what’s the process? + + 1. Install the ActivityPub plugin. + 2. Go to the plugin’s settings page and adjust the settings to your liking. Click the Save button when ready. + 3. Make sure your blog’s author profile page is active. + 4. Go to Mastodon or any other federated platform, search for your author’s new federated profile, and follow it. Your new profile will be in the form of @yourauthorname@yourwebsite.com, so that is what you’ll search for. + 5. On your blog, publish a new post. + 6. From Mastodon, check to see if the new post appears in your Home feed. + +Please note that it may take up to 15 minutes or so for the new post to show up in your federated feed. This is because the messages are sent to the federated platforms using a delayed cron. This avoids breaking the publishing process for those cases where users might have lots of followers. So please don’t assume that just because you didn’t see it show up right away that something is broken. Give it some time. In most cases, it will show up within a few minutes, and you’ll know everything is working as expected. + == Frequently Asked Questions == += tl;dr = + +This plugin connects your WordPress blog to popular social platforms like Mastodon, making your posts more accessible to a wider audience. Once installed, your blog's author pages can be followed by users on these platforms, allowing them to receive your new posts in their feeds. + +Here's how it works: + + 1. Install the plugin and adjust settings as needed. + 2. Ensure your blog's author profile page is active. + 3. On Mastodon or other supported platforms, search for and follow your author's new profile (e.g., `@yourauthorname@yourwebsite.com`). + 4. Publish a new post on your blog and check if it appears in your Mastodon feed. + +Please note that it may take up to 15 minutes for a new post to appear in your feed, as messages are sent on a delay to avoid overwhelming your followers. Be patient and give it some time. + = What is the status of this plugin? = Implemented: @@ -50,16 +86,6 @@ To implement: *ActivityPub for WordPress* extends WordPress with some Fediverse features, but it does not compete with platforms like Friendica or Mastodon. If you want to run a **decentralized social network**, please use [Mastodon](https://joinmastodon.org/) or [GNU social](https://gnusocial.network/). -= What are the differences between this plugin and Pterotype? = - -**Compatibility** - -*ActivityPub for WordPress* is compatible with OStatus and IndieWeb plugin suites. *Pterotype* is incompatible with the standalone [WebFinger plugin](https://wordpress.org/plugins/webfinger/), so it can't be run together with OStatus. - -**Custom tables** - -*Pterotype* creates/uses a bunch of custom tables, *ActivityPub for WordPress* only uses the native tables and adds as little meta data as possible. - = What if you are running your blog in a subdirectory? = In order for webfinger to work, it must be mapped to the root directory of the URL on which your blog resides. @@ -356,12 +382,12 @@ Follow the normal instructions for [installing WordPress plugins](https://wordpr To add a WordPress Plugin using the [built-in plugin installer](https://codex.wordpress.org/Administration_Screens#Add_New_Plugins): 1. Go to [Plugins](https://codex.wordpress.org/Administration_Screens#Plugins) > [Add New](https://codex.wordpress.org/Plugins_Add_New_Screen). -1. Type "`activitypub`" into the **Search Plugins** box. -1. Find the WordPress Plugin you wish to install. +2. Type "`activitypub`" into the **Search Plugins** box. +3. Find the WordPress Plugin you wish to install. 1. Click **Details** for more information about the Plugin and instructions you may wish to print or save to help setup the Plugin. - 1. Click **Install Now** to install the WordPress Plugin. -1. The resulting installation screen will list the installation as successful or note any problems during the install. -1. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. + 2. Click **Install Now** to install the WordPress Plugin. +4. The resulting installation screen will list the installation as successful or note any problems during the install. +5. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. = Manual Plugin Installation = From 70fe654c95624ec6fd0c50ad1c63116ac4597f67 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Sun, 19 Mar 2023 08:42:33 +0100 Subject: [PATCH 10/14] fix ordered lists --- README.md | 34 +++++++++++++++++----------------- readme.txt | 34 +++++++++++++++++----------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 7b394c1..d1b4461 100644 --- a/README.md +++ b/README.md @@ -35,17 +35,17 @@ Of course, if no one follows your author instance, then no one will ever see the Some things to note: - 1. Many single-author blogs have chosen to turn off or redirect their author profile pages, usually via an SEO plugin like Yoast or Rank Math. This is usually done to avoid duplicate content with your blog’s home page. If your author page has been deactivated in this way, then ActivityPub won’t work for you. Instead, you can turn your author profile page back on, and then use the option in your SEO plugin to noindex the author page. This will enable the page to be live and ActivityPub will now work, but the live page won’t cause any duplicate content issues with search engines. - 2. Once ActivityPub is installed, only new posts going forward will be available in the fediverse. Likewise, even if you’ve been using ActivityPub for a while, anyone who follows your site, will only see new posts you publish from that moment on. They will never see previously-published posts in their Home feed. This process is very similar to subscribing to a newsletter. If you subscribe to a newsletter, you will only receive future emails, but not the old archived ones. With ActivityPub, if someone follows your site, they will only receive new blog posts you publish from then on. +1. Many single-author blogs have chosen to turn off or redirect their author profile pages, usually via an SEO plugin like Yoast or Rank Math. This is usually done to avoid duplicate content with your blog’s home page. If your author page has been deactivated in this way, then ActivityPub won’t work for you. Instead, you can turn your author profile page back on, and then use the option in your SEO plugin to noindex the author page. This will enable the page to be live and ActivityPub will now work, but the live page won’t cause any duplicate content issues with search engines. +1. Once ActivityPub is installed, only new posts going forward will be available in the fediverse. Likewise, even if you’ve been using ActivityPub for a while, anyone who follows your site, will only see new posts you publish from that moment on. They will never see previously-published posts in their Home feed. This process is very similar to subscribing to a newsletter. If you subscribe to a newsletter, you will only receive future emails, but not the old archived ones. With ActivityPub, if someone follows your site, they will only receive new blog posts you publish from then on. So what’s the process? - 1. Install the ActivityPub plugin. - 2. Go to the plugin’s settings page and adjust the settings to your liking. Click the Save button when ready. - 3. Make sure your blog’s author profile page is active. - 4. Go to Mastodon or any other federated platform, search for your author’s new federated profile, and follow it. Your new profile will be in the form of @yourauthorname@yourwebsite.com, so that is what you’ll search for. - 5. On your blog, publish a new post. - 6. From Mastodon, check to see if the new post appears in your Home feed. +1. Install the ActivityPub plugin. +1. Go to the plugin’s settings page and adjust the settings to your liking. Click the Save button when ready. +1. Make sure your blog’s author profile page is active. +1. Go to Mastodon or any other federated platform, search for your author’s new federated profile, and follow it. Your new profile will be in the form of @yourauthorname@yourwebsite.com, so that is what you’ll search for. +1. On your blog, publish a new post. +1. From Mastodon, check to see if the new post appears in your Home feed. Please note that it may take up to 15 minutes or so for the new post to show up in your federated feed. This is because the messages are sent to the federated platforms using a delayed cron. This avoids breaking the publishing process for those cases where users might have lots of followers. So please don’t assume that just because you didn’t see it show up right away that something is broken. Give it some time. In most cases, it will show up within a few minutes, and you’ll know everything is working as expected. @@ -57,10 +57,10 @@ This plugin connects your WordPress blog to popular social platforms like Mastod Here's how it works: - 1. Install the plugin and adjust settings as needed. - 2. Ensure your blog's author profile page is active. - 3. On Mastodon or other supported platforms, search for and follow your author's new profile (e.g., `@yourauthorname@yourwebsite.com`). - 4. Publish a new post on your blog and check if it appears in your Mastodon feed. +1. Install the plugin and adjust settings as needed. +1. Ensure your blog's author profile page is active. +1. On Mastodon or other supported platforms, search for and follow your author's new profile (e.g., `@yourauthorname@yourwebsite.com`). +1. Publish a new post on your blog and check if it appears in your Mastodon feed. Please note that it may take up to 15 minutes for a new post to appear in your feed, as messages are sent on a delay to avoid overwhelming your followers. Be patient and give it some time. @@ -382,12 +382,12 @@ Follow the normal instructions for [installing WordPress plugins](https://wordpr To add a WordPress Plugin using the [built-in plugin installer](https://codex.wordpress.org/Administration_Screens#Add_New_Plugins): 1. Go to [Plugins](https://codex.wordpress.org/Administration_Screens#Plugins) > [Add New](https://codex.wordpress.org/Plugins_Add_New_Screen). -2. Type "`activitypub`" into the **Search Plugins** box. -3. Find the WordPress Plugin you wish to install. +1. Type "`activitypub`" into the **Search Plugins** box. +1. Find the WordPress Plugin you wish to install. 1. Click **Details** for more information about the Plugin and instructions you may wish to print or save to help setup the Plugin. - 2. Click **Install Now** to install the WordPress Plugin. -4. The resulting installation screen will list the installation as successful or note any problems during the install. -5. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. + 1. Click **Install Now** to install the WordPress Plugin. +1. The resulting installation screen will list the installation as successful or note any problems during the install. +1. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. ### Manual Plugin Installation ### diff --git a/readme.txt b/readme.txt index d47f644..9c7661d 100644 --- a/readme.txt +++ b/readme.txt @@ -35,17 +35,17 @@ Of course, if no one follows your author instance, then no one will ever see the Some things to note: - 1. Many single-author blogs have chosen to turn off or redirect their author profile pages, usually via an SEO plugin like Yoast or Rank Math. This is usually done to avoid duplicate content with your blog’s home page. If your author page has been deactivated in this way, then ActivityPub won’t work for you. Instead, you can turn your author profile page back on, and then use the option in your SEO plugin to noindex the author page. This will enable the page to be live and ActivityPub will now work, but the live page won’t cause any duplicate content issues with search engines. - 2. Once ActivityPub is installed, only new posts going forward will be available in the fediverse. Likewise, even if you’ve been using ActivityPub for a while, anyone who follows your site, will only see new posts you publish from that moment on. They will never see previously-published posts in their Home feed. This process is very similar to subscribing to a newsletter. If you subscribe to a newsletter, you will only receive future emails, but not the old archived ones. With ActivityPub, if someone follows your site, they will only receive new blog posts you publish from then on. +1. Many single-author blogs have chosen to turn off or redirect their author profile pages, usually via an SEO plugin like Yoast or Rank Math. This is usually done to avoid duplicate content with your blog’s home page. If your author page has been deactivated in this way, then ActivityPub won’t work for you. Instead, you can turn your author profile page back on, and then use the option in your SEO plugin to noindex the author page. This will enable the page to be live and ActivityPub will now work, but the live page won’t cause any duplicate content issues with search engines. +1. Once ActivityPub is installed, only new posts going forward will be available in the fediverse. Likewise, even if you’ve been using ActivityPub for a while, anyone who follows your site, will only see new posts you publish from that moment on. They will never see previously-published posts in their Home feed. This process is very similar to subscribing to a newsletter. If you subscribe to a newsletter, you will only receive future emails, but not the old archived ones. With ActivityPub, if someone follows your site, they will only receive new blog posts you publish from then on. So what’s the process? - 1. Install the ActivityPub plugin. - 2. Go to the plugin’s settings page and adjust the settings to your liking. Click the Save button when ready. - 3. Make sure your blog’s author profile page is active. - 4. Go to Mastodon or any other federated platform, search for your author’s new federated profile, and follow it. Your new profile will be in the form of @yourauthorname@yourwebsite.com, so that is what you’ll search for. - 5. On your blog, publish a new post. - 6. From Mastodon, check to see if the new post appears in your Home feed. +1. Install the ActivityPub plugin. +1. Go to the plugin’s settings page and adjust the settings to your liking. Click the Save button when ready. +1. Make sure your blog’s author profile page is active. +1. Go to Mastodon or any other federated platform, search for your author’s new federated profile, and follow it. Your new profile will be in the form of @yourauthorname@yourwebsite.com, so that is what you’ll search for. +1. On your blog, publish a new post. +1. From Mastodon, check to see if the new post appears in your Home feed. Please note that it may take up to 15 minutes or so for the new post to show up in your federated feed. This is because the messages are sent to the federated platforms using a delayed cron. This avoids breaking the publishing process for those cases where users might have lots of followers. So please don’t assume that just because you didn’t see it show up right away that something is broken. Give it some time. In most cases, it will show up within a few minutes, and you’ll know everything is working as expected. @@ -57,10 +57,10 @@ This plugin connects your WordPress blog to popular social platforms like Mastod Here's how it works: - 1. Install the plugin and adjust settings as needed. - 2. Ensure your blog's author profile page is active. - 3. On Mastodon or other supported platforms, search for and follow your author's new profile (e.g., `@yourauthorname@yourwebsite.com`). - 4. Publish a new post on your blog and check if it appears in your Mastodon feed. +1. Install the plugin and adjust settings as needed. +1. Ensure your blog's author profile page is active. +1. On Mastodon or other supported platforms, search for and follow your author's new profile (e.g., `@yourauthorname@yourwebsite.com`). +1. Publish a new post on your blog and check if it appears in your Mastodon feed. Please note that it may take up to 15 minutes for a new post to appear in your feed, as messages are sent on a delay to avoid overwhelming your followers. Be patient and give it some time. @@ -382,12 +382,12 @@ Follow the normal instructions for [installing WordPress plugins](https://wordpr To add a WordPress Plugin using the [built-in plugin installer](https://codex.wordpress.org/Administration_Screens#Add_New_Plugins): 1. Go to [Plugins](https://codex.wordpress.org/Administration_Screens#Plugins) > [Add New](https://codex.wordpress.org/Plugins_Add_New_Screen). -2. Type "`activitypub`" into the **Search Plugins** box. -3. Find the WordPress Plugin you wish to install. +1. Type "`activitypub`" into the **Search Plugins** box. +1. Find the WordPress Plugin you wish to install. 1. Click **Details** for more information about the Plugin and instructions you may wish to print or save to help setup the Plugin. - 2. Click **Install Now** to install the WordPress Plugin. -4. The resulting installation screen will list the installation as successful or note any problems during the install. -5. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. + 1. Click **Install Now** to install the WordPress Plugin. +1. The resulting installation screen will list the installation as successful or note any problems during the install. +1. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. = Manual Plugin Installation = From 7d11d3e2089d49c4e1626e4a73ca192aa5881eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Wrede?= Date: Thu, 23 Mar 2023 08:35:26 +0100 Subject: [PATCH 11/14] Fix documentation and typos. --- includes/class-health-check.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/includes/class-health-check.php b/includes/class-health-check.php index 26bc808..248d260 100644 --- a/includes/class-health-check.php +++ b/includes/class-health-check.php @@ -35,7 +35,7 @@ class Health_Check { /** * Author URL tests * - * @return void + * @return array */ public static function test_author_url() { $result = array( @@ -73,7 +73,7 @@ class Health_Check { /** * WebFinger tests * - * @return void + * @return array */ public static function test_webfinger() { $result = array( @@ -85,7 +85,7 @@ class Health_Check { ), 'description' => \sprintf( '

    %s

    ', - \__( 'Your WebFinger endpoint is accessible and returns the correct informations.', 'activitypub' ) + \__( 'Your WebFinger endpoint is accessible and returns the correct information.', 'activitypub' ) ), 'actions' => '', 'test' => 'test_webfinger', @@ -109,9 +109,9 @@ class Health_Check { } /** - * Check if `author_posts_url` is accessible and that requerst returns correct JSON + * Check if `author_posts_url` is accessible and that request returns correct JSON * - * @return boolean|WP_Error + * @return boolean|\WP_Error */ public static function is_author_url_accessible() { $user = \wp_get_current_user(); @@ -194,9 +194,9 @@ class Health_Check { } /** - * Check if WebFinger endoint is accessible and profile requerst returns correct JSON + * Check if WebFinger endpoint is accessible and profile request returns correct JSON * - * @return boolean|WP_Error + * @return boolean|\WP_Error */ public static function is_webfinger_endpoint_accessible() { $user = \wp_get_current_user(); @@ -272,7 +272,7 @@ class Health_Check { * Static function for generating site debug data when required. * * @param array $info The debug information to be added to the core information page. - * @return array The filtered informations + * @return array The filtered information */ public static function debug_information( $info ) { $info['activitypub'] = array( From 643c47dcb7644af10d6687e4a119a4c7c6fa7454 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Mon, 10 Apr 2023 13:10:46 +0200 Subject: [PATCH 12/14] Webfinger info: avoid PHP warning when user isn't defined This should avoid warnings like this one: ``` PHP Warning: Attempt to read property "user_login" on bool in /var/www/html/wp-content/plugins/activitypub/includes/class-webfinger.php on line 27 ``` --- includes/class-webfinger.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/class-webfinger.php b/includes/class-webfinger.php index ab33411..c7d2cba 100644 --- a/includes/class-webfinger.php +++ b/includes/class-webfinger.php @@ -23,6 +23,9 @@ class Webfinger { } $user = \get_user_by( 'id', $user_id ); + if ( ! $user ) { + return ''; + } return $user->user_login . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST ); } From c32eec2390328fb37b320fc31f8a74c6b1ac1f4d Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 20 Apr 2023 15:22:11 +0200 Subject: [PATCH 13/14] some code cleanup --- activitypub.php | 30 +++++++++++++------------- includes/class-activity-dispatcher.php | 30 +++++++++++++++----------- includes/class-activitypub.php | 12 +++++------ includes/class-admin.php | 16 +++++++------- includes/class-debug.php | 5 ++++- includes/class-hashtag.php | 4 ++-- includes/class-health-check.php | 8 +++---- includes/class-mention.php | 6 +++--- includes/class-webfinger.php | 10 +++++---- includes/model/class-activity.php | 2 ++ includes/rest/class-followers.php | 4 ++-- includes/rest/class-following.php | 4 ++-- includes/rest/class-inbox.php | 24 +++++++++++---------- includes/rest/class-nodeinfo.php | 12 +++++------ includes/rest/class-outbox.php | 4 ++-- includes/rest/class-webfinger.php | 17 +++++++++------ 16 files changed, 102 insertions(+), 86 deletions(-) diff --git a/activitypub.php b/activitypub.php index 7320f0c..35e6de8 100644 --- a/activitypub.php +++ b/activitypub.php @@ -39,50 +39,50 @@ function init() { require_once \dirname( __FILE__ ) . '/includes/model/class-post.php'; require_once \dirname( __FILE__ ) . '/includes/class-activity-dispatcher.php'; - \Activitypub\Activity_Dispatcher::init(); + Activity_Dispatcher::init(); require_once \dirname( __FILE__ ) . '/includes/class-activitypub.php'; - \Activitypub\Activitypub::init(); + Activitypub::init(); // Configure the REST API route require_once \dirname( __FILE__ ) . '/includes/rest/class-outbox.php'; - \Activitypub\Rest\Outbox::init(); + Rest\Outbox::init(); require_once \dirname( __FILE__ ) . '/includes/rest/class-inbox.php'; - \Activitypub\Rest\Inbox::init(); + Rest\Inbox::init(); require_once \dirname( __FILE__ ) . '/includes/rest/class-followers.php'; - \Activitypub\Rest\Followers::init(); + Rest\Followers::init(); require_once \dirname( __FILE__ ) . '/includes/rest/class-following.php'; - \Activitypub\Rest\Following::init(); + Rest\Following::init(); require_once \dirname( __FILE__ ) . '/includes/rest/class-webfinger.php'; - \Activitypub\Rest\Webfinger::init(); + Rest\Webfinger::init(); // load NodeInfo endpoints only if blog is public if ( true === (bool) \get_option( 'blog_public', 1 ) ) { require_once \dirname( __FILE__ ) . '/includes/rest/class-nodeinfo.php'; - \Activitypub\Rest\NodeInfo::init(); + Rest\NodeInfo::init(); } require_once \dirname( __FILE__ ) . '/includes/class-admin.php'; - \Activitypub\Admin::init(); + Admin::init(); require_once \dirname( __FILE__ ) . '/includes/class-hashtag.php'; - \Activitypub\Hashtag::init(); + Hashtag::init(); require_once \dirname( __FILE__ ) . '/includes/class-shortcodes.php'; - \Activitypub\Shortcodes::init(); + Shortcodes::init(); require_once \dirname( __FILE__ ) . '/includes/class-mention.php'; - \Activitypub\Mention::init(); + Mention::init(); require_once \dirname( __FILE__ ) . '/includes/class-debug.php'; - \Activitypub\Debug::init(); + Debug::init(); require_once \dirname( __FILE__ ) . '/includes/class-health-check.php'; - \Activitypub\Health_Check::init(); + Health_Check::init(); if ( \WP_DEBUG ) { require_once \dirname( __FILE__ ) . '/includes/debug.php'; @@ -136,6 +136,6 @@ function flush_rewrite_rules() { */ function enable_buddypress_features() { require_once \dirname( __FILE__ ) . '/integration/class-buddypress.php'; - \Activitypub\Integration\Buddypress::init(); + Integration\Buddypress::init(); } add_action( 'bp_include', '\Activitypub\enable_buddypress_features' ); diff --git a/includes/class-activity-dispatcher.php b/includes/class-activity-dispatcher.php index 6df83e7..57fee1a 100644 --- a/includes/class-activity-dispatcher.php +++ b/includes/class-activity-dispatcher.php @@ -1,6 +1,9 @@ get_post_author(); - $activitypub_activity = new \Activitypub\Model\Activity( $activity_type ); + $activitypub_activity = new Activity( $activity_type ); $activitypub_activity->from_post( $activitypub_post ); $inboxes = \Activitypub\get_follower_inboxes( $user_id, $activitypub_activity->get_cc() ); diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index 4a60915..4730515 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -11,9 +11,9 @@ class Activitypub { * Initialize the class, registering WordPress hooks. */ public static function init() { - \add_filter( 'template_include', array( '\Activitypub\Activitypub', 'render_json_template' ), 99 ); - \add_filter( 'query_vars', array( '\Activitypub\Activitypub', 'add_query_vars' ) ); - \add_filter( 'pre_get_avatar_data', array( '\Activitypub\Activitypub', 'pre_get_avatar_data' ), 11, 2 ); + \add_filter( 'template_include', array( self::class, 'render_json_template' ), 99 ); + \add_filter( 'query_vars', array( self::class, 'add_query_vars' ) ); + \add_filter( 'pre_get_avatar_data', array( self::class, 'pre_get_avatar_data' ), 11, 2 ); // Add support for ActivityPub to custom post types $post_types = \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) ) ? \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) ) : array(); @@ -22,9 +22,9 @@ class Activitypub { \add_post_type_support( $post_type, 'activitypub' ); } - \add_action( 'transition_post_status', array( '\Activitypub\Activitypub', 'schedule_post_activity' ), 33, 3 ); - \add_action( 'wp_trash_post', array( '\Activitypub\Activitypub', 'trash_post' ), 1 ); - \add_action( 'untrash_post', array( '\Activitypub\Activitypub', 'untrash_post' ), 1 ); + \add_action( 'transition_post_status', array( self::class, 'schedule_post_activity' ), 33, 3 ); + \add_action( 'wp_trash_post', array( self::class, 'trash_post' ), 1 ); + \add_action( 'untrash_post', array( self::class, 'untrash_post' ), 1 ); } /** diff --git a/includes/class-admin.php b/includes/class-admin.php index e98d547..220ed9b 100644 --- a/includes/class-admin.php +++ b/includes/class-admin.php @@ -11,10 +11,10 @@ class Admin { * Initialize the class, registering WordPress hooks */ public static function init() { - \add_action( 'admin_menu', array( '\Activitypub\Admin', 'admin_menu' ) ); - \add_action( 'admin_init', array( '\Activitypub\Admin', 'register_settings' ) ); - \add_action( 'show_user_profile', array( '\Activitypub\Admin', 'add_fediverse_profile' ) ); - \add_action( 'admin_enqueue_scripts', array( '\Activitypub\Admin', 'enqueue_scripts' ) ); + \add_action( 'admin_menu', array( self::class, 'admin_menu' ) ); + \add_action( 'admin_init', array( self::class, 'register_settings' ) ); + \add_action( 'show_user_profile', array( self::class, 'add_fediverse_profile' ) ); + \add_action( 'admin_enqueue_scripts', array( self::class, 'enqueue_scripts' ) ); } /** @@ -26,14 +26,14 @@ class Admin { 'ActivityPub', 'manage_options', 'activitypub', - array( '\Activitypub\Admin', 'settings_page' ) + array( self::class, 'settings_page' ) ); - \add_action( 'load-' . $settings_page, array( '\Activitypub\Admin', 'add_settings_help_tab' ) ); + \add_action( 'load-' . $settings_page, array( self::class, 'add_settings_help_tab' ) ); - $followers_list_page = \add_users_page( \__( 'Followers', 'activitypub' ), \__( 'Followers (Fediverse)', 'activitypub' ), 'read', 'activitypub-followers-list', array( '\Activitypub\Admin', 'followers_list_page' ) ); + $followers_list_page = \add_users_page( \__( 'Followers', 'activitypub' ), \__( 'Followers (Fediverse)', 'activitypub' ), 'read', 'activitypub-followers-list', array( self::class, 'followers_list_page' ) ); - \add_action( 'load-' . $followers_list_page, array( '\Activitypub\Admin', 'add_followers_list_help_tab' ) ); + \add_action( 'load-' . $followers_list_page, array( self::class, 'add_followers_list_help_tab' ) ); } /** diff --git a/includes/class-debug.php b/includes/class-debug.php index 767d4a9..36f8bda 100644 --- a/includes/class-debug.php +++ b/includes/class-debug.php @@ -1,6 +1,9 @@ \__( 'Author URL test', 'activitypub' ), - 'test' => array( '\Activitypub\Health_Check', 'test_author_url' ), + 'test' => array( self::class, 'test_author_url' ), ); $tests['direct']['activitypub_test_webfinger'] = array( 'label' => __( 'WebFinger Test', 'activitypub' ), - 'test' => array( '\Activitypub\Health_Check', 'test_webfinger' ), + 'test' => array( self::class, 'test_webfinger' ), ); return $tests; diff --git a/includes/class-mention.php b/includes/class-mention.php index 7c8672a..e0930cc 100644 --- a/includes/class-mention.php +++ b/includes/class-mention.php @@ -11,8 +11,8 @@ class Mention { * Initialize the class, registering WordPress hooks */ public static function init() { - \add_filter( 'the_content', array( '\Activitypub\Mention', 'the_content' ), 99, 2 ); - \add_filter( 'activitypub_extract_mentions', array( '\Activitypub\Mention', 'extract_mentions' ), 99, 2 ); + \add_filter( 'the_content', array( self::class, 'the_content' ), 99, 2 ); + \add_filter( 'activitypub_extract_mentions', array( self::class, 'extract_mentions' ), 99, 2 ); } /** @@ -46,7 +46,7 @@ class Mention { $the_content ); - $the_content = \preg_replace_callback( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/', array( '\Activitypub\Mention', 'replace_with_links' ), $the_content ); + $the_content = \preg_replace_callback( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/', array( self::class, 'replace_with_links' ), $the_content ); $the_content = str_replace( array_reverse( array_keys( $protected_tags ) ), array_reverse( array_values( $protected_tags ) ), $the_content ); diff --git a/includes/class-webfinger.php b/includes/class-webfinger.php index c7d2cba..1581853 100644 --- a/includes/class-webfinger.php +++ b/includes/class-webfinger.php @@ -1,6 +1,8 @@ \WP_REST_Server::READABLE, - 'callback' => array( '\Activitypub\Rest\Followers', 'get' ), + 'callback' => array( self::class, 'get' ), 'args' => self::request_parameters(), 'permission_callback' => '__return_true', ), diff --git a/includes/rest/class-following.php b/includes/rest/class-following.php index d7caff4..52a95e7 100644 --- a/includes/rest/class-following.php +++ b/includes/rest/class-following.php @@ -13,7 +13,7 @@ class Following { * Initialize the class, registering WordPress hooks */ public static function init() { - \add_action( 'rest_api_init', array( '\Activitypub\Rest\Following', 'register_routes' ) ); + \add_action( 'rest_api_init', array( self::class, 'register_routes' ) ); } /** @@ -26,7 +26,7 @@ class Following { array( array( 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( '\Activitypub\Rest\Following', 'get' ), + 'callback' => array( self::class, 'get' ), 'args' => self::request_parameters(), 'permission_callback' => '__return_true', ), diff --git a/includes/rest/class-inbox.php b/includes/rest/class-inbox.php index 86aefd4..1a63108 100644 --- a/includes/rest/class-inbox.php +++ b/includes/rest/class-inbox.php @@ -1,6 +1,8 @@ \WP_REST_Server::EDITABLE, - 'callback' => array( '\Activitypub\Rest\Inbox', 'shared_inbox_post' ), + 'callback' => array( self::class, 'shared_inbox_post' ), 'args' => self::shared_inbox_post_parameters(), 'permission_callback' => '__return_true', ), @@ -45,13 +47,13 @@ class Inbox { array( array( 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( '\Activitypub\Rest\Inbox', 'user_inbox_post' ), + 'callback' => array( self::class, 'user_inbox_post' ), 'args' => self::user_inbox_post_parameters(), 'permission_callback' => '__return_true', ), array( 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( '\Activitypub\Rest\Inbox', 'user_inbox_get' ), + 'callback' => array( self::class, 'user_inbox_get' ), 'args' => self::user_inbox_get_parameters(), 'permission_callback' => '__return_true', ), @@ -356,7 +358,7 @@ class Inbox { $inbox = \Activitypub\get_inbox_by_actor( $object['actor'] ); // send "Accept" activity - $activity = new \Activitypub\Model\Activity( 'Accept' ); + $activity = new Activity( 'Accept' ); $activity->set_object( $object ); $activity->set_actor( \get_author_posts_url( $user_id ) ); $activity->set_to( $object['actor'] ); diff --git a/includes/rest/class-nodeinfo.php b/includes/rest/class-nodeinfo.php index 3106c5e..100fdd3 100644 --- a/includes/rest/class-nodeinfo.php +++ b/includes/rest/class-nodeinfo.php @@ -13,9 +13,9 @@ class Nodeinfo { * Initialize the class, registering WordPress hooks */ public static function init() { - \add_action( 'rest_api_init', array( '\Activitypub\Rest\Nodeinfo', 'register_routes' ) ); - \add_filter( 'nodeinfo_data', array( '\Activitypub\Rest\Nodeinfo', 'add_nodeinfo_discovery' ), 10, 2 ); - \add_filter( 'nodeinfo2_data', array( '\Activitypub\Rest\Nodeinfo', 'add_nodeinfo2_discovery' ), 10 ); + \add_action( 'rest_api_init', array( self::class, 'register_routes' ) ); + \add_filter( 'nodeinfo_data', array( self::class, 'add_nodeinfo_discovery' ), 10, 2 ); + \add_filter( 'nodeinfo2_data', array( self::class, 'add_nodeinfo2_discovery' ), 10 ); } /** @@ -28,7 +28,7 @@ class Nodeinfo { array( array( 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( '\Activitypub\Rest\Nodeinfo', 'discovery' ), + 'callback' => array( self::class, 'discovery' ), 'permission_callback' => '__return_true', ), ) @@ -40,7 +40,7 @@ class Nodeinfo { array( array( 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( '\Activitypub\Rest\Nodeinfo', 'nodeinfo' ), + 'callback' => array( self::class, 'nodeinfo' ), 'permission_callback' => '__return_true', ), ) @@ -52,7 +52,7 @@ class Nodeinfo { array( array( 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( '\Activitypub\Rest\Nodeinfo', 'nodeinfo2' ), + 'callback' => array( self::class, 'nodeinfo2' ), 'permission_callback' => '__return_true', ), ) diff --git a/includes/rest/class-outbox.php b/includes/rest/class-outbox.php index 8749d11..905dfd5 100644 --- a/includes/rest/class-outbox.php +++ b/includes/rest/class-outbox.php @@ -13,7 +13,7 @@ class Outbox { * Initialize the class, registering WordPress hooks */ public static function init() { - \add_action( 'rest_api_init', array( '\Activitypub\Rest\Outbox', 'register_routes' ) ); + \add_action( 'rest_api_init', array( self::class, 'register_routes' ) ); } /** @@ -26,7 +26,7 @@ class Outbox { array( array( 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( '\Activitypub\Rest\Outbox', 'user_outbox_get' ), + 'callback' => array( self::class, 'user_outbox_get' ), 'args' => self::request_parameters(), 'permission_callback' => '__return_true', ), diff --git a/includes/rest/class-webfinger.php b/includes/rest/class-webfinger.php index 0c6d5f1..d41cf25 100644 --- a/includes/rest/class-webfinger.php +++ b/includes/rest/class-webfinger.php @@ -1,6 +1,9 @@ \WP_REST_Server::READABLE, - 'callback' => array( '\Activitypub\Rest\Webfinger', 'webfinger' ), + 'callback' => array( self::class, 'webfinger' ), 'args' => self::request_parameters(), 'permission_callback' => '__return_true', ), @@ -45,7 +48,7 @@ class Webfinger { $resource = $request->get_param( 'resource' ); if ( \strpos( $resource, '@' ) === false ) { - return new \WP_Error( 'activitypub_unsupported_resource', \__( 'Resource is invalid', 'activitypub' ), array( 'status' => 400 ) ); + return new WP_Error( 'activitypub_unsupported_resource', \__( 'Resource is invalid', 'activitypub' ), array( 'status' => 400 ) ); } $resource = \str_replace( 'acct:', '', $resource ); @@ -54,13 +57,13 @@ class Webfinger { $resource_host = \substr( \strrchr( $resource, '@' ), 1 ); if ( \wp_parse_url( \home_url( '/' ), \PHP_URL_HOST ) !== $resource_host ) { - return new \WP_Error( 'activitypub_wrong_host', \__( 'Resource host does not match blog host', 'activitypub' ), array( 'status' => 404 ) ); + return new WP_Error( 'activitypub_wrong_host', \__( 'Resource host does not match blog host', 'activitypub' ), array( 'status' => 404 ) ); } $user = \get_user_by( 'login', \esc_sql( $resource_identifier ) ); if ( ! $user || ! user_can( $user, 'publish_posts' ) ) { - return new \WP_Error( 'activitypub_user_not_found', \__( 'User not found', 'activitypub' ), array( 'status' => 404 ) ); + return new WP_Error( 'activitypub_user_not_found', \__( 'User not found', 'activitypub' ), array( 'status' => 404 ) ); } $json = array( @@ -82,7 +85,7 @@ class Webfinger { ), ); - return new \WP_REST_Response( $json, 200 ); + return new WP_REST_Response( $json, 200 ); } /** From eeb3ba295274f43b1776ad4e7953525327fa80f5 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 20 Apr 2023 15:32:38 +0200 Subject: [PATCH 14/14] remove unused "use function" --- includes/model/class-activity.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/includes/model/class-activity.php b/includes/model/class-activity.php index cfbb431..34f6146 100644 --- a/includes/model/class-activity.php +++ b/includes/model/class-activity.php @@ -1,8 +1,6 @@