re-add mention functionality

not perfect but works as expected
This commit is contained in:
Matthias Pfefferle 2023-04-25 11:59:08 +02:00
parent 764a091046
commit d1f6973d9b
3 changed files with 67 additions and 6 deletions

View file

@ -67,7 +67,11 @@ class Activity_Dispatcher {
$activitypub_activity = new Activity( $activity_type ); $activitypub_activity = new Activity( $activity_type );
$activitypub_activity->from_post( $activitypub_post ); $activitypub_activity->from_post( $activitypub_post );
$inboxes = Followers::get_inboxes( $user_id ); $follower_inboxes = Followers::get_inboxes( $user_id );
$mentioned_inboxes = Mention::get_inboxes( $activitypub_activity->get_cc() );
$inboxes = array_merge( $follower_inboxes, $mentioned_inboxes );
$inboxes = array_unique( $inboxes );
foreach ( $inboxes as $inbox ) { foreach ( $inboxes as $inbox ) {
$activity = $activitypub_activity->to_json(); $activity = $activitypub_activity->to_json();

View file

@ -1,6 +1,8 @@
<?php <?php
namespace Activitypub; namespace Activitypub;
use WP_Error;
/** /**
* ActivityPub Mention Class * ActivityPub Mention Class
* *
@ -57,10 +59,11 @@ class Mention {
* A callback for preg_replace to build the user links * A callback for preg_replace to build the user links
* *
* @param array $result the preg_match results * @param array $result the preg_match results
*
* @return string the final string * @return string the final string
*/ */
public static function replace_with_links( $result ) { public static function replace_with_links( $result ) {
$metadata = \ActivityPub\get_remote_metadata_by_actor( $result[0] ); $metadata = get_remote_metadata_by_actor( $result[0], true );
if ( ! is_wp_error( $metadata ) && ! empty( $metadata['url'] ) ) { if ( ! is_wp_error( $metadata ) && ! empty( $metadata['url'] ) ) {
$username = ltrim( $result[0], '@' ); $username = ltrim( $result[0], '@' );
if ( ! empty( $metadata['name'] ) ) { if ( ! empty( $metadata['name'] ) ) {
@ -76,17 +79,64 @@ class Mention {
return $result[0]; return $result[0];
} }
/**
* Get the Inboxes for the mentioned Actors
*
* @param array $mentioned The list of Actors that were mentioned
*
* @return array The list of Inboxes
*/
public static function get_inboxes( $mentioned ) {
$inboxes = array();
foreach ( $mentioned as $actor ) {
$inbox = self::get_inbox_by_mentioned_actor( $actor );
if ( ! is_wp_error( $inbox ) && $inbox ) {
$inboxes[] = $inbox;
}
}
return $inboxes;
}
/**
* Get the inbox from the Remote-Profile of a mentioned Actor
*
* @param string $actor The Actor-URL
*
* @return string The Inbox-URL
*/
public static function get_inbox_by_mentioned_actor( $actor ) {
$metadata = get_remote_metadata_by_actor( $actor, true );
if ( \is_wp_error( $metadata ) ) {
return $metadata;
}
if ( isset( $metadata['endpoints'] ) && isset( $metadata['endpoints']['sharedInbox'] ) ) {
return $metadata['endpoints']['sharedInbox'];
}
if ( \array_key_exists( 'inbox', $metadata ) ) {
return $metadata['inbox'];
}
return new WP_Error( 'activitypub_no_inbox', \__( 'No "Inbox" found', 'activitypub' ), $metadata );
}
/** /**
* Extract the mentions from the post_content. * Extract the mentions from the post_content.
* *
* @param array $mentions The already found mentions. * @param array $mentions The already found mentions.
* @param string $post_content The post content. * @param string $post_content The post content.
*
* @return mixed The discovered mentions. * @return mixed The discovered mentions.
*/ */
public static function extract_mentions( $mentions, $post_content ) { public static function extract_mentions( $mentions, $post_content ) {
\preg_match_all( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/i', $post_content, $matches ); \preg_match_all( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/i', $post_content, $matches );
foreach ( $matches[0] as $match ) { foreach ( $matches[0] as $match ) {
$link = \Activitypub\Webfinger::resolve( $match ); $link = Webfinger::resolve( $match );
if ( ! is_wp_error( $link ) ) { if ( ! is_wp_error( $link ) ) {
$mentions[ $match ] = $link; $mentions[ $match ] = $link;
} }

View file

@ -102,9 +102,12 @@ function get_webfinger_resource( $user_id ) {
* Requests the Meta-Data from the Actors profile * Requests the Meta-Data from the Actors profile
* *
* @param string $actor The Actor URL * @param string $actor The Actor URL
* @param bool $cache Enable/Disable caching of the meta.
* This does not effect Error-Caching.
*
* @return array The Actor profile as array * @return array The Actor profile as array
*/ */
function get_remote_metadata_by_actor( $actor ) { function get_remote_metadata_by_actor( $actor, $cache = false ) {
$pre = apply_filters( 'pre_get_remote_metadata_by_actor', false, $actor ); $pre = apply_filters( 'pre_get_remote_metadata_by_actor', false, $actor );
if ( $pre ) { if ( $pre ) {
return $pre; return $pre;
@ -158,6 +161,10 @@ function get_remote_metadata_by_actor( $actor ) {
$metadata = \wp_remote_retrieve_body( $response ); $metadata = \wp_remote_retrieve_body( $response );
$metadata = \json_decode( $metadata, true ); $metadata = \json_decode( $metadata, true );
if ( true === $cache ) {
\set_transient( $transient_key, $metadata, WEEK_IN_SECONDS );
}
if ( ! $metadata ) { if ( ! $metadata ) {
$metadata = new \WP_Error( 'activitypub_invalid_json', \__( 'No valid JSON data', 'activitypub' ), $actor ); $metadata = new \WP_Error( 'activitypub_invalid_json', \__( 'No valid JSON data', 'activitypub' ), $actor );
\set_transient( $transient_key, $metadata, HOUR_IN_SECONDS ); // Cache the error for a shorter period. \set_transient( $transient_key, $metadata, HOUR_IN_SECONDS ); // Cache the error for a shorter period.