PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.85
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.85
5.5.85 5.5.84 5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 5.5.41 All 161 releases
← All changes | WPDataAccess/List_Table/WPDA_List_Table.php +132 -150 5.5.32 → 5.5.85 View file →
@@ -4,21 +4,18 @@
4 4 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
5 5 *
6 6 * @package WPDataAccess\List_Table
7 7 */
8 +// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- verified on page
8 9 namespace WPDataAccess\List_Table;
9 10
10 11 use WPDataAccess\Connection\WPDADB;
11 -use WPDataAccess\Dashboard\WPDA_Dashboard;
12 12 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Exist;
13 -use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Lists;
14 13 use WPDataAccess\Data_Dictionary\WPDA_List_Columns;
15 14 use WPDataAccess\Macro\WPDA_Macro;
16 15 use WPDataAccess\Plugin_Table_Models\WPDA_CSV_Uploads_Model;
17 16 use WPDataAccess\Plugin_Table_Models\WPDA_Media_Model;
18 -use WPDataAccess\Utilities\WPDA_Import;
19 17 use WPDataAccess\Utilities\WPDA_Message_Box;
20 -use WPDataAccess\Utilities\WPDA_Repository;
21 18 use WPDataAccess\Wordpress_Original;
22 19 use WPDataAccess\WPDA;
23 20 use WPDataProjects\WPDP;
24 21 use WPDataAccess\Plugin_Table_Models\WPDA_Table_Settings_Model;
@@ -209,15 +206,8 @@
209 206 */
210 207 protected $column_headers;
211 208
212 209 /**
213 - * Reference to import object
214 - *
215 - * @var WPDA_Import
216 - */
217 - protected $wpda_import = null;
218 -
219 - /**
220 210 * Child tab clicked (used for parent child relationships only)
221 211 *
222 212 * @var null
223 213 */
@@ -365,9 +355,9 @@
365 355 *
366 356 * A list of rows for a specific table is based on WordPress class WP_List_Table.
367 357 *
368 358 * WPDA_List_Table can be used to build list tables for views as well. View based list tables however, do not
369 - * support insert, update, delete, import and export actions.
359 + * support insert, update, delete and export actions.
370 360 *
371 361 * A table name is not the only thing we need to build a list table. We also need to have access to the
372 362 * table columns. If no table columns are provided execution is stopped as well.
373 363 *
@@ -402,10 +392,8 @@
402 392 * 'allow_update' => (string) on|off
403 393 *
404 394 * 'allow_delete' => (string) on|off
405 395 *
406 - * 'allow_import' => (string) on|off
407 - *
408 396 * 'hide_navigation' => (boolean)
409 397 *
410 398 * 'default_where' => (string)
411 399 *
@@ -415,13 +403,13 @@
415 403 public function __construct( $args = array() ) {
416 404 global $wpdb;
417 405 if ( !isset( $args['table_name'] ) ) {
418 406 // Calling WPDA_List_Table without a table_name doesn't make sense.
419 - wp_die( __( 'ERROR: Wrong arguments [no table argument]', 'wp-data-access' ) );
407 + wp_die( esc_attr__( 'ERROR: Wrong arguments [no table argument]', 'wp-data-access' ) );
420 408 }
421 409 if ( !isset( $args['wpda_list_columns'] ) ) {
422 410 // Calling WPDA_List_Table without a column list is not allowed.
423 - wp_die( __( 'ERROR: Wrong arguments [no columns argument]', 'wp-data-access' ) );
411 + wp_die( esc_attr__( 'ERROR: Wrong arguments [no columns argument]', 'wp-data-access' ) );
424 412 }
425 413 parent::__construct( array(
426 414 'singular' => ( isset( $args['singular'] ) ? $args['singular'] : __( 'Row', 'wp-data-access' ) ),
427 415 'plural' => ( isset( $args['plural'] ) ? $args['plural'] : __( 'Rows', 'wp-data-access' ) ),
@@ -440,9 +428,9 @@
440 428 // Although this check is only needed when a table name is provided through the URL we will perform
441 429 // it in all situations. It is a fast query which makes our application much more safe and reliable.
442 430 $this->wpda_data_dictionary = new WPDA_Dictionary_Exist($this->schema_name, $this->table_name);
443 431 if ( !$this->wpda_data_dictionary->table_exists() ) {
444 - wp_die( __( 'ERROR: Invalid table name or not authorized', 'wp-data-access' ) );
432 + wp_die( esc_attr__( 'ERROR: Invalid table name or not authorized', 'wp-data-access' ) );
445 433 }
446 434 }
447 435 $this->pid = ( isset( $args['pid'] ) ? $args['pid'] : '' );
448 436 // Get menu slag of current page.
@@ -447,12 +435,11 @@
447 435 $this->pid = ( isset( $args['pid'] ) ? $args['pid'] : '' );
448 436 // Get menu slag of current page.
449 437 if ( isset( $_REQUEST['page'] ) ) {
450 438 $this->page = sanitize_text_field( wp_unslash( $_REQUEST['page'] ) );
451 - // input var okay.
452 439 } else {
453 440 // In order to show a list table we need a page.
454 - wp_die( __( 'ERROR: Wrong arguments [no page argument]', 'wp-data-access' ) );
441 + wp_die( esc_attr__( 'ERROR: Wrong arguments [no page argument]', 'wp-data-access' ) );
455 442 }
456 443 // Use column list: argument wpda_list_columns (availability already checked).
457 444 $this->wpda_list_columns =& $args['wpda_list_columns'];
458 445 // Set pagination.
@@ -479,17 +466,8 @@
479 466 } elseif ( WPDA::is_wpda_table( $this->table_name ) ) {
480 467 $this->subtitle = '<span class="dashicons dashicons-warning"></span> ' . WPDA::get_table_type_text( WPDA::TABLE_TYPE_WPDA );
481 468 }
482 469 }
483 - if ( !(isset( $args['allow_import'] ) && 'off' === $args['allow_import']) ) {
484 - try {
485 - // Instantiate WPDA_Import.
486 - $this->wpda_import = new WPDA_Import(( is_admin() ? "?page={$this->page}" : '' ), $this->schema_name, $this->table_name);
487 - } catch ( \Exception $e ) {
488 - // If import is turned off instantiation will fail. Handle is set to null (check in future calls).
489 - $this->wpda_import = null;
490 - }
491 - }
492 470 if ( isset( $args['bulk_export_enabled'] ) ) {
493 471 $this->bulk_export_enabled = $args['bulk_export_enabled'];
494 472 }
495 473 if ( isset( $args['search_box_enabled'] ) ) {
@@ -539,9 +517,8 @@
539 517 }
540 518 $this->search_value = ( is_scalar( $this->get_search_value() ) ? str_replace( "\\'", '', (string) $this->get_search_value() ) : '' );
541 519 if ( isset( $_REQUEST["{$this->search_item_name}_old_value"] ) ) {
542 520 $this->search_value_old = sanitize_text_field( wp_unslash( $_REQUEST["{$this->search_item_name}_old_value"] ) );
543 - // input var okay.
544 521 } else {
545 522 $this->search_value_old = $this->search_value;
546 523 }
547 524 // Get page number(s).
@@ -547,26 +524,27 @@
547 524 // Get page number(s).
548 525 if ( 'page_number' !== $this->page_number_item_name ) {
549 526 if ( isset( $_REQUEST['page_number'] ) ) {
550 527 $requested_page_number = sanitize_text_field( wp_unslash( $_REQUEST['page_number'] ) );
551 - // input var okay.
552 - $this->page_number_link = '&page_number=' . $requested_page_number;
553 - $this->page_number_item = "<input type='hidden' name='page_number' value='" . $requested_page_number . "' />";
528 + $this->page_number_link = '&page_number=' . esc_attr( $requested_page_number );
529 + $this->page_number_item = "<input type='hidden' name='page_number' value='" . esc_attr( $requested_page_number ) . "' />";
554 530 }
555 531 }
556 - $this->page_number_link .= '&paged=' . $this->get_pagenum();
557 - $this->page_number_item .= "<input type='hidden' name='" . $this->page_number_item_name . "' value='" . $this->get_pagenum() . "' />";
532 + $this->page_number_link .= '&paged=' . esc_attr( $this->get_pagenum() );
533 + $this->page_number_item .= "<input type='hidden' name='" . esc_attr( $this->page_number_item_name ) . "' value='" . esc_attr( $this->get_pagenum() ) . "' />";
558 534 // Add search arguments to link to return to same page.
559 535 foreach ( $_REQUEST as $key => $value ) {
560 - if ( substr( $key, 0, 19 ) === 'wpda_search_column_' ) {
536 + if ( substr( $key, 0, 19 ) === 'wpda_search_column_' && count( array_filter( $this->wpda_list_columns->get_table_columns(), function ( $column ) use($key) {
537 + return $column['column_name'] === substr( $key, 19 );
538 + } ) ) > 0 ) {
561 539 if ( is_array( $value ) ) {
562 540 foreach ( $value as $elem_key => $elem_value ) {
563 - $this->page_number_link .= "&{$elem_key}={$elem_value}";
564 - $this->page_number_item .= "<input type='hidden' name='{$key}[]' value='{$elem_value}' />";
541 + $this->page_number_link .= '&' . esc_attr( $elem_key ) . '=' . esc_attr( $elem_value );
542 + $this->page_number_item .= "<input type='hidden' name='{" . esc_attr( $elem_key ) . "[]' value='" . esc_attr( $elem_value ) . "' />";
565 543 }
566 544 } else {
567 - $this->page_number_link .= "&{$key}={$value}";
568 - $this->page_number_item .= "<input type='hidden' name='{$key}' value='{$value}' />";
545 + $this->page_number_link .= '&' . esc_attr( $key ) . '=' . esc_attr( $value );
546 + $this->page_number_item .= "<input type='hidden' name='{" . esc_attr( $key ) . "' value='" . esc_attr( $value ) . "' />";
569 547 }
570 548 }
571 549 }
572 550 // Check if a WHERE clause (filter) was defined.
@@ -693,9 +671,9 @@
693 671 *
694 672 * @since 1.0.0
695 673 */
696 674 public function no_items() {
697 - echo __( 'No data found', 'wp-data-access' );
675 + echo esc_attr__( 'No data found', 'wp-data-access' );
698 676 }
699 677
700 678 /**
701 679 * Use this method to build parent child relationships.
@@ -735,9 +713,9 @@
735 713 public function column_default( $item, $column_name ) {
736 714 if ( $this->wpda_list_columns->get_table_columns()[0]['column_name'] === $column_name || $column_name === $this->first_display_column ) {
737 715 // First column: add row actions.
738 716 $count = count( $this->wpda_list_columns->get_table_primary_key() );
739 - //phpcs:ignore - 8.1 proof
717 + // phpcs:ignore -- 8.1 proof
740 718 if ( 0 === $count ) {
741 719 // No actions without a primary key!
742 720 // This automatically covers view processing correctly.
743 721 return $this->render_column_content( $item, $column_name ) . $this->row_actions( array(
@@ -749,9 +727,9 @@
749 727 // No rights!
750 728 $actions = array();
751 729 $this->column_default_add_action( $item, $column_name, $actions );
752 730 if ( is_array( $actions ) && count( $actions ) > 0 ) {
753 - //phpcs:ignore - 8.1 proof
731 + // phpcs:ignore -- 8.1 proof
754 732 return sprintf( '%1$s %2$s', $this->render_column_content( $item, $column_name ), $this->row_actions( $actions ) );
755 733 } else {
756 734 return sprintf( '%1$s', $this->render_column_content( $item, $column_name ) );
757 735 }
@@ -803,10 +781,11 @@
803 781 ?>
804 782
805 783 <script type='text/javascript'>
806 784 jQuery("#wpda_invisible_container").append("<?php
785 + // phpcs:disable WordPress.Security.EscapeOutput
807 786 echo $view_form;
808 - // phpcs:ignore WordPress.Security.EscapeOutput
787 + // phpcs:enable WordPress.Security.EscapeOutput
809 788 ?>");
810 789 </script>
811 790
812 791 <?php
@@ -845,10 +824,11 @@
845 824 ?>
846 825
847 826 <script type='text/javascript'>
848 827 jQuery("#wpda_invisible_container").append("<?php
828 + // phpcs:disable WordPress.Security.EscapeOutput
849 829 echo $edit_form;
850 - // phpcs:ignore WordPress.Security.EscapeOutput
830 + // phpcs:enable WordPress.Security.EscapeOutput
851 831 ?>");
852 832 </script>
853 833
854 834 <?php
@@ -887,10 +867,11 @@
887 867 ?>
888 868
889 869 <script type='text/javascript'>
890 870 jQuery("#wpda_invisible_container").append("<?php
871 + // phpcs:disable WordPress.Security.EscapeOutput
891 872 echo $delete_form;
892 - // phpcs:ignore WordPress.Security.EscapeOutput
873 + // phpcs:enable WordPress.Security.EscapeOutput
893 874 ?>");
894 875 </script>
895 876
896 877 <?php
@@ -955,9 +936,15 @@
955 936 } else {
956 937 $hyperlink_label = ( isset( $hyperlink->hyperlink_label ) ? $hyperlink->hyperlink_label : '' );
957 938 $hyperlink_target = ( isset( $hyperlink->hyperlink_target ) ? $hyperlink->hyperlink_target : false );
958 939 $target = ( true === $hyperlink_target ? "target='_blank'" : '' );
959 - return "<a href='" . str_replace( ' ', '+', trim( $hyperlink_html ) ) . "' {$target}>{$hyperlink_label}</a>";
940 + if ( false === $hyperlink_target ) {
941 + $json = json_decode( $hyperlink_html, true );
942 + if ( isset( $json['url'] ) ) {
943 + $hyperlink_target = $json['url'];
944 + }
945 + }
946 + return "<a href='" . esc_url_raw( $hyperlink_target ) . "' {$target}>" . esc_attr( $hyperlink_label ) . "</a>";
960 947 }
961 948 } else {
962 949 return '';
963 950 }
@@ -967,9 +954,9 @@
967 954 // Check if column is of type media.
968 955 $media_type = WPDA_Media_Model::get_column_media( $this->table_name, $column_name, $this->schema_name );
969 956 if ( 'Image' === $media_type ) {
970 957 $image_ids = explode( ',', (string) $item[$column_name] );
971 - //phpcs:ignore - 8.1 proof
958 + // phpcs:ignore -- 8.1 proof
972 959 $image_src = '';
973 960 foreach ( $image_ids as $image_id ) {
974 961 $url = wp_get_attachment_url( esc_attr( $image_id ) );
975 962 if ( false !== $url ) {
@@ -974,17 +961,17 @@
974 961 $url = wp_get_attachment_url( esc_attr( $image_id ) );
975 962 if ( false !== $url ) {
976 963 $title = get_the_title( esc_attr( $image_id ) );
977 964 $image_src .= ( '' !== $image_src ? '<br/>' : '' );
978 - $image_src .= sprintf( '<img src="%s" class="wpda_tooltip" title="%s" width="100%%">', $url, $title );
965 + $image_src .= sprintf( '<img src="%s" class="wpda_tooltip" title="%s" width="100%%">', esc_url( $url ), esc_attr( $title ) );
979 966 }
980 967 }
981 968 return $image_src;
982 969 } elseif ( 'ImageURL' === $media_type ) {
983 - return sprintf( '<img src="%s" class="wpda_tooltip" width="100%%">', $item[$column_name] );
970 + return sprintf( '<img src="%s" class="wpda_tooltip" width="100%%">', esc_url( $item[$column_name] ) );
984 971 } elseif ( 'Attachment' === $media_type ) {
985 972 $media_ids = explode( ',', (string) $item[$column_name] );
986 - //phpcs:ignore - 8.1 proof
973 + // phpcs:ignore -- 8.1 proof
987 974 $media_links = '';
988 975 foreach ( $media_ids as $media_id ) {
989 976 $url = wp_get_attachment_url( esc_attr( $media_id ) );
990 977 if ( false !== $url ) {
@@ -1005,9 +992,9 @@
1005 992 if ( is_array( $hyperlink ) && isset( $hyperlink['label'] ) && isset( $hyperlink['url'] ) && isset( $hyperlink['target'] ) ) {
1006 993 if ( '' === $hyperlink['url'] ) {
1007 994 return '';
1008 995 } else {
1009 - return "<a href='{$hyperlink['url']}' target='{$hyperlink['target']}'>{$hyperlink['label']}</a>";
996 + return "<a href='" . esc_url_raw( $hyperlink['url'] ) . "' target='" . esc_attr( $hyperlink['target'] ) . "'>" . esc_attr( $hyperlink['label'] ) . "</a>";
1010 997 }
1011 998 } else {
1012 999 return '';
1013 1000 }
@@ -1012,14 +999,14 @@
1012 999 return '';
1013 1000 }
1014 1001 } else {
1015 1002 $hyperlink_label = $this->wpda_list_columns->get_column_label( $column_name );
1016 - return "<a href='{$item[$column_name]}' target='_blank'>{$hyperlink_label}</a>";
1003 + return "<a href='" . esc_url_raw( $item[$column_name] ) . "' target='_blank'>" . esc_attr( $hyperlink_label ) . "</a>";
1017 1004 }
1018 1005 }
1019 1006 } elseif ( 'Audio' === $media_type ) {
1020 1007 $audio_ids = explode( ',', (string) $item[$column_name] );
1021 - //phpcs:ignore - 8.1 proof
1008 + // phpcs:ignore -- 8.1 proof
1022 1009 $audio_src = '';
1023 1010 foreach ( $audio_ids as $audio_id ) {
1024 1011 if ( 'audio' === substr( get_post_mime_type( $audio_id ), 0, 5 ) ) {
1025 1012 $url = wp_get_attachment_url( esc_attr( $audio_id ) );
@@ -1025,9 +1012,9 @@
1025 1012 $url = wp_get_attachment_url( esc_attr( $audio_id ) );
1026 1013 if ( false !== $url ) {
1027 1014 $title = get_the_title( esc_attr( $audio_id ) );
1028 1015 if ( false !== $url ) {
1029 - $audio_src .= '<div title="' . $title . '" class="wpda_tooltip">' . do_shortcode( '[audio src="' . $url . '"]' ) . '</div>';
1016 + $audio_src .= '<div title="' . esc_attr( $title ) . '" class="wpda_tooltip">' . do_shortcode( '[audio src="' . esc_url_raw( $url ) . '"]' ) . '</div>';
1030 1017 }
1031 1018 }
1032 1019 }
1033 1020 }
@@ -1033,9 +1020,9 @@
1033 1020 }
1034 1021 return $audio_src;
1035 1022 } elseif ( 'Video' === $media_type ) {
1036 1023 $video_ids = explode( ',', (string) $item[$column_name] );
1037 - //phpcs:ignore - 8.1 proof
1024 + // phpcs:ignore -- 8.1 proof
1038 1025 $video_src = '';
1039 1026 foreach ( $video_ids as $video_id ) {
1040 1027 if ( 'video' === substr( get_post_mime_type( $video_id ), 0, 5 ) ) {
1041 1028 $url = wp_get_attachment_url( esc_attr( $video_id ) );
@@ -1040,9 +1027,9 @@
1040 1027 if ( 'video' === substr( get_post_mime_type( $video_id ), 0, 5 ) ) {
1041 1028 $url = wp_get_attachment_url( esc_attr( $video_id ) );
1042 1029 if ( false !== $url ) {
1043 1030 if ( false !== $url ) {
1044 - $video_src .= do_shortcode( '[video src="' . $url . '"]' );
1031 + $video_src .= do_shortcode( '[video src="' . esc_url_raw( $url ) . '"]' );
1045 1032 }
1046 1033 }
1047 1034 }
1048 1035 }
@@ -1068,9 +1055,9 @@
1068 1055 }
1069 1056 if ( 'csv' !== WPDA::get_option( WPDA::OPTION_PLUGIN_SET_FORMAT ) && isset( $this->columns_indexed[$column_name]['data_type'] ) && 'set' === $this->columns_indexed[$column_name]['data_type'] ) {
1070 1057 $list = '<' . WPDA::get_option( WPDA::OPTION_PLUGIN_SET_FORMAT ) . '>';
1071 1058 $listarray = explode( ',', (string) $item[$column_name] );
1072 - //phpcs:ignore - 8.1 proof
1059 + // phpcs:ignore -- 8.1 proof
1073 1060 foreach ( $listarray as $listitem ) {
1074 1061 $list .= "<li>{$listitem}</li>";
1075 1062 }
1076 1063 $list .= '</' . WPDA::get_option( WPDA::OPTION_PLUGIN_SET_FORMAT ) . '>';
@@ -1111,8 +1098,9 @@
1111 1098 $page_number_item = $this->page_number_item;
1112 1099 $case_sensitive_search = ( isset( $_REQUEST['wpda_c'] ) && 'true' === $_REQUEST['wpda_c'] ? "<input type='hidden' name='wpda_c' value='true'>" : '' );
1113 1100 $add_schema_and_table_name = ( !is_admin() ? '' : "\n\t\t\t\t\t<input type='hidden' name='wpdaschema_name' value='{$esc_attr( $schema_name )}' />\n\t\t\t\t\t<input type='hidden' name='table_name' value='{$esc_attr( $table_name )}' />\n\t\t\t\t" );
1114 1101 // Hide schema and table name on front-end
1102 + // phpcs:ignore PluginCheck.CodeAnalysis.Heredoc.NotAllowed
1115 1103 $form = <<<EOT
1116 1104 \t\t\t\t<form id='{$esc_attr( $form_id )}' action='{$url}' method='post'>
1117 1105 \t\t\t\t\t{$get_key_input_fields}
1118 1106 \t\t\t\t\t{$add_parent_args_as_string}
@@ -1118,11 +1106,11 @@
1118 1106 \t\t\t\t\t{$add_parent_args_as_string}
1119 1107 \t\t\t\t\t{$add_schema_and_table_name}
1120 1108 \t\t\t\t\t<input type='hidden' name='action' value='{$esc_attr( $action )}' />
1121 1109 \t\t\t\t\t<input type='hidden' name='_wpnonce' value='{$esc_attr( $wp_nonce )}'>
1122 -\t\t\t\t\t{$row_security_nonce_field}
1123 -\t\t\t\t\t{$page_number_item}
1124 -\t\t\t\t\t{$case_sensitive_search}
1110 +\t\t\t\t\t{$esc_attr( $row_security_nonce_field )}
1111 +\t\t\t\t\t{$esc_attr( $page_number_item )}
1112 +\t\t\t\t\t{$esc_attr( $case_sensitive_search )}
1125 1113 \t\t\t\t</form>
1126 1114 EOT;
1127 1115 return str_replace( array("\n", "\r"), '', $form );
1128 1116 }
@@ -1149,11 +1137,11 @@
1149 1137 $class = 'dashicons-external';
1150 1138 }
1151 1139 return sprintf(
1152 1140 '<a href="%s" title="%s" target="_blank"><span class="dashicons %s wpda_attachment_icon"></span></a>',
1153 - $url,
1154 - $title,
1155 - $class
1141 + esc_url( $url ),
1142 + esc_attr( $title ),
1143 + esc_attr( $class )
1156 1144 );
1157 1145 }
1158 1146
1159 1147 /**
@@ -1181,13 +1169,17 @@
1181 1169 */
1182 1170 protected function render_column_content( $item, $column_name, $substitute_newlines = true ) {
1183 1171 $column_content = ( isset( $item["lookup_value_{$column_name}"] ) ? $item["lookup_value_{$column_name}"] : $item[$column_name] );
1184 1172 if ( 'off' === WPDA::get_option( WPDA::OPTION_BE_TEXT_WRAP_SWITCH ) && WPDA::get_option( WPDA::OPTION_BE_TEXT_WRAP ) < strlen( (string) $column_content ) ) {
1185 - $title = sprintf( __( 'Output limited to %1$s characters', 'wp-data-access' ), WPDA::get_option( WPDA::OPTION_BE_TEXT_WRAP ) );
1173 + $title = sprintf(
1174 + /* translators: %s = number of characters before text is wrapped */
1175 + __( 'Output limited to %1$s characters', 'wp-data-access' ),
1176 + WPDA::get_option( WPDA::OPTION_BE_TEXT_WRAP )
1177 + );
1186 1178 if ( $substitute_newlines ) {
1187 - return str_replace( "\n", '<br/>', substr( esc_html( str_replace( '&', '&amp;', (string) $column_content ) ), 0, WPDA::get_option( WPDA::OPTION_BE_TEXT_WRAP ) ) . ' <a href="javascript:void(0)" title="' . $title . '">&bull;&bull;&bull;</a>' );
1179 + return str_replace( "\n", '<br/>', substr( esc_html( str_replace( '&', '&amp;', (string) $column_content ) ), 0, WPDA::get_option( WPDA::OPTION_BE_TEXT_WRAP ) ) . ' <a href="javascript:void(0)" title="' . esc_attr( $title ) . '">&bull;&bull;&bull;</a>' );
1188 1180 } else {
1189 - return substr( esc_html( str_replace( '&', '&amp;', (string) $column_content ) ), 0, WPDA::get_option( WPDA::OPTION_BE_TEXT_WRAP ) ) . ' <a href="javascript:void(0)" title="' . $title . '">&bull;&bull;&bull;</a>';
1181 + return substr( esc_html( str_replace( '&', '&amp;', (string) $column_content ) ), 0, WPDA::get_option( WPDA::OPTION_BE_TEXT_WRAP ) ) . ' <a href="javascript:void(0)" title="' . esc_attr( $title ) . '">&bull;&bull;&bull;</a>';
1190 1182 }
1191 1183 } else {
1192 1184 $column_data_type = $this->wpda_list_columns->get_column_data_type( $column_name );
1193 1185 switch ( $column_data_type ) {
@@ -1335,12 +1327,8 @@
1335 1327 *
1336 1328 * @see WPDA_List_Table::display()
1337 1329 */
1338 1330 public function show() {
1339 - // Check for import requested.
1340 - if ( null !== $this->wpda_import ) {
1341 - $this->wpda_import->check_post();
1342 - }
1343 1331 // Prepare list table items.
1344 1332 $this->prepare_items();
1345 1333 // Show list table.
1346 1334 ?>
@@ -1414,12 +1402,8 @@
1414 1402 <input type="text" name="_wpnonce" id="wpda_row_export_form__wpnonce" />
1415 1403 </form>
1416 1404 </div>
1417 1405 <?php
1418 - // Add import container.
1419 - if ( null !== $this->wpda_import ) {
1420 - $this->wpda_import->add_container();
1421 - }
1422 1406 // Add custom code before the list table.
1423 1407 do_action_ref_array( 'wpda_before_list_table', array($this) );
1424 1408 // Prepare url.
1425 1409 if ( is_admin() ) {
@@ -1472,34 +1456,28 @@
1472 1456 ?>
1473 1457 <input id="wpda_main_form_orderby" type="hidden" name="orderby"
1474 1458 value="<?php
1475 1459 echo ( isset( $_REQUEST['orderby'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) ) : '' );
1476 - // input var okay.
1477 1460 ?>"/>
1478 1461 <input id="wpda_main_form_order" type="hidden" name="order"
1479 1462 value="<?php
1480 1463 echo ( isset( $_REQUEST['order'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) ) : '' );
1481 - // input var okay.
1482 1464 ?>"/>
1483 1465 <input id="wpda_main_form_post_mime_type" type="hidden" name="post_mime_type"
1484 1466 value="<?php
1485 1467 echo ( isset( $_REQUEST['post_mime_type'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['post_mime_type'] ) ) ) : '' );
1486 - // input var okay.
1487 1468 ?>"/>
1488 1469 <input id="wpda_main_form_detached" type="hidden" name="detached"
1489 1470 value="<?php
1490 1471 echo ( isset( $_REQUEST['detached'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['detached'] ) ) ) : '' );
1491 - // input var okay.
1492 1472 ?>"/>
1493 1473 <input id="wpda_main_db_schema" type="hidden" name="wpda_main_db_schema"
1494 1474 value="<?php
1495 1475 echo ( isset( $_REQUEST['wpda_main_db_schema'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['wpda_main_db_schema'] ) ) ) : '' );
1496 - // input var okay.
1497 1476 ?>"/>
1498 1477 <input id="wpda_main_favourites" type="hidden" name="wpda_main_favourites"
1499 1478 value="<?php
1500 1479 echo ( isset( $_REQUEST['wpda_main_favourites'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['wpda_main_favourites'] ) ) ) : '' );
1501 - // input var okay.
1502 1480 ?>"/>
1503 1481 <?php
1504 1482 wp_nonce_field( 'wpda-export-' . wp_json_encode( $this->table_name ), '_wpnonce', false );
1505 1483 ?>
@@ -1586,20 +1564,16 @@
1586 1564
1587 1565 /**
1588 1566 * Add button to page header
1589 1567 *
1590 - * By default "add new" and "import" buttons are added (depending on the settings). Overwrite this method to
1568 + * "Add new" button is added (depending on the settings). Overwrite this method to
1591 1569 * add your own buttons.
1592 1570 *
1593 1571 * @since 1.0.1
1594 1572 */
1595 1573 protected function add_header_button() {
1596 - if ( 'off' === $this->allow_insert ) {
1597 - if ( null !== $this->wpda_import ) {
1598 - $this->wpda_import->add_button();
1599 - }
1600 - } else {
1601 - //phpcs:ignore - 8.1 proof
1574 + if ( 'off' !== $this->allow_insert ) {
1575 + // phpcs:ignore -- 8.1 proof
1602 1576 if ( WPDA::is_wpda_table( $this->table_name ) || ('on' === WPDA::get_option( WPDA::OPTION_BE_ALLOW_INSERT ) && count( $this->wpda_list_columns->get_table_primary_key() )) > 0 ) {
1603 1577 $storage_type = ( WPDA::is_wpda_table( $this->table_name ) ? __( 'respository', 'wp-data-access' ) : __( 'table', 'wp-data-access' ) );
1604 1578 // Prepare url.
1605 1579 if ( is_admin() ) {
@@ -1628,30 +1602,20 @@
1628 1602 ?>"/>
1629 1603 <input type="hidden" name="action" value="new">
1630 1604 <button type="submit" class="page-title-action wpda_tooltip"
1631 1605 title="<?php
1632 - echo sprintf( __( 'Add new %1$s to %2$s', 'wp-data-access' ), esc_attr( $this->_args['singular'] ), esc_attr( $storage_type ) );
1606 + /* translators: 1 = entiry name; 2: storage type */
1607 + echo esc_attr( sprintf( __( 'Add new %1$s to %2$s', 'wp-data-access' ), $this->_args['singular'], $storage_type ) );
1633 1608 ?>"
1634 1609 >
1635 1610 <i class="fas fa-plus-circle wpda_icon_on_button"></i>
1636 1611 <?php
1637 - echo __( 'Add New', 'wp-data-access' );
1612 + echo esc_attr__( 'Add New', 'wp-data-access' );
1638 1613 ?>
1639 1614 </button>
1640 - <?php
1641 - // Add import button to title.
1642 - if ( null !== $this->wpda_import ) {
1643 - $this->wpda_import->add_button();
1644 - }
1645 - ?>
1646 1615 </div>
1647 1616 </form>
1648 1617 <?php
1649 - } else {
1650 - // Add import button to title.
1651 - if ( null !== $this->wpda_import ) {
1652 - $this->wpda_import->add_button();
1653 - }
1654 1618 }
1655 1619 }
1656 1620 }
1657 1621
@@ -1779,9 +1743,9 @@
1779 1743 case 'delete':
1780 1744 // Check access rights.
1781 1745 if ( 'on' !== $this->allow_delete ) {
1782 1746 // Deleting records from list table is not allowed.
1783 - wp_die( __( 'ERROR: Not authorized [delete not allowed]', 'wp-data-access' ) );
1747 + wp_die( esc_attr__( 'ERROR: Not authorized [delete not allowed]', 'wp-data-access' ) );
1784 1748 }
1785 1749 // Prepare wp_nonce action security check.
1786 1750 $wp_nonce_action = "wpda-delete-{$this->table_name}";
1787 1751 $row_to_be_deleted = array();
@@ -1792,9 +1756,9 @@
1792 1756 foreach ( $this->wpda_list_columns->get_table_primary_key() as $key ) {
1793 1757 // Check if key is available.
1794 1758 if ( !isset( $_REQUEST[$key] ) ) {
1795 1759 // input var okay.
1796 - wp_die( __( 'ERROR: Invalid URL [missing primary key values]', 'wp-data-access' ) );
1760 + wp_die( esc_attr__( 'ERROR: Invalid URL [missing primary key values]', 'wp-data-access' ) );
1797 1761 }
1798 1762 // Write key value pair to array.
1799 1763 $row_to_be_deleted[$i]['key'] = $key;
1800 1764 $row_to_be_deleted[$i]['value'] = sanitize_text_field( wp_unslash( $_REQUEST[$key] ) );
@@ -1807,15 +1771,15 @@
1807 1771 // Check if delete is allowed.
1808 1772 $wp_nonce = ( isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : '' );
1809 1773 // input var okay.
1810 1774 if ( !wp_verify_nonce( $wp_nonce, $wp_nonce_action ) ) {
1811 - wp_die( __( 'ERROR: Not authorized', 'wp-data-access' ) );
1775 + wp_die( esc_attr__( 'ERROR: Not authorized', 'wp-data-access' ) );
1812 1776 }
1813 1777 // All key column values available: delete record.
1814 1778 // Prepare named array for delete operation.
1815 1779 $next_row_to_be_deleted = array();
1816 1780 $count_rows = count( $row_to_be_deleted );
1817 - //phpcs:ignore - 8.1 proof
1781 + // phpcs:ignore -- 8.1 proof
1818 1782 for ($i = 0; $i < $count_rows; $i++) {
1819 1783 $next_row_to_be_deleted[$row_to_be_deleted[$i]['key']] = $row_to_be_deleted[$i]['value'];
1820 1784 }
1821 1785 $engine = WPDA::get_table_engine( $this->schema_name, $this->table_name );
@@ -1836,9 +1800,9 @@
1836 1800 case 'bulk-delete':
1837 1801 // Check access rights.
1838 1802 if ( 'on' !== $this->allow_delete ) {
1839 1803 // Deleting records from list table is not allowed.
1840 - die( __( 'ERROR: Not authorized [delete not allowed]', 'wp-data-access' ) );
1804 + die( esc_attr__( 'ERROR: Not authorized [delete not allowed]', 'wp-data-access' ) );
1841 1805 }
1842 1806 // We first need to check if all the necessary information is available.
1843 1807 if ( !isset( $_REQUEST['bulk-selected'] ) ) {
1844 1808 // input var okay.
@@ -1853,14 +1817,15 @@
1853 1817 $wp_nonce_action = "wpda-delete-{$this->table_name}";
1854 1818 $wp_nonce = ( isset( $_REQUEST['_wpnonce2'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce2'] ) ) : '' );
1855 1819 // input var okay.
1856 1820 if ( !wp_verify_nonce( $wp_nonce, $wp_nonce_action ) ) {
1857 - die( __( 'ERROR: Not authorized', 'wp-data-access' ) );
1821 + die( esc_attr__( 'ERROR: Not authorized', 'wp-data-access' ) );
1858 1822 }
1823 + // phpcs:disable WordPress.Security.ValidatedSanitizedInput
1859 1824 $bulk_rows = (array) $_REQUEST['bulk-selected'];
1860 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
1825 + // phpcs:enable WordPress.Security.ValidatedSanitizedInput
1861 1826 $no_rows = count( $bulk_rows );
1862 - // # rows to be deleted. //phpcs:ignore - 8.1 proof being safe
1827 + // # rows to be deleted. // phpcs:ignore -- 8.1 proof being safe
1863 1828 $rows_to_be_deleted = array();
1864 1829 // Gonna hold rows to be deleted.
1865 1830 for ($i = 0; $i < $no_rows; $i++) {
1866 1831 // Write "json" to named array. Need to strip slashes twice. Once for the normal conversion
@@ -1872,9 +1837,9 @@
1872 1837 // Check all key columns.
1873 1838 foreach ( $this->wpda_list_columns->get_table_primary_key() as $key ) {
1874 1839 // Check if key is available.
1875 1840 if ( !isset( $row_object[$key] ) ) {
1876 - wp_die( __( 'ERROR: Invalid URL [missing primary key values]', 'wp-data-access' ) );
1841 + wp_die( esc_attr__( 'ERROR: Invalid URL [missing primary key values]', 'wp-data-access' ) );
1877 1842 }
1878 1843 // Write key value pair to array.
1879 1844 $rows_to_be_deleted[$i][$j]['key'] = $key;
1880 1845 $rows_to_be_deleted[$i][$j]['value'] = $row_object[$key];
@@ -1883,9 +1848,9 @@
1883 1848 }
1884 1849 }
1885 1850 // Looks like everything is there. Delete records from table...
1886 1851 $no_key_cols = count( $this->wpda_list_columns->get_table_primary_key() );
1887 - //phpcs:ignore - 8.1 proof
1852 + // phpcs:ignore -- 8.1 proof
1888 1853 $rows_successfully_deleted = 0;
1889 1854 // Number of rows successfully deleted.
1890 1855 $rows_with_errors = 0;
1891 1856 // Number of rows that could not be deleted.
@@ -1948,9 +1913,9 @@
1948 1913 // Check access rights.
1949 1914 if ( !WPDA::is_wpda_table( $this->table_name ) ) {
1950 1915 if ( 'on' !== WPDA::get_option( WPDA::OPTION_BE_EXPORT_ROWS ) ) {
1951 1916 // Exporting rows from list table is not allowed.
1952 - die( __( 'ERROR: Not authorized [export not allowed]', 'wp-data-access' ) );
1917 + die( esc_attr__( 'ERROR: Not authorized [export not allowed]', 'wp-data-access' ) );
1953 1918 }
1954 1919 }
1955 1920 // We first need to check if all the necessary information is available.
1956 1921 if ( !isset( $_REQUEST['bulk-selected'] ) ) {
@@ -1965,14 +1930,15 @@
1965 1930 // Check if export is allowed.
1966 1931 $wp_nonce = ( isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : '' );
1967 1932 // input var okay.
1968 1933 if ( !wp_verify_nonce( $wp_nonce, 'wpda-export-' . wp_json_encode( $this->table_name ) ) ) {
1969 - die( __( 'ERROR: Not authorized', 'wp-data-access' ) );
1934 + die( esc_attr__( 'ERROR: Not authorized', 'wp-data-access' ) );
1970 1935 }
1936 + // phpcs:disable WordPress.Security.ValidatedSanitizedInput
1971 1937 $bulk_rows = (array) $_REQUEST['bulk-selected'];
1972 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
1938 + // phpcs:enable WordPress.Security.ValidatedSanitizedInput
1973 1939 $no_rows = count( $bulk_rows );
1974 - // # rows to be exported. //phpcs:ignore - 8.1 proof being safe
1940 + // # rows to be exported. // phpcs:ignore -- 8.1 proof being safe
1975 1941 $format_type = '';
1976 1942 switch ( $this->current_action() ) {
1977 1943 case 'bulk-export-xml':
1978 1944 $format_type = 'xml';
@@ -2004,9 +1970,9 @@
2004 1970 // Check all key columns.
2005 1971 foreach ( $this->wpda_list_columns->get_table_primary_key() as $key ) {
2006 1972 // Check if key is available.
2007 1973 if ( !isset( $row_object[$key] ) ) {
2008 - wp_die( __( 'ERROR: Invalid URL', 'wp-data-access' ) );
1974 + wp_die( esc_attr__( 'ERROR: Invalid URL', 'wp-data-access' ) );
2009 1975 }
2010 1976 if ( !isset( $columns[$key] ) ) {
2011 1977 $columns[$key] = array();
2012 1978 }
@@ -2062,11 +2028,13 @@
2062 2028 public function delete_row( $where, $engine = '' ) {
2063 2029 $wpdadb = WPDADB::get_db_connection( $this->schema_name );
2064 2030 if ( null === $wpdadb ) {
2065 2031 if ( is_admin() ) {
2066 - wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
2032 + /* translators: %s = remote database name */
2033 + wp_die( esc_attr( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), $this->schema_name ) ) );
2067 2034 } else {
2068 - die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
2035 + /* translators: %s = remote database name */
2036 + die( esc_attr( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), $this->schema_name ) ) );
2069 2037 }
2070 2038 }
2071 2039 $row_deleted = $wpdadb->delete( $this->table_name, $where );
2072 2040 if ( 'connect' === strtolower( $engine ) ) {
@@ -2094,11 +2062,13 @@
2094 2062 // Get real row count.
2095 2063 $wpdadb = WPDADB::get_db_connection( $this->schema_name );
2096 2064 if ( null === $wpdadb ) {
2097 2065 if ( is_admin() ) {
2098 - wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
2066 + /* translators: %s = remote database name */
2067 + wp_die( esc_attr( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), $this->schema_name ) ) );
2099 2068 } else {
2100 - die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
2069 + /* translators: %s = remote database name */
2070 + die( esc_attr( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), $this->schema_name ) ) );
2101 2071 }
2102 2072 }
2103 2073 if ( '' === $this->schema_name ) {
2104 2074 $query = "\n\t\t\t\t\tselect count(*)\n\t\t\t\t\tfrom `{$this->table_name}`\n\t\t\t\t\t{$this->where}\n\t\t\t\t";
@@ -2109,9 +2079,8 @@
2109 2079 $query = "\n\t\t\t\t\t\tselect count(*)\n\t\t\t\t\t\tfrom `{$wpdadb->dbname}`.`{$this->table_name}`\n\t\t\t\t\t\t{$this->where}\n\t\t\t\t\t";
2110 2080 }
2111 2081 }
2112 2082 return $wpdadb->get_var( $query );
2113 - // phpcs:ignore Standard.Category.SniffName.ErrorCode
2114 2083 }
2115 2084
2116 2085 /**
2117 2086 * Perform query to retrieve rows from database
@@ -2126,11 +2095,13 @@
2126 2095 public function get_rows() {
2127 2096 $wpdadb = WPDADB::get_db_connection( $this->schema_name );
2128 2097 if ( null === $wpdadb ) {
2129 2098 if ( is_admin() ) {
2130 - wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
2099 + /* translators: %s = remote database name */
2100 + wp_die( esc_attr( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), $this->schema_name ) ) );
2131 2101 } else {
2132 - die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
2102 + /* translators: %s = remote database name */
2103 + die( esc_attr( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), $this->schema_name ) ) );
2133 2104 }
2134 2105 }
2135 2106 // Selected columns cannot be changed by the user at this time. No check for SQL injection needed now.
2136 2107 // This might change in the future when users are allowed to change or set this value. A method named
@@ -2184,9 +2155,8 @@
2184 2155 }
2185 2156 // Debug query.
2186 2157 // var_dump( $query );
2187 2158 $this->items = $wpdadb->get_results( $query, 'ARRAY_A' );
2188 - // phpcs:ignore Standard.Category.SniffName.ErrorCode
2189 2159 }
2190 2160
2191 2161 /**
2192 2162 * Get order by
@@ -2195,12 +2165,10 @@
2195 2165 */
2196 2166 protected function get_order_by() {
2197 2167 if ( !empty( $_REQUEST['orderby'] ) ) {
2198 2168 $orderby_arg = sanitize_sql_orderby( wp_unslash( $_REQUEST['orderby'] ) );
2199 - // input var okay.
2200 2169 if ( !empty( $_REQUEST['order'] ) ) {
2201 2170 $order_arg = sanitize_text_field( wp_unslash( $_REQUEST['order'] ) );
2202 - // input var okay.
2203 2171 } else {
2204 2172 $order_arg = '';
2205 2173 }
2206 2174 $columns = $this->get_sortable_columns();
@@ -2206,9 +2174,9 @@
2206 2174 $columns = $this->get_sortable_columns();
2207 2175 // Check column name for SQL injection.
2208 2176 if ( isset( $columns[$orderby_arg] ) || $this->wpda_data_dictionary->column_exists( $orderby_arg ) ) {
2209 2177 // Column name exists in current table, safely continue...
2210 - $orderby = " order by {$orderby_arg}";
2178 + $orderby = ' order by `' . WPDA::remove_backticks( $orderby_arg ) . '`';
2211 2179 // Prevent SQL injection for order. If 'desc' is found result will be ordered desc. In all other
2212 2180 // cases we'll order asc.
2213 2181 $orderby .= ( strtolower( trim( $order_arg ) ) === 'desc' ? ' desc' : ' asc' );
2214 2182 return $orderby;
@@ -2214,9 +2182,9 @@
2214 2182 return $orderby;
2215 2183 } else {
2216 2184 // The user provided a column name which is not in the table. Most probably the result of a
2217 2185 // SQL injection attack, so let's terminate.
2218 - wp_die( __( 'ERROR: Invalid URL [invalid column name]', 'wp-data-access' ) );
2186 + wp_die( esc_attr__( 'ERROR: Invalid URL [invalid column name]', 'wp-data-access' ) );
2219 2187 }
2220 2188 } else {
2221 2189 return '';
2222 2190 }
@@ -2238,9 +2206,9 @@
2238 2206 // Tables has primary key: bulk actions allowed!
2239 2207 // Primary key is used to ensure uniqueness.
2240 2208 $actions = $this->get_bulk_actions();
2241 2209 if ( is_array( $actions ) && 0 < count( $actions ) ) {
2242 - //phpcs:ignore - 8.1 proof
2210 + // phpcs:ignore -- 8.1 proof
2243 2211 $columns = array(
2244 2212 'cb' => '<input type="checkbox" />',
2245 2213 );
2246 2214 }
@@ -2390,10 +2358,12 @@
2390 2358 */
2391 2359 protected function get_search_value() {
2392 2360 if ( 'off' === WPDA::get_option( WPDA::OPTION_BE_REMEMBER_SEARCH ) ) {
2393 2361 if ( isset( $_REQUEST[$this->search_item_name] ) ) {
2394 - return wp_filter_nohtml_kses( wp_unslash( $_REQUEST[$this->search_item_name] ) );
2395 - // input var okay.
2362 + // phpcs:disable WordPress.Security.ValidatedSanitizedInput
2363 + $value = wp_filter_nohtml_kses( wp_unslash( $_REQUEST[$this->search_item_name] ) );
2364 + // phpcs:enable WordPress.Security.ValidatedSanitizedInput
2365 + return $value;
2396 2366 }
2397 2367 }
2398 2368 if ( 'wpda_wpdp_' === substr( $this->page, 0, 10 ) ) {
2399 2369 $cookie_name = $this->page;
@@ -2410,14 +2380,17 @@
2410 2380 } else {
2411 2381 $cookie_name = $this->page . '_search_' . str_replace( '.', '_', $this->table_name );
2412 2382 }
2413 2383 if ( isset( $_REQUEST[$this->search_item_name] ) && '' !== $_REQUEST[$this->search_item_name] ) {
2414 - // input var okay.
2415 - return wp_filter_nohtml_kses( wp_unslash( $_REQUEST[$this->search_item_name] ) );
2416 - // input var okay.
2384 + // phpcs:disable WordPress.Security.ValidatedSanitizedInput
2385 + $value = wp_filter_nohtml_kses( wp_unslash( $_REQUEST[$this->search_item_name] ) );
2386 + // phpcs:enable WordPress.Security.ValidatedSanitizedInput
2387 + return $value;
2417 2388 } elseif ( isset( $_COOKIE[$cookie_name] ) ) {
2418 - return wp_filter_nohtml_kses( wp_unslash( $_COOKIE[$cookie_name] ) );
2419 - // input var okay.
2389 + // phpcs:disable WordPress.Security.ValidatedSanitizedInput
2390 + $value = wp_filter_nohtml_kses( wp_unslash( $_COOKIE[$cookie_name] ) );
2391 + // phpcs:enable WordPress.Security.ValidatedSanitizedInput
2392 + return $value;
2420 2393 } else {
2421 2394 return null;
2422 2395 }
2423 2396 }
@@ -2435,9 +2408,9 @@
2435 2408 * @staticvar $cb_counter int
2436 2409 */
2437 2410 public function print_column_headers( $with_id = true ) {
2438 2411 list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
2439 - //phpcs:ignore - 8.1 proof
2412 + // phpcs:ignore -- 8.1 proof
2440 2413 // *********************
2441 2414 // *** BEGIN CHANGES ***
2442 2415 // *********************
2443 2416 // Code removed.
@@ -2445,14 +2418,12 @@
2445 2418 // *** END CHANGES ***
2446 2419 // *******************
2447 2420 if ( isset( $_REQUEST['orderby'] ) ) {
2448 2421 $current_orderby = sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) );
2449 - // input var okay.
2450 2422 } else {
2451 2423 $current_orderby = '';
2452 2424 }
2453 2425 if ( isset( $_REQUEST['order'] ) && 'desc' === $_REQUEST['order'] ) {
2454 - // input var okay.
2455 2426 $current_order = 'desc';
2456 2427 } else {
2457 2428 $current_order = 'asc';
2458 2429 }
@@ -2457,15 +2428,15 @@
2457 2428 $current_order = 'asc';
2458 2429 }
2459 2430 if ( !empty( $columns['cb'] ) ) {
2460 2431 static $cb_counter = 1;
2461 - $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>' . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
2432 + $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All', 'wp-data-access' ) . '</label>' . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
2462 2433 $cb_counter++;
2463 2434 }
2464 2435 foreach ( $columns as $column_key => $column_display_name ) {
2465 2436 $class = array('manage-column', "column-{$column_key}");
2466 2437 if ( in_array( $column_key, (array) $hidden ) ) {
2467 - //phpcs:ignore - 8.1 proof
2438 + // phpcs:ignore -- 8.1 proof
2468 2439 $class[] = 'hidden';
2469 2440 }
2470 2441 if ( 'cb' === $column_key ) {
2471 2442 $class[] = 'check-column';
@@ -2476,9 +2447,9 @@
2476 2447 $class[] = 'column-primary';
2477 2448 }
2478 2449 if ( isset( $sortable[$column_key] ) ) {
2479 2450 list( $orderby, $desc_first ) = (array) $sortable[$column_key];
2480 - //phpcs:ignore - 8.1 proof
2451 + // phpcs:ignore -- 8.1 proof
2481 2452 if ( $current_orderby === $orderby ) {
2482 2453 $order = ( 'asc' === $current_order ? 'desc' : 'asc' );
2483 2454 $class[] = 'sorted';
2484 2455 $class[] = $current_order;
@@ -2615,8 +2586,11 @@
2615 2586 * Add full export to CSV and JSON buttons
2616 2587 * Needs to be granted in project page configuration
2617 2588 */
2618 2589 protected function add_full_table_downloads() {
2590 + if ( !WPDA::current_user_is_admin() ) {
2591 + return;
2592 + }
2619 2593 }
2620 2594
2621 2595 // Override to add arguments to CSV and JSON full table exports.
2622 2596 protected function add_full_table_downloads_add_args() {
@@ -2647,9 +2621,14 @@
2647 2621 }
2648 2622 // Add estimate character if row_count_estimate is enabled.
2649 2623 $estimate = ( $this->row_count_estimate['is_estimate'] ? '~' : '' );
2650 2624 /* translators: %s: number of items (2x) */
2651 - $output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items ), $estimate . number_format_i18n( $total_items ) ) . '</span>';
2625 + $output = '<span class="displaying-num">' . sprintf( _n(
2626 + '%s item',
2627 + '%s items',
2628 + $total_items,
2629 + 'wp-data-access'
2630 + ), $estimate . number_format_i18n( $total_items ) ) . '</span>';
2652 2631 $current = $this->get_pagenum();
2653 2632 if ( $this->search_value !== $this->search_value_old ) {
2654 2633 $current = 1;
2655 2634 }
@@ -2694,9 +2673,9 @@
2694 2673 $page_links[] = sprintf(
2695 2674 $link_with_post_support,
2696 2675 'first-page button',
2697 2676 '',
2698 - __( 'First page' ),
2677 + __( 'First page', 'wp-data-access' ),
2699 2678 '&laquo;'
2700 2679 );
2701 2680 // *******************
2702 2681 // *** END CHANGES ***
@@ -2711,9 +2690,9 @@
2711 2690 $page_links[] = sprintf(
2712 2691 $link_with_post_support,
2713 2692 'prev-page button',
2714 2693 max( 1, $current - 1 ),
2715 - __( 'Previous page' ),
2694 + __( 'Previous page', 'wp-data-access' ),
2716 2695 '&lsaquo;'
2717 2696 );
2718 2697 // *******************
2719 2698 // *** END CHANGES ***
@@ -2720,13 +2699,13 @@
2720 2699 // *******************
2721 2700 }
2722 2701 if ( 'bottom' === $which ) {
2723 2702 $html_current_page = $current;
2724 - $total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page' ) . '</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">';
2703 + $total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page', 'wp-data-access' ) . '</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">';
2725 2704 } else {
2726 2705 $html_current_page = sprintf(
2727 2706 "%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' /><span class='tablenav-paging-text'>",
2728 - '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page' ) . '</label>',
2707 + '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page', 'wp-data-access' ) . '</label>',
2729 2708 $current,
2730 2709 strlen( (string) $total_pages )
2731 2710 );
2732 2711 }
@@ -2731,9 +2710,9 @@
2731 2710 );
2732 2711 }
2733 2712 $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
2734 2713 /* translators: %s: current page/total pages */
2735 - $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after;
2714 + $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging', 'wp-data-access' ), $html_current_page, $html_total_pages ) . $total_pages_after;
2736 2715 if ( $disable_next ) {
2737 2716 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
2738 2717 } else {
2739 2718 // *********************
@@ -2742,9 +2721,9 @@
2742 2721 $page_links[] = sprintf(
2743 2722 $link_with_post_support,
2744 2723 'next-page button',
2745 2724 min( $total_pages, $current + 1 ),
2746 - __( 'Next page' ),
2725 + __( 'Next page', 'wp-data-access' ),
2747 2726 '&rsaquo;'
2748 2727 );
2749 2728 // *******************
2750 2729 // *** END CHANGES ***
@@ -2759,9 +2738,9 @@
2759 2738 $page_links[] = sprintf(
2760 2739 $link_with_post_support,
2761 2740 'last-page button',
2762 2741 $total_pages,
2763 - __( 'Last page' ),
2742 + __( 'Last page', 'wp-data-access' ),
2764 2743 '&raquo;'
2765 2744 );
2766 2745 // *******************
2767 2746 // *** END CHANGES ***
@@ -2777,9 +2756,12 @@
2777 2756 } else {
2778 2757 $page_class = ' no-pages';
2779 2758 }
2780 2759 $this->_pagination = "<div class='tablenav-pages{$page_class}'>{$output}</div>";
2760 + // phpcs:disable WordPress.Security.EscapeOutput
2781 2761 echo $this->_pagination;
2782 - // phpcs:ignore WordPress.Security.EscapeOutput
2762 + // phpcs:enable WordPress.Security.EscapeOutput
2783 2763 }
2784 2764
2785 2765 }
2766 +
2767 +// phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing