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

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

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