PluginProbe
TablePress – Tables in WordPress made easy / 2.1.8
TablePress – Tables in WordPress made easy v2.1.8
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / views / class-all-tables-list-table.php

class-all-tables-list-table.php in TablePress – Tables in WordPress made easy 2.1.8, at views/class-all-tables-list-table.php

612 lines 22.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * List Tables View List Table
4 *
5 * @package TablePress
6 * @subpackage Views
7 * @author Tobias Bäthge
8 * @since 2.0.0
9 */
10
11 // Prohibit direct script loading.
12 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
13
14 /**
15 * TablePress All Tables List Table class
16 *
17 * @package TablePress
18 * @subpackage Views
19 * @author Tobias Bäthge
20 * @since 1.0.0
21 */
22 class TablePress_All_Tables_List_Table extends WP_List_Table {
23
24 /**
25 * Number of items of the initial data set (before sort, search, and pagination).
26 *
27 * @since 1.0.0
28 * @var int
29 */
30 protected $items_count = 0;
31
32 /**
33 * Cached bulk actions.
34 *
35 * This property has to be declared here, as it's `private` in the parent class
36 * and thus can't be inherited.
37 *
38 * @since 1.0.0
39 * @var array|null
40 */
41 protected $_actions;
42
43 /**
44 * Initialize the List Table.
45 *
46 * @since 1.0.0
47 */
48 public function __construct() {
49 $screen = get_current_screen();
50
51 // Hide "Last Modified By" column by default.
52 if ( false === get_user_option( "manage{$screen->id}columnshidden" ) ) {
53 update_user_option( get_current_user_id(), "manage{$screen->id}columnshidden", array( 'table_last_modified_by' ), true );
54 }
55
56 parent::__construct( array(
57 'singular' => 'tablepress-table', // Singular name of the listed records.
58 'plural' => 'tablepress-all-tables', // Plural name of the listed records.
59 'ajax' => false, // Does this list table support AJAX?
60 'screen' => $screen, // WP_Screen object.
61 ) );
62 }
63
64 /**
65 * Set the data items (here: tables) that are to be displayed by the List Tables, and their original count.
66 *
67 * @since 1.0.0
68 *
69 * @param array $items Tables to be displayed in the List Table.
70 */
71 public function set_items( array $items ) {
72 $this->items = $items;
73 $this->items_count = count( $items );
74 }
75
76 /**
77 * Check whether the user has permissions for certain AJAX actions.
78 * (not used, but must be implemented in this child class)
79 *
80 * @since 1.0.0
81 *
82 * @return bool true (Default value).
83 */
84 public function ajax_user_can() {
85 return true;
86 }
87
88 /**
89 * Get a list of columns in this List Table.
90 *
91 * Format: 'internal-name' => 'Column Title'.
92 *
93 * @since 1.0.0
94 *
95 * @return array List of columns in this List Table.
96 */
97 public function get_columns() {
98 $columns = array(
99 'cb' => $this->has_items() ? '<input type="checkbox" />' : '', // Checkbox for "Select all", but only if there are items in the table.
100 // "name" is special in WP, which is why we prefix every entry here, to be safe!
101 'table_id' => __( 'ID', 'tablepress' ),
102 'table_name' => __( 'Table Name', 'tablepress' ),
103 'table_description' => __( 'Description', 'tablepress' ),
104 'table_author' => __( 'Author', 'tablepress' ),
105 'table_last_modified_by' => __( 'Last Modified By', 'tablepress' ),
106 'table_last_modified' => __( 'Last Modified', 'tablepress' ),
107 );
108 return $columns;
109 }
110
111 /**
112 * Get a list of columns that are sortable.
113 *
114 * Format: 'internal-name' => array( $field for $item[ $field ], true for already sorted ).
115 *
116 * @since 1.0.0
117 *
118 * @return array List of sortable columns in this List Table.
119 */
120 protected function get_sortable_columns() {
121 // No sorting on the Empty List placeholder.
122 if ( ! $this->has_items() ) {
123 return array();
124 }
125
126 $sortable_columns = array(
127 'table_id' => array( 'id', true ), // true means its already sorted.
128 'table_name' => array( 'name', false ),
129 'table_description' => array( 'description', false ),
130 'table_author' => array( 'author', false ),
131 'table_last_modified_by' => array( 'last_modified_by', false ),
132 'table_last_modified' => array( 'last_modified', false ),
133 );
134 return $sortable_columns;
135 }
136
137 /**
138 * Gets the name of the default primary column.
139 *
140 * @since 1.7.0
141 *
142 * @return string Name of the default primary column, in this case, the table name.
143 */
144 protected function get_default_primary_column_name() {
145 return 'table_name';
146 }
147
148 /**
149 * Render a cell in the "cb" column.
150 *
151 * @since 1.0.0
152 *
153 * @param array $item Data item for the current row.
154 * @return string HTML content of the cell.
155 */
156 protected function column_cb( /* array */ $item ) {
157 // Don't use `array` type hint in method declaration to prevent a Strict Standards notice, as the method is inherited.
158 $user_can_copy_table = current_user_can( 'tablepress_copy_table', $item['id'] );
159 $user_can_delete_table = current_user_can( 'tablepress_delete_table', $item['id'] );
160 $user_can_export_table = current_user_can( 'tablepress_export_table', $item['id'] );
161
162 if ( ! ( $user_can_copy_table || $user_can_delete_table || $user_can_export_table ) ) {
163 return '';
164 }
165
166 if ( '' === trim( $item['name'] ) ) {
167 $item['name'] = __( '(no name)', 'tablepress' );
168 }
169
170 return sprintf(
171 // The `label-covers-full-cell` class on the <label> is kept for (some) backwards compatibility with WordPress 6.3, and can be removed once TablePress requires WordPress 6.4.
172 '<input type="checkbox" id="cb-select-%1$s" name="table[]" value="%1$s" /><label class="label-covers-full-cell" for="cb-select-%1$s"><span class="screen-reader-text">%2$s</span></label>',
173 esc_attr( $item['id'] ),
174 esc_html( sprintf( __( 'Select table “%s”', 'tablepress' ), $item['name'] ) )
175 );
176 }
177
178 /**
179 * Render a cell in the "table_id" column.
180 *
181 * @since 1.0.0
182 *
183 * @param array $item Data item for the current row.
184 * @return string HTML content of the cell.
185 */
186 protected function column_table_id( array $item ) {
187 return esc_html( $item['id'] );
188 }
189
190 /**
191 * Render a cell in the "table_name" column.
192 *
193 * @since 1.0.0
194 *
195 * @param array $item Data item for the current row.
196 * @return string HTML content of the cell.
197 */
198 protected function column_table_name( array $item ) {
199 $user_can_edit_table = current_user_can( 'tablepress_edit_table', $item['id'] );
200 $user_can_copy_table = current_user_can( 'tablepress_copy_table', $item['id'] );
201 $user_can_export_table = current_user_can( 'tablepress_export_table', $item['id'] );
202 $user_can_delete_table = current_user_can( 'tablepress_delete_table', $item['id'] );
203 $user_can_preview_table = current_user_can( 'tablepress_preview_table', $item['id'] );
204
205 $edit_url = TablePress::url( array( 'action' => 'edit', 'table_id' => $item['id'] ) );
206 $copy_url = TablePress::url( array( 'action' => 'copy_table', 'item' => $item['id'], 'return' => 'list', 'return_item' => $item['id'] ), true, 'admin-post.php' );
207 $export_url = TablePress::url( array( 'action' => 'export', 'table_id' => $item['id'] ) );
208 $delete_url = TablePress::url( array( 'action' => 'delete_table', 'item' => $item['id'], 'return' => 'list', 'return_item' => $item['id'] ), true, 'admin-post.php' );
209 $preview_url = TablePress::url( array( 'action' => 'preview_table', 'item' => $item['id'], 'return' => 'list', 'return_item' => $item['id'] ), true, 'admin-post.php' );
210
211 if ( '' === trim( $item['name'] ) ) {
212 $item['name'] = __( '(no name)', 'tablepress' );
213 }
214
215 if ( $user_can_edit_table ) {
216 $row_text = '<strong><a title="' . esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;', 'tablepress' ), esc_attr( $item['name'] ) ) ) . '" class="row-title" href="' . $edit_url . '">' . esc_html( $item['name'] ) . '</a></strong>';
217 } else {
218 $row_text = '<strong>' . esc_html( $item['name'] ) . '</strong>';
219 }
220
221 $row_actions = array();
222 if ( $user_can_edit_table ) {
223 $row_actions['edit'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $edit_url, esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;', 'tablepress' ), $item['name'] ) ), __( 'Edit', 'tablepress' ) );
224 }
225 $row_actions['shortcode hide-if-no-js'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', '#', esc_attr( '[' . TablePress::$shortcode . " id={$item['id']} /]" ), __( 'Show Shortcode', 'tablepress' ) );
226 if ( $user_can_copy_table ) {
227 $row_actions['copy'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $copy_url, esc_attr( sprintf( __( 'Copy &#8220;%s&#8221;', 'tablepress' ), $item['name'] ) ), __( 'Copy', 'tablepress' ) );
228 }
229 if ( $user_can_export_table ) {
230 $row_actions['export'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $export_url, esc_attr( sprintf( __( 'Export &#8220;%s&#8221;', 'tablepress' ), $item['name'] ) ), _x( 'Export', 'row action', 'tablepress' ) );
231 }
232 if ( $user_can_delete_table ) {
233 $row_actions['delete'] = sprintf( '<a href="%1$s" title="%2$s" class="delete-link">%3$s</a>', $delete_url, esc_attr( sprintf( __( 'Delete &#8220;%s&#8221;', 'tablepress' ), $item['name'] ) ), __( 'Delete', 'tablepress' ) );
234 }
235 if ( $user_can_preview_table ) {
236 $row_actions['table-preview'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $preview_url, esc_attr( sprintf( __( 'Preview of table “%1$s” (ID %2$s)', 'tablepress' ), $item['name'], $item['id'] ) ), __( 'Preview', 'tablepress' ) );
237 }
238
239 return $row_text . $this->row_actions( $row_actions );
240 }
241
242 /**
243 * Render a cell in the "table_description" column.
244 *
245 * @since 1.0.0
246 *
247 * @param array $item Data item for the current row.
248 * @return string HTML content of the cell.
249 */
250 protected function column_table_description( array $item ) {
251 if ( '' === trim( $item['description'] ) ) {
252 $item['description'] = __( '(no description)', 'tablepress' );
253 }
254 return esc_html( $item['description'] );
255 }
256
257 /**
258 * Render a cell in the "table_author" column.
259 *
260 * @since 1.0.0
261 *
262 * @param array $item Data item for the current row.
263 * @return string HTML content of the cell.
264 */
265 protected function column_table_author( array $item ) {
266 return TablePress::get_user_display_name( $item['author'] );
267 }
268
269 /**
270 * Render a cell in the "last_modified_by" column.
271 *
272 * @since 1.0.0
273 *
274 * @param array $item Data item for the current row.
275 * @return string HTML content of the cell.
276 */
277 protected function column_table_last_modified_by( array $item ) {
278 return TablePress::get_user_display_name( $item['options']['last_editor'] );
279 }
280
281 /**
282 * Render a cell in the "table_last_modified" column.
283 *
284 * @since 1.0.0
285 *
286 * @param array $item Data item for the current row.
287 * @return string HTML content of the cell.
288 */
289 protected function column_table_last_modified( array $item ) {
290 $modified_timestamp = date_create( $item['last_modified'], wp_timezone() );
291 $modified_timestamp = $modified_timestamp->getTimestamp();
292 $current_timestamp = time();
293 $time_diff = $current_timestamp - $modified_timestamp;
294 // Time difference is only shown up to one week.
295 if ( $time_diff >= 0 && $time_diff < WEEK_IN_SECONDS ) {
296 $time_diff = sprintf( __( '%s ago', 'default' ), human_time_diff( $modified_timestamp, $current_timestamp ) );
297 } else {
298 $time_diff = TablePress::format_datetime( $item['last_modified'], '<br />' );
299 }
300 $readable_time = TablePress::format_datetime( $item['last_modified'] );
301 return '<abbr title="' . esc_attr( $readable_time ) . '">' . $time_diff . '</abbr>';
302 }
303
304 /**
305 * Handles output for the default column.
306 *
307 * @since 1.8.0
308 *
309 * @param array $item Data item for the current row.
310 * @param string $column_name Current column name.
311 */
312 protected function column_default( /* array */ $item, $column_name ) {
313 // Don't use `array` type hint in method declaration to prevent a Strict Standards notice, as the method is inherited.
314 /**
315 * Fires inside each custom column of the TablePress list table.
316 *
317 * @since 1.8.0
318 *
319 * @param array $column_name Current column name.
320 * @param string $item Data item for the current row.
321 */
322 do_action( 'manage_tablepress_list_custom_column', $column_name, $item );
323 }
324
325 /**
326 * Generates and display row actions links for the list table.
327 *
328 * The "Table Name" column already gets these, so return an empty string here to prevent them from being duplicated.
329 *
330 * @since 2.0.0
331 *
332 * @param object|array $item The item being acted upon.
333 * @param string $column_name Current column name.
334 * @param string $primary Primary column name.
335 * @return string The row actions HTML, or an empty string
336 * if the current column is not the primary column.
337 */
338 protected function handle_row_actions( $item, $column_name, $primary ) {
339 return '';
340 }
341
342 /**
343 * Get a list (name => title) bulk actions that are available.
344 *
345 * @since 1.0.0
346 *
347 * @return array Bulk actions for this table.
348 */
349 protected function get_bulk_actions() {
350 $bulk_actions = array();
351
352 if ( current_user_can( 'tablepress_copy_tables' ) ) {
353 $bulk_actions['copy'] = _x( 'Copy', 'bulk action', 'tablepress' );
354 }
355 if ( current_user_can( 'tablepress_export_tables' ) ) {
356 $bulk_actions['export'] = _x( 'Export', 'bulk action', 'tablepress' );
357 }
358 if ( current_user_can( 'tablepress_delete_tables' ) ) {
359 $bulk_actions['delete'] = _x( 'Delete', 'bulk action', 'tablepress' );
360 }
361
362 return $bulk_actions;
363 }
364
365 /**
366 * Render the bulk actions dropdown.
367 *
368 * In comparison with parent class, this has modified HTML (especially no field named "action" as that's being used already)!
369 *
370 * @since 1.0.0
371 *
372 * @param string $which The location of the bulk actions: 'top' or 'bottom'.
373 * This is designated as optional for backwards-compatibility.
374 */
375 protected function bulk_actions( $which = '' ) {
376 if ( is_null( $this->_actions ) ) {
377 $this->_actions = $this->get_bulk_actions();
378 $no_new_actions = $this->_actions;
379 /** This filter is documented in the WordPress function WP_List_Table::bulk_actions() in wp-admin/includes/class-wp-list-table.php */
380 $this->_actions = apply_filters( 'bulk_actions-' . $this->screen->id, $this->_actions ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
381 $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions );
382 $two = '';
383 } else {
384 $two = '2';
385 }
386
387 if ( empty( $this->_actions ) ) {
388 return;
389 }
390
391 $name_id = "bulk-action-selector-{$which}";
392 echo "<label for='{$name_id}' class='screen-reader-text'>" . __( 'Select Bulk Action', 'tablepress' ) . "</label>\n";
393 echo "<select name='{$name_id}' id='{$name_id}'>\n";
394 echo "<option value='-1' selected='selected'>" . __( 'Bulk Actions', 'tablepress' ) . "</option>\n";
395 foreach ( $this->_actions as $name => $title ) {
396 echo "\t<option value='{$name}'>{$title}</option>\n";
397 }
398 echo "</select>\n";
399 submit_button( __( 'Apply', 'tablepress' ), 'action', '', false, array( 'id' => "doaction{$two}" ) );
400 echo "\n";
401 }
402
403 /**
404 * Holds the message to be displayed when there are no items in the table.
405 *
406 * @since 1.0.0
407 */
408 public function no_items() {
409 _e( 'No tables found.', 'tablepress' );
410 if ( 0 === $this->items_count ) {
411 $user_can_add_tables = current_user_can( 'tablepress_add_tables' );
412 $user_can_import_tables = current_user_can( 'tablepress_import_tables' );
413
414 $add_url = TablePress::url( array( 'action' => 'add' ) );
415 $import_url = TablePress::url( array( 'action' => 'import' ) );
416
417 if ( $user_can_add_tables && $user_can_import_tables ) {
418 echo ' ' . sprintf( __( 'You should <a href="%1$s">add</a> or <a href="%2$s">import</a> a table to get started!', 'tablepress' ), $add_url, $import_url );
419 } elseif ( $user_can_add_tables ) {
420 echo ' ' . sprintf( __( 'You should <a href="%s">add</a> a table to get started!', 'tablepress' ), $add_url );
421 } elseif ( $user_can_import_tables ) {
422 echo ' ' . sprintf( __( 'You should <a href="%s">import</a> a table to get started!', 'tablepress' ), $import_url );
423 }
424 }
425 }
426
427 /**
428 * Generate the elements above or below the table (like bulk actions and pagination).
429 *
430 * In comparison with parent class, this has no nonce field in its HTML code and a one-time filter around the pagination call, to change a string.
431 *
432 * @since 1.0.0
433 *
434 * @param string $which Location ("top" or "bottom").
435 */
436 protected function display_tablenav( $which ) {
437 ?>
438 <div class="tablenav <?php echo esc_attr( $which ); ?>">
439
440 <?php if ( $this->has_items() ) : ?>
441 <div class="alignleft actions bulkactions">
442 <?php $this->bulk_actions( $which ); ?>
443 </div>
444 <?php
445 endif;
446 $this->extra_tablenav( $which );
447
448 add_filter( 'ngettext_default', array( $this, 'change_pagination_items_string' ), 10, 5 );
449 $this->pagination( $which );
450 remove_filter( 'ngettext_default', array( $this, 'change_pagination_items_string' ), 10, 5 );
451 ?>
452
453 <br class="clear" />
454 </div>
455 <?php
456 }
457
458 /**
459 * Replaces the "%s item/%s items" string in the pagination with "%s table/%s tables".
460 *
461 * @since 2.0.0
462 *
463 * @param string $translation The current translation of a singular or plural form.
464 * @param string $single The text to be used if the number is singular.
465 * @param string $plural The text to be used if the number is plural.
466 * @param int $number The number to compare against to use either the singular or plural form.
467 * @param string $domain Text domain. Defaults to 'default'.
468 * @return string The changed translation.
469 */
470 public function change_pagination_items_string( $translation, $single, $plural, $number, $domain ) {
471 if ( '%s item' === $single && '%s items' === $plural ) {
472 $translation = _n( '%s table', '%s tables', $number, 'tablepress' );
473 }
474 return $translation;
475 }
476
477 /**
478 * Callback to determine whether the given $item contains the search term.
479 *
480 * @since 1.0.0
481 *
482 * @param string $item Table ID that shall be searched.
483 * @return bool Whether the search term was found or not.
484 */
485 protected function _search_callback( $item ) {
486 static $term;
487 static $json_encoded_term;
488 if ( is_null( $term ) || is_null( $json_encoded_term ) ) {
489 $term = wp_unslash( $_GET['s'] );
490 $json_encoded_term = substr( wp_json_encode( $term, TABLEPRESS_JSON_OPTIONS ), 1, -1 );
491 }
492
493 static $debug;
494 if ( is_null( $debug ) ) {
495 // Set debug variable to allow searching in corrupted tables.
496 $debug = isset( $_GET['debug'] ) ? ( 'true' === $_GET['debug'] ) : WP_DEBUG;
497 }
498
499 // load table again, with data and options (for last_editor).
500 $item = TablePress::$model_table->load( $item, true, true );
501
502 // Don't search corrupted tables, except when debug mode is enabled via $_GET parameter or WP_DEBUG constant.
503 if ( ! $debug && isset( $item['is_corrupted'] ) && $item['is_corrupted'] ) {
504 return false;
505 }
506
507 // Search from easy to hard, so that "expensive" code maybe doesn't have to run.
508 if ( false !== stripos( $item['id'], $term )
509 || false !== stripos( $item['name'], $term )
510 || false !== stripos( $item['description'], $term )
511 || false !== stripos( TablePress::get_user_display_name( $item['author'] ), $term )
512 || false !== stripos( TablePress::get_user_display_name( $item['options']['last_editor'] ), $term )
513 || false !== stripos( TablePress::format_datetime( $item['last_modified'] ), $term )
514 || false !== stripos( wp_json_encode( $item['data'], TABLEPRESS_JSON_OPTIONS ), $json_encoded_term ) ) {
515 return true;
516 }
517
518 return false;
519 }
520
521 /**
522 * Callback to for the array sort function.
523 *
524 * @since 1.0.0
525 *
526 * @param array $item_a First item that shall be compared to.
527 * @param array $item_b The second item for the comparison.
528 * @return int (-1, 0, 1) depending on which item sorts "higher".
529 */
530 protected function _order_callback( array $item_a, array $item_b ) {
531 global $orderby, $order;
532
533 if ( 'last_modified_by' !== $orderby ) {
534 if ( $item_a[ $orderby ] === $item_b[ $orderby ] ) {
535 return 0;
536 }
537 } else {
538 if ( $item_a['options']['last_editor'] === $item_b['options']['last_editor'] ) {
539 return 0;
540 }
541 }
542
543 // Certain fields require some extra work before being sortable.
544 switch ( $orderby ) {
545 case 'last_modified':
546 // Compare UNIX timestamps for "last modified", which actually is a mySQL datetime string.
547 $result = ( strtotime( $item_a['last_modified'] ) > strtotime( $item_b['last_modified'] ) ) ? 1 : -1;
548 break;
549 case 'author':
550 // Get the actual author name, plain value is just the user ID.
551 $result = strnatcasecmp( TablePress::get_user_display_name( $item_a['author'] ), TablePress::get_user_display_name( $item_b['author'] ) );
552 break;
553 case 'last_modified_by':
554 // Get the actual last editor name, plain value is just the user ID.
555 $result = strnatcasecmp( TablePress::get_user_display_name( $item_a['options']['last_editor'] ), TablePress::get_user_display_name( $item_b['options']['last_editor'] ) );
556 break;
557 default:
558 // Other fields (ID, name, description) are sorted as strings.
559 $result = strnatcasecmp( $item_a[ $orderby ], $item_b[ $orderby ] );
560 }
561
562 return ( 'asc' === $order ) ? $result : - $result;
563 }
564
565 /**
566 * Prepares the list of items for displaying, by maybe searching and sorting, and by doing pagination.
567 *
568 * @since 1.0.0
569 */
570 public function prepare_items() {
571 global $orderby, $order, $s;
572 wp_reset_vars( array( 'orderby', 'order', 's' ) );
573
574 // Maybe search in the items.
575 if ( $s ) {
576 $this->items = array_filter( $this->items, array( $this, '_search_callback' ) );
577 }
578
579 // Load actual tables after search for less memory consumption.
580 foreach ( $this->items as &$item ) {
581 // Don't load data, but load table options for access to last_editor.
582 $item = TablePress::$model_table->load( $item, false, true );
583 }
584 // Break reference in foreach iterator.
585 unset( $item );
586
587 // Maybe sort the items.
588 $_sortable_columns = $this->get_sortable_columns();
589 if ( $orderby && ! empty( $this->items ) && isset( $_sortable_columns[ "table_{$orderby}" ] ) ) {
590 usort( $this->items, array( $this, '_order_callback' ) );
591 }
592
593 // Number of records to show per page.
594 $per_page = $this->get_items_per_page( 'tablepress_list_per_page', 20 ); // Hard-coded, as in filter in Admin_Controller.
595 // Page number the user is currently viewing.
596 $current_page = $this->get_pagenum();
597 // Number of records in the array.
598 $total_items = count( $this->items );
599
600 // Slice items array to hold only items for the current page.
601 $this->items = array_slice( $this->items, ( ( $current_page - 1 ) * $per_page ), $per_page );
602
603 // Register pagination options and calculation results.
604 $this->set_pagination_args( array(
605 'total_items' => $total_items, // Total number of records/items.
606 'per_page' => $per_page, // Number of items per page.
607 'total_pages' => (int) ceil( $total_items / $per_page ), // Total number of pages.
608 ) );
609 }
610
611 } // class TablePress_All_Tables_List_Table
612