PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.22
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.22
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 5.5.43 All 159 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.22, at admin/class-wp-data-access-admin.php

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