PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.77
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.77
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 5.5.42 All 160 releases
wp-data-access / WPDataAccess / List_Table / WPDA_List_View.php

WPDA_List_View.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.77, at WPDataAccess/List_Table/WPDA_List_View.php

990 lines 31.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
4 *
5 * @package WPDataAccess\List_Table
6 */
7
8 namespace WPDataAccess\List_Table {
9
10 use WPDataAccess\CSV_Files\WPDA_CSV_List_Table;
11 use WPDataAccess\Data_Dictionary\WPDA_List_Columns;
12 use WPDataAccess\Data_Dictionary\WPDA_List_Columns_Cache;
13 use WPDataAccess\Data_Publisher\WPDA_Publisher_List_Table;
14 use WPDataAccess\Design_Table\WPDA_Design_Table_Form;
15 use WPDataAccess\Design_Table\WPDA_Design_Table_List_Table;
16 use WPDataAccess\Plugin_Table_Models\WPDA_CSV_Uploads_Model;
17 use WPDataAccess\Plugin_Table_Models\WPDA_Design_Table_Model;
18 use WPDataAccess\Plugin_Table_Models\WPDA_Publisher_Model;
19 use WPDataAccess\Plugin_Table_Models\WPDP_Page_Model;
20 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Design_Table_Model;
21 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Model;
22 use WPDataAccess\Utilities\WPDA_Repository;
23 use WPDataAccess\WPDA;
24 use WPDataProjects\Data_Dictionary\WPDP_List_Columns_Cache;
25 use WPDataProjects\Project\WPDP_Project;
26 use WPDataProjects\Project\WPDP_Project_Page_List;
27 use WPDataProjects\Project\WPDP_Project_Project_List;
28 use WPDataProjects\Project\WPDP_Project_Table_List;
29
30 /**
31 * Class WPDA_List_View
32 *
33 * A list view is an object that consists of a WordPress list table and it's screen options (displayed in the top
34 * right corner). The list view combines these options by identifying the different stages that apply to building
35 * a page containing both.
36 *
37 * Stages:
38 * + Screen options are added in the constructor
39 * + The list table is created in {@see WPDA_List_View::display_list_table()}
40 *
41 * To make sure that screen options are displayed with the list table, the constructor is called in the
42 * 'admin_menu' hook {@see \WP_Data_Access::define_admin_hooks()}. A object reference is stored in the class
43 * and used later when the list table is created on the page displayed.
44 *
45 * @see WPDA_List_View::display_list_table()
46 * @see \WP_Data_Access::define_admin_hooks()
47 *
48 * @author Peter Schulz
49 * @since 1.0.0
50 */
51 class WPDA_List_View {
52
53 const HIDDENCOLUMNS_PREFIX = 'wpda_manage_columnshidden_';
54
55 protected static $screen_settings_saved = false;
56
57 /**
58 * Page hook suffix
59 *
60 * @var object|boolean Reference to (sub) menu or false
61 */
62 protected $page_hook_suffix;
63
64 /**
65 * Database schema name
66 *
67 * @var string
68 */
69 protected $schema_name;
70
71 /**
72 * Database table name
73 *
74 * @var string
75 */
76 protected $table_name;
77
78 /**
79 * Indicates if bulk actions are allow
80 *
81 * @var boolean
82 */
83 protected $bulk_actions_enabled;
84
85 /**
86 * Indicates if a search box is shown
87 *
88 * @var boolean
89 */
90 protected $search_box_enabled;
91
92 /**
93 * Indicates if bulk exports are allowed
94 *
95 * @var boolean
96 */
97 protected $bulk_export_enabled;
98
99 /**
100 * Classname of list table
101 *
102 * @var string
103 */
104 protected $list_table_class;
105
106 /**
107 * Classname of data entry form
108 *
109 * @var string
110 */
111 protected $edit_form_class;
112
113 /**
114 * Reference to list table
115 *
116 * @var WPDA_List_Table|WPDA_List_Table_Menu
117 */
118 protected $wpda_list_table;
119
120 /**
121 * Reference to list columns
122 *
123 * @var WPDA_List_Columns
124 */
125 protected $wpda_list_columns = null;
126
127 /**
128 * Page title
129 *
130 * @var string
131 */
132 protected $title;
133
134 /**
135 * Page subtitle
136 *
137 * @var string
138 */
139 protected $subtitle;
140
141 /**
142 * Action (taken from $_REQUEST)
143 *
144 * @var string
145 */
146 protected $action = '';
147
148 /**
149 * Column headers (labels)
150 *
151 * @var string
152 */
153 protected $column_headers;
154
155 /**
156 * Show view link in list table? (on|off)
157 *
158 * @var string
159 */
160 protected $show_view_link = null;
161
162 /**
163 * Allow insert? (on|off)
164 *
165 * @var string
166 */
167 protected $allow_insert = null;
168
169 /**
170 * Allow update? (on|off)
171 *
172 * @var string
173 */
174 protected $allow_update = null;
175
176 /**
177 * Allow delete? (on|off)
178 *
179 * @var string
180 */
181 protected $allow_delete = null;
182
183 /**
184 * Allow import? (on|off)
185 *
186 * @var string
187 */
188 protected $allow_import = null;
189
190 /**
191 * Default WHERE clause
192 *
193 * @var string
194 */
195 protected $default_where = '';
196
197 /**
198 * Contains child table name if child request, otherwise false
199 *
200 * I don't like this kind of programming! This should be in child class of course! The load action to add
201 * screen options however cannot be delayed and therefore must be in the parent call.
202 *
203 * @var bool|string
204 */
205 protected $child_request = false;
206
207 /**
208 * WPDA_List_View constructor
209 *
210 * Page hook suffix
211 *
212 * We first check if we have a page hook suffix. This is the reference to the sub menu to which we want to
213 * add the list view. If no page hook suffix is provided, the list table might be displayed as expected, the
214 * screen options in the top right corner however will not be shown.
215 *
216 * Database table usage
217 * + The constructor can be called with or without a table name. If a table name is provided, a list table is
218 * generated for that database table.
219 * + If no table name is provided, we need to checked if a table name argument was given in the request. If a
220 * table name was provided with the request, a list table is generated for that table.
221 * + If no table name is provided (neither as an argument nor with the request) a list of all tables available
222 * in the WordPress database schema is generated.
223 *
224 * Table names are always checked! We need to check:
225 * + if a table exists in our database schema and
226 * + if we have access to that table.
227 *
228 * These checks are performed to prevent SQL injection and misuse of our WordPress database. These checks
229 * however are not performed in this class. They are performed in class {@see WPDA_List_Table} as we do not
230 * perform any queries in this class. We do perform queries on the given tables in {@see WPDA_List_Table}.
231 *
232 * @param array $args [
233 *
234 * 'page_hook_suffix' => (string|boolean) Page hook suffix of false (default = false)
235 *
236 * 'wpdaschema_name' => (string) Database schema name (default = '')
237 *
238 * 'table_name' => (string) Database table name (default = '')
239 *
240 * 'bulk_actions_enabled' => (boolean) Allow bulk actions? (default = TRUE)
241 *
242 * 'search_box_enabled' => (boolean) Show search box? (default = TRUE)
243 *
244 * 'bulk_export_enabled' => (boolean) Allow bulk exports? (default = TRUE)
245 *
246 * 'list_table_class' => (string) Class providing list table functionality
247 *
248 * 'edit_form_class' => (string) Class providing data entry functionality
249 *
250 * 'column_headers' => (array|string) Column headers (default = '' : headers taken from data dictionary)
251 *
252 * 'title' => (string) Page title (default = null)
253 *
254 * 'subtitle' => (string) Page subtitle (default = null)
255 *
256 * 'show_view_link' => (string) default = 'on'
257 *
258 * 'allow_insert' => (string) default = 'off'
259 *
260 * 'allow_update' => (string) default = 'off'
261 *
262 * 'allow_delete' => (string) default = 'off'
263 *
264 * 'allow_import' => (string) default = 'off'
265 *
266 * 'default_where' => (string)
267 *
268 * ]
269 * @see WPDA_List_Table
270 *
271 * @since 1.0.0
272 */
273 public function __construct( $args = array() ) {
274 $args = wp_parse_args(
275 $args,
276 array(
277 'page_hook_suffix' => false,
278 'wpdaschema_name' => '',
279 'table_name' => '',
280 'bulk_actions_enabled' => WPDA_List_Table::DEFAULT_BULK_ACTIONS_ENABLED,
281 'search_box_enabled' => WPDA_List_Table::DEFAULT_SEARCH_BOX_ENABLED,
282 'bulk_export_enabled' => WPDA_List_Table::DEFAULT_BULK_EXPORT_ENABLED,
283 'list_table_class' => 'WPDataAccess\\List_Table\\WPDA_List_Table',
284 'edit_form_class' => 'WPDataAccess\\Simple_Form\\WPDA_Simple_Form',
285 'column_headers' => '',
286 'title' => null,
287 'subtitle' => null,
288 )
289 );
290
291 // Check access arguments
292 if ( isset( $args['show_view_link'] ) ) {
293 $this->show_view_link = $args['show_view_link'];
294 }
295 if ( isset( $args['allow_insert'] ) ) {
296 $this->allow_insert = $args['allow_insert'];
297 }
298 if ( isset( $args['allow_update'] ) ) {
299 $this->allow_update = $args['allow_update'];
300 }
301 if ( isset( $args['allow_delete'] ) ) {
302 $this->allow_delete = $args['allow_delete'];
303 }
304 if ( isset( $args['allow_import'] ) ) {
305 $this->allow_import = $args['allow_import'];
306 }
307
308 $this->schema_name = $args['wpdaschema_name'];
309 if ( '' === $this->schema_name ) {
310 // No pre defined schema_name!
311 if ( isset( $_REQUEST['wpdaschema_name'] ) ) { // phpcs:ignore
312 // Get schema name from URL.
313 $this->schema_name = sanitize_text_field( wp_unslash( $_REQUEST['wpdaschema_name'] ) ); // phpcs:ignore
314 }
315 }
316
317 $this->table_name = $args['table_name'];
318 if ( '' === $this->table_name ) {
319 // No pre defined table_name!
320 if ( isset( $_REQUEST['table_name'] ) ) { // phpcs:ignore
321 // Get table name from URL. (later we'll check if the table exists in the WordPress database to
322 // protect ourselves against SQL injection).
323 $this->table_name = sanitize_text_field( wp_unslash( $_REQUEST['table_name'] ) ); // phpcs:ignore
324 }
325 }
326
327 $this->page_hook_suffix = $args['page_hook_suffix'];
328
329 // Set class to provide list table functionality.
330 $this->list_table_class = $args['list_table_class'];
331
332 // Set class for data entry form support (used for new, edit and view actions).
333 $this->edit_form_class = $args['edit_form_class'];
334
335 // Set page title.
336 $this->title = $args['title'];
337
338 // Set page subtitle.
339 $this->subtitle = $args['subtitle'];
340
341 $this->bulk_actions_enabled = $args['bulk_actions_enabled'];
342 $this->search_box_enabled = $args['search_box_enabled'];
343 $this->bulk_export_enabled = $args['bulk_export_enabled'];
344
345 if ( isset( $args['action'] ) ) {
346 $this->action = $args['action'];
347 } else {
348 if ( isset( $_REQUEST['action'] ) ) { // phpcs:ignore
349 $this->action = sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ); // phpcs:ignore
350 }
351 }
352
353 if ( false !== $this->page_hook_suffix ) {
354 if (
355 is_admin() &&
356 ! isset( $_REQUEST['page_action'] ) && // phpcs:ignore
357 (
358 ! ( 'new' === $this->action || 'edit' === $this->action || 'view' === $this->action || 'user_menu' === $this->action ) // phpcs:ignore
359 )
360 ) {
361 $page_action = isset( $_REQUEST['page_action'] ) ? 'defined' : ''; // phpcs:ignore
362 if ( $page_action === '' ) {
363 // Add screen options.
364 add_action( 'load-' . $this->page_hook_suffix, array( $this, 'page_screen_options' ) );
365 }
366 }
367 }
368
369 // Overwrite column header text.
370 $this->column_headers = isset( $args['column_headers'] ) ? $args['column_headers'] : '';
371
372 // Check for default WHERE clause
373 if ( isset( $args['default_where'] ) ) {
374 $this->default_where = $args['default_where'];
375 }
376 }
377
378 /**
379 * Set columns to be queried
380 *
381 * If not set all column (*) will be selected/set/queried.
382 *
383 * @param mixed $columns_queried Column array, '' or '*'.
384 *
385 * @since 1.0.0
386 */
387 public function set_columns_queried( $columns_queried ) {
388
389 $this->wpda_list_table->set_columns_queried( $columns_queried );
390
391 }
392
393 /**
394 * Enable or disable bulk actions
395 *
396 * If enabled user can perform actions on multiple rows at once.
397 *
398 * @param boolean $bulk_actions_enabled TRUE = allow bulk actions, FALSE = no bulk actions.
399 *
400 * @since 1.0.0
401 */
402 public function set_bulk_actions_enabled( $bulk_actions_enabled ) {
403
404 $this->bulk_actions_enabled = $bulk_actions_enabled;
405
406 }
407
408 /**
409 * Enable search box
410 *
411 * Shows a search box if enabled. In WP Data Access only columns with data type varchar or enum are searched.
412 *
413 * @param boolean $search_box_enabled TRUE = show search box, FALSE = no search box.
414 *
415 * @since 1.0.0
416 */
417 public function set_search_box_enabled( $search_box_enabled ) {
418
419 $this->search_box_enabled = $search_box_enabled;
420
421 }
422
423 /**
424 * Display page
425 *
426 * Page types to be displayed:
427 * + List table
428 * + View form
429 * + Data entry form (add new)
430 * + Data entry form (update)
431 *
432 * The type of table displayed depend on the value of the action argument provided in the request. The value
433 * of argument action is stored in $this->action in the constructor.
434 *
435 * @since 1.0.0
436 */
437 public function show() {
438 // Add datetimepicker
439 wp_enqueue_style( 'datetimepicker' );
440 wp_enqueue_script( 'datetimepicker' );
441
442 // Prepare columns for list table. Needed in get_column_headers() and handed over to list table to prevent
443 // processing the same queries multiple times.
444 if ( null === $this->wpda_list_columns ) {
445 $this->wpda_list_columns = WPDA_List_Columns_Cache::get_list_columns( $this->schema_name, $this->table_name );
446 }
447
448 $wpda_repository = new WPDA_Repository();
449 $wpda_repository->inform_user();
450
451 switch ( $this->action ) {
452 case 'new': // Show edit form in editing mode to create new records.
453 case 'edit': // Show edit form in editing mode to update records.
454 case 'view': // Show edit form in view mode to view records.
455 $this->display_edit_form();
456 break;
457 case 'create_table': // Show form to create new table.
458 $this->display_design_menu();
459 break;
460 default: // Show list (default).
461 $this->display_list_table();
462 }
463
464 }
465
466 /**
467 * Display data entry form
468 *
469 * Called when action is:
470 * + 'new' to add a new record to the table
471 * + 'edit' to update a record
472 * + 'view" to show a record (readonly)
473 *
474 * Class WPDA_Simple_Form is the default class used to generate data entry forms. This class provides dynamic
475 * generation of data entry forms for any table, as long as the table has a primary key. The primary key is
476 * necessary to perform updates (unique identification of records).
477 *
478 * For more specific data entry forms WPDA_Simple_Form can be extended. These classes need to implement some
479 * methods to work properly. Check out {@see \WPDataAccess\Simple_Form\WPDA_Simple_Form} for more information.
480 *
481 * @since 1.0.0
482 *
483 * @see \WPDataAccess\Simple_Form\WPDA_Simple_Form
484 */
485 protected function display_edit_form() {
486 $form = new $this->edit_form_class(
487 $this->schema_name,
488 $this->table_name,
489 $this->wpda_list_columns
490 );
491
492 $form->prepare_form();
493
494 if ( isset( $_POST['postaction'] ) && 'list' === $_POST['postaction'] ) { // phpcs:ignore
495 // Jump back to list after pressing SUBMIT > LIST
496 $this->display_list_table();
497 } else {
498 $form->show();
499 }
500 }
501
502 /**
503 * Adds Data Designer menu-item to plugin menu
504 */
505 protected function display_design_menu() {
506 $form = new WPDA_Design_Table_Form();
507 $form->show();
508 }
509
510 /**
511 * Display list table
512 *
513 * There are two type of list tables here:
514 * + List of tables in the WordPress database schema
515 * + List of rows in a specific table
516 *
517 * A list of tables in the WordPress database schema is in fact a list of rows as well. The MySQL base table
518 * (which is in fact a view) used to show this information is 'information_schema.tables'. The list of tables
519 * contains a link to a list table for every table.
520 *
521 * The list of rows is provided by class {@see WPDA_List_Table}. WPDA_List_Table extends WordPress class
522 * WP_List_Table.
523 *
524 * The list of tables is provided by class {@see WPDA_List_Table_Menu}. WPDA_List_Table_Menu extends class
525 * WPDA_List_Table.
526 *
527 * @since 1.0.0
528 *
529 * @see WPDA_List_Table
530 * @see WPDA_List_Table_Menu
531 */
532 protected function display_list_table() {
533 if ( '' === $this->table_name ) {
534 // List all tables in the database.
535 $this->list_table_class = 'WPDataAccess\\List_Table\\WPDA_List_Table_Menu';
536 }
537
538 $args = array(
539 'wpdaschema_name' => $this->schema_name,
540 'table_name' => $this->table_name,
541 'wpda_list_columns' => $this->wpda_list_columns,
542 'column_headers' => $this->column_headers,
543 'default_where' => $this->default_where,
544 );
545 if ( null !== $this->show_view_link ) {
546 $args['show_view_link'] = $this->show_view_link;
547 }
548 if ( null !== $this->allow_insert ) {
549 $args['allow_insert'] = $this->allow_insert;
550 }
551 if ( null !== $this->allow_update ) {
552 $args['allow_update'] = $this->allow_update;
553 }
554 if ( null !== $this->allow_delete ) {
555 $args['allow_delete'] = $this->allow_delete;
556 }
557 if ( null !== $this->allow_import ) {
558 $args['allow_import'] = $this->allow_import;
559 }
560
561 $this->wpda_list_table = new $this->list_table_class( $args );
562
563 $this->wpda_list_table->set_bulk_actions_enabled( $this->bulk_actions_enabled );
564 $this->wpda_list_table->set_search_box_enabled( $this->search_box_enabled );
565 $this->wpda_list_table->set_bulk_export_enabled( $this->bulk_export_enabled );
566
567 // Reset page title and subtitle to allow empty titles and subtitles as well.
568 if ( null !== $this->title ) {
569 $this->wpda_list_table->set_title( $this->title );
570 }
571 if ( null !== $this->subtitle ) {
572 $this->wpda_list_table->set_subtitle( $this->subtitle );
573 }
574
575 $this->wpda_list_table->show();
576 }
577
578 /**
579 * Set page screen options
580 *
581 * Provided are column selection (enable/disable) and rows per page. The table name is included in the meta_key
582 * to save screen options per table.
583 *
584 * @since 1.0.0
585 */
586 public function page_screen_options() {
587 if ( isset( $_REQUEST['child_tab'] ) ) { // phpcs:ignore
588 $this->child_request = sanitize_text_field( wp_unslash( $_REQUEST['child_tab'] ) ); // phpcs:ignore
589 }
590
591 if ( false !== $this->child_request ) {
592 $table_name = str_replace( '.', '_', $this->schema_name . $this->child_request );
593 } else {
594 global $wpdb;
595 if ( $this->schema_name === $wpdb->dbname && $this->table_name === WPDA_CSV_Uploads_Model::get_base_table_name() ) {
596 $table_name = $this->table_name; // csv upload = exception
597 } else {
598 $table_name = str_replace( '.', '_', $this->schema_name . $this->table_name );
599 }
600 }
601
602 add_filter( 'screen_settings', array( $this, 'show_screen_options' ), 10, 2 );
603 $this->set_screen_option();
604 $screen = get_current_screen();
605
606 if ( is_object( $screen ) && $screen->id === $this->page_hook_suffix ) {
607 if ( '' === $this->table_name ) {
608 // The WordPress Database Table List doesn't have a table_name at this stage. Use the base table
609 // defined in WPDA_List_Table_Menu instead.
610 $table_name = str_replace( '.', '_', WPDA_List_Table::LIST_BASE_TABLE );
611 // Set default column display values for repository tables if screen options is activated
612 // for the first time
613 if ( is_admin() &&
614 false === get_user_option( self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name )
615 ) {
616 $hidden = array(
617 'create_time',
618 'data_size',
619 'index_size',
620 'overhead',
621 'table_collation',
622 );
623
624 update_user_meta(
625 get_current_user_id(),
626 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name,
627 $hidden
628 );
629 }
630 } else {
631 // Set default column display values for repository tables if screen options is activated
632 // for the first time
633 if ( WPDA_Design_Table_Model::get_base_table_name() === $this->table_name ) {
634 if ( is_admin() &&
635 false === get_user_option( self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name )
636 ) {
637 $hidden = array(
638 'wpda_table_design',
639 );
640
641 update_user_meta(
642 get_current_user_id(),
643 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name,
644 $hidden
645 );
646 }
647 } elseif ( WPDA_Publisher_Model::get_base_table_name() === $this->table_name ) {
648 if ( is_admin() &&
649 false === get_user_option( self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name )
650 ) {
651 $hidden = array(
652 'pub_table_name',
653 'pub_column_names',
654 'pub_sort_icons',
655 'pub_styles',
656 'pub_style_premium',
657 'pub_style_user',
658 'pub_style_color',
659 'pub_style_space',
660 'pub_style_corner',
661 'pub_style_modal_width',
662 'pub_responsive_popup_title',
663 'pub_responsive_cols',
664 'pub_responsive_type',
665 'pub_responsive_modal_hyperlinks',
666 'pub_responsive_icon',
667 'pub_flat_scrollx',
668 'pub_format',
669 'pub_default_where',
670 'pub_default_orderby',
671 'pub_table_options_searching',
672 'pub_table_options_ordering',
673 'pub_table_options_paging',
674 'pub_table_options_advanced',
675 'pub_table_options_serverside',
676 'pub_table_options_nl2br',
677 'pub_show_advanced_settings',
678 'pub_extentions',
679 'pub_query',
680 'pub_cpt',
681 'pub_cpt_fields',
682 'pub_cpt_query',
683 'pub_cpt_format',
684 );
685
686 update_user_meta(
687 get_current_user_id(),
688 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name,
689 $hidden
690 );
691 }
692 } elseif ( WPDP_Project_Model::get_base_table_name() === $this->table_name ) {
693 if ( is_admin() &&
694 false === get_user_option( self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name )
695 ) {
696 $hidden = array(
697 'project_description',
698 'project_sequence',
699 );
700
701 update_user_meta(
702 get_current_user_id(),
703 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name,
704 $hidden
705 );
706
707 // Set default columns for project pages
708 if ( false === get_user_option( self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . WPDP_Page_Model::get_base_table_name() ) ) {
709 $hidden = array(
710 'project_id',
711 'page_schema_name',
712 'page_setname',
713 'page_allow_insert',
714 'page_allow_delete',
715 'page_allow_import',
716 'page_allow_bulk',
717 'page_allow_full_export',
718 'page_content',
719 'page_title',
720 'page_subtitle',
721 'page_where',
722 'page_orderby',
723 'page_sequence',
724 );
725
726 update_user_meta(
727 get_current_user_id(),
728 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . WPDP_Page_Model::get_base_table_name(),
729 $hidden
730 );
731 }
732 }
733 } elseif ( WPDP_Project_Design_Table_Model::get_base_table_name() === $this->table_name ) {
734 if ( is_admin() &&
735 false === get_user_option( self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name )
736 ) {
737 $hidden = array();
738
739 update_user_meta(
740 get_current_user_id(),
741 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name,
742 $hidden
743 );
744 }
745 } elseif ( WPDA_CSV_Uploads_Model::get_base_table_name() === $this->table_name ) {
746 if ( is_admin() &&
747 false === get_user_option( self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name )
748 ) {
749 $hidden = array(
750 'csv_real_file_name',
751 'csv_mapping',
752 'csv_encoding',
753 );
754
755 update_user_meta(
756 get_current_user_id(),
757 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name,
758 $hidden
759 );
760 }
761 }
762
763 // Allow external user to store defaults through action hook wpda_default_screen_option.
764 do_action( 'wpda_default_screen_option', $this->table_name, $table_name );
765 }
766
767 // Add column selection
768 if ( false !== $this->child_request ) {
769 if ( WPDP_Page_Model::get_base_table_name() === $this->child_request ) {
770 $cols = WPDP_Project_Page_List::column_headers_labels();
771 $hidden = get_user_meta(
772 get_current_user_id(),
773 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . WPDP_Page_Model::get_base_table_name()
774 );
775 } else {
776 $setname = 'default';
777 if ( isset( $_REQUEST['page'] ) ) { // phpcs:ignore
778 $ids = explode( '_', sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) ); // phpcs:ignore
779 if ( 4 === count( $ids ) ) { // phpcs:ignore -- 8.1 proof
780 $proj_id = $ids[2];
781 $page_id = $ids[3];
782 $project = new WPDP_Project( $proj_id, $page_id );
783 if ( null !== $project->get_project() ) {
784 if ( null !== $project->get_setname() ) {
785 $setname = $project->get_setname();
786 }
787 }
788 }
789 }
790 $wpdp_list_columns_child = WPDP_List_Columns_Cache::get_list_columns( $this->schema_name, $this->child_request, 'listtable', $setname );
791 $cols = $wpdp_list_columns_child->get_table_column_headers();
792 $hidden = get_user_meta(
793 get_current_user_id(),
794 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name
795 );
796 }
797 } else {
798 $cols = $this->get_column_headers();
799 $hidden = get_user_meta(
800 get_current_user_id(),
801 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name
802 );
803 }
804 foreach ( $cols as $col => $label ) {
805 if ( '' !== $label ) {
806 $args = array(
807 'option' => self::HIDDENCOLUMNS_PREFIX . $table_name . $col,
808 'column_name' => $col,
809 'label' => $label,
810 'value' => isset( $hidden[0] ) && in_array( $col, $hidden[0] ) ? '' : 'checked="checked"',
811 'default' => '',
812 );
813 add_screen_option( $col, $args );
814 }
815 }
816
817 // Add pagination
818 $pagination = WPDA::get_option( WPDA::OPTION_BE_PAGINATION );
819 $args = array(
820 'label' => __( 'Number of items per page', 'wp-data-access' ),
821 'default' => $pagination,
822 'option' => 'wpda_rows_per_page_' . $table_name,
823 );
824 add_screen_option( 'per_page', $args );
825 }
826 }
827
828 /**
829 * Get column headers
830 *
831 * @return array
832 * @since 1.0.0
833 */
834 public function get_column_headers() {
835 if ( '' === $this->table_name ) {
836 return WPDA_List_Table_Menu::column_headers_labels();
837 } elseif ( WPDA_Design_Table_Model::get_base_table_name() === $this->table_name ) {
838 return WPDA_Design_Table_List_Table::column_headers_labels();
839 } elseif ( WPDA_Publisher_Model::get_base_table_name() === $this->table_name ) {
840 return WPDA_Publisher_List_Table::column_headers_labels();
841 } elseif ( WPDP_Project_Model::get_base_table_name() === $this->table_name ) {
842 return WPDP_Project_Project_List::column_headers_labels();
843 } elseif ( WPDP_Project_Design_Table_Model::get_base_table_name() === $this->table_name ) {
844 return WPDP_Project_Table_List::column_headers_labels();
845 } elseif ( WPDP_Page_Model::get_base_table_name() === $this->table_name ) {
846 return WPDP_Project_Page_List::column_headers_labels();
847 } elseif ( WPDA_CSV_Uploads_Model::get_base_table_name() === $this->table_name ) {
848 return WPDA_CSV_List_Table::column_headers_labels();
849 } else {
850 if ( has_filter( 'wpda_get_column_headers' ) ) {
851 // Use filter
852 $column_headers = apply_filters( 'wpda_get_column_headers', $this->schema_name, $this->table_name );
853 if ( null !== $column_headers ) {
854 return $column_headers;
855 }
856 }
857 if ( null === $this->wpda_list_columns ) {
858 $this->wpda_list_columns = WPDA_List_Columns_Cache::get_list_columns( $this->schema_name, $this->table_name );
859 }
860 return $this->wpda_list_columns->get_table_column_headers();
861 }
862 }
863
864 /**
865 * Save screen options
866 *
867 * @return mixed
868 * @since 1.0.0
869 */
870 public function set_screen_option() {
871 $screen = get_current_screen();
872 if (
873 is_object( $screen ) &&
874 $screen->id === $this->page_hook_suffix &&
875 isset( $_REQUEST['screenoptionnonce'] ) // phpcs:ignore
876 ) {
877 // check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' );
878
879 if ( isset( $_REQUEST['wp_screen_options']['option'] ) && isset( $_REQUEST['wp_screen_options']['value'] ) ) { // phpcs:ignore
880 update_user_meta(
881 WPDA::get_current_user_id(),
882 sanitize_text_field( wp_unslash( $_REQUEST['wp_screen_options']['option'] ) ), // phpcs:ignore
883 sanitize_text_field( wp_unslash( $_REQUEST['wp_screen_options']['value'] ) ) // phpcs:ignore
884 );
885 }
886
887 if ( false !== $this->child_request ) {
888 $table_name = str_replace( '.', '_', $this->schema_name . $this->child_request );
889 if ( WPDP_Page_Model::get_base_table_name() === $this->child_request ) {
890 $cols = WPDP_Project_Page_List::column_headers_labels();
891 } else {
892 $wpda_list_columns_child = WPDA_List_Columns_Cache::get_list_columns( $this->schema_name, $this->child_request );
893 $cols = $wpda_list_columns_child->get_table_column_headers();
894 }
895 } else {
896 if ( '' === $this->table_name ) {
897 $table_name = str_replace( '.', '_', WPDA_List_Table::LIST_BASE_TABLE );
898 } else {
899 global $wpdb;
900 if ( $this->schema_name === $wpdb->dbname && $this->table_name === WPDA_CSV_Uploads_Model::get_base_table_name() ) {
901 $table_name = $this->table_name; // csv upload = exception
902 } else {
903 $table_name = str_replace( '.', '_', $this->schema_name . $this->table_name );
904 }
905 }
906 $cols = $this->get_column_headers();
907 }
908
909 $cols_hidden = array();
910 foreach ( $cols as $col => $label ) {
911 if ( isset( $_REQUEST[ $col . '-hide-setting' ] ) && 'HIDE' === $_REQUEST[ $col . '-hide-setting' ] ) { // phpcs:ignore
912 array_push( $cols_hidden, $col ); // phpcs:ignore -- 8.1 proof
913 }
914 }
915
916 if ( false !== $this->child_request && WPDP_Page_Model::get_base_table_name() === $this->child_request ) {
917 update_user_meta(
918 get_current_user_id(),
919 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $this->child_request,
920 $cols_hidden
921 );
922 } else {
923 update_user_meta(
924 get_current_user_id(),
925 self::HIDDENCOLUMNS_PREFIX . get_current_screen()->id . $table_name,
926 $cols_hidden
927 );
928 }
929 }
930 }
931
932 public function show_screen_options( $status, $args ) {
933 ob_start();
934 ?>
935 <fieldset class="metabox-prefs">
936 <legend><?php esc_html_e( 'Columns', 'wp-data-access' ); ?></legend>
937 <?php
938 $screen = get_current_screen();
939 foreach ( $screen->get_options() as $screen_option ) {
940 if ( self::HIDDENCOLUMNS_PREFIX === substr( $screen_option['option'], 0, 26 ) &&
941 '' !== $screen_option['label']
942 ) {
943 $hidden_value = '' === $screen_option['value'] ? 'HIDE' : 'SHOW';
944 ?>
945 <label>
946 <input type="checkbox"
947 id="<?php echo esc_attr( $screen_option['column_name'] ); ?>-hide"
948 name="<?php echo esc_attr( $screen_option['column_name'] ); ?>-hide"
949 value="<?php echo esc_attr( $screen_option['column_name'] ); ?>"
950 class="hide-column-tog"
951 <?php echo esc_attr( $screen_option['value'] ); ?>
952 onclick="update_column_setting(this)"
953 ><?php echo esc_attr( $screen_option['label'] ); ?>
954 <input type="hidden"
955 id="<?php echo esc_attr( $screen_option['column_name'] ); ?>-hide-setting"
956 name="<?php echo esc_attr( $screen_option['column_name'] ); ?>-hide-setting"
957 value="<?php echo esc_attr( $hidden_value ); ?>"
958 >
959 </label>
960 <?php
961 }
962 }
963 ?>
964 </fieldset>
965 <?php
966 if ( false !== $this->child_request ) {
967 echo '<input type="hidden" name="child_tab" value="' . esc_attr( $this->child_request ) . '">';
968 }
969 ?>
970 <script type='text/javascript'>
971 function update_column_setting(item) {
972 if (jQuery(item).is(':checked')) {
973 jQuery('#'+jQuery(item).attr('name')+'-setting').val('SHOW');
974 } else {
975 jQuery('#'+jQuery(item).attr('name')+'-setting').val('HIDE');
976 }
977 }
978 jQuery(function () {
979 // Switch fieldset: columns first = WordPress default
980 jQuery("#adv-settings fieldset:first").insertAfter(jQuery("#adv-settings fieldset:last"));
981 });
982 </script>
983 <?php
984 return ob_get_clean();
985 }
986
987 }
988
989 }
990