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. * @global array $themes_allowedtags 
  192. * @param object $theme An object that contains theme data returned by the WordPress.org API. 
  193. * Example theme data: 
  194. * object(stdClass)[59] 
  195. * public 'name' => string 'Magazine Basic' 
  196. * public 'slug' => string 'magazine-basic' 
  197. * public 'version' => string '1.1' 
  198. * public 'author' => string 'tinkerpriest' 
  199. * public 'preview_url' => string 'http://wp-themes.com/?magazine-basic' 
  200. * public 'screenshot_url' => string 'http://wp-themes.com/wp-content/themes/magazine-basic/screenshot.png' 
  201. * public 'rating' => float 80 
  202. * public 'num_ratings' => int 1 
  203. * public 'homepage' => string 'http://wordpress.org/themes/magazine-basic' 
  204. * public 'description' => string 'A basic magazine style layout with a fully customizable layout through a back-end interface. Designed by <a href="http://bavotasan.com">c.bavota</a> of <a href="http://tinkerpriestmedia.com">Tinker Priest Media</a>.' 
  205. * public 'download_link' => string 'http://wordpress.org/themes/download/magazine-basic.1.1.zip' 
  206. */ 
  207. public function single_row( $theme ) { 
  208. global $themes_allowedtags; 
  209.  
  210. if ( empty( $theme ) ) 
  211. return; 
  212.  
  213. $name = wp_kses( $theme->name, $themes_allowedtags ); 
  214. $author = wp_kses( $theme->author, $themes_allowedtags ); 
  215.  
  216. $preview_title = sprintf( __('Preview “%s”'), $name ); 
  217. $preview_url = add_query_arg( array( 
  218. 'tab' => 'theme-information',  
  219. 'theme' => $theme->slug,  
  220. ), self_admin_url( 'theme-install.php' ) ); 
  221.  
  222. $actions = array(); 
  223.  
  224. $install_url = add_query_arg( array( 
  225. 'action' => 'install-theme',  
  226. 'theme' => $theme->slug,  
  227. ), self_admin_url( 'update.php' ) ); 
  228.  
  229. $update_url = add_query_arg( array( 
  230. 'action' => 'upgrade-theme',  
  231. 'theme' => $theme->slug,  
  232. ), self_admin_url( 'update.php' ) ); 
  233.  
  234. $status = $this->_get_theme_status( $theme ); 
  235.  
  236. switch ( $status ) { 
  237. case 'update_available': 
  238. $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>'; 
  239. break; 
  240. case 'newer_installed': 
  241. case 'latest_installed': 
  242. $actions[] = '<span class="install-now" title="' . esc_attr__( 'This theme is already installed and is up to date' ) . '">' . _x( 'Installed', 'theme' ) . '</span>'; 
  243. break; 
  244. case 'install': 
  245. default: 
  246. $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>'; 
  247. break; 
  248.  
  249. $actions[] = '<a class="install-theme-preview" href="' . esc_url( $preview_url ) . '" title="' . esc_attr( sprintf( __( 'Preview %s' ), $name ) ) . '">' . __( 'Preview' ) . '</a>'; 
  250.  
  251. /** 
  252. * Filters the install action links for a theme in the Install Themes list table. 
  253. * @since 3.4.0 
  254. * @param array $actions An array of theme action hyperlinks. Defaults are 
  255. * links to Install Now, Preview, and Details. 
  256. * @param WP_Theme $theme Theme object. 
  257. */ 
  258. $actions = apply_filters( 'theme_install_actions', $actions, $theme ); 
  259.  
  260. ?> 
  261. <a class="screenshot install-theme-preview" href="<?php echo esc_url( $preview_url ); ?>" title="<?php echo esc_attr( $preview_title ); ?>"> 
  262. <img src="<?php echo esc_url( $theme->screenshot_url ); ?>" width="150" alt="" /> 
  263. </a> 
  264.  
  265. <h3><?php echo $name; ?></h3> 
  266. <div class="theme-author"><?php printf( __( 'By %s' ), $author ); ?></div> 
  267.  
  268. <div class="action-links"> 
  269. <ul> 
  270. <?php foreach ( $actions as $action ): ?> 
  271. <li><?php echo $action; ?></li> 
  272. <?php endforeach; ?> 
  273. <li class="hide-if-no-js"><a href="#" class="theme-detail"><?php _e('Details') ?></a></li> 
  274. </ul> 
  275. </div> 
  276.  
  277. <?php 
  278. $this->install_theme_info( $theme ); 
  279.  
  280. /** 
  281. * Prints the wrapper for the theme installer. 
  282. */ 
  283. public function theme_installer() { 
  284. ?> 
  285. <div id="theme-installer" class="wp-full-overlay expanded"> 
  286. <div class="wp-full-overlay-sidebar"> 
  287. <div class="wp-full-overlay-header"> 
  288. <a href="#" class="close-full-overlay button-secondary"><?php _e( 'Close' ); ?></a> 
  289. <span class="theme-install"></span> 
  290. </div> 
  291. <div class="wp-full-overlay-sidebar-content"> 
  292. <div class="install-theme-info"></div> 
  293. </div> 
  294. <div class="wp-full-overlay-footer"> 
  295. <button type="button" class="collapse-sidebar button-secondary" aria-expanded="true" aria-label="<?php esc_attr_e( 'Collapse Sidebar' ); ?>"> 
  296. <span class="collapse-sidebar-arrow"></span> 
  297. <span class="collapse-sidebar-label"><?php _e( 'Collapse' ); ?></span> 
  298. </button> 
  299. </div> 
  300. </div> 
  301. <div class="wp-full-overlay-main"></div> 
  302. </div> 
  303. <?php 
  304.  
  305. /** 
  306. * Prints the wrapper for the theme installer with a provided theme's data. 
  307. * Used to make the theme installer work for no-js. 
  308. * @param object $theme - A WordPress.org Theme API object. 
  309. */ 
  310. public function theme_installer_single( $theme ) { 
  311. ?> 
  312. <div id="theme-installer" class="wp-full-overlay single-theme"> 
  313. <div class="wp-full-overlay-sidebar"> 
  314. <?php $this->install_theme_info( $theme ); ?> 
  315. </div> 
  316. <div class="wp-full-overlay-main"> 
  317. <iframe src="<?php echo esc_url( $theme->preview_url ); ?>"></iframe> 
  318. </div> 
  319. </div> 
  320. <?php 
  321.  
  322. /** 
  323. * Prints the info for a theme (to be used in the theme installer modal). 
  324. * @global array $themes_allowedtags 
  325. * @param object $theme - A WordPress.org Theme API object. 
  326. */ 
  327. public function install_theme_info( $theme ) { 
  328. global $themes_allowedtags; 
  329.  
  330. if ( empty( $theme ) ) 
  331. return; 
  332.  
  333. $name = wp_kses( $theme->name, $themes_allowedtags ); 
  334. $author = wp_kses( $theme->author, $themes_allowedtags ); 
  335.  
  336. $install_url = add_query_arg( array( 
  337. 'action' => 'install-theme',  
  338. 'theme' => $theme->slug,  
  339. ), self_admin_url( 'update.php' ) ); 
  340.  
  341. $update_url = add_query_arg( array( 
  342. 'action' => 'upgrade-theme',  
  343. 'theme' => $theme->slug,  
  344. ), self_admin_url( 'update.php' ) ); 
  345.  
  346. $status = $this->_get_theme_status( $theme ); 
  347.  
  348. ?> 
  349. <div class="install-theme-info"><?php 
  350. switch ( $status ) { 
  351. case 'update_available': 
  352. echo '<a class="theme-install 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>'; 
  353. break; 
  354. case 'newer_installed': 
  355. case 'latest_installed': 
  356. echo '<span class="theme-install" title="' . esc_attr__( 'This theme is already installed and is up to date' ) . '">' . _x( 'Installed', 'theme' ) . '</span>'; 
  357. break; 
  358. case 'install': 
  359. default: 
  360. echo '<a class="theme-install button-primary" href="' . esc_url( wp_nonce_url( $install_url, 'install-theme_' . $theme->slug ) ) . '">' . __( 'Install' ) . '</a>'; 
  361. break; 
  362. } ?> 
  363. <h3 class="theme-name"><?php echo $name; ?></h3> 
  364. <span class="theme-by"><?php printf( __( 'By %s' ), $author ); ?></span> 
  365. <?php if ( isset( $theme->screenshot_url ) ): ?> 
  366. <img class="theme-screenshot" src="<?php echo esc_url( $theme->screenshot_url ); ?>" alt="" /> 
  367. <?php endif; ?> 
  368. <div class="theme-details"> 
  369. <?php wp_star_rating( array( 'rating' => $theme->rating, 'type' => 'percent', 'number' => $theme->num_ratings ) ); ?> 
  370. <div class="theme-version"> 
  371. <strong><?php _e('Version:') ?> </strong> 
  372. <?php echo wp_kses( $theme->version, $themes_allowedtags ); ?> 
  373. </div> 
  374. <div class="theme-description"> 
  375. <?php echo wp_kses( $theme->description, $themes_allowedtags ); ?> 
  376. </div> 
  377. </div> 
  378. <input class="theme-preview-url" type="hidden" value="<?php echo esc_url( $theme->preview_url ); ?>" /> 
  379. </div> 
  380. <?php 
  381.  
  382. /** 
  383. * Send required variables to JavaScript land 
  384. * @since 3.4.0 
  385. * @access public 
  386. * @global string $tab Current tab within Themes->Install screen 
  387. * @global string $type Type of search. 
  388. * @param array $extra_args Unused. 
  389. */ 
  390. public function _js_vars( $extra_args = array() ) { 
  391. global $tab, $type; 
  392. parent::_js_vars( compact( 'tab', 'type' ) ); 
  393.  
  394. /** 
  395. * Check to see if the theme is already installed. 
  396. * @since 3.4.0 
  397. * @access private 
  398. * @param object $theme - A WordPress.org Theme API object. 
  399. * @return string Theme status. 
  400. */ 
  401. private function _get_theme_status( $theme ) { 
  402. $status = 'install'; 
  403.  
  404. $installed_theme = wp_get_theme( $theme->slug ); 
  405. if ( $installed_theme->exists() ) { 
  406. if ( version_compare( $installed_theme->get('Version'), $theme->version, '=' ) ) 
  407. $status = 'latest_installed'; 
  408. elseif ( version_compare( $installed_theme->get('Version'), $theme->version, '>' ) ) 
  409. $status = 'newer_installed'; 
  410. else 
  411. $status = 'update_available'; 
  412.  
  413. return $status;