Skip to content

Commit f29b8ac

Browse files
authored
Add option to hide followers and following lists (#2294)
1 parent 7796e3c commit f29b8ac

File tree

10 files changed

+207
-38
lines changed

10 files changed

+207
-38
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: added
3+
4+
Added a privacy option to hide followers and following lists from profiles while keeping follow relationships intact.

includes/class-activitypub.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,18 @@ public static function register_user_meta() {
234234
)
235235
);
236236

237+
\register_meta(
238+
'user',
239+
$blog_prefix . 'activitypub_hide_social_graph',
240+
array(
241+
'type' => 'integer',
242+
'description' => 'Hide Followers and Followings on Profile.',
243+
'single' => true,
244+
'default' => 0,
245+
'sanitize_callback' => 'absint',
246+
)
247+
);
248+
237249
\register_meta(
238250
'user',
239251
$blog_prefix . 'activitypub_old_host_data',

includes/collection/class-actors.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,4 +817,19 @@ public static function normalize_identifier( $actor ) {
817817
_deprecated_function( __METHOD__, '7.4.0', 'Remote_Actors::normalize_identifier' );
818818
return Remote_Actors::normalize_identifier( $actor );
819819
}
820+
821+
/**
822+
* Determine if social graph (followers and following) should be shown for a given user.
823+
*
824+
* @param int $user_id The user ID.
825+
*
826+
* @return bool True if social graph should be shown, false otherwise.
827+
*/
828+
public static function show_social_graph( $user_id ) {
829+
if ( self::BLOG_USER_ID === (int) $user_id ) {
830+
return ! (bool) \get_option( 'activitypub_hide_social_graph' );
831+
} else {
832+
return ! (bool) \get_user_option( 'activitypub_hide_social_graph', $user_id );
833+
}
834+
}
820835
}

includes/rest/class-followers-controller.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Activitypub\Rest;
99

10+
use Activitypub\Collection\Actors;
1011
use Activitypub\Collection\Followers;
1112
use Activitypub\Collection\Remote_Actors;
1213

