8
8
namespace Activitypub ;
9
9
10
10
use Activitypub \Activity \Activity ;
11
+ use Activitypub \Collection \Actors ;
12
+ use Activitypub \Collection \Blocked_Actors ;
11
13
12
14
/**
13
15
* ActivityPub Moderation class.
14
16
*
15
17
* Handles user-specific blocking and site-wide moderation.
16
18
*/
17
19
class Moderation {
20
+
21
+ /**
22
+ * Block type constants.
23
+ */
24
+ const TYPE_ACTOR = 'actor ' ;
25
+ const TYPE_DOMAIN = 'domain ' ;
26
+ const TYPE_KEYWORD = 'keyword ' ;
27
+
28
+ /**
29
+ * Post meta key for blocked actors.
30
+ */
31
+ const BLOCKED_ACTORS_META_KEY = '_activitypub_blocked_by ' ;
32
+
18
33
/**
19
34
* User meta key for blocked keywords.
20
35
*/
21
36
const USER_META_KEYS = array (
22
- ' domain ' => 'activitypub_blocked_domains ' ,
23
- ' keyword ' => 'activitypub_blocked_keywords ' ,
37
+ self :: TYPE_DOMAIN => 'activitypub_blocked_domains ' ,
38
+ self :: TYPE_KEYWORD => 'activitypub_blocked_keywords ' ,
24
39
);
25
40
26
41
/**
27
42
* Option key for site-wide blocked keywords.
28
43
*/
29
44
const OPTION_KEYS = array (
30
- ' domain ' => 'activitypub_site_blocked_domains ' ,
31
- ' keyword ' => 'activitypub_site_blocked_keywords ' ,
45
+ self :: TYPE_DOMAIN => 'activitypub_site_blocked_domains ' ,
46
+ self :: TYPE_KEYWORD => 'activitypub_site_blocked_keywords ' ,
32
47
);
33
48
34
49
/**
@@ -95,11 +110,23 @@ public static function activity_is_blocked_for_user( $activity, $user_id ) {
95
110
*/
96
111
public static function add_user_block ( $ user_id , $ type , $ value ) {
97
112
switch ( $ type ) {
98
- case 'domain ' :
99
- case 'keyword ' :
113
+ case self ::TYPE_ACTOR :
114
+ return Blocked_Actors::add_block ( $ user_id , $ value );
115
+
116
+ case self ::TYPE_DOMAIN :
117
+ case self ::TYPE_KEYWORD :
100
118
$ blocks = \get_user_meta ( $ user_id , self ::USER_META_KEYS [ $ type ], true ) ?: array (); // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
101
119
102
- if ( ! in_array ( $ value , $ blocks , true ) ) {
120
+ if ( ! \in_array ( $ value , $ blocks , true ) ) {
121
+ /**
122
+ * Fired when a domain or keyword is blocked.
123
+ *
124
+ * @param string $value The blocked domain or keyword.
125
+ * @param string $type The block type (actor, domain, keyword).
126
+ * @param int $user_id The user ID.
127
+ */
128
+ \do_action ( 'activitypub_add_user_block ' , $ value , $ type , $ user_id );
129
+
103
130
$ blocks [] = $ value ;
104
131
return (bool ) \update_user_meta ( $ user_id , self ::USER_META_KEYS [ $ type ], $ blocks );
105
132
}
@@ -119,14 +146,26 @@ public static function add_user_block( $user_id, $type, $value ) {
119
146
*/
120
147
public static function remove_user_block ( $ user_id , $ type , $ value ) {
121
148
switch ( $ type ) {
122
- case 'domain ' :
123
- case 'keyword ' :
149
+ case self ::TYPE_ACTOR :
150
+ return Blocked_Actors::remove_block ( $ user_id , $ value );
151
+
152
+ case self ::TYPE_DOMAIN :
153
+ case self ::TYPE_KEYWORD :
124
154
$ blocks = \get_user_meta ( $ user_id , self ::USER_META_KEYS [ $ type ], true ) ?: array (); // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
125
- $ key = array_search ( $ value , $ blocks , true );
155
+ $ key = \ array_search ( $ value , $ blocks , true );
126
156
127
157
if ( false !== $ key ) {
158
+ /**
159
+ * Fired when a domain or keyword is unblocked.
160
+ *
161
+ * @param string $value The unblocked domain or keyword.
162
+ * @param string $type The block type (actor, domain, keyword).
163
+ * @param int $user_id The user ID.
164
+ */
165
+ \do_action ( 'activitypub_remove_user_block ' , $ value , $ type , $ user_id );
166
+
128
167
unset( $ blocks [ $ key ] );
129
- return \update_user_meta ( $ user_id , self ::USER_META_KEYS [ $ type ], array_values ( $ blocks ) );
168
+ return \update_user_meta ( $ user_id , self ::USER_META_KEYS [ $ type ], \ array_values ( $ blocks ) );
130
169
}
131
170
break ;
132
171
}
@@ -142,9 +181,9 @@ public static function remove_user_block( $user_id, $type, $value ) {
142
181
*/
143
182
public static function get_user_blocks ( $ user_id ) {
144
183
return array (
145
- 'actors ' => array ( ),
146
- 'domains ' => \get_user_meta ( $ user_id , self ::USER_META_KEYS [' domain ' ], true ) ?: array (), // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
147
- 'keywords ' => \get_user_meta ( $ user_id , self ::USER_META_KEYS [' keyword ' ], true ) ?: array (), // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
184
+ 'actors ' => \wp_list_pluck ( Blocked_Actors:: get_blocked_actors ( $ user_id ), ' guid ' ),
185
+ 'domains ' => \get_user_meta ( $ user_id , self ::USER_META_KEYS [ self :: TYPE_DOMAIN ], true ) ?: array (), // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
186
+ 'keywords ' => \get_user_meta ( $ user_id , self ::USER_META_KEYS [ self :: TYPE_KEYWORD ], true ) ?: array (), // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
148
187
);
149
188
}
150
189
@@ -157,11 +196,23 @@ public static function get_user_blocks( $user_id ) {
157
196
*/
158
197
public static function add_site_block ( $ type , $ value ) {
159
198
switch ( $ type ) {
160
- case 'domain ' :
161
- case 'keyword ' :
199
+ case self ::TYPE_ACTOR :
200
+ // Site-wide actor blocking uses the BLOG_USER_ID.
201
+ return self ::add_user_block ( Actors::BLOG_USER_ID , self ::TYPE_ACTOR , $ value );
202
+
203
+ case self ::TYPE_DOMAIN :
204
+ case self ::TYPE_KEYWORD :
162
205
$ blocks = \get_option ( self ::OPTION_KEYS [ $ type ], array () );
163
206
164
- if ( ! in_array ( $ value , $ blocks , true ) ) {
207
+ if ( ! \in_array ( $ value , $ blocks , true ) ) {
208
+ /**
209
+ * Fired when a domain or keyword is blocked site-wide.
210
+ *
211
+ * @param string $value The blocked domain or keyword.
212
+ * @param string $type The block type (actor, domain, keyword).
213
+ */
214
+ \do_action ( 'activitypub_add_site_block ' , $ value , $ type );
215
+
165
216
$ blocks [] = $ value ;
166
217
return \update_option ( self ::OPTION_KEYS [ $ type ], $ blocks );
167
218
}
@@ -180,14 +231,26 @@ public static function add_site_block( $type, $value ) {
180
231
*/
181
232
public static function remove_site_block ( $ type , $ value ) {
182
233
switch ( $ type ) {
183
- case 'domain ' :
184
- case 'keyword ' :
234
+ case self ::TYPE_ACTOR :
235
+ // Site-wide actor unblocking uses the BLOG_USER_ID.
236
+ return self ::remove_user_block ( Actors::BLOG_USER_ID , self ::TYPE_ACTOR , $ value );
237
+
238
+ case self ::TYPE_DOMAIN :
239
+ case self ::TYPE_KEYWORD :
185
240
$ blocks = \get_option ( self ::OPTION_KEYS [ $ type ], array () );
186
- $ key = array_search ( $ value , $ blocks , true );
241
+ $ key = \ array_search ( $ value , $ blocks , true );
187
242
188
243
if ( false !== $ key ) {
244
+ /**
245
+ * Fired when a domain or keyword is unblocked site-wide.
246
+ *
247
+ * @param string $value The unblocked domain or keyword.
248
+ * @param string $type The block type (actor, domain, keyword).
249
+ */
250
+ \do_action ( 'activitypub_remove_site_block ' , $ value , $ type );
251
+
189
252
unset( $ blocks [ $ key ] );
190
- return \update_option ( self ::OPTION_KEYS [ $ type ], array_values ( $ blocks ) );
253
+ return \update_option ( self ::OPTION_KEYS [ $ type ], \ array_values ( $ blocks ) );
191
254
}
192
255
break ;
193
256
}
@@ -202,9 +265,9 @@ public static function remove_site_block( $type, $value ) {
202
265
*/
203
266
public static function get_site_blocks () {
204
267
return array (
205
- 'actors ' => array ( ),
206
- 'domains ' => \get_option ( self ::OPTION_KEYS [' domain ' ], array () ),
207
- 'keywords ' => \get_option ( self ::OPTION_KEYS [' keyword ' ], array () ),
268
+ 'actors ' => \wp_list_pluck ( Blocked_Actors:: get_blocked_actors ( Actors:: BLOG_USER_ID ), ' guid ' ),
269
+ 'domains ' => \get_option ( self ::OPTION_KEYS [ self :: TYPE_DOMAIN ], array () ),
270
+ 'keywords ' => \get_option ( self ::OPTION_KEYS [ self :: TYPE_KEYWORD ], array () ),
208
271
);
209
272
}
210
273
@@ -224,8 +287,18 @@ private static function check_activity_against_blocks( $activity, $blocked_actor
224
287
$ actor_id = object_to_uri ( $ activity ->get_actor () );
225
288
226
289
// Check blocked actors.
227
- if ( $ actor_id && \in_array ( $ actor_id , $ blocked_actors , true ) ) {
228
- return true ;
290
+ if ( $ actor_id ) {
291
+ // If actor_id is not a URL, resolve it via webfinger.
292
+ if ( ! \str_starts_with ( $ actor_id , 'http ' ) ) {
293
+ $ resolved_url = Webfinger::resolve ( $ actor_id );
294
+ if ( ! \is_wp_error ( $ resolved_url ) ) {
295
+ $ actor_id = $ resolved_url ;
296
+ }
297
+ }
298
+
299
+ if ( \in_array ( $ actor_id , $ blocked_actors , true ) ) {
300
+ return true ;
301
+ }
229
302
}
230
303
231
304
// Check blocked domains.
0 commit comments