PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
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
← All changes | views/view-editor_button_thickbox.php +54 -418 1.9.2 → 3.4 View file →
@@ -7,13 +7,16 @@
7 7 * @author Tobias Bäthge
8 8 * @since 1.0.0
9 9 */
10 10
11 +declare(strict_types=1);
12 +
11 13 // Prohibit direct script loading.
12 14 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
13 15
14 16 /**
15 17 * Editor Button Thickbox List View class
18 + *
16 19 * @package TablePress
17 20 * @subpackage Views
18 21 * @author Tobias Bäthge
19 22 * @since 1.0.0
@@ -23,14 +26,13 @@
23 26 /**
24 27 * Object for the Editor Button Thickbox List Table.
25 28 *
26 29 * @since 1.0.0
27 - * @var TablePress_Editor_Button_Thickbox_List_Table
28 30 */
29 - protected $wp_list_table;
31 + protected \TablePress_Editor_Button_Thickbox_List_Table $wp_list_table;
30 32
31 33 /**
32 - * Initialize the View class.
34 + * Initializes the View class.
33 35 *
34 36 * @since 1.0.0
35 37 */
36 38 public function __construct() {
@@ -37,81 +39,58 @@
37 39 // Intentionally left empty, to void code from parent::__construct().
38 40 }
39 41
40 42 /**
41 - * Set up the view with data and do things that are specific for this view.
43 + * Sets up the view with data and do things that are specific for this view.
42 44 *
43 45 * @since 1.0.0
44 46 *
45 - * @param string $action Action for this view.
46 - * @param array $data Data for this view.
47 + * @param string $action Action for this view.
48 + * @param array<string, mixed> $data Data for this view.
47 49 */
48 - public function setup( $action, array $data ) {
50 + #[\Override]
51 + public function setup( /* string */ $action, array $data ) /* : void */ {
52 + // Don't use type hints in the method declaration to prevent PHP errors, as the method is inherited.
53 +
49 54 $this->action = $action;
50 55 $this->data = $data;
51 56
52 - $this->wp_list_table = new TablePress_Editor_Button_Thickbox_List_Table();
57 + $this->wp_list_table = TablePress::load_class( 'TablePress_Editor_Button_Thickbox_List_Table', 'class-editor-button-thickbox-list-table.php', 'views' );
58 +
53 59 $this->wp_list_table->set_items( $this->data['table_ids'] );
54 60 $this->wp_list_table->prepare_items();
55 61 }
56 62
57 63 /**
58 - * Render the current view.
64 + * Renders the current view.
59 65 *
60 66 * @since 1.0.0
61 67 */
62 - public function render() {
68 + #[\Override]
69 + public function render(): void {
63 70 _wp_admin_html_begin();
64 71
65 72 wp_print_styles( 'colors' );
66 73 wp_print_scripts( 'jquery-core' );
67 -?>
68 -<title><?php printf( __( '%1$s &lsaquo; %2$s', 'tablepress' ), __( 'List of Tables', 'tablepress' ), 'TablePress' ); ?></title>
69 -<style type="text/css">
70 -/* Account for .wp-toolbar */
74 + ?>
75 +<title><?php /* translators: %1$s: Page title, %2$s: Plugin name */ printf( __( '%1$s &lsaquo; %2$s', 'tablepress' ), __( 'List of Tables', 'tablepress' ), 'TablePress' ); ?></title>
76 +<style>
77 +/* Account for .wp-toolbar. */
71 78 html {
72 79 padding-top: 0 !important;
73 80 }
74 -body {
75 - margin: 0 0 15px 15px;
81 +#tablepress-page {
82 + margin: 0 15px;
83 + padding: 0 0 15px 0;
76 84 }
77 -
78 -/* Fix search field positioning */
79 -#tablepress-page .search-box {
80 - position: relative;
81 - height: auto;
82 - width: auto;
83 - float: right;
84 - clear: none;
85 - margin: 0;
86 -}
87 85 #tablepress-page .subtitle {
88 86 float: left;
89 87 padding: 10px 0 0;
90 88 }
91 -#tablepress-page .search-box input[name="s"] {
92 - float: left;
93 - width: auto;
89 +#tablepress-page p.search-box {
90 + position: relative;
94 91 }
95 -
96 -/* Fix pagination layout */
97 -#tablepress-page .tablenav-pages {
98 - text-align: left;
99 -}
100 -#tablepress-page .tablenav .tablenav-pages a {
101 - padding: 5px 12px;
102 - font-size: 16px;
103 -}
104 -#tablepress-page .tablenav-pages .pagination-links .paging-input {
105 - font-size: 16px;
106 -}
107 -
108 -#tablepress-page .tablenav-pages .pagination-links .current-page {
109 - padding: 4px;
110 - font-size: 16px;
111 -}
112 -
113 -/* Width and font weight for the columns */
92 +/* Width and font weight for the columns. */
114 93 .tablepress-editor-button-list thead .column-table_id {
115 94 width: 50px;
116 95 }
117 96 .tablepress-editor-button-list tbody .column-table_id,
@@ -118,11 +97,11 @@
118 97 .tablepress-editor-button-list tbody .column-table_name {
119 98 font-weight: bold;
120 99 }
121 100 .tablepress-editor-button-list thead .column-table_action {
122 - width: 150px;
101 + min-width: 150px;
123 102 }
124 -/* Responsiveness on the All Tables screen */
103 +/* Responsiveness on the All Tables screen. */
125 104 @media screen and (max-width: 782px) {
126 105 .tablepress-editor-button-list .column-table_id {
127 106 display: none !important;
128 107 padding: 3px 8px 3px 35%;
@@ -127,396 +106,53 @@
127 106 display: none !important;
128 107 padding: 3px 8px 3px 35%;
129 108 }
130 109 }
131 -
132 -/* Shortcode input field */
133 -#tablepress-page .table-shortcode-inline {
134 - background: transparent;
135 - border: none;
136 - color: #333333;
137 - width: 110px;
138 - margin: 0;
139 - padding: 0;
140 - font-weight: bold;
141 - font-size: 14px;
142 - -webkit-box-shadow: none;
143 - box-shadow: none;
144 - text-align: center;
145 - vertical-align: top;
146 -}
147 -#tablepress-page .table-shortcode {
148 - cursor: text;
149 -}
150 -<?php if ( is_rtl() ) : ?>
110 + <?php if ( is_rtl() ) : ?>
151 111 /* RTL CSS */
152 -body.rtl {
153 - margin: 0 15px 15px 0;
154 -}
155 -.rtl #tablepress-page .search-box {
156 - float: left;
157 -}
158 112 .rtl #tablepress-page .subtitle {
159 113 float: right;
160 114 }
161 -.rtl #tablepress-page .search-box input[name="s"] {
162 - float: right;
163 -}
164 -.rtl #tablepress-page .table-shortcode-inline {
165 - width: 125px;
166 - font-size: 13px;
167 - vertical-align: baseline;
168 -}
169 115 <?php endif; ?>
170 116 </style>
171 117 </head>
172 -<body class="wp-admin wp-core-ui js iframe<?php echo is_rtl() ? ' rtl' : ''; ?>">
118 +<body class="wp-admin wp-core-ui js iframe <?php echo 'admin-color-' . sanitize_html_class( get_user_option( 'admin_color' ), 'modern' ) . ( is_rtl() ? ' rtl' : '' ); ?>">
173 119 <div id="tablepress-page" class="wrap">
174 -<h1><?php printf( __( '%1$s &lsaquo; %2$s', 'tablepress' ), __( 'List of Tables', 'tablepress' ), 'TablePress' ); ?></h1>
120 +<h1><?php /* translators: %1$s: Page title, %2$s: Plugin name */ printf( __( '%1$s &lsaquo; %2$s', 'tablepress' ), __( 'List of Tables', 'tablepress' ), 'TablePress' ); ?></h1>
175 121 <div id="poststuff">
176 -<p>
177 -<?php _e( 'This is a list of all available tables.', 'tablepress' ); ?> <?php _e( 'You may insert a table into a post or page here.', 'tablepress' ); ?>
178 -</p><p>
179 -<?php printf( __( 'Click the &#8220;%1$s&#8221; button for the desired table to automatically insert the<br />corresponding Shortcode (%2$s) into the editor.', 'tablepress' ), __( 'Insert Shortcode', 'tablepress' ), '<input type="text" class="table-shortcode table-shortcode-inline ltr" value="' . esc_attr( '[' . TablePress::$shortcode . ' id=<ID> /]' ) . '" readonly="readonly" />' ); ?>
180 -</p>
181 -<?php
182 - if ( ! empty( $_GET['s'] ) ) {
183 - printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'tablepress' ) . '</span>', esc_html( wp_unslash( $_GET['s'] ) ) );
184 - }
185 -?>
186 -<form method="get" action="">
187 - <input type="hidden" name="action" value="tablepress_<?php echo $this->action; ?>" />
188 -<?php
189 - wp_nonce_field( TablePress::nonce( $this->action ), '_wpnonce', false );
190 - $this->wp_list_table->search_box( __( 'Search Tables', 'tablepress' ), 'tables_search' );
191 -?>
122 +<p><?php _e( 'This is a list of your tables.', 'tablepress' ); ?> <?php _e( 'You may insert a table into a post or page here.', 'tablepress' ); ?></p>
123 +<p><?php printf( __( 'Click the “%1$s” button for the desired table to automatically insert its Shortcode into the editor.', 'tablepress' ), __( 'Insert Shortcode', 'tablepress' ) ); ?></p>
124 + <?php
125 + if ( ! empty( $_GET['s'] ) ) {
126 + printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'tablepress' ) . '</span>', esc_html( wp_unslash( $_GET['s'] ) ) );
127 + }
128 + ?>
129 +<form method="get">
130 + <input type="hidden" name="action" value="tablepress_<?php echo $this->action; ?>">
131 + <?php
132 + wp_nonce_field( TablePress::nonce( $this->action ), '_wpnonce', false );
133 + $this->wp_list_table->search_box( __( 'Search Tables', 'tablepress' ), 'tables_search' );
134 + ?>
192 135 </form>
193 - <?php $this->wp_list_table->display(); ?>
136 + <?php $this->wp_list_table->display(); ?>
194 137 </div>
195 138 </div>
196 -<script type="text/javascript">
197 -jQuery( document ).ready( function( $ ) {
198 - // Toggle list table rows on small screens
139 +<script>
140 +jQuery( function( $ ) {
141 + // Toggle list table rows on small screens.
199 142 $( '.tablepress-editor-button-list' )
200 - .on( 'click', '.toggle-row', function() {
201 - $( this ).closest( 'tr' ).toggleClass( 'is-expanded' );
143 + .on( 'click', 'tr', function() {
144 + this.classList.toggle( 'is-expanded' );
202 145 })
203 146 .on( 'click', '.insert-shortcode', function() {
204 - var win = window.dialogArguments || opener || parent || top;
205 - win.send_to_editor( $(this).attr( 'title' ) );
147 + const win = window.dialogArguments || opener || parent || top;
148 + win.send_to_editor( this.title );
206 149 } );
207 150 } );
208 151 </script>
209 152 </body>
210 153 </html>
211 -<?php
154 + <?php
212 155 }
213 156
214 157 } // class TablePress_Editor_Button_View
215 158
216 -/**
217 - * TablePress Editor Button Thickbox List Table Class
218 - * @package TablePress
219 - * @subpackage Views
220 - * @author Tobias Bäthge
221 - * @link https://codex.wordpress.org/Class_Reference/WP_List_Table
222 - * @since 1.0.0
223 - */
224 -class TablePress_Editor_Button_Thickbox_List_Table extends WP_List_Table {
225 -
226 - /**
227 - * Number of items of the initial data set (before sort, search, and pagination).
228 - *
229 - * @since 1.0.0
230 - * @var int
231 - */
232 - protected $items_count = 0;
233 -
234 - /**
235 - * Initialize the List Table.
236 - *
237 - * @since 1.0.0
238 - */
239 - public function __construct() {
240 - parent::__construct( array(
241 - 'singular' => 'tablepress-table', // Singular name of the listed records.
242 - 'plural' => 'tablepress-editor-button-list', // Plural name of the listed records.
243 - 'ajax' => false, // Does this list table support AJAX?
244 - 'screen' => get_current_screen(), // WP_Screen object.
245 - ) );
246 - }
247 -
248 - /**
249 - * Set the data items (here: tables) that are to be displayed by the List Tables, and their original count.
250 - *
251 - * @since 1.0.0
252 - *
253 - * @param array $items Tables to be displayed in the List Table.
254 - */
255 - public function set_items( array $items ) {
256 - $this->items = $items;
257 - $this->items_count = count( $items );
258 - }
259 -
260 - /**
261 - * Check whether the user has permissions for certain AJAX actions.
262 - * (not used, but must be implemented in this child class)
263 - *
264 - * @since 1.0.0
265 - *
266 - * @return bool true (Default value).
267 - */
268 - public function ajax_user_can() {
269 - return true;
270 - }
271 -
272 - /**
273 - * Get a list of columns in this List Table.
274 - *
275 - * Format: 'internal-name' => 'Column Title'.
276 - *
277 - * @since 1.0.0
278 - *
279 - * @return array List of columns in this List Table.
280 - */
281 - public function get_columns() {
282 - $columns = array(
283 - // "name" is special in WP, which is why we prefix every entry here, to be safe!
284 - 'table_id' => __( 'ID', 'tablepress' ),
285 - 'table_name' => __( 'Table Name', 'tablepress' ),
286 - 'table_description' => __( 'Description', 'tablepress' ),
287 - 'table_action' => __( 'Action', 'tablepress' ),
288 - );
289 - return $columns;
290 - }
291 -
292 - /**
293 - * Get a list of columns that are sortable.
294 - *
295 - * Format: 'internal-name' => array( $field for $item[ $field ], true for already sorted ).
296 - *
297 - * @since 1.0.0
298 - *
299 - * @return array List of sortable columns in this List Table.
300 - */
301 - protected function get_sortable_columns() {
302 - // No sorting on the Empty List placeholder.
303 - if ( ! $this->has_items() ) {
304 - return array();
305 - }
306 -
307 - $sortable_columns = array(
308 - 'table_id' => array( 'id', true ), // true means its already sorted
309 - 'table_name' => array( 'name', false ),
310 - 'table_description' => array( 'description', false ),
311 - );
312 - return $sortable_columns;
313 - }
314 -
315 - /**
316 - * Gets the name of the default primary column.
317 - *
318 - * @since 1.7.0
319 - *
320 - * @return string Name of the default primary column, in this case, the table name.
321 - */
322 - protected function get_default_primary_column_name() {
323 - return 'table_name';
324 - }
325 -
326 - /**
327 - * Render a cell in the "table_id" column.
328 - *
329 - * @since 1.0.0
330 - *
331 - * @param array $item Data item for the current row.
332 - * @return string HTML content of the cell.
333 - */
334 - protected function column_table_id( array $item ) {
335 - return esc_html( $item['id'] );
336 - }
337 -
338 - /**
339 - * Render a cell in the "table_name" column.
340 - *
341 - * @since 1.0.0
342 - *
343 - * @param array $item Data item for the current row.
344 - * @return string HTML content of the cell.
345 - */
346 - protected function column_table_name( array $item ) {
347 - if ( '' === trim( $item['name'] ) ) {
348 - $item['name'] = __( '(no name)', 'tablepress' );
349 - }
350 - return esc_html( $item['name'] );
351 - }
352 -
353 - /**
354 - * Render a cell in the "table_description" column.
355 - *
356 - * @since 1.0.0
357 - *
358 - * @param array $item Data item for the current row.
359 - * @return string HTML content of the cell.
360 - */
361 - protected function column_table_description( array $item ) {
362 - if ( '' === trim( $item['description'] ) ) {
363 - $item['description'] = __( '(no description)', 'tablepress' );
364 - }
365 - return esc_html( $item['description'] );
366 - }
367 -
368 - /**
369 - * Render a cell in the "table_action" column, i.e. the "Insert" link.
370 - *
371 - * @since 1.0.0
372 - *
373 - * @param array $item Data item for the current row.
374 - * @return string HTML content of the cell.
375 - */
376 - protected function column_table_action( array $item ) {
377 - return '<input type="button" class="insert-shortcode button" title="' . esc_attr( '[' . TablePress::$shortcode . " id={$item['id']} /]" ) . '" value="' . esc_attr__( 'Insert Shortcode', 'tablepress' ) . '" />';
378 - }
379 -
380 - /**
381 - * Holds the message to be displayed when there are no items in the table.
382 - *
383 - * @since 1.0.0
384 - */
385 - public function no_items() {
386 - _e( 'No tables found.', 'tablepress' );
387 - if ( 0 === $this->items_count ) {
388 - echo ' ' . __( 'You should add or import a table on the TablePress screens to get started!', 'tablepress' );
389 - }
390 - }
391 -
392 - /**
393 - * Generate the elements above or below the table (like bulk actions and pagination).
394 - *
395 - * In comparison with parent class, this has modified HTML (no nonce field), and a check whether there are items.
396 - *
397 - * @since 1.0.0
398 - *
399 - * @param string $which Location ("top" or "bottom").
400 - */
401 - protected function display_tablenav( $which ) {
402 - if ( ! $this->has_items() ) {
403 - return;
404 - }
405 - ?>
406 - <div class="tablenav <?php echo esc_attr( $which ); ?>">
407 - <div class="alignleft actions">
408 - <?php $this->bulk_actions( $which ); ?>
409 - </div>
410 - <?php
411 - $this->extra_tablenav( $which );
412 - $this->pagination( $which );
413 - ?>
414 - <br class="clear" />
415 - </div>
416 - <?php
417 - }
418 -
419 - /**
420 - * Callback to determine whether the given $item contains the search term.
421 - *
422 - * @since 1.0.0
423 - *
424 - * @param string $item Table ID that shall be searched.
425 - * @return bool Whether the search term was found or not.
426 - */
427 - protected function _search_callback( $item ) {
428 - static $term, $json_encoded_term;
429 - if ( is_null( $term ) || is_null( $json_encoded_term ) ) {
430 - $term = wp_unslash( $_GET['s'] );
431 - $json_encoded_term = substr( wp_json_encode( $term, TABLEPRESS_JSON_OPTIONS ), 1, -1 );
432 - }
433 -
434 - // Load table again, with table data, but without options and visibility settings.
435 - $item = TablePress::$model_table->load( $item, true, false );
436 -
437 - if ( isset( $item['is_corrupted'] ) && $item['is_corrupted'] ) {
438 - return false; // Don't search corrupted tables
439 - }
440 -
441 - // Search from easy to hard, so that "expensive" code maybe doesn't have to run.
442 - if ( false !== stripos( $item['id'], $term )
443 - || false !== stripos( $item['name'], $term )
444 - || false !== stripos( $item['description'], $term )
445 - || false !== stripos( TablePress::get_user_display_name( $item['author'] ), $term )
446 - || false !== stripos( TablePress::format_datetime( $item['last_modified'], 'mysql', ' ' ), $term )
447 - || false !== stripos( wp_json_encode( $item['data'], TABLEPRESS_JSON_OPTIONS ), $json_encoded_term ) ) {
448 - return true;
449 - }
450 -
451 - return false;
452 - }
453 -
454 - /**
455 - * Callback to for the array sort function.
456 - *
457 - * @since 1.0.0
458 - *
459 - * @param array $item_a First item that shall be compared to.
460 - * @param array $item_b The second item for the comparison.
461 - * @return int (-1, 0, 1) depending on which item sorts "higher".
462 - */
463 - protected function _order_callback( array $item_a, array $item_b ) {
464 - global $orderby, $order;
465 -
466 - if ( $item_a[ $orderby ] === $item_b[ $orderby ] ) {
467 - return 0;
468 - }
469 -
470 - // Fields in this list table are all strings.
471 - $result = strnatcasecmp( $item_a[ $orderby ], $item_b[ $orderby ] );
472 -
473 - return ( 'asc' === $order ) ? $result : - $result;
474 - }
475 -
476 - /**
477 - * Prepares the list of items for displaying, by maybe searching and sorting, and by doing pagination.
478 - *
479 - * @since 1.0.0
480 - */
481 - public function prepare_items() {
482 - global $orderby, $order, $s;
483 - wp_reset_vars( array( 'orderby', 'order', 's' ) );
484 -
485 - // Maybe search in the items.
486 - if ( $s ) {
487 - $this->items = array_filter( $this->items, array( $this, '_search_callback' ) );
488 - }
489 -
490 - // Load actual tables after search for less memory consumption.
491 - foreach ( $this->items as &$item ) {
492 - // Don't load data nor table options.
493 - $item = TablePress::$model_table->load( $item, false, false );
494 - }
495 - // Break reference in foreach iterator.
496 - unset( $item );
497 -
498 - // Maybe sort the items.
499 - $_sortable_columns = $this->get_sortable_columns();
500 - if ( $orderby && ! empty( $this->items ) && isset( $_sortable_columns[ "table_{$orderby}" ] ) ) {
501 - usort( $this->items, array( $this, '_order_callback' ) );
502 - }
503 -
504 - // Number of records to show per page.
505 - $per_page = 15; // hard-coded, as there's no possibility to change this in the Thickbox
506 - // Page number the user is currently viewing.
507 - $current_page = $this->get_pagenum();
508 - // Number of records in the array.
509 - $total_items = count( $this->items );
510 -
511 - // Slice items array to hold only items for the current page.
512 - $this->items = array_slice( $this->items, ( ( $current_page - 1 ) * $per_page ), $per_page );
513 -
514 - // Register pagination options and calculation results.
515 - $this->set_pagination_args( array(
516 - 'total_items' => $total_items, // Total number of records/items
517 - 'per_page' => $per_page, // Number of items per page
518 - 'total_pages' => ceil( $total_items / $per_page ), // Total number of pages
519 - ) );
520 - }
521 -
522 -} // class TablePress_Editor_Button_Thickbox_List_Table