PluginProbe
ActivityPub / 3.2.4
ActivityPub v3.2.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 / class-activity-dispatcher.php

class-activity-dispatcher.php in ActivityPub 3.2.4, at includes/class-activity-dispatcher.php

316 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Activitypub;
3
4 use WP_Post;
5 use WP_Comment;
6 use Activitypub\Http;
7 use Activitypub\Collection\Users;
8 use Activitypub\Activity\Activity;
9 use Activitypub\Collection\Followers;
10 use Activitypub\Transformer\Factory;
11 use Activitypub\Transformer\Post;
12 use Activitypub\Transformer\Comment;
13
14 use function Activitypub\object_to_uri;
15 use function Activitypub\is_single_user;
16 use function Activitypub\is_user_disabled;
17 use function Activitypub\safe_remote_post;
18 use function Activitypub\set_wp_object_state;
19
20 /**
21 * ActivityPub Activity_Dispatcher Class
22 *
23 * @author Matthias Pfefferle
24 *
25 * @see https://www.w3.org/TR/activitypub/
26 */
27 class Activity_Dispatcher {
28 /**
29 * Initialize the class, registering WordPress hooks.
30 */
31 public static function init() {
32 \add_action( 'activitypub_send_post', array( self::class, 'send_post' ), 10, 2 );
33 \add_action( 'activitypub_send_comment', array( self::class, 'send_comment' ), 10, 2 );
34
35 \add_action( 'activitypub_send_activity', array( self::class, 'send_activity' ), 10, 2 );
36 \add_action( 'activitypub_send_activity', array( self::class, 'send_activity_or_announce' ), 10, 2 );
37 \add_action( 'activitypub_send_update_profile_activity', array( self::class, 'send_profile_update' ), 10, 1 );
38
39 // Default filters to add Inboxes to sent to
40 \add_filter( 'activitypub_send_to_inboxes', array( self::class, 'add_inboxes_of_follower' ), 10, 2 );
41 \add_filter( 'activitypub_send_to_inboxes', array( self::class, 'add_inboxes_by_mentioned_actors' ), 10, 3 );
42 \add_filter( 'activitypub_send_to_inboxes', array( self::class, 'add_inboxes_of_replied_urls' ), 10, 3 );
43 }
44
45 /**
46 * Send Activities to followers and mentioned users or `Announce` (boost) a blog post.
47 *
48 * @param mixed $wp_object The ActivityPub Post.
49 * @param string $type The Activity-Type.
50 *
51 * @return void
52 */
53 public static function send_activity_or_announce( $wp_object, $type ) {
54 if ( is_user_type_disabled( 'blog' ) ) {
55 return;
56 }
57
58 if ( is_single_user() ) {
59 self::send_activity( $wp_object, $type, Users::BLOG_USER_ID );
60 } else {
61 self::send_announce( $wp_object, $type );
62 }
63 }
64
65 /**
66 * Send Activities to followers and mentioned users.
67 *
68 * @param mixed $wp_object The ActivityPub Post.
69 * @param string $type The Activity-Type.
70 *
71 * @return void
72 */
73 public static function send_activity( $wp_object, $type, $user_id = null ) {
74 $transformer = Factory::get_transformer( $wp_object ); // Could potentially return a `\WP_Error` instance.
75
76 if ( \is_wp_error( $transformer ) ) {
77 return;
78 }
79
80 if ( null !== $user_id ) {
81 $transformer->change_wp_user_id( $user_id );
82 }
83
84 $user_id = $transformer->get_wp_user_id();
85
86 if ( is_user_disabled( $user_id ) ) {
87 return;
88 }
89
90 $activity = $transformer->to_activity( $type );
91
92 self::send_activity_to_followers( $activity, $user_id, $wp_object );
93 }
94
95 /**
96 * Send Announces to followers and mentioned users.
97 *
98 * @param mixed $wp_object The ActivityPub Post.
99 * @param string $type The Activity-Type.
100 *
101 * @return void
102 */
103 public static function send_announce( $wp_object, $type ) {
104 if ( ! in_array( $type, array( 'Create', 'Update', 'Delete' ), true ) ) {
105 return;
106 }
107
108 if ( is_user_disabled( Users::BLOG_USER_ID ) ) {
109 return;
110 }
111
112 $transformer = Factory::get_transformer( $wp_object );
113
114 if ( \is_wp_error( $transformer ) ) {
115 return;
116 }
117
118 $user_id = Users::BLOG_USER_ID;
119 $activity = $transformer->to_activity( $type );
120 $user = Users::get_by_id( Users::BLOG_USER_ID );
121
122 $announce = new Activity();
123 $announce->set_type( 'Announce' );
124 $announce->set_object( $activity );
125 $announce->set_actor( $user->get_id() );
126
127 self::send_activity_to_followers( $announce, $user_id, $wp_object );
128 }
129
130 /**
131 * Send a "Update" Activity when a user updates their profile.
132 *
133 * @param int $user_id The user ID to send an update for.
134 *
135 * @return void
136 */
137 public static function send_profile_update( $user_id ) {
138 $user = Users::get_by_various( $user_id );
139
140 // bail if that's not a good user
141 if ( is_wp_error( $user ) ) {
142 return;
143 }
144
145 // build the update
146 $activity = new Activity();
147 $activity->set_id( $user->get_url() . '#update' );
148 $activity->set_type( 'Update' );
149 $activity->set_actor( $user->get_url() );
150 $activity->set_object( $user->get_url() );
151 $activity->set_to( 'https://www.w3.org/ns/activitystreams#Public' );
152
153 // send the update
154 self::send_activity_to_followers( $activity, $user_id, $user );
155 }
156
157 /**
158 * Send an Activity to all followers and mentioned users.
159 *
160 * @param Activity $activity The ActivityPub Activity.
161 * @param int $user_id The user ID.
162 * @param WP_User|WP_Post|WP_Comment $wp_object The WordPress object.
163 *
164 * @return void
165 */
166 private static function send_activity_to_followers( $activity, $user_id, $wp_object ) {
167 // check if the Activity should be send to the followers
168 if ( ! apply_filters( 'activitypub_send_activity_to_followers', true, $activity, $user_id, $wp_object ) ) {
169 return;
170 }
171
172 $inboxes = apply_filters( 'activitypub_send_to_inboxes', array(), $user_id, $activity );
173 $inboxes = array_unique( $inboxes );
174
175 if ( empty( $inboxes ) ) {
176 return;
177 }
178
179 $json = $activity->to_json();
180
181 foreach ( $inboxes as $inbox ) {
182 safe_remote_post( $inbox, $json, $user_id );
183 }
184
185 set_wp_object_state( $wp_object, 'federated' );
186 }
187
188 /**
189 * Send a "Create" or "Update" Activity for a WordPress Post.
190 *
191 * @param int $id The WordPress Post ID.
192 * @param string $type The Activity-Type.
193 *
194 * @return void
195 */
196 public static function send_post( $id, $type ) {
197 $post = get_post( $id );
198
199 if ( ! $post ) {
200 return;
201 }
202
203 do_action( 'activitypub_send_activity', $post, $type );
204 do_action(
205 sprintf(
206 'activitypub_send_%s_activity',
207 \strtolower( $type )
208 ),
209 $post
210 );
211 }
212
213 /**
214 * Send a "Create" or "Update" Activity for a WordPress Comment.
215 *
216 * @param int $id The WordPress Comment ID.
217 * @param string $type The Activity-Type.
218 *
219 * @return void
220 */
221 public static function send_comment( $id, $type ) {
222 $comment = get_comment( $id );
223
224 if ( ! $comment ) {
225 return;
226 }
227
228 do_action( 'activitypub_send_activity', $comment, $type );
229 do_action(
230 sprintf(
231 'activitypub_send_%s_activity',
232 \strtolower( $type )
233 ),
234 $comment
235 );
236 }
237
238 /**
239 * Default filter to add Inboxes of Followers
240 *
241 * @param array $inboxes The list of Inboxes
242 * @param int $user_id The WordPress User-ID
243 *
244 * @return array The filtered Inboxes
245 */
246 public static function add_inboxes_of_follower( $inboxes, $user_id ) {
247 $follower_inboxes = Followers::get_inboxes( $user_id );
248
249 return array_merge( $inboxes, $follower_inboxes );
250 }
251
252 /**
253 * Default filter to add Inboxes of Mentioned Actors
254 *
255 * @param array $inboxes The list of Inboxes
256 * @param int $user_id The WordPress User-ID
257 * @param array $activity The ActivityPub Activity
258 *
259 * @return array The filtered Inboxes
260 */
261 public static function add_inboxes_by_mentioned_actors( $inboxes, $user_id, $activity ) {
262 $cc = $activity->get_cc();
263 if ( $cc ) {
264 $mentioned_inboxes = Mention::get_inboxes( $cc );
265
266 return array_merge( $inboxes, $mentioned_inboxes );
267 }
268
269 return $inboxes;
270 }
271
272 /**
273 * Default filter to add Inboxes of Posts that are set as `in-reply-to`
274 *
275 * @param array $inboxes The list of Inboxes
276 * @param int $user_id The WordPress User-ID
277 * @param array $activity The ActivityPub Activity
278 *
279 * @return array The filtered Inboxes
280 */
281 public static function add_inboxes_of_replied_urls( $inboxes, $user_id, $activity ) {
282 $in_reply_to = $activity->get_in_reply_to();
283
284 if ( ! $in_reply_to ) {
285 return $inboxes;
286 }
287
288 if ( ! is_array( $in_reply_to ) ) {
289 $in_reply_to = array( $in_reply_to );
290 }
291
292 foreach ( $in_reply_to as $url ) {
293 $object = Http::get_remote_object( $url );
294
295 if ( ! $object || empty( $object['attributedTo'] ) ) {
296 continue;
297 }
298
299 $actor = object_to_uri( $object['attributedTo'] );
300 $actor = Http::get_remote_object( $actor );
301
302 if ( ! $actor ) {
303 continue;
304 }
305
306 if ( ! empty( $actor['endpoints']['sharedInbox'] ) ) {
307 $inboxes[] = $actor['endpoints']['sharedInbox'];
308 } elseif ( ! empty( $actor['inbox'] ) ) {
309 $inboxes[] = $actor['inbox'];
310 }
311 }
312
313 return $inboxes;
314 }
315 }
316