PluginProbe
Friends / 2.8.8
Friends v2.8.8
4.3.2 4.3.1 4.3.0 4.2.2 4.2.1 4.2.0 4.1.0 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.0 2.9.1 All 88 releases
friends / includes / class-admin.php

class-admin.php in Friends 2.8.8, at includes/class-admin.php

3,106 lines 107.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Friends Admin
4 *
5 * This contains the functions for the admin section.
6 *
7 * @package Friends
8 */
9
10 namespace Friends;
11
12 /**
13 * This is the class for the Friends Plugin Admin section.
14 *
15 * @since 0.6
16 *
17 * @package Friends
18 * @author Alex Kirk
19 */
20 class Admin {
21 /**
22 * Contains a reference to the Friends class.
23 *
24 * @var Friends
25 */
26 private $friends;
27
28 /**
29 * Constructor
30 *
31 * @param Friends $friends A reference to the Friends object.
32 */
33 public function __construct( Friends $friends ) {
34 $this->friends = $friends;
35 $this->register_hooks();
36 }
37
38 /**
39 * Register the WordPress hooks
40 */
41 private function register_hooks() {
42 add_action( 'admin_menu', array( $this, 'admin_menu' ) );
43 add_action( 'friends_own_site_menu_top', array( $this, 'friends_add_menu_open_friend_request' ), 10, 2 );
44 add_filter( 'users_list_table_query_args', array( $this, 'allow_role_multi_select' ) );
45 add_filter( 'user_row_actions', array( get_called_class(), 'user_row_actions' ), 10, 2 );
46 add_filter( 'handle_bulk_actions-users', array( $this, 'handle_bulk_friend_request_approval' ), 10, 3 );
47 add_filter( 'bulk_actions-users', array( $this, 'add_user_bulk_options' ) );
48 add_filter( 'manage_users_columns', array( $this, 'user_list_columns' ) );
49 add_filter( 'manage_users_custom_column', array( get_called_class(), 'user_list_custom_column' ), 10, 3 );
50 add_filter( 'the_title', array( $this, 'override_post_format_title' ), 10, 2 );
51 add_filter( 'get_edit_user_link', array( $this, 'admin_edit_user_link' ), 10, 2 );
52 add_action( 'admin_bar_menu', array( $this, 'admin_bar_friends_menu' ), 39 );
53 add_action( 'admin_bar_menu', array( $this, 'admin_bar_new_content' ), 71 );
54 add_action( 'wp_head', array( $this, 'admin_bar_mobile' ) );
55 add_action( 'current_screen', array( $this, 'register_help' ) );
56 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 39 );
57 add_action( 'gettext_with_context', array( $this->friends, 'translate_user_role' ), 10, 4 );
58 add_action( 'wp_ajax_friends_preview_rules', array( $this, 'ajax_preview_friend_rules' ) );
59 add_action( 'wp_ajax_friends_refresh_link_token', array( $this, 'ajax_refresh_link_token' ) );
60 add_action( 'wp_ajax_friends_fetch_feeds', array( $this, 'ajax_fetch_feeds' ) );
61 add_action( 'wp_ajax_friends_set_avatar', array( $this, 'ajax_set_avatar' ) );
62 add_action( 'delete_user_form', array( $this, 'delete_user_form' ), 10, 2 );
63 add_action( 'delete_user', array( $this, 'delete_user' ) );
64 add_action( 'remove_user_from_blog', array( $this, 'delete_user' ) );
65 add_action( 'tool_box', array( $this, 'toolbox_bookmarklets' ) );
66 add_action( 'dashboard_glance_items', array( $this, 'dashboard_glance_items' ) );
67 add_filter( 'site_status_tests', array( $this, 'site_status_tests' ) );
68 add_filter( 'site_status_test_php_modules', array( $this, 'site_status_test_php_modules' ) );
69 add_filter( 'debug_information', array( $this, 'site_health_debug' ) );
70 add_filter( 'friends_create_and_follow', array( $this, 'create_and_follow' ), 10, 4 );
71 add_filter( 'friends_admin_tabs', array( $this, 'maybe_remove_friendship_settings' ) );
72
73 if ( ! get_option( 'permalink_structure' ) ) {
74 add_action( 'admin_notices', array( $this, 'admin_notice_unsupported_permalink_structure' ) );
75 }
76 add_filter( 'friends_unread_count', array( $this, 'friends_unread_friend_request_count' ) );
77 }
78
79 /**
80 * Display admin notice about an unsupported permalink structure
81 */
82 public function admin_notice_unsupported_permalink_structure() {
83 $screen = get_current_screen();
84
85 if ( 'plugins' !== $screen->id ) {
86 return;
87 }
88
89 ?>
90 <div class="friends-notice notice notice-error">
91 <p style="max-width:800px;"><b><?php esc_html_e( 'Friends', 'friends' ); ?></b><?php esc_html_e( '&#151; You are running an unsupported permalink structure.', 'friends' ); ?></p>
92 <p style="max-width:800px;">
93 <?php
94 echo wp_kses_post(
95 sprintf(
96 // translators: 1: URL to permalink settings, 2: the name of the Permalink Settings page.
97 __( 'In order to be able to view the Friends page, you need to enable a custom permalink structure. Please go to <a href="%1$s">%2$s</a> and enable an option other than Plain.', 'friends' ),
98 admin_url( 'options-permalink.php' ),
99 __( 'Permalink Settings' ) // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
100 )
101 );
102 ?>
103 </p>
104 </div>
105 <?php
106 }
107
108 /**
109 * Registers the admin menus
110 */
111 public function admin_menu() {
112 if ( isset( $_REQUEST['rerun-activate'] ) && isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'friends-settings' ) ) {
113 Friends::activate_plugin();
114 wp_safe_redirect( add_query_arg( array( 'reran-activation' => 'friends' ), wp_get_referer() ) );
115 exit;
116 }
117 $required_role = Friends::required_menu_role();
118 $unread_badge = $this->get_unread_badge();
119
120 $menu_title = __( 'Friends', 'friends' ) . $unread_badge;
121 $page_type = sanitize_title( $menu_title );
122 add_menu_page( 'friends', $menu_title, $required_role, 'friends', null, 'dashicons-groups', 3 );
123 // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
124 add_submenu_page( 'friends', __( 'Home' ), __( 'Home' ), $required_role, 'friends', array( $this, 'render_admin_home' ) );
125 add_action( 'load-' . $page_type . '_page_friends-page', array( $this, 'redirect_to_friends_page' ) );
126 add_submenu_page( 'friends', __( 'Add New Friend', 'friends' ), __( 'Add New Friend', 'friends' ), $required_role, 'add-friend', array( $this, 'render_admin_add_friend' ) );
127 // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
128 add_submenu_page( 'friends', __( 'Settings' ), __( 'Settings' ), $required_role, 'friends-settings', array( $this, 'render_admin_settings' ) );
129 if (
130 isset( $_GET['page'] ) &&
131 in_array(
132 $_GET['page'],
133 apply_filters( 'friends_admin_settings_slugs', array( 'friends-settings', 'friends-notification-manager', 'friends-wp-friendships', 'friends-import-export' ) )
134 )
135 ) {
136 add_submenu_page( 'friends', __( 'Notification Manager', 'friends' ), '- ' . __( 'Notification Manager', 'friends' ), $required_role, 'friends-notification-manager', array( $this, 'render_admin_notification_manager' ) );
137 add_submenu_page( 'friends', __( 'Friendships', 'friends' ), '- ' . __( 'Friendships', 'friends' ), $required_role, 'friends-wp-friendships', array( $this, 'render_admin_wp_friendship_settings' ) );
138 add_submenu_page( 'friends', __( 'Import/Export', 'friends' ), '- ' . __( 'Import/Export', 'friends' ), $required_role, 'friends-import-export', array( $this, 'render_admin_import_export' ) );
139 do_action( 'friends_admin_menu_settings', $page_type );
140 }
141 add_action( 'load-' . $page_type . '_page_friends-notification-manager', array( $this, 'process_admin_notification_manager' ) );
142 add_action( 'load-' . $page_type . '_page_friends-import-export', array( $this, 'process_admin_import_export' ) );
143 add_action( 'load-' . $page_type . '_page_friends-settings', array( $this, 'process_admin_settings' ) );
144 if ( get_option( 'friends_enable_wp_friendships' ) ) {
145 add_action( 'load-' . $page_type . '_page_friends-wp-friendships', array( $this, 'process_admin_wp_friendship_settings' ) );
146 }
147
148 add_submenu_page( 'friends', __( 'Friends &amp; Requests', 'friends' ), __( 'Friends &amp; Requests', 'friends' ), $required_role, 'friends-list', array( $this, 'render_friends_list' ) );
149
150 if ( $this->friends_unread_friend_request_count( 0 ) > 0 ) {
151 add_submenu_page( 'friends', __( 'Friend Requests', 'friends' ), __( 'Friend Requests', 'friends' ) . $unread_badge, $required_role, 'friends-list-requests', array( $this, 'render_friends_list' ) );
152 } elseif ( isset( $_GET['page'] ) && 'friends-list-requests' === $_GET['page'] ) {
153 // Don't show a no permission page but redirect to the friends list.
154 add_submenu_page( 'friends', __( 'Friend Requests', 'friends' ), __( 'Friend Requests', 'friends' ) . $unread_badge, $required_role, 'friends-list-requests', array( $this, 'render_friends_list' ) );
155 }
156
157 if ( isset( $_GET['page'] ) && 'friends-refresh' === $_GET['page'] ) {
158 add_submenu_page( 'friends', __( 'Refresh', 'friends' ), __( 'Refresh', 'friends' ), $required_role, 'friends-refresh', array( $this, 'admin_refresh_friend_posts' ) );
159 }
160
161 // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
162 add_submenu_page( 'friends', __( 'Plugins' ), __( 'Plugins' ), $required_role, 'friends-plugins', array( $this, 'admin_plugin_installer' ) );
163
164 if ( isset( $_GET['page'] ) && 0 === strpos( $_GET['page'], 'edit-friend' ) ) {
165 add_submenu_page( 'friends', __( 'Edit User', 'friends' ), __( 'Edit User', 'friends' ), $required_role, 'edit-friend' . ( 'edit-friend' !== $_GET['page'] && isset( $_GET['user'] ) ? '&user=' . $_GET['user'] : '' ), array( $this, 'render_admin_edit_friend' ) );
166 add_submenu_page( 'friends', __( 'Edit Feeds', 'friends' ), __( 'Edit Feeds', 'friends' ), $required_role, 'edit-friend-feeds' . ( 'edit-friend-feeds' !== $_GET['page'] && isset( $_GET['user'] ) ? '&user=' . $_GET['user'] : '' ), array( $this, 'render_admin_edit_friend_feeds' ) );
167 add_submenu_page( 'friends', __( 'Edit Notifications', 'friends' ), __( 'Edit Notifications', 'friends' ), $required_role, 'edit-friend-notifications' . ( 'edit-friend-notifications' !== $_GET['page'] && isset( $_GET['user'] ) ? '&user=' . $_GET['user'] : '' ), array( $this, 'render_admin_edit_friend_notifications' ) );
168 add_submenu_page( 'friends', __( 'Edit Rules', 'friends' ), __( 'Edit Rules', 'friends' ), $required_role, 'edit-friend-rules' . ( 'edit-friend-rules' !== $_GET['page'] && isset( $_GET['user'] ) ? '&user=' . $_GET['user'] : '' ), array( $this, 'render_admin_edit_friend_rules' ) );
169 add_action( 'load-' . $page_type . '_page_edit-friend', array( $this, 'process_admin_edit_friend' ) );
170 add_action( 'load-' . $page_type . '_page_edit-friend-feeds', array( $this, 'process_admin_edit_friend_feeds' ) );
171 add_action( 'load-' . $page_type . '_page_edit-friend-notifications', array( $this, 'process_admin_edit_friend_notifications' ) );
172 add_action( 'load-' . $page_type . '_page_edit-friend-rules', array( $this, 'process_admin_edit_friend_rules' ) );
173 }
174
175 if ( isset( $_GET['page'] ) && 'unfriend' === $_GET['page'] ) {
176 $user = new User( $_GET['user'] );
177 if ( $user ) {
178 $title = /* translators: %s is a username. */ sprintf( __( 'Unfriend %s', 'friends' ), $user->user_login );
179 add_submenu_page( 'friends', $title, $title, $required_role, 'unfriend', array( $this, 'render_admin_unfriend' ) );
180 add_action( 'load-' . $page_type . '_page_unfriend', array( $this, 'process_admin_unfriend' ) );
181 }
182 }
183 }
184
185 /**
186 * Allow making use of the role__in query.
187 *
188 * @param array $args The arguments.
189 *
190 * @return array The modified array.
191 */
192 public function allow_role_multi_select( $args ) {
193 if ( isset( $args['role'] ) && ! isset( $args['role__in'] ) ) {
194 if ( false !== strpos( $args['role'], ',' ) ) {
195 $args['role__in'] = explode( ',', $args['role'] );
196 unset( $args['role'] );
197 }
198
199 $roles = self::get_associated_roles();
200 if (
201 ( isset( $args['role__in'] ) && array_intersect( $args['role__in'], array_keys( $roles ) ) )
202 || ( isset( $args['role'] ) && isset( $roles[ $args['role'] ] ) )
203 ) {
204 add_action( 'admin_head-users.php', array( $this, 'keep_friends_open_on_users_screen' ) );
205 }
206 }
207 return $args;
208 }
209
210 /**
211 * Use JavaScript to keep the Friends menu open when responding to a Friend Request.
212 */
213 public function keep_friends_open_on_users_screen() {
214 ?>
215 <script type="text/javascript">
216 jQuery( document ).ready( function ( $ ) {
217 $( '#toplevel_page_friends-settings, #toplevel_page_friends-settings > a' ).addClass( 'wp-has-current-submenu wp-menu-open' ).removeClass( 'wp-not-current-submenu' );
218 $( '#menu-users > a' ).removeClass( 'wp-has-current-submenu wp-menu-open' );
219 $( "#toplevel_page_friends-settings ul li a[href='<?php echo esc_html( self::get_users_url() ); ?>']" ).closest( 'li' ).addClass( 'current' );
220 } );
221 </script>
222 <?php
223 }
224
225 /**
226 * Add our help information
227 *
228 * @param \WP_Screen $screen The current wp-admin screen.
229 */
230 public function register_help( $screen ) {
231 if ( ! ( $screen instanceof \WP_Screen ) ) {
232 return;
233 }
234
235 switch ( $screen->id ) {
236 case 'toplevel_page_friends-settings':
237 $screen->add_help_tab(
238 array(
239 'id' => 'overview',
240 'title' => __( 'Overview', 'friends' ),
241 'content' =>
242 '<p>' .
243 __( 'Welcome to the Friends Settings! You can configure the Friends plugin here to your liking.', 'friends' ) .
244 '</p>' .
245 '<p>' .
246 sprintf(
247 // translators: %1$s is a URL, %2$s is the name of a wp-admin screen.
248 __( 'There are more settings available for each friend or subscription individually. To get there, click on the user on the <a href=%1$s>%2$s</a> screen.', 'friends' ),
249 '"' . esc_attr( self_admin_url( self::get_users_url() ) ) . '"',
250 __( 'Friends &amp; Requests', 'friends' )
251 ) .
252 '</p>',
253 )
254 );
255 break;
256 case 'users':
257 $screen->add_help_tab(
258 array(
259 'id' => 'friends',
260 'title' => __( 'Friends', 'friends' ),
261 'content' => '<p>' . __( 'Here you can find your friends and subscriptions.', 'friends' ) . '</p><p>' . __( 'If you no longer want to be friends with someone or stop a subscription, you can simply delete that user.', 'friends' ) . '</p>',
262 )
263 );
264 break;
265 }
266 }
267
268 /**
269 * Reference our script for the /friends page
270 */
271 public function admin_enqueue_scripts() {
272 $handle = 'friends-admin';
273 $file = 'friends-admin.js';
274 $version = Friends::VERSION;
275 wp_enqueue_script( $handle, plugins_url( $file, FRIENDS_PLUGIN_FILE ), array( 'jquery' ), apply_filters( 'friends_debug_enqueue', $version, $handle, dirname( FRIENDS_PLUGIN_FILE ) . '/' . $file ) );
276
277 $variables = array(
278 'ajax_url' => admin_url( 'admin-ajax.php' ),
279 'add_friend_url' => self_admin_url( 'admin.php?page=add-friend' ),
280 'add_friend_text' => __( 'Add a Friend', 'friends' ),
281 'delete_feed_question' => __( 'Delete the feed? You need to click "Save Changes" to really delete it.', 'friends' ),
282 'role_friend' => __( 'Friend', 'friends' ),
283 'role_acquaintance' => __( 'Acquaintance', 'friends' ),
284 'role_friend_request' => __( 'Friend Request', 'friends' ),
285 'role_pending_friend_request' => __( 'Pending Friend Request', 'friends' ),
286 'role_subscription' => __( 'Following', 'friends' ),
287 'role_connection' => __( 'Connection', 'friends' ),
288 'role_contact' => __( 'Contact', 'friends' ),
289 'role_connection_request' => __( 'Connection Request', 'friends' ),
290 'role_pending_connection_request' => __( 'Pending Connection Request', 'friends' ),
291 'role_following' => __( 'Following', 'friends' ),
292 );
293 wp_localize_script( 'friends-admin', 'friends', $variables );
294
295 $handle = 'friends-admin';
296 $file = 'friends-admin.css';
297 $version = Friends::VERSION;
298 wp_enqueue_style( $handle, plugins_url( $file, FRIENDS_PLUGIN_FILE ), array(), apply_filters( 'friends_debug_enqueue', $version, $handle, dirname( FRIENDS_PLUGIN_FILE ) . '/' . $file ) );
299 }
300
301 /**
302 * Admin menu to refresh the friend posts.
303 */
304 public function admin_refresh_friend_posts() {
305 ?>
306 <h1><?php esc_html_e( "Refreshing Your Friends' Posts", 'friends' ); ?></h1>
307 <?php
308
309 add_filter( 'notify_about_new_friend_post', '__return_false', 999 );
310
311 add_filter(
312 'friends_friend_private_feed_url',
313 function ( $feed_url, $friend_user ) {
314 // translators: %1s is the name of the friend, %2$s is the feed URL.
315 printf( __( 'Refreshing %1$s at %2$s', 'friends' ) . '<br/>', '<a href="' . esc_url( $friend_user->get_local_friends_page_url() ) . '">' . esc_html( $friend_user->user_login ) . '</a>', '<a href="' . esc_url( $feed_url ) . '">' . esc_html( $feed_url ) . '</a>' );
316 return $feed_url;
317 },
318 10,
319 2
320 );
321
322 add_action(
323 'friends_retrieved_new_posts',
324 function ( $user_feed, $new_posts, $modified_posts ) {
325 // translators: %s is the number of new posts found.
326 echo esc_html( sprintf( _n( 'Found %d new post.', 'Found %d new posts.', count( $new_posts ), 'friends' ), count( $new_posts ) ) );
327 ?>
328 <br />
329 <?php
330 // translators: %s is the number of modified posts.
331 echo esc_html( sprintf( _n( '%d post was modified.', '%d posts were modified.', count( $modified_posts ), 'friends' ), count( $modified_posts ) ) );
332 ?>
333 <br />
334 <?php
335 },
336 10,
337 3
338 );
339
340 add_action(
341 'friends_incoming_feed_items',
342 function ( $items ) {
343 // translators: %s is the number of posts found.
344 echo esc_html( sprintf( _n( 'Found %d item in the feed.', 'Found %d items in the feed.', count( $items ), 'friends' ) . ' ', count( $items ) ) );
345 }
346 );
347
348 add_action(
349 'friends_retrieve_friends_error',
350 function ( $user_feed, $error ) {
351 esc_html_e( 'An error occurred while retrieving the posts.', 'friends' );
352 echo esc_html( $error->get_error_message() ), '<br/>';
353 },
354 10,
355 2
356 );
357
358 if ( isset( $_GET['user'] ) ) {
359 $friend_user = User::get_by_username( $_GET['user'] );
360 if ( ! $friend_user || is_wp_error( $friend_user ) || ! $friend_user->can_refresh_feeds() ) {
361 wp_die( esc_html__( 'Invalid user ID.' ) ); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
362 }
363 $friend_user->retrieve_posts_from_active_feeds();
364 } else {
365 $this->friends->feed->retrieve_friend_posts();
366 }
367 }
368
369 /**
370 * Admin page for installing plugins.
371 */
372 public function admin_plugin_installer() {
373 Friends::template_loader()->get_template_part( 'admin/plugin-installer-header' );
374 Plugin_Installer::init();
375 Friends::template_loader()->get_template_part( 'admin/plugin-installer-footer' );
376 }
377
378 /**
379 * Send a friend request to another WordPress with the Friends plugin
380 *
381 * @param string $rest_url The site URL of the friend's
382 * WordPress.
383 * @param string $user_login The user login.
384 * @param string $user_url The user url.
385 * @param string $display_name The display name.
386 * @param string $codeword A codeword to send along.
387 * @param string $message A message to send along.
388 *
389 * @return \WP_User|\WP_error $user The new associated user or an error object.
390 */
391 public function send_friend_request( $rest_url, $user_login, $user_url, $display_name, $codeword = 'friends', $message = '' ) {
392 if ( ! is_string( $rest_url ) || ! Friends::check_url( $rest_url ) ) {
393 return new \WP_Error( 'invalid-url', __( 'You entered an invalid URL.', 'friends' ) );
394 }
395
396 $future_in_token = wp_generate_password( 128, false );
397
398 $current_user = wp_get_current_user();
399 $response = wp_safe_remote_post(
400 $rest_url . '/friend-request',
401 array(
402 'body' => array(
403 'version' => 2,
404 'codeword' => $codeword,
405 'name' => $current_user->display_name,
406 'url' => home_url(),
407 'icon_url' => get_avatar_url( $current_user->ID ),
408 'message' => mb_substr( trim( $message ), 0, 2000 ),
409 'key' => $future_in_token,
410 ),
411 'timeout' => 20,
412 'redirection' => 5,
413 )
414 );
415 if ( is_wp_error( $response ) ) {
416 return $response;
417 }
418
419 $json = json_decode( wp_remote_retrieve_body( $response ) );
420 if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
421 if ( $json && isset( $json->code ) && isset( $json->message ) ) {
422 // translators: %s is the message from the other server.
423 return new \WP_Error( $json->code, sprintf( __( 'The other side responded: %s', 'friends' ), $json->message ), $json->data );
424 }
425 }
426
427 if ( ! $json || ! is_object( $json ) ) {
428 return new \WP_Error( 'unexpected-rest-response', 'Unexpected remote response: ' . substr( wp_remote_retrieve_body( $response ), 0, 30 ), $response );
429 }
430
431 $friend_user = User::create( $user_login, 'pending_friend_request', $user_url, $display_name );
432 if ( is_wp_error( $friend_user ) ) {
433 return $friend_user;
434 }
435 $friend_user->update_user_option( 'friends_rest_url', $rest_url );
436
437 if ( isset( $json->request ) ) {
438 update_option( 'friends_request_' . sha1( $json->request ), $friend_user->ID );
439 $friend_user->update_user_option( 'friends_future_in_token_' . sha1( $json->request ), $future_in_token );
440 $friend_user->set_role( 'pending_friend_request' );
441 }
442
443 return $friend_user;
444 }
445
446 /**
447 * Don't show the edit link for friend posts
448 *
449 * @param string $link The edit link.
450 * @param int|User $user The user.
451 * @return string|bool The edit link or false.
452 */
453 public static function admin_edit_user_link( $link, $user ) {
454 if ( ! $user instanceof \WP_User ) {
455 if ( is_string( $user ) ) {
456 $user = User::get_by_username( $user );
457 } else {
458 $user = new \WP_User( $user );
459 }
460 }
461
462 if ( is_multisite() && is_super_admin( $user->ID ) ) {
463 return $link;
464 }
465 if ( ! $user->has_cap( 'friends_plugin' ) ) {
466 return $link;
467 }
468
469 return self_admin_url( 'admin.php?page=edit-friend&user=' . $user->user_login );
470 }
471
472 public static function get_edit_friend_link( $user ) {
473 if ( ! $user instanceof \WP_User ) {
474 $user = new \WP_User( $user );
475 }
476 return apply_filters( 'get_edit_user_link', $user->user_url, $user->user_login );
477 }
478
479 public static function get_unfriend_link( $user ) {
480 if ( ! $user->has_cap( 'friends_plugin' ) ) {
481 return '';
482 }
483
484 return wp_nonce_url( self_admin_url( 'admin.php?page=unfriend&user=' . $user->user_login ), 'unfriend_' . $user->user_login );
485 }
486
487 /**
488 * Redirect to the Friends page
489 */
490 public function redirect_to_friends_page() {
491 wp_safe_redirect( home_url( '/friends/' ) );
492 exit;
493 }
494
495 /**
496 * Check access for the Friends Admin settings page
497 */
498 public function check_admin_settings() {
499 if ( ! Friends::has_required_privileges() ) {
500 wp_die( esc_html__( 'Sorry, you are not allowed to change the settings.', 'friends' ) );
501 }
502 }
503
504 /**
505 * Process the Friends Admin settings page
506 */
507 public function process_admin_settings() {
508 if ( empty( $_REQUEST ) || ! isset( $_REQUEST['_wpnonce'] ) ) {
509 return;
510 }
511
512 if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'friends-settings' ) ) {
513 return;
514 }
515
516 $this->check_admin_settings();
517 foreach ( array( 'ignore_incoming_friend_requests', 'enable_wp_friendships' ) as $checkbox ) {
518 if ( isset( $_POST[ $checkbox ] ) && $_POST[ $checkbox ] ) {
519 update_option( 'friends_' . $checkbox, true );
520 } else {
521 delete_option( 'friends_' . $checkbox );
522 }
523 }
524
525 foreach ( array( 'friend_request_notification' ) as $negative_user_checkbox ) {
526 if ( isset( $_POST[ $negative_user_checkbox ] ) && $_POST[ $negative_user_checkbox ] ) {
527 delete_user_option( get_current_user_id(), 'friends_no_' . $negative_user_checkbox );
528 } else {
529 update_user_option( get_current_user_id(), 'friends_no_' . $negative_user_checkbox, 1 );
530 }
531 }
532
533 if ( current_user_can( 'manage_options' ) ) {
534 foreach ( array( 'force_enable_post_formats', 'expose_post_format_feeds' ) as $checkbox ) {
535 if ( isset( $_POST[ $checkbox ] ) && $_POST[ $checkbox ] ) {
536 update_option( 'friends_' . $checkbox, true );
537 } else {
538 delete_option( 'friends_' . $checkbox );
539 }
540 }
541
542 if ( isset( $_POST['limit_homepage_post_format'] ) && $_POST['limit_homepage_post_format'] && in_array( $_POST['limit_homepage_post_format'], get_post_format_slugs() ) ) {
543 update_option( 'friends_limit_homepage_post_format', $_POST['limit_homepage_post_format'] );
544 } else {
545 delete_option( 'friends_limit_homepage_post_format' );
546 }
547 if ( isset( $_POST['blocks_everywhere'] ) && $_POST['blocks_everywhere'] ) {
548 update_user_option( get_current_user_id(), 'friends_blocks_everywhere', 1 );
549 } else {
550 delete_user_option( get_current_user_id(), 'friends_blocks_everywhere' );
551 }
552 }
553
554 if ( isset( $_POST['available_emojis'] ) && $_POST['available_emojis'] ) {
555 $available_emojis = array();
556 foreach ( $_POST['available_emojis'] as $id ) {
557 $data = Reactions::get_emoji_data( $id );
558 if ( $data ) {
559 $available_emojis[ $id ] = $data;
560 }
561 }
562 update_option( 'friends_selected_emojis', $available_emojis );
563 } else {
564 delete_option( 'friends_selected_emojis' );
565 }
566
567 // Global retention.
568 $retention_number_enabled = boolval( isset( $_POST['friends_enable_retention_number'] ) && $_POST['friends_enable_retention_number'] );
569 update_option( 'friends_enable_retention_number', $retention_number_enabled );
570 if ( $retention_number_enabled ) {
571 update_option( 'friends_retention_number', max( 1, intval( $_POST['friends_retention_number'] ) ) );
572 }
573 $retention_days_enabled = boolval( isset( $_POST['friends_enable_retention_days'] ) && $_POST['friends_enable_retention_days'] );
574 update_option( 'friends_enable_retention_days', $retention_days_enabled );
575 if ( $retention_days_enabled ) {
576 update_option( 'friends_retention_days', max( 1, intval( $_POST['friends_retention_days'] ) ) );
577 }
578
579 if ( isset( $_POST['frontend_default_view'] ) && in_array(
580 $_POST['frontend_default_view'],
581 array(
582 'collapsed',
583 )
584 ) ) {
585 update_option( 'friends_frontend_default_view', $_POST['frontend_default_view'] );
586 } else {
587 delete_option( 'friends_frontend_default_view' );
588 }
589
590 if ( isset( $_GET['_wp_http_referer'] ) ) {
591 wp_safe_redirect( wp_get_referer() );
592 } else {
593 wp_safe_redirect( add_query_arg( 'updated', '1', remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
594 }
595 exit;
596 }
597
598 /**
599 * Gets the frontend locale.
600 *
601 * @return string The frontend locale.
602 */
603 public function get_frontend_locale() {
604 $locale = get_option( 'WPLANG' );
605 return empty( $locale ) ? 'en_US' : $locale;
606 }
607
608 /**
609 * Render the Friends Admin home page
610 */
611 public function render_admin_home() {
612 $friends_subscriptions = User_Query::all_associated_users();
613 $has_friend_users = $friends_subscriptions->get_total() > 0;
614 wp_enqueue_script( 'plugin-install' );
615 add_thickbox();
616 wp_enqueue_script( 'updates' );
617
618 Friends::template_loader()->get_template_part(
619 'admin/settings-header',
620 null,
621 array(
622 'active' => 'friends',
623 'title' => __( 'Friends', 'friends' ),
624 )
625 );
626
627 Friends::template_loader()->get_template_part( 'admin/welcome', null, array( 'installed_plugins' => get_plugins() ) );
628
629 Friends::template_loader()->get_template_part( 'admin/settings-footer' );
630 }
631
632 /**
633 * Render the Friends Admin settings page
634 */
635 public function render_admin_settings() {
636 Friends::template_loader()->get_template_part(
637 'admin/settings-header',
638 null,
639 array(
640 'active' => 'friends-settings',
641 'title' => __( 'Friends', 'friends' ),
642 )
643 );
644 $this->check_admin_settings();
645
646 if ( isset( $_GET['updated'] ) ) {
647 ?>
648 <div id="message" class="updated notice is-dismissible"><p>
649 <?php
650 esc_html_e( 'Your settings were updated.', 'friends' );
651 ?>
652 </p></div>
653 <?php
654 }
655
656 $post_stats = Friends::get_post_stats();
657
658 Friends::template_loader()->get_template_part(
659 'admin/settings',
660 null,
661 array_merge(
662 Friends::get_post_stats(),
663 array(
664 'force_enable_post_formats' => get_option( 'friends_force_enable_post_formats' ),
665 'post_format_strings' => get_post_format_strings(),
666 'limit_homepage_post_format' => get_option( 'friends_limit_homepage_post_format', false ),
667 'expose_post_format_feeds' => get_option( 'friends_expose_post_format_feeds' ),
668 'enable_wp_friendships' => get_option( 'friends_enable_wp_friendships' ),
669 'retention_days' => Friends::get_retention_days(),
670 'retention_number' => Friends::get_retention_number(),
671 'retention_days_enabled' => get_option( 'friends_enable_retention_days' ),
672 'retention_number_enabled' => get_option( 'friends_enable_retention_number' ),
673 'frontend_default_view' => get_option( 'friends_frontend_default_view', 'expanded' ),
674 'blocks_everywhere' => get_user_option( 'friends_blocks_everywhere' ),
675 )
676 )
677 );
678
679 Friends::template_loader()->get_template_part( 'admin/settings-footer' );
680 }
681
682 /**
683 * Process access for the Friends Edit Rules page
684 */
685 private function check_admin_edit_friend_rules() {
686 if ( ! Friends::is_main_user() ) {
687 wp_die( esc_html__( 'Sorry, you are not allowed to edit the rules.', 'friends' ) );
688 }
689
690 if ( ! isset( $_GET['user'] ) ) {
691 wp_die( esc_html__( 'Invalid user.', 'friends' ) );
692 }
693
694 $friend = User::get_by_username( $_GET['user'] );
695 if ( ! $friend || is_wp_error( $friend ) ) {
696 wp_die( esc_html__( 'Invalid username.', 'friends' ) );
697 }
698
699 if (
700 ! $friend->has_cap( 'friend_request' ) &&
701 ! $friend->has_cap( 'pending_friend_request' ) &&
702 ! $friend->has_cap( 'friend' ) &&
703 ! $friend->has_cap( 'subscription' )
704 ) {
705 wp_die( esc_html__( 'This is not a user related to this plugin.', 'friends' ) );
706 }
707
708 return $friend;
709 }
710
711 /**
712 * Process the Friends Edit Rules page
713 */
714 public function process_admin_edit_friend_rules() {
715 $friend = $this->check_admin_edit_friend_rules();
716 $arg = 'updated';
717 $arg_value = 1;
718 if ( isset( $_POST['friend-rules-raw'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'friend-rules-raw-' . $friend->user_login ) ) {
719 $rules = $this->friends->feed->validate_feed_rules( json_decode( stripslashes( $_POST['rules'] ), true ) );
720 if ( false === $rules ) {
721 $arg = 'error';
722 } else {
723 $friend->update_user_option( 'friends_feed_rules', $rules );
724 }
725 } elseif ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'edit-friend-rules-' . $friend->user_login ) ) {
726 $friend->update_user_option( 'friends_feed_catch_all', $this->friends->feed->validate_feed_catch_all( $_POST['catch_all'] ) );
727 $friend->update_user_option( 'friends_feed_rules', $this->friends->feed->validate_feed_rules( $_POST['rules'] ) );
728 } else {
729 return;
730 }
731
732 if ( isset( $_GET['_wp_http_referer'] ) ) {
733 wp_safe_redirect( wp_get_referer() );
734 } else {
735 wp_safe_redirect( add_query_arg( $arg, $arg_value, remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
736 }
737 exit;
738 }
739
740 /**
741 * Render the Friends Edit Rules page
742 */
743 public function render_admin_edit_friend_rules() {
744 $friend = $this->check_admin_edit_friend_rules();
745 $catch_all = $friend->get_feed_catch_all();
746 $rules = $friend->get_feed_rules();
747
748 $this->header_edit_friend( $friend, 'edit-friend-rules' );
749
750 if ( isset( $_GET['updated'] ) ) {
751 ?>
752 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'Rules were updated.', 'friends' ); ?></p></div>
753 <?php
754 } elseif ( isset( $_GET['error'] ) ) {
755 ?>
756 <div id="message" class="updated error is-dismissible"><p><?php esc_html_e( 'An error occurred.', 'friends' ); ?></p></div>
757 <?php
758 }
759
760 $rules = array_values( $rules );
761 $rules[] = array(
762 'field' => 'title',
763 'regex' => '',
764 'action' => in_array( $catch_all, array( 'trash', 'delete' ), true ) ? 'accept' : 'trash',
765 'replace' => '',
766 );
767
768 if ( isset( $_GET['post'] ) && intval( $_GET['post'] ) ) {
769 $post = get_post( intval( $_GET['post'] ) );
770 } else {
771 $post = null;
772 }
773
774 $args = array(
775 'rules' => $rules,
776 'friend' => $friend,
777 'catch_all' => $catch_all,
778 'post' => $post,
779 );
780 Friends::template_loader()->get_template_part( 'admin/edit-rules', null, $args );
781
782 echo '<div id="preview-rules">';
783 $this->render_preview_friend_rules( $rules, $catch_all, $post );
784 echo '</div>';
785
786 array_pop( $args['rules'] );
787 Friends::template_loader()->get_template_part( 'admin/edit-raw-rules', null, $args );
788 }
789
790 /**
791 * Respond to the Ajax request to the Friend rules preview
792 */
793 public function ajax_preview_friend_rules() {
794 if ( ! Friends::has_required_privileges() ) {
795 wp_die( -1 );
796 }
797
798 if ( isset( $_GET['post'] ) && intval( $_GET['post'] ) ) {
799 $post = get_post( intval( $_GET['post'] ) );
800 } else {
801 $post = null;
802 }
803
804 $this->render_preview_friend_rules( $_POST['rules'], $_POST['catch_all'], $post );
805 wp_die( 1 );
806 }
807
808 /**
809 * Respond to the Ajax request to fetch feeds
810 */
811 public function ajax_fetch_feeds() {
812 if ( ! isset( $_POST['friend'] ) ) {
813 wp_send_json_error( 'missing-parameters' );
814 }
815 check_ajax_referer( 'fetch-feeds-' . $_POST['friend'] );
816
817 $friend_user = User::get_by_username( $_POST['friend'] );
818 if ( ! $friend_user ) {
819 wp_send_json_error( 'unknown-user' );
820 }
821
822 $friend_user->retrieve_posts_from_active_feeds();
823
824 wp_send_json_success();
825 }
826
827
828 /**
829 * Respond to the Ajax request to refresh the link token
830 */
831 public function ajax_refresh_link_token() {
832 if ( ! isset( $_POST['url'] ) || ! isset( $_POST['friend'] ) ) {
833 wp_send_json_error( 'missing-parameters' );
834 }
835 $url = $_POST['url'];
836 check_ajax_referer( 'auth-link-' . $url );
837
838 if ( ! friends::has_required_privileges() ) {
839 wp_send_json_error( 'missing-priviledges' );
840 }
841
842 $friend_user = User::get_user( $_POST['friend'] );
843 if ( ! $friend_user ) {
844 wp_send_json_error( 'unknown-user' );
845 }
846
847 wp_send_json_success(
848 array(
849 'success' => true,
850 'data' => array(
851 'token' => $friend_user->get_friend_auth(),
852 ),
853 )
854 );
855 }
856
857 public function render_friends_list() {
858 Friends::template_loader()->get_template_part(
859 'admin/settings-header',
860 null,
861 array(
862 'menu' => array(
863 __( 'Your Friends & Subscriptions', 'friends' ) => 'friends-list',
864 __( 'Your Friend Requests', 'friends' ) => 'friends-list-requests',
865 ),
866 'active' => $_GET['page'],
867 'title' => __( 'Friends', 'friends' ),
868 )
869 );
870
871 if ( isset( $_GET['page'] ) && 'friends-list-requests' === $_GET['page'] ) {
872 echo '<p>';
873 echo wp_kses(
874 sprintf(
875 // translators: %1$s is a URL, %2$s is the translated text "Your Friends & Subscriptions".
876 __( 'These are your current friend requests. To see all your friends and subscriptions, go to <a href="%1$s">%2$s</a>.', 'friends' ),
877 self_admin_url( 'admin.php?page=friends-list' ),
878 __( 'Your Friends & Subscriptions', 'friends' )
879 ),
880 array(
881 'a' => array(
882 'href' => array(),
883 ),
884 )
885 );
886 echo '</p>';
887 $query = User_Query::all_friend_requests();
888 } else {
889 $query = User_Query::all_associated_users();
890 }
891
892 if ( isset( $_GET['deleted'] ) ) {
893 ?>
894 <div id="message" class="updated notice is-dismissible"><p>
895 <?php
896 echo esc_html(
897 sprintf(
898 // translators: % s is a username.
899 __( '%s was deleted.', 'friends' ),
900 $_GET['deleted']
901 )
902 );
903 ?>
904 </p></div>
905 <?php
906 } elseif ( isset( $_GET['error'] ) ) {
907 ?>
908 <div id="message" class="updated error is-dismissible"><p>
909 <?php
910 esc_html_e( 'An error occurred.', 'friends' );
911 echo ' ';
912 echo esc_html( $_GET['error'] );
913 ?>
914 </p></div>
915 <?php
916 }
917
918 Friends::template_loader()->get_template_part(
919 'admin/friends-list',
920 null,
921 array(
922 'friends' => $query->get_results(),
923 )
924 );
925
926 Friends::template_loader()->get_template_part( 'admin/settings-footer' );
927 }
928
929 /**
930 * Render the Friend rules preview
931 *
932 * @param array $rules The rules to apply.
933 * @param string $catch_all The catch all behavior.
934 * @param \WP_Post $post The post.
935 */
936 public function render_preview_friend_rules( $rules, $catch_all, \WP_Post $post = null ) {
937 $friend = $this->check_admin_edit_friend_rules();
938 $friend_posts = new \WP_Query();
939
940 $friend_posts->set( 'post_type', Friends::CPT );
941 $friend_posts->set( 'post_status', array( 'publish', 'private', 'trash' ) );
942 $friend_posts->set( 'posts_per_page', 25 );
943 $friend_posts = $friend->modify_query_by_author( $friend_posts );
944
945 $args = array(
946 'friend' => $friend,
947 'friend_posts' => $friend_posts,
948 'feed' => $this->friends->feed,
949 'post' => $post,
950 );
951
952 $friend->set_feed_rules( $rules );
953 $friend->set_feed_catch_all( $catch_all );
954
955 Friends::template_loader()->get_template_part( 'admin/preview-rules', null, $args );
956 }
957
958 /**
959 * Process access for the Friends Edit User page
960 */
961 private function check_admin_edit_friend() {
962 if ( ! friends::has_required_privileges() ) {
963 wp_die( esc_html__( 'Sorry, you are not allowed to edit this user.' ) ); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
964 }
965
966 if ( ! isset( $_GET['user'] ) ) {
967 wp_die( esc_html__( 'Invalid user.', 'friends' ) );
968 }
969
970 $friend = User::get_by_username( $_GET['user'] );
971 if ( ! $friend || is_wp_error( $friend ) ) {
972 wp_die( esc_html__( 'Invalid username.', 'friends' ) );
973 }
974
975 if ( ! $friend->has_cap( 'friends_plugin' ) ) {
976 wp_die( esc_html__( 'This is not a user related to this plugin.', 'friends' ) );
977 }
978
979 return $friend;
980 }
981
982 /**
983 * Process the Friends Edit User page
984 */
985 public function process_admin_edit_friend() {
986 $friend = $this->check_admin_edit_friend();
987 $arg = 'updated';
988 $arg_value = 1;
989
990 if ( isset( $_GET['convert-to-user'] ) && wp_verify_nonce( $_GET['convert-to-user'], 'convert-to-user-' . $friend->user_login ) ) {
991 if ( $friend instanceof Subscription ) {
992 Subscription::convert_to_user( $friend );
993 }
994 } elseif ( isset( $_GET['convert-from-user'] ) && wp_verify_nonce( $_GET['convert-from-user'], 'convert-from-user-' . $friend->user_login ) ) {
995 if ( $friend instanceof User && ! $friend instanceof Subscription ) {
996 if ( $friend->has_cap( 'friends_plugin' ) && ! $friend->has_cap( 'friend' ) && ! $friend->has_cap( 'pending_friend_request' ) && ! $friend->has_cap( 'friend_request' ) ) {
997 Subscription::convert_from_user( $friend );
998 } else {
999 $arg = 'error';
1000 $arg_value = __( 'A friend cannot be converted to a virtual user.', 'friends' );
1001 }
1002 }
1003 } elseif ( isset( $_GET['accept-friend-request'] ) && wp_verify_nonce( $_GET['accept-friend-request'], 'accept-friend-request-' . $friend->user_login ) ) {
1004 if ( $friend->has_cap( 'friend_request' ) ) {
1005 $friend->set_role( get_option( 'friends_default_friend_role', 'friend' ) );
1006 $arg = 'friend';
1007 }
1008 } elseif ( isset( $_GET['add-friend'] ) && wp_verify_nonce( $_GET['add-friend'], 'add-friend-' . $friend->user_login ) ) {
1009 if ( $friend->has_cap( 'pending_friend_request' ) || $friend->has_cap( 'subscription' ) ) {
1010 $rest_url = $this->friends->rest->discover_rest_url( $friend->user_url );
1011 if ( ! is_wp_error( $rest_url ) ) {
1012 $response = $this->send_friend_request( $rest_url, $friend->user_login, $friend->user_url, $friend->display_name );
1013 } else {
1014 $response = $rest_url;
1015 }
1016
1017 if ( is_wp_error( $response ) ) {
1018 $arg = 'error';
1019 } elseif ( $response instanceof User ) {
1020 if ( $response->has_cap( 'pending_friend_request' ) ) {
1021 $arg = 'sent-request';
1022 // translators: %s is a Site URL.
1023 $arg_value = wp_kses( sprintf( __( 'Friendship requested for site %s.', 'friends' ), $response->get_local_friends_page_url() ), array( 'a' => array( 'href' => array() ) ) );
1024 } elseif ( $response->has_cap( 'friend' ) ) {
1025 $arg = 'friend';
1026 $arg_value = 1;
1027 } elseif ( $response->has_cap( 'subscription' ) ) {
1028 $arg = 'subscribed';
1029 $arg_value = 1;
1030 }
1031 }
1032 }
1033 } elseif ( isset( $_GET['change-to-restricted-friend'] ) && wp_verify_nonce( $_GET['change-to-restricted-friend'], 'change-to-restricted-friend-' . $friend->user_login ) ) {
1034 if ( $friend->has_cap( 'friend' ) ) {
1035 $friend->set_role( 'acquaintance' );
1036 }
1037 } elseif ( isset( $_GET['change-to-friend'] ) && wp_verify_nonce( $_GET['change-to-friend'], 'change-to-friend-' . $friend->user_login ) ) {
1038 if ( $friend->has_cap( 'acquaintance' ) ) {
1039 $friend->set_role( 'friend' );
1040 }
1041 } elseif ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'edit-friend-' . $friend->user_login ) ) {
1042 if ( trim( $_POST['friends_display_name'] ) ) {
1043 $friend->first_name = trim( $_POST['friends_display_name'] );
1044 $friend->display_name = trim( $_POST['friends_display_name'] );
1045 }
1046
1047 $friend->description = trim( $_POST['friends_description'] );
1048 if ( trim( $_POST['user_url'] ) && filter_var( $_POST['user_url'], FILTER_VALIDATE_URL ) ) {
1049 $friend->user_url = $_POST['user_url'];
1050 }
1051 $friend->save();
1052
1053 $hide_from_friends_page = get_user_option( 'friends_hide_from_friends_page' );
1054 if ( ! $hide_from_friends_page ) {
1055 $hide_from_friends_page = array();
1056 }
1057 if ( ! isset( $_POST['show_on_friends_page'] ) || ! $_POST['show_on_friends_page'] ) {
1058 if ( ! in_array( $friend->user_login, $hide_from_friends_page ) ) {
1059 $hide_from_friends_page[] = $friend->user_login;
1060 update_user_option( get_current_user_id(), 'friends_hide_from_friends_page', $hide_from_friends_page );
1061 }
1062 } else {
1063 if ( in_array( $friend->user_login, $hide_from_friends_page ) ) {
1064 $hide_from_friends_page = array_values( array_diff( $hide_from_friends_page, array( $friend->user_login ) ) );
1065 update_user_option( get_current_user_id(), 'friends_hide_from_friends_page', $hide_from_friends_page );
1066 }
1067 }
1068 } else {
1069 return;
1070 }
1071
1072 do_action( 'friends_edit_friend_after_form_submit', $friend );
1073
1074 if ( isset( $_GET['_wp_http_referer'] ) ) {
1075 wp_safe_redirect( add_query_arg( $arg, $arg_value, wp_get_referer() ) );
1076 } else {
1077 wp_safe_redirect( add_query_arg( $arg, $arg_value, remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
1078 }
1079 exit;
1080 }
1081
1082 /**
1083 * The Friends Edit User header
1084 *
1085 * @param User $friend The friend.
1086 * @param string $active The active menu entry.
1087 */
1088 public function header_edit_friend( User $friend, $active ) {
1089 $append = '&user=' . $friend->user_login;
1090 Friends::template_loader()->get_template_part(
1091 'admin/settings-header',
1092 null,
1093 array(
1094 'active' => $active . $append,
1095 'title' => $friend->user_login,
1096 'menu' => array(
1097 __( 'Settings' ) => 'edit-friend' . $append, // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
1098 __( 'Feeds', 'friends' ) => 'edit-friend-feeds' . $append,
1099 __( 'Notifications', 'friends' ) => 'edit-friend-notifications' . $append,
1100 __( 'Rules', 'friends' ) => 'edit-friend-rules' . $append,
1101 ),
1102 )
1103 );
1104 }
1105
1106 /**
1107 * Render the Friends Edit User page
1108 */
1109 public function render_admin_edit_friend() {
1110 $friend = $this->check_admin_edit_friend();
1111
1112 $args = array_merge(
1113 $friend->get_post_stats(),
1114 array(
1115 'friend' => $friend,
1116 'friends_settings_url' => add_query_arg( '_wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), self_admin_url( 'admin.php?page=friends-settings' ) ),
1117 'registered_parsers' => $this->friends->feed->get_registered_parsers(),
1118 'hide_from_friends_page' => get_user_option( 'friends_hide_from_friends_page' ),
1119 )
1120 );
1121 if ( ! $args['hide_from_friends_page'] ) {
1122 $args['hide_from_friends_page'] = array();
1123 }
1124
1125 $this->header_edit_friend( $friend, 'edit-friend' );
1126
1127 if ( isset( $_GET['updated'] ) ) {
1128 ?>
1129 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'User was updated.', 'friends' ); ?></p></div>
1130 <?php
1131 } elseif ( isset( $_GET['friend'] ) ) {
1132 ?>
1133 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'You are now friends.', 'friends' ); ?></p></div>
1134 <?php
1135 } elseif ( isset( $_GET['error'] ) ) {
1136 ?>
1137 <div id="message" class="updated error is-dismissible"><p><?php esc_html_e( 'An error occurred.', 'friends' ); ?></p></div>
1138 <?php
1139 } elseif ( isset( $_GET['sent-request'] ) ) {
1140 ?>
1141 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'Your request was sent.', 'friends' ); ?></p></div>
1142 <?php
1143 } elseif ( isset( $_GET['subscribed'] ) ) {
1144 ?>
1145 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'Subscription activated.', 'friends' ); ?></p></div>
1146 <?php
1147 }
1148
1149 Friends::template_loader()->get_template_part( 'admin/edit-friend', null, $args );
1150 }
1151
1152 public function ajax_set_avatar() {
1153 $user_id = isset( $_POST['user'] ) ? $_POST['user'] : 0;
1154
1155 check_ajax_referer( "set-avatar-$user_id" );
1156
1157 if ( ! current_user_can( Friends::REQUIRED_ROLE ) ) {
1158 wp_send_json_error();
1159 exit;
1160 }
1161
1162 if ( empty( $_POST['avatar'] ) || ! Friends::check_url( $_POST['avatar'] ) ) {
1163 wp_send_json_error();
1164 exit;
1165 }
1166
1167 $friend = User::get_user_by_id( $user_id );
1168
1169 // Use WordPress functions to check the image dimensions.
1170 $size = \wp_getimagesize( $_POST['avatar'] );
1171 if ( ! $size ) {
1172 wp_send_json_error( __( 'Image is in an unknown format.', 'friends' ) );
1173 exit;
1174 }
1175 // Needs to be square and not larger than 512x512.
1176 if ( $size[0] !== $size[1] || $size[0] > 512 ) {
1177 wp_send_json_error( __( 'Image must be square and not larger than 512x512.', 'friends' ) );
1178 exit;
1179 }
1180
1181 $url = $friend->update_user_icon_url( $_POST['avatar'] );
1182
1183 if ( ! $url || is_wp_error( $url ) ) {
1184 wp_send_json_error( $url );
1185 exit;
1186 }
1187
1188 wp_send_json_success(
1189 array(
1190 'url' => $url,
1191 )
1192 );
1193 }
1194
1195 /**
1196 * Process the Friends Edit Notifications page
1197 */
1198 public function process_admin_edit_friend_notifications() {
1199 $friend = $this->check_admin_edit_friend();
1200 $arg = 'updated';
1201 $arg_value = 1;
1202
1203 if ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'edit-friend-notifications-' . $friend->user_login ) ) {
1204 if ( ! get_user_option( 'friends_no_new_post_notification' ) ) {
1205 if ( isset( $_POST['friends_new_post_notification'] ) && $_POST['friends_new_post_notification'] ) {
1206 delete_user_option( get_current_user_id(), 'friends_no_new_post_notification_' . $friend->user_login );
1207 } else {
1208 update_user_option( get_current_user_id(), 'friends_no_new_post_notification_' . $friend->user_login, 1 );
1209 }
1210 }
1211
1212 if ( ! get_user_option( 'friends_no_keyword_notification' ) ) {
1213 if ( isset( $_POST['friends_keyword_notification'] ) && $_POST['friends_keyword_notification'] ) {
1214 delete_user_option( get_current_user_id(), 'friends_no_keyword_notification_' . $friend->user_login );
1215 } else {
1216 update_user_option( get_current_user_id(), 'friends_no_keyword_notification_' . $friend->user_login, 1 );
1217 }
1218 }
1219
1220 do_action( 'friends_edit_friend_notifications_after_form_submit', $friend );
1221 } else {
1222 return;
1223 }
1224
1225 if ( isset( $_GET['_wp_http_referer'] ) ) {
1226 wp_safe_redirect( wp_get_referer() );
1227 } else {
1228 wp_safe_redirect( add_query_arg( $arg, $arg_value, remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
1229 }
1230 exit;
1231 }
1232
1233 /**
1234 * Render the Friends Edit Notifications page
1235 */
1236 public function render_admin_edit_friend_notifications() {
1237 $friend = $this->check_admin_edit_friend();
1238 $post_stats = $friend->get_post_stats();
1239
1240 $this->header_edit_friend( $friend, 'edit-friend-notifications' );
1241
1242 if ( isset( $_GET['updated'] ) ) {
1243 ?>
1244 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'Notification Settings were updated.', 'friends' ); ?></p></div>
1245 <?php
1246 } elseif ( isset( $_GET['error'] ) ) {
1247 ?>
1248 <div id="message" class="updated error is-dismissible"><p><?php esc_html_e( 'An error occurred.', 'friends' ); ?></p></div>
1249 <?php
1250 }
1251
1252 Friends::template_loader()->get_template_part(
1253 'admin/edit-notifications',
1254 null,
1255 array(
1256 'friend' => $friend,
1257 )
1258 );
1259 }
1260
1261 /**
1262 * Process the Friends Edit Feeds page
1263 */
1264 public function process_admin_edit_friend_feeds() {
1265 $friend = $this->check_admin_edit_friend();
1266 $arg = 'updated';
1267 $arg_value = 1;
1268
1269 if ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'edit-friend-feeds-' . $friend->user_login ) ) {
1270 $hide_from_friends_page = get_user_option( 'friends_hide_from_friends_page' );
1271 if ( ! $hide_from_friends_page ) {
1272 $hide_from_friends_page = array();
1273 }
1274 if ( ! isset( $_POST['show_on_friends_page'] ) || ! $_POST['show_on_friends_page'] ) {
1275 if ( ! in_array( $friend->user_login, $hide_from_friends_page ) ) {
1276 $hide_from_friends_page[] = $friend->user_login;
1277 update_user_option( get_current_user_id(), 'friends_hide_from_friends_page', $hide_from_friends_page );
1278 }
1279 } else {
1280 if ( in_array( $friend->user_login, $hide_from_friends_page ) ) {
1281 $hide_from_friends_page = array_values( array_diff( $hide_from_friends_page, array( $friend->user_login ) ) );
1282 update_user_option( get_current_user_id(), 'friends_hide_from_friends_page', $hide_from_friends_page );
1283 }
1284 }
1285
1286 if ( $friend->set_retention_number_enabled( isset( $_POST['friends_enable_retention_number'] ) && $_POST['friends_enable_retention_number'] ) ) {
1287 $friend->set_retention_number( $_POST['friends_retention_number'] );
1288 }
1289 if ( $friend->set_retention_days_enabled( isset( $_POST['friends_enable_retention_days'] ) && $_POST['friends_enable_retention_days'] ) ) {
1290 $friend->set_retention_days( $_POST['friends_retention_days'] );
1291 }
1292
1293 $hide_from_friends_page = get_user_option( 'friends_hide_from_friends_page' );
1294 if ( ! $hide_from_friends_page ) {
1295 $hide_from_friends_page = array();
1296 }
1297
1298 if ( isset( $_POST['feeds'] ) ) {
1299 $existing_feeds = $friend->get_feeds();
1300 if ( '' === trim( $_POST['feeds']['new']['url'] ) ) {
1301 unset( $_POST['feeds']['new'] );
1302 } else {
1303 foreach ( $existing_feeds as $term_id => $user_feed ) {
1304 if ( $user_feed->get_url() === trim( $_POST['feeds']['new']['url'] ) ) {
1305 if ( isset( $_POST['feeds'][ $term_id ] ) ) {
1306 // Let a newly entered feed overrule an existing one.
1307 $_POST['feeds'][ $term_id ] = array_merge( $_POST['feeds'][ $term_id ], $_POST['feeds']['new'] );
1308 $_POST['feeds'][ $term_id ]['active'] = 1;
1309 }
1310 unset( $_POST['feeds']['new'] );
1311 break;
1312 }
1313 }
1314 }
1315 foreach ( $_POST['feeds'] as $term_id => $feed ) {
1316 if ( 'new' === $term_id ) {
1317 if ( '' === trim( $feed['url'] ) ) {
1318 continue;
1319 }
1320
1321 $feed['active'] = true;
1322 $protocol = wp_parse_url( $feed['url'], PHP_URL_SCHEME );
1323 if ( ! $protocol ) {
1324 $feed['url'] = apply_filters( 'friends_rewrite_incoming_url', 'https://' . $feed['url'], $feed['url'] );
1325 }
1326 $new_feed = $friend->subscribe( $feed['url'], $feed );
1327 if ( is_wp_error( $new_feed ) ) {
1328 do_action( 'friends_process_feed_item_submit_error', $new_feed, $feed );
1329 continue;
1330 }
1331
1332 do_action( 'friends_user_feed_activated', $new_feed );
1333 do_action( 'friends_process_feed_item_submit', $new_feed, $feed );
1334 continue;
1335 }
1336
1337 if ( ! isset( $existing_feeds[ $term_id ] ) ) {
1338 continue;
1339 }
1340 $user_feed = $existing_feeds[ $term_id ];
1341 unset( $existing_feeds[ $term_id ] );
1342
1343 $protocol = wp_parse_url( $feed['url'], PHP_URL_SCHEME );
1344 if ( ! $protocol ) {
1345 $feed['url'] = apply_filters( 'friends_rewrite_incoming_url', 'https://' . $feed['url'], $feed['url'] );
1346 }
1347
1348 if ( $user_feed->get_url() !== $feed['url'] ) {
1349 do_action( 'friends_user_feed_deactivated', $user_feed );
1350
1351 if ( ! isset( $feed['mime-type'] ) ) {
1352 $feed['mime-type'] = $user_feed->get_mime_type();
1353 }
1354
1355 if ( $feed['active'] ) {
1356 $new_feed = $friend->subscribe( $feed['url'], $feed );
1357 if ( ! is_wp_error( $new_feed ) ) {
1358 do_action( 'friends_user_feed_activated', $new_feed );
1359 }
1360 } else {
1361 $new_feed = $friend->save_feed( $feed['url'], $feed );
1362 }
1363
1364 // Since the URL has changed, the above will create a new feed, therefore we need to delete the old one.
1365 $user_feed->delete();
1366
1367 if ( is_wp_error( $new_feed ) ) {
1368 do_action( 'friends_process_feed_item_submit_error', $new_feed, $feed );
1369 continue;
1370 }
1371
1372 do_action( 'friends_process_feed_item_submit', $new_feed, $feed );
1373 continue;
1374 }
1375
1376 if ( $user_feed->get_title() !== $feed['title'] ) {
1377 $user_feed->update_metadata( 'title', $feed['title'] );
1378 }
1379
1380 if ( $user_feed->get_parser() !== $feed['parser'] ) {
1381 $user_feed->update_metadata( 'parser', $feed['parser'] );
1382 }
1383
1384 if ( $user_feed->get_post_format() !== $feed['post-format'] ) {
1385 $user_feed->update_metadata( 'post-format', $feed['post-format'] );
1386 }
1387
1388 if ( isset( $feed['mime-type'] ) && $user_feed->get_mime_type() !== $feed['mime-type'] ) {
1389 $user_feed->update_metadata( 'mime-type', $feed['mime-type'] );
1390 }
1391
1392 $was_active = $user_feed->is_active();
1393 $is_active = isset( $feed['active'] ) && $feed['active'];
1394 $user_feed->update_metadata( 'active', $is_active );
1395 if ( $was_active !== $is_active ) {
1396 if ( $is_active ) {
1397 do_action( 'friends_user_feed_activated', $user_feed );
1398 } else {
1399 do_action( 'friends_user_feed_deactivated', $user_feed );
1400 }
1401 }
1402
1403 do_action( 'friends_process_feed_item_submit', $user_feed, $feed );
1404 }
1405
1406 // Delete remaining existing feeds since they were not submitted.
1407 foreach ( $existing_feeds as $term_id => $user_feed ) {
1408 do_action( 'friends_user_feed_deactivated', $user_feed );
1409 $user_feed->delete();
1410 }
1411 }
1412 do_action( 'friends_edit_feeds_after_form_submit', $friend );
1413 } else {
1414 return;
1415 }
1416
1417 if ( isset( $_GET['_wp_http_referer'] ) ) {
1418 wp_safe_redirect( wp_get_referer() );
1419 } else {
1420 wp_safe_redirect( add_query_arg( $arg, $arg_value, remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
1421 }
1422 exit;
1423 }
1424
1425 /**
1426 * Render the Friends Edit Feeds page
1427 */
1428 public function render_admin_edit_friend_feeds() {
1429 $friend = $this->check_admin_edit_friend();
1430
1431 $args = array_merge(
1432 $friend->get_post_stats(),
1433 array(
1434 'friend' => $friend,
1435 'rules' => $friend->get_feed_rules(),
1436 'hide_from_friends_page' => get_user_option( 'friends_hide_from_friends_page' ),
1437 'post_formats' => array_merge( array( 'autodetect' => __( 'Autodetect Post Format', 'friends' ) ), get_post_format_strings() ),
1438 'friends_settings_url' => add_query_arg( '_wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), self_admin_url( 'admin.php?page=friends-settings' ) ),
1439 'registered_parsers' => $this->friends->feed->get_registered_parsers(),
1440 'global_retention_days' => Friends::get_retention_days(),
1441 'global_retention_number' => Friends::get_retention_number(),
1442 'global_retention_days_enabled' => get_option( 'friends_enable_retention_days' ),
1443 'global_retention_number_enabled' => get_option( 'friends_enable_retention_number' ),
1444 )
1445 );
1446 if ( ! $args['hide_from_friends_page'] ) {
1447 $args['hide_from_friends_page'] = array();
1448 }
1449 $this->header_edit_friend( $friend, 'edit-friend-feeds' );
1450
1451 if ( isset( $_GET['updated'] ) ) {
1452 ?>
1453 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'Feeds were updated.', 'friends' ); ?></p></div>
1454 <?php
1455 } elseif ( isset( $_GET['error'] ) ) {
1456 ?>
1457 <div id="message" class="updated error is-dismissible"><p><?php esc_html_e( 'An error occurred.', 'friends' ); ?></p></div>
1458 <?php
1459 }
1460
1461 Friends::template_loader()->get_template_part( 'admin/edit-feeds', null, $args );
1462 }
1463
1464 /**
1465 * Process the Unfriend page
1466 */
1467 public function process_admin_unfriend() {
1468 $friend = $this->check_admin_edit_friend();
1469 $arg = 'deleted';
1470 $arg_value = $friend->user_login;
1471
1472 if ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'unfriend-' . $friend->user_login ) ) {
1473 $friend->delete();
1474 } else {
1475 return;
1476 }
1477
1478 if ( isset( $_GET['_wp_http_referer'] ) ) {
1479 wp_safe_redirect( wp_get_referer() );
1480 } else {
1481 wp_safe_redirect( add_query_arg( $arg, $arg_value, self_admin_url( 'admin.php?page=friends-list' ) ) );
1482 }
1483 exit;
1484 }
1485
1486 /**
1487 * Render the Unfriend page
1488 */
1489 public function render_admin_unfriend() {
1490 $friend = $this->check_admin_edit_friend();
1491 $post_stats = $friend->get_post_stats();
1492
1493 $args = array(
1494 'friend' => $friend,
1495 'friend_posts' => $post_stats['post_count'],
1496 'total_size' => $post_stats['total_size'],
1497 );
1498
1499 Friends::template_loader()->get_template_part( 'admin/unfriend', null, $args );
1500 }
1501
1502 /**
1503 * Display error messages.
1504 *
1505 * @param object $errors The errors.
1506 */
1507 private function display_errors( $errors ) {
1508 if ( ! is_wp_error( $errors ) ) {
1509 return;
1510 }
1511
1512 ?>
1513 <div id="message" class="updated error is-dismissible"><p><?php echo esc_html( $errors->get_error_message() ); ?></p>
1514 <?php
1515 $error_data = $errors->get_error_data();
1516 if ( isset( $error_data->error ) ) {
1517 $error = unserialize( $error_data->error );
1518 if ( is_wp_error( $error ) ) {
1519 ?>
1520 <pre>
1521 <?php
1522 print_r( $error );
1523 ?>
1524 </pre>
1525 <?php
1526 } elseif ( is_array( $error ) && isset( $error['body'] ) ) {
1527 ?>
1528 <textarea>
1529 <?php
1530 echo esc_html( $error['body'] );
1531 ?>
1532 </textarea>
1533 <?php
1534 }
1535 }
1536 ?>
1537 </div>
1538 <?php
1539 }
1540
1541 public function create_and_follow( $user_id, $url, $type, $vars = array() ) {
1542 $vars['friend_url'] = $url;
1543
1544 $vars['user_login'] = apply_filters( 'friends_suggest_user_login', User::get_user_login_for_url( $url ), $url );
1545 if ( empty( $vars['display_name'] ) ) {
1546 $vars['display_name'] = apply_filters( 'friends_suggest_display_name', User::get_display_name_for_url( $url ), $url );
1547 }
1548
1549 $vars['step2'] = true;
1550
1551 $vars['subscribe'] = array( $url );
1552 $vars['feeds'] = $this->friends->feed->discover_available_feeds( $url );
1553
1554 ob_start();
1555 $ret = $this->process_admin_add_friend( $vars );
1556 ob_end_clean();
1557
1558 if ( is_wp_error( $ret ) ) {
1559 return $ret;
1560 }
1561
1562 $friend_user = User::get_by_username( $vars['user_login'] );
1563 if ( ! $friend_user || is_wp_error( $friend_user ) ) {
1564 return new \WP_Error( 'friend_not_created', __( 'Friend could not be created.', 'friends' ) );
1565 }
1566
1567 return $friend_user->ID;
1568 }
1569
1570 /**
1571 * Previous process the Add Friend form. Todo: re-integrate.
1572 *
1573 * @param User $friend_user The Friend user.
1574 * @param array $vars The variables from the admin
1575 * submission.
1576 *
1577 * @return boolean true when there was no error.
1578 */
1579 public function process_admin_add_friend_response( $friend_user, $vars ) {
1580 if ( is_wp_error( $friend_user ) ) {
1581 $this->display_errors( $friend_user );
1582 return false;
1583 }
1584
1585 if ( ! $friend_user instanceof User ) {
1586 ?>
1587 <div id="message" class="updated notice is-dismissible"><p>
1588 <?php
1589 // translators: %s is a username.
1590 esc_html_e( 'Unknown error', 'friends' );
1591 ?>
1592 </p></div>
1593 <?php
1594 return false;
1595 }
1596
1597 $feed_options = array();
1598 if ( ! isset( $vars['feeds'] ) ) {
1599 $vars['feeds'] = array();
1600 }
1601 foreach ( $vars['feeds'] as $feed ) {
1602 if ( isset( $feed['type'] ) ) {
1603 $feed['mime-type'] = $feed['type'];
1604 unset( $feed['type'] );
1605 }
1606 $feed_options[ $feed['url'] ] = $feed;
1607 }
1608
1609 // Save the all feeds for possible later activation.
1610 $friend_user->save_feeds( $feed_options );
1611
1612 if ( ! isset( $vars['subscribe'] ) ) {
1613 $vars['subscribe'] = array();
1614 }
1615
1616 $count = 0;
1617 foreach ( $vars['subscribe'] as $feed_url ) {
1618 if ( ! isset( $feed_options[ $feed_url ] ) ) {
1619 continue;
1620 }
1621 $new_feed = $friend_user->subscribe( $feed_url, $feed_options[ $feed_url ] );
1622 if ( ! is_wp_error( $new_feed ) ) {
1623 do_action( 'friends_user_feed_activated', $new_feed );
1624 $count += 1;
1625 }
1626 }
1627
1628 add_filter( 'notify_about_new_friend_post', '__return_false', 999 );
1629
1630 wp_schedule_single_event( time(), 'friends_retrieve_user_feeds', array( $friend_user->ID ) );
1631
1632 if ( isset( $vars['errors'] ) ) {
1633 $this->display_errors( $vars['errors'] );
1634 }
1635
1636 $friend_link = '<a href="' . esc_url( $this->admin_edit_user_link( $friend_user->get_local_friends_page_url(), $friend_user ) ) . '" target="_blank" rel="noopener noreferrer">' . esc_html( $friend_user->display_name ) . '</a>';
1637 $message = false;
1638
1639 if ( $friend_user->has_cap( 'pending_friend_request' ) ) {
1640 // translators: %s is a Site URL.
1641 $message = sprintf( __( 'Friendship requested for site %s.', 'friends' ), $friend_link );
1642 $message .= ' ' . sprintf( __( 'Until they respond, we have already subscribed you to their updates.', 'friends' ), $friend_link );
1643 } elseif ( $friend_user->has_cap( 'friend' ) ) {
1644 // translators: %s is a Site URL.
1645 $message = sprintf( __( "You're now a friend of site %s.", 'friends' ), $friend_link );
1646 // translators: %s is the friends page URL.
1647 } elseif ( $friend_user->has_cap( 'subscription' ) ) {
1648 if ( isset( $vars['friendship'] ) ) {
1649 // translators: %s is a Site URL.
1650 $message = sprintf( __( 'No friends plugin installed at %s.', 'friends' ), $friend_link );
1651 $message .= ' ' . esc_html__( 'We subscribed you to their updates.', 'friends' );
1652 } else {
1653 // translators: %s is a Site URL.
1654 $message = sprintf( __( "You're now subscribed to %s.", 'friends' ), $friend_link );
1655 }
1656 }
1657
1658 if ( $message ) {
1659 ?>
1660 <div id="message" class="updated notice is-dismissible"><p>
1661 <?php
1662 echo wp_kses( $message, array( 'a' => array( 'href' => array() ) ) );
1663 // translators: %s is the friends page URL.
1664 echo ' ', wp_kses( sprintf( __( 'Go to your <a href=%s>friends page</a> to view their posts.', 'friends' ), '"' . esc_url( $friend_user->get_local_friends_page_url() ) . '"' ), array( 'a' => array( 'href' => array() ) ) );
1665 echo ' <span id="fetch-feeds" data-nonce="', esc_attr( wp_create_nonce( 'fetch-feeds-' . $friend_user->user_login ) ), '" data-friend=', esc_attr( $friend_user->user_login ), '>', __( 'Fetching feeds...', 'friends' ), '</span>';
1666 ?>
1667 </p></div>
1668 <?php
1669 return true;
1670 }
1671
1672 ?>
1673 <div id="message" class="updated notice is-dismissible"><p>
1674 <?php
1675 // translators: %s is a username.
1676 echo esc_html( sprintf( __( 'User %s could not be assigned the appropriate role.', 'friends' ), $friend_user->display_name ) );
1677 ?>
1678 </p></div>
1679 <?php
1680 return false;
1681 }
1682
1683 /**
1684 * Process the Add Friend form.
1685 *
1686 * @param array $vars The POST or GET variables.
1687 *
1688 * @return boolean A \WP_Error or void.
1689 */
1690 public function process_admin_add_friend( $vars ) {
1691 $errors = new \WP_Error();
1692 $args = array();
1693
1694 $friend_url = isset( $vars['friend_url'] ) ? trim( $vars['friend_url'] ) : '';
1695 $codeword = isset( $vars['codeword'] ) ? trim( $vars['codeword'] ) : '';
1696 $message = isset( $vars['message'] ) ? trim( $vars['message'] ) : '';
1697
1698 $friends_plugin = false;
1699 $friend_user = false;
1700
1701 $protocol = wp_parse_url( $friend_url, PHP_URL_SCHEME );
1702 if ( ! $protocol ) {
1703 // Allow adding a friend by username.
1704 if ( is_multisite() ) {
1705 $friend_user = get_user_by( 'login', $friend_url );
1706 if ( $friend_user ) {
1707 $site = get_active_blog_for_user( $friend_user->ID );
1708 // Ensure we're using the same URL protocol.
1709 $friend_url = set_url_scheme( $site->siteurl );
1710 }
1711 }
1712
1713 // If unsuccessful, then the protocol was forgotten.
1714 if ( ! $friend_user ) {
1715 $friend_url = apply_filters( 'friends_rewrite_incoming_url', 'https://' . $friend_url, $friend_url );
1716 }
1717 }
1718 $friend_user_login = apply_filters( 'friends_suggest_user_login', User::get_user_login_for_url( $friend_url ), $friend_url );
1719 $friend_display_name = apply_filters( 'friends_suggest_display_name', User::get_display_name_for_url( $friend_url ), $friend_url );
1720
1721 $friend_user = get_user_by( 'login', $friend_user_login );
1722
1723 if ( $friend_user ) {
1724 $args['friends_multisite_user_login'] = $friend_user_login;
1725 $args['friends_multisite_display_name'] = $friend_display_name;
1726 }
1727 $rest_url = false;
1728
1729 if ( ( isset( $vars['step2'] ) && isset( $vars['feeds'] ) && is_array( $vars['feeds'] ) ) || isset( $vars['step3'] ) ) {
1730 $friend_user_login = str_replace( ' ', '-', sanitize_user( $vars['user_login'] ) );
1731 $friend_display_name = sanitize_text_field( $vars['display_name'] );
1732 if ( ! $friend_user_login ) {
1733 // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
1734 $errors->add( 'user_login', __( '<strong>Error</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
1735 } elseif ( ! is_multisite() && username_exists( $friend_user_login ) ) {
1736 // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
1737 $errors->add( 'user_login', __( '<strong>Error</strong>: This username is already registered. Please choose another one.' ) );
1738 }
1739
1740 $feeds = $vars['feeds'];
1741 if ( ! $errors->has_errors() ) {
1742 $friend_user = false;
1743 if ( isset( $vars['friendship'] ) ) {
1744 $friend_user = $this->send_friend_request( $vars['friendship'], $friend_user_login, $friend_url, $friend_display_name, $codeword, $message );
1745 if ( $friend_user->has_errors() ) {
1746 $vars['errors'] = $friend_user;
1747 }
1748 }
1749
1750 $avatar = null;
1751 $description = null;
1752 foreach ( $feeds as $feed_details ) {
1753 if ( ! $avatar && ! empty( $feed_details['avatar'] ) ) {
1754 $avatar = $feed_details['avatar'];
1755 }
1756 if ( ! $description && ! empty( $feed_details['description'] ) ) {
1757 $description = $feed_details['description'];
1758 }
1759 }
1760
1761 if ( ! $friend_user || is_wp_error( $friend_user ) ) {
1762 $friend_user = User::create( $friend_user_login, 'subscription', $friend_url, $friend_display_name, $avatar, $description );
1763 }
1764
1765 return $this->process_admin_add_friend_response( $friend_user, $vars );
1766 }
1767
1768 if ( isset( $vars['friendship'] ) ) {
1769 $rest_url = $vars['friendship'];
1770 } else {
1771 $rest_url = $this->friends->rest->get_friends_rest_url( $feeds );
1772 }
1773 } else {
1774 if ( home_url() === trailingslashit( $friend_url ) ) {
1775 return new \WP_Error( 'friend-yourself', __( 'It seems like you sent a friend request to yourself.', 'friends' ) );
1776 }
1777
1778 if ( ! Friends::check_url( $friend_url ) ) {
1779 return new \WP_Error( 'invalid-url', __( 'You entered an invalid URL.', 'friends' ) );
1780 }
1781
1782 $friend_user = User::get_user( $friend_user_login );
1783 if ( $friend_user && ! is_wp_error( $friend_user ) ) {
1784 if ( $friend_user->is_valid_friend() ) {
1785 return new \WP_Error( 'already-friend', __( 'You are already friends with this site.', 'friends' ) );
1786 }
1787
1788 // translators: %s is the name of a friend / site.
1789 return new \WP_Error( 'already-subscribed', sprintf( __( 'You are already subscribed to this site: %s', 'friends' ), '<a href="' . esc_url( $this->admin_edit_user_link( $friend_user->get_local_friends_page_url(), $friend_user ) ) . '">' . esc_html( $friend_user->display_name ) . '</a>' ) );
1790 }
1791
1792 $feeds = $this->friends->feed->discover_available_feeds( $friend_url );
1793 if ( is_wp_error( $feeds ) ) {
1794 return $feeds;
1795 }
1796 if ( ! $feeds ) {
1797 return new \WP_Error( 'no-feed-found', __( 'No suitable feed was found at the provided address.', 'friends' ) );
1798 }
1799
1800 $better_display_name = User::get_display_name_from_feeds( $feeds );
1801 if ( $better_display_name ) {
1802 $friend_display_name = $better_display_name;
1803 }
1804
1805 $rest_url = $this->friends->rest->get_friends_rest_url( $feeds );
1806 }
1807
1808 if ( $rest_url ) {
1809 $friends_plugin = $rest_url;
1810 unset( $feeds[ $rest_url ] );
1811 }
1812
1813 if ( isset( $vars['quick-subscribe'] ) ) {
1814 $vars['feeds'] = $feeds;
1815 $vars['subscribe'] = array();
1816 foreach ( $feeds as $feed_url => $details ) {
1817 if ( isset( $details['autoselect'] ) && $details['autoselect'] ) {
1818 $vars['subscribe'][] = $feed_url;
1819 }
1820 }
1821
1822 $friend_user = false;
1823 if ( isset( $rest_url ) ) {
1824 $friend_user = $this->send_friend_request( $rest_url, $friend_user_login, $friend_url, $friend_display_name, $codeword, $message );
1825 }
1826
1827 $avatar = null;
1828 $description = null;
1829 foreach ( $feeds as $feed_details ) {
1830 if ( ! $avatar && ! empty( $feed_details['avatar'] ) ) {
1831 $avatar = $feed_details['avatar'];
1832 }
1833 if ( ! $description && ! empty( $feed_details['description'] ) ) {
1834 $description = $feed_details['description'];
1835 }
1836 }
1837
1838 if ( ! $friend_user || is_wp_error( $friend_user ) ) {
1839 $friend_user = User::create( $friend_user_login, 'subscription', $friend_url, $friend_display_name, $avatar, $description );
1840 }
1841
1842 return $this->process_admin_add_friend_response( $friend_user, $vars );
1843 }
1844
1845 Friends::template_loader()->get_template_part(
1846 'admin/settings-header',
1847 null,
1848 array(
1849 'active' => 'add-friend-confirm',
1850 'title' => __( 'Add New Friend', 'friends' ),
1851 'menu' => array(
1852 '1. ' . __( 'Enter Details', 'friends' ) => 'add-friend' . ( isset( $friend_url ) ? '&url=' . urlencode( $friend_url ) : '' ),
1853 '2. ' . __( 'Confirm', 'friends' ) => 'add-friend-confirm',
1854 ),
1855 )
1856 );
1857
1858 if ( $errors->has_errors() ) {
1859 ?>
1860 <div id="message" class="updated notice is-dismissible"><p><?php echo wp_kses( $errors->get_error_message(), array( 'strong' => array() ) ); ?></p>
1861 </div>
1862 <?php
1863 }
1864
1865 Friends::template_loader()->get_template_part(
1866 'admin/select-feeds',
1867 null,
1868 array_merge(
1869 $args,
1870 array(
1871 'friends_plugin' => $friends_plugin,
1872 'friend_url' => $friend_url,
1873 'friend_user_login' => $friend_user_login,
1874 'friend_display_name' => $friend_display_name,
1875 'friend_roles' => $this->get_friend_roles(),
1876 'default_role' => get_option( 'friends_default_friend_role', 'friend' ),
1877 'codeword' => $codeword,
1878 'message' => $message,
1879 'post_formats' => array_merge( array( 'autodetect' => __( 'Autodetect Post Format', 'friends' ) ), get_post_format_strings() ),
1880 'registered_parsers' => $this->friends->feed->get_registered_parsers(),
1881 'feeds' => $feeds,
1882 )
1883 )
1884 );
1885 }
1886
1887 /**
1888 * Render the admin form for sending a friend request.
1889 */
1890 public function render_admin_add_friend() {
1891 if ( ! friends::has_required_privileges() ) {
1892 wp_die( esc_html__( 'Sorry, you are not allowed to add friends.', 'friends' ) );
1893 }
1894
1895 if ( ! empty( $_GET['preview'] ) ) {
1896 $url = $_GET['preview'];
1897
1898 ?>
1899 <h1>
1900 <?php
1901 // translators: %s is a URL.
1902 echo esc_html( sprintf( __( 'Preview for %s', 'friends' ), $url ) );
1903 ?>
1904 </h1>
1905 <?php
1906
1907 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'preview-feed' ) ) {
1908 ?>
1909 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'For security reasons, this preview is not available.', 'friends' ); ?></p>
1910 </div>
1911 <?php
1912 exit;
1913 }
1914
1915 $parser_name = $this->friends->feed->get_registered_parser( $_GET['parser'] );
1916 if ( ! $parser_name ) {
1917 ?>
1918 <div id="message" class="updated notice is-dismissible"><p><?php esc_html_e( 'An unknown parser name was supplied.', 'friends' ); ?></p>
1919 </div>
1920 <?php
1921 exit;
1922 }
1923 ?>
1924 <h3><?php esc_html_e( 'Parser Details', 'friends' ); ?></h3>
1925 <ul id="parser">
1926 <li>
1927 <?php
1928 echo wp_kses(
1929 // translators: %s is the name of a parser, e.g. simplepie.
1930 sprintf( __( 'Parser: %s', 'friends' ), $parser_name ),
1931 array(
1932 'a' => array(
1933 'href' => array(),
1934 'rel' => array(),
1935 'target' => array(),
1936 ),
1937 )
1938 );
1939 ?>
1940 </li>
1941 </ul>
1942 <h3><?php esc_html_e( 'Items in the Feed', 'friends' ); ?></h3>
1943
1944 <?php
1945
1946 $items = $this->friends->feed->preview( $_GET['parser'], $url, isset( $_GET['feed'] ) ? intval( $_GET['feed'] ) : null );
1947 if ( is_wp_error( $items ) ) {
1948 ?>
1949 <div id="message" class="updated notice is-dismissible"><p><?php echo esc_html( $items->get_error_message() ); ?></p>
1950 </div>
1951 <?php
1952 exit;
1953 }
1954 ?>
1955
1956 <ul>
1957 <?php
1958 foreach ( $items as $item ) {
1959 $title = $item->title;
1960 if ( 'status' === $item->post_format ) {
1961 $title = strip_tags( $item->content );
1962 }
1963 ?>
1964 <li><a href="<?php echo esc_url( $item->permalink ); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html( $item->date ); ?></a> (author: <?php echo esc_html( $item->author ); ?>, type: <?php echo esc_html( $item->post_format ); ?>):
1965 <?php if ( $title ) : ?>
1966 <a href="<?php echo esc_url( $item->permalink ); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html( $title ); ?></a> <?php echo esc_html( str_word_count( wp_strip_all_tags( $item->content ) ) ); ?> words
1967 <?php else : ?>
1968 <p>
1969 <?php
1970 echo wp_kses(
1971 wp_trim_excerpt( $item->content ),
1972 array(
1973 'a' => array( 'href' => array() ),
1974 'img' => array( 'src' => array() ),
1975 )
1976 );
1977 ?>
1978 </p>
1979 <?php endif; ?>
1980 </li>
1981 <?php
1982 }
1983 ?>
1984 </ul>
1985 <?php
1986 return;
1987 }
1988
1989 if ( apply_filters( 'friends_debug', false ) && isset( $_GET['next'] ) ) {
1990 $_POST = $_REQUEST;
1991 $_POST['_wpnonce'] = wp_create_nonce( 'add-friend' );
1992 if ( ! empty( $_POST['url'] ) && ! isset( $_POST['friend_url'] ) ) {
1993 $_POST['friend_url'] = $_POST['url'];
1994 $parsed_url = parse_url( $_POST['friend_url'] );
1995 if ( isset( $parsed_url['host'] ) ) {
1996 if ( ! isset( $parsed_url['scheme'] ) ) {
1997 $_POST['friend_url'] = 'https://' . ltrim( $_POST['friend_url'], '/' );
1998 }
1999 }
2000 }
2001 }
2002
2003 $response = null;
2004 $postdata = apply_filters( 'friends_add_friend_postdata', $_POST );
2005 if ( ! empty( $postdata ) ) {
2006 if ( ! wp_verify_nonce( $postdata['_wpnonce'], 'add-friend' ) ) {
2007 $response = new \WP_Error( 'invalid-nonce', __( 'For security reasons, please verify the URL and click next if you want to proceed.', 'friends' ) );
2008 } else {
2009 $response = $this->process_admin_add_friend( $postdata );
2010 }
2011 if ( is_wp_error( $response ) ) {
2012 ?>
2013 <div id="message" class="updated notice is-dismissible"><p>
2014 <?php
2015 $message = $response->get_error_message();
2016 if ( $response->get_error_data() ) {
2017 $message .= ' (' . $response->get_error_data() . ')';
2018 }
2019 echo wp_kses(
2020 $message,
2021 array(
2022 'strong' => array(),
2023 'a' => array(
2024 'href' => array(),
2025 'rel' => array(),
2026 'target' => array(),
2027 ),
2028 )
2029 );
2030 ?>
2031 </p>
2032 </div>
2033 <?php
2034 }
2035 if ( is_null( $response ) ) {
2036 return;
2037 }
2038 }
2039
2040 $args = array(
2041 'friend_url' => '',
2042 'add-friends-placeholder' => apply_filters( 'friends_add_friends_input_placeholder', __( 'Enter URL', 'friends' ) ),
2043 );
2044
2045 if ( ! empty( $_GET['url'] ) || ! empty( $_POST['url'] ) ) {
2046 $friend_url = isset( $_GET['url'] ) ? $_GET['url'] : $_POST['url'];
2047 $parsed_url = parse_url( $friend_url );
2048 if ( isset( $parsed_url['host'] ) ) {
2049 if ( ! isset( $parsed_url['scheme'] ) ) {
2050 $args['friend_url'] = apply_filters( 'friends_rewrite_incoming_url', 'https://' . ltrim( $friend_url, '/' ), $friend_url, $parsed_url );
2051 } else {
2052 $args['friend_url'] = $friend_url;
2053 }
2054 } elseif ( preg_match( '/^@?' . Feed_Parser_ActivityPub::ACTIVITYPUB_USERNAME_REGEXP . '$/i', $friend_url ) ) {
2055 $args['friend_url'] = $friend_url;
2056 }
2057 }
2058
2059 Friends::template_loader()->get_template_part(
2060 'admin/settings-header',
2061 null,
2062 array(
2063 'active' => 'add-friend',
2064 'title' => __( 'Add New Friend', 'friends' ),
2065 'menu' => array(
2066 '1. ' . __( 'Enter Details', 'friends' ) => 'add-friend' . ( isset( $friend_url ) ? '&url=' . urlencode( $friend_url ) : '' ),
2067 '2. ' . __( 'Confirm', 'friends' ) => false,
2068 ),
2069 )
2070 );
2071
2072 Friends::template_loader()->get_template_part( 'admin/add-friend', null, $args );
2073
2074 Friends::template_loader()->get_template_part(
2075 'admin/latest-friends',
2076 null,
2077 array(
2078 'friend_requests' => User_Query::recent_friends_subscriptions( 25 )->get_results(),
2079 )
2080 );
2081 Friends::template_loader()->get_template_part( 'admin/settings-footer', null, $args );
2082 }
2083
2084 /**
2085 * Process the admin notification manager form submission.
2086 */
2087 public function process_admin_notification_manager() {
2088
2089 if ( empty( $_POST ) || empty( $_POST['friend_listed'] ) ) {
2090 return;
2091 }
2092
2093 if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'notification-manager' ) ) {
2094 return;
2095 }
2096
2097 $this->check_admin_settings();
2098
2099 if ( isset( $_POST['notification_keywords'] ) && $_POST['notification_keywords'] ) {
2100 $keywords = array();
2101 foreach ( $_POST['notification_keywords'] as $i => $keyword ) {
2102 if ( trim( $keyword ) ) {
2103 $keywords[] = array(
2104 'enabled' => isset( $_POST['notification_keywords_enabled'][ $i ] ) && $_POST['notification_keywords_enabled'][ $i ],
2105 'keyword' => $keyword,
2106 );
2107 }
2108 }
2109 update_option( 'friends_notification_keywords', $keywords );
2110 }
2111
2112 if ( isset( $_POST['new_post_notification'] ) && $_POST['new_post_notification'] ) {
2113 delete_user_option( get_current_user_id(), 'friends_no_new_post_notification' );
2114 } else {
2115 update_user_option( get_current_user_id(), 'friends_no_new_post_notification', 1 );
2116 }
2117
2118 $friend_ids = $_POST['friend_listed'];
2119 $current_user_id = get_current_user_id();
2120 $hide_from_friends_page = array();
2121
2122 foreach ( $friend_ids as $friend_id ) {
2123 if ( ! isset( $_POST['show_on_friends_page'][ $friend_id ] ) ) {
2124 $hide_from_friends_page[] = $friend_id;
2125 }
2126
2127 $no_new_post_notification = ! isset( $_POST['new_friend_post_notification'][ $friend_id ] ) || '0' === $_POST['new_friend_post_notification'][ $friend_id ];
2128 if ( get_user_option( 'friends_no_new_post_notification_' . $friend_id ) !== $no_new_post_notification ) {
2129 update_user_option( $current_user_id, 'friends_no_new_post_notification_' . $friend_id, $no_new_post_notification );
2130 }
2131
2132 $no_keyword_notification = ! isset( $_POST['keyword_notification'][ $friend_id ] );
2133 if ( get_user_option( 'friends_no_keyword_notification_' . $friend_id ) !== $no_keyword_notification ) {
2134 update_user_option( $current_user_id, 'friends_no_keyword_notification_' . $friend_id, $no_keyword_notification );
2135 }
2136 }
2137
2138 update_user_option( $current_user_id, 'friends_hide_from_friends_page', $hide_from_friends_page );
2139
2140 do_action( 'friends_notification_manager_after_form_submit', $friend_ids );
2141
2142 if ( isset( $_GET['_wp_http_referer'] ) ) {
2143 wp_safe_redirect( wp_get_referer() );
2144 } else {
2145 wp_safe_redirect( add_query_arg( 'updated', '1', remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
2146 }
2147 exit;
2148 }
2149
2150 /**
2151 * Render the admin notification manager.
2152 */
2153 public function render_admin_notification_manager() {
2154 Friends::template_loader()->get_template_part(
2155 'admin/settings-header',
2156 null,
2157 array(
2158 'active' => 'friends-notification-manager',
2159 'title' => __( 'Friends', 'friends' ),
2160 )
2161 );
2162 $this->check_admin_settings();
2163
2164 ?>
2165 <h1><?php esc_html_e( 'Notification Manager', 'friends' ); ?></h1>
2166 <?php
2167
2168 $friend_users = new User_Query(
2169 array(
2170 'role__in' => array( 'friend', 'acquaintance', 'pending_friend_request', 'friend_request', 'subscription' ),
2171 'orderby' => 'display_name',
2172 'order' => 'ASC',
2173 )
2174 );
2175
2176 $hide_from_friends_page = get_user_option( 'friends_hide_from_friends_page' );
2177 if ( ! $hide_from_friends_page ) {
2178 $hide_from_friends_page = array();
2179 }
2180
2181 Friends::template_loader()->get_template_part(
2182 'admin/notification-manager',
2183 null,
2184 array(
2185 'friend_users' => $friend_users->get_results(),
2186 'friends_settings_url' => add_query_arg( '_wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), self_admin_url( 'admin.php?page=friends-settings' ) ),
2187 'hide_from_friends_page' => $hide_from_friends_page,
2188 'no_friend_request_notification' => get_user_option( 'friends_no_friend_request_notification' ),
2189 'no_new_post_notification' => get_user_option( 'friends_no_new_post_notification' ),
2190 'no_keyword_notification' => get_user_option( 'friends_no_keyword_notification' ),
2191 'notification_keywords' => Feed::get_all_notification_keywords(),
2192 'active_keywords' => Feed::get_active_notification_keywords(),
2193 )
2194 );
2195
2196 Friends::template_loader()->get_template_part( 'admin/settings-footer' );
2197 }
2198
2199 public function maybe_remove_friendship_settings( $items ) {
2200 if ( ! get_option( 'friends_enable_wp_friendships' ) ) {
2201 unset( $items[ __( 'Friendships', 'friends' ) ] );
2202 }
2203 return $items;
2204 }
2205
2206 public function render_admin_wp_friendship_settings() {
2207 Friends::template_loader()->get_template_part(
2208 'admin/settings-header',
2209 null,
2210 array(
2211 'active' => 'friends-wp-friendships',
2212 'title' => __( 'Friends', 'friends' ),
2213 )
2214 );
2215 $this->check_admin_settings();
2216
2217 // In order to switch to the frontend locale, we need to first pretend that nothing was loaded yet.
2218 global $l10n;
2219 $l10n = array();
2220
2221 switch_to_locale( $this->get_frontend_locale() );
2222 // Now while loading the next translations we need to ensure that determine_locale() doesn't return the admin language but the frontend language.
2223 add_filter( 'pre_determine_locale', array( $this, 'get_frontend_locale' ) );
2224
2225 $wrong_codeword_message = __( 'An invalid codeword was provided.', 'friends' );
2226 $comment_registration_message = __( 'Only people in my network can comment.', 'friends' );
2227 $my_network = __( 'my network', 'friends' );
2228 $comment_registration_default = strip_tags(
2229 /* translators: %s: Login URL. */
2230 __( 'You must be <a href="%s">logged in</a> to post a comment.' ) // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
2231 );
2232 // Now let's switch back to the admin language.
2233 remove_filter( 'pre_determine_locale', array( $this, 'get_frontend_locale' ) );
2234 restore_previous_locale();
2235
2236 ?>
2237 <h1><?php esc_html_e( 'Friendships', 'friends' ); ?></h1>
2238 <?php
2239
2240 Friends::template_loader()->get_template_part(
2241 'admin/settings-wp-friendships',
2242 null,
2243 array(
2244 'potential_main_users' => User_Query::all_admin_users(),
2245 'main_user_id' => Friends::get_main_friend_user_id(),
2246 'friend_roles' => $this->get_friend_roles(),
2247 'default_role' => get_option( 'friends_default_friend_role', 'friend' ),
2248 'comment_registration' => get_option( 'comment_registration' ), // WordPress option.
2249 'comment_registration_message' => get_option( 'friends_comment_registration_message', $comment_registration_message ),
2250 'comment_registration_default' => $comment_registration_default,
2251 'my_network' => $my_network,
2252 'public_profile_link' => home_url( '/friends/' ),
2253 'codeword' => get_option( 'friends_codeword', 'friends' ),
2254 'require_codeword' => get_option( 'friends_require_codeword' ),
2255 'wrong_codeword_message' => get_option( 'friends_wrong_codeword_message', $wrong_codeword_message ),
2256 )
2257 );
2258
2259 Friends::template_loader()->get_template_part( 'admin/settings-footer' );
2260 }
2261 public function process_admin_wp_friendship_settings() {
2262 if ( current_user_can( 'manage_options' ) ) {
2263
2264 if ( isset( $_POST['main_user_id'] ) && is_numeric( $_POST['main_user_id'] ) ) {
2265 update_option( 'friends_main_user_id', intval( $_POST['main_user_id'] ) );
2266 } else {
2267 $main_user_id = Friends::get_main_friend_user_id();
2268 $main_user_id_exists = false;
2269 $users = User_Query::all_admin_users();
2270 foreach ( $users->get_results() as $user ) {
2271 if ( $user->ID === $main_user_id ) {
2272 $main_user_id_exists = true;
2273 break;
2274 }
2275 }
2276 if ( ! $main_user_id_exists ) {
2277 // Reset the main user id.
2278 delete_option( 'friends_main_user_id' );
2279 Friends::get_main_friend_user_id();
2280 }
2281 }
2282
2283 if ( isset( $_POST['require_codeword'] ) && $_POST['require_codeword'] ) {
2284 update_option( 'friends_require_codeword', true );
2285 } else {
2286 delete_option( 'friends_require_codeword' );
2287 }
2288
2289 if ( isset( $_POST['codeword'] ) && $_POST['codeword'] ) {
2290 update_option( 'friends_codeword', $_POST['codeword'] );
2291 } else {
2292 delete_option( 'friends_codeword' );
2293 }
2294
2295 if ( isset( $_POST['wrong_codeword_message'] ) && $_POST['wrong_codeword_message'] ) {
2296 update_option( 'friends_wrong_codeword_message', $_POST['wrong_codeword_message'] );
2297 } else {
2298 delete_option( 'friends_wrong_codeword_message' );
2299 }
2300
2301 if ( isset( $_POST['default_role'] ) && in_array( $_POST['default_role'], array( 'friend', 'acquaintance' ), true ) ) {
2302 update_option( 'friends_default_friend_role', $_POST['default_role'] );
2303 }
2304
2305 if ( isset( $_POST['comment_registration'] ) && $_POST['comment_registration'] ) {
2306 update_option( 'comment_registration', true );
2307 } else {
2308 delete_option( 'comment_registration' );
2309 }
2310
2311 if ( isset( $_POST['comment_registration_message'] ) && $_POST['comment_registration_message'] ) {
2312 update_option( 'friends_comment_registration_message', $_POST['comment_registration_message'] );
2313 } else {
2314 delete_option( 'friends_comment_registration_message' );
2315 }
2316 }
2317 }
2318 public function render_admin_import_export() {
2319 Friends::template_loader()->get_template_part(
2320 'admin/settings-header',
2321 null,
2322 array(
2323 'active' => 'friends-import-export',
2324 'title' => __( 'Friends', 'friends' ),
2325 )
2326 );
2327 $this->check_admin_settings();
2328
2329 ?>
2330 <h1><?php esc_html_e( 'Import/Export', 'friends' ); ?></h1>
2331 <?php
2332
2333 Friends::template_loader()->get_template_part(
2334 'admin/import-export',
2335 null,
2336 array(
2337 'private_rss_key' => get_option( 'friends_private_rss_key' ),
2338 )
2339 );
2340
2341 Friends::template_loader()->get_template_part( 'admin/settings-footer' );
2342 }
2343
2344 public function process_admin_import_export() {
2345 }
2346
2347 /**
2348 * Gets the friend roles.
2349 *
2350 * @return array The friend roles.
2351 */
2352 public function get_friend_roles() {
2353 $roles = new \WP_Roles();
2354 $friend_roles = array();
2355 foreach ( $roles->roles as $role => $data ) {
2356 if ( isset( $data['capabilities']['friend'] ) ) {
2357 $friend_roles[ $role ] = $data['name'];
2358 }
2359 }
2360 return $friend_roles;
2361 }
2362
2363 /**
2364 * Gets the roles associated with the Friends plugin.
2365 *
2366 * @return array The associated roles.
2367 */
2368 public static function get_associated_roles() {
2369 $roles = new \WP_Roles();
2370 $friend_roles = array();
2371 foreach ( $roles->roles as $role => $data ) {
2372 if ( isset( $data['capabilities']['friends_plugin'] ) ) {
2373 $friend_roles[ $role ] = $data['name'];
2374 }
2375 }
2376 return $friend_roles;
2377 }
2378
2379 public static function get_users_url() {
2380 return 'admin.php?page=friends-list';
2381 }
2382
2383 /**
2384 * Add actions to the user rows
2385 *
2386 * @param array $actions The existing actions.
2387 * @param \WP_User $user The user in question.
2388 * @return array The extended actions.
2389 */
2390 public static function user_row_actions( array $actions, \WP_User $user ) {
2391 if (
2392 ! Friends::has_required_privileges() ||
2393 (
2394 ! $user->has_cap( 'friend_request' ) &&
2395 ! $user->has_cap( 'pending_friend_request' ) &&
2396 ! $user->has_cap( 'friend' ) &&
2397 ! $user->has_cap( 'subscription' )
2398 )
2399 ) {
2400 return $actions;
2401 }
2402
2403 if ( is_multisite() ) {
2404 // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
2405 $actions = array_merge( array( 'edit' => '<a href="' . esc_url( self_admin_url( 'admin.php?page=edit-friend&user=' . $user->user_login ) ) . '">' . __( 'Edit' ) . '</a>' ), $actions );
2406 }
2407
2408 // Ensuire we have a friends user here.
2409 $user = new User( $user );
2410
2411 $actions['view'] = Frontend::get_link(
2412 $user->user_url,
2413 sprintf(
2414 // translators: %s: Author’s display name.
2415 __( 'Visit %s&#8217;s website' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
2416 $user->display_name
2417 ),
2418 array(),
2419 $user
2420 );
2421 unset( $actions['resetpassword'] );
2422
2423 if ( $user->has_cap( 'friend_request' ) ) {
2424 $link = self_admin_url( wp_nonce_url( 'users.php?action=accept_friend_request&users[]=' . $user->ID ) );
2425
2426 $actions['user_accept_friend_request'] = '<a href="' . esc_url( $link ) . '">' . __( 'Accept Friend Request', 'friends' ) . '</a>';
2427 $message = get_user_option( 'friends_request_message', $user->ID );
2428 $actions['friends friends_request_date'] = '<br/><span class="nonessential">' . esc_html(
2429 sprintf(
2430 // translators: %s is a date.
2431 __( 'Requested on %s', 'friends' ),
2432 date_i18n( __( 'F j, Y g:i a' ), strtotime( $user->user_registered ) ) // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
2433 )
2434 ) . '</span>';
2435 if ( $message ) {
2436 // translators: %s is a message text.
2437 $actions['friends friend_request_message'] = '<br/><span class="nonessential">' . esc_html( sprintf( __( 'Message: %s', 'friends' ), $message ) ) . '</span>';
2438 }
2439 }
2440
2441 if ( $user->has_cap( 'pending_friend_request' ) || $user->has_cap( 'subscription' ) ) {
2442 $link = wp_nonce_url( add_query_arg( '_wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), self_admin_url( 'admin.php?page=edit-friend&user=' . $user->user_login ) ), 'add-friend-' . $user->user_login, 'add-friend' );
2443 if ( $user->has_cap( 'pending_friend_request' ) ) {
2444 $actions['user_friend_request'] = '<a href="' . esc_url( $link ) . '">' . __( 'Resend Friend Request', 'friends' ) . '</a>';
2445 } elseif ( $user->has_cap( 'subscription' ) ) {
2446 $actions['user_friend_request'] = '<a href="' . esc_url( $link ) . '">' . __( 'Send Friend Request', 'friends' ) . '</a>';
2447 }
2448 }
2449
2450 return $actions;
2451 }
2452
2453 /**
2454 * Handle bulk friend request approvals on the user page
2455 *
2456 * @param string $sendback The URL to send the user back to.
2457 * @param string $action The requested action.
2458 * @param array $users The selected users.
2459 */
2460 public function handle_bulk_friend_request_approval( $sendback, $action, $users ) {
2461 if ( 'accept_friend_request' !== $action ) {
2462 return $sendback;
2463 }
2464
2465 $accepted = 0;
2466 foreach ( $users as $user_id ) {
2467 $user = new User( $user_id );
2468 if ( ! $user || is_wp_error( $user ) ) {
2469 continue;
2470 }
2471
2472 if ( ! $user->has_cap( 'friend_request' ) ) {
2473 continue;
2474 }
2475
2476 if ( $user->has_cap( 'friend' ) ) {
2477 continue;
2478 }
2479
2480 $user->set_role( get_option( 'friends_default_friend_role', 'friend' ) );
2481 ++$accepted;
2482 }
2483
2484 if ( ! $sendback ) {
2485 return array(
2486 'accepted' => $accepted,
2487 );
2488 }
2489
2490 $sendback = add_query_arg( 'accepted', $accepted, $sendback );
2491 $sendback = remove_query_arg( 'role', $sendback );
2492 wp_safe_redirect( $sendback );
2493 }
2494
2495 /**
2496 * Add options to the Bulk dropdown on the users page
2497 *
2498 * @param array $actions The existing bulk options.
2499 * @return array The extended bulk options.
2500 */
2501 public function add_user_bulk_options( $actions ) {
2502 $friends = User_Query::all_friend_requests();
2503 $friends->get_results();
2504
2505 if ( ! empty( $friends ) ) {
2506 $actions['accept_friend_request'] = __( 'Accept Friend Request', 'friends' );
2507 }
2508
2509 $friends = User_Query::all_subscriptions();
2510 $friends->get_results();
2511
2512 if ( ! empty( $friends ) ) {
2513 $actions['friend_request'] = __( 'Send Friend Request', 'friends' );
2514 }
2515
2516 return $actions;
2517 }
2518
2519 /**
2520 * Add a column "Posts" (that emcompasses both user and friend posts.)
2521 *
2522 * @param array $columns The columns.
2523 *
2524 * @return array The columns extended by the friends_posts.
2525 */
2526 public function user_list_columns( $columns ) {
2527 $columns['friends_posts'] = __( 'Friend Posts', 'friends' );
2528 unset( $columns['email'] );
2529 return $columns;
2530 }
2531
2532 /**
2533 * Return the results for the friends_posts column.
2534 *
2535 * @param string $output Custom column output. Default empty.
2536 * @param string $column_name Column name.
2537 * @param int $user_id ID of the currently-listed user.
2538 *
2539 * @return string The column contents.
2540 */
2541 public static function user_list_custom_column( $output, $column_name, $user_id ) {
2542 if ( 'friends_posts' !== $column_name ) {
2543 return $output;
2544 }
2545 $numposts = count_user_posts( $user_id, apply_filters( 'friends_frontend_post_types', array( 'post' ) ) );
2546 $user = User::get_user_by_id( $user_id );
2547 return sprintf(
2548 '<a href="%s" class="edit"><span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
2549 $user ? $user->get_local_friends_page_url() : "edit.php?author={$user_id}",
2550 $numposts,
2551 sprintf(
2552 /* translators: %s: Number of posts. */
2553 _n( '%s post', '%s posts', $numposts ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
2554 number_format_i18n( $numposts )
2555 )
2556 );
2557 }
2558
2559 /**
2560 * Override the post title for specific post formats.
2561 *
2562 * @param string $title The title.
2563 * @param int $post_id The post id.
2564 *
2565 * @return string The potentially overriden title.
2566 */
2567 public function override_post_format_title( $title, $post_id = null ) {
2568 if ( $post_id && empty( $title ) && is_admin() && function_exists( 'get_current_screen' ) ) {
2569 $screen = get_current_screen();
2570 if ( $screen && 'edit-post' === $screen->id ) {
2571 if ( 'status' === get_post_format() ) {
2572 $post = get_post( $post_id );
2573 return wp_trim_words( wp_strip_all_tags( $post->post_content ) );
2574 }
2575 }
2576 }
2577 return $title;
2578 }
2579
2580 /**
2581 * Adds the friend requests to the unread count.
2582 *
2583 * @param int $unread The unread count.
2584 *
2585 * @return int Unread count + friend requests.
2586 */
2587 public function friends_unread_friend_request_count( $unread ) {
2588 $friend_requests = User_Query::all_friend_requests();
2589 return $unread + $friend_requests->get_total();
2590 }
2591
2592 /**
2593 * Add open friend requests to the menu.
2594 *
2595 * @param \WP_Menu $wp_menu The wp menu.
2596 * @param string $my_url My url.
2597 */
2598 public function friends_add_menu_open_friend_request( $wp_menu, $my_url ) {
2599 $friend_request_count = $this->friends_unread_friend_request_count( 0 );
2600 if ( $friend_request_count > 0 ) {
2601 $wp_menu->add_menu(
2602 array(
2603 'id' => 'open-friend-requests',
2604 'parent' => 'friends-menu',
2605 // translators: %s is the number of open friend requests.
2606 'title' => esc_html( sprintf( _n( 'Review %s Friend Request', 'Review %s Friends Request', $friend_request_count, 'friends' ), $friend_request_count ) ),
2607 'href' => $my_url . '/wp-admin/admin.php?page=friends-list-requests',
2608 )
2609 );
2610 }
2611 }
2612
2613 /**
2614 * Get the unread badge HTML
2615 *
2616 * @return string The unread badge HTML.
2617 */
2618 public function get_unread_badge() {
2619 $unread_count = apply_filters( 'friends_unread_count', 0 );
2620 if ( 0 === intval( $unread_count ) ) {
2621 return '';
2622 }
2623
2624 if ( get_user_option( 'friends_unobtrusive_badge' ) ) {
2625 return ' (' . $unread_count . ')';
2626 }
2627 $unread_badge = ' <div class="wp-core-ui wp-ui-notification friends-open-requests" style="display: inline; font-size: 11px; padding: .1em .5em .1em .4em; border-radius: 9px; background-color: #d63638; color: #fff; text-align: center; height: 18px"><span aria-hidden="true">' . $unread_count . '</span><span class="screen-reader-text">';
2628 // translators: %s is the number of unread items.
2629 $unread_badge .= sprintf( _n( '%s unread item', '%s unread items', $unread_count, 'friends' ), $unread_count );
2630 $unread_badge .= '</span></div>';
2631 return $unread_badge;
2632 }
2633
2634 /**
2635 * Add a Friends menu to the admin bar
2636 *
2637 * @param \WP_Admin_Bar $wp_menu The admin bar to modify.
2638 */
2639 public function admin_bar_friends_menu( \WP_Admin_Bar $wp_menu ) {
2640 $my_url = false;
2641 $my_own_site = false;
2642 $on_my_own_site = false;
2643 $we_requested_friendship = false;
2644 $they_requested_friendship = false;
2645
2646 if ( current_user_can( 'friend' ) ) {
2647 $current_user = wp_get_current_user();
2648 if ( ! $current_user->user_url ) {
2649 return;
2650 }
2651
2652 $my_url = $current_user->user_url;
2653 } elseif ( is_multisite() ) {
2654 $site = get_active_blog_for_user( get_current_user_id() );
2655 if ( ! $site ) {
2656 // If we cannot find a site, we shouldn't show the admin bar entry.
2657 return;
2658 }
2659
2660 $my_url = set_url_scheme( $site->siteurl );
2661 $my_own_site = $site;
2662 $on_my_own_site = get_current_blog_id() === intval( $site->blog_id );
2663 if ( is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
2664 if ( current_user_can( 'pending_friend_request' ) ) {
2665 $they_requested_friendship = true;
2666 } elseif ( current_user_can( 'friend_request' ) ) {
2667 $we_requested_friendship = true;
2668 }
2669 }
2670 } elseif ( Friends::has_required_privileges() ) {
2671 $my_url = home_url();
2672 $on_my_own_site = true;
2673 }
2674
2675 if ( ! $on_my_own_site && $my_own_site ) {
2676 switch_to_blog( $my_own_site->blog_id );
2677 }
2678
2679 $unread = '';
2680 if ( $on_my_own_site ) {
2681 $unread = $this->get_unread_badge();
2682 }
2683 $wp_menu->add_node(
2684 array(
2685 'id' => 'friends-menu',
2686 'parent' => '',
2687 'title' => '<span class="ab-icon dashicons dashicons-groups"></span> <span class="ab-label">' . esc_html( __( 'Friends', 'friends' ) ) . $unread . '</span>',
2688 'href' => $my_url . '/friends/',
2689 )
2690 );
2691
2692 if ( $on_my_own_site ) {
2693 do_action( 'friends_own_site_menu_top', $wp_menu, $my_url );
2694 }
2695
2696 if ( ! $on_my_own_site && $my_own_site ) {
2697 restore_current_blog();
2698 }
2699
2700 do_action( 'friends_current_site_menu_top', $wp_menu, $my_url );
2701
2702 $wp_menu->add_menu(
2703 array(
2704 'id' => 'your-feed',
2705 'parent' => 'friends-menu',
2706 'title' => esc_html__( 'My Friends Feed', 'friends' ),
2707 'href' => $my_url . '/friends/',
2708 )
2709 );
2710
2711 if ( $they_requested_friendship ) {
2712 $wp_menu->add_menu(
2713 array(
2714 'id' => 'add-friend',
2715 'parent' => 'friends-menu',
2716 'title' => '<span style="border-left: 2px solid #d63638; padding-left: .5em">' . esc_html(
2717 sprintf(
2718 // translators: %s is a site title.
2719 __( "Respond to %s's friend request", 'friends' ),
2720 get_bloginfo( 'name' )
2721 ) . '</span>'
2722 ),
2723 'href' => $my_url . '/wp-admin/admin.php?page=friends-list-requests',
2724 )
2725 );
2726 }
2727
2728 if ( $on_my_own_site ) {
2729 $wp_menu->add_menu(
2730 array(
2731 'id' => 'your-profile',
2732 'parent' => 'friends-menu',
2733 'title' => esc_html__( 'My Public Friends Profile', 'friends' ),
2734 'href' => $my_url . '/friends/?public',
2735 )
2736 );
2737 $wp_menu->add_menu(
2738 array(
2739 'id' => 'friends-requests',
2740 'parent' => 'friends-menu',
2741 'title' => esc_html__( 'My Friends & Requests', 'friends' ),
2742 'href' => $my_url . '/wp-admin/admin.php?page=friends-list',
2743 )
2744 );
2745 $wp_menu->add_menu(
2746 array(
2747 'id' => 'friends',
2748 'parent' => 'friends-menu',
2749 'title' => esc_html__( 'Settings' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
2750 'href' => $my_url . '/wp-admin/admin.php?page=friends-settings',
2751 )
2752 );
2753 } else {
2754 if ( ! current_user_can( 'friend' ) ) {
2755 if ( $we_requested_friendship ) {
2756 $wp_menu->add_menu(
2757 array(
2758 'id' => 'add-friend',
2759 'parent' => 'friends-menu',
2760 'title' => esc_html__( 'Friendship Already Requested', 'friends' ),
2761 'href' => $my_url . '/wp-admin/' . self::get_users_url(),
2762 )
2763 );
2764 } elseif ( ! $they_requested_friendship ) {
2765 $wp_menu->add_menu(
2766 array(
2767 'id' => 'add-friend',
2768 'parent' => 'friends-menu',
2769 'title' => esc_html(
2770 sprintf(
2771 // translators: %s is a site title.
2772 __( 'Add %s as a friend', 'friends' ),
2773 get_bloginfo( 'name' )
2774 )
2775 ),
2776 'href' => $my_url . '/?add-friend=' . urlencode( home_url() ),
2777 )
2778 );
2779 }
2780 }
2781
2782 $wp_menu->add_menu(
2783 array(
2784 'id' => 'profile',
2785 'parent' => 'friends-menu',
2786 'title' => esc_html(
2787 sprintf(
2788 // translators: %s is a site title.
2789 __( "%s's Profile", 'friends' ),
2790 get_bloginfo( 'name' )
2791 )
2792 ),
2793 'href' => home_url( '/friends/' ),
2794 )
2795 );
2796 }
2797 }
2798
2799 /**
2800 * Add Friend entries to the New Content admin section
2801 *
2802 * @param \WP_Admin_Bar $wp_menu The admin bar to modify.
2803 */
2804 public function admin_bar_new_content( \WP_Admin_Bar $wp_menu ) {
2805 if ( Friends::has_required_privileges() ) {
2806 $wp_menu->add_menu(
2807 array(
2808 'id' => 'new-friend-request',
2809 'parent' => 'new-content',
2810 'title' => esc_html__( 'Friend', 'friends' ),
2811 'href' => self_admin_url( 'admin.php?page=add-friend' ),
2812 )
2813 );
2814 $wp_menu->add_menu(
2815 array(
2816 'id' => 'new-subscription',
2817 'parent' => 'new-content',
2818 'title' => esc_html__( 'Subscription', 'friends' ),
2819 'href' => self_admin_url( 'admin.php?page=add-friend' ),
2820 )
2821 );
2822 }
2823 }
2824
2825 /**
2826 * Show friends admin bar item on mobile.
2827 */
2828 public function admin_bar_mobile() {
2829 if ( ! is_user_logged_in() ) {
2830 return;
2831 }
2832 ?>
2833 <style type="text/css" media="screen">
2834 @media screen and (max-width: 782px) {
2835 #wpadminbar #wp-admin-bar-friends, #wpadminbar #wp-admin-bar-friends .ab-icon {
2836 display: block !important;
2837 }
2838 #wpadminbar #wp-admin-bar-friends .ab-label {
2839 display: none !important;
2840 }
2841 }
2842 </style>
2843 <?php
2844 }
2845
2846
2847 /**
2848 * Fires at the end of the delete users form prior to the confirm button.
2849 *
2850 * @param \WP_User $current_user \WP_User object for the current user.
2851 * @param array $userids Array of IDs for users being deleted.
2852 */
2853 public function delete_user_form( $current_user, $userids ) {
2854 $only_friends_affiliated = true;
2855 foreach ( $userids as $user_id ) {
2856 $user = new \WP_User( $user_id );
2857 if (
2858 ! $user->has_cap( 'friend_request' ) &&
2859 ! $user->has_cap( 'pending_friend_request' ) &&
2860 ! $user->has_cap( 'friend' ) &&
2861 ! $user->has_cap( 'subscription' )
2862 ) {
2863 $only_friends_affiliated = false;
2864 break;
2865 }
2866 }
2867
2868 if ( $only_friends_affiliated ) {
2869 ?>
2870 <script type="text/javascript">
2871 jQuery( function () {
2872 jQuery( '#delete_option1' ).closest( 'li' ).hide();
2873 } );
2874 </script>
2875 <?php
2876 }
2877 }
2878
2879 /**
2880 * Actions when a (friend) user is deleted.
2881 *
2882 * @param integer $user_id The user identifier.
2883 */
2884 public function delete_user( $user_id ) {
2885 $friend_user = User::get_user_by_id( $user_id );
2886 if ( ! $friend_user ) {
2887 return; // user was already deleted?
2888 }
2889 // Allow unsubscribing to all these feeds.
2890 foreach ( $friend_user->get_active_feeds() as $feed ) {
2891 do_action( 'friends_user_feed_deactivated', $feed );
2892 $feed->delete();
2893 }
2894
2895 // Delete the rest.
2896 foreach ( $friend_user->get_feeds() as $feed ) {
2897 $feed->delete();
2898 }
2899
2900 foreach ( $friend_user->get_all_post_ids() as $post_id ) {
2901 wp_delete_post( $post_id );
2902 }
2903 }
2904
2905 /**
2906 * Display the Bookmarklets at the Tools section of wp-admin
2907 */
2908 public function toolbox_bookmarklets() {
2909 ?>
2910 <div class="card">
2911 <h2 class="title"><?php esc_html_e( 'Friends', 'friends' ); ?></h2>
2912 <h3><?php esc_html_e( 'Bookmarklets', 'friends' ); ?></h3>
2913
2914 <p><?php esc_html_e( "Drag one of these bookmarklets to your bookmarks bar and click it when you're on a site around the web for the appropriate action.", 'friends' ); ?></p>
2915 <p>
2916 <a href="javascript:void(location.href='<?php echo esc_attr( self_admin_url( 'admin.php?page=add-friend&url=' ) ); ?>'+encodeURIComponent(location.href))" style="display: inline-block; padding: .5em; border: 1px solid #999; border-radius: 4px; background-color: #ddd;text-decoration: none; margin-right: 3em"><?php echo esc_html_e( 'Add friend', 'friends' ); ?></a>
2917 <a href="javascript:void(location.href='<?php echo esc_attr( self_admin_url( 'admin.php?page=add-friend&url=' ) ); ?>'+encodeURIComponent(location.href))" style="display: inline-block; padding: .5em; border: 1px solid #999; border-radius: 4px; background-color: #ddd; text-decoration: none; margin-right: 3em"><?php echo esc_html_e( 'Subscribe', 'friends' ); ?></a>
2918 </p>
2919 <h3><?php esc_html_e( 'Browser Extension', 'friends' ); ?></h3>
2920
2921 <p><?php esc_html_e( 'There is also the option to use a browser extension.', 'friends' ); ?></p>
2922 <p>
2923 <a href="https://addons.mozilla.org/en-US/firefox/addon/wpfriends/"><?php echo esc_html_e( 'Firefox Extension', 'friends' ); ?></a>
2924 </p>
2925 </div>
2926 <?php
2927 }
2928
2929 /**
2930 * Add more "at a glance" items
2931
2932 * @param array $items Items inserted by another plugin.
2933 * @return array Items + our items.
2934 */
2935 public function dashboard_glance_items( $items ) {
2936 $count_users = count_users();
2937 $count = array_merge(
2938 array(
2939 'friend' => 0,
2940 'acquaintance' => 0,
2941 'friend_request' => 0,
2942 'subscription' => 0,
2943 ),
2944 $count_users['avail_roles']
2945 );
2946 $friend_count = $count['friend'] + $count['acquaintance'];
2947 $friend_request_count = $count['friend_request'];
2948 $subscription_count = $count['subscription'];
2949 $friend_post_count = wp_count_posts( Friends::CPT );
2950 $friend_post_count = $friend_post_count->publish + $friend_post_count->private;
2951
2952 $items[] = '<a class="friends" href="' . self_admin_url( 'users.php?role=friend' ) . '">' . sprintf(
2953 // translators: %s is the number of your friends.
2954 _n( '%s Friend', '%s Friends', $friend_count, 'friends' ),
2955 $friend_count
2956 ) . '</a>';
2957 if ( $friend_request_count ) {
2958 // translators: %s is the number of friend requests.
2959 $items[] = '<a class="friend-requests" href="' . self_admin_url( 'users.php?role=friend_request' ) . '">' . sprintf( _n( '%s Friend Request', '%s Friend Requests', $friend_request_count, 'friends' ), $friend_request_count ) . '</a>';
2960 }
2961 if ( $subscription_count ) {
2962 // translators: %s is the number of subscriptions.
2963 $items[] = '<a class="subscriptions" href="' . self_admin_url( 'users.php?role=subscription' ) . '">' . sprintf( _n( '%s Subscription', '%s Subscriptions', $subscription_count, 'friends' ), $subscription_count ) . '</a>';
2964 }
2965
2966 if ( $friend_post_count ) {
2967 // translators: %s is the number of friend posts.
2968 $items[] = '<a class="friend-posts" href="' . home_url( '/friends/' ) . '">' . sprintf( _n( '%s Post by Friends', '%s Posts by Friends', $friend_post_count, 'friends' ), $friend_post_count ) . '</a>';
2969 }
2970 return $items;
2971 }
2972
2973 public function site_status_tests( $tests ) {
2974 $tests['direct']['friends-roles'] = array(
2975 'label' => __( 'Friend roles were created', 'friends' ),
2976 'test' => array( $this, 'friend_roles_test' ),
2977 );
2978 return $tests;
2979 }
2980
2981 public function get_missing_friends_plugin_roles() {
2982 $missing = Friends::get_friends_plugin_roles();
2983 $roles = new \WP_Roles();
2984 foreach ( $roles->roles as $role => $data ) {
2985 if ( isset( $data['capabilities']['friends_plugin'] ) ) {
2986 foreach ( $missing as $k => $cap ) {
2987 if ( isset( $data['capabilities'][ $cap ] ) ) {
2988 unset( $missing[ $k ] );
2989 break;
2990 }
2991 }
2992 }
2993 }
2994
2995 return array_values( $missing );
2996 }
2997
2998 public function friend_roles_test() {
2999 $result = array(
3000 'label' => __( 'The friend roles have been installed', 'friends' ),
3001 'status' => 'good',
3002 'badge' => array(
3003 'label' => __( 'Friends', 'friends' ),
3004 'color' => 'green',
3005 ),
3006 'description' =>
3007 '<p>' .
3008 __( 'The Friends Plugin uses users and user roles to determine friendship status between sites.', 'friends' ) .
3009 '</p>' .
3010 '<p>' .
3011 sprintf(
3012 // translators: %s is a list of roles.
3013 __( 'These are the roles required for the friends plugin: %s', 'friends' ),
3014 implode( ', ', Friends::get_friends_plugin_roles() )
3015 ) .
3016 '</p>',
3017 'test' => 'friends-roles',
3018 );
3019
3020 $missing_friend_roles = $this->get_missing_friends_plugin_roles();
3021 if ( ! empty( $missing_friend_roles ) ) {
3022
3023 $result['label'] = sprintf(
3024 // translators: %s is a list of missing roles.
3025 __( 'Not all friend roles have been installed. Missing: %s', 'friends' ),
3026 implode( ', ', $missing_friend_roles )
3027 );
3028 $result['badge']['color'] = 'red';
3029 $result['status'] = 'critical';
3030 $result['description'] .= '<p>';
3031 $result['description'] .= wp_kses_post(
3032 sprintf(
3033 // translators: %s is a URL.
3034 __( '<strong>To fix this:</strong> <a href="%s">Re-run activation of the Friends plugin</a>.', 'friends' ),
3035 esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), self_admin_url( 'admin.php?page=friends-settings&rerun-activate' ) ), 'friends-settings' ) )
3036 )
3037 );
3038 $result['description'] .= '</p>';
3039 }
3040
3041 return $result;
3042 }
3043
3044 public function site_status_test_php_modules( $modules ) {
3045 $modules['mbstring']['required'] = true;
3046 return $modules;
3047 }
3048
3049 public function site_health_debug( $debug_info ) {
3050 $missing_friend_roles = $this->get_missing_friends_plugin_roles();
3051 $debug_info['friends'] = array(
3052 'label' => __( 'Friends', 'friends' ),
3053 'fields' => array(
3054 'version' => array(
3055 'label' => __( 'Friends Version', 'friends' ),
3056 'value' => Friends::VERSION,
3057 ),
3058 'mbstring' => array(
3059 'label' => __( 'mbstring is available', 'friends' ),
3060 'value' => function_exists( 'mb_check_encoding' ) ? __( 'Yes' ) : __( 'No' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
3061 ),
3062 'roles' => array(
3063 'label' => __( 'Friend roles missing', 'friends' ),
3064 'value' => empty( $missing_friend_roles ) ? sprintf(
3065 // translators: %s is a list of roles.
3066 __( 'All roles found: %s', 'friends' ),
3067 implode( ', ', Friends::get_friends_plugin_roles() )
3068 ) : implode( ', ', $missing_friend_roles ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
3069 ),
3070 'main_user' => array(
3071 'label' => __( 'Main Friend User', 'friends' ),
3072 'value' => self::human_readable_main_user(),
3073 ),
3074 'parsers' => array(
3075 'label' => __( 'Registered Parsers', 'friends' ),
3076 'value' => strip_tags( implode( ', ', $this->friends->feed->get_registered_parsers() ) ),
3077 ),
3078 ),
3079 );
3080
3081 return $debug_info;
3082 }
3083
3084 /**
3085 * Returns a human readable string for which user is the main user.
3086 *
3087 * @return string
3088 */
3089 private static function human_readable_main_user() {
3090 $main_user = Friends::get_main_friend_user_id();
3091
3092 if ( ! $main_user ) {
3093 // translators: %d is the number of users.
3094 return esc_html( sprintf( __( 'No main user set. Admin users: %d', 'friends' ), User_Query::all_admin_users()->get_total() ) );
3095 }
3096
3097 $user = new \WP_User( $main_user );
3098
3099 if ( ! $user ) {
3100 return sprintf( '#%1$d %2$s', $main_user, '???' );
3101 }
3102
3103 return sprintf( '#%1$d %2$s', $user->ID, $user->user_login );
3104 }
3105 }
3106