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