BP_Members_Admin

Load Members admin area.

Defined (1)

The class is defined in the following location(s).

/bp-members/classes/class-bp-members-admin.php  
  1. class BP_Members_Admin { 
  2.  
  3. /** Directory *************************************************************/ 
  4.  
  5. /** 
  6. * Path to the BP Members Admin directory. 
  7. * @var string $admin_dir 
  8. */ 
  9. public $admin_dir = ''; 
  10.  
  11. /** URLs ******************************************************************/ 
  12.  
  13. /** 
  14. * URL to the BP Members Admin directory. 
  15. * @var string $admin_url 
  16. */ 
  17. public $admin_url = ''; 
  18.  
  19. /** 
  20. * URL to the BP Members Admin CSS directory. 
  21. * @var string $css_url 
  22. */ 
  23. public $css_url = ''; 
  24.  
  25. /** 
  26. * URL to the BP Members Admin JS directory. 
  27. * @var string 
  28. */ 
  29. public $js_url = ''; 
  30.  
  31. /** Other *****************************************************************/ 
  32.  
  33. /** 
  34. * Screen id for edit user's profile page. 
  35. * @var string 
  36. */ 
  37. public $user_page = ''; 
  38.  
  39. /** 
  40. * Setup BP Members Admin. 
  41. * @since 2.0.0 
  42. */ 
  43. public static function register_members_admin() { 
  44. if ( ! is_admin() ) { 
  45. return; 
  46.  
  47. $bp = buddypress(); 
  48.  
  49. if ( empty( $bp->members->admin ) ) { 
  50. $bp->members->admin = new self; 
  51.  
  52. return $bp->members->admin; 
  53.  
  54. /** 
  55. * Constructor method. 
  56. * @since 2.0.0 
  57. */ 
  58. public function __construct() { 
  59. $this->setup_globals(); 
  60. $this->setup_actions(); 
  61.  
  62. /** 
  63. * Set admin-related globals. 
  64. * @since 2.0.0 
  65. */ 
  66. private function setup_globals() { 
  67. $bp = buddypress(); 
  68.  
  69. // Paths and URLs 
  70. $this->admin_dir = trailingslashit( $bp->plugin_dir . 'bp-members/admin' ); // Admin path. 
  71. $this->admin_url = trailingslashit( $bp->plugin_url . 'bp-members/admin' ); // Admin URL. 
  72. $this->css_url = trailingslashit( $this->admin_url . 'css' ); // Admin CSS URL. 
  73. $this->js_url = trailingslashit( $this->admin_url . 'js' ); // Admin CSS URL. 
  74.  
  75. // Capability depends on config. 
  76. $this->capability = bp_core_do_network_admin() ? 'manage_network_users' : 'edit_users'; 
  77.  
  78. // The Edit Profile Screen id. 
  79. $this->user_page = ''; 
  80.  
  81. // The Show Profile Screen id. 
  82. $this->user_profile = is_network_admin() ? 'users' : 'profile'; 
  83.  
  84. // The current user id. 
  85. $this->current_user_id = get_current_user_id(); 
  86.  
  87. // The user id being edited. 
  88. $this->user_id = 0; 
  89.  
  90. // Is a member editing their own profile. 
  91. $this->is_self_profile = false; 
  92.  
  93. // The screen ids to load specific css for. 
  94. $this->screen_id = array(); 
  95.  
  96. // The stats metabox default position. 
  97. $this->stats_metabox = new StdClass(); 
  98.  
  99. // BuddyPress edit user's profile args. 
  100. $this->edit_profile_args = array( 'page' => 'bp-profile-edit' ); 
  101. $this->edit_profile_url = ''; 
  102. $this->edit_url = ''; 
  103.  
  104. // Data specific to signups. 
  105. $this->users_page = ''; 
  106. $this->signups_page = ''; 
  107. $this->users_url = bp_get_admin_url( 'users.php' ); 
  108. $this->users_screen = bp_core_do_network_admin() ? 'users-network' : 'users'; 
  109.  
  110. // Specific config: BuddyPress is not network activated. 
  111. $this->subsite_activated = (bool) is_multisite() && ! bp_is_network_activated(); 
  112.  
  113. // When BuddyPress is not network activated, only Super Admin can moderate signups. 
  114. if ( ! empty( $this->subsite_activated ) ) { 
  115. $this->capability = 'manage_network_users'; 
  116.  
  117. /** 
  118. * Set admin-related actions and filters. 
  119. * @since 2.0.0 
  120. */ 
  121. private function setup_actions() { 
  122.  
  123. /** Extended Profile ************************************************* 
  124. */ 
  125.  
  126. // Enqueue all admin JS and CSS. 
  127. add_action( 'bp_admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); 
  128.  
  129. // Add some page specific output to the <head>. 
  130. add_action( 'bp_admin_head', array( $this, 'admin_head' ), 999 ); 
  131.  
  132. // Add menu item to all users menu. 
  133. add_action( 'admin_menu', array( $this, 'admin_menus' ), 5 ); 
  134. add_action( 'network_admin_menu', array( $this, 'admin_menus' ), 5 ); 
  135. add_action( 'user_admin_menu', array( $this, 'user_profile_menu' ), 5 ); 
  136.  
  137. // Create the Profile Navigation (Profile/Extended Profile). 
  138. add_action( 'edit_user_profile', array( $this, 'profile_nav' ), 99, 1 ); 
  139. add_action( 'show_user_profile', array( $this, 'profile_nav' ), 99, 1 ); 
  140.  
  141. // Editing users of a specific site. 
  142. add_action( "admin_head-site-users.php", array( $this, 'profile_admin_head' ) ); 
  143.  
  144. // Add a row action to users listing. 
  145. if ( bp_core_do_network_admin() ) { 
  146. add_filter( 'ms_user_row_actions', array( $this, 'row_actions' ), 10, 2 ); 
  147. add_action( 'admin_init', array( $this, 'add_edit_profile_url_filter' ) ); 
  148. add_action( 'wp_after_admin_bar_render', array( $this, 'remove_edit_profile_url_filter' ) ); 
  149.  
  150. // Add user row actions for single site. 
  151. add_filter( 'user_row_actions', array( $this, 'row_actions' ), 10, 2 ); 
  152.  
  153. // Process changes to member type. 
  154. add_action( 'bp_members_admin_load', array( $this, 'process_member_type_update' ) ); 
  155.  
  156. /** Signups ********************************************************** 
  157. */ 
  158.  
  159. if ( is_admin() ) { 
  160.  
  161. // Filter non multisite user query to remove sign-up users. 
  162. if ( ! is_multisite() ) { 
  163. add_action( 'pre_user_query', array( $this, 'remove_signups_from_user_query' ), 10, 1 ); 
  164.  
  165. // Reorganise the views navigation in users.php and signups page. 
  166. if ( current_user_can( $this->capability ) ) { 
  167. $user_screen = $this->users_screen; 
  168.  
  169. /** 
  170. * Users screen on multiblog is users, but signups 
  171. * need to be managed in the network for this case 
  172. */ 
  173. if ( bp_is_network_activated() && bp_is_multiblog_mode() && false === strpos( $user_screen, '-network' ) ) { 
  174. $user_screen .= '-network'; 
  175.  
  176. add_filter( "views_{$user_screen}", array( $this, 'signup_filter_view' ), 10, 1 ); 
  177. add_filter( 'set-screen-option', array( $this, 'signup_screen_options' ), 10, 3 ); 
  178.  
  179. // Registration is turned on. 
  180. add_action( 'update_site_option_registration', array( $this, 'multisite_registration_on' ), 10, 2 ); 
  181. add_action( 'update_option_users_can_register', array( $this, 'single_site_registration_on' ), 10, 2 ); 
  182.  
  183. /** Users List - Members Types *************************************** 
  184. */ 
  185.  
  186. if ( is_admin() && bp_get_member_types() ) { 
  187.  
  188. // Add "Change type" <select> to WP admin users list table and process bulk members type changes. 
  189. add_action( 'restrict_manage_users', array( $this, 'users_table_output_type_change_select' ) ); 
  190. add_action( 'load-users.php', array( $this, 'users_table_process_bulk_type_change' ) ); 
  191.  
  192. // Add the member type column to the WP admin users list table. 
  193. add_filter( 'manage_users_columns', array( $this, 'users_table_add_type_column' ) ); 
  194. add_filter( 'manage_users_custom_column', array( $this, 'users_table_populate_type_cell' ), 10, 3 ); 
  195.  
  196. // Filter WP admin users list table to include users of the specified type. 
  197. add_filter( 'pre_get_users', array( $this, 'users_table_filter_by_type' ) ); 
  198.  
  199. /** 
  200. * Create registration pages when multisite user registration is turned on. 
  201. * @since 2.7.0 
  202. * @param string $option_name Current option name; value is always 'registration'. 
  203. * @param string $value 
  204. */ 
  205. public function multisite_registration_on( $option_name, $value ) { 
  206. if ( 'user' === $value || 'all' === $value ) { 
  207. bp_core_add_page_mappings( array( 
  208. 'register' => 1,  
  209. 'activate' => 1 
  210. ) ); 
  211.  
  212. /** 
  213. * Create registration pages when single site registration is turned on. 
  214. * @since 2.7.0 
  215. * @param string $old_value 
  216. * @param string $value 
  217. */ 
  218. public function single_site_registration_on( $old_value, $value ) { 
  219. // Single site. 
  220. if ( ! is_multisite() && ! empty( $value ) ) { 
  221. bp_core_add_page_mappings( array( 
  222. 'register' => 1,  
  223. 'activate' => 1 
  224. ) ); 
  225.  
  226. /** 
  227. * Get the user ID. 
  228. * Look for $_GET['user_id']. If anything else, force the user ID to the 
  229. * current user's ID so they aren't left without a user to edit. 
  230. * @since 2.1.0 
  231. * @return int 
  232. */ 
  233. private function get_user_id() { 
  234. if ( ! empty( $this->user_id ) ) { 
  235. return $this->user_id; 
  236.  
  237. $this->user_id = (int) get_current_user_id(); 
  238.  
  239. // We'll need a user ID when not on self profile. 
  240. if ( ! empty( $_GET['user_id'] ) ) { 
  241. $this->user_id = (int) $_GET['user_id']; 
  242.  
  243. return $this->user_id; 
  244.  
  245. /** 
  246. * Can the current user edit the one displayed. 
  247. * Self profile editing / or bp_moderate check. 
  248. * This might be replaced by more granular capabilities 
  249. * in the future. 
  250. * @since 2.1.0 
  251. * @param int $user_id ID of the user being checked for edit ability. 
  252. * @return bool 
  253. */ 
  254. private function member_can_edit( $user_id = 0 ) { 
  255. $retval = false; 
  256.  
  257. // Bail if no user ID was passed. 
  258. if ( empty( $user_id ) ) { 
  259. return $retval; 
  260.  
  261. // Member can edit if they are viewing their own profile. 
  262. if ( $this->current_user_id === $user_id ) { 
  263. $retval = true; 
  264.  
  265. // Trust the 'bp_moderate' capability. 
  266. } else { 
  267. $retval = bp_current_user_can( 'bp_moderate' ); 
  268.  
  269. return $retval; 
  270.  
  271. /** 
  272. * Get admin notice when saving a user or member profile. 
  273. * @since 2.1.0 
  274. * @return array 
  275. */ 
  276. private function get_user_notice() { 
  277.  
  278. // Setup empty notice for return value. 
  279. $notice = array(); 
  280.  
  281. // Updates. 
  282. if ( ! empty( $_REQUEST['updated'] ) ) { 
  283. switch ( $_REQUEST['updated'] ) { 
  284. case 'avatar': 
  285. $notice = array( 
  286. 'class' => 'updated',  
  287. 'message' => __( 'Profile photo was deleted.', 'buddypress' ) 
  288. ); 
  289. break; 
  290. case 'ham' : 
  291. $notice = array( 
  292. 'class' => 'updated',  
  293. 'message' => __( 'User removed as spammer.', 'buddypress' ) 
  294. ); 
  295. break; 
  296. case 'spam' : 
  297. $notice = array( 
  298. 'class' => 'updated',  
  299. 'message' => __( 'User marked as spammer. Spam users are visible only to site admins.', 'buddypress' ) 
  300. ); 
  301. break; 
  302. case 1 : 
  303. $notice = array( 
  304. 'class' => 'updated',  
  305. 'message' => __( 'Profile updated.', 'buddypress' ) 
  306. ); 
  307. break; 
  308.  
  309. // Errors. 
  310. if ( ! empty( $_REQUEST['error'] ) ) { 
  311. switch ( $_REQUEST['error'] ) { 
  312. case 'avatar': 
  313. $notice = array( 
  314. 'class' => 'error',  
  315. 'message' => __( 'There was a problem deleting that profile photo. Please try again.', 'buddypress' ) 
  316. ); 
  317. break; 
  318. case 'ham' : 
  319. $notice = array( 
  320. 'class' => 'error',  
  321. 'message' => __( 'User could not be removed as spammer.', 'buddypress' ) 
  322. ); 
  323. break; 
  324. case 'spam' : 
  325. $notice = array( 
  326. 'class' => 'error',  
  327. 'message' => __( 'User could not be marked as spammer.', 'buddypress' ) 
  328. ); 
  329. break; 
  330. case 1 : 
  331. $notice = array( 
  332. 'class' => 'error',  
  333. 'message' => __( 'An error occurred while trying to update the profile.', 'buddypress' ) 
  334. ); 
  335. break; 
  336. case 2: 
  337. $notice = array( 
  338. 'class' => 'error',  
  339. 'message' => __( 'Please make sure you fill in all required fields in this profile field group before saving.', 'buddypress' ) 
  340. ); 
  341. break; 
  342. case 3: 
  343. $notice = array( 
  344. 'class' => 'error',  
  345. 'message' => __( 'There was a problem updating some of your profile information. Please try again.', 'buddypress' ) 
  346. ); 
  347. break; 
  348.  
  349. return $notice; 
  350.  
  351. /** 
  352. * Create the /user/ admin Profile submenus for all members. 
  353. * @since 2.1.0 
  354. */ 
  355. public function user_profile_menu() { 
  356.  
  357. // Setup the hooks array. 
  358. $hooks = array(); 
  359.  
  360. // Add the faux "Edit Profile" submenu page. 
  361. $hooks['user'] = $this->user_page = add_submenu_page( 
  362. 'profile.php',  
  363. __( 'Edit Profile', 'buddypress' ),  
  364. __( 'Edit Profile', 'buddypress' ),  
  365. 'exist',  
  366. 'bp-profile-edit',  
  367. array( $this, 'user_admin' ) 
  368. ); 
  369.  
  370. // Setup the screen ID's. 
  371. $this->screen_id = array( 
  372. $this->user_page . '-user',  
  373. $this->user_profile . '-user' 
  374. ); 
  375.  
  376. // Loop through new hooks and add method actions. 
  377. foreach ( $hooks as $key => $hook ) { 
  378. add_action( "load-{$hook}", array( $this, $key . '_admin_load' ) ); 
  379.  
  380. // Add the profile_admin_head method to proper admin_head actions. 
  381. add_action( "admin_head-{$this->user_page}", array( $this, 'profile_admin_head' ) ); 
  382. add_action( "admin_head-profile.php", array( $this, 'profile_admin_head' ) ); 
  383.  
  384. /** 
  385. * Create the All Users / Profile > Edit Profile and All Users Signups submenus. 
  386. * @since 2.0.0 
  387. */ 
  388. public function admin_menus() { 
  389.  
  390. // Setup the hooks array. 
  391. $hooks = array(); 
  392.  
  393. // Manage user's profile. 
  394. $hooks['user'] = $this->user_page = add_submenu_page( 
  395. $this->user_profile . '.php',  
  396. __( 'Edit Profile', 'buddypress' ),  
  397. __( 'Edit Profile', 'buddypress' ),  
  398. 'read',  
  399. 'bp-profile-edit',  
  400. array( $this, 'user_admin' ) 
  401. ); 
  402.  
  403. // Only show sign-ups where they belong. 
  404. if ( ( ! bp_is_network_activated() && ! is_network_admin() ) || ( is_network_admin() && bp_is_network_activated() ) ) { 
  405.  
  406. // Manage signups. 
  407. $hooks['signups'] = $this->signups_page = add_users_page( 
  408. __( 'Manage Signups', 'buddypress' ),  
  409. __( 'Manage Signups', 'buddypress' ),  
  410. $this->capability,  
  411. 'bp-signups',  
  412. array( $this, 'signups_admin' ) 
  413. ); 
  414.  
  415. $edit_page = 'user-edit'; 
  416. $profile_page = 'profile'; 
  417. $this->users_page = 'users'; 
  418.  
  419. // Self profile check is needed for this pages. 
  420. $page_head = array( 
  421. $edit_page . '.php',  
  422. $profile_page . '.php',  
  423. $this->user_page,  
  424. $this->users_page . '.php',  
  425. ); 
  426.  
  427. // Append '-network' to each array item if in network admin. 
  428. if ( is_network_admin() ) { 
  429. $edit_page .= '-network'; 
  430. $profile_page .= '-network'; 
  431. $this->user_page .= '-network'; 
  432. $this->users_page .= '-network'; 
  433. $this->signups_page .= '-network'; 
  434.  
  435. // Setup the screen ID's. 
  436. $this->screen_id = array( 
  437. $edit_page,  
  438. $this->user_page,  
  439. $profile_page 
  440. ); 
  441.  
  442. // Loop through new hooks and add method actions. 
  443. foreach ( $hooks as $key => $hook ) { 
  444. add_action( "load-{$hook}", array( $this, $key . '_admin_load' ) ); 
  445.  
  446. // Add the profile_admin_head method to proper admin_head actions. 
  447. foreach ( $page_head as $head ) { 
  448. add_action( "admin_head-{$head}", array( $this, 'profile_admin_head' ) ); 
  449.  
  450. /** 
  451. * Highlight the Users menu if on Edit Profile and check if on the user's admin profile. 
  452. * @since 2.1.0 
  453. */ 
  454. public function profile_admin_head() { 
  455. global $submenu_file, $parent_file; 
  456.  
  457. // Is the user editing their own profile? 
  458. if ( is_user_admin() || ( defined( 'IS_PROFILE_PAGE' ) && IS_PROFILE_PAGE ) ) { 
  459. $this->is_self_profile = true; 
  460.  
  461. // Is the user attempting to edit their own profile. 
  462. } elseif ( isset( $_GET['user_id' ] ) || ( isset( $_GET['page'] ) && ( 'bp-profile-edit' === $_GET['page'] ) ) ) { 
  463. $this->is_self_profile = (bool) ( $this->get_user_id() === $this->current_user_id ); 
  464.  
  465. // Force the parent file to users.php to open the correct top level menu 
  466. // but only if not editing a site via the network site editing page. 
  467. if ( 'sites.php' !== $parent_file ) { 
  468. $parent_file = 'users.php'; 
  469. $submenu_file = 'users.php'; 
  470.  
  471. // Editing your own profile, so recheck some vars. 
  472. if ( true === $this->is_self_profile ) { 
  473.  
  474. // Use profile.php as the edit page. 
  475. $edit_page = 'profile.php'; 
  476.  
  477. // Set profile.php as the parent & sub files to correct the menu nav. 
  478. if ( is_blog_admin() || is_user_admin() ) { 
  479. $parent_file = 'profile.php'; 
  480. $submenu_file = 'profile.php'; 
  481.  
  482. // Not editing yourself, so use user-edit.php. 
  483. } else { 
  484. $edit_page = 'user-edit.php'; 
  485.  
  486. if ( is_user_admin() ) { 
  487. $this->edit_profile_url = add_query_arg( $this->edit_profile_args, user_admin_url( 'profile.php' ) ); 
  488. $this->edit_url = user_admin_url( 'profile.php' ); 
  489.  
  490. } elseif ( is_blog_admin() ) { 
  491. $this->edit_profile_url = add_query_arg( $this->edit_profile_args, admin_url( 'users.php' ) ); 
  492. $this->edit_url = admin_url( $edit_page ); 
  493.  
  494. } elseif ( is_network_admin() ) { 
  495. $this->edit_profile_url = add_query_arg( $this->edit_profile_args, network_admin_url( 'users.php' ) ); 
  496. $this->edit_url = network_admin_url( $edit_page ); 
  497.  
  498. /** 
  499. * Remove the Edit Profile page. 
  500. * We add these pages in order to integrate with WP's Users panel, but 
  501. * we want them to show up as a row action of the WP panel, not as separate 
  502. * subnav items under the Users menu. 
  503. * @since 2.0.0 
  504. */ 
  505. public function admin_head() { 
  506. remove_submenu_page( 'users.php', 'bp-profile-edit' ); 
  507. remove_submenu_page( 'profile.php', 'bp-profile-edit' ); 
  508.  
  509. /** Community Profile *****************************************************/ 
  510.  
  511. /** 
  512. * Add some specific styling to the Edit User and Edit User's Profile page. 
  513. * @since 2.0.0 
  514. */ 
  515. public function enqueue_scripts() { 
  516. if ( ! in_array( get_current_screen()->id, $this->screen_id ) ) { 
  517. return; 
  518.  
  519. $min = bp_core_get_minified_asset_suffix(); 
  520. $css = $this->css_url . "admin{$min}.css"; 
  521.  
  522. /** 
  523. * Filters the CSS URL to enqueue in the Members admin area. 
  524. * @since 2.0.0 
  525. * @param string $css URL to the CSS admin file to load. 
  526. */ 
  527. $css = apply_filters( 'bp_members_admin_css', $css ); 
  528.  
  529. wp_enqueue_style( 'bp-members-css', $css, array(), bp_get_version() ); 
  530.  
  531. wp_style_add_data( 'bp-members-css', 'rtl', true ); 
  532. if ( $min ) { 
  533. wp_style_add_data( 'bp-members-css', 'suffix', $min ); 
  534.  
  535. // Only load JavaScript for BuddyPress profile. 
  536. if ( get_current_screen()->id == $this->user_page ) { 
  537. $js = $this->js_url . "admin{$min}.js"; 
  538.  
  539. /** 
  540. * Filters the JS URL to enqueue in the Members admin area. 
  541. * @since 2.0.0 
  542. * @param string $js URL to the JavaScript admin file to load. 
  543. */ 
  544. $js = apply_filters( 'bp_members_admin_js', $js ); 
  545. wp_enqueue_script( 'bp-members-js', $js, array( 'jquery' ), bp_get_version(), true ); 
  546.  
  547. /** 
  548. * Fires after all of the members JavaScript and CSS are enqueued. 
  549. * @since 2.0.0 
  550. * @param string $id ID of the current screen. 
  551. * @param array $screen_id Array of allowed screens to add scripts and styles to. 
  552. */ 
  553. do_action( 'bp_members_admin_enqueue_scripts', get_current_screen()->id, $this->screen_id ); 
  554.  
  555. /** 
  556. * Create the Profile navigation in Edit User & Edit Profile pages. 
  557. * @since 2.0.0 
  558. * @param object|null $user User to create profile navigation for. 
  559. * @param string $active Which profile to highlight. 
  560. * @return string 
  561. */ 
  562. public function profile_nav( $user = null, $active = 'WordPress' ) { 
  563.  
  564. // Bail if no user ID exists here. 
  565. if ( empty( $user->ID ) ) { 
  566. return; 
  567.  
  568. // Add the user ID to query arguments when not editing yourself. 
  569. if ( false === $this->is_self_profile ) { 
  570. $query_args = array( 'user_id' => $user->ID ); 
  571. } else { 
  572. $query_args = array(); 
  573.  
  574. // Conditionally add a referer if it exists in the existing request. 
  575. if ( ! empty( $_REQUEST['wp_http_referer'] ) ) { 
  576. $query_args['wp_http_referer'] = urlencode( stripslashes_deep( $_REQUEST['wp_http_referer'] ) ); 
  577.  
  578. // Setup the two distinct "edit" URL's. 
  579. $community_url = add_query_arg( $query_args, $this->edit_profile_url ); 
  580. $wordpress_url = add_query_arg( $query_args, $this->edit_url ); 
  581.  
  582. $bp_active = false; 
  583. $wp_active = ' nav-tab-active'; 
  584. if ( 'BuddyPress' === $active ) { 
  585. $bp_active = ' nav-tab-active'; 
  586. $wp_active = false; 
  587. } ?> 
  588.  
  589. <h2 id="profile-nav" class="nav-tab-wrapper"> 
  590. <?php 
  591. /** 
  592. * In configs where BuddyPress is not network activated, as regular 
  593. * admins do not have the capacity to edit other users, we must add 
  594. * this check. 
  595. */ 
  596. if ( current_user_can( 'edit_user', $user->ID ) ) : ?> 
  597.  
  598. <a class="nav-tab<?php echo esc_attr( $wp_active ); ?>" href="<?php echo esc_url( $wordpress_url );?>"><?php _e( 'Profile', 'buddypress' ); ?></a> 
  599.  
  600. <?php endif; ?> 
  601.  
  602. <a class="nav-tab<?php echo esc_attr( $bp_active ); ?>" href="<?php echo esc_url( $community_url );?>"><?php _e( 'Extended Profile', 'buddypress' ); ?></a> 
  603. </h2> 
  604.  
  605. <?php 
  606.  
  607. /** 
  608. * Set up the user's profile admin page. 
  609. * Loaded before the page is rendered, this function does all initial 
  610. * setup, including: processing form requests, registering contextual 
  611. * help, and setting up screen options. 
  612. * @since 2.0.0 
  613. */ 
  614. public function user_admin_load() { 
  615.  
  616. // Get the user ID. 
  617. $user_id = $this->get_user_id(); 
  618.  
  619. // Can current user edit this profile? 
  620. if ( ! $this->member_can_edit( $user_id ) ) { 
  621. wp_die( __( 'You cannot edit the requested user.', 'buddypress' ) ); 
  622.  
  623. // Build redirection URL. 
  624. $redirect_to = remove_query_arg( array( 'action', 'error', 'updated', 'spam', 'ham', 'delete_avatar' ), $_SERVER['REQUEST_URI'] ); 
  625. $doaction = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : false; 
  626.  
  627. if ( ! empty( $_REQUEST['user_status'] ) ) { 
  628. $spam = (bool) ( 'spam' === $_REQUEST['user_status'] ); 
  629.  
  630. if ( $spam !== bp_is_user_spammer( $user_id ) ) { 
  631. $doaction = $_REQUEST['user_status']; 
  632.  
  633. /** 
  634. * Fires at the start of the signups admin load. 
  635. * @since 2.0.0 
  636. * @param string $doaction Current bulk action being processed. 
  637. * @param array $_REQUEST Current $_REQUEST global. 
  638. */ 
  639. do_action_ref_array( 'bp_members_admin_load', array( $doaction, $_REQUEST ) ); 
  640.  
  641. /** 
  642. * Filters the allowed actions for use in the user admin page. 
  643. * @since 2.0.0 
  644. * @param array $value Array of allowed actions to use. 
  645. */ 
  646. $allowed_actions = apply_filters( 'bp_members_admin_allowed_actions', array( 'update', 'delete_avatar', 'spam', 'ham' ) ); 
  647.  
  648. // Prepare the display of the Community Profile screen. 
  649. if ( ! in_array( $doaction, $allowed_actions ) ) { 
  650. add_screen_option( 'layout_columns', array( 'default' => 2, 'max' => 2, ) ); 
  651.  
  652. get_current_screen()->add_help_tab( array( 
  653. 'id' => 'bp-profile-edit-overview',  
  654. 'title' => __( 'Overview', 'buddypress' ),  
  655. 'content' => 
  656. '<p>' . __( 'This is the admin view of a user's profile.', 'buddypress' ) . '</p>' . 
  657. '<p>' . __( 'In the main column, you can edit the fields of the user's extended profile.', 'buddypress' ) . '</p>' . 
  658. '<p>' . __( 'In the right-hand column, you can update the user's status, delete the user's avatar, and view recent statistics.', 'buddypress' ) . '</p>' 
  659. ) ); 
  660.  
  661. // Help panel - sidebar links. 
  662. get_current_screen()->set_help_sidebar( 
  663. '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' . 
  664. '<p>' . __( '<a href="https://codex.buddypress.org/administrator-guide/extended-profiles/">Managing Profiles</a>', 'buddypress' ) . '</p>' . 
  665. '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>' 
  666. ); 
  667.  
  668. // Register metaboxes for the edit screen. 
  669. add_meta_box( 
  670. 'submitdiv',  
  671. _x( 'Status', 'members user-admin edit screen', 'buddypress' ),  
  672. array( $this, 'user_admin_status_metabox' ),  
  673. get_current_screen()->id,  
  674. 'side',  
  675. 'core' 
  676. ); 
  677.  
  678. // In case xprofile is not active. 
  679. $this->stats_metabox->context = 'normal'; 
  680. $this->stats_metabox->priority = 'core'; 
  681.  
  682. /** 
  683. * Fires before loading the profile fields if component is active. 
  684. * Plugins should not use this hook, please use 'bp_members_admin_user_metaboxes' instead. 
  685. * @since 2.0.0 
  686. * @param int $user_id Current user ID for the screen. 
  687. * @param string $id Current screen ID. 
  688. * @param object $stats_metabox Object holding position data for use with the stats metabox. 
  689. */ 
  690. do_action_ref_array( 'bp_members_admin_xprofile_metabox', array( $user_id, get_current_screen()->id, $this->stats_metabox ) ); 
  691.  
  692. // If xProfile is inactive, difficult to know what's profile we're on. 
  693. if ( 'normal' === $this->stats_metabox->context ) { 
  694. $display_name = bp_core_get_user_displayname( $user_id ); 
  695. } else { 
  696. $display_name = __( 'Member', 'buddypress' ); 
  697.  
  698. // User Stat metabox. 
  699. add_meta_box( 
  700. 'bp_members_admin_user_stats',  
  701. sprintf( _x( "%s's Stats", 'members user-admin edit screen', 'buddypress' ), $display_name ),  
  702. array( $this, 'user_admin_stats_metabox' ),  
  703. get_current_screen()->id,  
  704. sanitize_key( $this->stats_metabox->context ),  
  705. sanitize_key( $this->stats_metabox->priority ) 
  706. ); 
  707.  
  708. // Member Type metabox. Only added if member types have been registered. 
  709. $member_types = bp_get_member_types(); 
  710. if ( ! empty( $member_types ) ) { 
  711. add_meta_box( 
  712. 'bp_members_admin_member_type',  
  713. _x( 'Member Type', 'members user-admin edit screen', 'buddypress' ),  
  714. array( $this, 'user_admin_member_type_metabox' ),  
  715. get_current_screen()->id,  
  716. 'side',  
  717. 'core' 
  718. ); 
  719.  
  720. /** 
  721. * Fires at the end of the Community Profile screen. 
  722. * Plugins can restrict metabox to "bp_moderate" admins by checking if 
  723. * the first argument ($this->is_self_profile) is false in their callback. 
  724. * They can also restrict their metabox to self profile editing 
  725. * by setting it to true. 
  726. * @since 2.0.0 
  727. * @param bool $is_self_profile Whether or not it is the current user's profile. 
  728. * @param int $user_id Current user ID. 
  729. */ 
  730. do_action( 'bp_members_admin_user_metaboxes', $this->is_self_profile, $user_id ); 
  731.  
  732. // Enqueue JavaScript files. 
  733. wp_enqueue_script( 'postbox' ); 
  734. wp_enqueue_script( 'dashboard' ); 
  735.  
  736. // Spam or Ham user. 
  737. } elseif ( in_array( $doaction, array( 'spam', 'ham' ) ) && empty( $this->is_self_profile ) ) { 
  738.  
  739. check_admin_referer( 'edit-bp-profile_' . $user_id ); 
  740.  
  741. if ( bp_core_process_spammer_status( $user_id, $doaction ) ) { 
  742. $redirect_to = add_query_arg( 'updated', $doaction, $redirect_to ); 
  743. } else { 
  744. $redirect_to = add_query_arg( 'error', $doaction, $redirect_to ); 
  745.  
  746. bp_core_redirect( $redirect_to ); 
  747.  
  748. // Update other stuff once above ones are done. 
  749. } else { 
  750. $this->redirect = $redirect_to; 
  751.  
  752. /** 
  753. * Fires at end of user profile admin load if doaction does not match any available actions. 
  754. * @since 2.0.0 
  755. * @param string $doaction Current bulk action being processed. 
  756. * @param int $user_id Current user ID. 
  757. * @param array $_REQUEST Current $_REQUEST global. 
  758. * @param string $redirect Determined redirect url to send user to. 
  759. */ 
  760. do_action_ref_array( 'bp_members_admin_update_user', array( $doaction, $user_id, $_REQUEST, $this->redirect ) ); 
  761.  
  762. bp_core_redirect( $this->redirect ); 
  763.  
  764. /** 
  765. * Display the user's profile. 
  766. * @since 2.0.0 
  767. */ 
  768. public function user_admin() { 
  769.  
  770. if ( ! bp_current_user_can( 'bp_moderate' ) && empty( $this->is_self_profile ) ) { 
  771. die( '-1' ); 
  772.  
  773. // Get the user ID. 
  774. $user_id = $this->get_user_id(); 
  775. $user = get_user_to_edit( $user_id ); 
  776.  
  777. // Construct title. 
  778. if ( true === $this->is_self_profile ) { 
  779. $title = __( 'Profile', 'buddypress' ); 
  780. } else { 
  781. $title = __( 'Edit User', 'buddypress' ); 
  782.  
  783. // Construct URL for form. 
  784. $request_url = remove_query_arg( array( 'action', 'error', 'updated', 'spam', 'ham' ), $_SERVER['REQUEST_URI'] ); 
  785. $form_action_url = add_query_arg( 'action', 'update', $request_url ); 
  786. $wp_http_referer = false; 
  787. if ( ! empty( $_REQUEST['wp_http_referer'] ) ) { 
  788. $wp_http_referer = remove_query_arg( array( 'action', 'updated' ), $_REQUEST['wp_http_referer'] ); 
  789.  
  790. // Prepare notice for admin. 
  791. $notice = $this->get_user_notice(); 
  792.  
  793. if ( ! empty( $notice ) ) : ?> 
  794.  
  795. <div <?php if ( 'updated' === $notice['class'] ) : ?>id="message" <?php endif; ?>class="<?php echo esc_attr( $notice['class'] ); ?>"> 
  796.  
  797. <p><?php echo esc_html( $notice['message'] ); ?></p> 
  798.  
  799. <?php if ( !empty( $wp_http_referer ) && ( 'updated' === $notice['class'] ) ) : ?> 
  800.  
  801. <p><a href="<?php echo esc_url( $wp_http_referer ); ?>"><?php esc_html_e( '← Back to Users', 'buddypress' ); ?></a></p> 
  802.  
  803. <?php endif; ?> 
  804.  
  805. </div> 
  806.  
  807. <?php endif; ?> 
  808.  
  809. <div class="wrap" id="community-profile-page"> 
  810. <h1><?php echo esc_html( $title ); ?> 
  811.  
  812. <?php if ( empty( $this->is_self_profile ) ) : ?> 
  813.  
  814. <?php if ( current_user_can( 'create_users' ) ) : ?> 
  815.  
  816. <a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add New', 'user', 'buddypress' ); ?></a> 
  817.  
  818. <?php elseif ( is_multisite() && current_user_can( 'promote_users' ) ) : ?> 
  819.  
  820. <a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add Existing', 'user', 'buddypress' ); ?></a> 
  821.  
  822. <?php endif; ?> 
  823.  
  824. <?php endif; ?> 
  825. </h1> 
  826.  
  827. <?php if ( ! empty( $user ) ) : 
  828.  
  829. $this->profile_nav( $user, 'BuddyPress' ); ?> 
  830.  
  831. <form action="<?php echo esc_url( $form_action_url ); ?>" id="your-profile" method="post"> 
  832. <div id="poststuff"> 
  833.  
  834. <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>"> 
  835.  
  836. <div id="postbox-container-1" class="postbox-container"> 
  837. <?php do_meta_boxes( get_current_screen()->id, 'side', $user ); ?> 
  838. </div> 
  839.  
  840. <div id="postbox-container-2" class="postbox-container"> 
  841. <?php do_meta_boxes( get_current_screen()->id, 'normal', $user ); ?> 
  842. <?php do_meta_boxes( get_current_screen()->id, 'advanced', $user ); ?> 
  843. </div> 
  844. </div><!-- #post-body --> 
  845.  
  846. </div><!-- #poststuff --> 
  847.  
  848. <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?> 
  849. <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?> 
  850. <?php wp_nonce_field( 'edit-bp-profile_' . $user->ID ); ?> 
  851.  
  852. </form> 
  853.  
  854. <?php else : ?> 
  855.  
  856. <p><?php 
  857. printf( 
  858. '%1$s <a href="%2$s">%3$s</a>',  
  859. __( 'No user found with this ID.', 'buddypress' ),  
  860. esc_url( bp_get_admin_url( 'users.php' ) ),  
  861. __( 'Go back and try again.', 'buddypress' ) 
  862. ); 
  863. ?></p> 
  864.  
  865. <?php endif; ?> 
  866.  
  867. </div><!-- .wrap --> 
  868. <?php 
  869.  
  870. /** 
  871. * Render the Status metabox for user's profile screen. 
  872. * Actions are: 
  873. * - Update profile fields if xProfile component is active 
  874. * - Spam/Unspam user 
  875. * @since 2.0.0 
  876. * @param WP_User|null $user The WP_User object to be edited. 
  877. */ 
  878. public function user_admin_status_metabox( $user = null ) { 
  879.  
  880. // Bail if no user id or if the user has not activated their account yet. 
  881. if ( empty( $user->ID ) ) { 
  882. return; 
  883.  
  884. // Bail if user has not been activated yet (how did you get here?). 
  885. if ( isset( $user->user_status ) && ( 2 == $user->user_status ) ) : ?> 
  886.  
  887. <p class="not-activated"><?php esc_html_e( 'User account has not yet been activated', 'buddypress' ); ?></p><br/> 
  888.  
  889. <?php return; 
  890.  
  891. endif; ?> 
  892.  
  893. <div class="submitbox" id="submitcomment"> 
  894. <div id="minor-publishing"> 
  895. <div id="misc-publishing-actions"> 
  896. <?php 
  897.  
  898. // Get the spam status once here to compare against below. 
  899. $is_spammer = bp_is_user_spammer( $user->ID ); 
  900.  
  901. /** 
  902. * In configs where BuddyPress is not network activated,  
  903. * regular admins cannot mark a user as a spammer on front 
  904. * end. This prevent them to do it in the back end. 
  905. * Also prevent admins from marking themselves or other 
  906. * admins as spammers. 
  907. */ 
  908. if ( ( empty( $this->is_self_profile ) && ( ! in_array( $user->user_login, get_super_admins() ) ) && empty( $this->subsite_activated ) ) || ( ! empty( $this->subsite_activated ) && current_user_can( 'manage_network_users' ) ) ) : ?> 
  909.  
  910. <div class="misc-pub-section" id="comment-status-radio"> 
  911. <label class="approved"><input type="radio" name="user_status" value="ham" <?php checked( $is_spammer, false ); ?>><?php esc_html_e( 'Active', 'buddypress' ); ?></label><br /> 
  912. <label class="spam"><input type="radio" name="user_status" value="spam" <?php checked( $is_spammer, true ); ?>><?php esc_html_e( 'Spammer', 'buddypress' ); ?></label> 
  913. </div> 
  914.  
  915. <?php endif ;?> 
  916.  
  917. <div class="misc-pub-section curtime misc-pub-section-last"> 
  918. <?php 
  919.  
  920. // Translators: Publish box date format, see http://php.net/date. 
  921. $datef = __( 'M j, Y @ G:i', 'buddypress' ); 
  922. $date = date_i18n( $datef, strtotime( $user->user_registered ) ); 
  923. ?> 
  924. <span id="timestamp"><?php printf( __( 'Registered on: %s', 'buddypress' ), '<strong>' . $date . '</strong>' ); ?></span> 
  925. </div> 
  926. </div> <!-- #misc-publishing-actions --> 
  927.  
  928. <div class="clear"></div> 
  929. </div><!-- #minor-publishing --> 
  930.  
  931. <div id="major-publishing-actions"> 
  932.  
  933. <div id="publishing-action"> 
  934. <a class="button bp-view-profile" href="<?php echo esc_url( bp_core_get_user_domain( $user->ID ) ); ?>" target="_blank"><?php esc_html_e( 'View Profile', 'buddypress' ); ?></a> 
  935. <?php submit_button( esc_html__( 'Update Profile', 'buddypress' ), 'primary', 'save', false ); ?> 
  936. </div> 
  937. <div class="clear"></div> 
  938. </div><!-- #major-publishing-actions --> 
  939.  
  940. </div><!-- #submitcomment --> 
  941.  
  942. <?php 
  943.  
  944. /** 
  945. * Render the fallback metabox in case a user has been marked as a spammer. 
  946. * @since 2.0.0 
  947. * @param WP_User|null $user The WP_User object to be edited. 
  948. */ 
  949. public function user_admin_spammer_metabox( $user = null ) { 
  950. ?> 
  951. <p><?php printf( __( '%s has been marked as a spammer. All BuddyPress data associated with the user has been removed', 'buddypress' ), esc_html( bp_core_get_user_displayname( $user->ID ) ) ) ;?></p> 
  952. <?php 
  953.  
  954. /** 
  955. * Render the Stats metabox to moderate inappropriate images. 
  956. * @since 2.0.0 
  957. * @param WP_User|null $user The WP_User object to be edited. 
  958. */ 
  959. public function user_admin_stats_metabox( $user = null ) { 
  960.  
  961. // Bail if no user ID. 
  962. if ( empty( $user->ID ) ) { 
  963. return; 
  964.  
  965. // If account is not activated last activity is the time user registered. 
  966. if ( isset( $user->user_status ) && 2 == $user->user_status ) { 
  967. $last_active = $user->user_registered; 
  968.  
  969. // Account is activated, getting user's last activity. 
  970. } else { 
  971. $last_active = bp_get_user_last_activity( $user->ID ); 
  972.  
  973. $datef = __( 'M j, Y @ G:i', 'buddypress' ); 
  974. $date = date_i18n( $datef, strtotime( $last_active ) ); ?> 
  975.  
  976. <ul> 
  977. <li class="bp-members-profile-stats"><?php printf( __( 'Last active: %1$s', 'buddypress' ), '<strong>' . $date . '</strong>' ); ?></li> 
  978.  
  979. <?php 
  980. // Loading other stats only if user has activated their account. 
  981. if ( empty( $user->user_status ) ) { 
  982.  
  983. /** 
  984. * Fires in the user stats metabox if the user has activated their account. 
  985. * @since 2.0.0 
  986. * @param array $value Array holding the user ID. 
  987. * @param object $user Current displayed user object. 
  988. */ 
  989. do_action( 'bp_members_admin_user_stats', array( 'user_id' => $user->ID ), $user ); 
  990. ?> 
  991. </ul> 
  992.  
  993. <?php 
  994.  
  995. /** 
  996. * Render the Member Type metabox. 
  997. * @since 2.2.0 
  998. * @param WP_User|null $user The WP_User object to be edited. 
  999. */ 
  1000. public function user_admin_member_type_metabox( $user = null ) { 
  1001.  
  1002. // Bail if no user ID. 
  1003. if ( empty( $user->ID ) ) { 
  1004. return; 
  1005.  
  1006. $types = bp_get_member_types( array(), 'objects' ); 
  1007. $current_type = bp_get_member_type( $user->ID ); 
  1008. ?> 
  1009.  
  1010. <label for="bp-members-profile-member-type" class="screen-reader-text"><?php 
  1011. /** translators: accessibility text */ 
  1012. esc_html_e( 'Select member type', 'buddypress' ); 
  1013. ?></label> 
  1014. <select name="bp-members-profile-member-type" id="bp-members-profile-member-type"> 
  1015. <option value="" <?php selected( '', $current_type ); ?>><?php 
  1016. /** translators: no option picked in select box */ 
  1017. esc_attr_e( '----', 'buddypress' ); 
  1018. ?></option> 
  1019. <?php foreach ( $types as $type ) : ?> 
  1020. <option value="<?php echo esc_attr( $type->name ) ?>" <?php selected( $type->name, $current_type ) ?>><?php echo esc_html( $type->labels['singular_name'] ) ?></option> 
  1021. <?php endforeach; ?> 
  1022. </select> 
  1023.  
  1024. <?php 
  1025.  
  1026. wp_nonce_field( 'bp-member-type-change-' . $user->ID, 'bp-member-type-nonce' ); 
  1027.  
  1028. /** 
  1029. * Process changes from the Member Type metabox. 
  1030. * @since 2.2.0 
  1031. */ 
  1032. public function process_member_type_update() { 
  1033. if ( ! isset( $_POST['bp-member-type-nonce'] ) || ! isset( $_POST['bp-members-profile-member-type'] ) ) { 
  1034. return; 
  1035.  
  1036. $user_id = $this->get_user_id(); 
  1037.  
  1038. check_admin_referer( 'bp-member-type-change-' . $user_id, 'bp-member-type-nonce' ); 
  1039.  
  1040. // Permission check. 
  1041. if ( ! current_user_can( 'bp_moderate' ) && $user_id != bp_loggedin_user_id() ) { 
  1042. return; 
  1043.  
  1044. // Member type string must either reference a valid member type, or be empty. 
  1045. $member_type = stripslashes( $_POST['bp-members-profile-member-type'] ); 
  1046. if ( ! empty( $member_type ) && ! bp_get_member_type_object( $member_type ) ) { 
  1047. return; 
  1048.  
  1049. /** 
  1050. * If an invalid member type is passed, someone's doing something 
  1051. * fishy with the POST request, so we can fail silently. 
  1052. */ 
  1053. if ( bp_set_member_type( $user_id, $member_type ) ) { 
  1054. // @todo Success messages can't be posted because other stuff happens on the page load. 
  1055.  
  1056. /** 
  1057. * Add a link to Profile in Users listing row actions. 
  1058. * @since 2.0.0 
  1059. * @param array|string $actions WordPress row actions (edit, delete). 
  1060. * @param object|null $user The object for the user row. 
  1061. * @return array Merged actions. 
  1062. */ 
  1063. public function row_actions( $actions = '', $user = null ) { 
  1064.  
  1065. // Bail if no user ID. 
  1066. if ( empty( $user->ID ) ) { 
  1067. return; 
  1068.  
  1069. // Setup args array. 
  1070. $args = array(); 
  1071.  
  1072. // Add the user ID if it's not for the current user. 
  1073. if ( $user->ID !== $this->current_user_id ) { 
  1074. $args['user_id'] = $user->ID; 
  1075.  
  1076. // Add the referer. 
  1077. $args['wp_http_referer'] = urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ); 
  1078.  
  1079. // Add the "Extended" link if the current user can edit this user. 
  1080. if ( current_user_can( 'edit_user', $user->ID ) || bp_current_user_can( 'bp_moderate' ) ) { 
  1081.  
  1082. // Add query args and setup the Extended link. 
  1083. $edit_profile = add_query_arg( $args, $this->edit_profile_url ); 
  1084. $edit_profile_link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $edit_profile ), esc_html__( 'Extended', 'buddypress' ) ); 
  1085.  
  1086. /** 
  1087. * Check the edit action is available 
  1088. * and preserve the order edit | profile | remove/delete. 
  1089. */ 
  1090. if ( ! empty( $actions['edit'] ) ) { 
  1091. $edit_action = $actions['edit']; 
  1092. unset( $actions['edit'] ); 
  1093.  
  1094. $new_edit_actions = array( 
  1095. 'edit' => $edit_action,  
  1096. 'edit-profile' => $edit_profile_link,  
  1097. ); 
  1098.  
  1099. // If not available simply add the edit profile action. 
  1100. } else { 
  1101. $new_edit_actions = array( 'edit-profile' => $edit_profile_link ); 
  1102.  
  1103. $actions = array_merge( $new_edit_actions, $actions ); 
  1104.  
  1105. return $actions; 
  1106.  
  1107. /** 
  1108. * Add a filter to edit profile url in WP Admin Bar. 
  1109. * @since 2.1.0 
  1110. */ 
  1111. public function add_edit_profile_url_filter() { 
  1112. add_filter( 'bp_members_edit_profile_url', array( $this, 'filter_adminbar_profile_link' ), 10, 3 ); 
  1113.  
  1114. /** 
  1115. * Filter the profile url. 
  1116. * @since 2.1.0 
  1117. * @param string $profile_link Profile Link for admin bar. 
  1118. * @param string $url Profile URL. 
  1119. * @param int $user_id User ID. 
  1120. * @return string 
  1121. */ 
  1122. public function filter_adminbar_profile_link( $profile_link = '', $url = '', $user_id = 0 ) { 
  1123. if ( ! is_super_admin( $user_id ) && is_admin() ) { 
  1124. $profile_link = user_admin_url( 'profile.php' ); 
  1125. return $profile_link; 
  1126.  
  1127. /** 
  1128. * Remove the filter to edit profile url in WP Admin Bar. 
  1129. * @since 2.1.0 
  1130. */ 
  1131. public function remove_edit_profile_url_filter() { 
  1132. remove_filter( 'bp_members_edit_profile_url', array( $this, 'filter_adminbar_profile_link' ), 10 ); 
  1133.  
  1134. /** Signups Management ****************************************************/ 
  1135.  
  1136. /** 
  1137. * Display the admin preferences about signups pagination. 
  1138. * @since 2.0.0 
  1139. * @param int $value Value for signup option. 
  1140. * @param string $option Value for the option key. 
  1141. * @param int $new_value Value for the saved option. 
  1142. * @return int The pagination preferences. 
  1143. */ 
  1144. public function signup_screen_options( $value = 0, $option = '', $new_value = 0 ) { 
  1145. if ( 'users_page_bp_signups_network_per_page' != $option && 'users_page_bp_signups_per_page' != $option ) { 
  1146. return $value; 
  1147.  
  1148. // Per page. 
  1149. $new_value = (int) $new_value; 
  1150. if ( $new_value < 1 || $new_value > 999 ) { 
  1151. return $value; 
  1152.  
  1153. return $new_value; 
  1154.  
  1155. /** 
  1156. * Make sure no signups will show in users list. 
  1157. * This is needed to handle signups that may have not been activated 
  1158. * before the 2.0.0 upgrade. 
  1159. * @since 2.0.0 
  1160. * @param WP_User_Query|null $query The users query. 
  1161. * @return WP_User_Query The users query without the signups. 
  1162. */ 
  1163. public function remove_signups_from_user_query( $query = null ) { 
  1164. global $wpdb; 
  1165.  
  1166. // Bail if this is an ajax request. 
  1167. if ( defined( 'DOING_AJAX' ) ) { 
  1168. return; 
  1169.  
  1170. // Bail if updating BuddyPress. 
  1171. if ( bp_is_update() ) { 
  1172. return; 
  1173.  
  1174. // Bail if there is no current admin screen. 
  1175. if ( ! function_exists( 'get_current_screen' ) || ! get_current_screen() ) { 
  1176. return; 
  1177.  
  1178. // Get current screen. 
  1179. $current_screen = get_current_screen(); 
  1180.  
  1181. // Bail if not on a users page. 
  1182. if ( ! isset( $current_screen->id ) || $this->users_page !== $current_screen->id ) { 
  1183. return; 
  1184.  
  1185. // Bail if already querying by an existing role. 
  1186. if ( ! empty( $query->query_vars['role'] ) ) { 
  1187. return; 
  1188.  
  1189. $query->query_where .= " AND {$wpdb->users}.user_status != 2"; 
  1190.  
  1191. /** 
  1192. * Filter the WP Users List Table views to include 'bp-signups'. 
  1193. * @since 2.0.0 
  1194. * @param array $views WP List Table views. 
  1195. * @return array The views with the signup view added. 
  1196. */ 
  1197. public function signup_filter_view( $views = array() ) { 
  1198. global $role; 
  1199.  
  1200. // Remove the 'current' class from All if we're on the signups view. 
  1201. if ( 'registered' === $role ) { 
  1202. $views['all'] = str_replace( 'class="current"', '', $views['all'] ); 
  1203. $class = 'current'; 
  1204. } else { 
  1205. $class = ''; 
  1206.  
  1207. $signups = BP_Signup::count_signups(); 
  1208.  
  1209. if ( is_network_admin() ) { 
  1210. $base_url = network_admin_url( 'users.php' ); 
  1211. } else { 
  1212. $base_url = bp_get_admin_url( 'users.php' ); 
  1213.  
  1214. $url = add_query_arg( 'page', 'bp-signups', $base_url ); 
  1215. $text = sprintf( _x( 'Pending %s', 'signup users', 'buddypress' ), '<span class="count">(' . number_format_i18n( $signups ) . ')</span>' ); 
  1216.  
  1217. $views['registered'] = sprintf( '<a href="%1$s" class="%2$s">%3$s</a>', esc_url( $url ), $class, $text ); 
  1218.  
  1219. return $views; 
  1220.  
  1221. /** 
  1222. * Load the Signup WP Users List table. 
  1223. * @since 2.0.0 
  1224. * @param string $class The name of the class to use. 
  1225. * @param string $required The parent class. 
  1226. * @return WP_List_Table The List table. 
  1227. */ 
  1228. public static function get_list_table_class( $class = '', $required = '' ) { 
  1229. if ( empty( $class ) ) { 
  1230. return; 
  1231.  
  1232. if ( ! empty( $required ) ) { 
  1233. require_once( ABSPATH . 'wp-admin/includes/class-wp-' . $required . '-list-table.php' ); 
  1234.  
  1235. return new $class(); 
  1236.  
  1237. /** 
  1238. * Set up the signups admin page. 
  1239. * Loaded before the page is rendered, this function does all initial 
  1240. * setup, including: processing form requests, registering contextual 
  1241. * help, and setting up screen options. 
  1242. * @since 2.0.0 
  1243. * @global $bp_members_signup_list_table 
  1244. */ 
  1245. public function signups_admin_load() { 
  1246. global $bp_members_signup_list_table; 
  1247.  
  1248. // Build redirection URL. 
  1249. $redirect_to = remove_query_arg( array( 'action', 'error', 'updated', 'activated', 'notactivated', 'deleted', 'notdeleted', 'resent', 'notresent', 'do_delete', 'do_resend', 'do_activate', '_wpnonce', 'signup_ids' ), $_SERVER['REQUEST_URI'] ); 
  1250. $doaction = bp_admin_list_table_current_bulk_action(); 
  1251.  
  1252. /** 
  1253. * Fires at the start of the signups admin load. 
  1254. * @since 2.0.0 
  1255. * @param string $doaction Current bulk action being processed. 
  1256. * @param array $_REQUEST Current $_REQUEST global. 
  1257. */ 
  1258. do_action( 'bp_signups_admin_load', $doaction, $_REQUEST ); 
  1259.  
  1260. /** 
  1261. * Filters the allowed actions for use in the user signups admin page. 
  1262. * @since 2.0.0 
  1263. * @param array $value Array of allowed actions to use. 
  1264. */ 
  1265. $allowed_actions = apply_filters( 'bp_signups_admin_allowed_actions', array( 'do_delete', 'do_activate', 'do_resend' ) ); 
  1266.  
  1267. // Prepare the display of the Community Profile screen. 
  1268. if ( ! in_array( $doaction, $allowed_actions ) || ( -1 == $doaction ) ) { 
  1269.  
  1270. if ( is_network_admin() ) { 
  1271. $bp_members_signup_list_table = self::get_list_table_class( 'BP_Members_MS_List_Table', 'ms-users' ); 
  1272. } else { 
  1273. $bp_members_signup_list_table = self::get_list_table_class( 'BP_Members_List_Table', 'users' ); 
  1274.  
  1275. // The per_page screen option. 
  1276. add_screen_option( 'per_page', array( 'label' => _x( 'Pending Accounts', 'Pending Accounts per page (screen options)', 'buddypress' ) ) ); 
  1277.  
  1278. get_current_screen()->add_help_tab( array( 
  1279. 'id' => 'bp-signups-overview',  
  1280. 'title' => __( 'Overview', 'buddypress' ),  
  1281. 'content' => 
  1282. '<p>' . __( 'This is the administration screen for pending accounts on your site.', 'buddypress' ) . '</p>' . 
  1283. '<p>' . __( 'From the screen options, you can customize the displayed columns and the pagination of this screen.', 'buddypress' ) . '</p>' . 
  1284. '<p>' . __( 'You can reorder the list of your pending accounts by clicking on the Username, Email or Registered column headers.', 'buddypress' ) . '</p>' . 
  1285. '<p>' . __( 'Using the search form, you can find pending accounts more easily. The Username and Email fields will be included in the search.', 'buddypress' ) . '</p>' 
  1286. ) ); 
  1287.  
  1288. get_current_screen()->add_help_tab( array( 
  1289. 'id' => 'bp-signups-actions',  
  1290. 'title' => __( 'Actions', 'buddypress' ),  
  1291. 'content' => 
  1292. '<p>' . __( 'Hovering over a row in the pending accounts list will display action links that allow you to manage pending accounts. You can perform the following actions:', 'buddypress' ) . '</p>' . 
  1293. '<ul><li>' . __( '"Email" takes you to the confirmation screen before being able to send the activation link to the desired pending account. You can only send the activation email once per day.', 'buddypress' ) . '</li>' . 
  1294. '<li>' . __( '"Delete" allows you to delete a pending account from your site. You will be asked to confirm this deletion.', 'buddypress' ) . '</li></ul>' . 
  1295. '<p>' . __( 'By clicking on a Username you will be able to activate a pending account from the confirmation screen.', 'buddypress' ) . '</p>' . 
  1296. '<p>' . __( 'Bulk actions allow you to perform these 3 actions for the selected rows.', 'buddypress' ) . '</p>' 
  1297. ) ); 
  1298.  
  1299. // Help panel - sidebar links. 
  1300. get_current_screen()->set_help_sidebar( 
  1301. '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' . 
  1302. '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>' 
  1303. ); 
  1304.  
  1305. // Add accessible hidden headings and text for the Pending Users screen. 
  1306. if ( bp_get_major_wp_version() >= 4.4 ) { 
  1307. get_current_screen()->set_screen_reader_content( array( 
  1308. /** translators: accessibility text */ 
  1309. 'heading_views' => __( 'Filter users list', 'buddypress' ),  
  1310. /** translators: accessibility text */ 
  1311. 'heading_pagination' => __( 'Pending users list navigation', 'buddypress' ),  
  1312. /** translators: accessibility text */ 
  1313. 'heading_list' => __( 'Pending users list', 'buddypress' ),  
  1314. ) ); 
  1315.  
  1316. } else { 
  1317. if ( ! empty( $_REQUEST['signup_ids' ] ) ) { 
  1318. $signups = wp_parse_id_list( $_REQUEST['signup_ids' ] ); 
  1319.  
  1320. // Handle resent activation links. 
  1321. if ( 'do_resend' == $doaction ) { 
  1322.  
  1323. // Nonce check. 
  1324. check_admin_referer( 'signups_resend' ); 
  1325.  
  1326. $resent = BP_Signup::resend( $signups ); 
  1327.  
  1328. if ( empty( $resent ) ) { 
  1329. $redirect_to = add_query_arg( 'error', $doaction, $redirect_to ); 
  1330. } else { 
  1331. $query_arg = array( 'updated' => 'resent' ); 
  1332.  
  1333. if ( ! empty( $resent['resent'] ) ) { 
  1334. $query_arg['resent'] = count( $resent['resent'] ); 
  1335.  
  1336. if ( ! empty( $resent['errors'] ) ) { 
  1337. $query_arg['notsent'] = count( $resent['errors'] ); 
  1338. set_transient( '_bp_admin_signups_errors', $resent['errors'], 30 ); 
  1339.  
  1340. $redirect_to = add_query_arg( $query_arg, $redirect_to ); 
  1341.  
  1342. bp_core_redirect( $redirect_to ); 
  1343.  
  1344. // Handle activated accounts. 
  1345. } elseif ( 'do_activate' == $doaction ) { 
  1346.  
  1347. // Nonce check. 
  1348. check_admin_referer( 'signups_activate' ); 
  1349.  
  1350. $activated = BP_Signup::activate( $signups ); 
  1351.  
  1352. if ( empty( $activated ) ) { 
  1353. $redirect_to = add_query_arg( 'error', $doaction, $redirect_to ); 
  1354. } else { 
  1355. $query_arg = array( 'updated' => 'activated' ); 
  1356.  
  1357. if ( ! empty( $activated['activated'] ) ) { 
  1358. $query_arg['activated'] = count( $activated['activated'] ); 
  1359.  
  1360. if ( ! empty( $activated['errors'] ) ) { 
  1361. $query_arg['notactivated'] = count( $activated['errors'] ); 
  1362. set_transient( '_bp_admin_signups_errors', $activated['errors'], 30 ); 
  1363.  
  1364. $redirect_to = add_query_arg( $query_arg, $redirect_to ); 
  1365.  
  1366. bp_core_redirect( $redirect_to ); 
  1367.  
  1368. // Handle sign-ups delete. 
  1369. } elseif ( 'do_delete' == $doaction ) { 
  1370.  
  1371. // Nonce check. 
  1372. check_admin_referer( 'signups_delete' ); 
  1373.  
  1374. $deleted = BP_Signup::delete( $signups ); 
  1375.  
  1376. if ( empty( $deleted ) ) { 
  1377. $redirect_to = add_query_arg( 'error', $doaction, $redirect_to ); 
  1378. } else { 
  1379. $query_arg = array( 'updated' => 'deleted' ); 
  1380.  
  1381. if ( ! empty( $deleted['deleted'] ) ) { 
  1382. $query_arg['deleted'] = count( $deleted['deleted'] ); 
  1383.  
  1384. if ( ! empty( $deleted['errors'] ) ) { 
  1385. $query_arg['notdeleted'] = count( $deleted['errors'] ); 
  1386. set_transient( '_bp_admin_signups_errors', $deleted['errors'], 30 ); 
  1387.  
  1388. $redirect_to = add_query_arg( $query_arg, $redirect_to ); 
  1389.  
  1390. bp_core_redirect( $redirect_to ); 
  1391.  
  1392. // Plugins can update other stuff from here. 
  1393. } else { 
  1394. $this->redirect = $redirect_to; 
  1395.  
  1396. /** 
  1397. * Fires at end of signups admin load if doaction does not match any actions. 
  1398. * @since 2.0.0 
  1399. * @param string $doaction Current bulk action being processed. 
  1400. * @param array $_REQUEST Current $_REQUEST global. 
  1401. * @param string $redirect Determined redirect url to send user to. 
  1402. */ 
  1403. do_action( 'bp_members_admin_update_signups', $doaction, $_REQUEST, $this->redirect ); 
  1404.  
  1405. bp_core_redirect( $this->redirect ); 
  1406.  
  1407. /** 
  1408. * Display any activation errors. 
  1409. * @since 2.0.0 
  1410. */ 
  1411. public function signups_display_errors() { 
  1412.  
  1413. // Look for sign-up errors. 
  1414. $errors = get_transient( '_bp_admin_signups_errors' ); 
  1415.  
  1416. // Bail if no activation errors. 
  1417. if ( empty( $errors ) ) { 
  1418. return; 
  1419.  
  1420. // Loop through errors and display them. 
  1421. foreach ( $errors as $error ) : ?> 
  1422.  
  1423. <li><?php echo esc_html( $error[0] );?>: <?php echo esc_html( $error[1] );?></li> 
  1424.  
  1425. <?php endforeach; 
  1426.  
  1427. // Delete the redirect transient. 
  1428. delete_transient( '_bp_admin_signups_errors' ); 
  1429.  
  1430. /** 
  1431. * Get admin notice when viewing the sign-up page. 
  1432. * @since 2.1.0 
  1433. * @return array 
  1434. */ 
  1435. private function get_signup_notice() { 
  1436.  
  1437. // Setup empty notice for return value. 
  1438. $notice = array(); 
  1439.  
  1440. // Updates. 
  1441. if ( ! empty( $_REQUEST['updated'] ) ) { 
  1442. switch ( $_REQUEST['updated'] ) { 
  1443. case 'resent': 
  1444. $notice = array( 
  1445. 'class' => 'updated',  
  1446. 'message' => '' 
  1447. ); 
  1448.  
  1449. if ( ! empty( $_REQUEST['resent'] ) ) { 
  1450. $notice['message'] .= sprintf( 
  1451. _nx( '%s activation email successfully sent! ', '%s activation emails successfully sent! ',  
  1452. absint( $_REQUEST['resent'] ),  
  1453. 'signup resent',  
  1454. 'buddypress' 
  1455. ),  
  1456. number_format_i18n( absint( $_REQUEST['resent'] ) ) 
  1457. ); 
  1458.  
  1459. if ( ! empty( $_REQUEST['notsent'] ) ) { 
  1460. $notice['message'] .= sprintf( 
  1461. _nx( '%s activation email was not sent.', '%s activation emails were not sent.',  
  1462. absint( $_REQUEST['notsent'] ),  
  1463. 'signup notsent',  
  1464. 'buddypress' 
  1465. ),  
  1466. number_format_i18n( absint( $_REQUEST['notsent'] ) ) 
  1467. ); 
  1468.  
  1469. if ( empty( $_REQUEST['resent'] ) ) { 
  1470. $notice['class'] = 'error'; 
  1471.  
  1472. break; 
  1473.  
  1474. case 'activated': 
  1475. $notice = array( 
  1476. 'class' => 'updated',  
  1477. 'message' => '' 
  1478. ); 
  1479.  
  1480. if ( ! empty( $_REQUEST['activated'] ) ) { 
  1481. $notice['message'] .= sprintf( 
  1482. _nx( '%s account successfully activated! ', '%s accounts successfully activated! ',  
  1483. absint( $_REQUEST['activated'] ),  
  1484. 'signup resent',  
  1485. 'buddypress' 
  1486. ),  
  1487. number_format_i18n( absint( $_REQUEST['activated'] ) ) 
  1488. ); 
  1489.  
  1490. if ( ! empty( $_REQUEST['notactivated'] ) ) { 
  1491. $notice['message'] .= sprintf( 
  1492. _nx( '%s account was not activated.', '%s accounts were not activated.',  
  1493. absint( $_REQUEST['notactivated'] ),  
  1494. 'signup notsent',  
  1495. 'buddypress' 
  1496. ),  
  1497. number_format_i18n( absint( $_REQUEST['notactivated'] ) ) 
  1498. ); 
  1499.  
  1500. if ( empty( $_REQUEST['activated'] ) ) { 
  1501. $notice['class'] = 'error'; 
  1502.  
  1503. break; 
  1504.  
  1505. case 'deleted': 
  1506. $notice = array( 
  1507. 'class' => 'updated',  
  1508. 'message' => '' 
  1509. ); 
  1510.  
  1511. if ( ! empty( $_REQUEST['deleted'] ) ) { 
  1512. $notice['message'] .= sprintf( 
  1513. _nx( '%s sign-up successfully deleted!', '%s sign-ups successfully deleted!',  
  1514. absint( $_REQUEST['deleted'] ),  
  1515. 'signup deleted',  
  1516. 'buddypress' 
  1517. ),  
  1518. number_format_i18n( absint( $_REQUEST['deleted'] ) ) 
  1519. ); 
  1520.  
  1521. if ( ! empty( $_REQUEST['notdeleted'] ) ) { 
  1522. $notice['message'] .= sprintf( 
  1523. _nx( '%s sign-up was not deleted.', '%s sign-ups were not deleted.',  
  1524. absint( $_REQUEST['notdeleted'] ),  
  1525. 'signup notdeleted',  
  1526. 'buddypress' 
  1527. ),  
  1528. number_format_i18n( absint( $_REQUEST['notdeleted'] ) ) 
  1529. ); 
  1530.  
  1531. if ( empty( $_REQUEST['deleted'] ) ) { 
  1532. $notice['class'] = 'error'; 
  1533.  
  1534. break; 
  1535.  
  1536. // Errors. 
  1537. if ( ! empty( $_REQUEST['error'] ) ) { 
  1538. switch ( $_REQUEST['error'] ) { 
  1539. case 'do_resend': 
  1540. $notice = array( 
  1541. 'class' => 'error',  
  1542. 'message' => esc_html__( 'There was a problem sending the activation emails. Please try again.', 'buddypress' ),  
  1543. ); 
  1544. break; 
  1545.  
  1546. case 'do_activate': 
  1547. $notice = array( 
  1548. 'class' => 'error',  
  1549. 'message' => esc_html__( 'There was a problem activating accounts. Please try again.', 'buddypress' ),  
  1550. ); 
  1551. break; 
  1552.  
  1553. case 'do_delete': 
  1554. $notice = array( 
  1555. 'class' => 'error',  
  1556. 'message' => esc_html__( 'There was a problem deleting sign-ups. Please try again.', 'buddypress' ),  
  1557. ); 
  1558. break; 
  1559.  
  1560. return $notice; 
  1561.  
  1562. /** 
  1563. * Signups admin page router. 
  1564. * Depending on the context, display 
  1565. * - the list of signups,  
  1566. * - or the delete confirmation screen,  
  1567. * - or the activate confirmation screen,  
  1568. * - or the "resend" email confirmation screen. 
  1569. * Also prepare the admin notices. 
  1570. * @since 2.0.0 
  1571. */ 
  1572. public function signups_admin() { 
  1573. $doaction = bp_admin_list_table_current_bulk_action(); 
  1574.  
  1575. // Prepare notices for admin. 
  1576. $notice = $this->get_signup_notice(); 
  1577.  
  1578. // Display notices. 
  1579. if ( ! empty( $notice ) ) : 
  1580. if ( 'updated' === $notice['class'] ) : ?> 
  1581.  
  1582. <div id="message" class="<?php echo esc_attr( $notice['class'] ); ?>"> 
  1583.  
  1584. <?php else: ?> 
  1585.  
  1586. <div class="<?php echo esc_attr( $notice['class'] ); ?>"> 
  1587.  
  1588. <?php endif; ?> 
  1589.  
  1590. <p><?php echo $notice['message']; ?></p> 
  1591.  
  1592. <?php if ( ! empty( $_REQUEST['notactivated'] ) || ! empty( $_REQUEST['notdeleted'] ) || ! empty( $_REQUEST['notsent'] ) ) :?> 
  1593.  
  1594. <ul><?php $this->signups_display_errors();?></ul> 
  1595.  
  1596. <?php endif ;?> 
  1597.  
  1598. </div> 
  1599.  
  1600. <?php endif; 
  1601.  
  1602. // Show the proper screen. 
  1603. switch ( $doaction ) { 
  1604. case 'activate' : 
  1605. case 'delete' : 
  1606. case 'resend' : 
  1607. $this->signups_admin_manage( $doaction ); 
  1608. break; 
  1609.  
  1610. default: 
  1611. $this->signups_admin_index(); 
  1612. break; 
  1613.  
  1614.  
  1615. /** 
  1616. * This is the list of the Pending accounts (signups). 
  1617. * @since 2.0.0 
  1618. * @global $plugin_page 
  1619. * @global $bp_members_signup_list_table 
  1620. */ 
  1621. public function signups_admin_index() { 
  1622. global $plugin_page, $bp_members_signup_list_table; 
  1623.  
  1624. $usersearch = ! empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : ''; 
  1625.  
  1626. // Prepare the group items for display. 
  1627. $bp_members_signup_list_table->prepare_items(); 
  1628.  
  1629. if ( is_network_admin() ) { 
  1630. $form_url = network_admin_url( 'users.php' ); 
  1631. } else { 
  1632. $form_url = bp_get_admin_url( 'users.php' ); 
  1633.  
  1634. $form_url = add_query_arg( 
  1635. array( 
  1636. 'page' => 'bp-signups',  
  1637. ),  
  1638. $form_url 
  1639. ); 
  1640.  
  1641. $search_form_url = remove_query_arg( 
  1642. array( 
  1643. 'action',  
  1644. 'deleted',  
  1645. 'notdeleted',  
  1646. 'error',  
  1647. 'updated',  
  1648. 'delete',  
  1649. 'activate',  
  1650. 'activated',  
  1651. 'notactivated',  
  1652. 'resend',  
  1653. 'resent',  
  1654. 'notresent',  
  1655. 'do_delete',  
  1656. 'do_activate',  
  1657. 'do_resend',  
  1658. 'action2',  
  1659. '_wpnonce',  
  1660. 'signup_ids' 
  1661. ), $_SERVER['REQUEST_URI'] 
  1662. ); 
  1663.  
  1664. ?> 
  1665.  
  1666. <div class="wrap"> 
  1667. <h1><?php _e( 'Users', 'buddypress' ); ?> 
  1668.  
  1669. <?php if ( current_user_can( 'create_users' ) ) : ?> 
  1670.  
  1671. <a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add New', 'user', 'buddypress' ); ?></a> 
  1672.  
  1673. <?php elseif ( is_multisite() && current_user_can( 'promote_users' ) ) : ?> 
  1674.  
  1675. <a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add Existing', 'user', 'buddypress' ); ?></a> 
  1676.  
  1677. <?php endif; 
  1678.  
  1679. if ( $usersearch ) { 
  1680. printf( '<span class="subtitle">' . __( 'Search results for “%s”', 'buddypress' ) . '</span>', esc_html( $usersearch ) ); 
  1681.  
  1682. ?> 
  1683. </h1> 
  1684.  
  1685. <?php // Display each signups on its own row. ?> 
  1686. <?php $bp_members_signup_list_table->views(); ?> 
  1687.  
  1688. <form id="bp-signups-search-form" action="<?php echo esc_url( $search_form_url ) ;?>"> 
  1689. <input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>" /> 
  1690. <?php $bp_members_signup_list_table->search_box( __( 'Search Pending Users', 'buddypress' ), 'bp-signups' ); ?> 
  1691. </form> 
  1692.  
  1693. <form id="bp-signups-form" action="<?php echo esc_url( $form_url );?>" method="post"> 
  1694. <?php $bp_members_signup_list_table->display(); ?> 
  1695. </form> 
  1696. </div> 
  1697. <?php 
  1698.  
  1699. /** 
  1700. * This is the confirmation screen for actions. 
  1701. * @since 2.0.0 
  1702. * @param string $action Delete, activate, or resend activation link. 
  1703. * @return string 
  1704. */ 
  1705. public function signups_admin_manage( $action = '' ) { 
  1706. if ( ! current_user_can( $this->capability ) || empty( $action ) ) { 
  1707. die( '-1' ); 
  1708.  
  1709. // Get the user IDs from the URL. 
  1710. $ids = false; 
  1711. if ( ! empty( $_POST['allsignups'] ) ) { 
  1712. $ids = wp_parse_id_list( $_POST['allsignups'] ); 
  1713. } elseif ( ! empty( $_GET['signup_id'] ) ) { 
  1714. $ids = absint( $_GET['signup_id'] ); 
  1715.  
  1716. if ( empty( $ids ) ) { 
  1717. return false; 
  1718.  
  1719. // Query for signups, and filter out those IDs that don't 
  1720. // correspond to an actual signup. 
  1721. $signups_query = BP_Signup::get( array( 
  1722. 'include' => $ids,  
  1723. ) ); 
  1724.  
  1725. $signups = $signups_query['signups']; 
  1726. $signup_ids = wp_list_pluck( $signups, 'signup_id' ); 
  1727.  
  1728. // Set up strings. 
  1729. switch ( $action ) { 
  1730. case 'delete' : 
  1731. $header_text = __( 'Delete Pending Accounts', 'buddypress' ); 
  1732. if ( 1 == count( $signup_ids ) ) { 
  1733. $helper_text = __( 'You are about to delete the following account:', 'buddypress' ); 
  1734. } else { 
  1735. $helper_text = __( 'You are about to delete the following accounts:', 'buddypress' ); 
  1736. break; 
  1737.  
  1738. case 'activate' : 
  1739. $header_text = __( 'Activate Pending Accounts', 'buddypress' ); 
  1740. if ( 1 == count( $signup_ids ) ) { 
  1741. $helper_text = __( 'You are about to activate the following account:', 'buddypress' ); 
  1742. } else { 
  1743. $helper_text = __( 'You are about to activate the following accounts:', 'buddypress' ); 
  1744. break; 
  1745.  
  1746. case 'resend' : 
  1747. $header_text = __( 'Resend Activation Emails', 'buddypress' ); 
  1748. if ( 1 == count( $signup_ids ) ) { 
  1749. $helper_text = __( 'You are about to resend an activation email to the following account:', 'buddypress' ); 
  1750. } else { 
  1751. $helper_text = __( 'You are about to resend an activation email to the following accounts:', 'buddypress' ); 
  1752. break; 
  1753.  
  1754. // These arguments are added to all URLs. 
  1755. $url_args = array( 'page' => 'bp-signups' ); 
  1756.  
  1757. // These arguments are only added when performing an action. 
  1758. $action_args = array( 
  1759. 'action' => 'do_' . $action,  
  1760. 'signup_ids' => implode( ', ', $signup_ids ) 
  1761. ); 
  1762.  
  1763. if ( is_network_admin() ) { 
  1764. $base_url = network_admin_url( 'users.php' ); 
  1765. } else { 
  1766. $base_url = bp_get_admin_url( 'users.php' ); 
  1767.  
  1768. $cancel_url = add_query_arg( $url_args, $base_url ); 
  1769. $action_url = wp_nonce_url( 
  1770. add_query_arg( 
  1771. array_merge( $url_args, $action_args ),  
  1772. $base_url 
  1773. ),  
  1774. 'signups_' . $action 
  1775. ); 
  1776.  
  1777. // Prefetch registration field data. 
  1778. $fdata = array(); 
  1779. if ( 'activate' === $action && bp_is_active( 'xprofile' ) ) { 
  1780. $fields = bp_xprofile_get_groups( array( 
  1781. 'profile_group_id' => 1,  
  1782. 'exclude_fields' => 1,  
  1783. 'update_meta_cache' => false,  
  1784. 'fetch_fields' => true,  
  1785. ) ); 
  1786. $fields = $fields[0]->fields; 
  1787. foreach( $fields as $f ) { 
  1788. $fdata[ $f->id ] = $f->name; 
  1789.  
  1790. ?> 
  1791.  
  1792. <div class="wrap"> 
  1793. <h1><?php echo esc_html( $header_text ); ?></h1> 
  1794. <p><?php echo esc_html( $helper_text ); ?></p> 
  1795.  
  1796. <ol class="bp-signups-list"> 
  1797. <?php foreach ( $signups as $signup ) : 
  1798. $last_notified = mysql2date( 'Y/m/d g:i:s a', $signup->date_sent ); 
  1799. $profile_field_ids = array(); 
  1800.  
  1801. // Get all xprofile field IDs except field 1. 
  1802. if ( ! empty( $signup->meta['profile_field_ids'] ) ) { 
  1803. $profile_field_ids = array_flip( explode( ', ', $signup->meta['profile_field_ids'] ) ); 
  1804. unset( $profile_field_ids[1] ); 
  1805. } ?> 
  1806.  
  1807. <li> 
  1808. <strong><?php echo esc_html( $signup->user_login ) ?></strong> 
  1809.  
  1810. <?php if ( 'activate' == $action ) : ?> 
  1811. <table class="wp-list-table widefat fixed striped"> 
  1812. <tbody> 
  1813. <tr> 
  1814. <td class="column-fields"><?php esc_html_e( 'Display Name', 'buddypress' ); ?></td> 
  1815. <td><?php echo esc_html( $signup->user_name ); ?></td> 
  1816. </tr> 
  1817.  
  1818. <tr> 
  1819. <td class="column-fields"><?php esc_html_e( 'Email', 'buddypress' ); ?></td> 
  1820. <td><?php echo sanitize_email( $signup->user_email ); ?></td> 
  1821. </tr> 
  1822.  
  1823. <?php if ( bp_is_active( 'xprofile' ) && ! empty( $profile_field_ids ) ) : ?> 
  1824. <?php foreach ( $profile_field_ids as $pid => $noop ) : 
  1825. $field_value = isset( $signup->meta[ "field_{$pid}" ] ) ? $signup->meta[ "field_{$pid}" ] : ''; ?> 
  1826. <tr> 
  1827. <td class="column-fields"><?php echo esc_html( $fdata[ $pid ] ); ?></td> 
  1828. <td><?php echo $this->format_xprofile_field_for_display( $field_value ); ?></td> 
  1829. </tr> 
  1830.  
  1831. <?php endforeach; ?> 
  1832.  
  1833. <?php endif; ?> 
  1834.  
  1835. </tbody> 
  1836. </table> 
  1837. <?php endif; ?> 
  1838.  
  1839. <?php if ( 'resend' == $action ) : ?> 
  1840.  
  1841. <p class="description"> 
  1842. <?php printf( esc_html__( 'Last notified: %s', 'buddypress'), $last_notified ) ;?> 
  1843.  
  1844. <?php if ( ! empty( $signup->recently_sent ) ) : ?> 
  1845.  
  1846. <span class="attention wp-ui-text-notification"> <?php esc_html_e( '(less than 24 hours ago)', 'buddypress' ); ?></span> 
  1847.  
  1848. <?php endif; ?> 
  1849. </p> 
  1850.  
  1851. <?php endif; ?> 
  1852.  
  1853. </li> 
  1854.  
  1855. <?php endforeach; ?> 
  1856. </ol> 
  1857.  
  1858. <?php if ( 'delete' === $action ) : ?> 
  1859.  
  1860. <p><strong><?php esc_html_e( 'This action cannot be undone.', 'buddypress' ) ?></strong></p> 
  1861.  
  1862. <?php endif ; ?> 
  1863.  
  1864. <a class="button-primary" href="<?php echo esc_url( $action_url ); ?>"><?php esc_html_e( 'Confirm', 'buddypress' ); ?></a> 
  1865. <a class="button" href="<?php echo esc_url( $cancel_url ); ?>"><?php esc_html_e( 'Cancel', 'buddypress' ) ?></a> 
  1866. </div> 
  1867.  
  1868. <?php 
  1869.  
  1870. /** Users List Management ****************************************************/ 
  1871.  
  1872. /** 
  1873. * Display a dropdown to bulk change the member type of selected user(s). 
  1874. * @since 2.7.0 
  1875. * @param string $which Where this dropdown is displayed - top or bottom. 
  1876. */ 
  1877. public function users_table_output_type_change_select( $which = 'top' ) { 
  1878.  
  1879. // Bail if current user cannot promote users. 
  1880. if ( ! bp_current_user_can( 'promote_users' ) ) { 
  1881. return; 
  1882.  
  1883. // `$which` is only passed in WordPress 4.6+. Avoid duplicating controls in earlier versions. 
  1884. static $displayed = false; 
  1885. if ( version_compare( bp_get_major_wp_version(), '4.6', '<' ) && $displayed ) { 
  1886. return; 
  1887. $displayed = true; 
  1888.  
  1889. $id_name = 'bottom' === $which ? 'bp_change_type2' : 'bp_change_type'; 
  1890.  
  1891. $types = bp_get_member_types( array(), 'objects' ); ?> 
  1892.  
  1893. <label class="screen-reader-text" for="<?php echo $id_name; ?>"><?php _e( 'Change member type to…', 'buddypress' ) ?></label> 
  1894. <select name="<?php echo $id_name; ?>" id="<?php echo $id_name; ?>" style="display:inline-block;float:none;"> 
  1895. <option value=""><?php _e( 'Change member type to…', 'buddypress' ) ?></option> 
  1896.  
  1897. <?php foreach( $types as $type ) : ?> 
  1898.  
  1899. <option value="<?php echo esc_attr( $type->name ); ?>"><?php echo esc_html( $type->labels['singular_name'] ); ?></option> 
  1900.  
  1901. <?php endforeach; ?> 
  1902.  
  1903. <option value="remove_member_type"><?php _e( 'No Member Type', 'buddypress' ) ?></option> 
  1904.  
  1905. </select> 
  1906. <?php 
  1907. wp_nonce_field( 'bp-bulk-users-change-type-' . bp_loggedin_user_id(), 'bp-bulk-users-change-type-nonce' ); 
  1908. submit_button( __( 'Change', 'buddypress' ), 'button', 'bp_change_member_type', false ); 
  1909.  
  1910. /** 
  1911. * Process bulk member type change submission from the WP admin users list table. 
  1912. * @since 2.7.0 
  1913. */ 
  1914. public function users_table_process_bulk_type_change() { 
  1915. // Output the admin notice. 
  1916. $this->users_type_change_notice(); 
  1917.  
  1918. // Bail if no users are specified or if this isn't a BuddyPress action. 
  1919. if ( empty( $_REQUEST['users'] ) 
  1920. || ( empty( $_REQUEST['bp_change_type'] ) && empty( $_REQUEST['bp_change_type2'] ) ) 
  1921. || empty( $_REQUEST['bp_change_member_type'] ) 
  1922. ) { 
  1923. return; 
  1924.  
  1925. // Bail if nonce check fails. 
  1926. check_admin_referer( 'bp-bulk-users-change-type-' . bp_loggedin_user_id(), 'bp-bulk-users-change-type-nonce' ); 
  1927.  
  1928. // Bail if current user cannot promote users. 
  1929. if ( ! bp_current_user_can( 'promote_users' ) ) { 
  1930. return; 
  1931.  
  1932. $new_type = ''; 
  1933. if ( ! empty( $_REQUEST['bp_change_type2'] ) ) { 
  1934. $new_type = sanitize_text_field( $_REQUEST['bp_change_type2'] ); 
  1935. } elseif ( ! empty( $_REQUEST['bp_change_type'] ) ) { 
  1936. $new_type = sanitize_text_field( $_REQUEST['bp_change_type'] ); 
  1937.  
  1938. // Check that the selected type actually exists. 
  1939. if ( 'remove_member_type' != $new_type && null === bp_get_member_type_object( $new_type ) ) { 
  1940. $error = true; 
  1941. } else { 
  1942. // Run through user ids. 
  1943. $error = false; 
  1944. foreach ( (array) $_REQUEST['users'] as $user_id ) { 
  1945. $user_id = (int) $user_id; 
  1946.  
  1947. // Get the old member type to check against. 
  1948. $member_type = bp_get_member_type( $user_id ); 
  1949.  
  1950. if ( 'remove_member_type' === $new_type ) { 
  1951. // Remove the current member type, if there's one to remove. 
  1952. if ( $member_type ) { 
  1953. $removed = bp_remove_member_type( $user_id, $member_type ); 
  1954. if ( false === $removed || is_wp_error( $removed ) ) { 
  1955. $error = true; 
  1956. } else { 
  1957. // Set the new member type. 
  1958. if ( $new_type !== $member_type ) { 
  1959. $set = bp_set_member_type( $user_id, $new_type ); 
  1960. if ( false === $set || is_wp_error( $set ) ) { 
  1961. $error = true; 
  1962.  
  1963. // If there were any errors, show the error message. 
  1964. if ( $error ) { 
  1965. $redirect = add_query_arg( array( 'updated' => 'member-type-change-error' ), wp_get_referer() ); 
  1966. } else { 
  1967. $redirect = add_query_arg( array( 'updated' => 'member-type-change-success' ), wp_get_referer() ); 
  1968.  
  1969. wp_redirect( $redirect ); 
  1970. exit(); 
  1971.  
  1972. /** 
  1973. * Display an admin notice upon member type bulk update. 
  1974. * @since 2.7.0 
  1975. */ 
  1976. public function users_type_change_notice() { 
  1977. $updated = isset( $_REQUEST['updated'] ) ? $_REQUEST['updated'] : false; 
  1978.  
  1979. // Display feedback. 
  1980. if ( $updated && in_array( $updated, array( 'member-type-change-error', 'member-type-change-success' ), true ) ) { 
  1981.  
  1982. if ( 'member-type-change-error' === $updated ) { 
  1983. $notice = __( 'There was an error while changing member type. Please try again.', 'buddypress' ); 
  1984. $type = 'error'; 
  1985. } else { 
  1986. $notice = __( 'Member type was changed successfully.', 'buddypress' ); 
  1987. $type = 'updated'; 
  1988.  
  1989. bp_core_add_admin_notice( $notice, $type ); 
  1990.  
  1991. /** 
  1992. * Add member type column to the WordPress admin users list table. 
  1993. * @since 2.7.0 
  1994. * @param array $columns Users table columns. 
  1995. * @return array $columns 
  1996. */ 
  1997. public function users_table_add_type_column( $columns = array() ) { 
  1998. $columns[ bp_get_member_type_tax_name() ] = _x( 'Member Type', 'Label for the WP users table member type column', 'buddypress' ); 
  1999.  
  2000. return $columns; 
  2001.  
  2002. /** 
  2003. * Return member's type for display in the WP admin users list table. 
  2004. * @since 2.7.0 
  2005. * @param string $retval 
  2006. * @param string $column_name 
  2007. * @param int $user_id 
  2008. * @return string Member type as a link to filter all users. 
  2009. */ 
  2010. public function users_table_populate_type_cell( $retval = '', $column_name = '', $user_id = 0 ) { 
  2011. // Only looking for member type column. 
  2012. if ( bp_get_member_type_tax_name() !== $column_name ) { 
  2013. return $retval; 
  2014.  
  2015. // Get the member type. 
  2016. $type = bp_get_member_type( $user_id ); 
  2017.  
  2018. // Output the 
  2019. if ( $type_obj = bp_get_member_type_object( $type ) ) { 
  2020. $url = add_query_arg( array( 'bp-member-type' => urlencode( $type ) ) ); 
  2021. $retval = '<a href="' . esc_url( $url ) . '">' . esc_html( $type_obj->labels['singular_name'] ) . '</a>'; 
  2022.  
  2023. return $retval; 
  2024.  
  2025. /** 
  2026. * Filter WP Admin users list table to include users of the specified type. 
  2027. * @param WP_Query $query 
  2028. * @since 2.7.0 
  2029. */ 
  2030. public function users_table_filter_by_type( $query ) { 
  2031. global $pagenow; 
  2032.  
  2033. if ( is_admin() && 'users.php' === $pagenow && ! empty( $_REQUEST['bp-member-type'] ) ) { 
  2034. $type_slug = sanitize_text_field( $_REQUEST['bp-member-type'] ); 
  2035.  
  2036. // Check that the type is registered. 
  2037. if ( null == bp_get_member_type_object( $type_slug ) ) { 
  2038. return; 
  2039.  
  2040. // Get the list of users that are assigned to this member type. 
  2041. $type = bp_get_term_by( 'slug', $type_slug, bp_get_member_type_tax_name() ); 
  2042.  
  2043. if ( empty( $type->term_id ) ) { 
  2044. return; 
  2045.  
  2046. $user_ids = bp_get_objects_in_term( $type->term_id, bp_get_member_type_tax_name() ); 
  2047.  
  2048. if ( $user_ids && ! is_wp_error( $user_ids ) ) { 
  2049. $query->set( 'include', (array) $user_ids ); 
  2050.  
  2051. /** 
  2052. * Formats a signup's xprofile field data for display. 
  2053. * Operates recursively on arrays, which are then imploded with commas. 
  2054. * @since 2.8.0 
  2055. * @param string|array $value Field value. 
  2056. * @return string 
  2057. */ 
  2058. protected function format_xprofile_field_for_display( $value ) { 
  2059. if ( is_array( $value ) ) { 
  2060. $value = array_map( array( $this, 'format_xprofile_field_for_display' ), $value ); 
  2061. $value = implode( ', ', $value ); 
  2062. } else { 
  2063. $value = stripslashes( $value ); 
  2064. $value = esc_html( $value ); 
  2065.  
  2066. return $value;