Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/changelog/2235-from-description
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

Added support for fetching actors by account identifiers and improved reliability of actor retrieval.
62 changes: 62 additions & 0 deletions includes/collection/class-remote-actors.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,29 @@ public static function get_by_uri( $actor_uri ) {
return \get_post( $post_id );
}

/**
* Fetch a remote actor post by either actor URI or acct, fetching from remote if not found locally.
*
* @param string $uri_or_acct The actor URI or acct identifier.
*
* @return \WP_Post|\WP_Error Post object or WP_Error if not found.
*/
public static function fetch_by_various( $uri_or_acct ) {
if ( \filter_var( $uri_or_acct, FILTER_VALIDATE_URL ) ) {
return self::fetch_by_uri( $uri_or_acct );
}

if ( preg_match( '/^@?' . ACTIVITYPUB_USERNAME_REGEXP . '$/i', $uri_or_acct ) ) {
return self::fetch_by_acct( $uri_or_acct );
}

return new \WP_Error(
'activitypub_invalid_actor_identifier',
'The actor identifier is not supported',
array( 'status' => 400 )
);
}

/**
* Lookup a remote actor post by actor URI (guid), fetching from remote if not found locally.
*
Expand Down Expand Up @@ -239,6 +262,45 @@ public static function fetch_by_uri( $actor_uri ) {
return \get_post( $post_id );
}

/**
* Fetch a remote actor post by acct, fetching from remote if not found locally.
*
* @param string $acct The acct identifier.
*
* @return \WP_Post|\WP_Error Post object or WP_Error if not found.
*/
public static function fetch_by_acct( $acct ) {
$acct = Sanitize::webfinger( $acct );

// Check local DB for acct post meta.
global $wpdb;
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$post_id = $wpdb->get_var(
$wpdb->prepare(
"SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_activitypub_acct' AND meta_value=%s",
$acct
)
);

if ( $post_id ) {
return \get_post( $post_id );
}

$profile_uri = Webfinger::resolve( $acct );

if ( \is_wp_error( $profile_uri ) ) {
return $profile_uri;
}

$post = self::fetch_by_uri( $profile_uri );

if ( ! \is_wp_error( $post ) ) {
\update_post_meta( $post->ID, '_activitypub_acct', $acct );
}

return $post;
}

/**
* Store an error that occurred when sending an ActivityPub message to a follower.
*
Expand Down
10 changes: 8 additions & 2 deletions includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function get_webfinger_resource( $user_id ) {
*
* @return array|\WP_Error The Actor profile as array or WP_Error on failure.
*/
function get_remote_metadata_by_actor( $actor, $cached = true ) {
function get_remote_metadata_by_actor( $actor, $cached = true ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable, Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
/**
* Filters the metadata before it is retrieved from a remote actor.
*
Expand All @@ -101,7 +101,13 @@ function get_remote_metadata_by_actor( $actor, $cached = true ) {
return $pre;
}

return Http::get_remote_object( $actor, $cached );
$remote_actor = Remote_Actors::fetch_by_various( $actor );

if ( is_wp_error( $remote_actor ) ) {
return $remote_actor;
}

return json_decode( $remote_actor->post_content, true );
}

/**
Expand Down
Loading