PluginProbe
ActivityPub / 8.0.2
ActivityPub v8.0.2
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
← All changes | includes/wp-admin/class-admin.php +139 -285 9.3.08.0.2 View file →
@@ -10,11 +10,10 @@
10 10 use Activitypub\Blocklist_Subscriptions;
11 11 use Activitypub\Collection\Actors;
12 12 use Activitypub\Collection\Extra_Fields;
13 13 use Activitypub\Comment;
14 +use Activitypub\Model\Blog;
14 15 use Activitypub\Moderation;
15 -use Activitypub\OAuth\Client;
16 -use Activitypub\OAuth\Token;
17 16 use Activitypub\Scheduler\Actor;
18 17 use Activitypub\Tombstone;
19 18
20 19 use function Activitypub\count_followers;
@@ -60,11 +59,8 @@
60 59 \add_action( 'admin_action_activitypub_confirm_removal', array( self::class, 'handle_bulk_actor_delete_page' ) );
61 60
62 61 if ( user_can_activitypub( \get_current_user_id() ) ) {
63 62 \add_action( 'show_user_profile', array( self::class, 'add_profile' ) );
64 - if ( \get_option( 'activitypub_api', false ) ) {
65 - \add_action( 'show_user_profile', array( User_Settings_Fields::class, 'connected_apps_section' ) );
66 - }
67 63 }
68 64
69 65 \add_filter( 'dashboard_glance_items', array( self::class, 'dashboard_glance_items' ) );
70 66 \add_filter( 'plugin_action_links_' . ACTIVITYPUB_PLUGIN_BASENAME, array( self::class, 'add_plugin_settings_link' ) );
@@ -74,19 +70,15 @@
74 70 \add_action( 'tool_box', array( self::class, 'tool_box' ) );
75 71 }
76 72
77 73 \add_action( 'admin_print_scripts-profile.php', array( self::class, 'enqueue_moderation_scripts' ) );
78 - \add_action( 'admin_print_scripts-profile.php', array( self::class, 'enqueue_connected_apps_scripts' ) );
79 74 \add_action( 'admin_print_scripts-settings_page_activitypub', array( self::class, 'enqueue_moderation_scripts' ) );
80 75 \add_action( 'admin_print_footer_scripts-settings_page_activitypub', array( self::class, 'open_help_tab' ) );
81 76
77 + \add_action( 'wp_dashboard_setup', array( self::class, 'add_dashboard_widgets' ) );
78 +
82 79 \add_action( 'wp_ajax_activitypub_moderation_settings', array( self::class, 'ajax_moderation_settings' ) );
83 80 \add_action( 'wp_ajax_activitypub_blocklist_subscription', array( self::class, 'ajax_blocklist_subscription' ) );
84 - \add_action( 'wp_ajax_activitypub_register_oauth_client', array( self::class, 'ajax_register_oauth_client' ) );
85 - \add_action( 'wp_ajax_activitypub_delete_oauth_client', array( self::class, 'ajax_delete_oauth_client' ) );
86 - \add_action( 'wp_ajax_activitypub_delete_all_oauth_clients', array( self::class, 'ajax_delete_all_oauth_clients' ) );
87 - \add_action( 'wp_ajax_activitypub_revoke_oauth_token', array( self::class, 'ajax_revoke_oauth_token' ) );
88 - \add_action( 'wp_ajax_activitypub_revoke_all_oauth_tokens', array( self::class, 'ajax_revoke_all_oauth_tokens' ) );
89 81 }
90 82
91 83 /**
92 84 * Display admin menu notices about configuration problems or conflicts.
@@ -91,9 +83,9 @@
91 83 /**
92 84 * Display admin menu notices about configuration problems or conflicts.
93 85 */
94 86 public static function admin_notices() {
95 - $current_screen = \get_current_screen();
87 + $current_screen = get_current_screen();
96 88
97 89 if ( ! $current_screen ) {
98 90 return;
99 91 }
@@ -105,12 +97,12 @@
105 97 \delete_option( 'activitypub_self_destruct_complete' );
106 98 ?>
107 99 <div class="notice notice-success is-dismissible">
108 100 <p>
109 - <strong><?php \esc_html_e( 'ActivityPub Self-Destruct Complete!', 'activitypub' ); ?></strong>
101 + <strong><?php esc_html_e( 'ActivityPub Self-Destruct Complete!', 'activitypub' ); ?></strong>
110 102 </p>
111 103 <p>
112 - <?php \esc_html_e( 'All Delete activities have been successfully sent to the Fediverse. Your blog is no longer discoverable via ActivityPub and all followers have been notified of the deletion.', 'activitypub' ); ?>
104 + <?php esc_html_e( 'All Delete activities have been successfully sent to the Fediverse. Your blog is no longer discoverable via ActivityPub and all followers have been notified of the deletion.', 'activitypub' ); ?>
113 105 </p>
114 106 </div>
115 107 <?php
116 108 }
@@ -118,9 +110,9 @@
118 110 if ( 'edit' === $current_screen->base && Extra_Fields::is_extra_fields_post_type( $current_screen->post_type ) ) {
119 111 ?>
120 112 <div class="notice" style="margin: 0; background: none; border: none; box-shadow: none; padding: 15px 0 0 0; font-size: 14px;">
121 113 <?php
122 - \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' );
114 + 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' );
123 115 ?>
124 116 </div>
125 117 <?php
126 118 }
@@ -199,13 +191,13 @@
199 191 /**
200 192 * Render user settings.
201 193 */
202 194 public static function add_profile() {
203 - \wp_enqueue_media();
204 - \wp_enqueue_script( 'activitypub-header-image' );
195 + wp_enqueue_media();
196 + wp_enqueue_script( 'activitypub-header-image' );
205 197
206 - \wp_nonce_field( 'activitypub-user-settings', '_apnonce' );
207 - \do_settings_sections( 'activitypub_user_settings' );
198 + wp_nonce_field( 'activitypub-user-settings', '_apnonce' );
199 + do_settings_sections( 'activitypub_user_settings' );
208 200 }
209 201
210 202 /**
211 203 * Save the user settings.
@@ -218,12 +210,12 @@
218 210 if ( ! isset( $_REQUEST['_apnonce'] ) ) {
219 211 return;
220 212 }
221 213
222 - $nonce = \sanitize_text_field( \wp_unslash( $_REQUEST['_apnonce'] ) );
214 + $nonce = sanitize_text_field( wp_unslash( $_REQUEST['_apnonce'] ) );
223 215 if (
224 - ! \wp_verify_nonce( $nonce, 'activitypub-user-settings' ) ||
225 - ! \current_user_can( 'edit_user', $user_id )
216 + ! wp_verify_nonce( $nonce, 'activitypub-user-settings' ) ||
217 + ! current_user_can( 'edit_user', $user_id )
226 218 ) {
227 219 return;
228 220 }
229 221
@@ -234,9 +226,9 @@
234 226 );
235 227
236 228 foreach ( $textarea_field_user_options as $option ) {
237 229 if ( ! empty( $_POST[ $option ] ) ) {
238 - \update_user_option( $user_id, $option, \sanitize_textarea_field( \wp_unslash( $_POST[ $option ] ) ) );
230 + \update_user_option( $user_id, $option, sanitize_textarea_field( wp_unslash( $_POST[ $option ] ) ) );
239 231 } else {
240 232 \delete_user_option( $user_id, $option );
241 233 }
242 234 }
@@ -247,9 +239,9 @@
247 239 );
248 240
249 241 foreach ( $text_field_user_options as $option ) {
250 242 if ( ! empty( $_POST[ $option ] ) ) {
251 - \update_user_option( $user_id, $option, \sanitize_text_field( \wp_unslash( $_POST[ $option ] ) ) );
243 + \update_user_option( $user_id, $option, sanitize_text_field( wp_unslash( $_POST[ $option ] ) ) );
252 244 } else {
253 245 \delete_user_option( $user_id, $option );
254 246 }
255 247 }
@@ -259,15 +251,12 @@
259 251 'activitypub_hide_social_graph',
260 252 'activitypub_mailer_new_dm',
261 253 'activitypub_mailer_new_follower',
262 254 'activitypub_mailer_new_mention',
263 - 'activitypub_mailer_new_reaction',
264 - 'activitypub_mailer_annual_report',
265 - 'activitypub_mailer_monthly_report',
266 255 );
267 256
268 257 foreach ( $required_user_options as $option ) {
269 - \update_user_option( $user_id, $option, \sanitize_text_field( \wp_unslash( $_POST[ $option ] ?? 0 ) ) );
258 + \update_user_option( $user_id, $option, sanitize_text_field( wp_unslash( $_POST[ $option ] ?? 0 ) ) );
270 259 }
271 260 }
272 261
273 262 /**
@@ -275,11 +264,11 @@
275 264 *
276 265 * @param string $hook_suffix The current page.
277 266 */
278 267 public static function enqueue_scripts( $hook_suffix ) {
279 - \wp_register_script(
268 + wp_register_script(
280 269 'activitypub-header-image',
281 - \plugins_url(
270 + plugins_url(
282 271 'assets/js/activitypub-header-image.js',
283 272 ACTIVITYPUB_PLUGIN_FILE
284 273 ),
285 274 array( 'jquery' ),
@@ -289,17 +278,17 @@
289 278
290 279 // Register and enqueue command palette integration.
291 280 if ( user_can_activitypub( \get_current_user_id() ) || \current_user_can( 'manage_options' ) ) {
292 281 $asset_data = include ACTIVITYPUB_PLUGIN_DIR . 'build/command-palette/plugin.asset.php';
293 - \wp_enqueue_script(
282 + wp_enqueue_script(
294 283 'activitypub-command-palette',
295 - \plugins_url( 'build/command-palette/plugin.js', ACTIVITYPUB_PLUGIN_FILE ),
284 + plugins_url( 'build/command-palette/plugin.js', ACTIVITYPUB_PLUGIN_FILE ),
296 285 $asset_data['dependencies'],
297 286 $asset_data['version'],
298 287 true
299 288 );
300 289
301 - \wp_localize_script(
290 + wp_localize_script(
302 291 'activitypub-command-palette',
303 292 'activitypubCommandPalette',
304 293 array(
305 294 'followingEnabled' => '1' === \get_option( 'activitypub_following_ui', '0' ),
@@ -308,12 +297,12 @@
308 297 )
309 298 );
310 299 }
311 300
312 - if ( false !== \strpos( $hook_suffix, 'activitypub' ) && 'dashboard_page_activitypub-social-web' !== $hook_suffix ) {
313 - \wp_enqueue_style(
301 + if ( false !== strpos( $hook_suffix, 'activitypub' ) && 'dashboard_page_activitypub-social-web' !== $hook_suffix ) {
302 + wp_enqueue_style(
314 303 'activitypub-admin-styles',
315 - \plugins_url(
304 + plugins_url(
316 305 'assets/css/activitypub-admin.css',
317 306 ACTIVITYPUB_PLUGIN_FILE
318 307 ),
319 308 array(),
@@ -318,11 +307,11 @@
318 307 ),
319 308 array(),
320 309 ACTIVITYPUB_PLUGIN_VERSION
321 310 );
322 - \wp_enqueue_script(
311 + wp_enqueue_script(
323 312 'activitypub-admin-script',
324 - \plugins_url(
313 + plugins_url(
325 314 'assets/js/activitypub-admin.js',
326 315 ACTIVITYPUB_PLUGIN_FILE
327 316 ),
328 317 array( 'jquery', 'wp-util' ),
@@ -336,11 +325,11 @@
336 325 \wp_enqueue_script( 'updates' );
337 326 }
338 327
339 328 if ( 'index.php' === $hook_suffix ) {
340 - \wp_enqueue_style(
329 + wp_enqueue_style(
341 330 'activitypub-admin-styles',
342 - \plugins_url(
331 + plugins_url(
343 332 'assets/css/activitypub-admin.css',
344 333 ACTIVITYPUB_PLUGIN_FILE
345 334 ),
346 335 array(),
@@ -384,48 +373,8 @@
384 373 );
385 374 }
386 375
387 376 /**
388 - * Enqueue connected apps admin scripts on the profile page.
389 - *
390 - * @since 8.1.0
391 - */
392 - public static function enqueue_connected_apps_scripts() {
393 - \wp_enqueue_script(
394 - 'activitypub-connected-apps',
395 - ACTIVITYPUB_PLUGIN_URL . 'assets/js/activitypub-connected-apps.js',
396 - array( 'jquery' ),
397 - ACTIVITYPUB_PLUGIN_VERSION,
398 - true
399 - );
400 -
401 - \wp_localize_script(
402 - 'activitypub-connected-apps',
403 - 'activitypubConnectedApps',
404 - array(
405 - 'ajaxUrl' => \admin_url( 'admin-ajax.php' ),
406 - 'nonce' => \wp_create_nonce( 'activitypub_connected_apps' ),
407 - 'confirm' => \__( 'Are you sure you want to revoke this application token? This action cannot be undone.', 'activitypub' ),
408 - 'confirmAll' => \__( 'Are you sure you want to revoke all connected applications? This action cannot be undone.', 'activitypub' ),
409 - 'confirmDelete' => \__( 'Are you sure you want to delete this application? This action cannot be undone.', 'activitypub' ),
410 - 'confirmDeleteAll' => \__( 'Are you sure you want to delete all registered applications? This action cannot be undone.', 'activitypub' ),
411 - 'registerError' => \__( 'Failed to register application.', 'activitypub' ),
412 - 'deleteLabel' => \__( 'Delete', 'activitypub' ),
413 - 'dismiss' => \__( 'Dismiss this notice.', 'activitypub' ),
414 - 'clientIdLabel' => \__( 'Your new Client ID:', 'activitypub' ),
415 - 'clientSecretLabel' => \__( 'Your new Client Secret:', 'activitypub' ),
416 - 'copy' => \__( 'Copy', 'activitypub' ),
417 - 'copied' => \__( 'Copied!', 'activitypub' ),
418 - 'saveWarning' => \__( 'Be sure to save this in a safe location. You will not be able to retrieve it.', 'activitypub' ),
419 - 'appRevoked' => \__( 'Application token revoked.', 'activitypub' ),
420 - 'allAppsRevoked' => \__( 'All application tokens revoked.', 'activitypub' ),
421 - 'appDeleted' => \__( 'Application deleted.', 'activitypub' ),
422 - 'allAppsDeleted' => \__( 'All registered applications deleted.', 'activitypub' ),
423 - )
424 - );
425 - }
426 -
427 - /**
428 377 * Hook into the edit_comment functionality.
429 378 *
430 379 * Disables the edit_comment capability for federated comments.
431 380 */
@@ -468,15 +417,15 @@
468 417 if ( 'edit_post' !== $arg[0] ) {
469 418 return $all_caps;
470 419 }
471 420
472 - $post = \get_post( $arg[2] );
421 + $post = get_post( $arg[2] );
473 422
474 423 if ( ! Extra_Fields::is_extra_field_post_type( $post->post_type ) ) {
475 424 return $all_caps;
476 425 }
477 426
478 - if ( \get_current_user_id() !== (int) $post->post_author ) {
427 + if ( get_current_user_id() !== (int) $post->post_author ) {
479 428 return false;
480 429 }
481 430
482 431 return $all_caps;
@@ -490,14 +439,14 @@
490 439 * Add ActivityPub specific actions/filters to the post list view.
491 440 */
492 441 public static function list_posts() {
493 442 // Remove all views for the extra fields.
494 - $screen_id = \get_current_screen()->id;
443 + $screen_id = get_current_screen()->id;
495 444
496 - \add_filter(
445 + add_filter(
497 446 "views_{$screen_id}",
498 447 static function ( $views ) {
499 - if ( Extra_Fields::is_extra_fields_post_type( \get_current_screen()->post_type ) ) {
448 + if ( Extra_Fields::is_extra_fields_post_type( get_current_screen()->post_type ) ) {
500 449 return array();
501 450 }
502 451
503 452 return $views;
@@ -517,9 +466,9 @@
517 466 if ( was_comment_received( $comment ) ) {
518 467 unset( $actions['edit'], $actions['quickedit'] );
519 468 }
520 469
521 - if ( \in_array( \get_comment_type( $comment ), Comment::get_comment_type_slugs(), true ) ) {
470 + if ( in_array( get_comment_type( $comment ), Comment::get_comment_type_slugs(), true ) ) {
522 471 unset( $actions['reply'] );
523 472 }
524 473
525 474 return $actions;
@@ -534,9 +483,9 @@
534 483 *
535 484 * @return array The columns extended by the activitypub.
536 485 */
537 486 public static function manage_users_columns( $columns ) {
538 - $columns['activitypub'] = \__( 'ActivityPub', 'activitypub' );
487 + $columns['activitypub'] = __( 'ActivityPub', 'activitypub' );
539 488 return $columns;
540 489 }
541 490
542 491 /**
@@ -546,10 +495,10 @@
546 495 *
547 496 * @return array The extended list of column names.
548 497 */
549 498 public static function manage_comment_columns( $columns ) {
550 - $columns['comment_type'] = \esc_attr__( 'Comment-Type', 'activitypub' );
551 - $columns['comment_protocol'] = \esc_attr__( 'Protocol', 'activitypub' );
499 + $columns['comment_type'] = esc_attr__( 'Comment-Type', 'activitypub' );
500 + $columns['comment_protocol'] = esc_attr__( 'Protocol', 'activitypub' );
552 501
553 502 return $columns;
554 503 }
555 504
@@ -563,10 +512,10 @@
563 512 */
564 513 public static function manage_post_columns( $columns, $post_type ) {
565 514 if ( Extra_Fields::is_extra_fields_post_type( $post_type ) ) {
566 515 $after_key = 'title';
567 - $index = \array_search( $after_key, \array_keys( $columns ), true );
568 - $columns = \array_slice( $columns, 0, $index + 1 ) + array( 'extra_field_content' => \esc_attr__( 'Content', 'activitypub' ) ) + $columns;
516 + $index = array_search( $after_key, array_keys( $columns ), true );
517 + $columns = array_slice( $columns, 0, $index + 1 ) + array( 'extra_field_content' => esc_attr__( 'Content', 'activitypub' ) ) + $columns;
569 518 }
570 519
571 520 return $columns;
572 521 }
@@ -577,17 +526,17 @@
577 526 * @param array $column The column to implement.
578 527 * @param int $comment_id The comment id.
579 528 */
580 529 public static function manage_comments_custom_column( $column, $comment_id ) {
581 - if ( 'comment_type' === $column && ! \defined( 'WEBMENTION_PLUGIN_DIR' ) ) {
582 - echo \esc_attr( \ucfirst( \get_comment_type( $comment_id ) ) );
530 + if ( 'comment_type' === $column && ! defined( 'WEBMENTION_PLUGIN_DIR' ) ) {
531 + echo esc_attr( ucfirst( get_comment_type( $comment_id ) ) );
583 532 } elseif ( 'comment_protocol' === $column ) {
584 - $protocol = \get_comment_meta( $comment_id, 'protocol', true );
533 + $protocol = get_comment_meta( $comment_id, 'protocol', true );
585 534
586 535 if ( $protocol ) {
587 - echo \esc_attr( \ucfirst( \str_replace( 'activitypub', 'ActivityPub', $protocol ) ) );
536 + echo esc_attr( ucfirst( str_replace( 'activitypub', 'ActivityPub', $protocol ) ) );
588 537 } else {
589 - \esc_attr_e( 'Local', 'activitypub' );
538 + esc_attr_e( 'Local', 'activitypub' );
590 539 }
591 540 }
592 541 }
593 542
@@ -599,9 +548,9 @@
599 548 * @return array The extended comment types.
600 549 */
601 550 public static function comment_types_dropdown( $types ) {
602 551 foreach ( Comment::get_comment_types() as $comment_type ) {
603 - $types[ $comment_type['type'] ] = \esc_html( $comment_type['label'] );
552 + $types[ $comment_type['type'] ] = esc_html( $comment_type['label'] );
604 553 }
605 554
606 555 return $types;
607 556 }
@@ -620,11 +569,11 @@
620 569 return $output;
621 570 }
622 571
623 572 if ( \user_can( $user_id, 'activitypub' ) ) {
624 - return '<span aria-hidden="true">&#x2713;</span><span class="screen-reader-text">' . \esc_html__( 'ActivityPub enabled for this author', 'activitypub' ) . '</span>';
573 + return '<span aria-hidden="true">&#x2713;</span><span class="screen-reader-text">' . esc_html__( 'ActivityPub enabled for this author', 'activitypub' ) . '</span>';
625 574 } else {
626 - return '<span aria-hidden="true">&#x2717;</span><span class="screen-reader-text">' . \esc_html__( 'ActivityPub disabled for this author', 'activitypub' ) . '</span>';
575 + return '<span aria-hidden="true">&#x2717;</span><span class="screen-reader-text">' . esc_html__( 'ActivityPub disabled for this author', 'activitypub' ) . '</span>';
627 576 }
628 577 }
629 578
630 579 /**
@@ -636,11 +585,11 @@
636 585 * @return void
637 586 */
638 587 public static function manage_posts_custom_column( $column_name, $post_id ) {
639 588 if ( 'extra_field_content' === $column_name ) {
640 - $post = \get_post( $post_id );
589 + $post = get_post( $post_id );
641 590 if ( Extra_Fields::is_extra_fields_post_type( $post->post_type ) ) {
642 - echo \esc_attr( \wp_strip_all_tags( $post->post_content ) );
591 + echo esc_attr( wp_strip_all_tags( $post->post_content ) );
643 592 }
644 593 }
645 594 }
646 595
@@ -651,10 +600,10 @@
651 600 *
652 601 * @return array The extended bulk options.
653 602 */
654 603 public static function user_bulk_options( $actions ) {
655 - $actions['add_activitypub_cap'] = \__( 'Enable for ActivityPub', 'activitypub' );
656 - $actions['remove_activitypub_cap'] = \__( 'Disable for ActivityPub', 'activitypub' );
604 + $actions['add_activitypub_cap'] = __( 'Enable for ActivityPub', 'activitypub' );
605 + $actions['remove_activitypub_cap'] = __( 'Disable for ActivityPub', 'activitypub' );
657 606
658 607 return $actions;
659 608 }
660 609
@@ -715,9 +664,9 @@
715 664 );
716 665
717 666 // Add user IDs as separate parameters.
718 667 foreach ( $users as $index => $user_id ) {
719 - $query_args[ \sprintf( 'users[%d]', $index ) ] = \absint( $user_id );
668 + $query_args[ sprintf( 'users[%d]', $index ) ] = absint( $user_id );
720 669 }
721 670
722 671 $confirmation_url = \add_query_arg( $query_args, \admin_url( 'users.php' ) );
723 672
@@ -819,9 +768,9 @@
819 768 * @return string The URL to redirect to.
820 769 */
821 770 public static function process_capability_removal( $users, $remove_from_fediverse, $send_back ) {
822 771 // Normalize fediverse removal parameter.
823 - if ( \is_string( $remove_from_fediverse ) ) {
772 + if ( is_string( $remove_from_fediverse ) ) {
824 773 // Legacy format: 'delete' or 'keep' for all users.
825 774 $delete_all = ( 'delete' === $remove_from_fediverse );
826 775 $users_to_delete = $delete_all ? $users : array();
827 776 } else {
@@ -859,11 +808,11 @@
859 808 public static function dashboard_glance_items( $items ) {
860 809 \add_filter( 'number_format_i18n', '\Activitypub\custom_large_numbers', 10, 2 );
861 810
862 811 if ( user_can_activitypub( \get_current_user_id() ) ) {
863 - $follower_count = \sprintf(
812 + $follower_count = sprintf(
864 813 // translators: %s: number of followers.
865 - \_n(
814 + _n(
866 815 '%s Follower',
867 816 '%s Followers',
868 817 count_followers( \get_current_user_id() ),
869 818 'activitypub'
@@ -869,9 +818,9 @@
869 818 'activitypub'
870 819 ),
871 820 \number_format_i18n( count_followers( \get_current_user_id() ) )
872 821 );
873 - $items['activitypub-followers-user'] = \sprintf(
822 + $items['activitypub-followers-user'] = sprintf(
874 823 '<a class="activitypub-followers" href="%1$s" title="%2$s">%3$s</a>',
875 824 \esc_url( \admin_url( 'users.php?page=activitypub-followers-list' ) ),
876 825 \esc_attr__( 'Your followers', 'activitypub' ),
877 826 \esc_html( $follower_count )
@@ -877,12 +826,12 @@
877 826 \esc_html( $follower_count )
878 827 );
879 828 }
880 829
881 - if ( ! is_user_type_disabled( 'blog' ) && \current_user_can( 'manage_options' ) ) {
882 - $follower_count = \sprintf(
830 + if ( ! is_user_type_disabled( 'blog' ) && current_user_can( 'manage_options' ) ) {
831 + $follower_count = sprintf(
883 832 // translators: %s: number of followers.
884 - \_n(
833 + _n(
885 834 '%s Follower (Blog)',
886 835 '%s Followers (Blog)',
887 836 count_followers( Actors::BLOG_USER_ID ),
888 837 'activitypub'
@@ -888,9 +837,9 @@
888 837 'activitypub'
889 838 ),
890 839 \number_format_i18n( count_followers( Actors::BLOG_USER_ID ) )
891 840 );
892 - $items['activitypub-followers-blog'] = \sprintf(
841 + $items['activitypub-followers-blog'] = sprintf(
893 842 '<a class="activitypub-followers" href="%1$s" title="%2$s">%3$s</a>',
894 843 \esc_url( \admin_url( 'options-general.php?page=activitypub&tab=followers' ) ),
895 844 \esc_attr__( 'The Blog\'s followers', 'activitypub' ),
896 845 \esc_html( $follower_count )
@@ -913,9 +862,9 @@
913 862 public static function row_actions( $actions, $post ) {
914 863 // check if the post is enabled for ActivityPub.
915 864 if (
916 865 ! \post_type_supports( \get_post_type( $post ), 'activitypub' ) ||
917 - ! \in_array( $post->post_status, array( 'pending', 'draft', 'future', 'publish' ), true ) ||
866 + ! in_array( $post->post_status, array( 'pending', 'draft', 'future', 'publish' ), true ) ||
918 867 ! \current_user_can( 'edit_post', $post->ID ) ||
919 868 ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL === get_content_visibility( $post->ID ) ||
920 869 ( site_supports_blocks() && \use_block_editor_for_post_type( $post->post_type ) )
921 870 ) {
@@ -921,11 +870,11 @@
921 870 ) {
922 871 return $actions;
923 872 }
924 873
925 - $preview_url = \add_query_arg( 'activitypub', 'true', \get_preview_post_link( $post ) );
874 + $preview_url = add_query_arg( 'activitypub', 'true', \get_preview_post_link( $post ) );
926 875
927 - $actions['activitypub'] = \sprintf(
876 + $actions['activitypub'] = sprintf(
928 877 '<a href="%s" target="_blank">%s</a>',
929 878 \esc_url( $preview_url ),
930 879 \esc_html__( 'Fediverse Preview ⁂', 'activitypub' )
931 880 );
@@ -958,9 +907,9 @@
958 907 if ( ! isset( $update->upgrade_notice ) ) {
959 908 return;
960 909 }
961 910
962 - echo '<br>' . \wp_strip_all_tags( $update->upgrade_notice ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
911 + echo '<br>' . wp_strip_all_tags( $update->upgrade_notice ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
963 912 }
964 913
965 914 /**
966 915 * Adds meta box on wp-admin/tools.php.
@@ -1005,8 +954,80 @@
1005 954 <?php
1006 955 }
1007 956
1008 957 /**
958 + * Add Dashboard widgets.
959 + */
960 + public static function add_dashboard_widgets() {
961 + \wp_add_dashboard_widget( 'activitypub_blog', \__( 'ActivityPub Plugin News', 'activitypub' ), array( self::class, 'blog_dashboard_widget' ) );
962 + if ( user_can_activitypub( \get_current_user_id() ) && ! is_user_type_disabled( 'user' ) ) {
963 + \wp_add_dashboard_widget( 'activitypub_profile', \__( 'ActivityPub Author profile', 'activitypub' ), array( self::class, 'profile_dashboard_widget' ) );
964 + }
965 + if ( ! is_user_type_disabled( 'blog' ) ) {
966 + \wp_add_dashboard_widget( 'activitypub_blog_profile', \__( 'ActivityPub Blog profile', 'activitypub' ), array( self::class, 'blogprofile_dashboard_widget' ) );
967 + }
968 + }
969 +
970 + /**
971 + * Add the `ActivityPub.blog` feed as a Dashboard widget.
972 + */
973 + public static function blog_dashboard_widget() {
974 + echo '<div class="rss-widget">';
975 + \wp_widget_rss_output(
976 + array(
977 + 'url' => 'https://activitypub.blog/feed/',
978 + 'items' => 3,
979 + 'show_summary' => 1,
980 + 'show_author' => 0,
981 + 'show_date' => 1,
982 + )
983 + );
984 + echo '</div>';
985 + }
986 +
987 + /**
988 + * Add the ActivityPub Author profile as a Dashboard widget.
989 + */
990 + public static function profile_dashboard_widget() {
991 + $user = Actors::get_by_id( \get_current_user_id() );
992 + ?>
993 + <p>
994 + <?php \esc_html_e( 'People can follow you by using your author name:', 'activitypub' ); ?>
995 + </p>
996 + <p><label for="activitypub-user-identifier"><?php \esc_html_e( 'Username', 'activitypub' ); ?></label><input type="text" class="large-text code" id="activitypub-user-identifier" value="<?php echo \esc_attr( $user->get_webfinger() ); ?>" readonly /></p>
997 + <p><label for="activitypub-user-url"><?php \esc_html_e( 'Profile URL', 'activitypub' ); ?></label><input type="text" class="large-text code" id="activitypub-user-url" value="<?php echo \esc_attr( $user->get_url() ); ?>" readonly /></p>
998 + <p>
999 + <?php \esc_html_e( 'Authors who can not access this settings page will find their username on the "Edit Profile" page.', 'activitypub' ); ?>
1000 + <a href="<?php echo \esc_url( \admin_url( '/profile.php#activitypub' ) ); ?>">
1001 + <?php \esc_html_e( 'Customize username on "Edit Profile" page.', 'activitypub' ); ?>
1002 + </a>
1003 + </p>
1004 + <?php
1005 + }
1006 +
1007 + /**
1008 + * Add the ActivityPub Blog profile as a Dashboard widget.
1009 + */
1010 + public static function blogprofile_dashboard_widget() {
1011 + $user = new Blog();
1012 + ?>
1013 + <p>
1014 + <?php \esc_html_e( 'People can follow your blog by using:', 'activitypub' ); ?>
1015 + </p>
1016 + <p><label for="activitypub-user-identifier"><?php \esc_html_e( 'Username', 'activitypub' ); ?></label><input type="text" class="large-text code" id="activitypub-user-identifier" value="<?php echo \esc_attr( $user->get_webfinger() ); ?>" readonly /></p>
1017 + <p><label for="activitypub-user-url"><?php \esc_html_e( 'Profile URL', 'activitypub' ); ?></label><input type="text" class="large-text code" id="activitypub-user-url" value="<?php echo \esc_attr( $user->get_url() ); ?>" readonly /></p>
1018 + <p>
1019 + <?php \esc_html_e( 'This blog profile will federate all posts written on your blog, regardless of the author who posted it.', 'activitypub' ); ?>
1020 + <?php if ( current_user_can( 'manage_options' ) ) : ?>
1021 + <a href="<?php echo \esc_url( \admin_url( '/options-general.php?page=activitypub&tab=blog-profile' ) ); ?>">
1022 + <?php \esc_html_e( 'Customize the blog profile.', 'activitypub' ); ?>
1023 + </a>
1024 + <?php endif; ?>
1025 + </p>
1026 + <?php
1027 + }
1028 +
1029 + /**
1009 1030 * AJAX handler for moderation settings (add/remove blocks).
1010 1031 */
1011 1032 public static function ajax_moderation_settings() {
1012 1033 $context = \sanitize_text_field( \wp_unslash( $_POST['context'] ?? '' ) );
@@ -1014,13 +1035,13 @@
1014 1035 $type = \sanitize_text_field( \wp_unslash( $_POST['type'] ?? '' ) );
1015 1036 $value = \sanitize_text_field( \wp_unslash( $_POST['value'] ?? '' ) );
1016 1037
1017 1038 // Validate required parameters.
1018 - if ( ! \in_array( $context, array( 'user', 'site' ), true ) || ! \in_array( $operation, array( 'add', 'remove' ), true ) ) {
1039 + if ( ! in_array( $context, array( 'user', 'site' ), true ) || ! in_array( $operation, array( 'add', 'remove' ), true ) ) {
1019 1040 \wp_send_json_error( array( 'message' => \__( 'Invalid context or action.', 'activitypub' ) ) );
1020 1041 }
1021 1042
1022 - if ( empty( $type ) || empty( $value ) || ! \in_array( $type, array( 'domain', 'keyword' ), true ) ) {
1043 + if ( empty( $type ) || empty( $value ) || ! in_array( $type, array( 'domain', 'keyword' ), true ) ) {
1023 1044 \wp_send_json_error( array( 'message' => \__( 'Invalid parameters.', 'activitypub' ) ) );
1024 1045 }
1025 1046
1026 1047 // Verify nonce for all operations.
@@ -1110,173 +1131,6 @@
1110 1131 \wp_send_json_success();
1111 1132 } else {
1112 1133 \wp_send_json_error( array( 'message' => \__( 'Failed to remove subscription.', 'activitypub' ) ) );
1113 1134 }
1114 - }
1115 -
1116 - /**
1117 - * AJAX handler for registering a new OAuth client from the user profile.
1118 - *
1119 - * @since 8.1.0
1120 - */
1121 - public static function ajax_register_oauth_client() {
1122 - // Verify nonce.
1123 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1124 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1125 - }
1126 -
1127 - if ( ! \current_user_can( 'manage_options' ) ) {
1128 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1129 - }
1130 -
1131 - $name = \sanitize_text_field( \wp_unslash( $_POST['name'] ?? '' ) );
1132 - $redirect_uri = \sanitize_url( \wp_unslash( $_POST['redirect_uri'] ?? '' ) );
1133 -
1134 - if ( empty( $name ) ) {
1135 - \wp_send_json_error( array( 'message' => \__( 'Application name is required.', 'activitypub' ) ) );
1136 - }
1137 -
1138 - if ( empty( $redirect_uri ) ) {
1139 - \wp_send_json_error( array( 'message' => \__( 'Redirect URI is required.', 'activitypub' ) ) );
1140 - }
1141 -
1142 - $result = Client::register(
1143 - array(
1144 - 'name' => $name,
1145 - 'redirect_uris' => array( $redirect_uri ),
1146 - 'is_public' => false,
1147 - )
1148 - );
1149 -
1150 - if ( \is_wp_error( $result ) ) {
1151 - \wp_send_json_error( array( 'message' => $result->get_error_message() ) );
1152 - }
1153 -
1154 - $data = array(
1155 - 'client_id' => $result['client_id'],
1156 - 'created' => \date_i18n( \get_option( 'date_format' ) ),
1157 - );
1158 -
1159 - if ( ! empty( $result['client_secret'] ) ) {
1160 - $data['client_secret'] = $result['client_secret'];
1161 - }
1162 -
1163 - \wp_send_json_success( $data );
1164 - }
1165 -
1166 - /**
1167 - * AJAX handler for deleting a registered OAuth client.
1168 - *
1169 - * @since 8.1.0
1170 - */
1171 - public static function ajax_delete_oauth_client() {
1172 - // Verify nonce.
1173 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1174 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1175 - }
1176 -
1177 - if ( ! \current_user_can( 'manage_options' ) ) {
1178 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1179 - }
1180 -
1181 - $client_id = \sanitize_text_field( \wp_unslash( $_POST['client_id'] ?? '' ) );
1182 -
1183 - if ( empty( $client_id ) ) {
1184 - \wp_send_json_error( array( 'message' => \__( 'Invalid client ID.', 'activitypub' ) ) );
1185 - }
1186 -
1187 - $deleted = Client::delete( $client_id );
1188 -
1189 - if ( ! $deleted ) {
1190 - \wp_send_json_error( array( 'message' => \__( 'Failed to delete application.', 'activitypub' ) ) );
1191 - }
1192 -
1193 - \wp_send_json_success( array( 'deleted' => true ) );
1194 - }
1195 -
1196 - /**
1197 - * AJAX handler for deleting all manually registered OAuth clients.
1198 - *
1199 - * @since 8.1.0
1200 - */
1201 - public static function ajax_delete_all_oauth_clients() {
1202 - // Verify nonce.
1203 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1204 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1205 - }
1206 -
1207 - if ( ! \current_user_can( 'manage_options' ) ) {
1208 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1209 - }
1210 -
1211 - $clients = Client::get_manually_registered();
1212 -
1213 - foreach ( $clients as $client ) {
1214 - Client::delete( $client->get_client_id() );
1215 - }
1216 -
1217 - \wp_send_json_success( array( 'deleted' => ! empty( $clients ) ) );
1218 - }
1219 -
1220 - /**
1221 - * AJAX handler for revoking an OAuth token from the user profile.
1222 - *
1223 - * Follows the WordPress core Application Passwords pattern.
1224 - *
1225 - * @since 8.1.0
1226 - */
1227 - public static function ajax_revoke_oauth_token() {
1228 - // Verify nonce.
1229 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1230 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1231 - }
1232 -
1233 - if ( ! \current_user_can( 'read' ) ) {
1234 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1235 - }
1236 -
1237 - $meta_key = \sanitize_text_field( \wp_unslash( $_POST['meta_key'] ?? '' ) ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Not a DB query parameter.
1238 -
1239 - // Verify the meta key belongs to our token prefix.
1240 - if ( 0 !== \strpos( $meta_key, Token::META_PREFIX ) ) {
1241 - \wp_send_json_error( array( 'message' => \__( 'Invalid token.', 'activitypub' ) ) );
1242 - }
1243 -
1244 - $user_id = \get_current_user_id();
1245 - $token_data = \get_user_meta( $user_id, $meta_key, true );
1246 -
1247 - // Verify the token belongs to the current user.
1248 - if ( empty( $token_data ) || ! \is_array( $token_data ) ) {
1249 - \wp_send_json_error( array( 'message' => \__( 'Token not found.', 'activitypub' ) ) );
1250 - }
1251 -
1252 - // Delete the token.
1253 - \delete_user_meta( $user_id, $meta_key );
1254 -
1255 - // Delete the associated refresh token index.
1256 - if ( ! empty( $token_data['refresh_token_hash'] ) ) {
1257 - \delete_user_meta( $user_id, Token::REFRESH_INDEX_PREFIX . $token_data['refresh_token_hash'] );
1258 - }
1259 -
1260 - \wp_send_json_success( array( 'deleted' => true ) );
1261 - }
1262 -
1263 - /**
1264 - * AJAX handler for revoking all OAuth tokens for the current user.
1265 - *
1266 - * @since 8.1.0
1267 - */
1268 - public static function ajax_revoke_all_oauth_tokens() {
1269 - // Verify nonce.
1270 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1271 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1272 - }
1273 -
1274 - if ( ! \current_user_can( 'read' ) ) {
1275 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1276 - }
1277 -
1278 - $count = Token::revoke_all_for_user( \get_current_user_id() );
1279 -
1280 - \wp_send_json_success( array( 'deleted' => $count > 0 ) );
1281 1135 }
1282 1136 }