Skip to content

Commit 971332b

Browse files
committed
Use object types as channels for ActivityPub adapter
- Create channels based on ap_object_type taxonomy (Note, Article, etc.) - Only show object types that have posts for the current user - Filter timeline by object type based on selected channel - Channel UIDs use 'ap-' prefix (e.g., ap-note, ap-article)
1 parent a218809 commit 971332b

1 file changed

Lines changed: 63 additions & 11 deletions

File tree

includes/adapters/class-activitypub.php

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)