Profiles: Update
followers when profile fields change (#542)
* Profiles: update followers when profile fields change * use static * only try to merge mention inboxes when valid * cleanups * add hook to wp_update_user * update readme --------- Co-authored-by: Matthias Pfefferle <pfefferle@users.noreply.github.com>
This commit is contained in:
parent
f2b231ccac
commit
3cda64a255
4 changed files with 137 additions and 13 deletions
|
@ -114,6 +114,7 @@ Project maintained on GitHub at [automattic/wordpress-activitypub](https://githu
|
||||||
* Added: CSS class for ActivityPub comments to allow custom designs
|
* Added: CSS class for ActivityPub comments to allow custom designs
|
||||||
* Added: FEP-2677: Identifying the Application Actor
|
* Added: FEP-2677: Identifying the Application Actor
|
||||||
* Added: Basic Comment Federation
|
* Added: Basic Comment Federation
|
||||||
|
* Added: Profile Update Activities
|
||||||
* Improved: WebFinger endpoints
|
* Improved: WebFinger endpoints
|
||||||
|
|
||||||
### 1.3.0 ###
|
### 1.3.0 ###
|
||||||
|
|
|
@ -28,6 +28,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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,17 +77,7 @@ class Activity_Dispatcher {
|
||||||
|
|
||||||
$activity = $transformer->to_activity( $type );
|
$activity = $transformer->to_activity( $type );
|
||||||
|
|
||||||
$follower_inboxes = Followers::get_inboxes( $user_id );
|
self::send_activity_to_inboxes( $activity, $user_id );
|
||||||
$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, $user_id );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,12 +103,60 @@ class Activity_Dispatcher {
|
||||||
$user_id = $transformer->get_wp_user_id();
|
$user_id = $transformer->get_wp_user_id();
|
||||||
$activity = $transformer->to_activity( 'Announce' );
|
$activity = $transformer->to_activity( 'Announce' );
|
||||||
|
|
||||||
$follower_inboxes = Followers::get_inboxes( $user_id );
|
self::send_activity_to_inboxes( $activity, $user_id );
|
||||||
$mentioned_inboxes = Mention::get_inboxes( $activity->get_cc() );
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a "Update" Activity when a user updates their profile.
|
||||||
|
*
|
||||||
|
* @param int $user_id The user ID to send an update for.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
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 = array();
|
||||||
|
$cc = $activity->get_cc();
|
||||||
|
if ( $cc ) {
|
||||||
|
$mentioned_inboxes = Mention::get_inboxes( $cc );
|
||||||
|
}
|
||||||
|
|
||||||
$inboxes = array_merge( $follower_inboxes, $mentioned_inboxes );
|
$inboxes = array_merge( $follower_inboxes, $mentioned_inboxes );
|
||||||
$inboxes = array_unique( $inboxes );
|
$inboxes = array_unique( $inboxes );
|
||||||
|
|
||||||
|
if ( empty( $inboxes ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$json = $activity->to_json();
|
$json = $activity->to_json();
|
||||||
|
|
||||||
foreach ( $inboxes as $inbox ) {
|
foreach ( $inboxes as $inbox ) {
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -58,6 +61,22 @@ class Scheduler {
|
||||||
|
|
||||||
// Migration
|
// Migration
|
||||||
\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( 'wp_update_user', array( self::class, 'user_update' ) );
|
||||||
|
\add_action( 'updated_user_meta', array( self::class, 'user_meta_update' ), 10, 3 );
|
||||||
|
// @todo figure out a feasible way of updating the header image since it's not unique to any user.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -255,4 +274,68 @@ 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_meta_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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a profile update when a user is updated.
|
||||||
|
*
|
||||||
|
* @param int $user_id User ID being updated.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function user_update( $user_id ) {
|
||||||
|
// don't bother if the user can't publish
|
||||||
|
if ( ! \user_can( $user_id, 'publish_posts' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 static function schedule_profile_update( $user_id ) {
|
||||||
|
\wp_schedule_single_event(
|
||||||
|
\time(),
|
||||||
|
'activitypub_send_update_profile_activity',
|
||||||
|
array( $user_id )
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,7 @@ Project maintained on GitHub at [automattic/wordpress-activitypub](https://githu
|
||||||
* Added: CSS class for ActivityPub comments to allow custom designs
|
* Added: CSS class for ActivityPub comments to allow custom designs
|
||||||
* Added: FEP-2677: Identifying the Application Actor
|
* Added: FEP-2677: Identifying the Application Actor
|
||||||
* Added: Basic Comment Federation
|
* Added: Basic Comment Federation
|
||||||
|
* Added: Profile Update Activities
|
||||||
* Improved: WebFinger endpoints
|
* Improved: WebFinger endpoints
|
||||||
|
|
||||||
= 1.3.0 =
|
= 1.3.0 =
|
||||||
|
|
Loading…
Reference in a new issue