PluginProbe
ActivityPub / 7.8.2
ActivityPub v7.8.2
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
← All changes | includes/collection/class-interactions.php +51 -100 8.2.0 → 7.8.2 View file →
@@ -7,9 +7,8 @@
7 7
8 8 namespace Activitypub\Collection;
9 9
10 10 use Activitypub\Comment;
11 -use Activitypub\Emoji;
12 11 use Activitypub\Webfinger;
13 12 use WP_Comment_Query;
14 13
15 14 use function Activitypub\get_remote_metadata_by_actor;
@@ -28,18 +27,14 @@
28 27
29 28 /**
30 29 * Add a comment to a post.
31 30 *
32 - * When $user_id is provided, comment author data is built from the
33 - * local WordPress user instead of fetching remote actor metadata.
31 + * @param array $activity The activity-object.
34 32 *
35 - * @param array $activity The activity-object.
36 - * @param int|null $user_id Optional. Local user ID for outbox replies.
37 - *
38 33 * @return int|false|\WP_Error The comment ID or false or WP_Error on failure.
39 34 */
40 - public static function add_comment( $activity, $user_id = null ) {
41 - $comment_data = self::activity_to_comment( $activity, $user_id );
35 + public static function add_comment( $activity ) {
36 + $comment_data = self::activity_to_comment( $activity );
42 37
43 38 if ( ! $comment_data ) {
44 39 return false;
45 40 }
@@ -74,9 +69,9 @@
74 69 $comment_post_id = \url_to_postid( $target_url );
75 70
76 71 if ( ! $comment_post_id ) {
77 72 // Check for `ap_post`.
78 - $comment_post = Remote_Posts::get_by_guid( $target_url );
73 + $comment_post = Posts::get_by_guid( $target_url );
79 74 if ( $comment_post instanceof \WP_Post ) {
80 75 $comment_post_id = $comment_post->ID;
81 76 }
82 77 }
@@ -107,12 +102,8 @@
107 102 */
108 103 public static function update_comment( $activity ) {
109 104 $meta = get_remote_metadata_by_actor( $activity['actor'] );
110 105
111 - if ( \is_wp_error( $meta ) || ! \is_array( $meta ) ) {
112 - return $meta;
113 - }
114 -
115 106 // Determine comment_ID.
116 107 $comment = object_id_to_comment( \esc_url_raw( $activity['object']['id'] ) );
117 108 $comment_data = \get_comment( $comment, ARRAY_A );
118 109
@@ -120,17 +111,11 @@
120 111 return false;
121 112 }
122 113
123 114 // Found a local comment id.
124 - $comment_data['comment_author'] = \sanitize_text_field( empty( $meta['name'] ) ? $meta['preferredUsername'] : $meta['name'] );
115 + $comment_data['comment_author'] = \esc_attr( empty( $meta['name'] ) ? $meta['preferredUsername'] : $meta['name'] );
116 + $comment_data['comment_content'] = \addslashes( $activity['object']['content'] );
125 117
126 - /*
127 - * Wrap emoji in content with blocks for runtime replacement.
128 - * Note: Remote images in comments are stripped for security (only emoji allowed).
129 - */
130 - $content = Emoji::wrap_in_content( $activity['object']['content'], $activity['object'] );
131 - $comment_data['comment_content'] = \addslashes( $content );
132 -
133 118 return self::persist( $comment_data, self::UPDATE );
134 119 }
135 120
136 121 /**
@@ -146,9 +131,9 @@
146 131 $parent_comment_id = url_to_commentid( $url );
147 132
148 133 if ( ! $comment_post_id ) {
149 134 // Check for `ap_post`.
150 - $comment_post = Remote_Posts::get_by_guid( $url );
135 + $comment_post = Posts::get_by_guid( $url );
151 136 if ( $comment_post instanceof \WP_Post ) {
152 137 $comment_post_id = $comment_post->ID;
153 138 }
154 139 }
@@ -330,81 +315,51 @@
330 315 if ( ! array_key_exists( 'p', $allowed_tags ) ) {
331 316 $allowed_tags['p'] = array();
332 317 }
333 318
334 - // Add `img` for custom emoji support with strict validation.
335 - $emoji_html = Emoji::get_kses_allowed_html();
336 - if ( ! array_key_exists( 'img', $allowed_tags ) ) {
337 - $allowed_tags['img'] = $emoji_html['img'];
338 - }
339 -
340 319 return $allowed_tags;
341 320 }
342 321
343 322 /**
344 - * Convert an Activity to a WP_Comment.
323 + * Convert an Activity to a WP_Comment
345 324 *
346 - * When $user_id is provided, comment author data is built from the
347 - * local WordPress user instead of fetching remote actor metadata.
325 + * @param array $activity The Activity array.
348 326 *
349 - * @param array $activity The Activity array.
350 - * @param int|null $user_id Optional. Local user ID for outbox comments.
351 - *
352 327 * @return array|false The comment data or false on failure.
353 328 */
354 - public static function activity_to_comment( $activity, $user_id = null ) {
329 + public static function activity_to_comment( $activity ) {
355 330 $comment_content = null;
331 + $actor = object_to_uri( $activity['actor'] ?? null );
332 + $actor = get_remote_metadata_by_actor( $actor );
356 333
357 - if ( $user_id ) {
358 - // Outbox: resolve author from the local WordPress user.
359 - $user = \get_userdata( $user_id );
334 + // Check Actor-Meta.
335 + if ( ! $actor || is_wp_error( $actor ) ) {
336 + return false;
337 + }
360 338
361 - if ( ! $user ) {
362 - return false;
363 - }
339 + // Check Actor-Name.
340 + $comment_author = null;
341 + if ( ! empty( $actor['name'] ) ) {
342 + $comment_author = $actor['name'];
343 + } elseif ( ! empty( $actor['preferredUsername'] ) ) {
344 + $comment_author = $actor['preferredUsername'];
345 + }
364 346
365 - $comment_author = $user->display_name;
366 - $comment_author_url = $user->user_url;
367 - $comment_author_email = $user->user_email;
368 - $comment_content = \wp_kses_post( $activity['object']['content'] ?? '' );
369 - } else {
370 - // S2S: resolve author from remote actor metadata.
371 - $actor = object_to_uri( $activity['actor'] ?? null );
372 - $actor = get_remote_metadata_by_actor( $actor );
347 + if ( empty( $comment_author ) && \get_option( 'require_name_email' ) ) {
348 + return false;
349 + }
373 350
374 - if ( ! $actor || is_wp_error( $actor ) ) {
375 - return false;
376 - }
351 + $url = object_to_uri( $actor['url'] ?? $actor['id'] );
377 352
378 - $comment_author = null;
379 - if ( ! empty( $actor['name'] ) ) {
380 - $comment_author = $actor['name'];
381 - } elseif ( ! empty( $actor['preferredUsername'] ) ) {
382 - $comment_author = $actor['preferredUsername'];
383 - }
353 + if ( isset( $activity['object']['content'] ) ) {
354 + $comment_content = \addslashes( $activity['object']['content'] );
355 + }
384 356
385 - if ( empty( $comment_author ) && \get_option( 'require_name_email' ) ) {
386 - return false;
387 - }
388 -
389 - $comment_author = $comment_author ?? __( 'Anonymous', 'activitypub' );
390 - $comment_author_url = \esc_url_raw( object_to_uri( $actor['url'] ?? $actor['id'] ) );
391 -
392 - $webfinger = Webfinger::uri_to_acct( $comment_author_url );
393 - if ( is_wp_error( $webfinger ) ) {
394 - $comment_author_email = '';
395 - } else {
396 - $comment_author_email = str_replace( 'acct:', '', $webfinger );
397 - }
398 -
399 - if ( isset( $activity['object']['content'] ) ) {
400 - /*
401 - * Wrap emoji in content with blocks for runtime replacement.
402 - * Note: Remote images in comments are stripped for security (only emoji allowed).
403 - */
404 - $content = Emoji::wrap_in_content( $activity['object']['content'], $activity['object'] );
405 - $comment_content = \addslashes( $content );
406 - }
357 + $webfinger = Webfinger::uri_to_acct( $url );
358 + if ( is_wp_error( $webfinger ) ) {
359 + $webfinger = '';
360 + } else {
361 + $webfinger = str_replace( 'acct:', '', $webfinger );
407 362 }
408 363
409 364 $published = $activity['object']['published'] ?? $activity['published'] ?? 'now';
410 365 $gm_date = \gmdate( 'Y-m-d H:i:s', \strtotime( $published ) );
@@ -409,36 +364,32 @@
409 364 $published = $activity['object']['published'] ?? $activity['published'] ?? 'now';
410 365 $gm_date = \gmdate( 'Y-m-d H:i:s', \strtotime( $published ) );
411 366
412 367 $comment_data = array(
413 - 'comment_author' => $comment_author,
414 - 'comment_author_url' => $comment_author_url,
368 + 'comment_author' => $comment_author ?? __( 'Anonymous', 'activitypub' ),
369 + 'comment_author_url' => \esc_url_raw( $url ),
415 370 'comment_content' => $comment_content,
416 371 'comment_type' => 'comment',
417 - 'comment_author_email' => $comment_author_email,
372 + 'comment_author_email' => $webfinger,
418 373 'comment_date' => \get_date_from_gmt( $gm_date ),
419 374 'comment_date_gmt' => $gm_date,
420 - 'comment_meta' => array(),
375 + 'comment_meta' => array(
376 + 'source_id' => \esc_url_raw( object_to_uri( $activity['object'] ) ),
377 + 'protocol' => 'activitypub',
378 + ),
421 379 );
422 380
423 - if ( $user_id ) {
424 - $comment_data['user_id'] = $user_id;
425 - } else {
426 - $comment_data['comment_meta']['protocol'] = 'activitypub';
427 - $comment_data['comment_meta']['source_id'] = \esc_url_raw( object_to_uri( $activity['object'] ) );
428 -
429 - // Store reference to remote actor post.
430 - $actor_uri = object_to_uri( $activity['actor'] ?? null );
431 - if ( $actor_uri ) {
432 - $remote_actor = Remote_Actors::get_by_uri( $actor_uri );
433 - if ( ! \is_wp_error( $remote_actor ) ) {
434 - $comment_data['comment_meta']['_activitypub_remote_actor_id'] = $remote_actor->ID;
435 - }
381 + // Store reference to remote actor post.
382 + $actor_uri = object_to_uri( $activity['actor'] ?? null );
383 + if ( $actor_uri ) {
384 + $remote_actor = Remote_Actors::get_by_uri( $actor_uri );
385 + if ( ! \is_wp_error( $remote_actor ) ) {
386 + $comment_data['comment_meta']['_activitypub_remote_actor_id'] = $remote_actor->ID;
436 387 }
388 + }
437 389
438 - if ( isset( $activity['object']['url'] ) ) {
439 - $comment_data['comment_meta']['source_url'] = \esc_url_raw( object_to_uri( $activity['object']['url'] ) );
440 - }
390 + if ( isset( $activity['object']['url'] ) ) {
391 + $comment_data['comment_meta']['source_url'] = \esc_url_raw( object_to_uri( $activity['object']['url'] ) );
441 392 }
442 393
443 394 return $comment_data;
444 395 }