PluginProbe
ActivityPub / 9.3.0
ActivityPub v9.3.0
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.3.0, at includes/wp-admin/class-settings-fields.php

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