PluginProbe
ActivityPub / 9.0.1
ActivityPub v9.0.1
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / wp-admin / class-user-settings-fields.php

class-user-settings-fields.php in ActivityPub 9.0.1, at includes/wp-admin/class-user-settings-fields.php

573 lines 22.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ActivityPub User Settings Fields Handler.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\WP_Admin;
9
10 use Activitypub\Collection\Actors;
11 use Activitypub\Collection\Extra_Fields;
12 use Activitypub\Moderation;
13 use Activitypub\OAuth\Client;
14 use Activitypub\OAuth\Scope;
15 use Activitypub\OAuth\Token;
16
17 /**
18 * Class to handle all user settings fields and callbacks.
19 */
20 class User_Settings_Fields {
21 /**
22 * Initialize the settings fields.
23 */
24 public static function init() {
25 \add_action( 'load-profile.php', array( self::class, 'register_settings' ) );
26 }
27
28 /**
29 * Register all settings fields.
30 */
31 public static function register_settings() {
32 // Mark checklist item as done.
33 \update_option( 'activitypub_checklist_profile_setup_visited', '1' );
34
35 \add_settings_section(
36 'activitypub_user_profile',
37 \esc_html__( 'ActivityPub', 'activitypub' ),
38 array( self::class, 'section_description' ),
39 'activitypub_user_settings',
40 array(
41 'before_section' => '<section id="activitypub">',
42 'after_section' => '</section>',
43 )
44 );
45
46 \add_settings_field(
47 'activitypub_profile_url',
48 \esc_html__( 'Profile URL', 'activitypub' ),
49 array( self::class, 'profile_url_callback' ),
50 'activitypub_user_settings',
51 'activitypub_user_profile'
52 );
53
54 \add_settings_field(
55 'activitypub_description',
56 \esc_html__( 'Biography', 'activitypub' ),
57 array( self::class, 'description_callback' ),
58 'activitypub_user_settings',
59 'activitypub_user_profile',
60 array( 'label_for' => 'activitypub_description' )
61 );
62
63 \add_settings_field(
64 'activitypub_header_image',
65 \esc_html__( 'Header Image', 'activitypub' ),
66 array( self::class, 'header_image_callback' ),
67 'activitypub_user_settings',
68 'activitypub_user_profile',
69 array( 'label_for' => 'activitypub_header_image' )
70 );
71
72 \add_settings_field(
73 'activitypub_notifications',
74 \esc_html__( 'Email Notifications', 'activitypub' ),
75 array( self::class, 'notifications_callback' ),
76 'activitypub_user_settings',
77 'activitypub_user_profile'
78 );
79
80 \add_settings_field(
81 'activitypub_extra_fields',
82 \esc_html__( 'Extra Fields', 'activitypub' ),
83 array( self::class, 'extra_fields_callback' ),
84 'activitypub_user_settings',
85 'activitypub_user_profile'
86 );
87
88 \add_settings_field(
89 'activitypub_also_known_as',
90 \esc_html__( 'Account Aliases', 'activitypub' ),
91 array( self::class, 'also_known_as_callback' ),
92 'activitypub_user_settings',
93 'activitypub_user_profile',
94 array( 'label_for' => 'activitypub_also_known_as' )
95 );
96
97 \add_settings_field(
98 'activitypub_hide_social_graph',
99 \__( 'Followers and Followings', 'activitypub' ),
100 array( self::class, 'hide_followers_callback' ),
101 'activitypub_user_settings',
102 'activitypub_user_profile'
103 );
104
105 // Add moderation section.
106 \add_settings_section(
107 'activitypub_user_moderation',
108 \esc_html__( 'Moderation', 'activitypub' ),
109 array( self::class, 'moderation_section_description' ),
110 'activitypub_user_settings',
111 array(
112 'before_section' => '<section id="activitypub-moderation">',
113 'after_section' => '</section>',
114 )
115 );
116
117 \add_settings_field(
118 'activitypub_user_blocked_domains',
119 \esc_html__( 'Blocked Domains', 'activitypub' ),
120 array( self::class, 'blocked_domains_callback' ),
121 'activitypub_user_settings',
122 'activitypub_user_moderation'
123 );
124
125 \add_settings_field(
126 'activitypub_user_blocked_keywords',
127 \esc_html__( 'Blocked Keywords', 'activitypub' ),
128 array( self::class, 'blocked_keywords_callback' ),
129 'activitypub_user_settings',
130 'activitypub_user_moderation'
131 );
132 }
133
134 /**
135 * Section description callback.
136 */
137 public static function section_description() {
138 echo '<p>' . \esc_html__( 'Define what others can see on your public Fediverse profile and next to your posts. With a profile picture and a fully completed profile, you are more likely to gain interactions and followers.', 'activitypub' ) . '</p>';
139 echo '<p>' . \esc_html__( 'The ActivityPub plugin tries to take as much information as possible from your profile settings. However, the following settings are not supported by WordPress or should be adjusted independently of the WordPress settings.', 'activitypub' ) . '</p>';
140 }
141
142 /**
143 * Profile URL field callback.
144 */
145 public static function profile_url_callback() {
146 $user = Actors::get_by_id( \get_current_user_id() );
147 ?>
148 <p>
149 <?php
150 \printf(
151 // translators: 1: the webfinger resource, 2: the author URL.
152 \esc_html__( '%1$s or %2$s', 'activitypub' ),
153 '<code>' . \esc_html( $user->get_webfinger() ) . '</code>',
154 '<code>' . \esc_url( $user->get_url() ) . '</code>'
155 );
156 ?>
157 </p>
158 <p class="description">
159 <?php
160 \printf(
161 // translators: the webfinger resource.
162 \esc_html__( 'Follow "@%s" by searching for it on Mastodon, Friendica, etc.', 'activitypub' ),
163 \esc_html( $user->get_webfinger() )
164 );
165 ?>
166 </p>
167 <?php
168 }
169
170 /**
171 * Description field callback.
172 */
173 public static function description_callback() {
174 $description = \get_user_option( 'activitypub_description', \get_current_user_id() );
175 $placeholder = \get_user_meta( \get_current_user_id(), 'description', true );
176 ?>
177 <textarea name="activitypub_description" id="activitypub_description" rows="5" cols="30" placeholder="<?php echo \esc_attr( $placeholder ); ?>"><?php echo \esc_html( $description ); ?></textarea>
178 <p class="description"><?php \esc_html_e( 'If you wish to use different biographical info for the fediverse, enter your alternate bio here.', 'activitypub' ); ?></p>
179 <?php
180 }
181
182 /**
183 * Header image field callback.
184 */
185 public static function header_image_callback() {
186 $header_image = \get_user_option( 'activitypub_header_image', \get_current_user_id() );
187 $classes_for_upload_button = 'button upload-button button-add-media button-add-header-image';
188 $classes_for_update_button = 'button';
189 $classes_for_wrapper = '';
190
191 if ( (int) $header_image ) {
192 $classes_for_wrapper .= ' has-header-image';
193 $classes_for_button = $classes_for_update_button;
194 $classes_for_button_on_change = $classes_for_upload_button;
195 } else {
196 $classes_for_wrapper .= ' hidden';
197 $classes_for_button = $classes_for_upload_button;
198 $classes_for_button_on_change = $classes_for_update_button;
199 }
200 ?>
201 <div id="activitypub-header-image-preview-wrapper" class="<?php echo \esc_attr( $classes_for_wrapper ); ?>">
202 <img id="activitypub-header-image-preview" src="<?php echo \esc_url( \wp_get_attachment_url( $header_image ) ); ?>" style="max-width: 100%;" alt="" />
203 </div>
204 <button
205 type="button"
206 id="activitypub-choose-from-library-button"
207 class="<?php echo \esc_attr( $classes_for_button ); ?>"
208 data-alt-classes="<?php echo \esc_attr( $classes_for_button_on_change ); ?>"
209 data-choose-text="<?php \esc_attr_e( 'Choose a Header Image', 'activitypub' ); ?>"
210 data-update-text="<?php \esc_attr_e( 'Change Header Image', 'activitypub' ); ?>"
211 data-update="<?php \esc_attr_e( 'Set as Header Image', 'activitypub' ); ?>"
212 data-width="1500"
213 data-height="500"
214 <?php
215 if ( ! \current_user_can( 'edit_others_posts' ) ) :
216 \printf( 'data-user-id="%s"', \esc_attr( \get_current_user_id() ) );
217 endif;
218 ?>
219 data-state="<?php echo \esc_attr( (int) $header_image ); ?>">
220 <?php echo (int) $header_image ? \esc_html__( 'Change Header Image', 'activitypub' ) : \esc_html__( 'Choose a Header Image', 'activitypub' ); ?>
221 </button>
222 <button
223 id="activitypub-remove-header-image"
224 type="button"
225 <?php echo (int) $header_image ? 'class="button button-secondary reset"' : 'class="button button-secondary reset hidden"'; ?>>
226 <?php \esc_html_e( 'Remove Header Image', 'activitypub' ); ?>
227 </button>
228 <input type="hidden" name="activitypub_header_image" id="activitypub_header_image" value="<?php echo \esc_attr( $header_image ); ?>">
229 <?php
230 }
231
232 /**
233 * Notifications field callback.
234 */
235 public static function notifications_callback() {
236 ?>
237 <fieldset id="activitypub-notifications">
238 <p>
239 <label>
240 <input type="checkbox" name="activitypub_mailer_new_follower" id="activitypub_mailer_new_follower" value="1" <?php \checked( 1, \get_user_option( 'activitypub_mailer_new_follower' ) ); ?> />
241 <?php \esc_html_e( 'New Followers', 'activitypub' ); ?>
242 </label>
243 </p>
244 <p>
245 <label>
246 <input type="checkbox" name="activitypub_mailer_new_dm" id="activitypub_mailer_new_dm" value="1" <?php \checked( 1, \get_user_option( 'activitypub_mailer_new_dm' ) ); ?> />
247 <?php \esc_html_e( 'Direct Messages', 'activitypub' ); ?>
248 </label>
249 </p>
250 <p>
251 <label>
252 <input type="checkbox" name="activitypub_mailer_new_mention" id="activitypub_mailer_new_mention" value="1" <?php \checked( 1, \get_user_option( 'activitypub_mailer_new_mention' ) ); ?> />
253 <?php \esc_html_e( 'New Mentions', 'activitypub' ); ?>
254 </label>
255 </p>
256 <p>
257 <label>
258 <input type="checkbox" name="activitypub_mailer_annual_report" id="activitypub_mailer_annual_report" value="1" <?php \checked( 1, \get_user_option( 'activitypub_mailer_annual_report' ) ); ?> />
259 <?php \esc_html_e( 'Annual Report', 'activitypub' ); ?>
260 </label>
261 </p>
262 <p>
263 <label>
264 <input type="checkbox" name="activitypub_mailer_monthly_report" id="activitypub_mailer_monthly_report" value="1" <?php \checked( 1, \get_user_option( 'activitypub_mailer_monthly_report' ) ); ?> />
265 <?php \esc_html_e( 'Monthly Report', 'activitypub' ); ?>
266 </label>
267 </p>
268 </fieldset>
269 <?php
270 }
271
272 /**
273 * Extra fields callback.
274 */
275 public static function extra_fields_callback() {
276 $extra_fields = Extra_Fields::get_actor_fields( \get_current_user_id() );
277 ?>
278 <p class="description">
279 <?php \esc_html_e( 'Your homepage, social profiles, pronouns, age, anything you want.', 'activitypub' ); ?>
280 </p>
281
282 <?php if ( ! empty( $extra_fields ) ) : ?>
283 <table class="widefat striped activitypub-extra-fields" role="presentation" style="margin: 15px 0;">
284 <?php foreach ( $extra_fields as $extra_field ) : ?>
285 <tr>
286 <td><?php echo \esc_html( $extra_field->post_title ); ?></td>
287 <td><?php echo \wp_kses_post( \get_the_excerpt( $extra_field ) ); ?></td>
288 <td>
289 <a href="<?php echo \esc_url( \get_edit_post_link( $extra_field->ID ) ); ?>" class="button">
290 <?php \esc_html_e( 'Edit', 'activitypub' ); ?>
291 </a>
292 </td>
293 </tr>
294 <?php endforeach; ?>
295 </table>
296 <?php endif; ?>
297
298 <p class="extra-fields-nav">
299 <a href="<?php echo \esc_url( \admin_url( '/post-new.php?post_type=ap_extrafield' ) ); ?>" class="button">
300 <?php \esc_html_e( 'Add new', 'activitypub' ); ?>
301 </a>
302 <a href="<?php echo \esc_url( \admin_url( '/edit.php?post_type=ap_extrafield' ) ); ?>">
303 <?php \esc_html_e( 'Manage all', 'activitypub' ); ?>
304 </a>
305 </p>
306 <?php
307 }
308
309 /**
310 * Also Known As field callback.
311 */
312 public static function also_known_as_callback() {
313 $also_known_as = \get_user_option( 'activitypub_also_known_as', \get_current_user_id() );
314 ?>
315 <textarea
316 class="large-text"
317 name="activitypub_also_known_as"
318 id="activitypub_also_known_as"
319 rows="5"
320 ><?php echo \esc_textarea( implode( PHP_EOL, (array) $also_known_as ) ); ?></textarea>
321 <p class="description">
322 <?php \esc_html_e( 'If you&#8217;re moving from another account to this one, you&#8217;ll need to create an alias here first before transferring your followers. This step is safe, reversible, and doesn&#8217;t affect anything on its own. The migration itself is initiated from your old account.', 'activitypub' ); ?>
323 </p>
324 <p class="description">
325 <?php echo \wp_kses_post( \__( 'Enter one account per line. Profile links or usernames like <code>@username@example.com</code> are accepted and will be automatically normalized to the correct format.', 'activitypub' ) ); ?>
326 </p>
327 <?php
328 }
329
330 /**
331 * Moderation section description callback.
332 */
333 public static function moderation_section_description() {
334 echo '<p>' . \esc_html__( 'Configure personal blocks to filter ActivityPub content you don\'t want to see.', 'activitypub' ) . '</p>';
335 }
336
337 /**
338 * Blocked domains field callback.
339 */
340 public static function blocked_domains_callback() {
341 $user_id = \get_current_user_id();
342 $blocked_domains = Moderation::get_user_blocks( $user_id )['domains'];
343 ?>
344 <p class="description"><?php \esc_html_e( 'Block entire ActivityPub instances by domain name.', 'activitypub' ); ?></p>
345
346 <div class="activitypub-user-block-list" data-user-id="<?php echo \esc_attr( $user_id ); ?>">
347 <?php if ( ! empty( $blocked_domains ) ) : ?>
348 <table class="widefat striped activitypub-blocked-domain" role="presentation" style="max-width: 500px; margin: 15px 0;">
349 <?php foreach ( $blocked_domains as $domain ) : ?>
350 <tr>
351 <td><?php echo \esc_html( $domain ); ?></td>
352 <td style="width: 80px;">
353 <button type="button" class="button button-small remove-user-block-btn" data-type="domain" data-value="<?php echo \esc_attr( $domain ); ?>">
354 <?php \esc_html_e( 'Remove', 'activitypub' ); ?>
355 </button>
356 </td>
357 </tr>
358 <?php endforeach; ?>
359 </table>
360 <?php endif; ?>
361
362 <div class="add-user-block-form" style="display: flex; max-width: 500px; gap: 8px;">
363 <input type="text" class="regular-text" id="new_user_domain" placeholder="<?php \esc_attr_e( 'example.com', 'activitypub' ); ?>" style="flex: 1; min-width: 0;" />
364 <button type="button" class="button add-user-block-btn" data-type="domain" style="flex-shrink: 0; white-space: nowrap;">
365 <?php \esc_html_e( 'Add Block', 'activitypub' ); ?>
366 </button>
367 </div>
368 </div>
369 <?php
370 }
371
372 /**
373 * Blocked keywords field callback.
374 */
375 public static function blocked_keywords_callback() {
376 $user_id = \get_current_user_id();
377 $blocked_keywords = Moderation::get_user_blocks( $user_id )['keywords'];
378 ?>
379 <p class="description"><?php \esc_html_e( 'Block ActivityPub content containing specific keywords.', 'activitypub' ); ?></p>
380
381 <div class="activitypub-user-block-list" data-user-id="<?php echo \esc_attr( $user_id ); ?>">
382 <?php if ( ! empty( $blocked_keywords ) ) : ?>
383 <table class="widefat striped activitypub-blocked-keyword" role="presentation" style="max-width: 500px; margin: 15px 0;">
384 <?php foreach ( $blocked_keywords as $keyword ) : ?>
385 <tr>
386 <td><?php echo \esc_html( $keyword ); ?></td>
387 <td style="width: 80px;">
388 <button type="button" class="button button-small remove-user-block-btn" data-type="keyword" data-value="<?php echo \esc_attr( $keyword ); ?>">
389 <?php \esc_html_e( 'Remove', 'activitypub' ); ?>
390 </button>
391 </td>
392 </tr>
393 <?php endforeach; ?>
394 </table>
395 <?php endif; ?>
396
397 <div class="add-user-block-form" style="display: flex; max-width: 500px; gap: 8px;">
398 <input type="text" class="regular-text" id="new_user_keyword" placeholder="<?php \esc_attr_e( 'spam keyword', 'activitypub' ); ?>" style="flex: 1; min-width: 0;" />
399 <button type="button" class="button add-user-block-btn" data-type="keyword" style="flex-shrink: 0; white-space: nowrap;">
400 <?php \esc_html_e( 'Add Block', 'activitypub' ); ?>
401 </button>
402 </div>
403 </div>
404 <?php
405 }
406
407 /**
408 * Render the Connected Applications section on the profile page.
409 *
410 * Rendered as a standalone section (like core's Application Passwords),
411 * not through the Settings API.
412 *
413 * @since 8.1.0
414 */
415 public static function connected_apps_section() {
416 $tokens = Token::get_all_for_user( \get_current_user_id() );
417 $clients = Client::get_manually_registered();
418
419 ?>
420 <div class="activitypub-connected-apps hide-if-no-js" id="activitypub-connected-apps-section">
421 <h2><?php \esc_html_e( 'OAuth Applications', 'activitypub' ); ?></h2>
422 <p><?php \esc_html_e( 'Register OAuth applications to connect third-party clients to your account, or revoke access for existing ones.', 'activitypub' ); ?></p>
423
424 <div class="create-application-password form-wrap" id="activitypub-new-application">
425 <div class="form-field">
426 <label for="activitypub-new-app-name"><?php \esc_html_e( 'New Application Name', 'activitypub' ); ?></label>
427 <input type="text" size="30" id="activitypub-new-app-name" class="input" aria-required="true" spellcheck="false" />
428 </div>
429 <div class="form-field">
430 <label for="activitypub-new-app-redirect-uri"><?php \esc_html_e( 'Redirect URI', 'activitypub' ); ?></label>
431 <input type="url" size="30" id="activitypub-new-app-redirect-uri" class="input" aria-required="true" spellcheck="false" />
432 </div>
433 <button type="button" class="button button-secondary" id="activitypub-register-app">
434 <?php \esc_html_e( 'Register Application', 'activitypub' ); ?>
435 </button>
436 </div>
437
438 <div class="activitypub-registered-apps-wrapper" id="activitypub-registered-apps-wrapper" <?php echo empty( $clients ) ? 'style="display: none;"' : ''; ?>>
439 <h3><?php \esc_html_e( 'Registered Applications', 'activitypub' ); ?></h3>
440 <table class="wp-list-table widefat fixed striped table-view-list">
441 <thead>
442 <tr>
443 <th scope="col"><?php \esc_html_e( 'Name', 'activitypub' ); ?></th>
444 <th scope="col"><?php \esc_html_e( 'Redirect URI', 'activitypub' ); ?></th>
445 <th scope="col"><?php \esc_html_e( 'Created', 'activitypub' ); ?></th>
446 <th scope="col"><?php \esc_html_e( 'Delete', 'activitypub' ); ?></th>
447 </tr>
448 </thead>
449 <tbody id="activitypub-registered-apps-tbody">
450 <?php foreach ( $clients as $client ) : ?>
451 <?php
452 $redirect_uris = $client->get_redirect_uris();
453 $redirect_uri = ! empty( $redirect_uris ) ? $redirect_uris[0] : '&mdash;';
454 $post = \get_post( $client->get_post_id() );
455 $created = $post ? \date_i18n( \get_option( 'date_format' ), \strtotime( $post->post_date ) ) : '&mdash;';
456 ?>
457 <tr data-client-id="<?php echo \esc_attr( $client->get_client_id() ); ?>">
458 <td><?php echo \esc_html( $client->get_name() ); ?></td>
459 <td><?php echo \esc_html( $redirect_uri ); ?></td>
460 <td><?php echo \esc_html( $created ); ?></td>
461 <td>
462 <?php
463 \printf(
464 '<button type="button" class="button delete" aria-label="%1$s">%2$s</button>',
465 /* translators: %s: the application name */
466 \esc_attr( \sprintf( \__( 'Delete "%s"', 'activitypub' ), $client->get_name() ) ),
467 \esc_html__( 'Delete', 'activitypub' )
468 );
469 ?>
470 </td>
471 </tr>
472 <?php endforeach; ?>
473 </tbody>
474 <tfoot>
475 <tr>
476 <th scope="col"><?php \esc_html_e( 'Name', 'activitypub' ); ?></th>
477 <th scope="col"><?php \esc_html_e( 'Redirect URI', 'activitypub' ); ?></th>
478 <th scope="col"><?php \esc_html_e( 'Created', 'activitypub' ); ?></th>
479 <th scope="col"><?php \esc_html_e( 'Delete', 'activitypub' ); ?></th>
480 </tr>
481 </tfoot>
482 </table>
483 <div class="tablenav bottom">
484 <div class="alignright">
485 <button type="button" class="button delete" id="activitypub-delete-all-clients">
486 <?php \esc_html_e( 'Delete all registered applications', 'activitypub' ); ?>
487 </button>
488 </div>
489 </div>
490 </div>
491
492 <?php if ( ! empty( $tokens ) ) : ?>
493 <div class="activitypub-connected-apps-list-table-wrapper">
494 <h3><?php \esc_html_e( 'Active Tokens', 'activitypub' ); ?></h3>
495 <table class="wp-list-table widefat fixed striped table-view-list">
496 <thead>
497 <tr>
498 <th scope="col"><?php \esc_html_e( 'Name', 'activitypub' ); ?></th>
499 <th scope="col"><?php \esc_html_e( 'Scopes', 'activitypub' ); ?></th>
500 <th scope="col"><?php \esc_html_e( 'Created', 'activitypub' ); ?></th>
501 <th scope="col"><?php \esc_html_e( 'Last Used', 'activitypub' ); ?></th>
502 <th scope="col"><?php \esc_html_e( 'Revoke', 'activitypub' ); ?></th>
503 </tr>
504 </thead>
505 <tbody id="activitypub-connected-apps-tbody">
506 <?php foreach ( $tokens as $token ) : ?>
507 <?php
508 $client_id = $token['client_id'] ?? '';
509 $client = Client::get( $client_id );
510 $client_name = ! \is_wp_error( $client ) ? $client->get_name() : $client_id;
511 $scopes = isset( $token['scopes'] ) ? Scope::to_string( $token['scopes'] ) : '';
512 $created = ! empty( $token['created_at'] ) ? \date_i18n( \get_option( 'date_format' ), $token['created_at'] ) : '&mdash;';
513 $last_used = ! empty( $token['last_used_at'] ) ? \date_i18n( \get_option( 'date_format' ), $token['last_used_at'] ) : '&mdash;';
514 $meta_key = $token['meta_key'] ?? ''; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Not a DB query, just array key.
515 ?>
516 <tr data-meta-key="<?php echo \esc_attr( $meta_key ); ?>">
517 <td><?php echo \esc_html( $client_name ); ?></td>
518 <td><?php echo \esc_html( $scopes ); ?></td>
519 <td><?php echo \esc_html( $created ); ?></td>
520 <td><?php echo $last_used; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Contains only escaped date or &mdash; entity. ?></td>
521 <td>
522 <?php
523 \printf(
524 '<button type="button" class="button delete" aria-label="%1$s">%2$s</button>',
525 /* translators: %s: the application name */
526 \esc_attr( \sprintf( \__( 'Revoke "%s"', 'activitypub' ), $client_name ) ),
527 \esc_html__( 'Revoke', 'activitypub' )
528 );
529 ?>
530 </td>
531 </tr>
532 <?php endforeach; ?>
533 </tbody>
534 <tfoot>
535 <tr>
536 <th scope="col"><?php \esc_html_e( 'Name', 'activitypub' ); ?></th>
537 <th scope="col"><?php \esc_html_e( 'Scopes', 'activitypub' ); ?></th>
538 <th scope="col"><?php \esc_html_e( 'Created', 'activitypub' ); ?></th>
539 <th scope="col"><?php \esc_html_e( 'Last Used', 'activitypub' ); ?></th>
540 <th scope="col"><?php \esc_html_e( 'Revoke', 'activitypub' ); ?></th>
541 </tr>
542 </tfoot>
543 </table>
544 <div class="tablenav bottom">
545 <div class="alignright">
546 <button type="button" class="button delete" id="activitypub-revoke-all-tokens">
547 <?php \esc_html_e( 'Revoke all connected applications', 'activitypub' ); ?>
548 </button>
549 </div>
550 </div>
551 </div>
552 <?php endif; ?>
553 </div>
554 <?php
555 }
556
557 /**
558 * Hide Social Graph field callback.
559 */
560 public static function hide_followers_callback() {
561 $hide_followers = \get_user_option( 'activitypub_hide_social_graph', \get_current_user_id() );
562 ?>
563 <label>
564 <input type="checkbox" name="activitypub_hide_social_graph" id="activitypub_hide_social_graph" value="1" <?php \checked( '1', $hide_followers ); ?> />
565 <?php \esc_html_e( 'Hide Followers and Following on Profile', 'activitypub' ); ?>
566 </label>
567 <p class="description">
568 <?php esc_html_e( 'People you follow will still see that you follow them.', 'activitypub' ); ?>
569 </p>
570 <?php
571 }
572 }
573