PluginProbe
ActivityPub / 9.0.1
ActivityPub v9.0.1
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / wp-admin / class-settings-fields.php

class-settings-fields.php in ActivityPub 9.0.1, at includes/wp-admin/class-settings-fields.php

682 lines 26.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ActivityPub Settings Fields Class.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\WP_Admin;
9
10 use Activitypub\Blocklist_Subscriptions;
11 use Activitypub\Moderation;
12
13 use function Activitypub\home_host;
14
15 /**
16 * Class Settings_Fields.
17 */
18 class Settings_Fields {
19 /**
20 * Initialize the settings fields.
21 */
22 public static function init() {
23 add_action( 'load-settings_page_activitypub', array( self::class, 'register_settings_fields' ) );
24 }
25
26 /**
27 * Register settings fields.
28 */
29 public static function register_settings_fields() {
30 // Add settings sections.
31 add_settings_section(
32 'activitypub_profiles',
33 __( 'Profiles', 'activitypub' ),
34 '__return_empty_string',
35 'activitypub_settings'
36 );
37
38 add_settings_section(
39 'activitypub_activities',
40 __( 'Activities', 'activitypub' ),
41 '__return_empty_string',
42 'activitypub_settings'
43 );
44
45 add_settings_section(
46 'activitypub_general',
47 __( 'General', 'activitypub' ),
48 '__return_empty_string',
49 'activitypub_settings'
50 );
51
52 add_settings_section(
53 'activitypub_server',
54 __( 'Server', 'activitypub' ),
55 '__return_empty_string',
56 'activitypub_settings'
57 );
58
59 add_settings_section(
60 'activitypub_moderation',
61 \esc_html__( 'Moderation', 'activitypub' ),
62 array( self::class, 'render_moderation_section_description' ),
63 'activitypub_settings',
64 array(
65 'before_section' => '<div id="moderation">',
66 'after_section' => '</div>',
67 )
68 );
69
70 // Add settings fields.
71 add_settings_field(
72 'activitypub_actor_mode',
73 __( 'Enable profiles by type', 'activitypub' ),
74 array( self::class, 'render_actor_mode_field' ),
75 'activitypub_settings',
76 'activitypub_profiles'
77 );
78
79 $object_type = \get_option( 'activitypub_object_type', ACTIVITYPUB_DEFAULT_OBJECT_TYPE );
80 if ( 'note' === $object_type ) {
81 add_settings_field(
82 'activitypub_custom_post_content',
83 __( 'Post content', 'activitypub' ),
84 array( self::class, 'render_custom_post_content_field' ),
85 'activitypub_settings',
86 'activitypub_activities',
87 array( 'label_for' => 'activitypub_custom_post_content' )
88 );
89 }
90
91 add_settings_field(
92 'activitypub_max_image_attachments',
93 __( 'Media attachments', 'activitypub' ),
94 array( self::class, 'render_max_image_attachments_field' ),
95 'activitypub_settings',
96 'activitypub_activities',
97 array( 'label_for' => 'activitypub_max_image_attachments' )
98 );
99
100 add_settings_field(
101 'activitypub_support_post_types',
102 __( 'Supported post types', 'activitypub' ),
103 array( self::class, 'render_support_post_types_field' ),
104 'activitypub_settings',
105 'activitypub_activities'
106 );
107
108 add_settings_field(
109 'activitypub_allow_interactions',
110 __( 'Post interactions', 'activitypub' ),
111 array( self::class, 'render_allow_interactions_field' ),
112 'activitypub_settings',
113 'activitypub_activities'
114 );
115
116 add_settings_field(
117 'activitypub_default_quote_policy',
118 __( 'Default quote policy', 'activitypub' ),
119 array( self::class, 'render_default_quote_policy_field' ),
120 'activitypub_settings',
121 'activitypub_activities',
122 array( 'label_for' => 'activitypub_default_quote_policy' )
123 );
124
125 \add_settings_field(
126 'activitypub_default_feature_policy',
127 \__( 'Default Starter Kit policy', 'activitypub' ),
128 array( self::class, 'render_default_feature_policy_field' ),
129 'activitypub_settings',
130 'activitypub_activities',
131 array( 'label_for' => 'activitypub_default_feature_policy' )
132 );
133
134 add_settings_field(
135 'activitypub_use_hashtags',
136 __( 'Hashtags', 'activitypub' ),
137 array( self::class, 'render_use_hashtags_field' ),
138 'activitypub_settings',
139 'activitypub_activities',
140 array( 'label_for' => 'activitypub_use_hashtags' )
141 );
142
143 add_settings_field(
144 'activitypub_use_opengraph',
145 __( 'OpenGraph', 'activitypub' ),
146 array( self::class, 'render_use_opengraph_field' ),
147 'activitypub_settings',
148 'activitypub_general',
149 array( 'label_for' => 'activitypub_use_opengraph' )
150 );
151
152 add_settings_field(
153 'activitypub_attribution_domains',
154 __( 'Attribution Domains', 'activitypub' ),
155 array( self::class, 'render_attribution_domains_field' ),
156 'activitypub_settings',
157 'activitypub_general',
158 array( 'label_for' => 'activitypub_attribution_domains' )
159 );
160
161 add_settings_field(
162 'activitypub_relays',
163 __( 'Relays', 'activitypub' ),
164 array( self::class, 'render_relays_field' ),
165 'activitypub_settings',
166 'activitypub_server',
167 array( 'label_for' => 'activitypub_relays' )
168 );
169
170 add_settings_field(
171 'activitypub_site_blocked_domains',
172 \esc_html__( 'Blocked Domains', 'activitypub' ),
173 array( self::class, 'render_site_blocked_domains_field' ),
174 'activitypub_settings',
175 'activitypub_moderation'
176 );
177
178 add_settings_field(
179 'activitypub_site_blocked_keywords',
180 \esc_html__( 'Blocked Keywords', 'activitypub' ),
181 array( self::class, 'render_site_blocked_keywords_field' ),
182 'activitypub_settings',
183 'activitypub_moderation'
184 );
185
186 add_settings_field(
187 'activitypub_blocklist_subscriptions',
188 \esc_html__( 'Blocklist Subscriptions', 'activitypub' ),
189 array( self::class, 'render_blocklist_subscriptions_field' ),
190 'activitypub_settings',
191 'activitypub_moderation'
192 );
193 }
194
195 /**
196 * Render actor mode field.
197 */
198 public static function render_actor_mode_field() {
199 $disabled = ( \defined( 'ACTIVITYPUB_SINGLE_USER_MODE' ) && ACTIVITYPUB_SINGLE_USER_MODE ) ||
200 ( \defined( 'ACTIVITYPUB_DISABLE_USER' ) && ACTIVITYPUB_DISABLE_USER ) ||
201 ( \defined( 'ACTIVITYPUB_DISABLE_BLOG_USER' ) && ACTIVITYPUB_DISABLE_BLOG_USER );
202
203 if ( $disabled ) :
204 ?>
205 <p class="description">
206 <?php esc_html_e( 'âš  This setting is defined through server configuration by your blog&#8217;s administrator.', 'activitypub' ); ?>
207 </p>
208 <?php
209 return;
210 endif;
211
212 $value = get_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_MODE );
213 ?>
214 <fieldset class="actor-mode-selection">
215 <div class="row">
216 <input type="radio" id="actor-mode" name="activitypub_actor_mode" value="<?php echo esc_attr( ACTIVITYPUB_ACTOR_MODE ); ?>" <?php checked( ACTIVITYPUB_ACTOR_MODE, $value ); ?> />
217 <div>
218 <label for="actor-mode"><strong><?php esc_html_e( 'Author Profiles Only', 'activitypub' ); ?></strong></label>
219 <p class="description">
220 <?php echo wp_kses( __( 'Every author on this blog (with the <code>activitypub</code> capability) gets their own ActivityPub profile.', 'activitypub' ), array( 'code' => array() ) ); ?>
221 <strong>
222 <?php
223 echo wp_kses(
224 sprintf(
225 // translators: %s is a URL.
226 __( 'You can add/remove the capability in the <a href="%s">user settings.</a>', 'activitypub' ),
227 admin_url( '/users.php' )
228 ),
229 array( 'a' => array( 'href' => array() ) )
230 );
231 ?>
232 </strong>
233 <?php echo wp_kses( __( 'Select all the users you want to update, choose the method from the drop-down list and click on the "Apply" button.', 'activitypub' ), array( 'code' => array() ) ); ?>
234 </p>
235 </div>
236 </div>
237 <div class="row">
238 <input type="radio" id="blog-mode" name="activitypub_actor_mode" value="<?php echo esc_attr( ACTIVITYPUB_BLOG_MODE ); ?>" <?php checked( ACTIVITYPUB_BLOG_MODE, $value ); ?> />
239 <div>
240 <label for="blog-mode"><strong><?php esc_html_e( 'Blog profile only', 'activitypub' ); ?></strong></label>
241 <p class="description">
242 <?php esc_html_e( 'Your blog becomes a single ActivityPub profile and every post will be published under this profile instead of the individual author profiles.', 'activitypub' ); ?>
243 </p>
244 </div>
245 </div>
246 <div class="row">
247 <input type="radio" id="actor-blog-mode" name="activitypub_actor_mode" value="<?php echo esc_attr( ACTIVITYPUB_ACTOR_AND_BLOG_MODE ); ?>" <?php checked( ACTIVITYPUB_ACTOR_AND_BLOG_MODE, $value ); ?> />
248 <div>
249 <label for="actor-blog-mode"><strong><?php esc_html_e( 'Both author and blog profiles', 'activitypub' ); ?></strong></label>
250 <p class="description">
251 <?php esc_html_e( "This combines both modes. Users can be followed individually, while following the blog will show boosts of individual user's posts.", 'activitypub' ); ?>
252 </p>
253 </div>
254 </div>
255 </fieldset>
256 <?php
257 }
258
259 /**
260 * Render custom post content field.
261 */
262 public static function render_custom_post_content_field() {
263 $switch_url = \wp_nonce_url(
264 \add_query_arg(
265 array(
266 'page' => 'activitypub',
267 'tab' => 'settings',
268 'activitypub_update_object_type' => '1',
269 ),
270 \admin_url( 'options-general.php' )
271 ),
272 'activitypub_switch_object_type'
273 );
274 ?>
275 <p class="description">
276 <?php \esc_html_e( 'âš  You are using the legacy template system to format your posts for the fediverse. We recommend switching to automatic mode, which intelligently chooses the best format for each post. Switching will remove this template field from the settings.', 'activitypub' ); ?>
277 </p>
278 <p>
279 <a href="<?php echo \esc_url( $switch_url ); ?>" class="button">
280 <?php \esc_html_e( 'Switch to Automatic Mode', 'activitypub' ); ?>
281 </a>
282 </p>
283 <?php
284 $value = get_option( 'activitypub_custom_post_content', ACTIVITYPUB_CUSTOM_POST_CONTENT );
285 ?>
286 <p>
287 <textarea id="activitypub_custom_post_content" name="activitypub_custom_post_content" rows="10" cols="50" class="large-text" placeholder="<?php echo esc_attr( ACTIVITYPUB_CUSTOM_POST_CONTENT ); ?>"><?php echo esc_textarea( wp_kses( $value, 'post' ) ); ?></textarea>
288 <details>
289 <summary><?php esc_html_e( 'See a list of ActivityPub Template Tags.', 'activitypub' ); ?></summary>
290 <div class="description">
291 <ul>
292 <li><code>[ap_title]</code> - <?php esc_html_e( 'The post&#8217;s title.', 'activitypub' ); ?></li>
293 <li><code>[ap_content]</code> - <?php esc_html_e( 'The post&#8217;s content.', 'activitypub' ); ?></li>
294 <li><code>[ap_excerpt]</code> - <?php esc_html_e( 'The post&#8217;s excerpt (may be truncated).', 'activitypub' ); ?></li>
295 <li><code>[ap_permalink]</code> - <?php esc_html_e( 'The post&#8217;s permalink.', 'activitypub' ); ?></li>
296 <li><code>[ap_shortlink]</code> - <?php echo wp_kses( __( 'The post&#8217;s shortlink. I can recommend <a href="https://wordpress.org/plugins/hum/" target="_blank">Hum</a>.', 'activitypub' ), 'default' ); ?></li>
297 <li><code>[ap_hashtags]</code> - <?php esc_html_e( 'The post&#8217;s tags as hashtags.', 'activitypub' ); ?></li>
298 </ul>
299 <p><?php esc_html_e( 'You can find the full list with all possible attributes in the help section on the top-right of the screen.', 'activitypub' ); ?></p>
300 </div>
301 </details>
302 </p>
303 <?php
304 }
305
306 /**
307 * Render max image attachments field.
308 */
309 public static function render_max_image_attachments_field() {
310 $value = get_option( 'activitypub_max_image_attachments', ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS );
311 ?>
312 <input id="activitypub_max_image_attachments" value="<?php echo esc_attr( $value ); ?>" name="activitypub_max_image_attachments" type="number" min="0" max="10" class="small-text" />
313 <p class="description">
314 <?php
315 echo wp_kses(
316 sprintf(
317 // translators: %s is a number.
318 __( 'The number of media (images, audio, video) to attach to posts. Default: <code>%s</code>', 'activitypub' ),
319 esc_html( ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS )
320 ),
321 'default'
322 );
323 ?>
324 </p>
325 <p class="description">
326 <em>
327 <?php esc_html_e( 'Note: audio and video attachments are only supported from Block Editor.', 'activitypub' ); ?>
328 </em>
329 </p>
330 <?php
331 }
332
333 /**
334 * Render support post types field.
335 */
336 public static function render_support_post_types_field() {
337 $post_types = \get_post_types( array( 'public' => true ), 'objects' );
338 $supported_post_types = \get_option( 'activitypub_support_post_types', array( 'post' ) );
339 ?>
340 <fieldset>
341 <?php esc_html_e( 'Automatically publish items of the selected post types to the fediverse:', 'activitypub' ); ?>
342 <ul>
343 <?php foreach ( $post_types as $post_type ) : ?>
344 <li>
345 <input type="checkbox" id="activitypub_support_post_type_<?php echo esc_attr( $post_type->name ); ?>" name="activitypub_support_post_types[]" value="<?php echo esc_attr( $post_type->name ); ?>" <?php checked( in_array( $post_type->name, $supported_post_types, true ) ); ?> />
346 <label for="activitypub_support_post_type_<?php echo esc_attr( $post_type->name ); ?>"><?php echo esc_html( $post_type->label ); ?></label>
347 <span class="description">
348 <?php echo esc_html( \Activitypub\get_post_type_description( $post_type ) ); ?>
349 </span>
350 </li>
351 <?php endforeach; ?>
352 </ul>
353 </fieldset>
354 <?php
355 }
356
357 /**
358 * Render allow interactions field.
359 */
360 public static function render_allow_interactions_field() {
361 if ( defined( 'ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS' ) && ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS ) {
362 echo '<p class="description">' . \esc_html__( 'âš  This setting is defined through server configuration by your blog&#8217;s administrator.', 'activitypub' ) . '</p>';
363 return;
364 }
365
366 $allow_likes = get_option( 'activitypub_allow_likes', '1' );
367 $allow_reposts = get_option( 'activitypub_allow_reposts', '1' );
368 $auto_approve = get_option( 'activitypub_auto_approve_reactions', '0' );
369 ?>
370 <fieldset>
371 <p>
372 <label>
373 <input type="checkbox" name="activitypub_allow_likes" value="1" <?php checked( '1', $allow_likes ); ?> />
374 <?php esc_html_e( 'Receive likes', 'activitypub' ); ?>
375 </label>
376 </p>
377 <p>
378 <label>
379 <input type="checkbox" name="activitypub_allow_reposts" value="1" <?php checked( '1', $allow_reposts ); ?> />
380 <?php esc_html_e( 'Receive reblogs (boosts)', 'activitypub' ); ?>
381 </label>
382 </p>
383 <p class="interactions description"><?php esc_html_e( 'Types of interactions from the Fediverse your blog should accept.', 'activitypub' ); ?></p>
384 <p>
385 <label>
386 <input type="checkbox" name="activitypub_auto_approve_reactions" value="1" <?php checked( '1', $auto_approve ); ?> />
387 <?php esc_html_e( 'Auto approve reactions', 'activitypub' ); ?>
388 </label>
389 </p>
390 </fieldset>
391 <?php
392 }
393
394 /**
395 * Render default quote policy field.
396 */
397 public static function render_default_quote_policy_field() {
398 $value = get_option( 'activitypub_default_quote_policy', ACTIVITYPUB_INTERACTION_POLICY_ANYONE );
399 ?>
400 <select id="activitypub_default_quote_policy" name="activitypub_default_quote_policy" class="regular-text">
401 <option value="<?php echo esc_attr( ACTIVITYPUB_INTERACTION_POLICY_ANYONE ); ?>" <?php selected( $value, ACTIVITYPUB_INTERACTION_POLICY_ANYONE ); ?>><?php esc_html_e( 'Anyone', 'activitypub' ); ?></option>
402 <option value="<?php echo esc_attr( ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS ); ?>" <?php selected( $value, ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS ); ?>><?php esc_html_e( 'Followers only', 'activitypub' ); ?></option>
403 <option value="<?php echo esc_attr( ACTIVITYPUB_INTERACTION_POLICY_ME ); ?>" <?php selected( $value, ACTIVITYPUB_INTERACTION_POLICY_ME ); ?>><?php esc_html_e( 'Just me', 'activitypub' ); ?></option>
404 </select>
405 <p class="description">
406 <?php esc_html_e( 'Default setting for who can quote new posts. This can be overridden per post.', 'activitypub' ); ?>
407 </p>
408 <?php
409 }
410
411 /**
412 * Render default feature policy field.
413 */
414 public static function render_default_feature_policy_field() {
415 $value = \get_option( 'activitypub_default_feature_policy', ACTIVITYPUB_INTERACTION_POLICY_ME );
416 ?>
417 <select id="activitypub_default_feature_policy" name="activitypub_default_feature_policy" class="regular-text">
418 <option value="<?php echo \esc_attr( ACTIVITYPUB_INTERACTION_POLICY_ANYONE ); ?>" <?php \selected( $value, ACTIVITYPUB_INTERACTION_POLICY_ANYONE ); ?>><?php \esc_html_e( 'Anyone', 'activitypub' ); ?></option>
419 <option value="<?php echo \esc_attr( ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS ); ?>" <?php \selected( $value, ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS ); ?>><?php \esc_html_e( 'Followers only', 'activitypub' ); ?></option>
420 <option value="<?php echo \esc_attr( ACTIVITYPUB_INTERACTION_POLICY_ME ); ?>" <?php \selected( $value, ACTIVITYPUB_INTERACTION_POLICY_ME ); ?>><?php \esc_html_e( 'Just me', 'activitypub' ); ?></option>
421 </select>
422 <p class="description">
423 <?php \esc_html_e( 'Default setting for who can include this site\'s actors in a Starter Kit (also called a Starter Pack or Featured Collection).', 'activitypub' ); ?>
424 </p>
425 <?php
426 }
427
428 /**
429 * Render use hashtags field.
430 */
431 public static function render_use_hashtags_field() {
432 $value = get_option( 'activitypub_use_hashtags', '0' );
433 ?>
434 <p>
435 <label>
436 <input type="checkbox" id="activitypub_use_hashtags" name="activitypub_use_hashtags" value="1" <?php checked( '1', $value ); ?> />
437 <?php echo wp_kses( __( 'Add hashtags in the content as native tags and replace the <code>#tag</code> with the tag link.', 'activitypub' ), 'default' ); ?>
438 </label>
439 </p>
440 <?php
441 }
442
443 /**
444 * Render use OpenGraph field.
445 */
446 public static function render_use_opengraph_field() {
447 $value = get_option( 'activitypub_use_opengraph', '1' );
448 ?>
449 <p>
450 <label>
451 <input type="checkbox" id="activitypub_use_opengraph" name="activitypub_use_opengraph" value="1" <?php checked( '1', $value ); ?> />
452 <?php echo wp_kses( __( 'Automatically add <code>&lt;meta name="fediverse:creator" /&gt;</code> tags for Authors and the Blog-User. You can read more about the feature on the <a href="https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/" target="_blank">Mastodon Blog</a>.', 'activitypub' ), 'post' ); ?>
453 </label>
454 </p>
455 <?php
456 }
457
458 /**
459 * Render attribution domains field.
460 */
461 public static function render_attribution_domains_field() {
462 $value = get_option( 'activitypub_attribution_domains', home_host() );
463 ?>
464 <textarea
465 id="activitypub_attribution_domains"
466 name="activitypub_attribution_domains"
467 class="large-text"
468 cols="50" rows="5"
469 placeholder="<?php echo esc_attr( home_host() ); ?>"
470 ><?php echo esc_textarea( $value ); ?></textarea>
471 <p class="description"><?php esc_html_e( 'Websites allowed to credit you, one per line. Protects from false attributions.', 'activitypub' ); ?></p>
472 <?php
473 }
474
475 /**
476 * Render relays field.
477 */
478 public static function render_relays_field() {
479 $value = \get_option( 'activitypub_relays', array() );
480 ?>
481 <textarea
482 id="activitypub_relays"
483 name="activitypub_relays"
484 class="large-text"
485 cols="50"
486 rows="5"
487 ><?php echo \esc_textarea( implode( PHP_EOL, $value ) ); ?></textarea>
488 <p class="description">
489 <?php echo \wp_kses( \__( 'A <strong>Fediverse-Relay</strong> distributes content across instances, expanding reach, engagement, and discoverability, especially for smaller instances.', 'activitypub' ), 'default' ); ?>
490 </p>
491 <p class="description">
492 <?php
493 echo \wp_kses(
494 \__( 'Enter the <strong>Inbox-URLs</strong> (e.g. <code>https://relay.example.com/inbox</code>) of the relays you want to use, one per line.', 'activitypub' ),
495 array(
496 'strong' => array(),
497 'code' => array(),
498 )
499 );
500 ?>
501 <?php echo \wp_kses( \__( 'You can find a list of public relays on <a href="https://relaylist.com/" target="_blank">relaylist.com</a> or on <a href="https://fedidb.org/software/activity-relay" target="_blank">FediDB</a>.', 'activitypub' ), 'default' ); ?>
502 </p>
503 <?php
504 }
505
506 /**
507 * Render moderation section description.
508 */
509 public static function render_moderation_section_description() {
510 echo '<p>' . \esc_html__( 'Configure site-wide moderation settings. These blocks will affect all users and ActivityPub content on your site.', 'activitypub' ) . '</p>';
511 }
512
513 /**
514 * Render site blocked domains field.
515 */
516 public static function render_site_blocked_domains_field() {
517 $blocked_domains = Moderation::get_site_blocks()['domains'];
518 $count = \count( $blocked_domains );
519 ?>
520 <p class="description"><?php \esc_html_e( 'Block entire ActivityPub instances by domain name.', 'activitypub' ); ?></p>
521
522 <div class="activitypub-site-block-list">
523 <details class="activitypub-site-block-details" data-type="domain"<?php echo empty( $blocked_domains ) ? ' open' : ''; ?>>
524 <summary>
525 <?php if ( $count > 0 ) : ?>
526 <?php
527 echo \esc_html(
528 \sprintf(
529 /* translators: %s: Number of blocked domains */
530 \_n( '%s blocked domain', '%s blocked domains', $count, 'activitypub' ),
531 \number_format_i18n( $count )
532 )
533 );
534 ?>
535 <?php else : ?>
536 <?php \esc_html_e( 'No blocked domains', 'activitypub' ); ?>
537 <?php endif; ?>
538 </summary>
539 <?php if ( ! empty( $blocked_domains ) ) : ?>
540 <table class="widefat striped activitypub-site-blocked-domain" role="presentation">
541 <tbody>
542 <?php foreach ( $blocked_domains as $domain ) : ?>
543 <tr>
544 <td><?php echo \esc_html( $domain ); ?></td>
545 <td>
546 <button type="button" class="button button-small remove-site-block-btn" data-type="domain" data-value="<?php echo \esc_attr( $domain ); ?>">
547 <?php \esc_html_e( 'Remove', 'activitypub' ); ?>
548 </button>
549 </td>
550 </tr>
551 <?php endforeach; ?>
552 </tbody>
553 </table>
554 <?php endif; ?>
555 </details>
556
557 <div class="add-site-block-form" style="display: flex; max-width: 500px; gap: 8px;">
558 <input type="text" class="regular-text" id="new_site_domain" placeholder="<?php \esc_attr_e( 'example.com', 'activitypub' ); ?>" style="flex: 1; min-width: 0;" />
559 <button type="button" class="button add-site-block-btn" data-type="domain" style="flex-shrink: 0; white-space: nowrap;">
560 <?php \esc_html_e( 'Add Block', 'activitypub' ); ?>
561 </button>
562 </div>
563 </div>
564 <?php
565 }
566
567 /**
568 * Render site blocked keywords field.
569 */
570 public static function render_site_blocked_keywords_field() {
571 $blocked_keywords = Moderation::get_site_blocks()['keywords'];
572 $count = \count( $blocked_keywords );
573 ?>
574 <p class="description"><?php \esc_html_e( 'Block ActivityPub content containing specific keywords.', 'activitypub' ); ?></p>
575
576 <div class="activitypub-site-block-list">
577 <details class="activitypub-site-block-details" data-type="keyword"<?php echo empty( $blocked_keywords ) ? ' open' : ''; ?>>
578 <summary>
579 <?php if ( $count > 0 ) : ?>
580 <?php
581 echo \esc_html(
582 \sprintf(
583 /* translators: %s: Number of blocked keywords */
584 \_n( '%s blocked keyword', '%s blocked keywords', $count, 'activitypub' ),
585 \number_format_i18n( $count )
586 )
587 );
588 ?>
589 <?php else : ?>
590 <?php \esc_html_e( 'No blocked keywords', 'activitypub' ); ?>
591 <?php endif; ?>
592 </summary>
593 <?php if ( ! empty( $blocked_keywords ) ) : ?>
594 <table class="widefat striped activitypub-site-blocked-keyword" role="presentation">
595 <tbody>
596 <?php foreach ( $blocked_keywords as $keyword ) : ?>
597 <tr>
598 <td><?php echo \esc_html( $keyword ); ?></td>
599 <td>
600 <button type="button" class="button button-small remove-site-block-btn" data-type="keyword" data-value="<?php echo \esc_attr( $keyword ); ?>">
601 <?php \esc_html_e( 'Remove', 'activitypub' ); ?>
602 </button>
603 </td>
604 </tr>
605 <?php endforeach; ?>
606 </tbody>
607 </table>
608 <?php endif; ?>
609 </details>
610
611 <div class="add-site-block-form" style="display: flex; max-width: 500px; gap: 8px;">
612 <input type="text" class="regular-text" id="new_site_keyword" placeholder="<?php \esc_attr_e( 'spam keyword', 'activitypub' ); ?>" style="flex: 1; min-width: 0;" />
613 <button type="button" class="button add-site-block-btn" data-type="keyword" style="flex-shrink: 0; white-space: nowrap;">
614 <?php \esc_html_e( 'Add Block', 'activitypub' ); ?>
615 </button>
616 </div>
617 </div>
618 <?php
619 }
620
621 /**
622 * Render blocklist subscriptions field.
623 */
624 public static function render_blocklist_subscriptions_field() {
625 $subscriptions = Blocklist_Subscriptions::get_all();
626 ?>
627 <p class="description"><?php \esc_html_e( 'Subscribe to remote blocklists that sync automatically every week.', 'activitypub' ); ?></p>
628
629 <div class="activitypub-blocklist-subscriptions">
630 <?php if ( ! empty( $subscriptions ) ) : ?>
631 <table class="widefat striped" role="presentation" style="max-width: 500px; margin: 15px 0;">
632 <thead>
633 <tr>
634 <th style="padding: 10px;"><?php \esc_html_e( 'URL', 'activitypub' ); ?></th>
635 <th style="padding: 10px;"><?php \esc_html_e( 'Last Synced', 'activitypub' ); ?></th>
636 <th style="width: 80px;"></th>
637 </tr>
638 </thead>
639 <tbody>
640 <?php foreach ( $subscriptions as $url => $timestamp ) : ?>
641 <tr>
642 <td>
643 <abbr title="<?php echo \esc_attr( $url ); ?>"><?php echo \esc_html( \wp_parse_url( $url, PHP_URL_HOST ) ); ?></abbr>
644 </td>
645 <td>
646 <?php if ( $timestamp > 0 ) : ?>
647 <?php echo \esc_html( \human_time_diff( $timestamp, \time() ) . ' ' . \__( 'ago', 'activitypub' ) ); ?>
648 <?php else : ?>
649 <em><?php \esc_html_e( 'Never', 'activitypub' ); ?></em>
650 <?php endif; ?>
651 </td>
652 <td>
653 <button type="button" class="button button-small remove-blocklist-subscription-btn" data-url="<?php echo \esc_attr( $url ); ?>">
654 <?php \esc_html_e( 'Remove', 'activitypub' ); ?>
655 </button>
656 </td>
657 </tr>
658 <?php endforeach; ?>
659 </tbody>
660 </table>
661 <?php endif; ?>
662
663 <div class="add-blocklist-subscription-form" style="display: flex; max-width: 500px; gap: 8px;">
664 <input type="url" class="regular-text" id="new_blocklist_subscription_url" placeholder="<?php \esc_attr_e( 'https://example.com/blocklist.csv', 'activitypub' ); ?>" style="flex: 1; min-width: 0;" />
665 <button type="button" class="button add-blocklist-subscription-btn" style="flex-shrink: 0; white-space: nowrap;">
666 <?php \esc_html_e( 'Subscribe', 'activitypub' ); ?>
667 </button>
668 </div>
669
670 <?php if ( ! isset( $subscriptions[ Blocklist_Subscriptions::IFTAS_DNI_URL ] ) ) : ?>
671 <p class="description" style="margin-top: 10px;">
672 <button type="button" class="button add-blocklist-subscription-btn" data-url="<?php echo \esc_attr( Blocklist_Subscriptions::IFTAS_DNI_URL ); ?>">
673 <?php \esc_html_e( 'Subscribe to IFTAS DNI List', 'activitypub' ); ?>
674 </button>
675 <?php echo \wp_kses_post( \__( 'Domains <a href="https://about.iftas.org/" target="_blank" rel="noopener">IFTAS</a> recommends not federating with.', 'activitypub' ) ); ?>
676 </p>
677 <?php endif; ?>
678 </div>
679 <?php
680 }
681 }
682