PluginProbe
ActivityPub / 4.2.1
ActivityPub v4.2.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 / class-admin.php

class-admin.php in ActivityPub 4.2.1, at includes/class-admin.php

798 lines 22.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Admin Class.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub;
9
10 use WP_User_Query;
11 use Activitypub\Model\Blog;
12 use Activitypub\Collection\Actors;
13 use Activitypub\Collection\Extra_Fields;
14
15 /**
16 * ActivityPub Admin Class.
17 *
18 * @author Matthias Pfefferle
19 */
20 class Admin {
21 /**
22 * Initialize the class, registering WordPress hooks,
23 */
24 public static function init() {
25 \add_action( 'admin_menu', array( self::class, 'admin_menu' ) );
26 \add_action( 'admin_init', array( self::class, 'register_settings' ) );
27 \add_action( 'load-comment.php', array( self::class, 'edit_comment' ) );
28 \add_action( 'load-post.php', array( self::class, 'edit_post' ) );
29 \add_action( 'load-edit.php', array( self::class, 'list_posts' ) );
30 \add_action( 'personal_options_update', array( self::class, 'save_user_settings' ) );
31 \add_action( 'admin_enqueue_scripts', array( self::class, 'enqueue_scripts' ) );
32 \add_action( 'admin_notices', array( self::class, 'admin_notices' ) );
33
34 \add_filter( 'comment_row_actions', array( self::class, 'comment_row_actions' ), 10, 2 );
35 \add_filter( 'manage_edit-comments_columns', array( static::class, 'manage_comment_columns' ) );
36 \add_action( 'manage_comments_custom_column', array( static::class, 'manage_comments_custom_column' ), 9, 2 );
37
38 \add_filter( 'manage_posts_columns', array( static::class, 'manage_post_columns' ), 10, 2 );
39 \add_action( 'manage_posts_custom_column', array( self::class, 'manage_posts_custom_column' ), 10, 2 );
40
41 \add_filter( 'manage_users_columns', array( self::class, 'manage_users_columns' ) );
42 \add_action( 'manage_users_custom_column', array( self::class, 'manage_users_custom_column' ), 10, 3 );
43 \add_filter( 'bulk_actions-users', array( self::class, 'user_bulk_options' ) );
44 \add_filter( 'handle_bulk_actions-users', array( self::class, 'handle_bulk_request' ), 10, 3 );
45
46 if ( ! is_user_disabled( get_current_user_id() ) ) {
47 \add_action( 'show_user_profile', array( self::class, 'add_profile' ) );
48 }
49
50 \add_filter( 'dashboard_glance_items', array( self::class, 'dashboard_glance_items' ) );
51 }
52
53 /**
54 * Add admin menu entry.
55 */
56 public static function admin_menu() {
57 $settings_page = \add_options_page(
58 'Welcome',
59 'ActivityPub',
60 'manage_options',
61 'activitypub',
62 array( self::class, 'settings_page' )
63 );
64
65 \add_action(
66 'load-' . $settings_page,
67 array( self::class, 'add_settings_help_tab' )
68 );
69
70 // User has to be able to publish posts.
71 if ( ! is_user_disabled( get_current_user_id() ) ) {
72 $followers_list_page = \add_users_page(
73 \__( '⁂ Followers', 'activitypub' ),
74 \__( '⁂ Followers', 'activitypub' ),
75 'activitypub',
76 'activitypub-followers-list',
77 array(
78 self::class,
79 'followers_list_page',
80 )
81 );
82
83 \add_action(
84 'load-' . $followers_list_page,
85 array( self::class, 'add_followers_list_help_tab' )
86 );
87
88 \add_users_page(
89 \__( '⁂ Extra Fields', 'activitypub' ),
90 \__( '⁂ Extra Fields', 'activitypub' ),
91 'activitypub',
92 \esc_url( \admin_url( '/edit.php?post_type=ap_extrafield' ) )
93 );
94 }
95 }
96
97 /**
98 * Display admin menu notices about configuration problems or conflicts.
99 */
100 public static function admin_notices() {
101 $permalink_structure = \get_option( 'permalink_structure' );
102 if ( empty( $permalink_structure ) ) {
103 $admin_notice = sprintf(
104 /* translators: %s: Permalink settings URL. */
105 \__( 'ActivityPub needs SEO-friendly URLs to work properly. Please <a href="%s">update your permalink structure</a> to an option other than Plain.', 'activitypub' ),
106 esc_url( admin_url( 'options-permalink.php' ) )
107 );
108 self::show_admin_notice( $admin_notice, 'error' );
109 }
110
111 $current_screen = get_current_screen();
112 if ( ! $current_screen ) {
113 return;
114 }
115 if ( 'edit' === $current_screen->base && Extra_Fields::is_extra_fields_post_type( $current_screen->post_type ) ) {
116 ?>
117 <div class="notice" style="margin: 0; background: none; border: none; box-shadow: none; padding: 15px 0 0 0; font-size: 14px;">
118 <?php
119 esc_html_e( 'These are extra fields that are used for your ActivityPub profile. You can use your homepage, social profiles, pronouns, age, anything you want.', 'activitypub' );
120 ?>
121 </div>
122 <?php
123 }
124 }
125
126 /**
127 * Display one admin menu notice about configuration problems or conflicts.
128 *
129 * @param string $admin_notice The notice to display.
130 * @param string $level The level of the notice (error, warning, success, info).
131 */
132 private static function show_admin_notice( $admin_notice, $level ) {
133 ?>
134
135 <div class="notice notice-<?php echo esc_attr( $level ); ?>">
136 <p><?php echo wp_kses( $admin_notice, 'data' ); ?></p>
137 </div>
138
139 <?php
140 }
141
142 /**
143 * Load settings page.
144 */
145 public static function settings_page() {
146 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
147 if ( empty( $_GET['tab'] ) ) {
148 $tab = 'welcome';
149 } else {
150 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
151 $tab = sanitize_key( $_GET['tab'] );
152 }
153
154 switch ( $tab ) {
155 case 'settings':
156 \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/settings.php' );
157 break;
158 case 'blog-profile':
159 wp_enqueue_media();
160 wp_enqueue_script( 'activitypub-header-image' );
161
162 \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/blog-settings.php' );
163 break;
164 case 'followers':
165 \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/blog-followers-list.php' );
166 break;
167 case 'welcome':
168 default:
169 wp_enqueue_script( 'plugin-install' );
170 add_thickbox();
171 wp_enqueue_script( 'updates' );
172
173 \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/welcome.php' );
174 break;
175 }
176 }
177
178 /**
179 * Load user settings page
180 */
181 public static function followers_list_page() {
182 // User has to be able to publish posts.
183 if ( ! is_user_disabled( get_current_user_id() ) ) {
184 \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/user-followers-list.php' );
185 }
186 }
187
188 /**
189 * Register ActivityPub settings
190 */
191 public static function register_settings() {
192 \register_setting(
193 'activitypub',
194 'activitypub_post_content_type',
195 array(
196 'type' => 'string',
197 'description' => \__( 'Use title and link, summary, full or custom content', 'activitypub' ),
198 'show_in_rest' => array(
199 'schema' => array(
200 'enum' => array(
201 'title',
202 'excerpt',
203 'content',
204 ),
205 ),
206 ),
207 'default' => 'content',
208 )
209 );
210 \register_setting(
211 'activitypub',
212 'activitypub_custom_post_content',
213 array(
214 'type' => 'string',
215 'description' => \__( 'Define your own custom post template', 'activitypub' ),
216 'show_in_rest' => true,
217 'default' => ACTIVITYPUB_CUSTOM_POST_CONTENT,
218 )
219 );
220 \register_setting(
221 'activitypub',
222 'activitypub_max_image_attachments',
223 array(
224 'type' => 'integer',
225 'description' => \__( 'Number of images to attach to posts.', 'activitypub' ),
226 'default' => ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS,
227 )
228 );
229 \register_setting(
230 'activitypub',
231 'activitypub_object_type',
232 array(
233 'type' => 'string',
234 'description' => \__( 'The Activity-Object-Type', 'activitypub' ),
235 'show_in_rest' => array(
236 'schema' => array(
237 'enum' => array(
238 'note',
239 'wordpress-post-format',
240 ),
241 ),
242 ),
243 'default' => ACTIVITYPUB_DEFAULT_OBJECT_TYPE,
244 )
245 );
246 \register_setting(
247 'activitypub',
248 'activitypub_use_hashtags',
249 array(
250 'type' => 'boolean',
251 'description' => \__( 'Add hashtags in the content as native tags and replace the #tag with the tag-link', 'activitypub' ),
252 'default' => '0',
253 )
254 );
255 \register_setting(
256 'activitypub',
257 'activitypub_use_opengraph',
258 array(
259 'type' => 'boolean',
260 'description' => \__( 'Automatically add "fediverse:creator" OpenGraph tags for Authors and the Blog-User.', 'activitypub' ),
261 'default' => '1',
262 )
263 );
264 \register_setting(
265 'activitypub',
266 'activitypub_support_post_types',
267 array(
268 'type' => 'string',
269 'description' => \esc_html__( 'Enable ActivityPub support for post types', 'activitypub' ),
270 'show_in_rest' => true,
271 'default' => array( 'post' ),
272 )
273 );
274 \register_setting(
275 'activitypub',
276 'activitypub_actor_mode',
277 array(
278 'type' => 'integer',
279 'description' => \__( 'Choose your preferred Actor-Mode.', 'activitypub' ),
280 'default' => ACTIVITYPUB_ACTOR_MODE,
281 )
282 );
283
284 \register_setting(
285 'activitypub',
286 'activitypub_attribution_domains',
287 array(
288 'type' => 'string',
289 'description' => \__( 'Websites allowed to credit you.', 'activitypub' ),
290 'default' => home_host(),
291 'sanitize_callback' => function ( $value ) {
292 $value = explode( PHP_EOL, $value );
293 $value = array_filter( array_map( 'trim', $value ) );
294 $value = array_filter( array_map( 'esc_attr', $value ) );
295 $value = implode( PHP_EOL, $value );
296
297 return $value;
298 },
299 )
300 );
301
302 // Blog-User Settings.
303 \register_setting(
304 'activitypub_blog',
305 'activitypub_blog_description',
306 array(
307 'type' => 'string',
308 'description' => \esc_html__( 'The Description of the Blog-User', 'activitypub' ),
309 'show_in_rest' => true,
310 'default' => '',
311 )
312 );
313 \register_setting(
314 'activitypub_blog',
315 'activitypub_blog_identifier',
316 array(
317 'type' => 'string',
318 'description' => \esc_html__( 'The Identifier of the Blog-User', 'activitypub' ),
319 'show_in_rest' => true,
320 'default' => Blog::get_default_username(),
321 'sanitize_callback' => function ( $value ) {
322 // Hack to allow dots in the username.
323 $parts = explode( '.', $value );
324 $sanitized = array();
325
326 foreach ( $parts as $part ) {
327 $sanitized[] = \sanitize_title( $part );
328 }
329
330 $sanitized = implode( '.', $sanitized );
331
332 // Check for login or nicename.
333 $user = new WP_User_Query(
334 array(
335 'search' => $sanitized,
336 'search_columns' => array( 'user_login', 'user_nicename' ),
337 'number' => 1,
338 'hide_empty' => true,
339 'fields' => 'ID',
340 )
341 );
342
343 if ( $user->results ) {
344 add_settings_error(
345 'activitypub_blog_identifier',
346 'activitypub_blog_identifier',
347 \esc_html__( 'You cannot use an existing author\'s name for the blog profile ID.', 'activitypub' ),
348 'error'
349 );
350
351 return Blog::get_default_username();
352 }
353
354 return $sanitized;
355 },
356 )
357 );
358 \register_setting(
359 'activitypub_blog',
360 'activitypub_header_image',
361 array(
362 'type' => 'integer',
363 'description' => \__( 'The Attachment-ID of the Sites Header-Image', 'activitypub' ),
364 'default' => null,
365 )
366 );
367 }
368
369 /**
370 * Adds the ActivityPub settings to the Help tab.
371 */
372 public static function add_settings_help_tab() {
373 require_once ACTIVITYPUB_PLUGIN_DIR . 'includes/help.php';
374 }
375
376 /**
377 * Adds the follower list to the Help tab.
378 */
379 public static function add_followers_list_help_tab() {
380 // todo.
381 }
382
383 /**
384 * Add the profile.
385 *
386 * @param \WP_User $user The user object.
387 */
388 public static function add_profile( $user ) {
389 $description = \get_user_option( 'activitypub_description', $user->ID );
390
391 wp_enqueue_media();
392 wp_enqueue_script( 'activitypub-header-image' );
393
394 \load_template(
395 ACTIVITYPUB_PLUGIN_DIR . 'templates/user-settings.php',
396 true,
397 array(
398 'description' => $description,
399 )
400 );
401 }
402
403 /**
404 * Save the user settings.
405 *
406 * Handles the saving of the ActivityPub settings.
407 *
408 * @param int $user_id The user ID.
409 */
410 public static function save_user_settings( $user_id ) {
411 if ( ! isset( $_REQUEST['_apnonce'] ) ) {
412 return;
413 }
414
415 $nonce = sanitize_text_field( wp_unslash( $_REQUEST['_apnonce'] ) );
416 if (
417 ! wp_verify_nonce( $nonce, 'activitypub-user-settings' ) ||
418 ! current_user_can( 'edit_user', $user_id )
419 ) {
420 return;
421 }
422
423 $description = ! empty( $_POST['activitypub_description'] ) ? sanitize_textarea_field( wp_unslash( $_POST['activitypub_description'] ) ) : false;
424 if ( $description ) {
425 \update_user_option( $user_id, 'activitypub_description', $description );
426 } else {
427 \delete_user_option( $user_id, 'activitypub_description' );
428 }
429
430 $header_image = ! empty( $_POST['activitypub_header_image'] ) ? sanitize_text_field( wp_unslash( $_POST['activitypub_header_image'] ) ) : false;
431 if ( $header_image && \wp_attachment_is_image( $header_image ) ) {
432 \update_user_option( $user_id, 'activitypub_header_image', $header_image );
433 } else {
434 \delete_user_option( $user_id, 'activitypub_header_image' );
435 }
436 }
437
438 /**
439 * Enqueue the admin scripts and styles.
440 *
441 * @param string $hook_suffix The current page.
442 */
443 public static function enqueue_scripts( $hook_suffix ) {
444 wp_register_script(
445 'activitypub-header-image',
446 plugins_url(
447 'assets/js/activitypub-header-image.js',
448 ACTIVITYPUB_PLUGIN_FILE
449 ),
450 array( 'jquery' ),
451 ACTIVITYPUB_PLUGIN_VERSION,
452 false
453 );
454
455 if ( false !== strpos( $hook_suffix, 'activitypub' ) ) {
456 wp_enqueue_style(
457 'activitypub-admin-styles',
458 plugins_url(
459 'assets/css/activitypub-admin.css',
460 ACTIVITYPUB_PLUGIN_FILE
461 ),
462 array(),
463 ACTIVITYPUB_PLUGIN_VERSION
464 );
465 wp_enqueue_script(
466 'activitypub-admin-script',
467 plugins_url(
468 'assets/js/activitypub-admin.js',
469 ACTIVITYPUB_PLUGIN_FILE
470 ),
471 array( 'jquery' ),
472 ACTIVITYPUB_PLUGIN_VERSION,
473 false
474 );
475 }
476
477 if ( 'index.php' === $hook_suffix ) {
478 wp_enqueue_style(
479 'activitypub-admin-styles',
480 plugins_url(
481 'assets/css/activitypub-admin.css',
482 ACTIVITYPUB_PLUGIN_FILE
483 ),
484 array(),
485 ACTIVITYPUB_PLUGIN_VERSION
486 );
487 }
488 }
489
490 /**
491 * Hook into the edit_comment functionality.
492 *
493 * Disables the edit_comment capability for federated comments.
494 */
495 public static function edit_comment() {
496 // Disable the edit_comment capability for federated comments.
497 \add_filter(
498 'user_has_cap',
499 function ( $allcaps, $caps, $arg ) {
500 if ( 'edit_comment' !== $arg[0] ) {
501 return $allcaps;
502 }
503
504 if ( was_comment_received( $arg[2] ) ) {
505 return false;
506 }
507
508 return $allcaps;
509 },
510 1,
511 3
512 );
513 }
514
515 /**
516 * Hook into the edit_post functionality.
517 *
518 * Disables the edit_post capability for federated posts.
519 */
520 public static function edit_post() {
521 // Disable the edit_post capability for federated posts.
522 \add_filter(
523 'user_has_cap',
524 function ( $allcaps, $caps, $arg ) {
525 if ( 'edit_post' !== $arg[0] ) {
526 return $allcaps;
527 }
528
529 $post = get_post( $arg[2] );
530
531 if ( ! Extra_Fields::is_extra_field_post_type( $post->post_type ) ) {
532 return $allcaps;
533 }
534
535 if ( (int) get_current_user_id() !== (int) $post->post_author ) {
536 return false;
537 }
538
539 return $allcaps;
540 },
541 1,
542 3
543 );
544 }
545
546 /**
547 * Add ActivityPub specific actions/filters to the post list view.
548 */
549 public static function list_posts() {
550 // Show only the user's extra fields.
551 \add_action(
552 'pre_get_posts',
553 function ( $query ) {
554 if ( $query->get( 'post_type' ) === 'ap_extrafield' ) {
555 $query->set( 'author', get_current_user_id() );
556 }
557 }
558 );
559
560 // Remove all views for the extra fields.
561 $screen_id = get_current_screen()->id;
562
563 add_filter(
564 "views_{$screen_id}",
565 function ( $views ) {
566 if ( Extra_Fields::is_extra_fields_post_type( get_current_screen()->post_type ) ) {
567 return array();
568 }
569
570 return $views;
571 }
572 );
573 }
574
575 /**
576 * Comment row actions.
577 *
578 * @param array $actions The existing actions.
579 * @param int|\WP_Comment $comment The comment object or ID.
580 *
581 * @return array The modified actions.
582 */
583 public static function comment_row_actions( $actions, $comment ) {
584 if ( was_comment_received( $comment ) ) {
585 unset( $actions['edit'] );
586 unset( $actions['quickedit'] );
587 }
588
589 return $actions;
590 }
591
592 /**
593 * Add a column "activitypub".
594 *
595 * This column shows if the user has the capability to use ActivityPub.
596 *
597 * @param array $columns The columns.
598 *
599 * @return array The columns extended by the activitypub.
600 */
601 public static function manage_users_columns( $columns ) {
602 $columns['activitypub'] = __( 'ActivityPub', 'activitypub' );
603 return $columns;
604 }
605
606 /**
607 * Add "comment-type" and "protocol" as column in WP-Admin.
608 *
609 * @param array $columns The list of column names.
610 *
611 * @return array The extended list of column names.
612 */
613 public static function manage_comment_columns( $columns ) {
614 $columns['comment_type'] = esc_attr__( 'Comment-Type', 'activitypub' );
615 $columns['comment_protocol'] = esc_attr__( 'Protocol', 'activitypub' );
616
617 return $columns;
618 }
619
620 /**
621 * Add "post_content" as column for Extra-Fields in WP-Admin.
622 *
623 * @param array $columns The list of column names.
624 * @param string $post_type The post type.
625 *
626 * @return array The extended list of column names.
627 */
628 public static function manage_post_columns( $columns, $post_type ) {
629 if ( Extra_Fields::is_extra_fields_post_type( $post_type ) ) {
630 $after_key = 'title';
631 $index = array_search( $after_key, array_keys( $columns ), true );
632 $columns = array_slice( $columns, 0, $index + 1 ) + array( 'extra_field_content' => esc_attr__( 'Content', 'activitypub' ) ) + $columns;
633 }
634
635 return $columns;
636 }
637
638 /**
639 * Add "comment-type" and "protocol" as column in WP-Admin.
640 *
641 * @param array $column The column to implement.
642 * @param int $comment_id The comment id.
643 */
644 public static function manage_comments_custom_column( $column, $comment_id ) {
645 if ( 'comment_type' === $column && ! defined( 'WEBMENTION_PLUGIN_DIR' ) ) {
646 echo esc_attr( ucfirst( get_comment_type( $comment_id ) ) );
647 } elseif ( 'comment_protocol' === $column ) {
648 $protocol = get_comment_meta( $comment_id, 'protocol', true );
649
650 if ( $protocol ) {
651 echo esc_attr( ucfirst( str_replace( 'activitypub', 'ActivityPub', $protocol ) ) );
652 } else {
653 esc_attr_e( 'Local', 'activitypub' );
654 }
655 }
656 }
657
658 /**
659 * Return the results for the activitypub column.
660 *
661 * @param string $output Custom column output. Default empty.
662 * @param string $column_name Column name.
663 * @param int $user_id ID of the currently-listed user.
664 *
665 * @return string The column contents.
666 */
667 public static function manage_users_custom_column( $output, $column_name, $user_id ) {
668 if ( 'activitypub' !== $column_name ) {
669 return $output;
670 }
671
672 if ( \user_can( $user_id, 'activitypub' ) ) {
673 return '<span aria-hidden="true">&#x2713;</span><span class="screen-reader-text">' . esc_html__( 'ActivityPub enabled for this author', 'activitypub' ) . '</span>';
674 } else {
675 return '<span aria-hidden="true">&#x2717;</span><span class="screen-reader-text">' . esc_html__( 'ActivityPub disabled for this author', 'activitypub' ) . '</span>';
676 }
677 }
678
679 /**
680 * Add a column "extra_field_content" to the post list view.
681 *
682 * @param string $column_name The column name.
683 * @param int $post_id The post ID.
684 *
685 * @return void
686 */
687 public static function manage_posts_custom_column( $column_name, $post_id ) {
688 if ( 'extra_field_content' === $column_name ) {
689 $post = get_post( $post_id );
690 if ( Extra_Fields::is_extra_fields_post_type( $post->post_type ) ) {
691 echo esc_attr( wp_strip_all_tags( $post->post_content ) );
692 }
693 }
694 }
695
696 /**
697 * Add options to the Bulk dropdown on the users page.
698 *
699 * @param array $actions The existing bulk options.
700 *
701 * @return array The extended bulk options.
702 */
703 public static function user_bulk_options( $actions ) {
704 $actions['add_activitypub_cap'] = __( 'Enable for ActivityPub', 'activitypub' );
705 $actions['remove_activitypub_cap'] = __( 'Disable for ActivityPub', 'activitypub' );
706
707 return $actions;
708 }
709
710 /**
711 * Handle bulk activitypub requests.
712 *
713 * * `add_activitypub_cap` - Add the activitypub capability to the selected users.
714 * * `remove_activitypub_cap` - Remove the activitypub capability from the selected users.
715 *
716 * @param string $sendback The URL to send the user back to.
717 * @param string $action The requested action.
718 * @param array $users The selected users.
719 *
720 * @return string The URL to send the user back to.
721 */
722 public static function handle_bulk_request( $sendback, $action, $users ) {
723 if (
724 'remove_activitypub_cap' !== $action &&
725 'add_activitypub_cap' !== $action
726 ) {
727 return $sendback;
728 }
729
730 foreach ( $users as $user_id ) {
731 $user = new \WP_User( $user_id );
732 if (
733 'add_activitypub_cap' === $action &&
734 user_can( $user_id, 'publish_posts' )
735 ) {
736 $user->add_cap( 'activitypub' );
737 } elseif ( 'remove_activitypub_cap' === $action ) {
738 $user->remove_cap( 'activitypub' );
739 }
740 }
741
742 return $sendback;
743 }
744
745 /**
746 * Add ActivityPub infos to the dashboard glance items.
747 *
748 * @param array $items The existing glance items.
749 *
750 * @return array The extended glance items.
751 */
752 public static function dashboard_glance_items( $items ) {
753 \add_filter( 'number_format_i18n', '\Activitypub\custom_large_numbers', 10, 3 );
754
755 if ( ! is_user_disabled( get_current_user_id() ) ) {
756 $follower_count = sprintf(
757 // translators: %s: number of followers.
758 _n(
759 '%s Follower',
760 '%s Followers',
761 count_followers( \get_current_user_id() ),
762 'activitypub'
763 ),
764 \number_format_i18n( count_followers( \get_current_user_id() ) )
765 );
766 $items['activitypub-followers-user'] = sprintf(
767 '<a class="activitypub-followers" href="%1$s" title="%2$s">%3$s</a>',
768 \esc_url( \admin_url( 'users.php?page=activitypub-followers-list' ) ),
769 \esc_attr__( 'Your followers', 'activitypub' ),
770 \esc_html( $follower_count )
771 );
772 }
773
774 if ( ! is_user_type_disabled( 'blog' ) && current_user_can( 'manage_options' ) ) {
775 $follower_count = sprintf(
776 // translators: %s: number of followers.
777 _n(
778 '%s Follower (Blog)',
779 '%s Followers (Blog)',
780 count_followers( Actors::BLOG_USER_ID ),
781 'activitypub'
782 ),
783 \number_format_i18n( count_followers( Actors::BLOG_USER_ID ) )
784 );
785 $items['activitypub-followers-blog'] = sprintf(
786 '<a class="activitypub-followers" href="%1$s" title="%2$s">%3$s</a>',
787 \esc_url( \admin_url( 'options-general.php?page=activitypub&tab=followers' ) ),
788 \esc_attr__( 'The Blog\'s followers', 'activitypub' ),
789 \esc_html( $follower_count )
790 );
791 }
792
793 \remove_filter( 'number_format_i18n', '\Activitypub\custom_large_numbers' );
794
795 return $items;
796 }
797 }
798