From 0f4155ed0eab3c903447853628883195b5e016d3 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:09:39 +0200 Subject: [PATCH 01/19] Comment: Send announce for all new comments Supersedes #1515 and fixes #1001 --- includes/class-comment.php | 34 ++++++++++++++++++++++ includes/collection/class-interactions.php | 5 ++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/includes/class-comment.php b/includes/class-comment.php index 0f989376c..aa9edd7a0 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -33,6 +33,8 @@ public static function init() { \add_action( 'update_option_activitypub_allow_likes', array( self::class, 'maybe_update_comment_counts' ), 10, 2 ); \add_action( 'update_option_activitypub_allow_reposts', array( self::class, 'maybe_update_comment_counts' ), 10, 2 ); \add_filter( 'pre_wp_update_comment_count_now', array( static::class, 'pre_wp_update_comment_count_now' ), 10, 3 ); + + \add_action( 'transition_comment_status', array( self::class, 'maybe_announce_interaction' ), 20, 3 ); } /** @@ -804,6 +806,38 @@ public static function pre_wp_update_comment_count_now( $new_count, $old_count, return $new_count; } + /** + * Announce an interaction. + * + * @param string $new_status The new comment status. + * @param string $old_status The old comment status. + * @param \WP_Comment $comment The comment object. + */ + public static function maybe_announce_interaction( $new_status, $old_status, $comment ) { + if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) { + return; + } + + if ( 'approved' !== $new_status || 'approved' === $old_status ) { + return; + } + + $comment = \get_comment( $comment ); + + if ( ! self::was_received( $comment ) ) { + return; + } + + // get activity from comment meta + $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); + + if ( ! $activity ) { + return; + } + + add_to_outbox( $activity, 'Announce', Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); + } + /** * Check if a comment type is enabled. * diff --git a/includes/collection/class-interactions.php b/includes/collection/class-interactions.php index dc1f94170..f40a9c706 100644 --- a/includes/collection/class-interactions.php +++ b/includes/collection/class-interactions.php @@ -270,8 +270,9 @@ public static function activity_to_comment( $activity ) { 'comment_type' => 'comment', 'comment_author_email' => $webfinger, 'comment_meta' => array( - 'source_id' => \esc_url_raw( object_to_uri( $activity['object'] ) ), - 'protocol' => 'activitypub', + 'source_id' => \esc_url_raw( object_to_uri( $activity['object'] ) ), + 'protocol' => 'activitypub', + '_activitypub_activity' => $activity, ), ); From bb1ad46c9bd7c952c5f9bef8b5f6960d7b961b34 Mon Sep 17 00:00:00 2001 From: Automattic Bot Date: Thu, 10 Apr 2025 14:12:15 +0300 Subject: [PATCH 02/19] Add changelog --- .github/changelog/1562-from-description | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/changelog/1562-from-description diff --git a/.github/changelog/1562-from-description b/.github/changelog/1562-from-description new file mode 100644 index 000000000..acf5ca947 --- /dev/null +++ b/.github/changelog/1562-from-description @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Incoming interactions create an Announce activity so other instances get notified about it. From adab3162dd7d8b877d1f870cb2eaf534afdcb6a7 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:14:20 +0200 Subject: [PATCH 03/19] phpcs fix --- includes/class-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-comment.php b/includes/class-comment.php index aa9edd7a0..69c458447 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -828,7 +828,7 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - // get activity from comment meta + // Get activity from comment meta. $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); if ( ! $activity ) { From c069473ebdedef7904503a0c031103f8fcf2b00c Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:32:49 +0200 Subject: [PATCH 04/19] activities are normally not in reply to --- includes/activity/class-activity.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/includes/activity/class-activity.php b/includes/activity/class-activity.php index f9da8b26f..7eade851b 100644 --- a/includes/activity/class-activity.php +++ b/includes/activity/class-activity.php @@ -233,10 +233,6 @@ public function pre_fill_activity_from_object() { $this->set( 'actor', $object->get_attributed_to() ); } - if ( $object->get_in_reply_to() && ! $this->get_in_reply_to() ) { - $this->set( 'in_reply_to', $object->get_in_reply_to() ); - } - if ( $object->get_id() && ! $this->get_id() ) { $id = strtok( $object->get_id(), '#' ); if ( $object->get_updated() ) { From b1d461c7484fd088cf7583aaefbfa5fa12c4d4cd Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:36:52 +0200 Subject: [PATCH 05/19] Set Actor URL! --- includes/collection/class-outbox.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/collection/class-outbox.php b/includes/collection/class-outbox.php index f610ea6b5..ba4c8076e 100644 --- a/includes/collection/class-outbox.php +++ b/includes/collection/class-outbox.php @@ -36,6 +36,10 @@ public static function add( Activity $activity, $user_id, $visibility = ACTIVITY $object_id = self::get_object_id( $activity ); $title = self::get_object_title( $activity->get_object() ); + if ( ! $activity->get_actor() ) { + $activity->set_actor( Actors::get_by_id( $user_id )->get_id() ); + } + $outbox_item = array( 'post_type' => self::POST_TYPE, 'post_title' => sprintf( From 3fcdf0fed03e1439354a07c34c99e24eedf26e6c Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:38:37 +0200 Subject: [PATCH 06/19] backwards compatibility --- includes/collection/class-outbox.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/collection/class-outbox.php b/includes/collection/class-outbox.php index ba4c8076e..cf1dff89f 100644 --- a/includes/collection/class-outbox.php +++ b/includes/collection/class-outbox.php @@ -217,6 +217,9 @@ public static function get_activity( $outbox_item ) { if ( $activity_object['type'] === $type ) { $activity = Activity::init_from_array( $activity_object ); + if ( ! $activity->get_actor() ) { + $activity->set_actor( $actor->get_id() ); + } } else { $activity = new Activity(); $activity->set_type( $type ); From ec02ba3b519a4a62d7f578c44b26643c296c8c31 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:47:49 +0200 Subject: [PATCH 07/19] AI test fail --- tests/includes/collection/class-test-outbox.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/includes/collection/class-test-outbox.php b/tests/includes/collection/class-test-outbox.php index fc4ee1335..e03117468 100644 --- a/tests/includes/collection/class-test-outbox.php +++ b/tests/includes/collection/class-test-outbox.php @@ -115,7 +115,7 @@ public function activity_object_provider() { ), 'Create', 1, - '{"@context":["https:\/\/www.w3.org\/ns\/activitystreams",{"Hashtag":"as:Hashtag","sensitive":"as:sensitive"}],"id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=351","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/1","type":"Note","content":"\u003Cp\u003EThis is a note\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EThis is a note\u003C\/p\u003E"},"to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html"}}', + '{"@context":["https:\/\/www.w3.org\/ns\/activitystreams",{"Hashtag":"as:Hashtag","sensitive":"as:sensitive"}],"actor":"http:\/\/example.org\/?author=1","id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=351","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/1","type":"Note","content":"\u003Cp\u003EThis is a note\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EThis is a note\u003C\/p\u003E"},"to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html"}}', ), array( array( @@ -126,7 +126,7 @@ public function activity_object_provider() { ), 'Create', 2, - '{"@context":["https:\/\/www.w3.org\/ns\/activitystreams",{"Hashtag":"as:Hashtag","sensitive":"as:sensitive"}],"id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=352","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/2","type":"Note","content":"\u003Cp\u003EThis is another note\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EThis is another note\u003C\/p\u003E"},"to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html"}}', + '{"@context":["https:\/\/www.w3.org\/ns\/activitystreams",{"Hashtag":"as:Hashtag","sensitive":"as:sensitive"}],"actor":"http:\/\/example.org\/?author=0","id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=352","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/2","type":"Note","content":"\u003Cp\u003EThis is another note\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EThis is another note\u003C\/p\u003E"},"to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html"}}', ), array( Event::init_from_array( @@ -163,7 +163,7 @@ public function activity_object_provider() { ), 'Create', 1, - '{"@context":["https:\/\/schema.org\/","https:\/\/www.w3.org\/ns\/activitystreams",{"pt":"https:\/\/joinpeertube.org\/ns#","mz":"https:\/\/joinmobilizon.org\/ns#","status":"http:\/\/www.w3.org\/2002\/12\/cal\/ical#status","commentsEnabled":"pt:commentsEnabled","isOnline":"mz:isOnline","timezone":"mz:timezone","participantCount":"mz:participantCount","anonymousParticipationEnabled":"mz:anonymousParticipationEnabled","joinMode":{"@id":"mz:joinMode","@type":"mz:joinModeType"},"externalParticipationUrl":{"@id":"mz:externalParticipationUrl","@type":"schema:URL"},"repliesModerationOption":{"@id":"mz:repliesModerationOption","@type":"@vocab"},"contacts":{"@id":"mz:contacts","@type":"@id"}}],"id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=353","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/3","type":"Event","content":"\u003Cp\u003EYou should not miss this Event!\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EYou should not miss this Event!\u003C\/p\u003E"},"name":"WP Test Event","nameMap":{"en":"WP Test Event"},"endTime":"2030-02-29T17:00:00+01:00","location":[{"id":"https:\/\/example.com\/place\/1","type":"Place","attributedTo":"https:\/\/wp-test.event-federation.eu\/@test","name":"Fediverse Place","address":{"type":"PostalAddress","addressCountry":"FediCountry","addressLocality":"FediTown","postalCode":"1337","streetAddress":"FediStreet"}},{"type":"VirtualLocation","url":"https:\/\/example.com\/VirtualMeetingRoom"}],"startTime":"2030-02-29T16:00:00+01:00","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html","timezone":"Europe\/Vienna","category":"MOVEMENTS_POLITICS","joinMode":"external"}}', + '{"@context":["https:\/\/schema.org\/","https:\/\/www.w3.org\/ns\/activitystreams",{"pt":"https:\/\/joinpeertube.org\/ns#","mz":"https:\/\/joinmobilizon.org\/ns#","status":"http:\/\/www.w3.org\/2002\/12\/cal\/ical#status","commentsEnabled":"pt:commentsEnabled","isOnline":"mz:isOnline","timezone":"mz:timezone","participantCount":"mz:participantCount","anonymousParticipationEnabled":"mz:anonymousParticipationEnabled","joinMode":{"@id":"mz:joinMode","@type":"mz:joinModeType"},"externalParticipationUrl":{"@id":"mz:externalParticipationUrl","@type":"schema:URL"},"repliesModerationOption":{"@id":"mz:repliesModerationOption","@type":"@vocab"},"contacts":{"@id":"mz:contacts","@type":"@id"}}],"actor":"http:\/\/example.org\/?author=1","id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=353","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/3","type":"Event","content":"\u003Cp\u003EYou should not miss this Event!\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EYou should not miss this Event!\u003C\/p\u003E"},"name":"WP Test Event","nameMap":{"en":"WP Test Event"},"endTime":"2030-02-29T17:00:00+01:00","location":[{"id":"https:\/\/example.com\/place\/1","type":"Place","attributedTo":"https:\/\/wp-test.event-federation.eu\/@test","name":"Fediverse Place","address":{"type":"PostalAddress","addressCountry":"FediCountry","addressLocality":"FediTown","postalCode":"1337","streetAddress":"FediStreet"}},{"type":"VirtualLocation","url":"https:\/\/example.com\/VirtualMeetingRoom"}],"startTime":"2030-02-29T16:00:00+01:00","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html","timezone":"Europe\/Vienna","category":"MOVEMENTS_POLITICS","joinMode":"external"}}', ), ); } From 882157827abcbf1c3d6bffd1e8888acb620790af Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 14:00:12 +0200 Subject: [PATCH 08/19] lemmy sends 400 for "inbox_timeout" --- includes/class-dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-dispatcher.php b/includes/class-dispatcher.php index b76f00d1c..4190c5525 100644 --- a/includes/class-dispatcher.php +++ b/includes/class-dispatcher.php @@ -40,7 +40,7 @@ class Dispatcher { * @see https://github.com/tfredrich/RestApiTutorial.com/blob/fd08b0f67f07450521d143b123cd6e1846cb2e3b/content/advanced/responses/retries.md * @var int[] */ - public static $retry_error_codes = array( 408, 429, 500, 502, 503, 504 ); + public static $retry_error_codes = array( 400, 408, 429, 500, 502, 503, 504 ); /** * Initialize the class, registering WordPress hooks. From ced037c9fdf4a28f8338c72baad4c19f459c4e2a Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 14:33:22 +0200 Subject: [PATCH 09/19] move function to scheduler class --- includes/class-comment.php | 34 ---------------------------- includes/scheduler/class-comment.php | 33 +++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/includes/class-comment.php b/includes/class-comment.php index 69c458447..0f989376c 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -33,8 +33,6 @@ public static function init() { \add_action( 'update_option_activitypub_allow_likes', array( self::class, 'maybe_update_comment_counts' ), 10, 2 ); \add_action( 'update_option_activitypub_allow_reposts', array( self::class, 'maybe_update_comment_counts' ), 10, 2 ); \add_filter( 'pre_wp_update_comment_count_now', array( static::class, 'pre_wp_update_comment_count_now' ), 10, 3 ); - - \add_action( 'transition_comment_status', array( self::class, 'maybe_announce_interaction' ), 20, 3 ); } /** @@ -806,38 +804,6 @@ public static function pre_wp_update_comment_count_now( $new_count, $old_count, return $new_count; } - /** - * Announce an interaction. - * - * @param string $new_status The new comment status. - * @param string $old_status The old comment status. - * @param \WP_Comment $comment The comment object. - */ - public static function maybe_announce_interaction( $new_status, $old_status, $comment ) { - if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) { - return; - } - - if ( 'approved' !== $new_status || 'approved' === $old_status ) { - return; - } - - $comment = \get_comment( $comment ); - - if ( ! self::was_received( $comment ) ) { - return; - } - - // Get activity from comment meta. - $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); - - if ( ! $activity ) { - return; - } - - add_to_outbox( $activity, 'Announce', Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); - } - /** * Check if a comment type is enabled. * diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index 1d63f01e5..b6d4a10be 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -42,9 +42,12 @@ public static function schedule_comment_activity( $new_status, $old_status, $com } $comment = get_comment( $comment ); + if ( ! $comment ) { + return; + } - // Federate only comments that are written by a registered user. - if ( ! $comment || ! $comment->user_id ) { + if ( ! $comment->user_id ) { + self::maybe_announce_interaction( $new_status, $old_status, $comment ); return; } @@ -77,6 +80,32 @@ public static function schedule_comment_activity( $new_status, $old_status, $com add_to_outbox( $comment, $type, $comment->user_id ); } + /** + * Announce an interaction. + * + * @param string $new_status The new comment status. + * @param string $old_status The old comment status. + * @param \WP_Comment $comment The comment object. + */ + public static function maybe_announce_interaction( $new_status, $old_status, $comment ) { + if ( 'approved' !== $new_status || 'approved' === $old_status ) { + return; + } + + if ( ! self::was_received( $comment ) ) { + return; + } + + // Get activity from comment meta. + $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); + + if ( ! $activity ) { + return; + } + + add_to_outbox( $activity, 'Announce', Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); + } + /** * Schedule Comment Activities on insert. * From c9bdb969b6807c8dfea74b904bf1a7821c5f5c42 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 14:44:13 +0200 Subject: [PATCH 10/19] add blog user to audience --- includes/scheduler/class-comment.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index b6d4a10be..ef04bd1f4 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -88,6 +88,11 @@ public static function schedule_comment_activity( $new_status, $old_status, $com * @param \WP_Comment $comment The comment object. */ public static function maybe_announce_interaction( $new_status, $old_status, $comment ) { + // Only if we're in both Blog and User modes. + if ( ACTIVITYPUB_ACTOR_AND_BLOG_MODE !== \get_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_MODE ) ) { + return; + } + if ( 'approved' !== $new_status || 'approved' === $old_status ) { return; } @@ -103,7 +108,14 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - add_to_outbox( $activity, 'Announce', Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); + $activity['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + $activity['object']['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + + $announce = new Activity(); + $announce->set_type( 'Announce' ); + $announce->set_object( $activity ); + + add_to_outbox( $announce, null, Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); } /** From fb8938d3f58a827033b1fb74e9945823bd8c6a03 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 14:48:05 +0200 Subject: [PATCH 11/19] add missing namespaces --- includes/scheduler/class-comment.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index ef04bd1f4..e9b95ff0c 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -7,6 +7,10 @@ namespace Activitypub\Scheduler; +use Activitypub\Activity; +use Activitypub\Actors; +use Activitypub\Comments; + use function Activitypub\add_to_outbox; use function Activitypub\should_comment_be_federated; From 4a119b3b4facda3d72a91cc84a4b2bd5a461c10d Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 15:04:52 +0200 Subject: [PATCH 12/19] fix namespace issue --- includes/scheduler/class-comment.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index e9b95ff0c..a8b0fd41f 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -9,7 +9,7 @@ use Activitypub\Activity; use Activitypub\Actors; -use Activitypub\Comments; +use Activitypub\Comment as Comment_Util; use function Activitypub\add_to_outbox; use function Activitypub\should_comment_be_federated; @@ -101,7 +101,7 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - if ( ! self::was_received( $comment ) ) { + if ( ! Comment_Util::was_received( $comment ) ) { return; } From 4bd182a855798fa3b575bb38d20f38de6e9e5dcb Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 15:06:22 +0200 Subject: [PATCH 13/19] Fix namespaces --- includes/scheduler/class-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index a8b0fd41f..b833ee36b 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -8,7 +8,7 @@ namespace Activitypub\Scheduler; use Activitypub\Activity; -use Activitypub\Actors; +use Activitypub\Collection\Actors; use Activitypub\Comment as Comment_Util; use function Activitypub\add_to_outbox; From 3888f573a733264a006aa621abf0787b3b83e9e6 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 15:29:30 +0200 Subject: [PATCH 14/19] fix namespace --- includes/scheduler/class-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index b833ee36b..3ed984125 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -7,7 +7,7 @@ namespace Activitypub\Scheduler; -use Activitypub\Activity; +use Activitypub\Activity\Activity; use Activitypub\Collection\Actors; use Activitypub\Comment as Comment_Util; From a5ceb574946e45f5c08fbd049a2e0e1e5a966539 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Wed, 30 Apr 2025 16:28:49 +0200 Subject: [PATCH 15/19] Add `to` --- includes/scheduler/class-comment.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index 3ed984125..6afaf5b1e 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -113,7 +113,9 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co } $activity['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + $activity['to'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); $activity['object']['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + $activity['object']['to'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); $announce = new Activity(); $announce->set_type( 'Announce' ); From f16bf041b4109835309264faf31562109688cac7 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Oct 2025 15:15:18 +0200 Subject: [PATCH 16/19] Fix typo in Comment_Utils class reference Replaces incorrect 'Comment_Utils' with 'Comment_Util' in schedule_comment_delete_activity to ensure the correct utility class is used for checking if a comment was sent. --- includes/scheduler/class-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index d5b71581d..e60061e42 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -146,7 +146,7 @@ public static function schedule_comment_activity_on_insert( $comment_id, $commen */ public static function schedule_comment_delete_activity( $comment_id, $comment ) { // Only send Delete activities for comments that were previously federated. - if ( Comment_Utils::was_sent( $comment ) ) { + if ( Comment_Util::was_sent( $comment ) ) { self::schedule_comment_activity( 'delete', '', $comment ); } } From f90bdb0c66e8140a89a52521d8df3eefb80574d5 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Oct 2025 15:16:17 +0200 Subject: [PATCH 17/19] Fix incorrect import and usage of Comment_Util class Replaces all instances of 'Comment_Util' with 'Comment_Utils' in class-comment.php to match the correct class name and prevent potential errors. --- includes/scheduler/class-comment.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index e60061e42..905a90fd7 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -9,7 +9,7 @@ use Activitypub\Activity\Activity; use Activitypub\Collection\Actors; -use Activitypub\Comment as Comment_Util; +use Activitypub\Comment as Comment_Utils; use function Activitypub\add_to_outbox; use function Activitypub\should_comment_be_federated; @@ -103,7 +103,7 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - if ( ! Comment_Util::was_received( $comment ) ) { + if ( ! Comment_Utils::was_received( $comment ) ) { return; } @@ -146,7 +146,7 @@ public static function schedule_comment_activity_on_insert( $comment_id, $commen */ public static function schedule_comment_delete_activity( $comment_id, $comment ) { // Only send Delete activities for comments that were previously federated. - if ( Comment_Util::was_sent( $comment ) ) { + if ( Comment_Utils::was_sent( $comment ) ) { self::schedule_comment_activity( 'delete', '', $comment ); } } From 11e098c54890ebc2f61edea176e214d329b4ae38 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 3 Oct 2025 07:56:35 +0200 Subject: [PATCH 18/19] Improve Undo handler object validation and defaults Adds a default value for the 'type' field in handle_undo to prevent undefined index errors. Updates object attribute validation to only check required fields if 'object' is an array, allowing string/URI objects. Adds a test case to ensure URI objects pass validation. --- includes/handler/class-undo.php | 25 +++++++++++----------- tests/includes/handler/class-test-undo.php | 10 +++++++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/includes/handler/class-undo.php b/includes/handler/class-undo.php index 45433cc25..a1346ac11 100644 --- a/includes/handler/class-undo.php +++ b/includes/handler/class-undo.php @@ -33,7 +33,7 @@ public static function init() { * @param int|null $user_id The ID of the user who initiated the "Undo" activity. */ public static function handle_undo( $activity, $user_id ) { - $type = $activity['object']['type']; + $type = $activity['object']['type'] ?? 'Announce'; $success = false; $result = null; @@ -48,10 +48,7 @@ public static function handle_undo( $activity, $user_id ) { $success = Followers::remove( $post, $user_id ); } } - } - - // Handle "Undo" requests for "Like" and "Create" activities. - if ( in_array( $type, array( 'Like', 'Create', 'Announce' ), true ) ) { + } if ( in_array( $type, array( 'Like', 'Create', 'Announce' ), true ) ) { // Handle "Undo" requests for "Like" and "Create" activities. if ( ! ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS ) { $object_id = object_to_uri( $activity['object'] ); $result = Comment::object_id_to_comment( esc_url_raw( $object_id ) ); @@ -107,15 +104,17 @@ public static function validate_object( $valid, $param, $request ) { return false; } - $required_object_attributes = array( - 'id', - 'type', - 'actor', - 'object', - ); + if ( \is_array( $json_params['object'] ) ) { + $required_object_attributes = array( + 'id', + 'type', + 'actor', + 'object', + ); - if ( ! empty( \array_diff( $required_object_attributes, \array_keys( $json_params['object'] ) ) ) ) { - return false; + if ( ! empty( \array_diff( $required_object_attributes, \array_keys( $json_params['object'] ) ) ) ) { + return false; + } } return $valid; diff --git a/tests/includes/handler/class-test-undo.php b/tests/includes/handler/class-test-undo.php index b3e57e81c..6a7dac049 100644 --- a/tests/includes/handler/class-test-undo.php +++ b/tests/includes/handler/class-test-undo.php @@ -452,6 +452,16 @@ public function validate_object_provider() { false, 'Missing object.object should fail validation', ), + 'uri_object' => array( + array( + 'type' => 'Undo', + 'actor' => 'https://example.com/actor', + 'object' => 'https://example.com/activity/123', + ), + true, + true, + 'URI object should pass validation', + ), ); } From 8777641a398669ed3c3e728960d0358943d44303 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 3 Oct 2025 07:57:11 +0200 Subject: [PATCH 19/19] Revert "Improve Undo handler object validation and defaults" This reverts commit 11e098c54890ebc2f61edea176e214d329b4ae38. --- includes/handler/class-undo.php | 25 +++++++++++----------- tests/includes/handler/class-test-undo.php | 10 --------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/includes/handler/class-undo.php b/includes/handler/class-undo.php index a1346ac11..45433cc25 100644 --- a/includes/handler/class-undo.php +++ b/includes/handler/class-undo.php @@ -33,7 +33,7 @@ public static function init() { * @param int|null $user_id The ID of the user who initiated the "Undo" activity. */ public static function handle_undo( $activity, $user_id ) { - $type = $activity['object']['type'] ?? 'Announce'; + $type = $activity['object']['type']; $success = false; $result = null; @@ -48,7 +48,10 @@ public static function handle_undo( $activity, $user_id ) { $success = Followers::remove( $post, $user_id ); } } - } if ( in_array( $type, array( 'Like', 'Create', 'Announce' ), true ) ) { // Handle "Undo" requests for "Like" and "Create" activities. + } + + // Handle "Undo" requests for "Like" and "Create" activities. + if ( in_array( $type, array( 'Like', 'Create', 'Announce' ), true ) ) { if ( ! ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS ) { $object_id = object_to_uri( $activity['object'] ); $result = Comment::object_id_to_comment( esc_url_raw( $object_id ) ); @@ -104,17 +107,15 @@ public static function validate_object( $valid, $param, $request ) { return false; } - if ( \is_array( $json_params['object'] ) ) { - $required_object_attributes = array( - 'id', - 'type', - 'actor', - 'object', - ); + $required_object_attributes = array( + 'id', + 'type', + 'actor', + 'object', + ); - if ( ! empty( \array_diff( $required_object_attributes, \array_keys( $json_params['object'] ) ) ) ) { - return false; - } + if ( ! empty( \array_diff( $required_object_attributes, \array_keys( $json_params['object'] ) ) ) ) { + return false; } return $valid; diff --git a/tests/includes/handler/class-test-undo.php b/tests/includes/handler/class-test-undo.php index 6a7dac049..b3e57e81c 100644 --- a/tests/includes/handler/class-test-undo.php +++ b/tests/includes/handler/class-test-undo.php @@ -452,16 +452,6 @@ public function validate_object_provider() { false, 'Missing object.object should fail validation', ), - 'uri_object' => array( - array( - 'type' => 'Undo', - 'actor' => 'https://example.com/actor', - 'object' => 'https://example.com/activity/123', - ), - true, - true, - 'URI object should pass validation', - ), ); }