From 6ebd1e1f9f2ea65b64d4935b79d467442cc0bbaf Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 11:44:38 +0200 Subject: [PATCH 01/10] Refactor collection classes to use unified query methods Replaces legacy methods in Blocked_Actors, Followers, Following, and Interactions classes with new unified methods such as query(), get_many(), add(), remove(), and count(). Deprecated old methods and updated all usages throughout the codebase, including handlers, REST controllers, admin tables, integration, CLI, and tests, to use the new APIs. This improves consistency, maintainability, and clarity in collection handling. --- build/follow-me/render.php | 2 +- build/followers/render.php | 2 +- includes/class-migration.php | 6 +- includes/class-moderation.php | 8 +- includes/collection/class-blocked-actors.php | 77 +++++++- includes/collection/class-followers.php | 103 +++++++++- includes/collection/class-following.php | 186 +++++++++++------- includes/collection/class-interactions.php | 36 +++- includes/functions.php | 4 +- includes/handler/class-delete.php | 4 +- includes/handler/class-follow.php | 2 +- includes/rest/class-followers-controller.php | 2 +- includes/rest/class-following-controller.php | 2 +- .../wp-admin/table/class-blocked-actors.php | 2 +- includes/wp-admin/table/class-followers.php | 4 +- includes/wp-admin/table/class-following.php | 25 ++- integration/class-enable-mastodon-apps.php | 6 +- local/class-cli.php | 2 +- src/follow-me/render.php | 2 +- src/followers/render.php | 2 +- .../tests/includes/class-test-dispatcher.php | 6 +- .../collection/class-test-followers.php | 98 ++++----- .../collection/class-test-following.php | 8 +- .../collection/class-test-interactions.php | 4 +- .../includes/handler/class-test-follow.php | 8 +- .../includes/handler/class-test-move.php | 10 +- .../handler/class-test-quote-request.php | 2 +- .../includes/handler/class-test-undo.php | 4 +- .../includes/handler/class-test-update.php | 2 +- .../wp-admin/table/class-test-followers.php | 4 +- .../class-test-enable-mastodon-apps.php | 2 +- 31 files changed, 437 insertions(+), 188 deletions(-) diff --git a/build/follow-me/render.php b/build/follow-me/render.php index 8f786892b..7105a6a3f 100644 --- a/build/follow-me/render.php +++ b/build/follow-me/render.php @@ -108,7 +108,7 @@ $stats = array( 'posts' => $user_id ? count_user_posts( $user_id, 'post', true ) : (int) wp_count_posts()->publish, - 'followers' => Followers::count_followers( $user_id ), + 'followers' => Followers::count( $user_id ), ); ob_start(); diff --git a/build/followers/render.php b/build/followers/render.php index 9d054c5e6..2f4dbcd3a 100644 --- a/build/followers/render.php +++ b/build/followers/render.php @@ -46,7 +46,7 @@ } $_per_page = absint( $attributes['per_page'] ); -$follower_data = Followers::get_followers_with_count( $user_id, $_per_page ); +$follower_data = Followers::query( $user_id, $_per_page ); // Prepare Followers data for the Interactivity API context. $followers = array_map( diff --git a/includes/class-migration.php b/includes/class-migration.php index 741b2f53a..c3d95354a 100644 --- a/includes/class-migration.php +++ b/includes/class-migration.php @@ -284,7 +284,7 @@ public static function migrate_from_0_17() { if ( $followers ) { foreach ( $followers as $actor ) { - Followers::add_follower( $user_id, $actor ); + Followers::add( $user_id, $actor ); } } } @@ -378,14 +378,14 @@ private static function migrate_to_4_0_0() { ); foreach ( $users as $user ) { - $followers = Followers::get_followers( $user->ID ); + $followers = Followers::get_many( $user->ID ); if ( $followers ) { \update_user_option( $user->ID, 'activitypub_use_permalink_as_id', '1' ); } } - $followers = Followers::get_followers( Actors::BLOG_USER_ID ); + $followers = Followers::get_many( Actors::BLOG_USER_ID ); if ( $followers ) { \update_option( 'activitypub_use_permalink_as_id_for_blog', '1' ); diff --git a/includes/class-moderation.php b/includes/class-moderation.php index eaf14c82c..0ba86f8b4 100644 --- a/includes/class-moderation.php +++ b/includes/class-moderation.php @@ -112,7 +112,7 @@ public static function activity_is_blocked_for_user( $activity, $user_id ) { public static function add_user_block( $user_id, $type, $value ) { switch ( $type ) { case self::TYPE_ACTOR: - return Blocked_Actors::add_block( $user_id, $value ); + return Blocked_Actors::add( $user_id, $value ); case self::TYPE_DOMAIN: case self::TYPE_KEYWORD: @@ -148,7 +148,7 @@ public static function add_user_block( $user_id, $type, $value ) { public static function remove_user_block( $user_id, $type, $value ) { switch ( $type ) { case self::TYPE_ACTOR: - return Blocked_Actors::remove_block( $user_id, $value ); + return Blocked_Actors::remove( $user_id, $value ); case self::TYPE_DOMAIN: case self::TYPE_KEYWORD: @@ -182,7 +182,7 @@ public static function remove_user_block( $user_id, $type, $value ) { */ public static function get_user_blocks( $user_id ) { return array( - 'actors' => \wp_list_pluck( Blocked_Actors::get_blocked_actors( $user_id ), 'guid' ), + 'actors' => \wp_list_pluck( Blocked_Actors::get_many( $user_id ), 'guid' ), 'domains' => \get_user_meta( $user_id, self::USER_META_KEYS[ self::TYPE_DOMAIN ], true ) ?: array(), // phpcs:ignore Universal.Operators.DisallowShortTernary.Found 'keywords' => \get_user_meta( $user_id, self::USER_META_KEYS[ self::TYPE_KEYWORD ], true ) ?: array(), // phpcs:ignore Universal.Operators.DisallowShortTernary.Found ); @@ -266,7 +266,7 @@ public static function remove_site_block( $type, $value ) { */ public static function get_site_blocks() { return array( - 'actors' => \wp_list_pluck( Blocked_Actors::get_blocked_actors( Actors::BLOG_USER_ID ), 'guid' ), + 'actors' => \wp_list_pluck( Blocked_Actors::get_many( Actors::BLOG_USER_ID ), 'guid' ), 'domains' => \get_option( self::OPTION_KEYS[ self::TYPE_DOMAIN ], array() ), 'keywords' => \get_option( self::OPTION_KEYS[ self::TYPE_KEYWORD ], array() ), ); diff --git a/includes/collection/class-blocked-actors.php b/includes/collection/class-blocked-actors.php index 998cd0488..4b2aaad09 100644 --- a/includes/collection/class-blocked-actors.php +++ b/includes/collection/class-blocked-actors.php @@ -21,7 +21,7 @@ class Blocked_Actors { * @param string $value The actor URI to block. * @return bool True on success, false on failure. */ - public static function add_block( $user_id, $value ) { + public static function add( $user_id, $value ) { // Find or create actor post. $actor_post = Remote_Actors::fetch_by_uri( $value ); if ( \is_wp_error( $actor_post ) ) { @@ -55,7 +55,7 @@ public static function add_block( $user_id, $value ) { * @param string|int $value The actor URI or post ID to unblock. * @return bool True on success, false on failure. */ - public static function remove_block( $user_id, $value ) { + public static function remove( $user_id, $value ) { // Handle both post ID and URI formats. if ( \is_numeric( $value ) ) { $post_id = (int) $value; @@ -84,7 +84,7 @@ public static function remove_block( $user_id, $value ) { } /** - * Get the blocked actors of a given user, along with a total count for pagination purposes. + * Query blocked actors of a given user, with pagination info. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -98,7 +98,7 @@ public static function remove_block( $user_id, $value ) { * @type int $total Total number of blocked actors. * } */ - public static function get_blocked_actors_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + public static function query( $user_id, $number = -1, $page = null, $args = array() ) { $defaults = array( 'post_type' => Remote_Actors::POST_TYPE, 'posts_per_page' => $number, @@ -122,9 +122,75 @@ public static function get_blocked_actors_with_count( $user_id, $number = -1, $p return \compact( 'blocked_actors', 'total' ); } + /** + * Get many blocked actors. + * + * @param int|null $user_id The ID of the WordPress User. + * @param int $number Maximum number of results to return. + * @param int $page Page number. + * @param array $args The WP_Query arguments. + * + * @return \WP_Post[] List of blocked Actors. + */ + public static function get_many( $user_id, $number = -1, $page = null, $args = array() ) { + return self::query( $user_id, $number, $page, $args )['blocked_actors']; + } + + /** + * Add an actor block for a user. + * + * @deprecated unreleased Use {@see Blocked_Actors::add()} + * + * @param int $user_id The user ID. + * @param string $value The actor URI to block. + * @return bool True on success, false on failure. + */ + public static function add_block( $user_id, $value ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::add' ); + return self::add( $user_id, $value ); + } + + /** + * Remove an actor block for a user. + * + * @deprecated unreleased Use {@see Blocked_Actors::remove()} + * + * @param int $user_id The user ID. + * @param string|int $value The actor URI or post ID to unblock. + * @return bool True on success, false on failure. + */ + public static function remove_block( $user_id, $value ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::remove' ); + return self::remove( $user_id, $value ); + } + + /** + * Get the blocked actors of a given user, along with a total count for pagination purposes. + * + * @deprecated unreleased Use {@see Blocked_Actors::query()} + * + * @param int|null $user_id The ID of the WordPress User. + * @param int $number Maximum number of results to return. + * @param int $page Page number. + * @param array $args The WP_Query arguments. + * + * @return array { + * Data about the blocked actors. + * + * @type \WP_Post[] $blocked_actors List of blocked Actor WP_Post objects. + * @type int $total Total number of blocked actors. + * } + */ + public static function get_blocked_actors_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::query' ); + return self::query( $user_id, $number, $page, $args ); + } + /** * Get the blocked actors of a given user. * + * @deprecated unreleased Use {@see Blocked_Actors::get_many()} + * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. * @param int $page Page number. @@ -133,6 +199,7 @@ public static function get_blocked_actors_with_count( $user_id, $number = -1, $p * @return \WP_Post[] List of blocked Actors. */ public static function get_blocked_actors( $user_id, $number = -1, $page = null, $args = array() ) { - return self::get_blocked_actors_with_count( $user_id, $number, $page, $args )['blocked_actors']; + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::get_many' ); + return self::get_many( $user_id, $number, $page, $args ); } } diff --git a/includes/collection/class-followers.php b/includes/collection/class-followers.php index 64bc16447..20d6481f4 100644 --- a/includes/collection/class-followers.php +++ b/includes/collection/class-followers.php @@ -40,7 +40,7 @@ class Followers { * * @return int|\WP_Error The Follower ID or an WP_Error. */ - public static function add_follower( $user_id, $actor ) { + public static function add( $user_id, $actor ) { $meta = get_remote_metadata_by_actor( $actor ); if ( Tombstone::exists( $meta ) ) { @@ -66,6 +66,21 @@ public static function add_follower( $user_id, $actor ) { return $post_id; } + /** + * Add new Follower. + * + * @deprecated unreleased Use {@see Followers::add()} + * + * @param int $user_id The ID of the WordPress User. + * @param string $actor The Actor URL. + * + * @return int|\WP_Error The Follower ID or an WP_Error. + */ + public static function add_follower( $user_id, $actor ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::add' ); + return self::add( $user_id, $actor ); + } + /** * Remove a Follower. * @@ -109,7 +124,7 @@ public static function remove( $post_or_id, $user_id ) { public static function remove_follower( $user_id, $actor ) { _deprecated_function( __METHOD__, '7.1.0', 'Activitypub\Collection\Followers::remove' ); - $remote_actor = self::get_follower( $user_id, $actor ); + $remote_actor = self::get_by_uri( $user_id, $actor ); if ( \is_wp_error( $remote_actor ) ) { return false; @@ -119,14 +134,14 @@ public static function remove_follower( $user_id, $actor ) { } /** - * Get a Follower. + * Get a Follower by URI. * * @param int $user_id The ID of the WordPress User. * @param string $actor The Actor URL. * * @return \WP_Post|\WP_Error The Follower object or WP_Error on failure. */ - public static function get_follower( $user_id, $actor ) { + public static function get_by_uri( $user_id, $actor ) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery @@ -153,6 +168,21 @@ public static function get_follower( $user_id, $actor ) { return \get_post( $id ); } + /** + * Get a Follower. + * + * @deprecated unreleased Use {@see Followers::get_by_uri()} + * + * @param int $user_id The ID of the WordPress User. + * @param string $actor The Actor URL. + * + * @return \WP_Post|\WP_Error The Follower object or WP_Error on failure. + */ + public static function get_follower( $user_id, $actor ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::get_by_uri' ); + return self::get_by_uri( $user_id, $actor ); + } + /** * Get a Follower by Actor independent of the User. * @@ -169,7 +199,7 @@ public static function get_follower_by_actor( $actor ) { } /** - * Get the Followers of a given user. + * Get many followers. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -178,15 +208,34 @@ public static function get_follower_by_actor( $actor ) { * * @return \WP_Post[] List of `Follower` objects. */ - public static function get_followers( $user_id, $number = -1, $page = null, $args = array() ) { - $data = self::get_followers_with_count( $user_id, $number, $page, $args ); + public static function get_many( $user_id, $number = -1, $page = null, $args = array() ) { + $data = self::query( $user_id, $number, $page, $args ); return $data['followers']; } + /** + * Get the Followers of a given user. + * + * @deprecated unreleased Use {@see Followers::get_many()} + * + * @param int|null $user_id The ID of the WordPress User. + * @param int $number Maximum number of results to return. + * @param int $page Page number. + * @param array $args The WP_Query arguments. + * + * @return \WP_Post[] List of `Follower` objects. + */ + public static function get_followers( $user_id, $number = -1, $page = null, $args = array() ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::get_many' ); + return self::get_many( $user_id, $number, $page, $args ); + } + /** * Get the Followers of a given user, along with a total count for pagination purposes. * + * @deprecated unreleased Use {@see Followers::query()} + * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. * @param int $page Page number. @@ -200,6 +249,26 @@ public static function get_followers( $user_id, $number = -1, $page = null, $arg * } */ public static function get_followers_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::query' ); + return self::query( $user_id, $number, $page, $args ); + } + + /** + * Query followers with pagination info. + * + * @param int|null $user_id The ID of the WordPress User. + * @param int $number Maximum number of results to return. + * @param int $page Page number. + * @param array $args The WP_Query arguments. + * + * @return array { + * Data about the followers. + * + * @type \WP_Post[] $followers List of `Follower` objects. + * @type int $total Total number of followers. + * } + */ + public static function query( $user_id, $number = -1, $page = null, $args = array() ) { $defaults = array( 'post_type' => Remote_Actors::POST_TYPE, 'posts_per_page' => $number, @@ -230,14 +299,28 @@ public static function get_followers_with_count( $user_id, $number = -1, $page = } /** - * Count the total number of followers + * Count the total number of followers. + * + * @param int $user_id The ID of the WordPress User. + * + * @return int The number of Followers + */ + public static function count( $user_id ) { + return self::query( $user_id, 1 )['total']; + } + + /** + * Count the total number of followers. + * + * @deprecated unreleased Use {@see Followers::count()} * * @param int $user_id The ID of the WordPress User. * * @return int The number of Followers */ public static function count_followers( $user_id ) { - return self::get_followers_with_count( $user_id, 1 )['total']; + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::count' ); + return self::count( $user_id ); } /** @@ -377,7 +460,7 @@ public static function get_all_followers() { ), ), ); - return self::get_followers( null, null, null, $args ); + return self::get_many( null, null, null, $args ); } /** diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index 0f28701ad..a36b83538 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -201,7 +201,7 @@ public static function unfollow( $post, $user_id ) { } /** - * Get the Followings of a given user, along with a total count for pagination purposes. + * Query followings of a given user, with pagination info. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -211,11 +211,11 @@ public static function unfollow( $post, $user_id ) { * @return array { * Data about the followings. * - * @type \WP_Post[] $followings List of `Following` objects. - * @type int $total Total number of followings. + * @type \WP_Post[] $following List of `Following` objects. + * @type int $total Total number of followings. * } */ - public static function get_following_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + public static function query( $user_id, $number = -1, $page = null, $args = array() ) { $defaults = array( 'post_type' => Remote_Actors::POST_TYPE, 'posts_per_page' => $number, @@ -240,7 +240,7 @@ public static function get_following_with_count( $user_id, $number = -1, $page = } /** - * Get the Followings of a given user. + * Get many followings of a given user. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -249,26 +249,17 @@ public static function get_following_with_count( $user_id, $number = -1, $page = * * @return \WP_Post[] List of `Following` objects. */ - public static function get_following( $user_id, $number = -1, $page = null, $args = array() ) { - $data = self::get_following_with_count( $user_id, $number, $page, $args ); + public static function get_many( $user_id, $number = -1, $page = null, $args = array() ) { + $data = self::query( $user_id, $number, $page, $args ); return $data['following']; } - /** - * Get the total number of followings of a given user. - * - * @param int|null $user_id The ID of the WordPress User. - * - * @return int The total number of followings. - */ - public static function count_following( $user_id ) { - return self::get_following_with_count( $user_id, 1 )['total']; - } - /** * Get the Followings of a given user, along with a total count for pagination purposes. * + * @deprecated unreleased Use {@see Following::query()} with status parameter + * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. * @param int $page Page number. @@ -282,27 +273,15 @@ public static function count_following( $user_id ) { * } */ public static function get_pending_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - $defaults = array( - 'post_type' => Remote_Actors::POST_TYPE, - 'posts_per_page' => $number, - 'paged' => $page, - 'orderby' => 'ID', - 'order' => 'DESC', - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'meta_query' => array( - array( - 'key' => self::PENDING_META_KEY, - 'value' => $user_id, - ), + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query' ); + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + $args['meta_query'] = array( + array( + 'key' => self::PENDING_META_KEY, + 'value' => $user_id, ), ); - - $args = \wp_parse_args( $args, $defaults ); - $query = new \WP_Query( $args ); - $total = $query->found_posts; - $following = \array_filter( $query->posts ); - - return \compact( 'following', 'total' ); + return self::query( $user_id, $number, $page, $args ); } /** @@ -316,7 +295,14 @@ public static function get_pending_with_count( $user_id, $number = -1, $page = n * @return \WP_Post[] List of `Following` objects. */ public static function get_pending( $user_id, $number = -1, $page = null, $args = array() ) { - $data = self::get_pending_with_count( $user_id, $number, $page, $args ); + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + $args['meta_query'] = array( + array( + 'key' => self::PENDING_META_KEY, + 'value' => $user_id, + ), + ); + $data = self::query( $user_id, $number, $page, $args ); return $data['following']; } @@ -329,11 +315,22 @@ public static function get_pending( $user_id, $number = -1, $page = null, $args * @return int The total number of pending followings. */ public static function count_pending( $user_id ) { - return self::get_pending_with_count( $user_id, 1 )['total']; + $args = array( + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + 'meta_query' => array( + array( + 'key' => self::PENDING_META_KEY, + 'value' => $user_id, + ), + ), + ); + return self::query( $user_id, 1, null, $args )['total']; } /** - * Get all followings of a given user. + * Get all followings of a given user, along with a total count for pagination purposes. + * + * @deprecated unreleased Use {@see Following::query()} with status parameter * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -348,14 +345,21 @@ public static function count_pending( $user_id ) { * } */ public static function get_all_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - $defaults = array( - 'post_type' => Remote_Actors::POST_TYPE, - 'posts_per_page' => $number, - 'paged' => $page, - 'orderby' => 'ID', - 'order' => 'DESC', + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query' ); + return self::get_all( $user_id, $number = -1, $page = null, $args = array() ); + } + + /** + * Get all followings of a given user. + * + * @param int|null $user_id The ID of the WordPress User. + * + * @return \WP_Post[] List of `Following` objects. + */ + public static function get_all( $user_id ) { + $args = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'meta_query' => array( + 'meta_query' => array( 'relation' => 'OR', array( 'key' => self::FOLLOWING_META_KEY, @@ -368,48 +372,57 @@ public static function get_all_with_count( $user_id, $number = -1, $page = null, ), ); - $args = \wp_parse_args( $args, $defaults ); - $query = new \WP_Query( $args ); - $total = $query->found_posts; - $following = \array_filter( $query->posts ); - - return \compact( 'following', 'total' ); + return self::query( $user_id, -1, null, $args )['following']; } /** - * Get all followings of a given user. + * Get the total number of all followings of a given user. * * @param int|null $user_id The ID of the WordPress User. * - * @return \WP_Post[] List of `Following` objects. + * @return int The total number of all followings. */ - public static function get_all( $user_id ) { - return self::get_all_with_count( $user_id )['following']; + public static function count_all( $user_id ) { + $args = array( + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + 'meta_query' => array( + 'relation' => 'OR', + array( + 'key' => self::FOLLOWING_META_KEY, + 'value' => $user_id, + ), + array( + 'key' => self::PENDING_META_KEY, + 'value' => $user_id, + ), + ), + ); + return self::query( $user_id, 1, null, $args )['total']; } /** - * Get the total number of all followings of a given user. + * Count the total number of followings. * - * @param int|null $user_id The ID of the WordPress User. + * @param int $user_id The ID of the WordPress User. * - * @return int The total number of all followings. + * @return int The number of Followings */ - public static function count_all( $user_id ) { - return self::get_all_with_count( $user_id, 1 )['total']; + public static function count( $user_id ) { + return self::query( $user_id, 1 )['total']; } /** - * Get the total number of followings of a given user. + * Get the total number of followings of a given user by status. * * @param int|null $user_id The ID of the WordPress User. * * @return array Total number of followings and pending followings. */ - public static function count( $user_id ) { + public static function count_by_status( $user_id ) { return array( - self::ALL => self::get_all_with_count( $user_id, 1 )['total'], - self::ACCEPTED => self::get_following_with_count( $user_id, 1 )['total'], - self::PENDING => self::get_pending_with_count( $user_id, 1 )['total'], + self::ALL => self::count_all( $user_id ), + self::ACCEPTED => self::count( $user_id ), + self::PENDING => self::count_pending( $user_id ), ); } @@ -458,4 +471,43 @@ public static function remove_blocked_actors( $value, $type, $user_id ) { self::unfollow( $actor_id, $user_id ); } + + /** + * Get the Followings of a given user, along with a total count for pagination purposes. + * + * @deprecated unreleased Use {@see Following::query()} + * + * @param int|null $user_id The ID of the WordPress User. + * @param int $number Maximum number of results to return. + * @param int $page Page number. + * @param array $args The WP_Query arguments. + * + * @return array { + * Data about the followings. + * + * @type \WP_Post[] $following List of `Following` objects. + * @type int $total Total number of followings. + * } + */ + public static function get_following_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query' ); + return self::query( $user_id, $number, $page, $args ); + } + + /** + * Get the Followings of a given user. + * + * @deprecated unreleased Use {@see Following::get_many()} + * + * @param int|null $user_id The ID of the WordPress User. + * @param int $number Maximum number of results to return. + * @param int $page Page number. + * @param array $args The WP_Query arguments. + * + * @return \WP_Post[] List of `Following` objects. + */ + public static function get_following( $user_id, $number = -1, $page = null, $args = array() ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::get_many' ); + return self::get_many( $user_id, $number, $page, $args ); + } } diff --git a/includes/collection/class-interactions.php b/includes/collection/class-interactions.php index f532ecf00..9ba485733 100644 --- a/includes/collection/class-interactions.php +++ b/includes/collection/class-interactions.php @@ -127,13 +127,13 @@ public static function add_reaction( $activity ) { } /** - * Get interaction(s) for a given URL/ID. + * Get interaction(s) by ID. * * @param string $url The URL/ID to get interactions for. * * @return array The interactions as WP_Comment objects. */ - public static function get_interaction_by_id( $url ) { + public static function get_by_id( $url ) { $args = array( 'nopaging' => true, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query @@ -162,13 +162,27 @@ public static function get_interaction_by_id( $url ) { } /** - * Get interaction(s) for a given actor. + * Get interaction(s) for a given URL/ID. + * + * @deprecated unreleased Use {@see Interactions::get_by_id()} + * + * @param string $url The URL/ID to get interactions for. + * + * @return array The interactions as WP_Comment objects. + */ + public static function get_interaction_by_id( $url ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Interactions::get_by_id' ); + return self::get_by_id( $url ); + } + + /** + * Get interaction(s) by actor. * * @param string $actor The Actor-URL. * * @return array The interactions as WP_Comment objects. */ - public static function get_interactions_by_actor( $actor ) { + public static function get_by_actor( $actor ) { $meta = get_remote_metadata_by_actor( $actor ); // Get URL, because $actor seems to be the ID. @@ -191,6 +205,20 @@ public static function get_interactions_by_actor( $actor ) { return get_comments( $args ); } + /** + * Get interaction(s) for a given actor. + * + * @deprecated unreleased Use {@see Interactions::get_by_actor()} + * + * @param string $actor The Actor-URL. + * + * @return array The interactions as WP_Comment objects. + */ + public static function get_interactions_by_actor( $actor ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Interactions::get_by_actor' ); + return self::get_by_actor( $actor ); + } + /** * Adds line breaks to the list of allowed comment tags. * diff --git a/includes/functions.php b/includes/functions.php index e46da9639..2d3064cab 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -121,7 +121,7 @@ function get_remote_metadata_by_actor( $actor, $cached = true ) { // phpcs:ignor * @return array The followers. */ function get_followers( $user_id ) { - return Followers::get_followers( $user_id ); + return Followers::get_many( $user_id ); } /** @@ -132,7 +132,7 @@ function get_followers( $user_id ) { * @return int The number of followers. */ function count_followers( $user_id ) { - return Followers::count_followers( $user_id ); + return Followers::count( $user_id ); } /** diff --git a/includes/handler/class-delete.php b/includes/handler/class-delete.php index 3c58e68ad..e50e75086 100644 --- a/includes/handler/class-delete.php +++ b/includes/handler/class-delete.php @@ -161,7 +161,7 @@ public static function maybe_delete_interactions( $activity ) { * @return bool True on success, false otherwise. */ public static function delete_interactions( $actor ) { - $comments = Interactions::get_interactions_by_actor( $actor ); + $comments = Interactions::get_by_actor( $actor ); foreach ( $comments as $comment ) { wp_delete_comment( $comment, true ); @@ -188,7 +188,7 @@ public static function maybe_delete_interaction( $activity ) { $id = $activity['object']; } - $comments = Interactions::get_interaction_by_id( $id ); + $comments = Interactions::get_by_id( $id ); if ( $comments && Tombstone::exists( $id ) ) { foreach ( $comments as $comment ) { diff --git a/includes/handler/class-follow.php b/includes/handler/class-follow.php index 25e2b498c..b576e8ddf 100644 --- a/includes/handler/class-follow.php +++ b/includes/handler/class-follow.php @@ -38,7 +38,7 @@ public static function handle_follow( $activity, $user_id ) { } // Save follower. - $remote_actor = Followers::add_follower( + $remote_actor = Followers::add( $user_id, $activity['actor'] ); diff --git a/includes/rest/class-followers-controller.php b/includes/rest/class-followers-controller.php index b83fdded7..fc2b43440 100644 --- a/includes/rest/class-followers-controller.php +++ b/includes/rest/class-followers-controller.php @@ -96,7 +96,7 @@ public function get_items( $request ) { $page = $request->get_param( 'page' ) ?? 1; $context = $request->get_param( 'context' ); - $data = Followers::get_followers_with_count( $user_id, $per_page, $page, array( 'order' => \ucwords( $order ) ) ); + $data = Followers::query( $user_id, $per_page, $page, array( 'order' => \ucwords( $order ) ) ); $response = array( 'id' => get_rest_url_by_path( \sprintf( 'actors/%d/followers', $user_id ) ), diff --git a/includes/rest/class-following-controller.php b/includes/rest/class-following-controller.php index 857da1374..770192f1f 100644 --- a/includes/rest/class-following-controller.php +++ b/includes/rest/class-following-controller.php @@ -101,7 +101,7 @@ public function get_items( $request ) { $page = $request->get_param( 'page' ) ?? 1; $context = $request->get_param( 'context' ); - $data = Following::get_following_with_count( $user_id, $per_page, $page, array( 'order' => \ucwords( $order ) ) ); + $data = Following::query( $user_id, $per_page, $page, array( 'order' => \ucwords( $order ) ) ); $response = array( 'id' => get_rest_url_by_path( \sprintf( 'actors/%d/following', $user_id ) ), diff --git a/includes/wp-admin/table/class-blocked-actors.php b/includes/wp-admin/table/class-blocked-actors.php index 85911ffb5..870c345ab 100644 --- a/includes/wp-admin/table/class-blocked-actors.php +++ b/includes/wp-admin/table/class-blocked-actors.php @@ -208,7 +208,7 @@ public function prepare_items() { $args['s'] = $this->normalize_search_term( \wp_unslash( $_GET['s'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized } - $blocked_with_count = Blocked_Actors_Collection::get_blocked_actors_with_count( $this->user_id, $per_page, $page_num, $args ); + $blocked_with_count = Blocked_Actors_Collection::query( $this->user_id, $per_page, $page_num, $args ); $blocked_actor_posts = $blocked_with_count['blocked_actors']; $counter = $blocked_with_count['total']; diff --git a/includes/wp-admin/table/class-followers.php b/includes/wp-admin/table/class-followers.php index 84711b9b7..fdae40fb3 100644 --- a/includes/wp-admin/table/class-followers.php +++ b/includes/wp-admin/table/class-followers.php @@ -261,7 +261,7 @@ public function prepare_items() { $args['s'] = $this->normalize_search_term( \wp_unslash( $_GET['s'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized } - $followers_with_count = Follower_Collection::get_followers_with_count( $this->user_id, $per_page, $page_num, $args ); + $followers_with_count = Follower_Collection::query( $this->user_id, $per_page, $page_num, $args ); $followers = $followers_with_count['followers']; $counter = $followers_with_count['total']; @@ -299,7 +299,7 @@ public function prepare_items() { * @return string[] */ public function get_views() { - $count = Follower_Collection::count_followers( $this->user_id ); + $count = Follower_Collection::count( $this->user_id ); $path = 'users.php?page=activitypub-followers-list'; if ( Actors::BLOG_USER_ID === $this->user_id ) { diff --git a/includes/wp-admin/table/class-following.php b/includes/wp-admin/table/class-following.php index ff711f4fe..d0532eda9 100644 --- a/includes/wp-admin/table/class-following.php +++ b/includes/wp-admin/table/class-following.php @@ -223,11 +223,30 @@ public function prepare_items() { } if ( Following_Collection::PENDING === $status ) { - $following_with_count = Following_Collection::get_pending_with_count( $this->user_id, $per_page, $page_num, $args ); + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + $args['meta_query'] = array( + array( + 'key' => Following_Collection::PENDING_META_KEY, + 'value' => $this->user_id, + ), + ); + $following_with_count = Following_Collection::query( $this->user_id, $per_page, $page_num, $args ); } elseif ( Following_Collection::ACCEPTED === $status ) { - $following_with_count = Following_Collection::get_following_with_count( $this->user_id, $per_page, $page_num, $args ); + $following_with_count = Following_Collection::query( $this->user_id, $per_page, $page_num, $args ); } else { - $following_with_count = Following_Collection::get_all_with_count( $this->user_id, $per_page, $page_num, $args ); + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + $args['meta_query'] = array( + 'relation' => 'OR', + array( + 'key' => Following_Collection::FOLLOWING_META_KEY, + 'value' => $this->user_id, + ), + array( + 'key' => Following_Collection::PENDING_META_KEY, + 'value' => $this->user_id, + ), + ); + $following_with_count = Following_Collection::query( $this->user_id, $per_page, $page_num, $args ); } $followings = $following_with_count['following']; diff --git a/integration/class-enable-mastodon-apps.php b/integration/class-enable-mastodon-apps.php index f60294a79..423acf653 100644 --- a/integration/class-enable-mastodon-apps.php +++ b/integration/class-enable-mastodon-apps.php @@ -185,7 +185,7 @@ private static function set_extra_fields( $user_id, $fields ) { */ public static function api_account_followers( $followers, $user_id ) { $user_id = self::maybe_map_user_to_blog( $user_id ); - $activitypub_followers = Followers::get_followers( $user_id, 40 ); + $activitypub_followers = Followers::get_many( $user_id, 40 ); $mastodon_followers = array_map( function ( $item ) { $actor = Remote_Actors::get_actor( $item ); @@ -323,7 +323,7 @@ function ( $field ) { $account->fields ); - $account->followers_count = Followers::count_followers( $user_id ); + $account->followers_count = Followers::count( $user_id ); return $account; } @@ -476,7 +476,7 @@ public static function api_search( $search_data, $request ) { } $q = sanitize_text_field( wp_unslash( $q ) ); - $followers = Followers::get_followers( $user_id, 40, null, array( 's' => $q ) ); + $followers = Followers::get_many( $user_id, 40, null, array( 's' => $q ) ); if ( ! $followers ) { return $search_data; } diff --git a/local/class-cli.php b/local/class-cli.php index 657b2bc12..a5c4195ba 100644 --- a/local/class-cli.php +++ b/local/class-cli.php @@ -51,7 +51,7 @@ public function add_follower( $args, $assoc_args ) { $user_id = get_flag_value( $assoc_args, 'user', Actors::BLOG_USER_ID ); \WP_CLI::log( sprintf( 'Adding follower %s to user %d...', $actor_url, $user_id ) ); - $result = Followers::add_follower( $user_id, $actor_url ); + $result = Followers::add( $user_id, $actor_url ); if ( \is_wp_error( $result ) ) { \WP_CLI::error( $result->get_error_message() ); diff --git a/src/follow-me/render.php b/src/follow-me/render.php index 8f786892b..7105a6a3f 100644 --- a/src/follow-me/render.php +++ b/src/follow-me/render.php @@ -108,7 +108,7 @@ $stats = array( 'posts' => $user_id ? count_user_posts( $user_id, 'post', true ) : (int) wp_count_posts()->publish, - 'followers' => Followers::count_followers( $user_id ), + 'followers' => Followers::count( $user_id ), ); ob_start(); diff --git a/src/followers/render.php b/src/followers/render.php index 9d054c5e6..2f4dbcd3a 100644 --- a/src/followers/render.php +++ b/src/followers/render.php @@ -46,7 +46,7 @@ } $_per_page = absint( $attributes['per_page'] ); -$follower_data = Followers::get_followers_with_count( $user_id, $_per_page ); +$follower_data = Followers::query( $user_id, $_per_page ); // Prepare Followers data for the Interactivity API context. $followers = array_map( diff --git a/tests/phpunit/tests/includes/class-test-dispatcher.php b/tests/phpunit/tests/includes/class-test-dispatcher.php index bdddc86d4..3388ab347 100644 --- a/tests/phpunit/tests/includes/class-test-dispatcher.php +++ b/tests/phpunit/tests/includes/class-test-dispatcher.php @@ -48,8 +48,8 @@ public function test_send_to_followers() { $post_id = self::factory()->post->create( array( 'post_author' => self::$user_id ) ); $outbox_item = $this->get_latest_outbox_item( \add_query_arg( 'p', $post_id, \home_url( '/' ) ) ); - Followers::add_follower( self::$user_id, 'https://example.org/users/username' ); - Followers::add_follower( self::$user_id, 'https://example.com/users/username' ); + Followers::add( self::$user_id, 'https://example.org/users/username' ); + Followers::add( self::$user_id, 'https://example.com/users/username' ); $result = Dispatcher::send_to_followers( $outbox_item->ID, 1 ); @@ -219,7 +219,7 @@ public function test_should_send_to_followers() { $this->assertFalse( $should_send->invoke( null, $activity, Actors::get_by_id( self::$user_id ), $outbox_item ) ); // Add a follower. - Followers::add_follower( self::$user_id, 'https://example.org/users/username' ); + Followers::add( self::$user_id, 'https://example.org/users/username' ); $this->assertTrue( $should_send->invoke( null, $activity, Actors::get_by_id( self::$user_id ), $outbox_item ) ); } diff --git a/tests/phpunit/tests/includes/collection/class-test-followers.php b/tests/phpunit/tests/includes/collection/class-test-followers.php index 830410281..801cb2ee2 100644 --- a/tests/phpunit/tests/includes/collection/class-test-followers.php +++ b/tests/phpunit/tests/includes/collection/class-test-followers.php @@ -103,10 +103,10 @@ public function test_get_followers() { $followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' ); foreach ( $followers as $follower ) { - Followers::add_follower( 1, $follower ); + Followers::add( 1, $follower ); } - $db_followers = Followers::get_followers( 1 ); + $db_followers = Followers::get_many( 1 ); $this->assertEquals( 3, \count( $db_followers ) ); @@ -128,12 +128,12 @@ function ( $item ) { public function test_add_follower() { $follower = 'https://12345.example.com'; $follower2 = 'https://user2.example.com'; - Followers::add_follower( 1, $follower ); - Followers::add_follower( 2, $follower ); - Followers::add_follower( 2, $follower2 ); + Followers::add( 1, $follower ); + Followers::add( 2, $follower ); + Followers::add( 2, $follower2 ); - $db_followers = Followers::get_followers( 1 ); - $db_followers2 = Followers::get_followers( 2 ); + $db_followers = Followers::get_many( 1 ); + $db_followers2 = Followers::get_many( 2 ); $this->assertStringContainsString( $follower, serialize( $db_followers ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize $this->assertStringContainsString( $follower2, serialize( $db_followers2 ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize @@ -147,17 +147,17 @@ public function test_add_follower() { public function test_add_follower_error() { $follower = 'error@example.net'; - $result = Followers::add_follower( 1, $follower ); + $result = Followers::add( 1, $follower ); $this->assertTrue( \is_wp_error( $result ) ); $follower2 = 'https://error.example.net'; - $result = Followers::add_follower( 1, $follower2 ); + $result = Followers::add( 1, $follower2 ); $this->assertTrue( \is_wp_error( $result ) ); - $db_followers = Followers::get_followers( 1 ); + $db_followers = Followers::get_many( 1 ); $this->assertEmpty( $db_followers ); } @@ -172,26 +172,26 @@ public function test_get_follower() { $followers2 = array( 'https://user2.example.com' ); foreach ( $followers as $follower ) { - Followers::add_follower( 1, $follower ); + Followers::add( 1, $follower ); } foreach ( $followers2 as $follower ) { - Followers::add_follower( 2, $follower ); + Followers::add( 2, $follower ); } - $follower = Followers::get_follower( 1, 'https://example.com/author/jon' ); + $follower = Followers::get_by_uri( 1, 'https://example.com/author/jon' ); $this->assertEquals( 'https://example.com/author/jon', $follower->guid ); - $follower = Followers::get_follower( 1, 'http://sally.example.org' ); + $follower = Followers::get_by_uri( 1, 'http://sally.example.org' ); $this->assertWPError( $follower ); - $follower = Followers::get_follower( 1, 'https://user2.example.com' ); + $follower = Followers::get_by_uri( 1, 'https://user2.example.com' ); $this->assertWPError( $follower ); - $follower = Followers::get_follower( 1, 'https://example.com/author/jon' ); + $follower = Followers::get_by_uri( 1, 'https://example.com/author/jon' ); $this->assertEquals( 'https://example.com/author/jon', $follower->guid ); - $follower2 = Followers::get_follower( 2, 'https://user2.example.com' ); + $follower2 = Followers::get_by_uri( 2, 'https://user2.example.com' ); $this->assertEquals( 'https://user2.example.com', $follower2->guid ); $this->assertEquals( 'úser2', Remote_Actors::get_actor( $follower2 )->get_name() ); } @@ -209,35 +209,35 @@ public function test_delete_follower() { $followers2 = array( 'https://user2.example.com' ); foreach ( $followers as $follower ) { - Followers::add_follower( 1, $follower ); - Followers::add_follower( 1, $follower ); - Followers::add_follower( 1, $follower ); - Followers::add_follower( 2, $follower ); + Followers::add( 1, $follower ); + Followers::add( 1, $follower ); + Followers::add( 1, $follower ); + Followers::add( 2, $follower ); } foreach ( $followers2 as $follower2 ) { - Followers::add_follower( 2, $follower2 ); + Followers::add( 2, $follower2 ); } - $follower = Followers::get_follower( 1, 'https://example.com/author/jon' ); + $follower = Followers::get_by_uri( 1, 'https://example.com/author/jon' ); $this->assertEquals( 'https://example.com/author/jon', $follower->guid ); - $followers = Followers::get_followers( 1 ); + $followers = Followers::get_many( 1 ); $this->assertEquals( 2, count( $followers ) ); - $follower2 = Followers::get_follower( 2, 'https://example.com/author/jon' ); + $follower2 = Followers::get_by_uri( 2, 'https://example.com/author/jon' ); $this->assertEquals( 'https://example.com/author/jon', $follower2->guid ); $this->setExpectedDeprecated( 'Activitypub\Collection\Followers::remove_follower' ); Followers::remove_follower( 1, 'https://example.com/author/jon' ); - $follower = Followers::get_follower( 1, 'https://example.com/author/jon' ); + $follower = Followers::get_by_uri( 1, 'https://example.com/author/jon' ); $this->assertWPError( $follower ); - $follower2 = Followers::get_follower( 2, 'https://example.com/author/jon' ); + $follower2 = Followers::get_by_uri( 2, 'https://example.com/author/jon' ); $this->assertEquals( 'https://example.com/author/jon', $follower2->guid ); - $followers = Followers::get_followers( 1 ); + $followers = Followers::get_many( 1 ); $this->assertEquals( 1, count( $followers ) ); } @@ -253,21 +253,21 @@ public function test_remove() { ); foreach ( $followers as $follower ) { - Followers::add_follower( 1, $follower ); + Followers::add( 1, $follower ); } - $follower = Followers::get_follower( 1, 'https://example.com/author/jon' ); + $follower = Followers::get_by_uri( 1, 'https://example.com/author/jon' ); $this->assertEquals( 'https://example.com/author/jon', $follower->guid ); - $followers = Followers::get_followers( 1 ); + $followers = Followers::get_many( 1 ); $this->assertEquals( 2, count( $followers ) ); Followers::remove( $followers[0]->ID, 1 ); - $follower = Followers::get_follower( 1, $followers[0]->guid ); + $follower = Followers::get_by_uri( 1, $followers[0]->guid ); $this->assertWPError( $follower ); - $followers = Followers::get_followers( 1 ); + $followers = Followers::get_many( 1 ); $this->assertEquals( 1, count( $followers ) ); } @@ -280,10 +280,10 @@ public function test_get_outdated_followers() { $followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' ); foreach ( $followers as $follower ) { - Followers::add_follower( 1, $follower ); + Followers::add( 1, $follower ); } - $follower = Followers::get_follower( 1, 'https://example.com/author/jon' ); + $follower = Followers::get_by_uri( 1, 'https://example.com/author/jon' ); global $wpdb; @@ -321,16 +321,16 @@ public function test_get_faulty_followers() { $followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' ); foreach ( $followers as $follower ) { - Followers::add_follower( 1, $follower ); + Followers::add( 1, $follower ); } - $follower = Followers::get_follower( 1, 'http://sally.example.org' ); + $follower = Followers::get_by_uri( 1, 'http://sally.example.org' ); for ( $i = 1; $i <= 15; $i++ ) { \add_post_meta( $follower->ID, '_activitypub_errors', 'error ' . $i ); } - $follower = Followers::get_follower( 1, 'http://sally.example.org' ); + $follower = Followers::get_by_uri( 1, 'http://sally.example.org' ); $actors = Remote_Actors::get_faulty(); $this->assertEquals( 1, \count( $actors ) ); @@ -338,7 +338,7 @@ public function test_get_faulty_followers() { Remote_Actors::clear_errors( $follower->ID ); - $follower = Followers::get_follower( 1, 'http://sally.example.org' ); + $follower = Followers::get_by_uri( 1, 'http://sally.example.org' ); $actors = Remote_Actors::get_faulty(); $this->assertEquals( 0, \count( $actors ) ); @@ -352,14 +352,14 @@ public function test_get_faulty_followers() { public function test_add_duplicate_follower() { $follower = 'https://12345.example.com'; - Followers::add_follower( 1, $follower ); - Followers::add_follower( 1, $follower ); - Followers::add_follower( 1, $follower ); - Followers::add_follower( 1, $follower ); - Followers::add_follower( 1, $follower ); - Followers::add_follower( 1, $follower ); + Followers::add( 1, $follower ); + Followers::add( 1, $follower ); + Followers::add( 1, $follower ); + Followers::add( 1, $follower ); + Followers::add( 1, $follower ); + Followers::add( 1, $follower ); - $db_followers = Followers::get_followers( 1 ); + $db_followers = Followers::get_many( 1 ); $this->assertStringContainsString( $follower, serialize( $db_followers ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize @@ -426,7 +426,7 @@ function ( $pre, $actor ) { \Activitypub\Migration::migrate_from_0_17(); - $db_followers = Followers::get_followers( 1 ); + $db_followers = Followers::get_many( 1 ); $this->assertCount( $expected_count, $db_followers ); if ( $expected_count > 0 ) { @@ -624,7 +624,7 @@ public function test_get_inboxes_for_activity() { // Create test followers. foreach ( $followers as $follower ) { $actor = self::$actors[ $follower ]; - Followers::add_follower( $actor_id, $actor['id'] ); + Followers::add( $actor_id, $actor['id'] ); } // Test basic retrieval. @@ -651,7 +651,7 @@ public function test_get_inboxes_for_activity() { // Test with blog user in dual mode. \update_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_AND_BLOG_MODE ); - Followers::add_follower( Actors::BLOG_USER_ID, self::$actors['sally@example.org']['id'] ); + Followers::add( Actors::BLOG_USER_ID, self::$actors['sally@example.org']['id'] ); $inboxes = Followers::get_inboxes_for_activity( '{"type":"Delete"}', diff --git a/tests/phpunit/tests/includes/collection/class-test-following.php b/tests/phpunit/tests/includes/collection/class-test-following.php index ed61e5d5b..bd913feea 100644 --- a/tests/phpunit/tests/includes/collection/class-test-following.php +++ b/tests/phpunit/tests/includes/collection/class-test-following.php @@ -396,11 +396,11 @@ public function test_unfollow() { Accept::handle_accept( $accept_5, -1 ); // User 1 follows https://example.com/actor/1. - $following = Following::get_following_with_count( $user_ids[0] ); + $following = Following::query( $user_ids[0] ); $this->assertCount( 1, $following['following'] ); $this->assertSame( 1, $following['total'] ); - $following = Following::get_following_with_count( -1 ); + $following = Following::query( -1 ); $this->assertCount( 1, $following['following'] ); $this->assertSame( 1, $following['total'] ); @@ -410,11 +410,11 @@ public function test_unfollow() { // User 3 unfollows https://example.com/actor/1. Following::unfollow( Remote_Actors::get_by_uri( 'https://example.com/actor/1' ), 0 ); - $following = Following::get_following_with_count( 0 ); + $following = Following::query( 0 ); $this->assertCount( 0, $following['following'] ); $this->assertSame( 0, $following['total'] ); - $following = Following::get_following_with_count( -1 ); + $following = Following::query( -1 ); $this->assertCount( 1, $following['following'] ); $this->assertSame( 1, $following['total'] ); diff --git a/tests/phpunit/tests/includes/collection/class-test-interactions.php b/tests/phpunit/tests/includes/collection/class-test-interactions.php index 34bc339ca..0248ab8fa 100644 --- a/tests/phpunit/tests/includes/collection/class-test-interactions.php +++ b/tests/phpunit/tests/includes/collection/class-test-interactions.php @@ -299,12 +299,12 @@ public function test_get_interaction_by_id() { Interactions::add_comment( $object ); $comment = \Activitypub\object_id_to_comment( $id ); - $interactions = Interactions::get_interaction_by_id( $id ); + $interactions = Interactions::get_by_id( $id ); $this->assertIsArray( $interactions ); $this->assertEquals( $comment->comment_ID, $interactions[0]->comment_ID ); $comment = \Activitypub\object_id_to_comment( $id ); - $interactions = Interactions::get_interaction_by_id( $url ); + $interactions = Interactions::get_by_id( $url ); $this->assertIsArray( $interactions ); $this->assertEquals( $comment->comment_ID, $interactions[0]->comment_ID ); } diff --git a/tests/phpunit/tests/includes/handler/class-test-follow.php b/tests/phpunit/tests/includes/handler/class-test-follow.php index f9e08c61b..c58699691 100644 --- a/tests/phpunit/tests/includes/handler/class-test-follow.php +++ b/tests/phpunit/tests/includes/handler/class-test-follow.php @@ -105,18 +105,18 @@ function () use ( $actor_url ) { ); // Track followers count before. - $followers_before = Followers::get_followers( $target_user_id ); + $followers_before = Followers::get_many( $target_user_id ); $followers_count_before = count( $followers_before ); Follow::handle_follow( $activity_object, $target_user_id ); // Check if follower was added. if ( $should_add_follower ) { - $followers_after = Followers::get_followers( $target_user_id ); + $followers_after = Followers::get_many( $target_user_id ); $followers_count_after = count( $followers_after ); $this->assertEquals( $followers_count_before + 1, $followers_count_after, $description . ' - Follower should be added' ); } else { - $followers_after = Followers::get_followers( $target_user_id ); + $followers_after = Followers::get_many( $target_user_id ); $followers_count_after = count( $followers_after ); $this->assertEquals( $followers_count_before, $followers_count_after, $description . ' - Follower should not be added' ); } @@ -223,7 +223,7 @@ function () use ( $actor ) { } ); - $remote_actor = Followers::add_follower( + $remote_actor = Followers::add( self::$user_id, $activity_object['actor'] ); diff --git a/tests/phpunit/tests/includes/handler/class-test-move.php b/tests/phpunit/tests/includes/handler/class-test-move.php index 8d3ee2310..d096e0c38 100644 --- a/tests/phpunit/tests/includes/handler/class-test-move.php +++ b/tests/phpunit/tests/includes/handler/class-test-move.php @@ -173,12 +173,12 @@ public function test_handle_move_with_invalid_target() { Move::handle_move( $activity, 1 ); // Assert that the original follower still exists and wasn't modified. - $existing_follower = Followers::get_follower( $this->user_id, $origin ); + $existing_follower = Followers::get_by_uri( $this->user_id, $origin ); $this->assertNotNull( $existing_follower ); $this->assertEquals( $origin, $existing_follower->guid ); // Assert that no new follower was created for the target. - $target_follower = Followers::get_follower( $this->user_id, $target ); + $target_follower = Followers::get_by_uri( $this->user_id, $target ); $this->assertWPError( $target_follower ); // Cleanup. @@ -206,7 +206,7 @@ public function test_handle_move_without_target_or_origin() { \add_post_meta( $id, Followers::FOLLOWER_META_KEY, $this->user_id ); // Store initial followers count. - $initial_followers = Followers::get_followers( $this->user_id ); + $initial_followers = Followers::get_many( $this->user_id ); $initial_count = count( $initial_followers ); $activity = array( @@ -216,11 +216,11 @@ public function test_handle_move_without_target_or_origin() { Move::handle_move( $activity, 1 ); // Verify that no followers were added or removed. - $final_followers = Followers::get_followers( $this->user_id ); + $final_followers = Followers::get_many( $this->user_id ); $this->assertEquals( $initial_count, count( $final_followers ) ); // Verify that our test follower remains unchanged. - $existing_follower = Followers::get_follower( $this->user_id, 'https://example.com/test-profile' ); + $existing_follower = Followers::get_by_uri( $this->user_id, 'https://example.com/test-profile' ); $this->assertNotNull( $existing_follower ); $actor = Remote_Actors::get_actor( $existing_follower ); diff --git a/tests/phpunit/tests/includes/handler/class-test-quote-request.php b/tests/phpunit/tests/includes/handler/class-test-quote-request.php index 32e8f53bf..c3fe3e37b 100644 --- a/tests/phpunit/tests/includes/handler/class-test-quote-request.php +++ b/tests/phpunit/tests/includes/handler/class-test-quote-request.php @@ -163,7 +163,7 @@ function () use ( $actor_url ) { // Run setup callback if provided. if ( 'add_follower' === $setup_callback ) { - $remote_actor_id = Followers::add_follower( self::$user_id, $actor_url ); + $remote_actor_id = Followers::add( self::$user_id, $actor_url ); $this->assertNotFalse( $remote_actor_id, 'Should successfully add follower' ); } elseif ( 'mock_actor_error' === $setup_callback ) { // Override the actor metadata filter to return an error. diff --git a/tests/phpunit/tests/includes/handler/class-test-undo.php b/tests/phpunit/tests/includes/handler/class-test-undo.php index 08d3bbdbe..ff232c010 100644 --- a/tests/phpunit/tests/includes/handler/class-test-undo.php +++ b/tests/phpunit/tests/includes/handler/class-test-undo.php @@ -110,7 +110,7 @@ function () use ( $actor_url ) { \Activitypub\Handler\Follow::handle_follow( $follow_activity, self::$user_id ); // Verify follower was added. - $followers = Followers::get_followers( self::$user_id ); + $followers = Followers::get_many( self::$user_id ); $this->assertNotEmpty( $followers, $description . ' - Should have followers after Follow activity' ); // Create undo follow activity. @@ -131,7 +131,7 @@ function () use ( $actor_url ) { Undo::handle_undo( $undo_activity, self::$user_id ); // Verify follower was removed. - $followers_after = Followers::get_followers( self::$user_id ); + $followers_after = Followers::get_many( self::$user_id ); $this->assertEmpty( $followers_after, $description . ' - Should have no followers after Undo activity' ); } diff --git a/tests/phpunit/tests/includes/handler/class-test-update.php b/tests/phpunit/tests/includes/handler/class-test-update.php index 81324289f..e89bac7f4 100644 --- a/tests/phpunit/tests/includes/handler/class-test-update.php +++ b/tests/phpunit/tests/includes/handler/class-test-update.php @@ -109,7 +109,7 @@ public function test_update_actor( $activity_data, $http_response, $expected_out $this->assertWPError( $follower, $description ); } else { // For successful updates, add follower first then test update. - Followers::add_follower( $this->user_id, $actor_url ); + Followers::add( $this->user_id, $actor_url ); $follower = Remote_Actors::get_by_uri( $actor_url ); $this->assertNotNull( $follower, $description ); diff --git a/tests/phpunit/tests/includes/wp-admin/table/class-test-followers.php b/tests/phpunit/tests/includes/wp-admin/table/class-test-followers.php index ee6001f4d..8be8f0598 100644 --- a/tests/phpunit/tests/includes/wp-admin/table/class-test-followers.php +++ b/tests/phpunit/tests/includes/wp-admin/table/class-test-followers.php @@ -86,7 +86,7 @@ function ( $value, $actor ) use ( $actor_url, $actor_data ) { ); // Add the follower. - Follower_Collection::add_follower( get_current_user_id(), $actor_url ); + Follower_Collection::add( get_current_user_id(), $actor_url ); // Use the real prepare_items() method. $this->followers_table->prepare_items(); @@ -222,7 +222,7 @@ function ( $value, $actor ) use ( $actor_data ) { ); // Add follower using the actor object. - Follower_Collection::add_follower( get_current_user_id(), $actor_data['id'] ); + Follower_Collection::add( get_current_user_id(), $actor_data['id'] ); // Prepare items to test normalization. $this->followers_table->prepare_items(); diff --git a/tests/phpunit/tests/integration/class-test-enable-mastodon-apps.php b/tests/phpunit/tests/integration/class-test-enable-mastodon-apps.php index 451b137b0..90b5463b0 100644 --- a/tests/phpunit/tests/integration/class-test-enable-mastodon-apps.php +++ b/tests/phpunit/tests/integration/class-test-enable-mastodon-apps.php @@ -119,7 +119,7 @@ public function test_api_account_followers_internal() { $followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' ); foreach ( $followers as $follower ) { - \Activitypub\Collection\Followers::add_follower( 1, $follower ); + \Activitypub\Collection\Followers::add( 1, $follower ); } $account = new \Enable_Mastodon_Apps\Entity\Account(); From 742411ebf9414d067bc47884f319b843ec9236a1 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 11:48:49 +0200 Subject: [PATCH 02/10] Update includes/collection/class-following.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- includes/collection/class-following.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index a36b83538..11fc093f5 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -346,7 +346,7 @@ public static function count_pending( $user_id ) { */ public static function get_all_with_count( $user_id, $number = -1, $page = null, $args = array() ) { _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query' ); - return self::get_all( $user_id, $number = -1, $page = null, $args = array() ); + return self::get_all( $user_id, $number, $page, $args ); } /** From 24b98355f7e7786de86e1aa685318fb590942c88 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 16:41:35 +0200 Subject: [PATCH 03/10] Update includes/collection/class-following.php Co-authored-by: Konstantin Obenland --- includes/collection/class-following.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index 11fc093f5..18a1e4b99 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -281,6 +281,7 @@ public static function get_pending_with_count( $user_id, $number = -1, $page = n 'value' => $user_id, ), ); + return self::query( $user_id, $number, $page, $args ); } From f65111a027b558fd08402d1b3d3a15e000db2272 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 16:41:41 +0200 Subject: [PATCH 04/10] Update includes/collection/class-following.php Co-authored-by: Konstantin Obenland --- includes/collection/class-following.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index 18a1e4b99..9839b3a00 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -325,6 +325,7 @@ public static function count_pending( $user_id ) { ), ), ); + return self::query( $user_id, 1, null, $args )['total']; } From 2dd4b7beb1a662775ca35c53bab0c7594532cfb9 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 16:41:47 +0200 Subject: [PATCH 05/10] Update includes/collection/class-following.php Co-authored-by: Konstantin Obenland --- includes/collection/class-following.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index 9839b3a00..d802447f0 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -399,6 +399,7 @@ public static function count_all( $user_id ) { ), ), ); + return self::query( $user_id, 1, null, $args )['total']; } From e7974353a7bb9954f4650ab86f98dc468f14c756 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 19:13:13 +0200 Subject: [PATCH 06/10] Refactor following queries for clarity and reuse Moved meta_query logic for pending and all followings into dedicated methods in Following_Collection, improving code reuse and clarity. Updated admin table to use these methods instead of duplicating query logic. --- includes/collection/class-following.php | 55 +++++++++++++-------- includes/wp-admin/table/class-following.php | 23 +-------- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index d802447f0..ac46c1e7c 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -256,9 +256,7 @@ public static function get_many( $user_id, $number = -1, $page = null, $args = a } /** - * Get the Followings of a given user, along with a total count for pagination purposes. - * - * @deprecated unreleased Use {@see Following::query()} with status parameter + * Get the pending followings of a given user, along with a total count for pagination purposes. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -266,22 +264,25 @@ public static function get_many( $user_id, $number = -1, $page = null, $args = a * @param array $args The WP_Query arguments. * * @return array { - * Data about the followings. + * Data about the pending followings. * - * @type \WP_Post[] $followings List of `Following` objects. - * @type int $total Total number of followings. + * @type \WP_Post[] $following List of `Following` objects. + * @type int $total Total number of pending followings. * } */ public static function get_pending_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query' ); - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - $args['meta_query'] = array( - array( - 'key' => self::PENDING_META_KEY, - 'value' => $user_id, + $defaults = array( + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + 'meta_query' => array( + array( + 'key' => self::PENDING_META_KEY, + 'value' => $user_id, + ), ), ); + $args = \wp_parse_args( $args, $defaults ); + return self::query( $user_id, $number, $page, $args ); } @@ -330,9 +331,7 @@ public static function count_pending( $user_id ) { } /** - * Get all followings of a given user, along with a total count for pagination purposes. - * - * @deprecated unreleased Use {@see Following::query()} with status parameter + * Get all followings of a given user (both accepted and pending), along with a total count for pagination purposes. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -340,15 +339,31 @@ public static function count_pending( $user_id ) { * @param array $args The WP_Query arguments. * * @return array { - * Data about the followings. + * Data about all followings. * - * @type \WP_Post[] $followers List of `Follower` objects. - * @type int $total Total number of followers. + * @type \WP_Post[] $following List of `Following` objects. + * @type int $total Total number of all followings. * } */ public static function get_all_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query' ); - return self::get_all( $user_id, $number, $page, $args ); + $defaults = array( + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + 'meta_query' => array( + 'relation' => 'OR', + array( + 'key' => self::FOLLOWING_META_KEY, + 'value' => $user_id, + ), + array( + 'key' => self::PENDING_META_KEY, + 'value' => $user_id, + ), + ), + ); + + $args = \wp_parse_args( $args, $defaults ); + + return self::query( $user_id, $number, $page, $args ); } /** diff --git a/includes/wp-admin/table/class-following.php b/includes/wp-admin/table/class-following.php index d0532eda9..71ea66ac9 100644 --- a/includes/wp-admin/table/class-following.php +++ b/includes/wp-admin/table/class-following.php @@ -223,30 +223,11 @@ public function prepare_items() { } if ( Following_Collection::PENDING === $status ) { - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - $args['meta_query'] = array( - array( - 'key' => Following_Collection::PENDING_META_KEY, - 'value' => $this->user_id, - ), - ); - $following_with_count = Following_Collection::query( $this->user_id, $per_page, $page_num, $args ); + $following_with_count = Following_Collection::get_pending_with_count( $this->user_id, $per_page, $page_num, $args ); } elseif ( Following_Collection::ACCEPTED === $status ) { $following_with_count = Following_Collection::query( $this->user_id, $per_page, $page_num, $args ); } else { - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - $args['meta_query'] = array( - 'relation' => 'OR', - array( - 'key' => Following_Collection::FOLLOWING_META_KEY, - 'value' => $this->user_id, - ), - array( - 'key' => Following_Collection::PENDING_META_KEY, - 'value' => $this->user_id, - ), - ); - $following_with_count = Following_Collection::query( $this->user_id, $per_page, $page_num, $args ); + $following_with_count = Following_Collection::get_all_with_count( $this->user_id, $per_page, $page_num, $args ); } $followings = $following_with_count['following']; From 2a2160b264bb5ac5b6066cdc0d4f16bca585ac09 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 19:23:10 +0200 Subject: [PATCH 07/10] Refactor following queries for clarity and reuse Renamed and refactored methods in Following_Collection to use query_pending and query_all for pending and all followings, improving code clarity and reducing duplication. Updated usages in admin table to match new method names. --- includes/collection/class-following.php | 63 +++------------------ includes/wp-admin/table/class-following.php | 4 +- 2 files changed, 10 insertions(+), 57 deletions(-) diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index ac46c1e7c..5bdf9ae09 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -256,7 +256,7 @@ public static function get_many( $user_id, $number = -1, $page = null, $args = a } /** - * Get the pending followings of a given user, along with a total count for pagination purposes. + * Query pending followings of a given user, with pagination info. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -270,7 +270,7 @@ public static function get_many( $user_id, $number = -1, $page = null, $args = a * @type int $total Total number of pending followings. * } */ - public static function get_pending_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + public static function query_pending( $user_id, $number = -1, $page = null, $args = array() ) { $defaults = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 'meta_query' => array( @@ -297,14 +297,7 @@ public static function get_pending_with_count( $user_id, $number = -1, $page = n * @return \WP_Post[] List of `Following` objects. */ public static function get_pending( $user_id, $number = -1, $page = null, $args = array() ) { - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - $args['meta_query'] = array( - array( - 'key' => self::PENDING_META_KEY, - 'value' => $user_id, - ), - ); - $data = self::query( $user_id, $number, $page, $args ); + $data = self::query_pending( $user_id, $number, $page, $args ); return $data['following']; } @@ -317,21 +310,11 @@ public static function get_pending( $user_id, $number = -1, $page = null, $args * @return int The total number of pending followings. */ public static function count_pending( $user_id ) { - $args = array( - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'meta_query' => array( - array( - 'key' => self::PENDING_META_KEY, - 'value' => $user_id, - ), - ), - ); - - return self::query( $user_id, 1, null, $args )['total']; + return self::query_pending( $user_id, 1 )['total']; } /** - * Get all followings of a given user (both accepted and pending), along with a total count for pagination purposes. + * Query all followings of a given user (both accepted and pending), with pagination info. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -345,7 +328,7 @@ public static function count_pending( $user_id ) { * @type int $total Total number of all followings. * } */ - public static function get_all_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + public static function query_all( $user_id, $number = -1, $page = null, $args = array() ) { $defaults = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 'meta_query' => array( @@ -374,22 +357,7 @@ public static function get_all_with_count( $user_id, $number = -1, $page = null, * @return \WP_Post[] List of `Following` objects. */ public static function get_all( $user_id ) { - $args = array( - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'meta_query' => array( - 'relation' => 'OR', - array( - 'key' => self::FOLLOWING_META_KEY, - 'value' => $user_id, - ), - array( - 'key' => self::PENDING_META_KEY, - 'value' => $user_id, - ), - ), - ); - - return self::query( $user_id, -1, null, $args )['following']; + return self::query_all( $user_id, -1 )['following']; } /** @@ -400,22 +368,7 @@ public static function get_all( $user_id ) { * @return int The total number of all followings. */ public static function count_all( $user_id ) { - $args = array( - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'meta_query' => array( - 'relation' => 'OR', - array( - 'key' => self::FOLLOWING_META_KEY, - 'value' => $user_id, - ), - array( - 'key' => self::PENDING_META_KEY, - 'value' => $user_id, - ), - ), - ); - - return self::query( $user_id, 1, null, $args )['total']; + return self::query_all( $user_id, 1 )['total']; } /** diff --git a/includes/wp-admin/table/class-following.php b/includes/wp-admin/table/class-following.php index 71ea66ac9..5212b408b 100644 --- a/includes/wp-admin/table/class-following.php +++ b/includes/wp-admin/table/class-following.php @@ -223,11 +223,11 @@ public function prepare_items() { } if ( Following_Collection::PENDING === $status ) { - $following_with_count = Following_Collection::get_pending_with_count( $this->user_id, $per_page, $page_num, $args ); + $following_with_count = Following_Collection::query_pending( $this->user_id, $per_page, $page_num, $args ); } elseif ( Following_Collection::ACCEPTED === $status ) { $following_with_count = Following_Collection::query( $this->user_id, $per_page, $page_num, $args ); } else { - $following_with_count = Following_Collection::get_all_with_count( $this->user_id, $per_page, $page_num, $args ); + $following_with_count = Following_Collection::query_all( $this->user_id, $per_page, $page_num, $args ); } $followings = $following_with_count['following']; From 3cc5d459ed0e7a70e37cbcc5b7c68f337ed72a77 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 19:25:52 +0200 Subject: [PATCH 08/10] Add deprecated methods for pending and all followings with count Introduces get_pending_with_count() and get_all_with_count() methods to retrieve pending and all followings with total count for pagination. These methods are marked as deprecated in favor of query_pending() and query_all(). --- includes/collection/class-following.php | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index 5bdf9ae09..ea1ef5c4d 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -465,6 +465,50 @@ public static function get_following_with_count( $user_id, $number = -1, $page = return self::query( $user_id, $number, $page, $args ); } + /** + * Get pending followings of a given user, along with a total count for pagination purposes. + * + * @deprecated unreleased Use {@see Following::query_pending()} + * + * @param int|null $user_id The ID of the WordPress User. + * @param int $number Maximum number of results to return. + * @param int $page Page number. + * @param array $args The WP_Query arguments. + * + * @return array { + * Data about the pending followings. + * + * @type \WP_Post[] $following List of `Following` objects. + * @type int $total Total number of pending followings. + * } + */ + public static function get_pending_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query_pending' ); + return self::query_pending( $user_id, $number, $page, $args ); + } + + /** + * Get all followings of a given user (both accepted and pending), along with a total count for pagination purposes. + * + * @deprecated unreleased Use {@see Following::query_all()} + * + * @param int|null $user_id The ID of the WordPress User. + * @param int $number Maximum number of results to return. + * @param int $page Page number. + * @param array $args The WP_Query arguments. + * + * @return array { + * Data about all followings. + * + * @type \WP_Post[] $following List of `Following` objects. + * @type int $total Total number of all followings. + * } + */ + public static function get_all_with_count( $user_id, $number = -1, $page = null, $args = array() ) { + _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query_all' ); + return self::query_all( $user_id, $number, $page, $args ); + } + /** * Get the Followings of a given user. * From 93d58b7c70f257ec04553066c512bd383deac4bb Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 20 Oct 2025 19:31:54 +0200 Subject: [PATCH 09/10] Update following count method to count_by_status Replaces calls to Following::count and Following_Collection::count with count_by_status in Heartbeat and Following classes for more accurate status-based counting. --- includes/wp-admin/class-heartbeat.php | 2 +- includes/wp-admin/table/class-following.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/wp-admin/class-heartbeat.php b/includes/wp-admin/class-heartbeat.php index bf0e42088..57e7b7800 100644 --- a/includes/wp-admin/class-heartbeat.php +++ b/includes/wp-admin/class-heartbeat.php @@ -84,7 +84,7 @@ public static function heartbeat_received( $response, $data ) { // Initialize the response. $response['activitypub_following'] = array( - 'counts' => Following::count( $user_id ), + 'counts' => Following::count_by_status( $user_id ), 'message' => __( 'Follow requests updated.', 'activitypub' ), 'no_items' => __( 'No profiles found.', 'activitypub' ), 'updated_items' => array(), diff --git a/includes/wp-admin/table/class-following.php b/includes/wp-admin/table/class-following.php index 5212b408b..39a4c97b5 100644 --- a/includes/wp-admin/table/class-following.php +++ b/includes/wp-admin/table/class-following.php @@ -268,7 +268,7 @@ public function prepare_items() { * @return string[] */ public function get_views() { - $count = Following_Collection::count( $this->user_id ); + $count = Following_Collection::count_by_status( $this->user_id ); $path = 'users.php?page=activitypub-following-list'; $status = Following_Collection::ALL; From fddb1dd480a24629373b220ff955ae9422248914 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Mon, 20 Oct 2025 13:19:05 -0500 Subject: [PATCH 10/10] Formatting changes --- includes/collection/class-blocked-actors.php | 20 +++++++++------ includes/collection/class-followers.php | 27 +++++++++++--------- includes/collection/class-following.php | 24 +++++++++-------- includes/collection/class-interactions.php | 10 +++++--- 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/includes/collection/class-blocked-actors.php b/includes/collection/class-blocked-actors.php index 4b2aaad09..338b07970 100644 --- a/includes/collection/class-blocked-actors.php +++ b/includes/collection/class-blocked-actors.php @@ -139,35 +139,37 @@ public static function get_many( $user_id, $number = -1, $page = null, $args = a /** * Add an actor block for a user. * - * @deprecated unreleased Use {@see Blocked_Actors::add()} + * @deprecated unreleased Use {@see Blocked_Actors::add()}. * * @param int $user_id The user ID. * @param string $value The actor URI to block. * @return bool True on success, false on failure. */ public static function add_block( $user_id, $value ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::add' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::add' ); + return self::add( $user_id, $value ); } /** * Remove an actor block for a user. * - * @deprecated unreleased Use {@see Blocked_Actors::remove()} + * @deprecated unreleased Use {@see Blocked_Actors::remove()}. * * @param int $user_id The user ID. * @param string|int $value The actor URI or post ID to unblock. * @return bool True on success, false on failure. */ public static function remove_block( $user_id, $value ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::remove' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::remove' ); + return self::remove( $user_id, $value ); } /** * Get the blocked actors of a given user, along with a total count for pagination purposes. * - * @deprecated unreleased Use {@see Blocked_Actors::query()} + * @deprecated unreleased Use {@see Blocked_Actors::query()}. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -182,14 +184,15 @@ public static function remove_block( $user_id, $value ) { * } */ public static function get_blocked_actors_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::query' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::query' ); + return self::query( $user_id, $number, $page, $args ); } /** * Get the blocked actors of a given user. * - * @deprecated unreleased Use {@see Blocked_Actors::get_many()} + * @deprecated unreleased Use {@see Blocked_Actors::get_many()}. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -199,7 +202,8 @@ public static function get_blocked_actors_with_count( $user_id, $number = -1, $p * @return \WP_Post[] List of blocked Actors. */ public static function get_blocked_actors( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::get_many' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Blocked_Actors::get_many' ); + return self::get_many( $user_id, $number, $page, $args ); } } diff --git a/includes/collection/class-followers.php b/includes/collection/class-followers.php index 20d6481f4..69ebddc6b 100644 --- a/includes/collection/class-followers.php +++ b/includes/collection/class-followers.php @@ -69,7 +69,7 @@ public static function add( $user_id, $actor ) { /** * Add new Follower. * - * @deprecated unreleased Use {@see Followers::add()} + * @deprecated unreleased Use {@see Followers::add()}. * * @param int $user_id The ID of the WordPress User. * @param string $actor The Actor URL. @@ -77,7 +77,8 @@ public static function add( $user_id, $actor ) { * @return int|\WP_Error The Follower ID or an WP_Error. */ public static function add_follower( $user_id, $actor ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::add' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::add' ); + return self::add( $user_id, $actor ); } @@ -114,7 +115,7 @@ public static function remove( $post_or_id, $user_id ) { /** * Remove a Follower. * - * @deprecated Use Activitypub\Collection\Followers::remove instead. + * @deprecated 7.1.0 Use {@see Followers::remove()}. * * @param int $user_id The ID of the WordPress User. * @param string $actor The Actor URL. @@ -122,7 +123,7 @@ public static function remove( $post_or_id, $user_id ) { * @return bool True on success, false on failure. */ public static function remove_follower( $user_id, $actor ) { - _deprecated_function( __METHOD__, '7.1.0', 'Activitypub\Collection\Followers::remove' ); + \_deprecated_function( __METHOD__, '7.1.0', 'Activitypub\Collection\Followers::remove' ); $remote_actor = self::get_by_uri( $user_id, $actor ); @@ -186,14 +187,14 @@ public static function get_follower( $user_id, $actor ) { /** * Get a Follower by Actor independent of the User. * - * @deprecated 7.4.0 + * @deprecated 7.4.0 Use {@see Remote_Actors::get_by_uri()}. * * @param string $actor The Actor URL. * * @return \WP_Post|\WP_Error The Follower object or WP_Error on failure. */ public static function get_follower_by_actor( $actor ) { - _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_by_uri' ); + \_deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_by_uri' ); return Remote_Actors::get_by_uri( $actor ); } @@ -234,7 +235,7 @@ public static function get_followers( $user_id, $number = -1, $page = null, $arg /** * Get the Followers of a given user, along with a total count for pagination purposes. * - * @deprecated unreleased Use {@see Followers::query()} + * @deprecated unreleased Use {@see Followers::query()}. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -249,7 +250,8 @@ public static function get_followers( $user_id, $number = -1, $page = null, $arg * } */ public static function get_followers_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::query' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::query' ); + return self::query( $user_id, $number, $page, $args ); } @@ -312,14 +314,15 @@ public static function count( $user_id ) { /** * Count the total number of followers. * - * @deprecated unreleased Use {@see Followers::count()} + * @deprecated unreleased Use {@see Followers::count()}. * * @param int $user_id The ID of the WordPress User. * * @return int The number of Followers */ public static function count_followers( $user_id ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::count' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Followers::count' ); + return self::count( $user_id ); } @@ -508,7 +511,7 @@ public static function get_faulty_followers( $number = 20 ) { * @return int|false The meta ID on success, false on failure. */ public static function add_error( $post_id, $error ) { - _deprecated_function( __METHOD__, '7.0.0', 'Activitypub\Collection\Remote_Actors::add_error' ); + \_deprecated_function( __METHOD__, '7.0.0', 'Activitypub\Collection\Remote_Actors::add_error' ); return Remote_Actors::add_error( $post_id, $error ); } @@ -523,7 +526,7 @@ public static function add_error( $post_id, $error ) { * @return bool True on success, false on failure. */ public static function clear_errors( $post_id ) { - _deprecated_function( __METHOD__, '7.0.0', 'Activitypub\Collection\Remote_Actors::clear_errors' ); + \_deprecated_function( __METHOD__, '7.0.0', 'Activitypub\Collection\Remote_Actors::clear_errors' ); return Remote_Actors::clear_errors( $post_id ); } diff --git a/includes/collection/class-following.php b/includes/collection/class-following.php index ea1ef5c4d..5861d743e 100644 --- a/includes/collection/class-following.php +++ b/includes/collection/class-following.php @@ -297,9 +297,7 @@ public static function query_pending( $user_id, $number = -1, $page = null, $arg * @return \WP_Post[] List of `Following` objects. */ public static function get_pending( $user_id, $number = -1, $page = null, $args = array() ) { - $data = self::query_pending( $user_id, $number, $page, $args ); - - return $data['following']; + return self::query_pending( $user_id, $number, $page, $args )['following']; } /** @@ -446,7 +444,7 @@ public static function remove_blocked_actors( $value, $type, $user_id ) { /** * Get the Followings of a given user, along with a total count for pagination purposes. * - * @deprecated unreleased Use {@see Following::query()} + * @deprecated unreleased Use {@see Following::query()}. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -461,14 +459,15 @@ public static function remove_blocked_actors( $value, $type, $user_id ) { * } */ public static function get_following_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query' ); + return self::query( $user_id, $number, $page, $args ); } /** * Get pending followings of a given user, along with a total count for pagination purposes. * - * @deprecated unreleased Use {@see Following::query_pending()} + * @deprecated unreleased Use {@see Following::query_pending()}. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -483,14 +482,15 @@ public static function get_following_with_count( $user_id, $number = -1, $page = * } */ public static function get_pending_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query_pending' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query_pending' ); + return self::query_pending( $user_id, $number, $page, $args ); } /** * Get all followings of a given user (both accepted and pending), along with a total count for pagination purposes. * - * @deprecated unreleased Use {@see Following::query_all()} + * @deprecated unreleased Use {@see Following::query_all()}. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -505,14 +505,15 @@ public static function get_pending_with_count( $user_id, $number = -1, $page = n * } */ public static function get_all_with_count( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query_all' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::query_all' ); + return self::query_all( $user_id, $number, $page, $args ); } /** * Get the Followings of a given user. * - * @deprecated unreleased Use {@see Following::get_many()} + * @deprecated unreleased Use {@see Following::get_many()}. * * @param int|null $user_id The ID of the WordPress User. * @param int $number Maximum number of results to return. @@ -522,7 +523,8 @@ public static function get_all_with_count( $user_id, $number = -1, $page = null, * @return \WP_Post[] List of `Following` objects. */ public static function get_following( $user_id, $number = -1, $page = null, $args = array() ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::get_many' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Following::get_many' ); + return self::get_many( $user_id, $number, $page, $args ); } } diff --git a/includes/collection/class-interactions.php b/includes/collection/class-interactions.php index 9ba485733..3d014dbe6 100644 --- a/includes/collection/class-interactions.php +++ b/includes/collection/class-interactions.php @@ -164,14 +164,15 @@ public static function get_by_id( $url ) { /** * Get interaction(s) for a given URL/ID. * - * @deprecated unreleased Use {@see Interactions::get_by_id()} + * @deprecated unreleased Use {@see Interactions::get_by_id()}. * * @param string $url The URL/ID to get interactions for. * * @return array The interactions as WP_Comment objects. */ public static function get_interaction_by_id( $url ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Interactions::get_by_id' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Interactions::get_by_id' ); + return self::get_by_id( $url ); } @@ -208,14 +209,15 @@ public static function get_by_actor( $actor ) { /** * Get interaction(s) for a given actor. * - * @deprecated unreleased Use {@see Interactions::get_by_actor()} + * @deprecated unreleased Use {@see Interactions::get_by_actor()}. * * @param string $actor The Actor-URL. * * @return array The interactions as WP_Comment objects. */ public static function get_interactions_by_actor( $actor ) { - _deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Interactions::get_by_actor' ); + \_deprecated_function( __METHOD__, 'unreleased', 'Activitypub\Collection\Interactions::get_by_actor' ); + return self::get_by_actor( $actor ); }