PluginProbe ʕ •ᴥ•ʔ
Easy Updates Manager / 8.0.5
Easy Updates Manager v8.0.5
trunk 2.0.0 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.5.0 2.5.1 2.6.0 2.7.0 3.0.0 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 3.6.0 4.0 4.0.2 4.0.3 4.1.0 4.1.10 4.1.12 4.2.21 4.2.24 4.3.0 4.3.10 4.3.12 4.3.13 4.6.0 4.7.0 5.0.0 5.1.0 5.1.1 5.2.0 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1 5.4.2 5.4.3 5.4.5 6.0.0 6.0.1 6.0.3 6.0.5 6.1.0 6.1.1 6.1.3 6.1.5 6.1.8 6.2.0 6.2.11 6.2.2 6.2.3 6.2.5 6.2.7 6.2.9 6.3.0 6.3.1 6.3.3 6.4.0 6.4.4 6.4.6 6.4.7 6.4.8 7.0.0 7.0.1 7.0.2 7.0.3 8.0.1 8.0.2 8.0.3 8.0.5 8.1.0 8.1.1 8.2.0 9.0.0 9.0.1 9.0.10 9.0.11 9.0.12 9.0.13 9.0.14 9.0.15 9.0.16 9.0.17 9.0.18 9.0.19 9.0.20 9.0.21 9.0.3 9.0.5 9.0.6 9.0.7 9.0.8 9.0.9
stops-core-theme-and-plugin-updates / includes / MPSUM_Themes_List_Table.php
stops-core-theme-and-plugin-updates / includes Last commit date
MPSUM_Admin.php 7 years ago MPSUM_Admin_Advanced.php 7 years ago MPSUM_Admin_Advanced_Preview.php 7 years ago MPSUM_Admin_Ajax.php 7 years ago MPSUM_Admin_Bar.php 7 years ago MPSUM_Admin_Core.php 7 years ago MPSUM_Admin_Dashboard.php 7 years ago MPSUM_Admin_Help.php 7 years ago MPSUM_Admin_Logs.php 7 years ago MPSUM_Admin_Plugins.php 7 years ago MPSUM_Admin_Screen_Options.php 7 years ago MPSUM_Admin_Themes.php 7 years ago MPSUM_Advanced_Premium.php 7 years ago MPSUM_Check_Plugin_Install_Status.php 7 years ago MPSUM_Check_Theme_Install_Status.php 7 years ago MPSUM_Commands.php 7 years ago MPSUM_Disable_Updates.php 7 years ago MPSUM_Disable_Updates_All.php 7 years ago MPSUM_Disable_Updates_Plugins.php 7 years ago MPSUM_Disable_Updates_Themes.php 7 years ago MPSUM_Disable_Updates_Translations.php 7 years ago MPSUM_Disable_Updates_WordPress.php 7 years ago MPSUM_Exclude_Users.php 7 years ago MPSUM_Force_Updates.php 7 years ago MPSUM_List_Table.php 7 years ago MPSUM_Logs.php 7 years ago MPSUM_Logs_List_Table.php 7 years ago MPSUM_Plugins_List_Table.php 7 years ago MPSUM_Reset_Options.php 7 years ago MPSUM_Themes_List_Table.php 7 years ago MPSUM_UpdraftCentral.php 7 years ago MPSUM_UpdraftCentral_EUM_Commands.php 7 years ago MPSUM_Utils.php 7 years ago easy-updates-manager-notices.php 7 years ago updraft-notices.php 7 years ago
MPSUM_Themes_List_Table.php
632 lines
1 <?php
2 if (!defined('ABSPATH')) die('No direct access.');
3 /**
4 * Easy Updates Manager Themes List Table class.
5 *
6 * @package Easy Updates Manager
7 * @subpackage MPSUM_List_Table
8 * @since 5.0.0
9 * @access private
10 */
11 class MPSUM_Themes_List_Table extends MPSUM_List_Table {
12
13 public $site_id;
14
15 public $is_site_themes;
16
17 private $tab = 'themes';
18
19 private $status = 'all';
20
21 private $page = '1';
22
23 /**
24 * Constructor.
25 *
26 * @since 3.1.0
27 * @access public
28 *
29 * @see WP_List_Table::__construct() for more information on default arguments.
30 *
31 * @param array $args An associative array of arguments.
32 */
33 public function __construct($args = array()) {
34 parent::__construct(array(
35 'singular' => 'theme',
36 'plural' => 'themes',
37 'screen' => isset($args['screen']) ? $args['screen'] : 'eum_themes_tab',
38 'ajax' => true
39 ));
40
41 if (isset($_REQUEST['action']) && 'eum_ajax' === $_REQUEST['action']) {
42 $this->status = isset($_REQUEST['view']) ? $_REQUEST['view'] : 'all';
43 if (!in_array($this->status, array('all', 'update_disabled', 'update_enabled', 'automatic')))
44 $this->status = 'all';
45
46 $this->page = isset($_REQUEST['paged']) ? $_REQUEST['paged'] : '1';
47 } else {
48 $this->status = isset($args['view']) ? $args['view'] : 'all';
49 if (!in_array($this->status, array('all', 'update_disabled', 'update_enabled', 'automatic')))
50 $this->status = 'all';
51
52 $this->page = isset($args['paged']) ? $args['paged'] : 1;
53 }
54
55 $this->is_site_themes = ('site-themes-network' == $this->screen->id) ? true : false;
56
57 if ($this->is_site_themes)
58 $this->site_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
59 }
60
61 /**
62 * Get table classes
63 *
64 * @return array
65 */
66 protected function get_table_classes() {
67 // todo: remove and add CSS for .themes
68 return array('widefat', 'plugins');
69 }
70
71 /**
72 * Ajax user capability check
73 *
74 * @return boolean
75 */
76 public function ajax_user_can() {
77 if ($this->is_site_themes) {
78 return current_user_can('manage_sites');
79 } else {
80 return current_user_can('manage_network_themes');
81 }
82 }
83
84 /**
85 * Prepares theme items to display
86 *
87 * Prepares theme items by setting pagination variables, order, filter
88 */
89 public function prepare_items() {
90 global $totals;
91 $order = 'DESC';
92 $orderby = 'Name';
93
94 $themes = array(
95 /**
96 * Filter the full array of WP_Theme objects to list in the Multisite
97 * themes list table.
98 *
99 * @since 3.1.0
100 *
101 * @param array $all An array of WP_Theme objects to display in the list table.
102 */
103 'all' => apply_filters('all_themes', wp_get_themes()),
104 'update_enabled' => array(),
105 'update_disabled' => array(),
106 'automatic' => array()
107
108 );
109
110
111 $maybe_update = current_user_can('update_themes') && ! $this->is_site_themes && $current = get_site_transient('update_themes');
112 $theme_options = MPSUM_Updates_Manager::get_options('themes');
113 $theme_automatic_options = MPSUM_Updates_Manager::get_options('themes_automatic');
114 foreach ((array) $themes['all'] as $theme => $theme_data) {
115 if (false !== $key = array_search($theme, $theme_options)) {
116 $themes['update_disabled'][$theme] = $theme_data;
117 } else {
118 $themes['update_enabled'][$theme] = $theme_data;
119 if (in_array($theme, $theme_automatic_options)) {
120 $themes['automatic'][$theme] = $theme_data;
121 }
122 }
123 }
124
125 $totals = array();
126
127 foreach ($themes as $type => $list)
128 $totals[$type] = count($list);
129
130 // Disable the automatic updates view
131 $core_options = MPSUM_Updates_Manager::get_options('core');
132 if (isset($core_options['automatic_theme_updates']) && 'individual' !== $core_options['automatic_theme_updates']) {
133 unset($totals['automatic']);
134 $themes['automatic'] = array();
135 }
136
137 if (empty($themes[$this->status]))
138 $this->status = 'all';
139
140 $this->items = $themes[$this->status];
141 WP_Theme::sort_by_name($this->items);
142
143 $this->has_items = ! empty($themes['all']);
144 $total_this_page = $totals[$this->status];
145
146 if ($orderby) {
147 $orderby = ucfirst($orderby);
148 $order = strtoupper($order);
149
150 if ('Name' == $orderby) {
151 if ('ASC' == $order)
152 $this->items = array_reverse($this->items);
153 } else {
154 uasort($this->items, array($this, '_order_callback'));
155 }
156 }
157
158 // Get themes per page
159 $user_id = get_current_user_id();
160 $themes_per_page = get_user_meta($user_id, 'mpsum_items_per_page', true);
161 if (! is_numeric($themes_per_page)) {
162 $themes_per_page = 100;
163 }
164
165 $start = ($this->page - 1) * $themes_per_page;
166
167 if ($total_this_page > $themes_per_page)
168 $this->items = array_slice($this->items, $start, $themes_per_page, true);
169
170 $this->set_pagination_args(array(
171 'total_items' => $total_this_page,
172 'per_page' => $themes_per_page,
173 'total_pages' => ceil($total_this_page / $themes_per_page),
174 'view' => $this->status,
175 'tab' => $this->tab,
176 'paged' => $this->page
177 ));
178 }
179
180 /**
181 * Search Callback
182 *
183 * @staticvar string $term
184 * @param string $theme WP Theme
185 * @return bool
186 */
187 public function _search_callback($theme) {
188 static $term;
189 if (is_null($term))
190 $term = wp_unslash($_REQUEST['s']);
191
192 foreach (array('Name', 'Description', 'Author', 'Author', 'AuthorURI') as $field) {
193 // Don't mark up; Do translate.
194 if (false !== stripos($theme->display($field, false, true), $term))
195 return true;
196 }
197
198 if (false !== stripos($theme->get_stylesheet(), $term))
199 return true;
200
201 if (false !== stripos($theme->get_template(), $term))
202 return true;
203
204 return false;
205 }
206
207 /**
208 * Order callback
209 * Not used by any core columns.
210 *
211 * @global string $orderby
212 * @global string $order
213 * @param array $theme_a Theme A
214 * @param array $theme_b Theme B
215 * @return int
216 */
217 public function _order_callback($theme_a, $theme_b) {
218 global $orderby, $order;
219
220 $a = $theme_a[$orderby];
221 $b = $theme_b[$orderby];
222
223 if ($a == $b)
224 return 0;
225
226 if ('DESC' == $order) {
227 return ($a < $b) ? 1 : -1;
228 } else {
229 return ($a < $b) ? -1 : 1;
230 }
231 }
232
233 /**
234 * No Items
235 *
236 * @return void
237 */
238 public function no_items() {
239 if (! $this->has_items) {
240 _e('No themes found.', 'stops-core-theme-and-plugin-updates');
241 } else {
242 _e('You do not appear to have any themes available at this time.', 'stops-core-theme-and-plugin-updates');
243 }
244 }
245
246 /**
247 * Get columns
248 *
249 * @return array
250 */
251 public function get_columns() {
252 return array(
253 'cb' => '<input type="checkbox" />',
254 'name' => __('Theme', 'stops-core-theme-and-plugin-updates'),
255 'description' => __('Description', 'stops-core-theme-and-plugin-updates'),
256 );
257 }
258
259 /**
260 * Get sortable columns
261 *
262 * @return array
263 */
264 protected function get_sortable_columns() {
265 return array();
266 }
267
268 /**
269 * Get views
270 *
271 * @return array
272 */
273 protected function get_views() {
274 global $totals;
275
276 $status_links = array();
277 foreach ($totals as $type => $count) {
278 if (!$count)
279 continue;
280
281 switch ($type) {
282 case 'all':
283 $text = _nx('All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $count, 'themes');
284 break;
285 case 'update_disabled':
286 $text = _n('Updates Disabled <span class="count">(%s)</span>', 'Updates Disabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
287 break;
288 case 'update_enabled':
289 $text = _n('Updates Enabled <span class="count">(%s)</span>', 'Updates Enabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
290 break;
291 case 'automatic':
292 $text = _n('Automatic Updates <span class="count">(%s)</span>', 'Automatic Updates <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates');
293 break;
294 }
295
296 if ('search' != $type) {
297 $theme_url = MPSUM_Admin::get_url();
298 $query_args = array(
299 'tab' => $this->tab,
300 'view' => $type
301 );
302
303 $status_links[$type] = sprintf("<a href='%s' data-view='%s' %s>%s</a>",
304 add_query_arg($query_args, $theme_url),
305 $this->status,
306 ($type == $this->status) ? ' class="current"' : '',
307 sprintf($text, number_format_i18n($count))
308 );
309 }
310 }
311
312 return $status_links;
313 }
314
315 /**
316 * Get bulk actions
317 *
318 * @return array
319 */
320 protected function get_bulk_actions() {
321 $actions = array();
322
323 $actions['allow-update-selected'] = esc_html__('Theme Updates On', 'stops-core-theme-and-plugin-updates');
324 $actions['disallow-update-selected'] = esc_html__('Theme Updates Off', 'stops-core-theme-and-plugin-updates');
325 $core_options = MPSUM_Updates_Manager::get_options('core');
326 if (isset($core_options['automatic_theme_updates']) && 'individual' == $core_options['automatic_theme_updates']) {
327 $actions['allow-automatic-selected'] = esc_html__('Automatic Updates On', 'stops-core-theme-and-plugin-updates');
328 $actions['disallow-automatic-selected'] = esc_html__('Automatic Updates Off', 'stops-core-theme-and-plugin-updates');
329 }
330
331 return $actions;
332 }
333
334 /**
335 * Display rows
336 *
337 * @return void
338 */
339 public function display_rows() {
340 foreach ($this->items as $theme)
341 $this->single_row($theme);
342 }
343
344 /**
345 * Single row theme
346 *
347 * @param object $theme The specified WP_Theme object
348 */
349 public function single_row($theme) {
350 $this->status = 'all';
351 $stylesheet = $theme->get_stylesheet();
352 remove_action("after_theme_row_$stylesheet", 'wp_theme_update_row', 10, 2);
353 $theme_key = urlencode($stylesheet);
354
355 /**
356 * Filter the action links that show up under each theme row.
357 *
358 * @since 5.0.0
359 *
360 * @param array Array of action links
361 * @param WP_Theme $theme WP_Theme object
362 * @param string $this->status Status of the theme.
363 */
364 $actions = apply_filters('mpsum_theme_action_links', array(), $theme, 'all');
365
366 $checkbox_id = "checkbox_" . md5($theme->get('Name'));
367 $checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr($stylesheet) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select', 'stops-core-theme-and-plugin-updates') . " " . $theme->display('Name') . "</label>";
368
369 $id = sanitize_html_class($theme->get_stylesheet());
370 $class = 'active';
371 $theme_options = MPSUM_Updates_Manager::get_options('themes');
372 if (false !== $key = array_search($stylesheet, $theme_options)) {
373 $class = 'inactive';
374 }
375 echo "<tr id='$id' class='$class'>";
376
377 list($columns, $hidden) = $this->get_column_info();
378
379 foreach ($columns as $column_name => $column_display_name) {
380 $style = '';
381 if (in_array($column_name, $hidden))
382 $style = ' style="display:none;"';
383
384 switch ($column_name) {
385 case 'cb':
386 echo "<th scope='row' class='check-column'>$checkbox</th>";
387 break;
388 case 'name':
389 echo "<td class='theme-title'$style>";
390 echo "<img src='" . esc_url($theme->get_screenshot()) . "' width='85' height='64' class='updates-table-screenshot' alt='' />";
391 echo '<div class="eum-themes-name-actions">';
392 echo "<h3 class='eum-themes-name'>" . $theme->display('Name') . "</h3>";
393 echo '<div class="eum-themes-wrapper">';
394 printf('<h4>%s</h4>', esc_html__('Theme Updates', 'stops-core-theme-and-plugin-updates'));
395
396 echo '<div class="toggle-wrapper toggle-wrapper-themes">';
397
398 $enable_class = $disable_class = '';
399 $checked = 'false';
400 $key = in_array($stylesheet, $theme_options);
401 if (! $key) {
402 $enable_class = 'eum-enabled eum-active';
403 $checked = 'true';
404 } else {
405 $disable_class = 'eum-disabled eum-active';
406 }
407
408 printf('<input type="hidden" name="themes[%s]" value="%s">',
409 $stylesheet,
410 $checked
411 );
412
413 printf('<button aria-label="%s" class="eum-toggle-button eum-enabled %s" data-checked="%s">%s</button>',
414 esc_attr__('Allow Updates', 'stops-core-theme-and-plugin-updates'),
415 esc_attr($enable_class),
416 $stylesheet,
417 esc_html__('Allowed', 'stops-core-theme-and-plugin-updates')
418 );
419
420 printf('<button aria-label="%s" class="eum-toggle-button eum-disabled %s" data-checked="%s">%s</button>',
421 esc_attr__('Disallow Updates', 'stops-core-theme-and-plugin-updates'),
422 esc_attr($disable_class),
423 $stylesheet,
424 esc_html__('Blocked', 'stops-core-theme-and-plugin-updates')
425 );
426
427 echo '</div></div>';
428
429 // Automatic Link
430 $theme_automatic_options = MPSUM_Updates_Manager::get_options('themes_automatic');
431 $core_options = MPSUM_Updates_Manager::get_options('core');
432 if (isset($core_options['automatic_theme_updates']) && 'individual' == $core_options['automatic_theme_updates']) {
433 printf('<div class="eum-themes-automatic-wrapper" %s>', ($key) ? 'style="display: none;"' : '');
434 printf('<h4>%s</h4>', esc_html__('Automatic Updates', 'stops-core-theme-and-plugin-updates'));
435 echo '<div class="toggle-wrapper toggle-wrapper-themes-automatic">';
436 $enable_class = $disable_class = '';
437 if (in_array($stylesheet, $theme_automatic_options)) {
438 $enable_class = 'eum-active';
439 $checked = 'true';
440 } else {
441 $disable_class = 'eum-active';
442 }
443
444 printf('<input type="hidden" name="themes_automatic[%s]" value="%s">',
445 $stylesheet,
446 $checked
447 );
448
449 printf('<button aria-label="%s" class="eum-toggle-button eum-enabled %s" data-checked="%s">%s</button>',
450 esc_html__('Enable Automatic Updates', 'stops-core-theme-and-plugin-updates'),
451 esc_attr($enable_class),
452 $stylesheet,
453 esc_html__('On', 'stops-core-theme-and-plugin-updates')
454 );
455
456 printf('<button aria-label="%s" class="eum-toggle-button eum-disabled %s" data-checked="%s">%s</button>',
457 esc_attr__('Enable Automatic Updates', 'stops-core-theme-and-plugin-updates'),
458 esc_attr($disable_class),
459 $stylesheet,
460 esc_html__('Off', 'stops-core-theme-and-plugin-updates')
461 );
462
463 echo '</div></div>';
464 }
465 echo '</div>';
466 echo "</td>";
467 break;
468 case 'description':
469 echo "<td class='column-description desc'$style>";
470 if ($theme->errors()) {
471 $pre = 'broken' == $this->status ? __('Broken Theme:', 'stops-core-theme-and-plugin-updates') . ' ' : '';
472 echo '<p><strong class="attention">' . $pre . $theme->errors()->get_error_message() . '</strong></p>';
473 }
474 echo "<div class='theme-description'><p>" . $theme->display('Description') . "</p></div>
475 <div class='second theme-version-author-uri'>";
476
477 $theme_meta = array();
478
479 if ($theme->get('Version'))
480 $theme_meta[] = sprintf(__('Version %s', 'stops-core-theme-and-plugin-updates'), $theme->display('Version'));
481
482 $theme_meta[] = sprintf(__('By %s', 'stops-core-theme-and-plugin-updates'), $theme->display('Author'));
483
484 if ($theme->get('ThemeURI'))
485 $theme_meta[] = '<a href="' . $theme->display('ThemeURI') . '" title="' . esc_attr__('Visit theme homepage', 'stops-core-theme-and-plugin-updates') . '">' . __('Visit Theme Site', 'stops-core-theme-and-plugin-updates') . '</a>';
486
487 /**
488 * Filter the array of row meta for each theme in the Multisite themes
489 * list table.
490 *
491 * @since 3.1.0
492 *
493 * @param array $theme_meta An array of the theme's metadata,
494 * including the version, author, and
495 * theme URI.
496 * @param string $stylesheet Directory name of the theme.
497 * @param WP_Theme $theme WP_Theme object.
498 * @param string $this->status Status of the theme.
499 */
500 $theme_meta = apply_filters('theme_row_meta', $theme_meta, $stylesheet, $theme, $this->status);
501 echo implode(' | ', $theme_meta);
502
503 // Show active status for blogs
504 if (is_multisite()) {
505 $themes = wp_get_themes(array('allowed' => true));
506 $is_allowed_theme[] = array();
507 foreach ($themes as $style => $theme_data) {
508 if ($style === $stylesheet) {
509 $is_allowed_theme[] = $stylesheet;
510 }
511 }
512 $is_allowed_stylesheet = false;
513 foreach ($is_allowed_theme as $allowed_stylesheet) {
514 if ($allowed_stylesheet === $stylesheet) {
515 $is_allowed_stylesheet = true;
516 }
517 }
518 if ($is_allowed_stylesheet) {
519 printf('<div class="mpsum-success mpsum-regular"><a href="#" data-theme-file="%s" class="eum-list-themes-action">%s</a><div class="eum-list-themes"></div></div>', esc_attr($stylesheet), esc_html__('View all sites that have this theme installed.', 'stops-core-theme-and-plugin-updates'));
520 } else {
521 printf('<div class="mpsum-notice mpsum-regular">%s<br /><a href="#" data-theme-file="%s" class="eum-list-themes-action">%s</a><div class="eum-list-themes"></div></div>', esc_html__('This theme is not allowed to be activated on your network of sites, but may be enabled for specific sites.', 'stops-core-theme-and-plugin-updates'), esc_attr($stylesheet), esc_html__('View all sites that have this theme installed.', 'stops-core-theme-and-plugin-updates'));
522 }
523 } else {
524 if (get_stylesheet() === $stylesheet) {
525 printf('<div class="mpsum-success mpsum-regular">%s</div>', esc_html__('This theme is active for your site.', 'stops-core-theme-and-plugin-updates'));
526 } else {
527 printf('<div class="mpsum-error mpsum-bold">%s</div>', esc_html__('This theme is inactive for your site.', 'stops-core-theme-and-plugin-updates'));
528 }
529 }
530
531 echo "</div></td>";
532 break;
533
534 default:
535 echo "<td class='$column_name column-$column_name'$style>";
536
537 /**
538 * Fires inside each custom column of the Multisite themes list table.
539 *
540 * @since 3.1.0
541 *
542 * @param string $column_name Name of the column.
543 * @param string $stylesheet Directory name of the theme.
544 * @param WP_Theme $theme Current WP_Theme object.
545 */
546 do_action('manage_themes_custom_column', $column_name, $stylesheet, $theme);
547 echo "</td>";
548 }
549 }
550
551 echo "</tr>";
552
553 if ($this->is_site_themes)
554 remove_action("after_theme_row_$stylesheet", 'wp_theme_update_row');
555
556 /**
557 * Fires after each row in the Multisite themes list table.
558 *
559 * @since 3.1.0
560 *
561 * @param string $stylesheet Directory name of the theme.
562 * @param WP_Theme $theme Current WP_Theme object.
563 * @param string $this->status Status of the theme.
564 */
565 do_action('after_theme_row', $stylesheet, $theme, $this->status);
566
567 /**
568 * Fires after each specific row in the Multisite themes list table.
569 *
570 * The dynamic portion of the hook name, `$stylesheet`, refers to the
571 * directory name of the theme, most often synonymous with the template
572 * name of the theme.
573 *
574 * @since 3.5.0
575 *
576 * @param string $stylesheet Directory name of the theme.
577 * @param WP_Theme $theme Current WP_Theme object.
578 * @param string $this->status Status of the theme.
579 */
580 do_action("after_theme_row_$stylesheet", $stylesheet, $theme, $this->status);
581 }
582
583 /**
584 * Captures response of ajax calls and returns it
585 */
586 public function ajax_response() {
587 $this->prepare_items();
588 extract($this->_args);
589 extract($this->_pagination_args, EXTR_SKIP);
590 ob_start();
591 $this->views();
592 $views = ob_get_clean();
593
594 ob_start();
595 if (!empty($_REQUEST['no_placeholder'])) {
596 $this->display_rows();
597 } else {
598 $this->display_rows_or_placeholder();
599 }
600 $rows = ob_get_clean();
601
602 ob_start();
603 $this->print_column_headers();
604 $headers = ob_get_clean();
605
606 ob_start();
607 $this->pagination('top');
608 $pagination_top = ob_get_clean();
609
610 ob_start();
611 $this->pagination('bottom');
612 $pagination_bottom = ob_get_clean();
613
614 $response['views'] = array($views);
615 $response['rows'] = array($rows);
616 $response['pagination']['top'] = $pagination_top;
617 $response['pagination']['bottom'] = $pagination_bottom;
618 $response['headers'] = $headers;
619
620 if (isset($total_items)) {
621 $response['total_items_i18n'] = sprintf(_n('1 plugin', '%s plugins', $total_items), number_format_i18n($total_items));
622 }
623
624 if (isset($total_pages)) {
625 $response['total_pages'] = $total_pages;
626 $response['total_pages_i18n'] = number_format_i18n($total_pages);
627 }
628
629 wp_send_json($response);
630 }
631 }
632