@@ -98,12 +99,15 @@ public function get_items( $request ) {
9899
$data = Followers::get_followers_with_count( $user_id, $per_page, $page, array( 'order' => \ucwords( $order ) ) );
99100

100101
$response = array(
101-
'@context' => get_context(),
102-
'id' => get_rest_url_by_path( \sprintf( 'actors/%d/followers', $user_id ) ),
103-
'generator' => 'https://wordpress.org/?v=' . get_masked_wp_version(),
104-
'type' => 'OrderedCollection',
105-
'totalItems' => $data['total'],
106-
'orderedItems' => \array_filter(
102+
'@context' => get_context(),
103+
'id' => get_rest_url_by_path( \sprintf( 'actors/%d/followers', $user_id ) ),
104+
'generator' => 'https://wordpress.org/?v=' . get_masked_wp_version(),
105+
'type' => 'OrderedCollection',
106+
'totalItems' => $data['total'],
107+
);
108+
109+
if ( Actors::show_social_graph( $user_id ) ) {
110+
$response['orderedItems'] = \array_filter(
107111
\array_map(
108112
function ( $item ) use ( $context ) {
109113
if ( 'full' === $context ) {
@@ -117,8 +121,8 @@ function ( $item ) use ( $context ) {
117121
},
118122
$data['followers']
119123
)
120-
),
121-
);
124+
);
125+
}
122126

123127
$response = $this->prepare_collection_response( $response, $request );
124128
if ( \is_wp_error( $response ) ) {

includes/rest/class-following-controller.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,15 @@ public function get_items( $request ) {
104104
$data = Following::get_following_with_count( $user_id, $per_page, $page, array( 'order' => \ucwords( $order ) ) );
105105

106106
$response = array(
107-
'@context' => get_context(),
108-
'id' => get_rest_url_by_path( \sprintf( 'actors/%d/following', $user_id ) ),
109-
'generator' => 'https://wordpress.org/?v=' . get_masked_wp_version(),
110-
'type' => 'OrderedCollection',
111-
'totalItems' => $data['total'],
112-
'orderedItems' => \array_filter(
107+
'@context' => get_context(),
108+
'id' => get_rest_url_by_path( \sprintf( 'actors/%d/following', $user_id ) ),
109+
'generator' => 'https://wordpress.org/?v=' . get_masked_wp_version(),
110+
'type' => 'OrderedCollection',
111+
'totalItems' => $data['total'],
112+
);
113+
114+
if ( Actors::show_social_graph( $user_id ) ) {
115+
$response['orderedItems'] = \array_filter(
113116
\array_map(
114117
function ( $item ) use ( $context ) {
115118
if ( 'full' === $context ) {
@@ -123,8 +126,8 @@ function ( $item ) use ( $context ) {
123126
},
124127
$data['following']
125128
)
126-
),
127-
);
129+
);
130+
}
128131

129132
/**
130133
* Filter the list of following urls

includes/wp-admin/class-admin.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ public static function save_user_settings( $user_id ) {
245245

246246
// User options that have a default value and therefore can't be empty (Empty triggers the default value).
247247
$required_user_options = array(
248+
'activitypub_hide_social_graph',
248249
'activitypub_mailer_new_dm',
249250
'activitypub_mailer_new_follower',
250251
'activitypub_mailer_new_mention',

includes/wp-admin/class-blog-settings-fields.php

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class Blog_Settings_Fields {
1919
* Initialize the settings fields.
2020
*/
2121
public static function init() {
22-
add_action( 'load-settings_page_activitypub', array( self::class, 'register_settings' ) );
22+
\add_action( 'load-settings_page_activitypub', array( self::class, 'register_settings' ) );
2323
}
2424

2525
/**
@@ -31,41 +31,41 @@ public static function register_settings() {
3131
\update_option( 'activitypub_checklist_profile_setup_visited', '1' );
3232
}
3333

34-
add_settings_section(
34+
\add_settings_section(
3535
'activitypub_blog_profile',
36-
__( 'Blog Profile', 'activitypub' ),
36+
\__( 'Blog Profile', 'activitypub' ),
3737
'__return_empty_string',
3838
'activitypub_blog_settings'
3939
);
4040

41-
add_settings_field(
41+
\add_settings_field(
4242
'activitypub_blog_avatar',
43-
__( 'Manage Avatar', 'activitypub' ),
43+
\__( 'Manage Avatar', 'activitypub' ),
4444
array( self::class, 'avatar_callback' ),
4545
'activitypub_blog_settings',
4646
'activitypub_blog_profile'
4747
);
4848

49-
add_settings_field(
49+
\add_settings_field(
5050
'activitypub_header_image',
51-
__( 'Manage Header Image', 'activitypub' ),
51+
\__( 'Manage Header Image', 'activitypub' ),
5252
array( self::class, 'header_image_callback' ),
5353
'activitypub_blog_settings',
5454
'activitypub_blog_profile'
5555
);
5656

57-
add_settings_field(
57+
\add_settings_field(
5858
'activitypub_blog_identifier',
59-
__( 'Change Profile ID', 'activitypub' ),
59+
\__( 'Change Profile ID', 'activitypub' ),
6060
array( self::class, 'profile_id_callback' ),
6161
'activitypub_blog_settings',
6262
'activitypub_blog_profile',
6363
array( 'label_for' => 'activitypub_blog_identifier' )
6464
);
6565

66-
add_settings_field(
66+
\add_settings_field(
6767
'activitypub_blog_description',
68-
__( 'Change Description', 'activitypub' ),
68+
\__( 'Change Description', 'activitypub' ),
6969
array( self::class, 'description_callback' ),
7070
'activitypub_blog_settings',
7171
'activitypub_blog_profile',
@@ -80,38 +80,46 @@ public static function register_settings() {
8080
'activitypub_blog_profile'
8181
);
8282

83-
add_settings_field(
83+
\add_settings_field(
8484
'activitypub_extra_fields',
85-
__( 'Extra Fields', 'activitypub' ),
85+
\__( 'Extra Fields', 'activitypub' ),
8686
array( self::class, 'extra_fields_callback' ),
8787
'activitypub_blog_settings',
8888
'activitypub_blog_profile'
8989
);
9090

91-
add_settings_field(
91+
\add_settings_field(
9292
'activitypub_blog_user_also_known_as',
93-
__( 'Account Aliases', 'activitypub' ),
93+
\__( 'Account Aliases', 'activitypub' ),
9494
array( self::class, 'also_known_as_callback' ),
9595
'activitypub_blog_settings',
9696
'activitypub_blog_profile'
9797
);
98+
99+
\add_settings_field(
100+
'activitypub_hide_social_graph',
101+
\__( 'Followers and Followings', 'activitypub' ),
102+
array( self::class, 'hide_followers_callback' ),
103+
'activitypub_blog_settings',
104+
'activitypub_blog_profile'
105+
);
98106
}
99107

100108
/**
101109
* Avatar field callback.
102110
*/
103111
public static function avatar_callback() {
104112
?>
105-
<?php if ( has_site_icon() ) : ?>
106-
<p><img src="<?php echo esc_url( get_site_icon_url( 50 ) ); ?>" alt="" /></p>
113+
<?php if ( \has_site_icon() ) : ?>
114+
<p><img src="<?php echo \esc_url( \get_site_icon_url( 50 ) ); ?>" alt="" /></p>
107115
<?php endif; ?>
108116
<p class="description">
109117
<?php
110-
echo wp_kses(
118+
echo \wp_kses(
111119
sprintf(
112120
// translators: %s is a URL.
113-
__( 'The ActivityPub plugin uses the WordPress Site Icon as Avatar for the Blog-Profile, you can change the Site Icon in the "<a href="%s">General Settings</a>" of WordPress.', 'activitypub' ),
114-
esc_url( admin_url( 'options-general.php' ) )
121+
\__( 'The ActivityPub plugin uses the WordPress Site Icon as Avatar for the Blog-Profile, you can change the Site Icon in the "<a href="%s">General Settings</a>" of WordPress.', 'activitypub' ),
122+
\esc_url( \admin_url( 'options-general.php' ) )
115123
),
116124
'default'
117125
);
@@ -295,11 +303,26 @@ class="large-text"
295303
><?php echo esc_textarea( implode( PHP_EOL, (array) $also_known_as ) ); ?></textarea>
296304
</label>
297305
<p class="description">
298-
<?php esc_html_e( 'If youre moving from another account to this one, youll need to create an alias here first before transferring your followers. This step is safe, reversible, and doesn’t affect anything on its own. The migration itself is initiated from your old account.', 'activitypub' ); ?>
306+
<?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’t affect anything on its own. The migration itself is initiated from your old account.', 'activitypub' ); ?>
299307
</p>
300308
<p class="description">
301309
<?php echo \wp_kses_post( \__( 'Enter one account per line. Profile links or usernames like <code>@[email protected]</code> are accepted and will be automatically normalized to the correct format.', 'activitypub' ) ); ?>
302310
</p>
303311
<?php
304312
}
313+
314+
/**
315+
* Hide Social Graph field callback.
316+
*/
317+
public static function hide_followers_callback() {
318+
?>
319+
<label>
320+
<input type="checkbox" name="activitypub_hide_social_graph" id="activitypub_hide_social_graph" value="1" <?php \checked( '1', \get_option( 'activitypub_hide_social_graph', '0' ) ); ?> />
321+
<?php \esc_html_e( 'Hide Followers and Following on Profile', 'activitypub' ); ?>
322+
</label>
323+
<p class="description">
324+
<?php esc_html_e( 'People you follow will still see that you follow them.', 'activitypub' ); ?>
325+
</p>
326+
<?php
327+
}
305328
}

includes/wp-admin/class-settings.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,17 @@ public static function register_settings() {
336336
)
337337
);
338338

339+
\register_setting(
340+
'activitypub_blog',
341+
'activitypub_hide_social_graph',
342+
array(
343+
'type' => 'integer',
344+
'description' => 'Hide Followers and Followings on Profile.',
345+
'default' => 0,
346+
'sanitize_callback' => 'absint',
347+
)
348+
);
349+
339350
// Moderation settings.
340351
\register_setting(
341352
'activitypub',

includes/wp-admin/class-user-settings-fields.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class User_Settings_Fields {
1919
* Initialize the settings fields.
2020
*/
2121
public static function init() {
22-
add_action( 'load-profile.php', array( self::class, 'register_settings' ) );
22+
\add_action( 'load-profile.php', array( self::class, 'register_settings' ) );
2323
}
2424

2525
/**
@@ -91,6 +91,14 @@ public static function register_settings() {
9191
array( 'label_for' => 'activitypub_also_known_as' )
9292
);
9393

94+
\add_settings_field(
95+
'activitypub_hide_social_graph',
96+
\__( 'Followers and Followings', 'activitypub' ),
97+
array( self::class, 'hide_followers_callback' ),
98+
'activitypub_user_settings',
99+
'activitypub_user_profile'
100+
);
101+
94102
// Add moderation section.
95103
\add_settings_section(
96104
'activitypub_user_moderation',
@@ -380,4 +388,20 @@ public static function blocked_keywords_callback() {
380388
</div>
381389
<?php
382390
}
391+
392+
/**
393+
* Hide Social Graph field callback.
394+
*/
395+
public static function hide_followers_callback() {
396+
$hide_followers = \get_user_option( 'activitypub_hide_social_graph', \get_current_user_id() );
397+
?>
398+
<label>
399+
<input type="checkbox" name="activitypub_hide_social_graph" id="activitypub_hide_social_graph" value="1" <?php \checked( '1', $hide_followers ); ?> />
400+
<?php \esc_html_e( 'Hide Followers and Following on Profile', 'activitypub' ); ?>
401+
</label>
402+
<p class="description">
403+
<?php esc_html_e( 'People you follow will still see that you follow them.', 'activitypub' ); ?>
404+
</p>
405+
<?php
406+
}
383407
}

0 commit comments

Comments
 (0)