PluginProbe
TablePress – Tables in WordPress made easy / 3.0.4
TablePress – Tables in WordPress made easy v3.0.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 2.4.4 All 44 releases
← All changes | controllers/controller-admin.php +53 -43 2.4.33.0.4 View file →
@@ -27,9 +27,9 @@
27 27 *
28 28 * @since 1.0.0
29 29 * @var string[]
30 30 */
31 - protected $page_hooks = array();
31 + protected array $page_hooks = array();
32 32
33 33 /**
34 34 * Actions that have a view and admin menu or nav tab menu entry.
35 35 *
@@ -35,17 +35,16 @@
35 35 *
36 36 * @since 1.0.0
37 37 * @var array<string, array<string, bool|string>>
38 38 */
39 - protected $view_actions = array();
39 + protected array $view_actions = array();
40 40
41 41 /**
42 42 * Instance of the TablePress Admin View that is rendered.
43 43 *
44 44 * @since 1.0.0
45 - * @var TablePress_View
46 45 */
47 - protected $view;
46 + protected \TablePress_View $view;
48 47
49 48 /**
50 49 * Initialize the Admin Controller, determine location the admin menu, set up actions.
51 50 *
@@ -97,11 +96,11 @@
97 96
98 97 $this->init_view_actions();
99 98 $min_access_cap = $this->view_actions['list']['required_cap'];
100 99
101 - if ( $this->is_top_level_page ) {
102 - $icon_url = 'dashicons-list-view';
103 - switch ( $this->parent_page ) {
100 + if ( TablePress::$controller->is_top_level_page ) {
101 + $icon_url = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgdmlld0JveD0iLTMyIC0zMiA2NCA2NCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTAtMjUuODU0aC0yNS44NTR2NTEuNzA4aDUxLjcwOFYwSDIxdjIxaC00MnYtNDJIMFoiLz48cGF0aCBkPSJNLTE4LTE4aDEwdjEwaC0xMHpNLTE4LTVoMTBWNWgtMTB6TS01LTVINVY1SC01ek0tMTggOGgxMHYxMGgtMTB6TS01IDhINXYxMEgtNXpNOCA4aDEwdjEwSDh6TTUtMzFoNi4xOHY2LjE4SDV6TTE5LTI1aDYuMTh2Ni4xOEgxOXpNMC0xNWgzLjgydjMuODJIMHpNMTAtMjBoMy44MnYzLjgySDEwek0yNS0xMmgzLjgydjMuODJIMjV6TTgtMTNoMTB2MTBIOHoiLz48L3N2Zz4=';
102 + switch ( TablePress::$controller->parent_page ) {
104 103 case 'top':
105 104 $position = 3; // Position of Dashboard + 1.
106 105 break;
107 106 case 'bottom':
@@ -115,9 +114,9 @@
115 114 // Prevent overwriting existing menu entries.
116 115 while ( isset( $GLOBALS['menu'][ $position ] ) ) {
117 116 ++$position;
118 117 }
119 - add_menu_page( 'TablePress', $admin_menu_entry_name, $min_access_cap, 'tablepress', $callback, $icon_url, $position ); // @phpstan-ignore-line
118 + add_menu_page( 'TablePress', $admin_menu_entry_name, $min_access_cap, 'tablepress', $callback, $icon_url, $position ); // @phpstan-ignore argument.type
120 119 foreach ( $this->view_actions as $action => $entry ) {
121 120 if ( ! $entry['show_entry'] ) {
122 121 continue;
123 122 }
@@ -124,9 +123,9 @@
124 123 $slug = 'tablepress';
125 124 if ( 'list' !== $action ) {
126 125 $slug .= '_' . $action;
127 126 }
128 - // @phpstan-ignore-next-line
127 + // @phpstan-ignore argument.type, argument.type
129 128 $page_hook = add_submenu_page( 'tablepress', sprintf( __( '%1$s &lsaquo; %2$s', 'tablepress' ), $entry['page_title'], 'TablePress' ), $entry['admin_menu_title'], $entry['required_cap'], $slug, $callback );
130 129 if ( false !== $page_hook ) {
131 130 $this->page_hooks[] = $page_hook;
132 131 }
@@ -131,10 +130,10 @@
131 130 $this->page_hooks[] = $page_hook;
132 131 }
133 132 }
134 133 } else {
135 - // @phpstan-ignore-next-line
136 - $page_hook = add_submenu_page( $this->parent_page, 'TablePress', $admin_menu_entry_name, $min_access_cap, 'tablepress', $callback );
134 + // @phpstan-ignore argument.type
135 + $page_hook = add_submenu_page( TablePress::$controller->parent_page, 'TablePress', $admin_menu_entry_name, $min_access_cap, 'tablepress', $callback );
137 136 if ( false !== $page_hook ) {
138 137 $this->page_hooks[] = $page_hook;
139 138 }
140 139 }
@@ -179,13 +178,8 @@
179 178 add_action( 'admin_bar_menu', array( $this, 'add_wp_admin_bar_new_content_menu_entry' ), 71 );
180 179 }
181 180
182 181 add_action( 'load-plugins.php', array( $this, 'plugins_page' ) );
183 -
184 - // Add filters and actions for the integration into the WP WXR exporter and importer.
185 - add_action( 'wp_import_insert_post', array( TablePress::$model_table, 'add_table_id_on_wp_import' ), 10, 4 );
186 - add_filter( 'wp_import_post_meta', array( TablePress::$model_table, 'prevent_table_id_post_meta_import_on_wp_import' ), 10, 3 );
187 - add_filter( 'wxr_export_skip_postmeta', array( TablePress::$model_table, 'add_table_id_to_wp_export' ), 10, 3 );
188 182 }
189 183
190 184 /**
191 185 * Loads additional JavaScript code for the TablePress table block (in the block editor context).
@@ -192,8 +186,16 @@
192 186 *
193 187 * @since 2.2.0
194 188 */
195 189 public function enqueue_block_editor_assets(): void {
190 + /*
191 + * Register the `react-jsx-runtime` polyfill, if it is not already registered.
192 + * This is needed as a polyfill for WP < 6.6, and can be removed once WP 6.6 is the minimum requirement for TablePress.
193 + */
194 + if ( ! wp_script_is( 'react-jsx-runtime', 'registered' ) ) {
195 + wp_register_script( 'react-jsx-runtime', plugins_url( 'admin/js/react-jsx-runtime.min.js', TABLEPRESS__FILE__ ), array( 'react' ), TablePress::version, true );
196 + }
197 +
196 198 // Add table information for the block editor to the page.
197 199 $handle = generate_block_asset_handle( 'tablepress/table', 'editorScript' );
198 200 $data = $this->get_block_editor_data();
199 201 wp_add_inline_script( $handle, $data, 'before' );
@@ -206,9 +208,9 @@
206 208 */
207 209 public function enqueue_block_assets(): void {
208 210 // Load the TablePress default CSS and the user's "Custom CSS" in the block editor iframe.
209 211 if ( is_admin() ) {
210 - TablePress::$controller->enqueue_css();
212 + TablePress::$controller->maybe_enqueue_css();
211 213 }
212 214 }
213 215
214 216 /**
@@ -280,17 +282,17 @@
280 282 $url = TablePress::url( array( 'action' => 'list' ) );
281 283 }
282 284
283 285 return <<<JS
284 -// Ensure the global `tp` object exists.
285 -window.tp = window.tp || {};
286 -tp.url = '{$url}';
287 -tp.load_block_preview = {$load_block_preview};
288 -tp.table = {};
289 -tp.table.shortcode = '{$shortcode}';
290 -tp.table.template = JSON.parse( '{$template}' );
291 -tp.tables = JSON.parse( '{$tables}' );
292 -JS;
286 + // Ensure the global `tp` object exists.
287 + window.tp = window.tp || {};
288 + tp.url = '{$url}';
289 + tp.load_block_preview = {$load_block_preview};
290 + tp.table = {};
291 + tp.table.shortcode = '{$shortcode}';
292 + tp.table.template = JSON.parse( '{$template}' );
293 + tp.tables = JSON.parse( '{$tables}' );
294 + JS;
293 295 }
294 296
295 297 /**
296 298 * Register actions to add "Table" button to "HTML editor" and "Visual editor" toolbars.
@@ -318,9 +320,9 @@
318 320 'title' => __( 'Insert a TablePress table', 'tablepress' ),
319 321 'thickbox_title' => __( 'Insert a TablePress table', 'tablepress' ),
320 322 'thickbox_url' => TablePress::url( array( 'action' => 'editor_button_thickbox' ), true, 'admin-post.php' ),
321 323 ),
322 - )
324 + ),
323 325 );
324 326
325 327 // TinyMCE integration.
326 328 if ( user_can_richedit() ) {
@@ -374,9 +376,9 @@
374 376
375 377 $wp_admin_bar->add_menu( array(
376 378 'parent' => 'new-content',
377 379 'id' => 'new-tablepress-table',
378 - 'title' => __( 'TablePress Table', 'tablepress' ),
380 + 'title' => __( 'TablePress table', 'tablepress' ),
379 381 'href' => TablePress::url( array( 'action' => 'add' ) ),
380 382 ) );
381 383 }
382 384
@@ -393,8 +395,9 @@
393 395 'tablepress-datatables-alphabetsearch/tablepress-datatables-alphabetsearch.php',
394 396 'tablepress-datatables-column-filter-widgets/tablepress-datatables-column-filter-widgets.php',
395 397 'tablepress-datatables-columnfilter/tablepress-datatables-columnfilter.php',
396 398 'tablepress-datatables-fixedcolumns/tablepress-datatables-fixedcolumns.php',
399 + 'tablepress-datatables-inverted-filter/tablepress-datatables-inverted-filter.php',
397 400 'tablepress-datatables-row-details/tablepress-datatables-row-details.php',
398 401 'tablepress-datatables-rowgroup/tablepress-datatables-rowgroup.php',
399 402 'tablepress-responsive-tables/tablepress-responsive-tables.php',
400 403 );
@@ -460,9 +463,9 @@
460 463 if ( tb_tp_fs()->is_free_plan() ) {
461 464 echo '<p style="font-size:14px;">';
462 465 _e( 'This TablePress Extension was retired.', 'tablepress' );
463 466 echo ' ';
464 - _e( '<strong>The plugin will stop working with TablePress 3 later this year</strong> and will no longer receive updates or support!', 'tablepress' );
467 + _e( '<strong>The plugin does no longer work with TablePress 3</strong> and will no longer receive updates or support!', 'tablepress' );
465 468 echo '<br>';
466 469 _e( 'Keeping it activated can lead to errors on your website!', 'tablepress' );
467 470 echo ' <strong>' . sprintf( __( '<a href="%s">Find out what you can do to continue using its features!</a>', 'tablepress' ), 'https://tablepress.org/upgrade-extensions/?utm_source=plugin&utm_medium=textlink&utm_content=plugins-list-table' ) . '</strong>';
468 471 echo '</p>';
@@ -492,9 +495,9 @@
492 495 */
493 496 public function load_admin_page(): void {
494 497 // Determine the action from either the GET parameter (for sub-menu entries, and the main admin menu entry).
495 498 $action = ( ! empty( $_GET['action'] ) ) ? $_GET['action'] : 'list'; // Default action is list.
496 - if ( $this->is_top_level_page ) {
499 + if ( TablePress::$controller->is_top_level_page ) {
497 500 // Or, for sub-menu entry of an admin menu "TablePress" entry, get it from the "page" GET parameter.
498 501 if ( 'tablepress' !== $_GET['page'] ) {
499 502 // Actions that are top-level entries, but don't have an action GET parameter (action is after last _ in string).
500 503 $action = substr( $_GET['page'], 11 ); // $_GET['page'] has the format 'tablepress_{$action}'
@@ -501,9 +504,9 @@
501 504 }
502 505 }
503 506
504 507 // Check if action is a supported action, and whether the user is allowed to access this screen.
505 - if ( ! isset( $this->view_actions[ $action ] ) || ! current_user_can( $this->view_actions[ $action ]['required_cap'] ) ) { // @phpstan-ignore-line (The array value for the capability is always a string.)
508 + if ( ! isset( $this->view_actions[ $action ] ) || ! current_user_can( $this->view_actions[ $action ]['required_cap'] ) ) { // @phpstan-ignore argument.type (The array value for the capability is always a string.)
506 509 wp_die( __( 'Sorry, you are not allowed to access this page.', 'default' ), 403 );
507 510 }
508 511
509 512 // Don't load TablePress assets on the Freemius opt-in/activation screen.
@@ -551,9 +554,9 @@
551 554 * (called here, as the credentials form posts to this handler again, due to how `request_filesystem_credentials()` works)
552 555 */
553 556 if ( isset( $_GET['item'] ) && 'save_custom_css' === $_GET['item'] ) {
554 557 TablePress::check_nonce( 'options', $_GET['item'] ); // Nonce check here, as we don't have an explicit handler, and even viewing the screen needs to be checked.
555 - $action = 'options_custom_css'; // to load a different view
558 + $action = 'options_custom_css'; // To load a different view.
556 559 // Try saving "Custom CSS" to a file, otherwise this gets the HTML for the credentials form.
557 560 $tablepress_css = TablePress::load_class( 'TablePress_CSS', 'class-css.php', 'classes' );
558 561 $result = $tablepress_css->save_custom_css_to_file_plugin_options( TablePress::$model_options->get( 'custom_css' ), TablePress::$model_options->get( 'custom_css_minified' ) );
559 562 if ( is_string( $result ) ) {
@@ -574,9 +577,9 @@
574 577 break;
575 578 }
576 579 $data['frontend_options']['use_custom_css'] = TablePress::$model_options->get( 'use_custom_css' );
577 580 $data['frontend_options']['custom_css'] = TablePress::$model_options->get( 'custom_css' );
578 - $data['user_options']['parent_page'] = $this->parent_page;
581 + $data['user_options']['parent_page'] = TablePress::$controller->parent_page;
579 582 break;
580 583 case 'edit':
581 584 if ( empty( $_GET['table_id'] ) ) {
582 585 TablePress::redirect( array( 'action' => 'list', 'message' => 'error_no_table' ) );
@@ -868,10 +871,10 @@
868 871
869 872 $add_table = wp_unslash( $_POST['table'] );
870 873
871 874 // Perform confidence checks of posted data.
872 - $name = ( isset( $add_table['name'] ) ) ? $add_table['name'] : '';
873 - $description = ( isset( $add_table['description'] ) ) ? $add_table['description'] : '';
875 + $name = $add_table['name'] ?? '';
876 + $description = $add_table['description'] ?? '';
874 877 if ( ! isset( $add_table['rows'], $add_table['columns'] ) ) {
875 878 TablePress::redirect( array( 'action' => 'add', 'message' => 'error_add', 'error_details' => 'The HTTP POST data does not contain the table size.' ) );
876 879 }
877 880
@@ -931,10 +934,10 @@
931 934 if ( ! empty( $posted_options['admin_menu_parent_page'] ) && '-' !== $posted_options['admin_menu_parent_page'] ) {
932 935 $new_options['admin_menu_parent_page'] = $posted_options['admin_menu_parent_page'];
933 936 // Re-init parent information, as `TablePress::redirect()` URL might be wrong otherwise.
934 937 /** This filter is documented in classes/class-controller.php */
935 - $this->parent_page = apply_filters( 'tablepress_admin_menu_parent_page', $posted_options['admin_menu_parent_page'] );
936 - $this->is_top_level_page = in_array( $this->parent_page, array( 'top', 'middle', 'bottom' ), true );
938 + TablePress::$controller->parent_page = apply_filters( 'tablepress_admin_menu_parent_page', $posted_options['admin_menu_parent_page'] );
939 + TablePress::$controller->is_top_level_page = in_array( TablePress::$controller->parent_page, array( 'top', 'middle', 'bottom' ), true );
937 940 }
938 941
939 942 // Custom CSS can only be saved if the user is allowed to do so.
940 943 $update_custom_css_files = false;
@@ -945,13 +948,20 @@
945 948 if ( isset( $posted_options['custom_css'] ) ) {
946 949 $new_options['custom_css'] = $posted_options['custom_css'];
947 950
948 951 $tablepress_css = TablePress::load_class( 'TablePress_CSS', 'class-css.php', 'classes' );
949 - // Sanitize and tidy up Custom CSS.
950 - $new_options['custom_css'] = $tablepress_css->sanitize_css( $new_options['custom_css'] );
951 - // Minify Custom CSS.
952 - $new_options['custom_css_minified'] = $tablepress_css->minify_css( $new_options['custom_css'] );
953 952
953 + if ( '' !== $new_options['custom_css'] ) {
954 + // Update "Custom CSS" to use DataTables 2 variants instead of old DataTables 1.x CSS classes.
955 + $new_options['custom_css'] = TablePress::convert_datatables_api_data( $new_options['custom_css'] );
956 + // Sanitize and tidy up Custom CSS.
957 + $new_options['custom_css'] = $tablepress_css->sanitize_css( $new_options['custom_css'] );
958 + // Minify Custom CSS.
959 + $new_options['custom_css_minified'] = $tablepress_css->minify_css( $new_options['custom_css'] );
960 + } else {
961 + $new_options['custom_css_minified'] = '';
962 + }
963 +
954 964 // Maybe update CSS files as well.
955 965 $custom_css_file_contents = $tablepress_css->load_custom_css_from_file( 'normal' );
956 966 if ( false === $custom_css_file_contents ) {
957 967 $custom_css_file_contents = '';
@@ -1078,9 +1088,9 @@
1078 1088 /** This filter is documented in controllers/controller-admin.php */
1079 1089 $download_filename = apply_filters( 'tablepress_export_filename', $download_filename, '', '', $export['format'], $export_to_zip );
1080 1090 $download_filename = sanitize_file_name( $download_filename );
1081 1091 $full_filename = wp_tempnam( $download_filename );
1082 - if ( true !== $zip_file->open( $full_filename, ZIPARCHIVE::OVERWRITE ) ) {
1092 + if ( true !== $zip_file->open( $full_filename, ZipArchive::OVERWRITE ) ) {
1083 1093 @unlink( $full_filename ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
1084 1094 TablePress::redirect( array( 'action' => 'export', 'message' => 'error_create_zip_file', 'export_format' => $export['format'], 'csv_delimiter' => $export['csv_delimiter'], 'error_details' => 'The ZIP file could not be opened for writing.' ) );
1085 1095 }
1086 1096
@@ -1110,9 +1120,9 @@
1110 1120 }
1111 1121
1112 1122 // If something went wrong, or no files were added to the ZIP file, bail out.
1113 1123 // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
1114 - if ( ZIPARCHIVE::ER_OK !== $zip_file->status || 0 === $zip_file->numFiles ) {
1124 + if ( ZipArchive::ER_OK !== $zip_file->status || 0 === $zip_file->numFiles ) {
1115 1125 $zip_file->close();
1116 1126 @unlink( $full_filename ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
1117 1127 TablePress::redirect( array( 'action' => 'export', 'message' => 'error_create_zip_file', 'export_format' => $export['format'], 'csv_delimiter' => $export['csv_delimiter'], 'error_details' => 'The ZIP file could not be written or is empty.' ) );
1118 1128 }