PluginProbe
ActivityPub / 5.7.0
ActivityPub v5.7.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/wp-admin/class-settings.php +418 -302 8.2.15.7.0 View file →
@@ -7,9 +7,10 @@
7 7
8 8 namespace Activitypub\WP_Admin;
9 9
10 10 use Activitypub\Collection\Actors;
11 -
11 +use Activitypub\Model\Blog;
12 +use Activitypub\Sanitize;
12 13 use function Activitypub\user_can_activitypub;
13 14
14 15 /**
15 16 * ActivityPub Settings Class.
@@ -18,26 +19,269 @@
18 19 /**
19 20 * Initialize the class, registering WordPress hooks,
20 21 */
21 22 public static function init() {
23 + \add_action( 'admin_init', array( self::class, 'register_settings' ), 11 );
22 24 \add_action( 'admin_menu', array( self::class, 'add_settings_page' ) );
23 25
24 26 \add_action( 'load-settings_page_activitypub', array( self::class, 'handle_welcome_query_arg' ) );
25 - \add_action( 'load-settings_page_activitypub', array( self::class, 'handle_switch_object_type' ) );
27 + \add_filter( 'screen_settings', array( self::class, 'add_screen_option' ), 10, 2 );
28 + \add_filter( 'screen_options_show_submit', array( self::class, 'screen_options_show_submit' ), 10, 2 );
26 29 }
27 30
28 31 /**
32 + * Register ActivityPub settings
33 + */
34 + public static function register_settings() {
35 + \register_setting(
36 + 'activitypub',
37 + 'activitypub_post_content_type',
38 + array(
39 + 'type' => 'string',
40 + 'description' => \__( 'Use title and link, summary, full or custom content', 'activitypub' ),
41 + 'show_in_rest' => array(
42 + 'schema' => array(
43 + 'enum' => array( 'title', 'excerpt', 'content' ),
44 + ),
45 + ),
46 + 'default' => 'content',
47 + )
48 + );
49 +
50 + \register_setting(
51 + 'activitypub',
52 + 'activitypub_custom_post_content',
53 + array(
54 + 'type' => 'string',
55 + 'description' => \__( 'Define your own custom post template', 'activitypub' ),
56 + 'show_in_rest' => true,
57 + 'default' => ACTIVITYPUB_CUSTOM_POST_CONTENT,
58 + )
59 + );
60 +
61 + \register_setting(
62 + 'activitypub',
63 + 'activitypub_max_image_attachments',
64 + array(
65 + 'type' => 'integer',
66 + 'description' => \__( 'Number of images to attach to posts.', 'activitypub' ),
67 + 'default' => ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS,
68 + )
69 + );
70 +
71 + \register_setting(
72 + 'activitypub',
73 + 'activitypub_object_type',
74 + array(
75 + 'type' => 'string',
76 + 'description' => \__( 'The Activity-Object-Type', 'activitypub' ),
77 + 'show_in_rest' => array(
78 + 'schema' => array(
79 + 'enum' => array( 'note', 'wordpress-post-format' ),
80 + ),
81 + ),
82 + 'default' => ACTIVITYPUB_DEFAULT_OBJECT_TYPE,
83 + )
84 + );
85 +
86 + \register_setting(
87 + 'activitypub',
88 + 'activitypub_use_hashtags',
89 + array(
90 + 'type' => 'boolean',
91 + 'description' => \__( 'Add hashtags in the content as native tags and replace the #tag with the tag-link', 'activitypub' ),
92 + 'default' => '0',
93 + )
94 + );
95 +
96 + \register_setting(
97 + 'activitypub',
98 + 'activitypub_use_opengraph',
99 + array(
100 + 'type' => 'boolean',
101 + 'description' => \__( 'Automatically add "fediverse:creator" OpenGraph tags for Authors and the Blog-User.', 'activitypub' ),
102 + 'default' => '1',
103 + )
104 + );
105 +
106 + \register_setting(
107 + 'activitypub',
108 + 'activitypub_support_post_types',
109 + array(
110 + 'type' => 'string',
111 + 'description' => \esc_html__( 'Enable ActivityPub support for post types', 'activitypub' ),
112 + 'show_in_rest' => true,
113 + 'default' => array( 'post' ),
114 + )
115 + );
116 +
117 + \register_setting(
118 + 'activitypub',
119 + 'activitypub_actor_mode',
120 + array(
121 + 'type' => 'integer',
122 + 'description' => \__( 'Choose your preferred Actor-Mode.', 'activitypub' ),
123 + 'default' => ACTIVITYPUB_ACTOR_MODE,
124 + )
125 + );
126 +
127 + \register_setting(
128 + 'activitypub',
129 + 'activitypub_attribution_domains',
130 + array(
131 + 'type' => 'string',
132 + 'description' => \__( 'Websites allowed to credit you.', 'activitypub' ),
133 + 'default' => \Activitypub\home_host(),
134 + 'sanitize_callback' => array( Sanitize::class, 'host_list' ),
135 + )
136 + );
137 +
138 + \register_setting(
139 + 'activitypub',
140 + 'activitypub_allow_likes',
141 + array(
142 + 'type' => 'integer',
143 + 'description' => \__( 'Allow likes.', 'activitypub' ),
144 + 'default' => '1',
145 + 'sanitize_callback' => 'absint',
146 + )
147 + );
148 +
149 + \register_setting(
150 + 'activitypub',
151 + 'activitypub_allow_reposts',
152 + array(
153 + 'type' => 'integer',
154 + 'description' => \__( 'Allow reposts.', 'activitypub' ),
155 + 'default' => '1',
156 + 'sanitize_callback' => 'absint',
157 + )
158 + );
159 +
160 + \register_setting(
161 + 'activitypub',
162 + 'activitypub_mailer_new_dm',
163 + array(
164 + 'type' => 'boolean',
165 + 'description' => \__( 'Send notifications via e-mail when a direct message is received.', 'activitypub' ),
166 + 'default' => '0',
167 + )
168 + );
169 +
170 + \register_setting(
171 + 'activitypub_advanced',
172 + 'activitypub_outbox_purge_days',
173 + array(
174 + 'type' => 'integer',
175 + 'description' => \__( 'Number of days to keep items in the Outbox.', 'activitypub' ),
176 + 'default' => 180,
177 + )
178 + );
179 +
180 + \register_setting(
181 + 'activitypub_advanced',
182 + 'activitypub_vary_header',
183 + array(
184 + 'type' => 'boolean',
185 + 'description' => \__( 'Add the Vary header to the ActivityPub response.', 'activitypub' ),
186 + 'default' => false,
187 + )
188 + );
189 +
190 + \register_setting(
191 + 'activitypub_advanced',
192 + 'activitypub_authorized_fetch',
193 + array(
194 + 'type' => 'boolean',
195 + 'description' => \__( 'Require HTTP signature authentication.', 'activitypub' ),
196 + 'default' => false,
197 + )
198 + );
199 +
200 + \register_setting(
201 + 'activitypub_advanced',
202 + 'activitypub_shared_inbox',
203 + array(
204 + 'type' => 'boolean',
205 + 'description' => \__( 'Enable the shared inbox.', 'activitypub' ),
206 + 'default' => false,
207 + )
208 + );
209 +
210 + \register_setting(
211 + 'activitypub',
212 + 'activitypub_relays',
213 + array(
214 + 'type' => 'array',
215 + 'description' => \__( 'Relays', 'activitypub' ),
216 + 'default' => array(),
217 + 'sanitize_callback' => array( Sanitize::class, 'url_list' ),
218 + )
219 + );
220 +
221 + // Blog-User Settings.
222 + \register_setting(
223 + 'activitypub_blog',
224 + 'activitypub_blog_description',
225 + array(
226 + 'type' => 'string',
227 + 'description' => \esc_html__( 'The Description of the Blog-User', 'activitypub' ),
228 + 'show_in_rest' => true,
229 + 'default' => '',
230 + )
231 + );
232 +
233 + \register_setting(
234 + 'activitypub_blog',
235 + 'activitypub_blog_identifier',
236 + array(
237 + 'type' => 'string',
238 + 'description' => \esc_html__( 'The Identifier of the Blog-User', 'activitypub' ),
239 + 'show_in_rest' => true,
240 + 'default' => Blog::get_default_username(),
241 + 'sanitize_callback' => array( Sanitize::class, 'blog_identifier' ),
242 + )
243 + );
244 +
245 + \register_setting(
246 + 'activitypub_blog',
247 + 'activitypub_header_image',
248 + array(
249 + 'type' => 'integer',
250 + 'description' => \__( 'The Attachment-ID of the Sites Header-Image', 'activitypub' ),
251 + 'default' => null,
252 + )
253 + );
254 +
255 + \register_setting(
256 + 'activitypub_blog',
257 + 'activitypub_blog_user_also_known_as',
258 + array(
259 + 'type' => 'array',
260 + 'description' => 'An array of URLs that the blog user is known by.',
261 + 'default' => array(),
262 + 'sanitize_callback' => array( Sanitize::class, 'url_list' ),
263 + )
264 + );
265 + }
266 +
267 + /**
29 268 * Load settings page.
30 269 */
31 270 public static function settings_page() {
32 271 $show_welcome_tab = \get_user_meta( \get_current_user_id(), 'activitypub_show_welcome_tab', true );
33 272 $show_advanced_tab = \get_user_meta( \get_current_user_id(), 'activitypub_show_advanced_tab', true );
34 - $settings_tabs = array();
35 - $settings_tab = array(
36 - 'label' => __( 'Settings', 'activitypub' ),
37 - 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/settings.php',
38 - );
273 + $default_tab = $show_welcome_tab ? 'welcome' : 'settings';
274 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
275 + $tab = isset( $_GET['tab'] ) ? \sanitize_key( $_GET['tab'] ) : $default_tab;
39 276
277 + // Redirect welcome tab to settings if skipped.
278 + if ( 'welcome' === $tab && ! $show_welcome_tab ) {
279 + $tab = 'settings';
280 + }
281 +
282 + $settings_tabs = array();
283 +
40 284 if ( $show_welcome_tab ) {
41 285 $settings_tabs['welcome'] = array(
42 286 'label' => __( 'Welcome', 'activitypub' ),
43 287 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/welcome.php',
@@ -43,9 +287,12 @@
43 287 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/welcome.php',
44 288 );
45 289 }
46 290
47 - $settings_tabs['settings'] = $settings_tab;
291 + $settings_tabs['settings'] = array(
292 + 'label' => __( 'Settings', 'activitypub' ),
293 + 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/settings.php',
294 + );
48 295
49 296 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
50 297 if ( ( isset( $_GET['tab'] ) && 'advanced' === $_GET['tab'] ) || $show_advanced_tab ) {
51 298 $settings_tabs['advanced'] = array(
@@ -53,14 +300,8 @@
53 300 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/advanced-settings.php',
54 301 );
55 302 }
56 303
57 - // Add blocked actors tab for site-wide blocking.
58 - $settings_tabs['blocked-actors'] = array(
59 - 'label' => \__( 'Blocked Actors', 'activitypub' ),
60 - 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/blocked-actors-list.php',
61 - );
62 -
63 304 if ( user_can_activitypub( Actors::BLOG_USER_ID ) ) {
64 305 $settings_tabs['blog-profile'] = array(
65 306 'label' => __( 'Blog Profile', 'activitypub' ),
66 307 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/blog-settings.php',
@@ -66,17 +307,10 @@
66 307 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/blog-settings.php',
67 308 );
68 309 $settings_tabs['followers'] = array(
69 310 'label' => __( 'Followers', 'activitypub' ),
70 - 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/followers-list.php',
311 + 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/blog-followers-list.php',
71 312 );
72 -
73 - if ( '1' === \get_option( 'activitypub_following_ui', '0' ) ) {
74 - $settings_tabs['following'] = array(
75 - 'label' => __( 'Following', 'activitypub' ),
76 - 'template' => ACTIVITYPUB_PLUGIN_DIR . 'templates/following-list.php',
77 - );
78 - }
79 313 }
80 314
81 315 /**
82 316 * Filters the tabs displayed in the ActivityPub settings.
@@ -82,44 +316,31 @@
82 316 * Filters the tabs displayed in the ActivityPub settings.
83 317 *
84 318 * @param array $settings_tabs The tabs to display.
85 319 */
86 - $settings_tabs = \apply_filters( 'activitypub_admin_settings_tabs', $settings_tabs );
320 + $custom_tabs = \apply_filters( 'activitypub_admin_settings_tabs', array() );
321 + $settings_tabs = \array_merge( $settings_tabs, $custom_tabs );
87 322
88 - if ( empty( $settings_tabs ) ) {
89 - _doing_it_wrong( __FUNCTION__, 'No settings tabs found. There should be at least one tab to show a settings page.', '7.0.0' );
90 - $settings_tabs['settings'] = $settings_tab;
91 - }
92 -
93 - $tab_keys = array_keys( $settings_tabs );
94 - $default_tab = reset( $tab_keys );
95 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended
96 - $tab = isset( $_GET['tab'] ) ? \sanitize_key( $_GET['tab'] ) : $default_tab;
97 -
98 - if ( ! isset( $settings_tabs[ $tab ] ) ) {
99 - $tab = $default_tab;
100 - }
101 -
102 323 switch ( $tab ) {
103 324 case 'blog-profile':
104 325 \wp_enqueue_media();
105 326 \wp_enqueue_script( 'activitypub-header-image' );
106 327 break;
107 - case 'settings':
108 - \update_option( 'activitypub_checklist_settings_visited', '1' );
328 + case 'welcome':
329 + \wp_enqueue_script( 'plugin-install' );
330 + \add_thickbox();
331 + \wp_enqueue_script( 'updates' );
109 332 break;
110 - default:
111 - if ( isset( $_GET['help-tab'] ) && 'getting-started' === $_GET['help-tab'] ) { // phpcs:ignore WordPress.Security.NonceVerification
112 - \update_option( 'activitypub_checklist_fediverse_intro_visited', '1' );
113 - } elseif ( isset( $_GET['help-tab'] ) && 'editor-blocks' === $_GET['help-tab'] ) { // phpcs:ignore WordPress.Security.NonceVerification
114 - \update_option( 'activitypub_checklist_blocks_visited', '1' );
115 - }
116 - break;
117 333 }
118 334
335 + if ( ! isset( $settings_tabs[ $tab ] ) ) {
336 + $tab = $default_tab;
337 + }
338 +
119 339 // Only show tabs if there are more than one.
120 - $labels = array();
121 - if ( \count( $settings_tabs ) > 1 ) {
340 + if ( \count( $settings_tabs ) <= 1 ) {
341 + $labels = array();
342 + } else {
122 343 $labels = \wp_list_pluck( $settings_tabs, 'label' );
123 344 }
124 345
125 346 $args = \array_fill_keys( \array_keys( $labels ), '' );
@@ -133,150 +354,138 @@
133 354 /**
134 355 * Adds the ActivityPub settings to the Help tab.
135 356 */
136 357 public static function add_settings_help_tab() {
137 - // Getting Started / Introduction to the Fediverse.
138 - \get_current_screen()->add_help_tab(
139 - array(
140 - 'id' => 'getting-started',
141 - 'title' => \__( 'Getting Started', 'activitypub' ),
142 - 'content' => self::get_help_tab_template( 'getting-started' ),
143 - )
358 + $code_html = array( 'code' => array() );
359 + $anchor_html = array(
360 + 'a' => array(
361 + 'href' => true,
362 + 'target' => true,
363 + ),
144 364 );
145 365
146 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended
147 - if ( 'following' === \sanitize_text_field( \wp_unslash( $_GET['tab'] ?? '' ) ) ) {
148 - self::add_following_help_tab();
366 + if ( user_can_activitypub( \get_current_user_id() ) ) {
367 + $webfinger = Actors::get_by_id( \get_current_user_id() )->get_webfinger();
368 + } else {
369 + $webfinger = ( new Blog() )->get_webfinger();
149 370 }
150 371
151 - // Core Features.
152 372 \get_current_screen()->add_help_tab(
153 373 array(
154 - 'id' => 'core-features',
155 - 'title' => \__( 'Core Features', 'activitypub' ),
156 - 'content' => self::get_help_tab_template( 'core-features' ),
374 + 'id' => 'template-tags',
375 + 'title' => \__( 'Template Tags', 'activitypub' ),
376 + 'content' => '<h2>' . \esc_html__( 'The following Template Tags are available:', 'activitypub' ) . '</h2>' . "\n" .
377 + '<dl>' . "\n" .
378 + '<dt><code>[ap_title]</code></dt>' . "\n" .
379 + '<dd>' . \esc_html__( 'The post&#8217;s title.', 'activitypub' ) . '</dd>' . "\n" .
380 + '<dt><code>[ap_content apply_filters="yes"]</code></dt>' . "\n" .
381 + '<dd>' . \wp_kses( \__( 'The post&#8217;s content. With <code>apply_filters</code> you can decide if filters (<code>apply_filters( \'the_content\', $content )</code>) should be applied or not (default is <code>yes</code>). The values can be <code>yes</code> or <code>no</code>. <code>apply_filters</code> attribute is optional.', 'activitypub' ), $code_html ) . '</dd>' . "\n" .
382 + '<dt><code>[ap_excerpt length="400"]</code></dt>' . "\n" .
383 + '<dd>' . \wp_kses( \__( 'The post&#8217;s excerpt (uses <code>the_excerpt</code> if that is set). If no excerpt is provided, will truncate at <code>length</code> (optional, default = 400).', 'activitypub' ), $code_html ) . '</dd>' . "\n" .
384 + '<dt><code>[ap_permalink type="url"]</code></dt>' . "\n" .
385 + '<dd>' . \wp_kses( \__( 'The post&#8217;s permalink. <code>type</code> can be either: <code>url</code> or <code>html</code> (an &lt;a /&gt; tag). <code>type</code> attribute is optional.', 'activitypub' ), $code_html ) . '</dd>' . "\n" .
386 + '<dt><code>[ap_shortlink type="url"]</code></dt>' . "\n" .
387 + '<dd>' . \wp_kses( \__( 'The post&#8217;s shortlink. <code>type</code> can be either <code>url</code> or <code>html</code> (an &lt;a /&gt; tag). I can recommend <a href="https://wordpress.org/plugins/hum/" target="_blank">Hum</a>, to prettify the Shortlinks. <code>type</code> attribute is optional.', 'activitypub' ), $code_html ) . '</dd>' . "\n" .
388 + '<dt><code>[ap_hashtags]</code></dt>' . "\n" .
389 + '<dd>' . \esc_html__( 'The post&#8217;s tags as hashtags.', 'activitypub' ) . '</dd>' . "\n" .
390 + '<dt><code>[ap_hashcats]</code></dt>' . "\n" .
391 + '<dd>' . \esc_html__( 'The post&#8217;s categories as hashtags.', 'activitypub' ) . '</dd>' . "\n" .
392 + '<dt><code>[ap_image type=full]</code></dt>' . "\n" .
393 + '<dd>' . \wp_kses( __( 'The URL for the post&#8217;s featured image, defaults to full size. The type attribute can be any of the following: <code>thumbnail</code>, <code>medium</code>, <code>large</code>, <code>full</code>. <code>type</code> attribute is optional.', 'activitypub' ), $code_html ) . '</dd>' . "\n" .
394 + '<dt><code>[ap_author]</code></dt>' . "\n" .
395 + '<dd>' . \esc_html__( 'The author&#8217;s name.', 'activitypub' ) . '</dd>' . "\n" .
396 + '<dt><code>[ap_authorurl]</code></dt>' . "\n" .
397 + '<dd>' . \esc_html__( 'The URL to the author&#8217;s profile page.', 'activitypub' ) . '</dd>' . "\n" .
398 + '<dt><code>[ap_date]</code></dt>' . "\n" .
399 + '<dd>' . \esc_html__( 'The post&#8217;s date.', 'activitypub' ) . '</dd>' . "\n" .
400 + '<dt><code>[ap_time]</code></dt>' . "\n" .
401 + '<dd>' . \esc_html__( 'The post&#8217;s time.', 'activitypub' ) . '</dd>' . "\n" .
402 + '<dt><code>[ap_datetime]</code></dt>' . "\n" .
403 + '<dd>' . \esc_html__( 'The post&#8217;s date/time formated as "date @ time".', 'activitypub' ) . '</dd>' . "\n" .
404 + '<dt><code>[ap_blogurl]</code></dt>' . "\n" .
405 + '<dd>' . \esc_html__( 'The URL to the site.', 'activitypub' ) . '</dd>' . "\n" .
406 + '<dt><code>[ap_blogname]</code></dt>' . "\n" .
407 + '<dd>' . \esc_html__( 'The name of the site.', 'activitypub' ) . '</dd>' . "\n" .
408 + '<dt><code>[ap_blogdesc]</code></dt>' . "\n" .
409 + '<dd>' . \esc_html__( 'The description of the site.', 'activitypub' ) . '</dd>' . "\n" .
410 + '</dl>' . "\n" .
411 + '<p>' . \esc_html__( 'You may also use any Shortcode normally available to you on your site, however be aware that Shortcodes may significantly increase the size of your content depending on what they do.', 'activitypub' ) . '</p>' . "\n" .
412 + '<p>' . \esc_html__( 'Note: the old Template Tags are now deprecated and automatically converted to the new ones.', 'activitypub' ) . '</p>' . "\n" .
413 + '<p>' . \wp_kses( \__( '<a href="https://github.com/automattic/wordpress-activitypub/issues/new" target="_blank">Let us know</a> if you miss a Template Tag.', 'activitypub' ), $anchor_html ) . '</p>',
157 414 )
158 415 );
159 416
160 - // Editor Blocks.
161 417 \get_current_screen()->add_help_tab(
162 418 array(
163 - 'id' => 'editor-blocks',
164 - 'title' => \__( 'Editor Blocks', 'activitypub' ),
165 - 'content' => self::get_help_tab_template( 'editor-blocks' ),
166 - )
167 - );
168 -
169 - // Account Migration.
170 - \get_current_screen()->add_help_tab(
171 - array(
172 419 'id' => 'account-migration',
173 420 'title' => \__( 'Account Migration', 'activitypub' ),
174 - 'content' => self::get_help_tab_template( 'account-migration' ),
421 + 'content' =>
422 + '<h2>' . \esc_html__( 'Migrating Between Mastodon and WordPress', 'activitypub' ) . '</h2>' . "\n" .
423 + '<p>' . \esc_html__( 'The ActivityPub plugin allows you to migrate your account between WordPress and Mastodon (or other ActivityPub-compatible platforms) while bringing your followers with you.', 'activitypub' ) . '</p>' . "\n" .
424 +
425 + '<h3>' . \esc_html__( 'Migrating from Mastodon to WordPress', 'activitypub' ) . '</h3>' . "\n" .
426 + '<ol>' . "\n" .
427 + '<li>' . \wp_kses(
428 + \sprintf(
429 + /* translators: %s is the URL to the profile page */
430 + \__( 'In your WordPress profile, go to the <a href="%s">Account Aliases</a> section and add your Mastodon profile URL (e.g., <code>https://mastodon.social/@username</code>).', 'activitypub' ),
431 + \esc_url( \admin_url( 'profile.php#activitypub_blog_user_also_known_as' ) )
432 + ),
433 + array_merge( $code_html, $anchor_html )
434 + ) . '</li>' . "\n" .
435 + '<li>' . \esc_html__( 'Save your WordPress profile changes.', 'activitypub' ) . '</li>' . "\n" .
436 + '<li>' . \esc_html__( 'Log in to your Mastodon account.', 'activitypub' ) . '</li>' . "\n" .
437 + '<li>' . \esc_html__( 'Go to Preferences > Account > Move to a different account.', 'activitypub' ) . '</li>' . "\n" .
438 + '<li>' . \wp_kses(
439 + \sprintf(
440 + /* translators: %s is the user's ActivityPub username */
441 + \__( 'Enter your WordPress ActivityPub username (e.g., <code>%s</code>) in the "Handle of the new account" field.', 'activitypub' ),
442 + \esc_html( $webfinger )
443 + ),
444 + $code_html
445 + ) . '</li>' . "\n" .
446 + '<li>' . \esc_html__( 'Confirm the migration in Mastodon by entering your password.', 'activitypub' ) . '</li>' . "\n" .
447 + '<li>' . \esc_html__( 'Your followers will be notified and redirected to follow your WordPress account.', 'activitypub' ) . '</li>' . "\n" .
448 + '</ol>' . "\n",
175 449 )
176 450 );
177 451
178 - // Show only if templating is enabled.
179 - $object_type = \get_option( 'activitypub_object_type', ACTIVITYPUB_DEFAULT_OBJECT_TYPE );
180 - if ( 'note' === $object_type ) {
181 - // Template Tags.
182 - \get_current_screen()->add_help_tab(
183 - array(
184 - 'id' => 'template-tags',
185 - 'title' => \__( 'Template Tags', 'activitypub' ),
186 - 'content' => self::get_help_tab_template( 'template-tags' ),
187 - )
188 - );
189 - }
452 + /* translators: %s: Link to more information */
453 + $info_string = \esc_html__( 'For more information please visit %s.', 'activitypub' );
190 454
191 - // Recommended Plugins.
192 - if ( ! empty( self::get_recommended_plugins() ) ) {
193 - \get_current_screen()->add_help_tab(
194 - array(
195 - 'id' => 'recommended-plugins',
196 - 'title' => __( 'Recommended Plugins', 'activitypub' ),
197 - 'content' =>
198 - '<h2>' . esc_html__( 'Supercharge Your Fediverse Experience', 'activitypub' ) . '</h2>' .
199 - '<p>' . esc_html__( 'Enhance your WordPress ActivityPub setup with these hand-picked plugins, each adding unique capabilities for a richer Fediverse experience.', 'activitypub' ) . '</p>' .
200 - self::render_recommended_plugins_list(),
201 - )
202 - );
203 - }
204 -
205 - // Troubleshooting.
206 455 \get_current_screen()->add_help_tab(
207 456 array(
208 - 'id' => 'troubleshooting',
209 - 'title' => \__( 'Troubleshooting', 'activitypub' ),
210 - 'content' => self::get_help_tab_template( 'troubleshooting' ),
211 - )
212 - );
213 -
214 - // Glossary.
215 - \get_current_screen()->add_help_tab(
216 - array(
217 457 'id' => 'glossary',
218 458 'title' => \__( 'Glossary', 'activitypub' ),
219 - 'content' => self::get_help_tab_template( 'glossary' ),
220 - )
221 - );
459 + 'content' =>
460 + '<h2>' . \esc_html__( 'Fediverse', 'activitypub' ) . '</h2>' . "\n" .
461 + '<p>' . \esc_html__( 'The Fediverse is a new word made of two words: "federation" + "universe"', 'activitypub' ) . '</p>' . "\n" .
462 + '<p>' . \esc_html__( 'It is a federated social network running on free open software on a myriad of computers across the globe. Many independent servers are interconnected and allow people to interact with one another. There&#8217;s no one central site: you choose a server to register. This ensures some decentralization and sovereignty of data. Fediverse (also called Fedi) has no built-in advertisements, no tricky algorithms, no one big corporation dictating the rules. Instead we have small cozy communities of like-minded people. Welcome!', 'activitypub' ) . '</p>' . "\n" .
463 + '<p>' . \sprintf( $info_string, '<a href="https://fediverse.party/" target="_blank">fediverse.party</a>' ) . '</p>' . "\n" .
222 464
223 - // Resources.
224 - \get_current_screen()->add_help_tab(
225 - array(
226 - 'id' => 'resources',
227 - 'title' => \__( 'Resources', 'activitypub' ),
228 - 'content' => self::get_help_tab_template( 'resources' ),
465 + '<h2>' . \esc_html__( 'ActivityPub', 'activitypub' ) . '</h2>' . "\n" .
466 + '<p>' . \esc_html__( 'ActivityPub is a decentralized social networking protocol based on the ActivityStreams 2.0 data format. ActivityPub is an official W3C recommended standard published by the W3C Social Web Working Group. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and subscribing to content.', 'activitypub' ) . '</p>' . "\n" .
467 +
468 + '<h2>' . \esc_html__( 'WebFinger', 'activitypub' ) . '</h2>' . "\n" .
469 + '<p>' . \esc_html__( 'WebFinger is used to discover information about people or other entities on the Internet that are identified by a URI using standard Hypertext Transfer Protocol (HTTP) methods over a secure transport. A WebFinger resource returns a JavaScript Object Notation (JSON) object describing the entity that is queried. The JSON object is referred to as the JSON Resource Descriptor (JRD).', 'activitypub' ) . '</p>' . "\n" .
470 + '<p>' . \esc_html__( 'For a person, the type of information that might be discoverable via WebFinger includes a personal profile address, identity service, telephone number, or preferred avatar. For other entities on the Internet, a WebFinger resource might return JRDs containing link relations that enable a client to discover, for example, that a printer can print in color on A4 paper, the physical location of a server, or other static information.', 'activitypub' ) . '</p>' . "\n" .
471 + '<p>' . \wp_kses( \__( 'On Mastodon [and other platforms], user profiles can be hosted either locally on the same website as yours, or remotely on a completely different website. The same username may be used on a different domain. Therefore, a Mastodon user&#8217;s full mention consists of both the username and the domain, in the form <code>@username@domain</code>. In practical terms, <code>@user@example.com</code> is not the same as <code>@user@example.org</code>. If the domain is not included, Mastodon will try to find a local user named <code>@username</code>. However, in order to deliver to someone over ActivityPub, the <code>@username@domain</code> mention is not enough – mentions must be translated to an HTTPS URI first, so that the remote actor&#8217;s inbox and outbox can be found. (This paragraph is copied from the <a href="https://docs.joinmastodon.org/spec/webfinger/" target="_blank">Mastodon Documentation</a>)', 'activitypub' ), array_merge( $code_html, $anchor_html ) ) . '</p>' . "\n" .
472 + '<p>' . \sprintf( $info_string, '<a href="https://webfinger.net/" target="_blank">webfinger.net</a>' ) . '</p>' . "\n" .
473 +
474 + '<h2>' . \esc_html__( 'NodeInfo', 'activitypub' ) . '</h2>' . "\n" .
475 + '<p>' . \esc_html__( 'NodeInfo is an effort to create a standardized way of exposing metadata about a server running one of the distributed social networks. The two key goals are being able to get better insights into the user base of distributed social networking and the ability to build tools that allow users to choose the best fitting software and server for their needs.', 'activitypub' ) . '</p>' . "\n" .
476 + '<p>' . \sprintf( $info_string, '<a href="http://nodeinfo.diaspora.software/" target="_blank">nodeinfo.diaspora.software</a>' ) . '</p>',
229 477 )
230 478 );
231 479
232 - // Enhanced Help Sidebar.
233 480 \get_current_screen()->set_help_sidebar(
234 481 '<p><strong>' . \__( 'For more information:', 'activitypub' ) . '</strong></p>' . "\n" .
235 - '<p><a href="https://wordpress.org/support/plugin/activitypub/">' . \esc_html__( 'Get support', 'activitypub' ) . '</a></p>' . "\n" .
236 - '<p><a href="https://github.com/Automattic/wordpress-activitypub/issues">' . \esc_html__( 'Report an issue', 'activitypub' ) . '</a></p>' . "\n" .
237 - '<p><a href="https://github.com/Automattic/wordpress-activitypub/tree/trunk/docs">' . \esc_html__( 'Documentation', 'activitypub' ) . '</a></p>' . "\n" .
238 - '<p><a href="https://github.com/Automattic/wordpress-activitypub/releases">' . \esc_html__( 'View latest changes', 'activitypub' ) . '</a></p>'
482 + '<p>' . \__( '<a href="https://wordpress.org/support/plugin/activitypub/">Get support</a>', 'activitypub' ) . '</p>' . "\n" .
483 + '<p>' . \__( '<a href="https://github.com/automattic/wordpress-activitypub/issues">Report an issue</a>', 'activitypub' ) . '</p>'
239 484 );
240 485 }
241 486
242 487 /**
243 - * Adds the ActivityPub help tab to the users page.
244 - */
245 - public static function add_following_help_tab() {
246 - \get_current_screen()->add_help_tab(
247 - array(
248 - 'id' => 'starter-kit',
249 - 'title' => \__( 'Starter Kits', 'activitypub' ),
250 - 'content' => \sprintf(
251 - '<h2>%s</h2>' .
252 - '<p>%s</p>' .
253 - '<p>%s</p>',
254 - \__( 'Starter Kits', 'activitypub' ),
255 - \__( 'Starter kits are curated lists of accounts that help you quickly build your fediverse network. Import a starter kit to automatically follow a collection of interesting accounts in specific topics or communities.', 'activitypub' ),
256 - // translators: %s: Importer URL.
257 - \wp_kses_post( \sprintf( \__( 'To import a starter kit, go to <strong>Tools &#8594; Import</strong> and look for <a href="%s">the &#8220;Starter Kit&#8221; option</a>.', 'activitypub' ), \admin_url( 'admin.php?import=starter-kit' ) ) )
258 - ),
259 - )
260 - );
261 - }
262 -
263 - /**
264 - * Adds the ActivityPub help tab to the users page.
265 - */
266 - public static function add_users_help_tab() {
267 - \get_current_screen()->add_help_tab(
268 - array(
269 - 'id' => 'activitypub',
270 - 'title' => \__( 'ActivityPub', 'activitypub' ),
271 - 'content' => self::get_help_tab_template( 'users' ),
272 - // Add to the end of the list.
273 - 'priority' => 20,
274 - )
275 - );
276 - }
277 -
278 - /**
279 488 * Handle 'welcome' query arg.
280 489 */
281 490 public static function handle_welcome_query_arg() {
282 491 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
@@ -289,167 +498,74 @@
289 498 }
290 499 }
291 500
292 501 /**
293 - * Handle switching from legacy template mode to automatic object type.
502 + * Add screen option.
294 503 *
295 - * @since 8.0.0
504 + * @param string $screen_settings The screen settings.
505 + * @param object $screen The screen object.
506 + *
507 + * @return string The screen settings.
296 508 */
297 - public static function handle_switch_object_type() {
298 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended
299 - if ( ! isset( $_GET['activitypub_update_object_type'] ) ) {
300 - return;
509 + public static function add_screen_option( $screen_settings, $screen ) {
510 + if ( 'settings_page_activitypub' !== $screen->id ) {
511 + return $screen_settings;
301 512 }
302 513
303 - \check_admin_referer( 'activitypub_switch_object_type' );
304 -
305 - if ( ! \current_user_can( 'manage_options' ) ) {
306 - return;
514 + // Verify screen options nonce.
515 + if ( isset( $_POST['screenoptionnonce'] ) ) {
516 + $nonce = \sanitize_text_field( \wp_unslash( $_POST['screenoptionnonce'] ) );
517 + if ( ! \wp_verify_nonce( $nonce, 'screen-options-nonce' ) ) {
518 + return $screen_settings;
519 + }
307 520 }
308 521
309 - \update_option( 'activitypub_object_type', ACTIVITYPUB_DEFAULT_OBJECT_TYPE );
310 -
311 - \wp_safe_redirect( \admin_url( 'options-general.php?page=activitypub&tab=settings' ) );
312 - exit;
313 - }
314 -
315 - /**
316 - * Returns an array of recommended plugins for ActivityPub.
317 - */
318 - public static function get_recommended_plugins() {
319 - $plugins = array();
320 -
321 - if ( ! \is_plugin_active( 'friends/friends.php' ) ) {
322 - $plugins['friends'] = array(
323 - 'slug' => 'friends',
324 - 'author' => 'Alex Kirk',
325 - 'author_url' => 'https://profiles.wordpress.org/akirk/',
326 - 'icon' => 'https://ps.w.org/friends/assets/icon-256x256.png',
327 - 'name' => \__( 'Friends', 'activitypub' ),
328 - 'description' => \__( 'Follow people on Mastodon or similar platforms and display their posts on your WordPress, making your site a true Fediverse instance.', 'activitypub' ),
329 - 'install_url' => \admin_url( 'plugin-install.php?tab=plugin-information&plugin=friends&TB_iframe=true' ),
330 - );
522 + if ( isset( $_POST['activitypub_show_welcome_tab'] ) ) {
523 + $welcome = \sanitize_text_field( \wp_unslash( $_POST['activitypub_show_welcome_tab'] ) );
524 + $welcome_checked = empty( $welcome ) ? 0 : 1;
525 + \update_user_meta( \get_current_user_id(), 'activitypub_show_welcome_tab', $welcome_checked );
331 526 }
332 527
333 - if ( ! \is_plugin_active( 'event-bridge-for-activitypub/event-bridge-for-activitypub.php' ) ) {
334 - $plugins['event_bridge'] = array(
335 - 'slug' => 'event-bridge-for-activitypub',
336 - 'author' => 'André Menrath',
337 - 'author_url' => 'https://profiles.wordpress.org/andremenrath/',
338 - 'icon' => 'https://ps.w.org/event-bridge-for-activitypub/assets/icon-256x256.gif',
339 - 'name' => \__( 'Event Bridge for ActivityPub', 'activitypub' ),
340 - 'description' => \__( 'Make your events discoverable and federate them across decentralized platforms like Mastodon or Gancio.', 'activitypub' ),
341 - 'install_url' => \admin_url( 'plugin-install.php?tab=plugin-information&plugin=event-bridge-for-activitypub&TB_iframe=true' ),
342 - );
528 + if ( isset( $_POST['activitypub_show_advanced_tab'] ) ) {
529 + $advanced_settings = \sanitize_text_field( \wp_unslash( $_POST['activitypub_show_advanced_tab'] ) );
530 + $advanced_settings_checked = empty( $advanced_settings ) ? 0 : 1;
531 + \update_user_meta( \get_current_user_id(), 'activitypub_show_advanced_tab', $advanced_settings_checked );
343 532 }
344 533
345 - if ( ! \is_plugin_active( 'enable-mastodon-apps/enable-mastodon-apps.php' ) ) {
346 - $plugins['enable_mastodon_apps'] = array(
347 - 'slug' => 'enable-mastodon-apps',
348 - 'author' => 'Alex Kirk',
349 - 'author_url' => 'https://profiles.wordpress.org/akirk/',
350 - 'icon' => 'https://ps.w.org/enable-mastodon-apps/assets/icon-256x256.png',
351 - 'name' => \__( 'Enable Mastodon Apps', 'activitypub' ),
352 - 'description' => \__( 'Allow Mastodon apps to interact with your WordPress site, letting you write posts from your favorite app.', 'activitypub' ),
353 - 'install_url' => \admin_url( 'plugin-install.php?tab=plugin-information&plugin=enable-mastodon-apps&TB_iframe=true' ),
354 - );
355 - }
534 + $screen_settings = '<fieldset>
535 + <legend class="screen-layout">' . \esc_html__( 'Settings Pages', 'activitypub' ) . '</legend>
536 + <p>
537 + ' . \esc_html__( 'Some settings pages can be shown or hidden by using the checkboxes.', 'activitypub' ) . '
538 + </p>
539 + <div class="metabox-prefs-container">
540 + <label for="activitypub_show_welcome_tab">
541 + <input name="activitypub_show_welcome_tab" type="hidden" value="0" />
542 + <input name="activitypub_show_welcome_tab" type="checkbox" id="activitypub_show_welcome_tab" value="1" ' . \checked( 1, \get_user_meta( \get_current_user_id(), 'activitypub_show_welcome_tab', true ), false ) . ' />
543 + ' . \esc_html__( 'Welcome Page', 'activitypub' ) . '
544 + </label>
545 + <label for="activitypub_show_advanced_tab">
546 + <input name="activitypub_show_advanced_tab" type="hidden" value="0" />
547 + <input name="activitypub_show_advanced_tab" type="checkbox" id="activitypub_show_advanced_tab" value="1" ' . \checked( 1, \get_user_meta( \get_current_user_id(), 'activitypub_show_advanced_tab', true ), false ) . ' />
548 + ' . \esc_html__( 'Advanced Settings', 'activitypub' ) . '
549 + </label>
550 + </div>
551 + </fieldset>';
356 552
357 - if ( ! \is_plugin_active( 'hum/hum.php' ) ) {
358 - $plugins['hum'] = array(
359 - 'slug' => 'hum',
360 - 'author' => 'Will Norris',
361 - 'author_url' => 'https://profiles.wordpress.org/willnorris/',
362 - 'icon' => 'https://s.w.org/plugins/geopattern-icon/hum.svg',
363 - 'name' => \__( 'Hum', 'activitypub' ),
364 - 'description' => \__( 'A personal URL shortener for WordPress, perfect for sharing short links on the Fediverse.', 'activitypub' ),
365 - 'install_url' => \admin_url( 'plugin-install.php?tab=plugin-information&plugin=hum&TB_iframe=true' ),
366 - );
367 - }
368 -
369 - if ( ! \is_plugin_active( 'webfinger/webfinger.php' ) ) {
370 - $plugins['webfinger'] = array(
371 - 'slug' => 'webfinger',
372 - 'author' => 'Matthias Pfefferle',
373 - 'author_url' => 'https://profiles.wordpress.org/pfefferle/',
374 - 'icon' => 'https://ps.w.org/webfinger/assets/icon-256x256.png',
375 - 'name' => \__( 'WebFinger', 'activitypub' ),
376 - 'description' => \__( 'WebFinger protocol support for better discovery and compatibility.', 'activitypub' ),
377 - 'install_url' => \admin_url( 'plugin-install.php?tab=plugin-information&plugin=webfinger&TB_iframe=true' ),
378 - );
379 - }
380 -
381 - if ( ! \is_plugin_active( 'nodeinfo/nodeinfo.php' ) ) {
382 - $plugins['nodeinfo'] = array(
383 - 'slug' => 'nodeinfo',
384 - 'author' => 'Matthias Pfefferle',
385 - 'author_url' => 'https://profiles.wordpress.org/pfefferle/',
386 - 'icon' => 'https://ps.w.org/nodeinfo/assets/icon-256x256.png',
387 - 'name' => \__( 'NodeInfo', 'activitypub' ),
388 - 'description' => \__( 'Advanced NodeInfo protocol support for better discovery and compatibility.', 'activitypub' ),
389 - 'install_url' => \admin_url( 'plugin-install.php?tab=plugin-information&plugin=nodeinfo&TB_iframe=true' ),
390 - );
391 - }
392 -
393 - return $plugins;
553 + return $screen_settings;
394 554 }
395 555
396 556 /**
397 - * Render recommended plugins as a beautiful, rich showcase for the help tab.
398 - */
399 - public static function render_recommended_plugins_list() {
400 - $plugins = self::get_recommended_plugins();
401 -
402 - \ob_start();
403 -
404 - echo '<div class="plugin-list widefat">';
405 -
406 - foreach ( $plugins as $plugin ) :
407 - ?>
408 - <div class="plugin-card plugin-card-<?php echo \esc_attr( $plugin['slug'] ); ?>">
409 - <div class="plugin-card-top">
410 - <div class="name column-name">
411 - <h3>
412 - <a href="<?php echo \esc_url( $plugin['install_url'] ); ?>" class="thickbox open-plugin-details-modal">
413 - <?php echo \esc_html( $plugin['name'] ); ?>
414 - <img src="<?php echo \esc_url( $plugin['icon'] ); ?>" class="plugin-icon" alt="">
415 - </a>
416 - </h3>
417 - </div>
418 - <div class="action-links">
419 - <ul class="plugin-action-buttons">
420 - <li>
421 - <a href="<?php echo \esc_url( $plugin['install_url'] ); ?>" class="button thickbox open-plugin-details-modal"><?php \esc_html_e( 'More Details', 'activitypub' ); ?></a>
422 - </li>
423 - </ul>
424 - </div>
425 - <div class="desc column-description">
426 - <p><?php echo \esc_html( $plugin['description'] ); ?></p>
427 - <p class="authors"> <cite>By <a href="<?php echo \esc_url( $plugin['author_url'] ); ?>"><?php echo \esc_html( $plugin['author'] ); ?></a></cite></p>
428 - </div>
429 - </div>
430 - </div>
431 - <?php
432 - endforeach;
433 -
434 - echo '</div>';
435 -
436 - return \ob_get_clean();
437 - }
438 -
439 - /**
440 - * Loads a help tab template.
557 + * Show the submit button on the screen options page.
441 558 *
442 - * @param string $template_name The template file name (without ".php").
443 - * @return string Rendered template output.
559 + * @param bool $show_submit Whether to show the submit button.
560 + * @param object $screen The screen object.
561 + *
562 + * @return bool Whether to show the submit button.
444 563 */
445 - private static function get_help_tab_template( $template_name ) {
446 - $template_path = ACTIVITYPUB_PLUGIN_DIR . 'templates/help-tab/' . $template_name . '.php';
447 - if ( ! file_exists( $template_path ) ) {
448 - return '';
564 + public static function screen_options_show_submit( $show_submit, $screen ) {
565 + if ( 'settings_page_activitypub' !== $screen->id ) {
566 + return $show_submit;
449 567 }
450 568
451 - ob_start();
452 - load_template( $template_path, false );
453 - return ob_get_clean();
569 + return true;
454 570 }
455 571 }