Profiles: update followers when profile fields change

This commit is contained in:
Matt Wiebe 2023-10-31 17:16:49 -05:00
parent 74a774e8e7
commit bcf29e1caf
2 changed files with 107 additions and 13 deletions

View file

@ -25,6 +25,7 @@ class Activity_Dispatcher {
public static function init() { public static function init() {
\add_action( 'activitypub_send_activity', array( self::class, 'send_activity' ), 10, 2 ); \add_action( 'activitypub_send_activity', array( self::class, 'send_activity' ), 10, 2 );
\add_action( 'activitypub_send_activity', array( self::class, 'send_activity_or_announce' ), 10, 2 ); \add_action( 'activitypub_send_activity', array( self::class, 'send_activity_or_announce' ), 10, 2 );
\add_action( 'activitypub_send_update_profile_activity', array( self::class, 'send_profile_update' ), 10, 1 );
} }
/** /**
@ -71,17 +72,7 @@ class Activity_Dispatcher {
$activity->set_type( $type ); $activity->set_type( $type );
$activity->set_object( $object ); $activity->set_object( $object );
$follower_inboxes = Followers::get_inboxes( $wp_post->post_author ); self::send_activity_to_inboxes( $activity, $wp_post->post_author );
$mentioned_inboxes = Mention::get_inboxes( $activity->get_cc() );
$inboxes = array_merge( $follower_inboxes, $mentioned_inboxes );
$inboxes = array_unique( $inboxes );
$json = $activity->to_json();
foreach ( $inboxes as $inbox ) {
safe_remote_post( $inbox, $json, $wp_post->post_author );
}
} }
/** /**
@ -110,7 +101,45 @@ class Activity_Dispatcher {
// send only the id // send only the id
$activity->set_object( $object->get_id() ); $activity->set_object( $object->get_id() );
$follower_inboxes = Followers::get_inboxes( $wp_post->post_author ); self::send_activity_to_inboxes( $activity, $wp_post->post_author );
}
/**
* Send a "Update" Activity when a user updates their profile.
*
* @param int $user_id The user ID to send an update for.
*
*/
public static function send_profile_update( $user_id ) {
$user = Users::get_by_various( $user_id );
// bail if that's not a good user
if ( is_wp_error( $user ) ) {
return;
}
// build the update
$activity = new Activity();
$activity->set_id( $user->get_url() . '#update' );
$activity->set_type( 'Update' );
$activity->set_actor( $user->get_url() );
$activity->set_object( $user->get_url() );
$activity->set_to( 'https://www.w3.org/ns/activitystreams#Public' );
// send the update
self::send_activity_to_inboxes( $activity, $user_id );
}
/**
* Send an Activity to all followers and mentioned users.
*
* @param Activity $activity The ActivityPub Activity.
* @param int $user_id The user ID.
*
* @return void
*/
private static function send_activity_to_inboxes( $activity, $user_id ) {
$follower_inboxes = Followers::get_inboxes( $user_id );
$mentioned_inboxes = Mention::get_inboxes( $activity->get_cc() ); $mentioned_inboxes = Mention::get_inboxes( $activity->get_cc() );
$inboxes = array_merge( $follower_inboxes, $mentioned_inboxes ); $inboxes = array_merge( $follower_inboxes, $mentioned_inboxes );
@ -119,7 +148,7 @@ class Activity_Dispatcher {
$json = $activity->to_json(); $json = $activity->to_json();
foreach ( $inboxes as $inbox ) { foreach ( $inboxes as $inbox ) {
safe_remote_post( $inbox, $json, $wp_post->post_author ); safe_remote_post( $inbox, $json, $user_id );
} }
} }
} }

View file

@ -6,12 +6,15 @@ use Activitypub\Collection\Users;
use Activitypub\Collection\Followers; use Activitypub\Collection\Followers;
use Activitypub\Transformer\Post; use Activitypub\Transformer\Post;
use function Activitypub\is_user_type_disabled;
/** /**
* ActivityPub Scheduler Class * ActivityPub Scheduler Class
* *
* @author Matthias Pfefferle * @author Matthias Pfefferle
*/ */
class Scheduler { class Scheduler {
/** /**
* Initialize the class, registering WordPress hooks * Initialize the class, registering WordPress hooks
*/ */
@ -22,6 +25,21 @@ class Scheduler {
\add_action( 'activitypub_cleanup_followers', array( self::class, 'cleanup_followers' ) ); \add_action( 'activitypub_cleanup_followers', array( self::class, 'cleanup_followers' ) );
\add_action( 'admin_init', array( self::class, 'schedule_migration' ) ); \add_action( 'admin_init', array( self::class, 'schedule_migration' ) );
// profile updates for blog options
if ( ! is_user_type_disabled( 'blog' ) ) {
\add_action( 'update_option_site_icon', array( self::class, 'blog_user_update' ) );
\add_action( 'update_option_blogdescription', array( self::class, 'blog_user_update' ) );
\add_action( 'update_option_blogname', array( self::class, 'blog_user_update' ) );
\add_filter( 'pre_set_theme_mod_custom_logo', array( self::class, 'blog_user_update' ) );
\add_filter( 'pre_set_theme_mod_header_image', array( self::class, 'blog_user_update' ) );
}
// profile updates for user options
if ( ! is_user_type_disabled( 'user' ) ) {
\add_action( 'updated_user_meta', array( self::class, 'user_update' ), 10, 3 );
// @todo figure out a feasible way of updating the header image since it's not unique to any user.
}
} }
/** /**
@ -166,4 +184,51 @@ class Scheduler {
\wp_schedule_single_event( \time(), 'activitypub_schedule_migration' ); \wp_schedule_single_event( \time(), 'activitypub_schedule_migration' );
} }
} }
/**
* Send a profile update when relevant user meta is updated.
*
* @param int $meta_id Meta ID being updated.
* @param int $user_id User ID being updated.
* @param string $meta_key Meta key being updated.
* @return void
*/
public static function user_update( $meta_id, $user_id, $meta_key ) {
// don't bother if the user can't publish
if ( ! \user_can( $user_id, 'publish_posts' ) ) {
return;
}
// the user meta fields that affect a profile.
$fields = array(
'activitypub_user_description',
'description',
'user_url',
'display_name',
);
if ( in_array( $meta_key, $fields, true ) ) {
self::schedule_profile_update( $user_id );
}
}
/**
* Theme mods only have a dynamic filter so we fudge it like this.
* @param mixed $value
* @return mixed
*/
public static function blog_user_update( $value = null ) {
self::schedule_profile_update( 0 );
return $value;
}
/**
* Send a profile update to all followers. Gets hooked into all relevant options/meta etc.
* @param int $user_id The user ID to update (Could be 0 for Blog-User).
*/
public function schedule_profile_update( $user_id ) {
\wp_schedule_single_event(
\time(),
'activitypub_send_update_profile_activity',
array( $user_id )
);
}
} }