WP_Theme_Install_List_Table

Core class used to implement displaying themes to install in a list table.

Defined (1)

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

/wp-admin/includes/class-wp-theme-install-list-table.php  
  1. class WP_Theme_Install_List_Table extends WP_Themes_List_Table { 
  2.  
  3. public $features = array(); 
  4.  
  5. /** 
  6. * @return bool 
  7. */ 
  8. public function ajax_user_can() { 
  9. return current_user_can( 'install_themes' ); 
  10.  
  11. /** 
  12. * @global array $tabs 
  13. * @global string $tab 
  14. * @global int $paged 
  15. * @global string $type 
  16. * @global array $theme_field_defaults 
  17. */ 
  18. public function prepare_items() { 
  19. include( ABSPATH . 'wp-admin/includes/theme-install.php' ); 
  20.  
  21. global $tabs, $tab, $paged, $type, $theme_field_defaults; 
  22. wp_reset_vars( array( 'tab' ) ); 
  23.  
  24. $search_terms = array(); 
  25. $search_string = ''; 
  26. if ( ! empty( $_REQUEST['s'] ) ) { 
  27. $search_string = strtolower( wp_unslash( $_REQUEST['s'] ) ); 
  28. $search_terms = array_unique( array_filter( array_map( 'trim', explode( ', ', $search_string ) ) ) ); 
  29.  
  30. if ( ! empty( $_REQUEST['features'] ) ) 
  31. $this->features = $_REQUEST['features']; 
  32.  
  33. $paged = $this->get_pagenum(); 
  34.  
  35. $per_page = 36; 
  36.  
  37. // These are the tabs which are shown on the page,  
  38. $tabs = array(); 
  39. $tabs['dashboard'] = __( 'Search' ); 
  40. if ( 'search' === $tab ) 
  41. $tabs['search'] = __( 'Search Results' ); 
  42. $tabs['upload'] = __( 'Upload' ); 
  43. $tabs['featured'] = _x( 'Featured', 'themes' ); 
  44. //$tabs['popular'] = _x( 'Popular', 'themes' ); 
  45. $tabs['new'] = _x( 'Latest', 'themes' ); 
  46. $tabs['updated'] = _x( 'Recently Updated', 'themes' ); 
  47.  
  48. $nonmenu_tabs = array( 'theme-information' ); // Valid actions to perform which do not have a Menu item. 
  49.  
  50. /** This filter is documented in wp-admin/theme-install.php */ 
  51. $tabs = apply_filters( 'install_themes_tabs', $tabs ); 
  52.  
  53. /** 
  54. * Filters tabs not associated with a menu item on the Install Themes screen. 
  55. * @since 2.8.0 
  56. * @param array $nonmenu_tabs The tabs that don't have a menu item on 
  57. * the Install Themes screen. 
  58. */ 
  59. $nonmenu_tabs = apply_filters( 'install_themes_nonmenu_tabs', $nonmenu_tabs ); 
  60.  
  61. // If a non-valid menu tab has been selected, And it's not a non-menu action. 
  62. if ( empty( $tab ) || ( ! isset( $tabs[ $tab ] ) && ! in_array( $tab, (array) $nonmenu_tabs ) ) ) 
  63. $tab = key( $tabs ); 
  64.  
  65. $args = array( 'page' => $paged, 'per_page' => $per_page, 'fields' => $theme_field_defaults ); 
  66.  
  67. switch ( $tab ) { 
  68. case 'search': 
  69. $type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; 
  70. switch ( $type ) { 
  71. case 'tag': 
  72. $args['tag'] = array_map( 'sanitize_key', $search_terms ); 
  73. break; 
  74. case 'term': 
  75. $args['search'] = $search_string; 
  76. break; 
  77. case 'author': 
  78. $args['author'] = $search_string; 
  79. break; 
  80.  
  81. if ( ! empty( $this->features ) ) { 
  82. $args['tag'] = $this->features; 
  83. $_REQUEST['s'] = implode( ', ', $this->features ); 
  84. $_REQUEST['type'] = 'tag'; 
  85.  
  86. add_action( 'install_themes_table_header', 'install_theme_search_form', 10, 0 ); 
  87. break; 
  88.  
  89. case 'featured': 
  90. // case 'popular': 
  91. case 'new': 
  92. case 'updated': 
  93. $args['browse'] = $tab; 
  94. break; 
  95.  
  96. default: 
  97. $args = false; 
  98. break; 
  99.  
  100. /** 
  101. * Filters API request arguments for each Install Themes screen tab. 
  102. * The dynamic portion of the hook name, `$tab`, refers to the theme install 
  103. * tabs. Default tabs are 'dashboard', 'search', 'upload', 'featured',  
  104. * 'new', and 'updated'. 
  105. * @since 3.7.0 
  106. * @param array $args An array of themes API arguments. 
  107. */ 
  108. $args = apply_filters( "install_themes_table_api_args_{$tab}", $args ); 
  109.  
  110. if ( ! $args ) 
  111. return; 
  112.  
  113. $api = themes_api( 'query_themes', $args ); 
  114.  
  115. if ( is_wp_error( $api ) ) 
  116. wp_die( $api->get_error_message() . '</p> <p><a href="#" onclick="document.location.reload(); return false;">' . __( 'Try again' ) . '</a>' ); 
  117.  
  118. $this->items = $api->themes; 
  119.  
  120. $this->set_pagination_args( array( 
  121. 'total_items' => $api->info['results'],  
  122. 'per_page' => $args['per_page'],  
  123. 'infinite_scroll' => true,  
  124. ) ); 
  125.  
  126. /** 
  127. * @access public 
  128. */ 
  129. public function no_items() { 
  130. _e( 'No themes match your request.' ); 
  131.  
  132. /** 
  133. * @global array $tabs 
  134. * @global string $tab 
  135. * @return array 
  136. */ 
  137. protected function get_views() { 
  138. global $tabs, $tab; 
  139.  
  140. $display_tabs = array(); 
  141. foreach ( (array) $tabs as $action => $text ) { 
  142. $class = ( $action === $tab ) ? ' class="current"' : ''; 
  143. $href = self_admin_url('theme-install.php?tab=' . $action); 
  144. $display_tabs['theme-install-'.$action] = "<a href='$href'$class>$text</a>"; 
  145.  
  146. return $display_tabs; 
  147.  
  148. /** 
  149. * @access public 
  150. */ 
  151. public function display() { 
  152. wp_nonce_field( "fetch-list-" . get_class( $this ), '_ajax_fetch_list_nonce' ); 
  153. ?> 
  154. <div class="tablenav top themes"> 
  155. <div class="alignleft actions"> 
  156. <?php 
  157. /** 
  158. * Fires in the Install Themes list table header. 
  159. * @since 2.8.0 
  160. */ 
  161. do_action( 'install_themes_table_header' ); 
  162. ?> 
  163. </div> 
  164. <?php $this->pagination( 'top' ); ?> 
  165. <br class="clear" /> 
  166. </div> 
  167.  
  168. <div id="availablethemes"> 
  169. <?php $this->display_rows_or_placeholder(); ?> 
  170. </div> 
  171.  
  172. <?php 
  173. $this->tablenav( 'bottom' ); 
  174.  
  175. /** 
  176. * @access public 
  177. */ 
  178. public function display_rows() { 
  179. $themes = $this->items; 
  180. foreach ( $themes as $theme ) { 
  181. ?> 
  182. <div class="available-theme installable-theme"><?php 
  183. $this->single_row( $theme ); 
  184. ?></div> 
  185. <?php } // end foreach $theme_names 
  186.  
  187. $this->theme_installer(); 
  188.  
  189. /** 
  190. * Prints a theme from the WordPress.org API. 
  191. * @since 3.1.0 
  192. * @access public 
  193. * @global array $themes_allowedtags 
  194. * @param object $theme { 
  195. * An object that contains theme data returned by the WordPress.org API. 
  196. * @type string $name Theme name, e.g. 'Twenty Seventeen'. 
  197. * @type string $slug Theme slug, e.g. 'twentyseventeen'. 
  198. * @type string $version Theme version, e.g. '1.1'. 
  199. * @type string $author Theme author username, e.g. 'melchoyce'. 
  200. * @type string $preview_url Preview URL, e.g. 'http://2017.wordpress.net/'. 
  201. * @type string $screenshot_url Screenshot URL, e.g. 'https://wordpress.org/themes/twentyseventeen/'. 
  202. * @type float $rating Rating score. 
  203. * @type int $num_ratings The number of ratings. 
  204. * @type string $homepage Theme homepage, e.g. 'https://wordpress.org/themes/twentyseventeen/'. 
  205. * @type string $description Theme description. 
  206. * @type string $download_link Theme ZIP download URL. 
  207. * } 
  208. */ 
  209. public function single_row( $theme ) { 
  210. global $themes_allowedtags; 
  211.  
  212. if ( empty( $theme ) ) 
  213. return; 
  214.  
  215. $name = wp_kses( $theme->name, $themes_allowedtags ); 
  216. $author = wp_kses( $theme->author, $themes_allowedtags ); 
  217.  
  218. $preview_title = sprintf( __('Preview “%s”'), $name ); 
  219. $preview_url = add_query_arg( array( 
  220. 'tab' => 'theme-information',  
  221. 'theme' => $theme->slug,  
  222. ), self_admin_url( 'theme-install.php' ) ); 
  223.  
  224. $actions = array(); 
  225.  
  226. $install_url = add_query_arg( array( 
  227. 'action' => 'install-theme',  
  228. 'theme' => $theme->slug,  
  229. ), self_admin_url( 'update.php' ) ); 
  230.  
  231. $update_url = add_query_arg( array( 
  232. 'action' => 'upgrade-theme',  
  233. 'theme' => $theme->slug,  
  234. ), self_admin_url( 'update.php' ) ); 
  235.  
  236. $status = $this->_get_theme_status( $theme ); 
  237.  
  238. switch ( $status ) { 
  239. case 'update_available': 
  240. $actions[] = '<a class="install-now" href="' . esc_url( wp_nonce_url( $update_url, 'upgrade-theme_' . $theme->slug ) ) . '" title="' . esc_attr( sprintf( __( 'Update to version %s' ), $theme->version ) ) . '">' . __( 'Update' ) . '</a>'; 
  241. break; 
  242. case 'newer_installed': 
  243. case 'latest_installed': 
  244. $actions[] = '<span class="install-now" title="' . esc_attr__( 'This theme is already installed and is up to date' ) . '">' . _x( 'Installed', 'theme' ) . '</span>'; 
  245. break; 
  246. case 'install': 
  247. default: 
  248. $actions[] = '<a class="install-now" href="' . esc_url( wp_nonce_url( $install_url, 'install-theme_' . $theme->slug ) ) . '" title="' . esc_attr( sprintf( __( 'Install %s' ), $name ) ) . '">' . __( 'Install Now' ) . '</a>'; 
  249. break; 
  250.  
  251. $actions[] = '<a class="install-theme-preview" href="' . esc_url( $preview_url ) . '" title="' . esc_attr( sprintf( __( 'Preview %s' ), $name ) ) . '">' . __( 'Preview' ) . '</a>'; 
  252.  
  253. /** 
  254. * Filters the install action links for a theme in the Install Themes list table. 
  255. * @since 3.4.0 
  256. * @param array $actions An array of theme action hyperlinks. Defaults are 
  257. * links to Install Now, Preview, and Details. 
  258. * @param WP_Theme $theme Theme object. 
  259. */ 
  260. $actions = apply_filters( 'theme_install_actions', $actions, $theme ); 
  261.  
  262. ?> 
  263. <a class="screenshot install-theme-preview" href="<?php echo esc_url( $preview_url ); ?>" title="<?php echo esc_attr( $preview_title ); ?>"> 
  264. <img src="<?php echo esc_url( $theme->screenshot_url ); ?>" width="150" alt="" /> 
  265. </a> 
  266.  
  267. <h3><?php echo $name; ?></h3> 
  268. <div class="theme-author"><?php printf( __( 'By %s' ), $author ); ?></div> 
  269.  
  270. <div class="action-links"> 
  271. <ul> 
  272. <?php foreach ( $actions as $action ): ?> 
  273. <li><?php echo $action; ?></li> 
  274. <?php endforeach; ?> 
  275. <li class="hide-if-no-js"><a href="#" class="theme-detail"><?php _e('Details') ?></a></li> 
  276. </ul> 
  277. </div> 
  278.  
  279. <?php 
  280. $this->install_theme_info( $theme ); 
  281.  
  282. /** 
  283. * Prints the wrapper for the theme installer. 
  284. */ 
  285. public function theme_installer() { 
  286. ?> 
  287. <div id="theme-installer" class="wp-full-overlay expanded"> 
  288. <div class="wp-full-overlay-sidebar"> 
  289. <div class="wp-full-overlay-header"> 
  290. <a href="#" class="close-full-overlay button"><?php _e( 'Close' ); ?></a> 
  291. <span class="theme-install"></span> 
  292. </div> 
  293. <div class="wp-full-overlay-sidebar-content"> 
  294. <div class="install-theme-info"></div> 
  295. </div> 
  296. <div class="wp-full-overlay-footer"> 
  297. <button type="button" class="collapse-sidebar button" aria-expanded="true" aria-label="<?php esc_attr_e( 'Collapse Sidebar' ); ?>"> 
  298. <span class="collapse-sidebar-arrow"></span> 
  299. <span class="collapse-sidebar-label"><?php _e( 'Collapse' ); ?></span> 
  300. </button> 
  301. </div> 
  302. </div> 
  303. <div class="wp-full-overlay-main"></div> 
  304. </div> 
  305. <?php 
  306.  
  307. /** 
  308. * Prints the wrapper for the theme installer with a provided theme's data. 
  309. * Used to make the theme installer work for no-js. 
  310. * @param object $theme - A WordPress.org Theme API object. 
  311. */ 
  312. public function theme_installer_single( $theme ) { 
  313. ?> 
  314. <div id="theme-installer" class="wp-full-overlay single-theme"> 
  315. <div class="wp-full-overlay-sidebar"> 
  316. <?php $this->install_theme_info( $theme ); ?> 
  317. </div> 
  318. <div class="wp-full-overlay-main"> 
  319. <iframe src="<?php echo esc_url( $theme->preview_url ); ?>"></iframe> 
  320. </div> 
  321. </div> 
  322. <?php 
  323.  
  324. /** 
  325. * Prints the info for a theme (to be used in the theme installer modal). 
  326. * @global array $themes_allowedtags 
  327. * @param object $theme - A WordPress.org Theme API object. 
  328. */ 
  329. public function install_theme_info( $theme ) { 
  330. global $themes_allowedtags; 
  331.  
  332. if ( empty( $theme ) ) 
  333. return; 
  334.  
  335. $name = wp_kses( $theme->name, $themes_allowedtags ); 
  336. $author = wp_kses( $theme->author, $themes_allowedtags ); 
  337.  
  338. $install_url = add_query_arg( array( 
  339. 'action' => 'install-theme',  
  340. 'theme' => $theme->slug,  
  341. ), self_admin_url( 'update.php' ) ); 
  342.  
  343. $update_url = add_query_arg( array( 
  344. 'action' => 'upgrade-theme',  
  345. 'theme' => $theme->slug,  
  346. ), self_admin_url( 'update.php' ) ); 
  347.  
  348. $status = $this->_get_theme_status( $theme ); 
  349.  
  350. ?> 
  351. <div class="install-theme-info"><?php 
  352. switch ( $status ) { 
  353. case 'update_available': 
  354. echo '<a class="theme-install button button-primary" href="' . esc_url( wp_nonce_url( $update_url, 'upgrade-theme_' . $theme->slug ) ) . '" title="' . esc_attr( sprintf( __( 'Update to version %s' ), $theme->version ) ) . '">' . __( 'Update' ) . '</a>'; 
  355. break; 
  356. case 'newer_installed': 
  357. case 'latest_installed': 
  358. echo '<span class="theme-install" title="' . esc_attr__( 'This theme is already installed and is up to date' ) . '">' . _x( 'Installed', 'theme' ) . '</span>'; 
  359. break; 
  360. case 'install': 
  361. default: 
  362. echo '<a class="theme-install button button-primary" href="' . esc_url( wp_nonce_url( $install_url, 'install-theme_' . $theme->slug ) ) . '">' . __( 'Install' ) . '</a>'; 
  363. break; 
  364. } ?> 
  365. <h3 class="theme-name"><?php echo $name; ?></h3> 
  366. <span class="theme-by"><?php printf( __( 'By %s' ), $author ); ?></span> 
  367. <?php if ( isset( $theme->screenshot_url ) ): ?> 
  368. <img class="theme-screenshot" src="<?php echo esc_url( $theme->screenshot_url ); ?>" alt="" /> 
  369. <?php endif; ?> 
  370. <div class="theme-details"> 
  371. <?php wp_star_rating( array( 'rating' => $theme->rating, 'type' => 'percent', 'number' => $theme->num_ratings ) ); ?> 
  372. <div class="theme-version"> 
  373. <strong><?php _e('Version:') ?> </strong> 
  374. <?php echo wp_kses( $theme->version, $themes_allowedtags ); ?> 
  375. </div> 
  376. <div class="theme-description"> 
  377. <?php echo wp_kses( $theme->description, $themes_allowedtags ); ?> 
  378. </div> 
  379. </div> 
  380. <input class="theme-preview-url" type="hidden" value="<?php echo esc_url( $theme->preview_url ); ?>" /> 
  381. </div> 
  382. <?php 
  383.  
  384. /** 
  385. * Send required variables to JavaScript land 
  386. * @since 3.4.0 
  387. * @access public 
  388. * @global string $tab Current tab within Themes->Install screen 
  389. * @global string $type Type of search. 
  390. * @param array $extra_args Unused. 
  391. */ 
  392. public function _js_vars( $extra_args = array() ) { 
  393. global $tab, $type; 
  394. parent::_js_vars( compact( 'tab', 'type' ) ); 
  395.  
  396. /** 
  397. * Check to see if the theme is already installed. 
  398. * @since 3.4.0 
  399. * @access private 
  400. * @param object $theme - A WordPress.org Theme API object. 
  401. * @return string Theme status. 
  402. */ 
  403. private function _get_theme_status( $theme ) { 
  404. $status = 'install'; 
  405.  
  406. $installed_theme = wp_get_theme( $theme->slug ); 
  407. if ( $installed_theme->exists() ) { 
  408. if ( version_compare( $installed_theme->get('Version'), $theme->version, '=' ) ) 
  409. $status = 'latest_installed'; 
  410. elseif ( version_compare( $installed_theme->get('Version'), $theme->version, '>' ) ) 
  411. $status = 'newer_installed'; 
  412. else 
  413. $status = 'update_available'; 
  414.  
  415. return $status;