class-wp-ms-users-list-table.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <?php
  2. /**
  3. * List Table API: WP_MS_Users_List_Table class
  4. *
  5. * @package WordPress
  6. * @subpackage Administration
  7. * @since 3.1.0
  8. */
  9. /**
  10. * Core class used to implement displaying users in a list table for the network admin.
  11. *
  12. * @since 3.1.0
  13. * @access private
  14. *
  15. * @see WP_List_Table
  16. */
  17. class WP_MS_Users_List_Table extends WP_List_Table {
  18. /**
  19. *
  20. * @return bool
  21. */
  22. public function ajax_user_can() {
  23. return current_user_can( 'manage_network_users' );
  24. }
  25. /**
  26. *
  27. * @global string $usersearch
  28. * @global string $role
  29. * @global wpdb $wpdb
  30. * @global string $mode
  31. */
  32. public function prepare_items() {
  33. global $usersearch, $role, $wpdb, $mode;
  34. $usersearch = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : '';
  35. $users_per_page = $this->get_items_per_page( 'users_network_per_page' );
  36. $role = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : '';
  37. $paged = $this->get_pagenum();
  38. $args = array(
  39. 'number' => $users_per_page,
  40. 'offset' => ( $paged-1 ) * $users_per_page,
  41. 'search' => $usersearch,
  42. 'blog_id' => 0,
  43. 'fields' => 'all_with_meta'
  44. );
  45. if ( wp_is_large_network( 'users' ) ) {
  46. $args['search'] = ltrim( $args['search'], '*' );
  47. } else if ( '' !== $args['search'] ) {
  48. $args['search'] = trim( $args['search'], '*' );
  49. $args['search'] = '*' . $args['search'] . '*';
  50. }
  51. if ( $role === 'super' ) {
  52. $logins = implode( "', '", get_super_admins() );
  53. $args['include'] = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_login IN ('$logins')" );
  54. }
  55. /*
  56. * If the network is large and a search is not being performed,
  57. * show only the latest users with no paging in order to avoid
  58. * expensive count queries.
  59. */
  60. if ( !$usersearch && wp_is_large_network( 'users' ) ) {
  61. if ( !isset($_REQUEST['orderby']) )
  62. $_GET['orderby'] = $_REQUEST['orderby'] = 'id';
  63. if ( !isset($_REQUEST['order']) )
  64. $_GET['order'] = $_REQUEST['order'] = 'DESC';
  65. $args['count_total'] = false;
  66. }
  67. if ( isset( $_REQUEST['orderby'] ) )
  68. $args['orderby'] = $_REQUEST['orderby'];
  69. if ( isset( $_REQUEST['order'] ) )
  70. $args['order'] = $_REQUEST['order'];
  71. if ( ! empty( $_REQUEST['mode'] ) ) {
  72. $mode = $_REQUEST['mode'] === 'excerpt' ? 'excerpt' : 'list';
  73. set_user_setting( 'network_users_list_mode', $mode );
  74. } else {
  75. $mode = get_user_setting( 'network_users_list_mode', 'list' );
  76. }
  77. /** This filter is documented in wp-admin/includes/class-wp-users-list-table.php */
  78. $args = apply_filters( 'users_list_table_query_args', $args );
  79. // Query the user IDs for this page
  80. $wp_user_search = new WP_User_Query( $args );
  81. $this->items = $wp_user_search->get_results();
  82. $this->set_pagination_args( array(
  83. 'total_items' => $wp_user_search->get_total(),
  84. 'per_page' => $users_per_page,
  85. ) );
  86. }
  87. /**
  88. *
  89. * @return array
  90. */
  91. protected function get_bulk_actions() {
  92. $actions = array();
  93. if ( current_user_can( 'delete_users' ) )
  94. $actions['delete'] = __( 'Delete' );
  95. $actions['spam'] = _x( 'Mark as Spam', 'user' );
  96. $actions['notspam'] = _x( 'Not Spam', 'user' );
  97. return $actions;
  98. }
  99. /**
  100. */
  101. public function no_items() {
  102. _e( 'No users found.' );
  103. }
  104. /**
  105. *
  106. * @global string $role
  107. * @return array
  108. */
  109. protected function get_views() {
  110. global $role;
  111. $total_users = get_user_count();
  112. $super_admins = get_super_admins();
  113. $total_admins = count( $super_admins );
  114. $current_link_attributes = $role !== 'super' ? ' class="current" aria-current="page"' : '';
  115. $role_links = array();
  116. $role_links['all'] = "<a href='" . network_admin_url( 'users.php' ) . "'$current_link_attributes>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_users, 'users' ), number_format_i18n( $total_users ) ) . '</a>';
  117. $current_link_attributes = $role === 'super' ? ' class="current" aria-current="page"' : '';
  118. $role_links['super'] = "<a href='" . network_admin_url( 'users.php?role=super' ) . "'$current_link_attributes>" . sprintf( _n( 'Super Admin <span class="count">(%s)</span>', 'Super Admins <span class="count">(%s)</span>', $total_admins ), number_format_i18n( $total_admins ) ) . '</a>';
  119. return $role_links;
  120. }
  121. /**
  122. * @global string $mode List table view mode.
  123. *
  124. * @param string $which
  125. */
  126. protected function pagination( $which ) {
  127. global $mode;
  128. parent::pagination ( $which );
  129. if ( 'top' === $which ) {
  130. $this->view_switcher( $mode );
  131. }
  132. }
  133. /**
  134. *
  135. * @return array
  136. */
  137. public function get_columns() {
  138. $users_columns = array(
  139. 'cb' => '<input type="checkbox" />',
  140. 'username' => __( 'Username' ),
  141. 'name' => __( 'Name' ),
  142. 'email' => __( 'Email' ),
  143. 'registered' => _x( 'Registered', 'user' ),
  144. 'blogs' => __( 'Sites' )
  145. );
  146. /**
  147. * Filters the columns displayed in the Network Admin Users list table.
  148. *
  149. * @since MU (3.0.0)
  150. *
  151. * @param array $users_columns An array of user columns. Default 'cb', 'username',
  152. * 'name', 'email', 'registered', 'blogs'.
  153. */
  154. return apply_filters( 'wpmu_users_columns', $users_columns );
  155. }
  156. /**
  157. *
  158. * @return array
  159. */
  160. protected function get_sortable_columns() {
  161. return array(
  162. 'username' => 'login',
  163. 'name' => 'name',
  164. 'email' => 'email',
  165. 'registered' => 'id',
  166. );
  167. }
  168. /**
  169. * Handles the checkbox column output.
  170. *
  171. * @since 4.3.0
  172. *
  173. * @param WP_User $user The current WP_User object.
  174. */
  175. public function column_cb( $user ) {
  176. if ( is_super_admin( $user->ID ) ) {
  177. return;
  178. }
  179. ?>
  180. <label class="screen-reader-text" for="blog_<?php echo $user->ID; ?>"><?php echo sprintf( __( 'Select %s' ), $user->user_login ); ?></label>
  181. <input type="checkbox" id="blog_<?php echo $user->ID ?>" name="allusers[]" value="<?php echo esc_attr( $user->ID ) ?>" />
  182. <?php
  183. }
  184. /**
  185. * Handles the ID column output.
  186. *
  187. * @since 4.4.0
  188. *
  189. * @param WP_User $user The current WP_User object.
  190. */
  191. public function column_id( $user ) {
  192. echo $user->ID;
  193. }
  194. /**
  195. * Handles the username column output.
  196. *
  197. * @since 4.3.0
  198. *
  199. * @param WP_User $user The current WP_User object.
  200. */
  201. public function column_username( $user ) {
  202. $super_admins = get_super_admins();
  203. $avatar = get_avatar( $user->user_email, 32 );
  204. $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user->ID ) ) );
  205. echo $avatar;
  206. ?><strong><a href="<?php echo $edit_link; ?>" class="edit"><?php echo $user->user_login; ?></a><?php
  207. if ( in_array( $user->user_login, $super_admins ) ) {
  208. echo ' &mdash; ' . __( 'Super Admin' );
  209. }
  210. ?></strong>
  211. <?php
  212. }
  213. /**
  214. * Handles the name column output.
  215. *
  216. * @since 4.3.0
  217. *
  218. * @param WP_User $user The current WP_User object.
  219. */
  220. public function column_name( $user ) {
  221. if ( $user->first_name && $user->last_name ) {
  222. echo "$user->first_name $user->last_name";
  223. } elseif ( $user->first_name ) {
  224. echo $user->first_name;
  225. } elseif ( $user->last_name ) {
  226. echo $user->last_name;
  227. } else {
  228. echo '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">' . _x( 'Unknown', 'name' ) . '</span>';
  229. }
  230. }
  231. /**
  232. * Handles the email column output.
  233. *
  234. * @since 4.3.0
  235. *
  236. * @param WP_User $user The current WP_User object.
  237. */
  238. public function column_email( $user ) {
  239. echo "<a href='" . esc_url( "mailto:$user->user_email" ) . "'>$user->user_email</a>";
  240. }
  241. /**
  242. * Handles the registered date column output.
  243. *
  244. * @since 4.3.0
  245. *
  246. * @global string $mode List table view mode.
  247. *
  248. * @param WP_User $user The current WP_User object.
  249. */
  250. public function column_registered( $user ) {
  251. global $mode;
  252. if ( 'list' === $mode ) {
  253. $date = __( 'Y/m/d' );
  254. } else {
  255. $date = __( 'Y/m/d g:i:s a' );
  256. }
  257. echo mysql2date( $date, $user->user_registered );
  258. }
  259. /**
  260. * @since 4.3.0
  261. *
  262. * @param WP_User $user
  263. * @param string $classes
  264. * @param string $data
  265. * @param string $primary
  266. */
  267. protected function _column_blogs( $user, $classes, $data, $primary ) {
  268. echo '<td class="', $classes, ' has-row-actions" ', $data, '>';
  269. echo $this->column_blogs( $user );
  270. echo $this->handle_row_actions( $user, 'blogs', $primary );
  271. echo '</td>';
  272. }
  273. /**
  274. * Handles the sites column output.
  275. *
  276. * @since 4.3.0
  277. *
  278. * @param WP_User $user The current WP_User object.
  279. */
  280. public function column_blogs( $user ) {
  281. $blogs = get_blogs_of_user( $user->ID, true );
  282. if ( ! is_array( $blogs ) ) {
  283. return;
  284. }
  285. foreach ( $blogs as $val ) {
  286. if ( ! can_edit_network( $val->site_id ) ) {
  287. continue;
  288. }
  289. $path = ( $val->path === '/' ) ? '' : $val->path;
  290. echo '<span class="site-' . $val->site_id . '" >';
  291. echo '<a href="'. esc_url( network_admin_url( 'site-info.php?id=' . $val->userblog_id ) ) .'">' . str_replace( '.' . get_network()->domain, '', $val->domain . $path ) . '</a>';
  292. echo ' <small class="row-actions">';
  293. $actions = array();
  294. $actions['edit'] = '<a href="'. esc_url( network_admin_url( 'site-info.php?id=' . $val->userblog_id ) ) .'">' . __( 'Edit' ) . '</a>';
  295. $class = '';
  296. if ( $val->spam == 1 ) {
  297. $class .= 'site-spammed ';
  298. }
  299. if ( $val->mature == 1 ) {
  300. $class .= 'site-mature ';
  301. }
  302. if ( $val->deleted == 1 ) {
  303. $class .= 'site-deleted ';
  304. }
  305. if ( $val->archived == 1 ) {
  306. $class .= 'site-archived ';
  307. }
  308. $actions['view'] = '<a class="' . $class . '" href="' . esc_url( get_home_url( $val->userblog_id ) ) . '">' . __( 'View' ) . '</a>';
  309. /**
  310. * Filters the action links displayed next the sites a user belongs to
  311. * in the Network Admin Users list table.
  312. *
  313. * @since 3.1.0
  314. *
  315. * @param array $actions An array of action links to be displayed.
  316. * Default 'Edit', 'View'.
  317. * @param int $userblog_id The site ID.
  318. */
  319. $actions = apply_filters( 'ms_user_list_site_actions', $actions, $val->userblog_id );
  320. $i=0;
  321. $action_count = count( $actions );
  322. foreach ( $actions as $action => $link ) {
  323. ++$i;
  324. $sep = ( $i == $action_count ) ? '' : ' | ';
  325. echo "<span class='$action'>$link$sep</span>";
  326. }
  327. echo '</small></span><br/>';
  328. }
  329. }
  330. /**
  331. * Handles the default column output.
  332. *
  333. * @since 4.3.0
  334. *
  335. * @param WP_User $user The current WP_User object.
  336. * @param string $column_name The current column name.
  337. */
  338. public function column_default( $user, $column_name ) {
  339. /** This filter is documented in wp-admin/includes/class-wp-users-list-table.php */
  340. echo apply_filters( 'manage_users_custom_column', '', $column_name, $user->ID );
  341. }
  342. public function display_rows() {
  343. foreach ( $this->items as $user ) {
  344. $class = '';
  345. $status_list = array( 'spam' => 'site-spammed', 'deleted' => 'site-deleted' );
  346. foreach ( $status_list as $status => $col ) {
  347. if ( $user->$status ) {
  348. $class .= " $col";
  349. }
  350. }
  351. ?>
  352. <tr class="<?php echo trim( $class ); ?>">
  353. <?php $this->single_row_columns( $user ); ?>
  354. </tr>
  355. <?php
  356. }
  357. }
  358. /**
  359. * Gets the name of the default primary column.
  360. *
  361. * @since 4.3.0
  362. *
  363. * @return string Name of the default primary column, in this case, 'username'.
  364. */
  365. protected function get_default_primary_column_name() {
  366. return 'username';
  367. }
  368. /**
  369. * Generates and displays row action links.
  370. *
  371. * @since 4.3.0
  372. *
  373. * @param object $user User being acted upon.
  374. * @param string $column_name Current column name.
  375. * @param string $primary Primary column name.
  376. * @return string Row actions output for users in Multisite.
  377. */
  378. protected function handle_row_actions( $user, $column_name, $primary ) {
  379. if ( $primary !== $column_name ) {
  380. return '';
  381. }
  382. $super_admins = get_super_admins();
  383. $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user->ID ) ) );
  384. $actions = array();
  385. $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
  386. if ( current_user_can( 'delete_user', $user->ID ) && ! in_array( $user->user_login, $super_admins ) ) {
  387. $actions['delete'] = '<a href="' . $delete = esc_url( network_admin_url( add_query_arg( '_wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), wp_nonce_url( 'users.php', 'deleteuser' ) . '&amp;action=deleteuser&amp;id=' . $user->ID ) ) ) . '" class="delete">' . __( 'Delete' ) . '</a>';
  388. }
  389. /**
  390. * Filters the action links displayed under each user in the Network Admin Users list table.
  391. *
  392. * @since 3.2.0
  393. *
  394. * @param array $actions An array of action links to be displayed.
  395. * Default 'Edit', 'Delete'.
  396. * @param WP_User $user WP_User object.
  397. */
  398. $actions = apply_filters( 'ms_user_row_actions', $actions, $user );
  399. return $this->row_actions( $actions );
  400. }
  401. }