| @@ -7,8 +7,10 @@ | ||
| 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 | /** |
| @@ -93,8 +95,12 @@ | ||
| 93 | 95 | * @param string $entry_name The admin menu entry name. Default "TablePress". |
| 94 | 96 | */ |
| 95 | 97 | $admin_menu_entry_name = apply_filters( 'tablepress_admin_menu_entry_name', 'TablePress' ); |
| 96 | 98 | |
| 99 | + if ( TablePress::$model_options->get( 'message_plugin_update' ) && strtotime( '2026-10-10' ) >= strtotime( 'today' ) ) { | |
| 100 | + $admin_menu_entry_name .= ' <span class="dashicons dashicons-buddicons-community" aria-hidden="true" style="color:orange"></span>'; | |
| 101 | + } | |
| 102 | + | |
| 97 | 103 | $this->init_view_actions(); |
| 98 | 104 | $min_access_cap = $this->view_actions['list']['required_cap']; |
| 99 | 105 | |
| 100 | 106 | if ( TablePress::$controller->is_top_level_page ) { |
| @@ -525,9 +531,9 @@ | ||
| 525 | 531 | |
| 526 | 532 | // Depending on the action, load more necessary data for the corresponding view. |
| 527 | 533 | switch ( $action ) { |
| 528 | 534 | case 'list': |
| 529 | - $data['table_id'] = ( ! empty( $_GET['table_id'] ) ) ? $_GET['table_id'] : false; | |
| 535 | + $data['table_id'] = ( isset( $_GET['table_id'] ) ) ? preg_replace( '/[^a-zA-Z0-9_-]/', '', $_GET['table_id'] ) : false; | |
| 530 | 536 | // Prime the post meta cache for cached loading of last_editor. |
| 531 | 537 | $data['table_ids'] = TablePress::$model_table->load_all( true ); |
| 532 | 538 | $data['messages']['donation_nag'] = $this->maybe_show_donation_message(); |
| 533 | 539 | $data['messages']['first_visit'] = ! $data['messages']['donation_nag'] && TablePress::$model_options->get( 'message_first_visit' ); |
| @@ -570,9 +576,9 @@ | ||
| 570 | 576 | $data['frontend_options']['custom_css'] = TablePress::$model_options->get( 'custom_css' ); |
| 571 | 577 | $data['user_options']['parent_page'] = TablePress::$controller->parent_page; |
| 572 | 578 | break; |
| 573 | 579 | case 'edit': |
| 574 | - if ( empty( $_GET['table_id'] ) ) { | |
| 580 | + if ( ! isset( $_GET['table_id'] ) || ! preg_match( '/^[a-zA-Z0-9_-]+$/', $_GET['table_id'] ) ) { | |
| 575 | 581 | TablePress::redirect( array( 'action' => 'list', 'message' => 'error_no_table' ) ); |
| 576 | 582 | } |
| 577 | 583 | // Load table, with table data, options, and visibility settings. |
| 578 | 584 | $data['table'] = TablePress::$model_table->load( $_GET['table_id'], true, true ); |
| @@ -601,9 +607,9 @@ | ||
| 601 | 607 | |
| 602 | 608 | $data['tables'][ $table['id'] ] = $table['name']; |
| 603 | 609 | } |
| 604 | 610 | $data['tables_count'] = TablePress::$model_table->count_tables(); |
| 605 | - $data['export_ids'] = ( ! empty( $_GET['table_id'] ) ) ? explode( ',', $_GET['table_id'] ) : array(); | |
| 611 | + $data['export_ids'] = ( isset( $_GET['table_id'] ) && preg_match( '/^[,a-zA-Z0-9_-]+$/', $_GET['table_id'] ) ) ? explode( ',', $_GET['table_id'] ) : array(); | |
| 606 | 612 | $exporter = TablePress::load_class( 'TablePress_Export', 'class-export.php', 'classes' ); |
| 607 | 613 | $data['zip_support_available'] = $exporter->zip_support_available; |
| 608 | 614 | $data['export_formats'] = $exporter->export_formats; |
| 609 | 615 | $data['csv_delimiters'] = $exporter->csv_delimiters; |
| @@ -631,9 +637,9 @@ | ||
| 631 | 637 | $data['table_ids'] = $table_ids; // Backward compatibility for the retired "Table Auto Update" Extension, which still relies on this variable name. |
| 632 | 638 | $data['tables_count'] = TablePress::$model_table->count_tables(); |
| 633 | 639 | $importer = TablePress::load_class( 'TablePress_Import', 'class-import.php', 'classes' ); |
| 634 | 640 | $data['import_type'] = ( ! empty( $_GET['import_type'] ) ) ? $_GET['import_type'] : 'add'; |
| 635 | - $data['import_existing_table'] = ( ! empty( $_GET['import_existing_table'] ) ) ? $_GET['import_existing_table'] : ''; | |
| 641 | + $data['import_existing_table'] = $_GET['import_existing_table'] ?? ''; | |
| 636 | 642 | $data['import_source'] = ( ! empty( $_GET['import_source'] ) ) ? $_GET['import_source'] : 'file-upload'; |
| 637 | 643 | $data['import_url'] = ( ! empty( $_GET['import_url'] ) ) ? rawurldecode( wp_unslash( $_GET['import_url'] ) ) : 'https://'; |
| 638 | 644 | $data['import_server'] = ( ! empty( $_GET['import_server'] ) ) ? rawurldecode( wp_unslash( $_GET['import_server'] ) ) : ABSPATH; |
| 639 | 645 | $data['import_form-field'] = ( ! empty( $_GET['import_form-field'] ) ) ? rawurldecode( wp_unslash( $_GET['import_form-field'] ) ) : ''; |
| @@ -1005,10 +1011,9 @@ | ||
| 1005 | 1011 | |
| 1006 | 1012 | if ( empty( $export['format'] ) || ! isset( $exporter->export_formats[ $export['format'] ] ) ) { |
| 1007 | 1013 | TablePress::redirect( array( 'action' => 'export', 'message' => 'error_export', 'error_details' => 'The export format is invalid.' ) ); |
| 1008 | 1014 | } |
| 1009 | - if ( empty( $export['csv_delimiter'] ) ) { | |
| 1010 | - // Set a value, so that the variable exists. | |
| 1015 | + if ( ! isset( $export['csv_delimiter'] ) ) { | |
| 1011 | 1016 | $export['csv_delimiter'] = ''; |
| 1012 | 1017 | } |
| 1013 | 1018 | if ( 'csv' === $export['format'] && ! isset( $exporter->csv_delimiters[ $export['csv_delimiter'] ] ) ) { |
| 1014 | 1019 | TablePress::redirect( array( 'action' => 'export', 'message' => 'error_export', 'error_details' => 'The CSV delimiter is invalid.' ) ); |
| @@ -1052,9 +1057,13 @@ | ||
| 1052 | 1057 | */ |
| 1053 | 1058 | $download_filename = apply_filters( 'tablepress_export_filename', $download_filename, $table['id'], $table['name'], $export['format'], $export_to_zip ); |
| 1054 | 1059 | $download_filename = sanitize_file_name( $download_filename ); |
| 1055 | 1060 | // Export the table. |
| 1056 | - $export_data = $exporter->export_table( $table, $export['format'], $export['csv_delimiter'] ); | |
| 1061 | + $options = array(); | |
| 1062 | + if ( 'csv' === $export['format'] ) { | |
| 1063 | + $options['csv_delimiter'] = $export['csv_delimiter']; | |
| 1064 | + } | |
| 1065 | + $export_data = $exporter->export_table( $table, $export['format'], $options ); | |
| 1057 | 1066 | /** |
| 1058 | 1067 | * Filters the exported table data. |
| 1059 | 1068 | * |
| 1060 | 1069 | * @since 1.6.0 |
| @@ -1098,9 +1107,13 @@ | ||
| 1098 | 1107 | // Don't export if the table is corrupted. |
| 1099 | 1108 | if ( isset( $table['is_corrupted'] ) && $table['is_corrupted'] ) { |
| 1100 | 1109 | continue; |
| 1101 | 1110 | } |
| 1102 | - $export_data = $exporter->export_table( $table, $export['format'], $export['csv_delimiter'] ); | |
| 1111 | + $options = array(); | |
| 1112 | + if ( 'csv' === $export['format'] ) { | |
| 1113 | + $options['csv_delimiter'] = $export['csv_delimiter']; | |
| 1114 | + } | |
| 1115 | + $export_data = $exporter->export_table( $table, $export['format'], $options ); | |
| 1103 | 1116 | /** This filter is documented in controllers/controller-admin.php */ |
| 1104 | 1117 | $export_data = apply_filters( 'tablepress_export_data', $export_data, $table, $export['format'], $export['csv_delimiter'] ); |
| 1105 | 1118 | $export_filename = sprintf( '%1$s-%2$s-%3$s.%4$s', $table['id'], $table['name'], wp_date( 'Y-m-d' ), $export['format'] ); |
| 1106 | 1119 | /** This filter is documented in controllers/controller-admin.php */ |
| @@ -1244,9 +1257,9 @@ | ||
| 1244 | 1257 | * |
| 1245 | 1258 | * @since 1.0.0 |
| 1246 | 1259 | */ |
| 1247 | 1260 | public function handle_get_action_hide_message(): void { |
| 1248 | - $message_item = ! empty( $_GET['item'] ) ? $_GET['item'] : ''; | |
| 1261 | + $message_item = $_GET['item'] ?? ''; | |
| 1249 | 1262 | TablePress::check_nonce( 'hide_message', $message_item ); |
| 1250 | 1263 | |
| 1251 | 1264 | if ( ! current_user_can( 'tablepress_list_tables' ) ) { |
| 1252 | 1265 | wp_die( __( 'Sorry, you are not allowed to access this page.', 'default' ), 403 ); |