WP_MS_Sites_List_Table

Core class used to implement displaying sites in a list table for the network admin.

Defined (1)

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

/wp-admin/includes/class-wp-ms-sites-list-table.php  
  1. class WP_MS_Sites_List_Table extends WP_List_Table { 
  2.  
  3. /** 
  4. * Site status list. 
  5. * @since 4.3.0 
  6. * @access public 
  7. * @var array 
  8. */ 
  9. public $status_list; 
  10.  
  11. /** 
  12. * Constructor. 
  13. * @since 3.1.0 
  14. * @access public 
  15. * @see WP_List_Table::__construct() for more information on default arguments. 
  16. * @param array $args An associative array of arguments. 
  17. */ 
  18. public function __construct( $args = array() ) { 
  19. $this->status_list = array( 
  20. 'archived' => array( 'site-archived', __( 'Archived' ) ),  
  21. 'spam' => array( 'site-spammed', _x( 'Spam', 'site' ) ),  
  22. 'deleted' => array( 'site-deleted', __( 'Deleted' ) ),  
  23. 'mature' => array( 'site-mature', __( 'Mature' ) ) 
  24. ); 
  25.  
  26. parent::__construct( array( 
  27. 'plural' => 'sites',  
  28. 'screen' => isset( $args['screen'] ) ? $args['screen'] : null,  
  29. ) ); 
  30.  
  31. /** 
  32. * @return bool 
  33. */ 
  34. public function ajax_user_can() { 
  35. return current_user_can( 'manage_sites' ); 
  36.  
  37. /** 
  38. * Prepares the list of sites for display. 
  39. * @since 3.1.0 
  40. * @global string $s 
  41. * @global string $mode 
  42. * @global wpdb $wpdb 
  43. */ 
  44. public function prepare_items() { 
  45. global $s, $mode, $wpdb; 
  46.  
  47. if ( ! empty( $_REQUEST['mode'] ) ) { 
  48. $mode = $_REQUEST['mode'] === 'excerpt' ? 'excerpt' : 'list'; 
  49. set_user_setting( 'sites_list_mode', $mode ); 
  50. } else { 
  51. $mode = get_user_setting( 'sites_list_mode', 'list' ); 
  52.  
  53. $per_page = $this->get_items_per_page( 'sites_network_per_page' ); 
  54.  
  55. $pagenum = $this->get_pagenum(); 
  56.  
  57. $s = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST[ 's' ] ) ) : ''; 
  58. $wild = ''; 
  59. if ( false !== strpos($s, '*') ) { 
  60. $wild = '*'; 
  61. $s = trim($s, '*'); 
  62.  
  63. /** 
  64. * If the network is large and a search is not being performed, show only 
  65. * the latest sites with no paging in order to avoid expensive count queries. 
  66. */ 
  67. if ( !$s && wp_is_large_network() ) { 
  68. if ( !isset($_REQUEST['orderby']) ) 
  69. $_GET['orderby'] = $_REQUEST['orderby'] = ''; 
  70. if ( !isset($_REQUEST['order']) ) 
  71. $_GET['order'] = $_REQUEST['order'] = 'DESC'; 
  72.  
  73. $args = array( 
  74. 'number' => intval( $per_page ),  
  75. 'offset' => intval( ( $pagenum - 1 ) * $per_page ),  
  76. 'network_id' => get_current_network_id(),  
  77. ); 
  78.  
  79. if ( empty($s) ) { 
  80. // Nothing to do. 
  81. } elseif ( preg_match( '/^[0-9]{1, 3}\.[0-9]{1, 3}\.[0-9]{1, 3}\.[0-9]{1, 3}$/', $s ) || 
  82. preg_match( '/^[0-9]{1, 3}\.[0-9]{1, 3}\.[0-9]{1, 3}\.?$/', $s ) || 
  83. preg_match( '/^[0-9]{1, 3}\.[0-9]{1, 3}\.?$/', $s ) || 
  84. preg_match( '/^[0-9]{1, 3}\.$/', $s ) ) { 
  85. // IPv4 address 
  86. $sql = $wpdb->prepare( "SELECT blog_id FROM {$wpdb->registration_log} WHERE {$wpdb->registration_log}.IP LIKE %s", $wpdb->esc_like( $s ) . ( ! empty( $wild ) ? '%' : '' ) ); 
  87. $reg_blog_ids = $wpdb->get_col( $sql ); 
  88.  
  89. if ( $reg_blog_ids ) { 
  90. $args['site__in'] = $reg_blog_ids; 
  91. } elseif ( is_numeric( $s ) && empty( $wild ) ) { 
  92. $args['ID'] = $s; 
  93. } else { 
  94. $args['search'] = $s; 
  95.  
  96. if ( ! is_subdomain_install() ) { 
  97. $args['search_columns'] = array( 'path' ); 
  98.  
  99. $order_by = isset( $_REQUEST['orderby'] ) ? $_REQUEST['orderby'] : ''; 
  100. if ( 'registered' === $order_by ) { 
  101. // registered is a valid field name. 
  102. } elseif ( 'lastupdated' === $order_by ) { 
  103. $order_by = 'last_updated'; 
  104. } elseif ( 'blogname' === $order_by ) { 
  105. if ( is_subdomain_install() ) { 
  106. $order_by = 'domain'; 
  107. } else { 
  108. $order_by = 'path'; 
  109. } elseif ( 'blog_id' === $order_by ) { 
  110. $order_by = 'id'; 
  111. } elseif ( ! $order_by ) { 
  112. $order_by = false; 
  113.  
  114. $args['orderby'] = $order_by; 
  115.  
  116. if ( $order_by ) { 
  117. $args['order'] = ( isset( $_REQUEST['order'] ) && 'DESC' === strtoupper( $_REQUEST['order'] ) ) ? "DESC" : "ASC"; 
  118.  
  119. if ( wp_is_large_network() ) { 
  120. $args['no_found_rows'] = true; 
  121. } else { 
  122. $args['no_found_rows'] = false; 
  123.  
  124. /** 
  125. * Filters the arguments for the site query in the sites list table. 
  126. * @since 4.6.0 
  127. * @param array $args An array of get_sites() arguments. 
  128. */ 
  129. $args = apply_filters( 'ms_sites_list_table_query_args', $args ); 
  130.  
  131. $_sites = get_sites( $args ); 
  132. if ( is_array( $_sites ) ) { 
  133. update_site_cache( $_sites ); 
  134.  
  135. $this->items = array_slice( $_sites, 0, $per_page ); 
  136.  
  137. $total_sites = get_sites( array_merge( $args, array( 
  138. 'count' => true,  
  139. 'offset' => 0,  
  140. 'number' => 0,  
  141. ) ) ); 
  142.  
  143. $this->set_pagination_args( array( 
  144. 'total_items' => $total_sites,  
  145. 'per_page' => $per_page,  
  146. ) ); 
  147.  
  148. /** 
  149. * @access public 
  150. */ 
  151. public function no_items() { 
  152. _e( 'No sites found.' ); 
  153.  
  154. /** 
  155. * @return array 
  156. */ 
  157. protected function get_bulk_actions() { 
  158. $actions = array(); 
  159. if ( current_user_can( 'delete_sites' ) ) 
  160. $actions['delete'] = __( 'Delete' ); 
  161. $actions['spam'] = _x( 'Mark as Spam', 'site' ); 
  162. $actions['notspam'] = _x( 'Not Spam', 'site' ); 
  163.  
  164. return $actions; 
  165.  
  166. /** 
  167. * @global string $mode 
  168. * @param string $which 
  169. */ 
  170. protected function pagination( $which ) { 
  171. global $mode; 
  172.  
  173. parent::pagination( $which ); 
  174.  
  175. if ( 'top' === $which ) 
  176. $this->view_switcher( $mode ); 
  177.  
  178. /** 
  179. * @return array 
  180. */ 
  181. public function get_columns() { 
  182. $sites_columns = array( 
  183. 'cb' => '<input type="checkbox" />',  
  184. 'blogname' => __( 'URL' ),  
  185. 'lastupdated' => __( 'Last Updated' ),  
  186. 'registered' => _x( 'Registered', 'site' ),  
  187. 'users' => __( 'Users' ),  
  188. ); 
  189.  
  190. if ( has_filter( 'wpmublogsaction' ) ) { 
  191. $sites_columns['plugins'] = __( 'Actions' ); 
  192.  
  193. /** 
  194. * Filters the displayed site columns in Sites list table. 
  195. * @since MU 
  196. * @param array $sites_columns An array of displayed site columns. Default 'cb',  
  197. * 'blogname', 'lastupdated', 'registered', 'users'. 
  198. */ 
  199. return apply_filters( 'wpmu_blogs_columns', $sites_columns ); 
  200.  
  201. /** 
  202. * @return array 
  203. */ 
  204. protected function get_sortable_columns() { 
  205. return array( 
  206. 'blogname' => 'blogname',  
  207. 'lastupdated' => 'lastupdated',  
  208. 'registered' => 'blog_id',  
  209. ); 
  210.  
  211. /** 
  212. * Handles the checkbox column output. 
  213. * @since 4.3.0 
  214. * @access public 
  215. * @param array $blog Current site. 
  216. */ 
  217. public function column_cb( $blog ) { 
  218. if ( ! is_main_site( $blog['blog_id'] ) ) : 
  219. $blogname = untrailingslashit( $blog['domain'] . $blog['path'] ); 
  220. ?> 
  221. <label class="screen-reader-text" for="blog_<?php echo $blog['blog_id']; ?>"><?php 
  222. printf( __( 'Select %s' ), $blogname ); 
  223. ?></label> 
  224. <input type="checkbox" id="blog_<?php echo $blog['blog_id'] ?>" name="allblogs[]" value="<?php echo esc_attr( $blog['blog_id'] ) ?>" /> 
  225. <?php endif; 
  226.  
  227. /** 
  228. * Handles the ID column output. 
  229. * @since 4.4.0 
  230. * @access public 
  231. * @param array $blog Current site. 
  232. */ 
  233. public function column_id( $blog ) { 
  234. echo $blog['blog_id']; 
  235.  
  236. /** 
  237. * Handles the site name column output. 
  238. * @since 4.3.0 
  239. * @access public 
  240. * @global string $mode 
  241. * @param array $blog Current site. 
  242. */ 
  243. public function column_blogname( $blog ) { 
  244. global $mode; 
  245.  
  246. $blogname = untrailingslashit( $blog['domain'] . $blog['path'] ); 
  247. $blog_states = array(); 
  248. reset( $this->status_list ); 
  249.  
  250. foreach ( $this->status_list as $status => $col ) { 
  251. if ( $blog[ $status ] == 1 ) { 
  252. $blog_states[] = $col[1]; 
  253. $blog_state = ''; 
  254. if ( ! empty( $blog_states ) ) { 
  255. $state_count = count( $blog_states ); 
  256. $i = 0; 
  257. $blog_state .= ' - '; 
  258. foreach ( $blog_states as $state ) { 
  259. ++$i; 
  260. $sep = ( $i == $state_count ) ? '' : ', '; 
  261. $blog_state .= "<span class='post-state'>$state$sep</span>"; 
  262.  
  263. ?> 
  264. <a href="<?php echo esc_url( network_admin_url( 'site-info.php?id=' . $blog['blog_id'] ) ); ?>" class="edit"><?php echo $blogname . $blog_state; ?></a> 
  265. <?php 
  266. if ( 'list' !== $mode ) { 
  267. switch_to_blog( $blog['blog_id'] ); 
  268. echo '<p>'; 
  269. printf( 
  270. /** translators: 1: site name, 2: site tagline. */ 
  271. __( '%1$s – %2$s' ),  
  272. get_option( 'blogname' ),  
  273. '<em>' . get_option( 'blogdescription ' ) . '</em>' 
  274. ); 
  275. echo '</p>'; 
  276. restore_current_blog(); 
  277.  
  278. /** 
  279. * Handles the lastupdated column output. 
  280. * @since 4.3.0 
  281. * @access public 
  282. * @param array $blog Current site. 
  283. */ 
  284. public function column_lastupdated( $blog ) { 
  285. global $mode; 
  286.  
  287. if ( 'list' === $mode ) { 
  288. $date = __( 'Y/m/d' ); 
  289. } else { 
  290. $date = __( 'Y/m/d g:i:s a' ); 
  291.  
  292. echo ( $blog['last_updated'] === '0000-00-00 00:00:00' ) ? __( 'Never' ) : mysql2date( $date, $blog['last_updated'] ); 
  293.  
  294. /** 
  295. * Handles the registered column output. 
  296. * @since 4.3.0 
  297. * @access public 
  298. * @param array $blog Current site. 
  299. */ 
  300. public function column_registered( $blog ) { 
  301. global $mode; 
  302.  
  303. if ( 'list' === $mode ) { 
  304. $date = __( 'Y/m/d' ); 
  305. } else { 
  306. $date = __( 'Y/m/d g:i:s a' ); 
  307.  
  308. if ( $blog['registered'] === '0000-00-00 00:00:00' ) { 
  309. echo '—'; 
  310. } else { 
  311. echo mysql2date( $date, $blog['registered'] ); 
  312.  
  313. /** 
  314. * Handles the users column output. 
  315. * @since 4.3.0 
  316. * @access public 
  317. * @param array $blog Current site. 
  318. */ 
  319. public function column_users( $blog ) { 
  320. $user_count = wp_cache_get( $blog['blog_id'] . '_user_count', 'blog-details' ); 
  321. if ( ! $user_count ) { 
  322. $blog_users = get_users( array( 'blog_id' => $blog['blog_id'], 'fields' => 'ID' ) ); 
  323. $user_count = count( $blog_users ); 
  324. unset( $blog_users ); 
  325. wp_cache_set( $blog['blog_id'] . '_user_count', $user_count, 'blog-details', 12 * HOUR_IN_SECONDS ); 
  326.  
  327. printf( 
  328. '<a href="%s">%s</a>',  
  329. esc_url( network_admin_url( 'site-users.php?id=' . $blog['blog_id'] ) ),  
  330. number_format_i18n( $user_count ) 
  331. ); 
  332.  
  333. /** 
  334. * Handles the plugins column output. 
  335. * @since 4.3.0 
  336. * @access public 
  337. * @param array $blog Current site. 
  338. */ 
  339. public function column_plugins( $blog ) { 
  340. if ( has_filter( 'wpmublogsaction' ) ) { 
  341. /** 
  342. * Fires inside the auxiliary 'Actions' column of the Sites list table. 
  343. * By default this column is hidden unless something is hooked to the action. 
  344. * @since MU 
  345. * @param int $blog_id The site ID. 
  346. */ 
  347. do_action( 'wpmublogsaction', $blog['blog_id'] ); 
  348.  
  349. /** 
  350. * Handles output for the default column. 
  351. * @since 4.3.0 
  352. * @access public 
  353. * @param array $blog Current site. 
  354. * @param string $column_name Current column name. 
  355. */ 
  356. public function column_default( $blog, $column_name ) { 
  357. /** 
  358. * Fires for each registered custom column in the Sites list table. 
  359. * @since 3.1.0 
  360. * @param string $column_name The name of the column to display. 
  361. * @param int $blog_id The site ID. 
  362. */ 
  363. do_action( 'manage_sites_custom_column', $column_name, $blog['blog_id'] ); 
  364.  
  365. /** 
  366. * @global string $mode 
  367. */ 
  368. public function display_rows() { 
  369. foreach ( $this->items as $blog ) { 
  370. $blog = $blog->to_array(); 
  371. $class = ''; 
  372. reset( $this->status_list ); 
  373.  
  374. foreach ( $this->status_list as $status => $col ) { 
  375. if ( $blog[ $status ] == 1 ) { 
  376. $class = " class='{$col[0]}'"; 
  377.  
  378. echo "<tr{$class}>"; 
  379.  
  380. $this->single_row_columns( $blog ); 
  381.  
  382. echo '</tr>'; 
  383.  
  384. /** 
  385. * Gets the name of the default primary column. 
  386. * @since 4.3.0 
  387. * @access protected 
  388. * @return string Name of the default primary column, in this case, 'blogname'. 
  389. */ 
  390. protected function get_default_primary_column_name() { 
  391. return 'blogname'; 
  392.  
  393. /** 
  394. * Generates and displays row action links. 
  395. * @since 4.3.0 
  396. * @access protected 
  397. * @param object $blog Site being acted upon. 
  398. * @param string $column_name Current column name. 
  399. * @param string $primary Primary column name. 
  400. * @return string Row actions output. 
  401. */ 
  402. protected function handle_row_actions( $blog, $column_name, $primary ) { 
  403. if ( $primary !== $column_name ) { 
  404. return; 
  405.  
  406. $blogname = untrailingslashit( $blog['domain'] . $blog['path'] ); 
  407.  
  408. // Preordered. 
  409. $actions = array( 
  410. 'edit' => '', 'backend' => '',  
  411. 'activate' => '', 'deactivate' => '',  
  412. 'archive' => '', 'unarchive' => '',  
  413. 'spam' => '', 'unspam' => '',  
  414. 'delete' => '',  
  415. 'visit' => '',  
  416. ); 
  417.  
  418. $actions['edit'] = '<a href="' . esc_url( network_admin_url( 'site-info.php?id=' . $blog['blog_id'] ) ) . '">' . __( 'Edit' ) . '</a>'; 
  419. $actions['backend'] = "<a href='" . esc_url( get_admin_url( $blog['blog_id'] ) ) . "' class='edit'>" . __( 'Dashboard' ) . '</a>'; 
  420. if ( get_current_site()->blog_id != $blog['blog_id'] ) { 
  421. if ( $blog['deleted'] == '1' ) { 
  422. $actions['activate'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&action2=activateblog&id=' . $blog['blog_id'] ), 'activateblog_' . $blog['blog_id'] ) ) . '">' . __( 'Activate' ) . '</a>'; 
  423. } else { 
  424. $actions['deactivate'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&action2=deactivateblog&id=' . $blog['blog_id'] ), 'deactivateblog_' . $blog['blog_id'] ) ) . '">' . __( 'Deactivate' ) . '</a>'; 
  425.  
  426. if ( $blog['archived'] == '1' ) { 
  427. $actions['unarchive'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&action2=unarchiveblog&id=' . $blog['blog_id'] ), 'unarchiveblog_' . $blog['blog_id'] ) ) . '">' . __( 'Unarchive' ) . '</a>'; 
  428. } else { 
  429. $actions['archive'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&action2=archiveblog&id=' . $blog['blog_id'] ), 'archiveblog_' . $blog['blog_id'] ) ) . '">' . _x( 'Archive', 'verb; site' ) . '</a>'; 
  430.  
  431. if ( $blog['spam'] == '1' ) { 
  432. $actions['unspam'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&action2=unspamblog&id=' . $blog['blog_id'] ), 'unspamblog_' . $blog['blog_id'] ) ) . '">' . _x( 'Not Spam', 'site' ) . '</a>'; 
  433. } else { 
  434. $actions['spam'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&action2=spamblog&id=' . $blog['blog_id'] ), 'spamblog_' . $blog['blog_id'] ) ) . '">' . _x( 'Spam', 'site' ) . '</a>'; 
  435.  
  436. if ( current_user_can( 'delete_site', $blog['blog_id'] ) ) { 
  437. $actions['delete'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&action2=deleteblog&id=' . $blog['blog_id'] ), 'deleteblog_' . $blog['blog_id'] ) ) . '">' . __( 'Delete' ) . '</a>'; 
  438.  
  439. $actions['visit'] = "<a href='" . esc_url( get_home_url( $blog['blog_id'], '/' ) ) . "' rel='permalink'>" . __( 'Visit' ) . '</a>'; 
  440.  
  441. /** 
  442. * Filters the action links displayed for each site in the Sites list table. 
  443. * The 'Edit', 'Dashboard', 'Delete', and 'Visit' links are displayed by 
  444. * default for each site. The site's status determines whether to show the 
  445. * 'Activate' or 'Deactivate' link, 'Unarchive' or 'Archive' links, and 
  446. * 'Not Spam' or 'Spam' link for each site. 
  447. * @since 3.1.0 
  448. * @param array $actions An array of action links to be displayed. 
  449. * @param int $blog_id The site ID. 
  450. * @param string $blogname Site path, formatted depending on whether it is a sub-domain 
  451. * or subdirectory multisite install. 
  452. */ 
  453. $actions = apply_filters( 'manage_sites_action_links', array_filter( $actions ), $blog['blog_id'], $blogname ); 
  454. return $this->row_actions( $actions );