PluginProbe
ActivityPub / 7.8.4
ActivityPub v7.8.4
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / handler / class-follow.php

class-follow.php in ActivityPub 7.8.4, at includes/handler/class-follow.php

152 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Follow handler file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Handler;
9
10 use Activitypub\Activity\Activity;
11 use Activitypub\Collection\Actors;
12 use Activitypub\Collection\Followers;
13 use Activitypub\Collection\Remote_Actors;
14
15 use function Activitypub\add_to_outbox;
16
17 /**
18 * Handle Follow requests.
19 */
20 class Follow {
21 /**
22 * Initialize the class, registering WordPress hooks.
23 */
24 public static function init() {
25 \add_action( 'activitypub_inbox_follow', array( self::class, 'handle_follow' ), 10, 2 );
26 \add_action( 'activitypub_handled_follow', array( self::class, 'queue_accept' ), 10, 4 );
27 }
28
29 /**
30 * Handle "Follow" requests.
31 *
32 * @param array $activity The activity object.
33 * @param int|int[] $user_ids The user ID(s).
34 */
35 public static function handle_follow( $activity, $user_ids ) {
36 // Extract the user ID (follow requests are always for a single user).
37 $user_id = \is_array( $user_ids ) ? \reset( $user_ids ) : $user_ids;
38
39 if ( Actors::APPLICATION_USER_ID === $user_id ) {
40 self::queue_reject( $activity, $user_id );
41 return;
42 }
43
44 // Check if the actor already follows the user.
45 $already_following = false;
46 $remote_actor = Remote_Actors::get_by_uri( $activity['actor'] );
47 if ( ! \is_wp_error( $remote_actor ) ) {
48 $already_following = Followers::follows( $remote_actor->ID, $user_id );
49 }
50
51 // Save follower if not already following.
52 if ( $already_following ) {
53 $success = false;
54 } else {
55 $remote_actor = Followers::add( $user_id, $activity['actor'] );
56 $success = ! \is_wp_error( $remote_actor );
57
58 if ( $success ) {
59 $remote_actor = \get_post( $remote_actor );
60 }
61 }
62
63 /**
64 * Fires after a new follower has been added.
65 *
66 * @deprecated 7.5.0 Use "activitypub_handled_follow" instead.
67 *
68 * @param string $actor The URL of the actor (follower) who initiated the follow.
69 * @param array $activity The complete activity data of the follow request.
70 * @param int $user_id The ID of the WordPress user being followed.
71 * @param \WP_Post|\WP_Error $remote_actor The Actor object containing the new follower's data.
72 */
73 \do_action_deprecated( 'activitypub_followers_post_follow', array( $activity['actor'], $activity, $user_id, $remote_actor ), '7.5.0', 'activitypub_handled_follow' );
74
75 /**
76 * Fires after a Follow activity has been handled.
77 *
78 * @param array $activity The ActivityPub activity data.
79 * @param int[] $user_ids The local user IDs.
80 * @param bool $success True on success, false otherwise.
81 * @param \WP_Post|\WP_Error $remote_actor The remote actor/follower, or WP_Error if failed.
82 */
83 \do_action( 'activitypub_handled_follow', $activity, (array) $user_ids, $success, $remote_actor );
84 }
85
86 /**
87 * Send Accept response.
88 *
89 * @param array $activity_object The ActivityPub activity data.
90 * @param int|int[] $user_ids The local user IDs.
91 * @param bool $success True on success, false otherwise.
92 * @param \WP_Post|\WP_Error $remote_actor The remote actor/follower, or WP_Error if failed.
93 */
94 public static function queue_accept( $activity_object, $user_ids, $success, $remote_actor ) {
95 if ( \is_wp_error( $remote_actor ) ) {
96 // Impossible to send a "Reject" because we can not get the Remote-Inbox.
97 return;
98 }
99
100 // Extract the user ID from the array (follow requests are always for a single user).
101 $user_id = \is_array( $user_ids ) ? \reset( $user_ids ) : $user_ids;
102
103 $actor = $activity_object['actor'];
104
105 // Only send minimal data.
106 $activity_object = array_intersect_key(
107 $activity_object,
108 array(
109 'id' => 1,
110 'type' => 1,
111 'actor' => 1,
112 'object' => 1,
113 )
114 );
115
116 $activity = new Activity();
117 $activity->set_type( 'Accept' );
118 $activity->set_actor( Actors::get_by_id( $user_id )->get_id() );
119 $activity->set_object( $activity_object );
120 $activity->set_to( array( $actor ) );
121
122 add_to_outbox( $activity, null, $user_id, ACTIVITYPUB_CONTENT_VISIBILITY_PRIVATE );
123 }
124
125 /**
126 * Send Reject response.
127 *
128 * @param array $activity The Activity array.
129 * @param int $user_id The ID of the WordPress User.
130 */
131 public static function queue_reject( $activity, $user_id ) {
132 // Only send minimal data.
133 $origin_activity = array_intersect_key(
134 $activity,
135 array(
136 'id' => 1,
137 'type' => 1,
138 'actor' => 1,
139 'object' => 1,
140 )
141 );
142
143 $activity = new Activity();
144 $activity->set_type( 'Reject' );
145 $activity->set_actor( Actors::get_by_id( $user_id )->get_id() );
146 $activity->set_object( $origin_activity );
147 $activity->set_to( array( $origin_activity['actor'] ) );
148
149 add_to_outbox( $activity, null, $user_id, ACTIVITYPUB_CONTENT_VISIBILITY_PRIVATE );
150 }
151 }
152