@@ -90,15 +90,59 @@ public function get_channels( $channels, $user_id ) {
9090 return $ channels ;
9191 }
9292
93- // Add ActivityPub channel.
94- $ channels [] = array (
95- 'uid ' => 'activitypub ' ,
96- 'name ' => \__ ( 'ActivityPub ' , 'microsub ' ),
97- );
93+ // Get object types that have posts for this user.
94+ $ terms = $ this ->get_object_types_for_user ( $ user_id );
95+
96+ foreach ( $ terms as $ term ) {
97+ $ channels [] = array (
98+ 'uid ' => 'ap- ' . $ term ->slug ,
99+ 'name ' => $ term ->name ,
100+ );
101+ }
98102
99103 return $ channels ;
100104 }
101105
106+ /**
107+ * Get object types that have posts for a user.
108+ *
109+ * @param int $user_id The user ID.
110+ * @return array Array of term objects.
111+ */
112+ protected function get_object_types_for_user ( $ user_id ) {
113+ global $ wpdb ;
114+
115+ // Get term IDs that have posts for this user.
116+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
117+ $ term_ids = $ wpdb ->get_col (
118+ $ wpdb ->prepare (
119+ "SELECT DISTINCT tt.term_id
120+ FROM {$ wpdb ->term_taxonomy } tt
121+ INNER JOIN {$ wpdb ->term_relationships } tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
122+ INNER JOIN {$ wpdb ->posts } p ON tr.object_id = p.ID
123+ INNER JOIN {$ wpdb ->postmeta } pm ON p.ID = pm.post_id
124+ WHERE tt.taxonomy = 'ap_object_type'
125+ AND p.post_type = %s
126+ AND pm.meta_key = '_activitypub_user_id'
127+ AND pm.meta_value = %s " ,
128+ Posts::POST_TYPE ,
129+ $ user_id
130+ )
131+ );
132+
133+ if ( empty ( $ term_ids ) ) {
134+ return array ();
135+ }
136+
137+ return \get_terms (
138+ array (
139+ 'taxonomy ' => 'ap_object_type ' ,
140+ 'include ' => $ term_ids ,
141+ 'hide_empty ' => false ,
142+ )
143+ );
144+ }
145+
102146 /**
103147 * Get timeline entries for a channel.
104148 *
@@ -112,13 +156,14 @@ public function get_timeline( $result, $channel, $args ) {
112156 return $ result ;
113157 }
114158
115- // Only handle 'activitypub' channel .
116- if ( ' activitypub ' !== $ channel ) {
159+ // Only handle 'ap-*' channels .
160+ if ( ! \str_starts_with ( $ channel, ' ap- ' ) ) {
117161 return $ result ;
118162 }
119163
120- $ limit = isset ( $ args ['limit ' ] ) ? \absint ( $ args ['limit ' ] ) : 20 ;
121- $ user_id = \get_current_user_id ();
164+ $ object_type_slug = \substr ( $ channel , 3 );
165+ $ limit = isset ( $ args ['limit ' ] ) ? \absint ( $ args ['limit ' ] ) : 20 ;
166+ $ user_id = \get_current_user_id ();
122167
123168 $ query_args = array (
124169 'post_type ' => Posts::POST_TYPE ,
@@ -128,6 +173,13 @@ public function get_timeline( $result, $channel, $args ) {
128173 'order ' => 'DESC ' ,
129174 'meta_key ' => '_activitypub_user_id ' , // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
130175 'meta_value ' => $ user_id , // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
176+ 'tax_query ' => array ( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
177+ array (
178+ 'taxonomy ' => 'ap_object_type ' ,
179+ 'field ' => 'slug ' ,
180+ 'terms ' => $ object_type_slug ,
181+ ),
182+ ),
131183 );
132184
133185 if ( ! empty ( $ args ['after ' ] ) ) {
@@ -167,8 +219,8 @@ public function get_following( $result, $channel, $user_id ) {
167219 return $ result ;
168220 }
169221
170- // Only handle 'activitypub' channel .
171- if ( ' activitypub ' !== $ channel ) {
222+ // Only handle 'ap-*' channels .
223+ if ( ! \str_starts_with ( $ channel, ' ap- ' ) ) {
172224 return $ result ;
173225 }
174226
0 commit comments