PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.4
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.4
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 / admin / class-wp-data-access-admin.php

class-wp-data-access-admin.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.4, at admin/class-wp-data-access-admin.php

1,189 lines 41.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
5 *
6 * @package plugin\admin
7 */
8 use WPDataAccess\API\WPDA_API;
9 use WPDataAccess\Backup\WPDA_Data_Export;
10 use WPDataAccess\CSV_Files\WPDA_CSV_Import;
11 use WPDataAccess\Dashboard\WPDA_Dashboard;
12 use WPDataAccess\Data_Apps\WPDA_Apps;
13 use WPDataAccess\Data_Apps\WPDA_Explorer_Container;
14 use WPDataAccess\Data_Apps\WPDA_Apps_List;
15 use WPDataAccess\Global_Search\WPDA_Global_Search;
16 use WPDataAccess\List_Table\WPDA_List_View;
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\WPDA_User_Menus_Model;
20 use WPDataAccess\Premium\WPDAPRO_Data_Publisher\WPDAPRO_Data_Publisher_Manage_Styles;
21 use WPDataAccess\Query_Builder\WPDA_Query_Builder;
22 use WPDataAccess\Settings\WPDA_Settings;
23 use WPDataAccess\Utilities\WPDA_Repository;
24 use WPDataAccess\WPDA;
25 use WPDataProjects\WPDP;
26 /**
27 * Class WP_Data_Access_Admin
28 *
29 * Defines admin specific functionality for plugin WP Data Access.
30 *
31 * @author Peter Schulz
32 * @since 1.0.0
33 */
34 class WP_Data_Access_Admin {
35 /**
36 * Menu slug for main page
37 */
38 const PAGE_MAIN = 'wpda';
39
40 /**
41 * Menu slug for apps page
42 */
43 const PAGE_APPS = 'wpda_apps';
44
45 /**
46 * Menu slug for dashboard page
47 */
48 const PAGE_DASHBOARD = 'wpda_dashboard';
49
50 /**
51 * Menu slug for setting page
52 */
53 const PAGE_SETTINGS = 'wpdataaccess';
54
55 /**
56 * Menu slug for explorer page
57 */
58 const PAGE_EXPLORER = 'wpda_explorer';
59
60 /**
61 * Menu slug for query builder page
62 */
63 const PAGE_QUERY_BUILDER = 'wpda_query_builder';
64
65 /**
66 * Menu slug for Data Tables page
67 */
68 const PAGE_PUBLISHER = 'wpda_publisher';
69
70 /**
71 * Menu slug for charts page
72 */
73 const PAGE_CHARTS = 'wpda_charts';
74
75 /**
76 * Menu slug for designer page
77 */
78 const PAGE_DESIGNER = 'wpda_designer';
79
80 /**
81 * Menu slug for my tables page
82 */
83 const PAGE_MY_TABLES = 'wpda_my_tables';
84
85 /**
86 * Page hook suffix to Data Explorer page or false
87 *
88 * @var string|false
89 */
90 protected $wpda_data_explorer_menu;
91
92 /**
93 * Page hook suffix to Data Designer page or false
94 *
95 * @var string|false
96 */
97 protected $wpda_data_designer_menu;
98
99 /**
100 * Page hook suffix to Data Tables page or false
101 *
102 * @var string|false
103 */
104 protected $wpda_data_publisher_menu;
105
106 /**
107 * Page hook suffix to Charts page or false
108 *
109 * @var string|false
110 */
111 protected $wpda_charts_menu;
112
113 /**
114 * Reference to list view for Data Explorer page
115 *
116 * @var WPDA_List_View
117 */
118 protected $wpda_data_explorer_view;
119
120 /**
121 * Reference to list view for Data Designer page
122 *
123 * @var WPDA_List_View
124 */
125 protected $wpda_data_designer_view;
126
127 /**
128 * Reference to list view for Data Tables page
129 *
130 * @var WPDA_List_View
131 */
132 protected $wpda_data_publisher_view;
133
134 /**
135 * Reference to list view for Charts page
136 *
137 * @var WPDA_List_View
138 */
139 protected $wpda_charts_view;
140
141 /**
142 * Array of page hook suffixes to user defined sub menus
143 *
144 * @var array
145 */
146 protected $wpda_my_table_list_menu = array();
147
148 /**
149 * Array of list view for user defined sub menus
150 *
151 * @var array
152 */
153 protected $wpda_my_table_list_view = array();
154
155 /**
156 * Page hook suffix help page or false
157 *
158 * @var string|false
159 */
160 protected $wpda_help;
161
162 /**
163 * Menu slug or null
164 *
165 * @var null
166 */
167 protected $page = null;
168
169 /**
170 * Status loading indicator
171 *
172 * @var bool
173 */
174 protected $loaded_user_main_menu = false;
175
176 /**
177 * Main menu page
178 *
179 * @var null
180 */
181 protected $first_page = null;
182
183 /**
184 * WP_Data_Access_Admin constructor
185 *
186 * @since 1.0.0
187 */
188 public function __construct() {
189 if ( isset( $_REQUEST['page'] ) ) {
190 // phpcs:ignore WordPress.Security.NonceVerification
191 $this->page = sanitize_text_field( wp_unslash( $_REQUEST['page'] ) );
192 // phpcs:ignore WordPress.Security.NonceVerification
193 }
194 }
195
196 /**
197 * Add stylesheets to back-end
198 *
199 * The following stylesheets are added:
200 * + Plugin stylesheet
201 * + Visual editor stylesheet
202 *
203 * The plugin stylesheet is used to style the setting forms {@see WPDA_Settings}, simple forms
204 * {@see \WPDataAccess\Simple_Form\WPDA_Simple_Form}.
205 *
206 * @since 1.0.0
207 *
208 * @see WPDA_Settings
209 * @see \WPDataAccess\Simple_Form\WPDA_Simple_Form
210 * @see WP_Data_Access_Public
211 */
212 public function enqueue_styles() {
213 if ( !WPDA::is_plugin_page( $this->page ) ) {
214 // Admin styles are only added to plugin admin pages.
215 return;
216 }
217 wp_enqueue_style( 'wp-jquery-ui-core' );
218 wp_enqueue_style( 'wp-jquery-ui-dialog' );
219 wp_enqueue_style( 'wp-jquery-ui-sortable' );
220 wp_enqueue_style( 'wp-jquery-ui-tabs' );
221 // WPDataAccess apps CSS.
222 wp_register_style(
223 'wpda_apps',
224 plugins_url( '../assets/css/wpda_apps.css', __FILE__ ),
225 array(),
226 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
227 );
228 // WPDataAccess CSS.
229 wp_enqueue_style(
230 'wpdataaccess',
231 plugins_url( '../assets/css/wpda_style.css', __FILE__ ),
232 array(),
233 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
234 );
235 // WPDataAccess dashboard.
236 wp_register_style(
237 'wpdataaccess_dashboard',
238 plugins_url( '../assets/css/wpda_dashboard.css', __FILE__ ),
239 array(),
240 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
241 );
242 // Add WP Data Projects stylesheet.
243 wp_enqueue_style(
244 'wpdataprojects',
245 plugins_url( '../WPDataProjects/assets/css/wpdp_style.css', __FILE__ ),
246 array(),
247 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
248 );
249 // Register datetimepicker external library.
250 wp_register_style(
251 'datetimepicker',
252 plugins_url( '../assets/css/jquery.datetimepicker.min.css', __FILE__ ),
253 array(),
254 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
255 );
256 // Register JQuery DataTables to use data tables in the dashboard.
257 wp_register_style(
258 'jquery_datatables',
259 plugins_url( '../assets/css/jquery.dataTables.min.css', __FILE__ ),
260 array(),
261 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
262 );
263 // Register JQuery DataTables Responsive to use data tables in the dashboard.
264 wp_register_style(
265 'jquery_datatables_responsive',
266 plugins_url( '../assets/css/responsive.dataTables.min.css', __FILE__ ),
267 array(),
268 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
269 );
270 if ( self::PAGE_MAIN === $this->page || self::PAGE_APPS === $this->page || self::PAGE_DASHBOARD === $this->page || self::PAGE_QUERY_BUILDER === $this->page || self::PAGE_PUBLISHER === $this->page || self::PAGE_CHARTS === $this->page ) {
271 // Load UI smoothness theme.
272 wp_enqueue_style(
273 'wpda_ui_smoothness',
274 plugins_url( '../assets/css/jquery-ui.smoothness.min.css', __FILE__ ),
275 array(),
276 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
277 );
278 } else {
279 // Load UI darkness theme.
280 wp_enqueue_style(
281 'wpda_ui_darkness',
282 plugins_url( '../assets/css/jquery-ui.min.css', __FILE__ ),
283 array(),
284 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
285 );
286 }
287 $hide_button_icons = WPDA::get_option( WPDA::OPTION_BE_HIDE_BUTTON_ICONS );
288 if ( false !== $hide_button_icons && 'on' !== $hide_button_icons ) {
289 // SAVING SPACE - According to the plugin guidelines it is allowed to include external fonts:
290 // https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/#8-plugins-may-not-send-executable-code-via-third-party-systems .
291 // Load fontawesome icons.
292 wp_enqueue_style(
293 // phpcs:ignore WordPress.WP.EnqueuedResourceParameters
294 'wpda_fontawesome_icons',
295 WPDA::CDN_FONTAWESOME . 'all.min.css',
296 array(),
297 null,
298 false
299 );
300 }
301 if ( self::PAGE_PUBLISHER === $this->page ) {
302 wp_register_style(
303 'wpda_datatables_default',
304 plugins_url( '../assets/css/wpda_datatables_default.css', __FILE__ ),
305 array(),
306 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
307 );
308 // Add jQuery multiselect resources.
309 wp_enqueue_style(
310 'wpda_jquery_multiselect',
311 plugins_url( '../assets/css/jquery.multiselect.sortable.js.css', __FILE__ ),
312 array(),
313 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
314 false
315 );
316 }
317 if ( self::PAGE_QUERY_BUILDER === $this->page ) {
318 // Add Query Builder resources.
319 wp_enqueue_style(
320 'wpda_query_builder',
321 plugins_url( '../assets/css/wpda_query_builder.css', __FILE__ ),
322 array(),
323 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
324 );
325 wp_enqueue_style(
326 'wpda_jquery_json_viewer',
327 plugins_url( '../assets/css/jquery.json-viewer.css', __FILE__ ),
328 array(),
329 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
330 );
331 }
332 if ( !current_user_can( 'manage_options' ) ) {
333 wp_enqueue_style(
334 'wpda_non_admin',
335 plugins_url( '../assets/css/wpda_non_admin.css', __FILE__ ),
336 array(),
337 WPDA::get_option( WPDA::OPTION_WPDA_VERSION )
338 );
339 }
340 }
341
342 /**
343 * Remove icons from buttons (if configured)
344 *
345 * @return void
346 */
347 public function remove_icons() {
348 if ( !WPDA::is_plugin_page( $this->page ) ) {
349 // Only executed on plugin pages.
350 return;
351 }
352 if ( 'on' === WPDA::get_option( WPDA::OPTION_BE_HIDE_BUTTON_ICONS ) ) {
353 echo '
354 <style>
355 i.fas.wpda_icon_on_button {
356 display: none;
357 }
358 </style>
359 ';
360 }
361 }
362
363 /**
364 * Add scripts to back-end
365 *
366 * @since 1.0.0
367 *
368 * @see WP_Data_Access_Public
369 */
370 public function enqueue_scripts() {
371 if ( !WPDA::is_plugin_page( $this->page ) ) {
372 // Admin styles are only added to plugin admin pages.
373 return;
374 }
375 wp_enqueue_script( 'jquery-ui-core' );
376 wp_enqueue_script( 'jquery-ui-dialog' );
377 wp_enqueue_script( 'jquery-ui-tabs' );
378 wp_enqueue_script( 'jquery-ui-sortable' );
379 wp_enqueue_script( 'jquery-ui-tooltip' );
380 wp_enqueue_script( 'jquery-ui-autocomplete' );
381 // Register wpda rest api.
382 wp_enqueue_script(
383 'wpda_rest_api',
384 plugins_url( '../assets/js/wpda_rest_api.js', __FILE__ ),
385 array('wp-api'),
386 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
387 false
388 );
389 wp_localize_script( 'wpda_rest_api', 'wpdaApiSettings', array(
390 'path' => WPDA_API::WPDA_NAMESPACE,
391 ) );
392 // Register wpda admin functions.
393 wp_enqueue_script(
394 'wpda_admin_scripts',
395 plugins_url( '../assets/js/wpda_admin.js', __FILE__ ),
396 array(),
397 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
398 false
399 );
400 wp_localize_script( 'wpda_admin_scripts', 'wpda_admin_vars', array(
401 'wpda_ajaxurl' => admin_url( 'admin-ajax.php' ),
402 ) );
403 // Register dashboard.
404 wp_register_script(
405 'wpdataaccess_dashboard',
406 plugins_url( '../assets/js/wpda_dashboard.js', __FILE__ ),
407 array(),
408 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
409 false
410 );
411 wp_localize_script( 'wpdataaccess_dashboard', 'wpda_dashboard_vars', array(
412 'wpda_ajaxurl' => admin_url( 'admin-ajax.php' ),
413 ) );
414 // Add WP Data Projects JS functions.RESEARCH.
415 wp_enqueue_script(
416 'wpdataprojects',
417 plugins_url( '../WPDataProjects/assets/js/wpdp_admin.js', __FILE__ ),
418 array(),
419 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
420 false
421 );
422 // Register jQuery DataTables to use data tables in the dashboard.
423 wp_register_script(
424 'jquery_datatables',
425 plugins_url( '../assets/js/jquery.dataTables.min.js', __FILE__ ),
426 array(),
427 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
428 false
429 );
430 // Register jQuery DataTables Responsive to use data tables in the dashboard.
431 wp_register_script(
432 'jquery_datatables_responsive',
433 plugins_url( '../assets/js/dataTables.responsive.min.js', __FILE__ ),
434 array(),
435 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
436 false
437 );
438 // Ajax call to WPDA datatables implementation to use data tables in the dashboard.
439 wp_register_script(
440 'wpda_datatables',
441 plugins_url( '../assets/js/wpda_datatables.js', __FILE__ ),
442 array(),
443 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
444 false
445 );
446 wp_localize_script( 'wpda_datatables', 'wpda_publication_vars', array(
447 'wpda_ajaxurl' => admin_url( 'admin-ajax.php' ),
448 ) );
449 // Register notify external library.
450 wp_enqueue_script(
451 'wpda_notify',
452 plugins_url( '../assets/js/notify.min.js', __FILE__ ),
453 array(),
454 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
455 false
456 );
457 // Register datetimepicker external library.
458 wp_register_script(
459 'datetimepicker',
460 plugins_url( '../assets/js/jquery.datetimepicker.full.min.js', __FILE__ ),
461 array(),
462 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
463 false
464 );
465 // Register clipboard.js.
466 wp_enqueue_script( 'clipboard' );
467 if ( self::PAGE_PUBLISHER === $this->page ) {
468 if ( isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], array('view', 'new', 'edit'), true ) ) {
469 $json_editing = WPDA::get_option( WPDA::OPTION_DP_JSON_EDITING );
470 if ( WPDA::OPTION_DP_JSON_EDITING[1] === $json_editing ) {
471 // Register codeEditor to support JSON editing in Data Tables (table options advanced).
472 $cm_settings['codeEditor'] = wp_enqueue_code_editor( array(
473 'type' => 'application/json',
474 'codemirror' => array(
475 'autoRefresh' => true,
476 ),
477 ) );
478 wp_localize_script( 'wp-theme-plugin-editor', 'cm_settings', $cm_settings );
479 wp_enqueue_script( 'wp-theme-plugin-editor' );
480 }
481 // Add jQuery multiselect resources.
482 wp_enqueue_script(
483 'wpda_jquery_multiselect',
484 plugins_url( '../assets/js/jquery.multiselect.sortable.js', __FILE__ ),
485 array(),
486 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
487 false
488 );
489 }
490 }
491 if ( self::PAGE_CHARTS === $this->page ) {
492 $this->load_google_charts();
493 }
494 if ( self::PAGE_QUERY_BUILDER === $this->page ) {
495 // Add Query Builder resources.
496 wp_enqueue_script(
497 'wpda_query_builder',
498 plugins_url( '../assets/js/wpda_query_builder.js', __FILE__ ),
499 array(),
500 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
501 false
502 );
503 wp_enqueue_script(
504 'wpda_jquery_xml2json',
505 plugins_url( '../assets/js/jquery.xml2json.js', __FILE__ ),
506 array(),
507 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
508 false
509 );
510 wp_enqueue_script(
511 'wpda_jquery_json_viewer',
512 plugins_url( '../assets/js/jquery.json-viewer.js', __FILE__ ),
513 array(),
514 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
515 false
516 );
517 // Add codeEditor to query builder.
518 $cm_settings['codeEditor'] = wp_enqueue_code_editor( array(
519 'type' => 'text/x-sql',
520 'codemirror' => array(
521 'mode' => 'sql',
522 'lineNumbers' => true,
523 'autoRefresh' => true,
524 'lineWrapping' => true,
525 'styleActiveLine' => true,
526 ),
527 ) );
528 wp_enqueue_script( 'wp-theme-plugin-editor' );
529 wp_localize_script( 'wp-theme-plugin-editor', 'cm_settings', $cm_settings );
530 wp_enqueue_style( 'wp-codemirror' );
531 }
532 if ( self::PAGE_DASHBOARD === $this->page ) {
533 $this->load_google_charts();
534 // Load DBMS panels.
535 wp_enqueue_script(
536 'wpda_dbms',
537 plugins_url( '../assets/js/wpda_dbms.js', __FILE__ ),
538 array(),
539 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
540 false
541 );
542 wp_localize_script( 'wpda_dbms', 'wpda_dbms_vars', array(
543 'wpda_ajaxurl' => admin_url( 'admin-ajax.php' ),
544 ) );
545 }
546 wp_enqueue_media();
547 }
548
549 /**
550 * Load Google Charts resources
551 *
552 * @return void
553 */
554 private function load_google_charts() {
555 // Load Google Charts.
556 wp_enqueue_script(
557 'wpda_google_charts',
558 WPDA::GOOGLE_CHARTS,
559 array(),
560 null,
561 false
562 );
563 wp_enqueue_script(
564 'wpda_google_charts_fnc',
565 plugins_url( '../assets/js/wpda_google_charts.js', __FILE__ ),
566 array(),
567 WPDA::get_option( WPDA::OPTION_WPDA_VERSION ),
568 false
569 );
570 wp_localize_script( 'wpda_google_charts_fnc', 'wpda_chart_vars', array(
571 'wpda_ajaxurl' => admin_url( 'admin-ajax.php' ),
572 'wpda_chartdir' => plugin_dir_url( __FILE__ ) . '../assets/images/google_chart_types/',
573 'wpda_premium' => ( wpda_freemius()->can_use_premium_code__premium_only() ? 'true' : 'false' ),
574 ) );
575 }
576
577 /**
578 * Hide admin notices
579 *
580 * @return void
581 */
582 public function user_admin_notices() {
583 if ( WPDA::is_plugin_page( $this->page ) && 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_HIDE_NOTICES ) ) {
584 remove_all_actions( 'admin_notices' );
585 remove_all_actions( 'all_admin_notices' );
586 }
587 }
588
589 /**
590 * Add plugin menu and sub menus
591 *
592 * Adds the following menu and sub menus to the back-end menu:
593 * + WP Data Access
594 * + Data Explorer
595 * + Data Designer
596 * + Data Projects
597 * + Manage Plugin
598 *
599 * @since 1.0.0
600 */
601 public function add_menu_items() {
602 if ( current_user_can( 'manage_options' ) ) {
603 if ( 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_HIDE_ADMIN_MENU ) ) {
604 // Show Data Projects.
605 $this->add_data_projects();
606 // Hide admin menu.
607 return;
608 }
609 if ( self::PAGE_MAIN === $this->page && isset( $_REQUEST['de'] ) ) {
610 if ( 'new' === $_REQUEST['de'] ) {
611 update_user_meta( WPDA::get_current_user_id(), 'wpda_data_explorer', 'new' );
612 }
613 if ( 'old' === $_REQUEST['de'] ) {
614 delete_user_meta( WPDA::get_current_user_id(), 'wpda_data_explorer' );
615 }
616 }
617 // Specific list tables (and forms) can be made available for specific capabilities:
618 // managed in method add_menu_my_tables.
619 // Main menu and items are only available to admin users (set capability to 'manage_options').
620 add_menu_page(
621 'WP Data Access',
622 'WP Data Access',
623 'manage_options',
624 self::PAGE_MAIN,
625 null,
626 'dashicons-database',
627 999999999
628 );
629 // Add data explorer to WPDA menu.
630 $current_data_explorer_version = get_user_meta( WPDA::get_current_user_id(), 'wpda_data_explorer', true );
631 $this->wpda_data_explorer_menu = add_submenu_page(
632 self::PAGE_MAIN,
633 'WP Data Access',
634 'Data Explorer',
635 'manage_options',
636 self::PAGE_MAIN,
637 array($this, ( 'new' !== $current_data_explorer_version ? 'data_explorer_page' : 'data_explorer_page_new' ))
638 );
639 if ( self::PAGE_MAIN === $this->page ) {
640 if ( 'new' !== $current_data_explorer_version ) {
641 $args = array(
642 'page_hook_suffix' => $this->wpda_data_explorer_menu,
643 );
644 $this->wpda_data_explorer_view = new WPDA_List_View($args);
645 }
646 }
647 // Add apps to menu.
648 add_submenu_page(
649 self::PAGE_MAIN,
650 'App Builder',
651 'App Builder',
652 'manage_options',
653 self::PAGE_APPS,
654 array($this, 'data_apps')
655 );
656 // Add dashboard to menu.
657 add_submenu_page(
658 self::PAGE_MAIN,
659 'Dashboards',
660 'Dashboards',
661 'manage_options',
662 self::PAGE_DASHBOARD,
663 array($this, 'data_dashboard_page')
664 );
665 // Add submenu for Data Tables.
666 $this->wpda_data_publisher_menu = add_submenu_page(
667 self::PAGE_MAIN,
668 'WP Data Access',
669 'Table Builder',
670 'manage_options',
671 self::PAGE_PUBLISHER,
672 array($this, 'data_publisher_page')
673 );
674 if ( self::PAGE_PUBLISHER === $this->page ) {
675 $this->wpda_data_publisher_view = new WPDA_List_View(array(
676 'page_hook_suffix' => $this->wpda_data_publisher_menu,
677 'table_name' => WPDA_Publisher_Model::get_base_table_name(),
678 'list_table_class' => 'WPDataAccess\\Data_Publisher\\WPDA_Publisher_List_Table',
679 'edit_form_class' => 'WPDataAccess\\Data_Publisher\\WPDA_Publisher_Form',
680 ));
681 }
682 // Add Data Projects menu.
683 $wpdp = new WPDP(self::PAGE_MAIN);
684 $wpdp->add_menu_items();
685 // Add data designer to WPDA menu.
686 $this->wpda_data_designer_menu = add_submenu_page(
687 self::PAGE_MAIN,
688 'WP Data Access',
689 'Data Designer',
690 'manage_options',
691 self::PAGE_DESIGNER,
692 array($this, 'data_designer_page')
693 );
694 if ( self::PAGE_DESIGNER === $this->page ) {
695 $this->wpda_data_designer_view = new WPDA_List_View(array(
696 'page_hook_suffix' => $this->wpda_data_designer_menu,
697 'table_name' => WPDA_Design_Table_Model::get_base_table_name(),
698 'list_table_class' => 'WPDataAccess\\Design_Table\\WPDA_Design_Table_List_Table',
699 'edit_form_class' => 'WPDataAccess\\Design_Table\\WPDA_Design_Table_Form',
700 'subtitle' => '',
701 ));
702 }
703 } else {
704 $this->grant_access_to_dashboard();
705 $this->grant_access_to_data_publications();
706 }
707 $this->add_data_projects();
708 $this->add_apps();
709 // Add submenu for Query Builder.
710 $this->wpda_data_publisher_menu = add_submenu_page(
711 self::PAGE_MAIN,
712 'WP Data Access',
713 'Query Builder',
714 'manage_options',
715 self::PAGE_QUERY_BUILDER,
716 array($this, 'query_builder')
717 );
718 }
719
720 /**
721 * Remove plugin sub menu items (when in dashboard mode)
722 *
723 * @param mixed $submenu_file Dashboard menu items.
724 * @return mixed
725 */
726 public function wpda_submenu_filter( $submenu_file ) {
727 if ( current_user_can( 'manage_options' ) ) {
728 $hidden_submenus = array(
729 // self::PAGE_APPS,
730 self::PAGE_DASHBOARD,
731 self::PAGE_DESIGNER,
732 WPDP::PAGE_TEMPLATES,
733 'wpda-account',
734 'wpda-wp-support-forum',
735 );
736 foreach ( $hidden_submenus as $submenu ) {
737 remove_submenu_page( self::PAGE_MAIN, $submenu );
738 }
739 } else {
740 global $submenu;
741 $submenu[self::PAGE_MAIN][0][2] = self::PAGE_DASHBOARD;
742 // phpcs:ignore WordPress.WP.GlobalVariablesOverride
743 }
744 return $submenu_file;
745 }
746
747 /**
748 * Add apps to dashboard menu.
749 *
750 * @return void
751 */
752 protected function add_apps() {
753 // Add apps to dashbaord menu
754 $apps = new WPDA_Apps();
755 $apps->add_apps_to_menu();
756 }
757
758 /**
759 * Add Data Projects and Project Templates to plugin navigation
760 *
761 * @return void
762 */
763 protected function add_data_projects() {
764 // Add Data Projects.
765 $wpdp = new WPDP();
766 $wpdp->add_projects();
767 }
768
769 /**
770 * Allow authorized users to access WP Data Access dashboard
771 *
772 * @return void
773 */
774 protected function grant_access_to_dashboard() {
775 // Check user role.
776 $user_roles = WPDA::get_current_user_roles();
777 if ( false === $user_roles || !is_array( $user_roles ) ) {
778 // Cannot determine the user roles (not able to show menus).
779 return;
780 }
781 // Check dashboard role access.
782 $dashboard_roles = get_option( \WPDataAccess\Settings\WPDA_Settings_Dashboard::DASHBOARD_ROLES );
783 $user_has_role = false;
784 foreach ( $user_roles as $user_role ) {
785 if ( false !== strpos( $dashboard_roles, $user_role ) ) {
786 $user_has_role = true;
787 break;
788 }
789 }
790 // Check dashboard user access.
791 $dashboard_users = get_option( \WPDataAccess\Settings\WPDA_Settings_Dashboard::DASHBOARD_USERS );
792 $user_has_access = false !== strpos( $dashboard_users, WPDA::get_current_user_login() );
793 if ( !$user_has_role && !$user_has_access ) {
794 return;
795 }
796 // User has dashboard access: add menu item.
797 $this->create_non_admin_menu( self::PAGE_DASHBOARD );
798 add_submenu_page(
799 $this->first_page,
800 'Dashboard',
801 'Dashboard',
802 WPDA::get_current_user_capability(),
803 self::PAGE_DASHBOARD,
804 array($this, 'data_dashboard_page')
805 );
806 }
807
808 /**
809 * Allow authorized users to access Data Tables
810 *
811 * @return void
812 */
813 protected function grant_access_to_data_publications() {
814 // Check user role.
815 $user_roles = WPDA::get_current_user_roles();
816 if ( false === $user_roles || !is_array( $user_roles ) ) {
817 // Cannot determine the user roles (not able to show menus).
818 return;
819 }
820 $publication_roles = WPDA::get_option( WPDA::OPTION_DP_PUBLICATION_ROLES );
821 if ( '' === $publication_roles || 'administrator' === $publication_roles ) {
822 // No access.
823 return;
824 }
825 $user_has_role = false;
826 foreach ( $user_roles as $user_role ) {
827 if ( false !== stripos( $publication_roles, $user_role ) ) {
828 $user_has_role = true;
829 }
830 }
831 if ( !$user_has_role ) {
832 // No access.
833 return;
834 }
835 // Grant access to main menu.
836 $this->create_non_admin_menu( self::PAGE_PUBLISHER );
837 // Add submenu for Data Tables.
838 $this->wpda_data_publisher_menu = add_submenu_page(
839 $this->first_page,
840 'WP Data Access',
841 'Data Tables',
842 WPDA::get_current_user_capability(),
843 self::PAGE_PUBLISHER,
844 array($this, 'data_publisher_page')
845 );
846 if ( self::PAGE_PUBLISHER === $this->page ) {
847 global $wpdb;
848 $this->wpda_data_publisher_view = new WPDA_List_View(array(
849 'page_hook_suffix' => $this->wpda_data_publisher_menu,
850 'table_name' => $wpdb->prefix . 'wpda_publisher',
851 'list_table_class' => 'WPDataAccess\\Data_Publisher\\WPDA_Publisher_List_Table',
852 'edit_form_class' => 'WPDataAccess\\Data_Publisher\\WPDA_Publisher_Form',
853 ));
854 }
855 }
856
857 /**
858 * Add dashboard page
859 *
860 * @return void
861 */
862 public function data_dashboard_page() {
863 WPDA_Dashboard::add_dashboard( true );
864 }
865
866 /**
867 * Show data explorer main page
868 *
869 * Initialization of $this->wpda_data_explorer_view is done earlier in
870 * {@see WP_Data_Access_Admin::add_menu_items()} to support screen options. This method just shows the page
871 * containing the list table.
872 *
873 * @since 1.0.0
874 *
875 * @see WP_Data_Access_Admin::add_menu_items()
876 */
877 public function data_explorer_page() {
878 WPDA_Dashboard::add_dashboard();
879 if ( isset( $_REQUEST['page_action'] ) && 'wpda_backup' === $_REQUEST['page_action'] ) {
880 // phpcs:ignore WordPress.Security.NonceVerification
881 $this->backup_page();
882 } elseif ( isset( $_REQUEST['page_action'] ) && 'wpda_import_csv' === $_REQUEST['page_action'] ) {
883 // phpcs:ignore WordPress.Security.NonceVerification
884 $this->import_csv();
885 } elseif ( isset( $_REQUEST['page_action'] ) && 'wpda_global_search' === $_REQUEST['page_action'] ) {
886 // phpcs:ignore WordPress.Security.NonceVerification
887 $this->advanced_search();
888 } else {
889 $this->wpda_data_explorer_view->show();
890 }
891 }
892
893 public function data_explorer_page_new() {
894 WPDA_Dashboard::add_dashboard();
895 if ( isset( $_REQUEST['page_action'] ) && 'wpda_backup' === $_REQUEST['page_action'] ) {
896 // phpcs:ignore WordPress.Security.NonceVerification
897 $this->backup_page();
898 } elseif ( isset( $_REQUEST['page_action'] ) && 'wpda_import_csv' === $_REQUEST['page_action'] ) {
899 // phpcs:ignore WordPress.Security.NonceVerification
900 $this->import_csv();
901 } elseif ( isset( $_REQUEST['page_action'] ) && 'wpda_global_search' === $_REQUEST['page_action'] ) {
902 // phpcs:ignore WordPress.Security.NonceVerification
903 $this->advanced_search();
904 } else {
905 $explorer = new WPDA_Explorer_Container();
906 $explorer->show();
907 }
908 }
909
910 public function data_apps() {
911 WPDA_Dashboard::add_dashboard();
912 $wpda_apps_list = new WPDA_Apps_List();
913 $wpda_apps_list->show();
914 }
915
916 public function advanced_search() {
917 $advanced_search = new WPDA_Global_Search();
918 $advanced_search->show();
919 }
920
921 /**
922 * Add Query Builder
923 *
924 * @return void
925 */
926 public function query_builder() {
927 WPDA_Dashboard::add_dashboard();
928 $query_builder = new WPDA_Query_Builder();
929 $query_builder->show();
930 }
931
932 /**
933 * Add CSV page
934 *
935 * @return void
936 */
937 public function import_csv() {
938 $csv_import = new WPDA_CSV_Import();
939 $csv_import->show();
940 }
941
942 /**
943 * Show data designer main page
944 *
945 * Initialization of $this->wpda_data_designer_view is done earlier in
946 * {@see WP_Data_Access_Admin::add_menu_items()} to support screen options. This method just shows the page
947 * containing the list table.
948 *
949 * @since 1.0.0
950 *
951 * @see WP_Data_Access_Admin::add_menu_items()
952 */
953 public function data_designer_page() {
954 WPDA_Dashboard::add_dashboard();
955 $data_designer_table_found = WPDA_Design_Table_Model::table_exists();
956 if ( $data_designer_table_found ) {
957 $this->wpda_data_designer_view->show();
958 } else {
959 $this->data_designer_page_not_found();
960 }
961 }
962
963 /**
964 * Data Designer repository table not found
965 */
966 public function data_designer_page_not_found() {
967 WPDA_Dashboard::add_dashboard();
968 $wpda_repository = new WPDA_Repository();
969 $wpda_repository->inform_user();
970 ?>
971 <div class="wrap">
972 <h1 class="wp-heading-inline">
973 <span>Data Designer</span>
974 <a href="https://wpdataaccess.com/docs/data-designer/data-designer-getting-started/" target="_blank" class="wpda_tooltip" title="Plugin Help - opens in a new tab or window">
975 <span class="dashicons dashicons-editor-help" style="text-decoration:none;vertical-align:top;font-size:30px;">
976 </span>
977 </a>
978 </h1>
979 <p>
980 <?php
981 echo __( 'ERROR: Repository table not found!', 'wp-data-access' );
982 // phpcs:ignore WordPress.Security.EscapeOutput
983 ?>
984 </p>
985 </div>
986 <?php
987 }
988
989 /**
990 * Show Data Tables main page
991 */
992 public function data_publisher_page() {
993 if ( current_user_can( 'manage_options' ) ) {
994 WPDA_Dashboard::add_dashboard();
995 }
996 $data_publisher_table_found = WPDA_Publisher_Model::table_exists();
997 if ( $data_publisher_table_found ) {
998 $this->wpda_data_publisher_view->show();
999 } else {
1000 $this->data_publisher_page_not_found();
1001 }
1002 }
1003
1004 public function data_publisher_mngstl() {
1005 $mngstl = new WPDAPRO_Data_Publisher_Manage_Styles();
1006 $mngstl->show();
1007 }
1008
1009 /**
1010 * Add Charts page
1011 *
1012 * @return void
1013 */
1014 public function data_charts_page() {
1015 }
1016
1017 /**
1018 * Data Tables repository table not found
1019 */
1020 public function data_publisher_page_not_found() {
1021 if ( current_user_can( 'manage_options' ) ) {
1022 WPDA_Dashboard::add_dashboard();
1023 }
1024 $wpda_repository = new WPDA_Repository();
1025 $wpda_repository->inform_user();
1026 ?>
1027 <div class="wrap">
1028 <h1 class="wp-heading-inline">
1029 <span>Data Tables</span>
1030 <a href="https://wpdataaccess.com/docs/data-tables/data-tables-getting-started/" target="_blank" class="wpda_tooltip" title="Plugin Help - opens in a new tab or window">
1031 <span class="dashicons dashicons-editor-help" style="text-decoration:none;vertical-align:top;font-size:30px;">
1032 </span>
1033 </a>
1034 </h1>
1035 <p>
1036 <?php
1037 echo __( 'ERROR: Repository table not found!', 'wp-data-access' );
1038 // phpcs:ignore WordPress.Security.EscapeOutput
1039 ?>
1040 </p>
1041 </div>
1042 <?php
1043 }
1044
1045 /**
1046 * Show data backup main page
1047 *
1048 * Calls a page to create automatic backups (in fact data exports) and offers possibilities to restore (in fact
1049 * data imports).
1050 *
1051 * @since 2.0.6
1052 *
1053 * @see WPDA_Data_Export::show_wp_cron()
1054 */
1055 public function backup_page() {
1056 $wpda_backup = new WPDA_Data_Export();
1057 if ( isset( $_REQUEST['action'] ) ) {
1058 // phpcs:ignore WordPress.Security.NonceVerification
1059 $action = sanitize_text_field( wp_unslash( $_REQUEST['action'] ) );
1060 // phpcs:ignore WordPress.Security.NonceVerification
1061 if ( 'new' === $action ) {
1062 $wpda_backup->create_export( 'add' );
1063 } elseif ( 'add' === $action ) {
1064 $wpda_backup->wpda_add_cron_job();
1065 } elseif ( 'remove' === $action ) {
1066 $wpda_backup->wpda_remove_cron_job();
1067 } elseif ( 'edit' === $action ) {
1068 $wpda_backup->create_export( 'update' );
1069 } elseif ( 'update' === $action ) {
1070 $wpda_backup->wpda_update_cron_job();
1071 }
1072 } else {
1073 $wpda_backup->show_wp_cron();
1074 }
1075 }
1076
1077 /**
1078 * Add user defined sub menu
1079 *
1080 * WPDA allows users to create sub menu for table lists and simple forms. Sub menus can be added to the WPDA
1081 * menu or any other (external) menu. A sub menu is added to an external menu via the menu slug. Sub menus are
1082 * taken from {@see WPDA_User_Menus_Model}.
1083 *
1084 * This method is called from the admin_menu action with a lower priority to make sure other menus are available.
1085 * User defined menu items are added to available menus in this method. These can be WPDA menus or external menus
1086 * as mentioned in the according list table and edit form. WPDA menus are added to menu WP Data Tables. External
1087 * menus are added to the menu having the menu slug defined by the user.
1088 *
1089 * This method does not actually show the list tables! It just creates the menu items. When the user clicks on such
1090 * a dynamically defined menu item, method {@see WP_Data_Access_Admin::my_tables_page()} is called, which takes
1091 * care of showing the list table.
1092 *
1093 * @since 1.0.0
1094 *
1095 * @see WP_Data_Access_Admin::my_tables_page()
1096 * @see WPDA_User_Menus_Model
1097 */
1098 public function add_menu_my_tables() {
1099 $menus_shown_to_current_user = array();
1100 // Add list tables to external menus.
1101 foreach ( WPDA_User_Menus_Model::list_external_menus() as $menu ) {
1102 $user_roles = WPDA::get_current_user_roles();
1103 $user_has_role = false;
1104 if ( '' === $menu->menu_role || null === $menu->menu_role ) {
1105 $user_has_role = in_array( 'administrator', $user_roles, true );
1106 } else {
1107 $user_role_array = explode( ',', (string) $menu->menu_role );
1108 //phpcs:ignore - 8.1 proof
1109 foreach ( $user_role_array as $user_role_array_item ) {
1110 $user_has_role = in_array( $user_role_array_item, $user_roles, true );
1111 //phpcs:ignore - 8.1 proof
1112 if ( $user_has_role ) {
1113 break;
1114 }
1115 }
1116 }
1117 if ( $user_has_role ) {
1118 if ( !isset( $menus_shown_to_current_user[$menu->menu_slug . '/' . $menu->menu_name . '/' . $menu->menu_table_name . '/' . $menu->menu_schema_name] ) ) {
1119 $menu_slug = self::PAGE_EXPLORER . '_' . $menu->menu_table_name;
1120 $menu_index = $menu->menu_table_name;
1121 $this->create_non_admin_menu( $menu_slug );
1122 $this->wpda_my_table_list_menu[$menu_index] = add_submenu_page(
1123 $this->first_page,
1124 'WP Data Access : ' . strtoupper( $menu->menu_table_name ),
1125 $menu->menu_name,
1126 WPDA::get_current_user_capability(),
1127 $menu_slug,
1128 array($this, 'my_tables_page')
1129 );
1130 $this->wpda_my_table_list_view[$menu_index] = new WPDA_List_View(array(
1131 'page_hook_suffix' => $this->wpda_my_table_list_menu[$menu_index],
1132 'wpdaschema_name' => $menu->menu_schema_name,
1133 'table_name' => $menu->menu_table_name,
1134 ));
1135 $menus_shown_to_current_user[$menu->menu_slug . '/' . $menu->menu_name . '/' . $menu_index . '/' . $menu->menu_schema_name] = true;
1136 }
1137 }
1138 }
1139 }
1140
1141 /**
1142 * Show user defined menus
1143 *
1144 * A user defined menu that are added to the plugin menu in {@see WP_Data_Access_Admin::add_menu_my_tables()} is
1145 * shown here. This method is called when the user clicks on the menu item generated in
1146 * {@see WP_Data_Access_Admin::add_menu_my_tables()}.
1147 *
1148 * @since 1.0.0
1149 *
1150 * @see WP_Data_Access_Admin::add_menu_my_tables()
1151 */
1152 public function my_tables_page() {
1153 // Grab table name from menu slug.
1154 if ( null !== $this->page ) {
1155 if ( strpos( $this->page, self::PAGE_EXPLORER ) !== false ) {
1156 $table = substr( $this->page, strlen( self::PAGE_EXPLORER . '_' ) );
1157 } else {
1158 $table = substr( $this->page, strlen( self::PAGE_MY_TABLES . '_' ) );
1159 }
1160 // Show list table.
1161 $this->wpda_my_table_list_view[$table]->show();
1162 }
1163 }
1164
1165 /**
1166 * Add main menu for non admin user
1167 *
1168 * @param string $first_page First plugin page.
1169 * @return void
1170 */
1171 protected function create_non_admin_menu( $first_page ) {
1172 if ( !$this->loaded_user_main_menu ) {
1173 add_menu_page(
1174 'WP Data Access',
1175 'WP Data Access',
1176 WPDA::get_current_user_capability(),
1177 $first_page,
1178 function () {
1179 },
1180 'dashicons-database-view',
1181 999999999
1182 );
1183 $this->loaded_user_main_menu = true;
1184 $this->first_page = $first_page;
1185 }
1186 }
1187
1188 }
1189