PluginProbe
WP Data Access – App Builder for Tables, Forms, Dashboards, Charts & Maps / 5.5.87
WP Data Access – App Builder for Tables, Forms, Dashboards, Charts & Maps v5.5.87
5.5.87 5.5.85 5.5.84 5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 All 162 releases
wp-data-access / WPDataAccess / Dashboard / WPDA_Dashboard.php

WPDA_Dashboard.php in WP Data Access – App Builder for Tables, Forms, Dashboards, Charts & Maps 5.5.87, at WPDataAccess/Dashboard/WPDA_Dashboard.php

2,004 lines 66.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- verified on page
4 namespace WPDataAccess\Dashboard;
5
6 use WP_Data_Access_Admin;
7 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Lists;
8 use WPDataAccess\Plugin_Table_Models\WPDA_App_Model;
9 use WPDataAccess\Plugin_Table_Models\WPDA_Design_Table_Model;
10 use WPDataAccess\Plugin_Table_Models\WPDA_Publisher_Model;
11 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Model;
12 use WPDataAccess\Premium\WPDAPRO_Dashboard\WPDAPRO_Dashboard;
13 use WPDataAccess\Premium\WPDAPRO_Dashboard\WPDAPRO_Widget_Project;
14 use WPDataAccess\Premium\WPDAPRO_Data_Forms\WPDAPRO_Data_Forms_Init;
15 use WPDataAccess\Utilities\WPDA_Message_Box;
16 use WPDataAccess\WPDA;
17 use WPDataAccess\Connection\WPDADB;
18 use WPDataProjects\WPDP;
19 use WPDataAccess\Settings\WPDA_Settings_Legacy_Dashboard;
20 /**
21 * Dashboard class
22 */
23 class WPDA_Dashboard {
24 /**
25 * Nonce seed
26 */
27 const DASHBOARD_SAVE = 'WPDA_DASHBOARD_SAVE';
28
29 /**
30 * Nonce seed
31 */
32 const USER_DASHBOARD = 'wpda-user-dashboard-widgets';
33
34 /**
35 * Meta key
36 */
37 const USER_NEW_MESSAGE = 'wpda_new_dashboard_message';
38
39 /**
40 * Available dashboards
41 *
42 * @var array|null
43 */
44 protected $dashboards = null;
45
46 /**
47 * Number of dashboard columns
48 *
49 * @var int
50 */
51 protected $number_of_columns = 2;
52
53 /**
54 * Nonce for adding objects
55 *
56 * @var null
57 */
58 protected $wp_nonce_add = null;
59
60 /**
61 * Nonce for save actions
62 *
63 * @var null
64 */
65 protected $wp_nonce_save = null;
66
67 /**
68 * Current dashboard
69 *
70 * @var WPDAPRO_Dashboard|null
71 */
72 protected $dashboard = null;
73
74 /**
75 * Widgets on current dashboard
76 *
77 * @var array|null
78 */
79 protected $dashboard_widgets = null;
80
81 /**
82 * Dashboard positions of all visible objects
83 *
84 * @var array|null
85 */
86 protected $dashboard_positions = null;
87
88 /**
89 * Shared dashboards
90 *
91 * @var array
92 */
93 protected $shared_dashboards = array();
94
95 /**
96 * Dashboard access
97 *
98 * @var array
99 */
100 protected $shared_access = array();
101
102 /**
103 * Locked dashboards
104 *
105 * @var array
106 */
107 protected $shared_locked = array();
108
109 /**
110 * Locked dashboards
111 *
112 * @var array
113 */
114 protected $locked_dashboards = array();
115
116 /**
117 * Indicates if current user can create dashboards
118 *
119 * @var bool
120 */
121 protected $cannot_create_dashboard = false;
122
123 /**
124 * Available tabs on current dashboard
125 *
126 * @var string[]
127 */
128 protected $tabs = array('Default');
129
130 /**
131 * Current tabs
132 *
133 * @var int|mixed|string|null
134 */
135 protected $tab = 'Default';
136
137 /**
138 * Current tab label
139 *
140 * @var string
141 */
142 protected $tab_name = '';
143
144 /**
145 * Current tab index
146 *
147 * @var false|int|string
148 */
149 protected $tab_index = 0;
150
151 /**
152 * Indicates if default tab show be hidden
153 *
154 * @var bool
155 */
156 protected $hide_default_tab = false;
157
158 /**
159 * Indicates if dashboard is locked
160 *
161 * @var bool
162 */
163 protected $is_locked = false;
164
165 /**
166 * Message
167 *
168 * @var null
169 */
170 protected $message = null;
171
172 /**
173 * Message type
174 *
175 * @var string|null
176 */
177 protected $message_type = null;
178
179 private $option_legacy_tools;
180
181 /**
182 * Constructor
183 *
184 * @param boolean $widget_mode True = allowed to manage dashboards and widgets.
185 */
186 public function __construct( $widget_mode = false ) {
187 if ( $widget_mode ) {
188 // Prepare nonces.
189 $this->wp_nonce_add = wp_create_nonce( WPDA_Widget::WIDGET_ADD . WPDA::get_current_user_login() );
190 $this->wp_nonce_save = wp_create_nonce( static::DASHBOARD_SAVE . WPDA::get_current_user_login() );
191 // Load Data Tables resources.
192 \WPDataAccess\Data_Tables\WPDA_Data_Tables::enqueue_styles_and_script();
193 }
194 // Start with empty array.
195 if ( $widget_mode ) {
196 update_user_meta( WPDA::get_current_user_id(), self::USER_DASHBOARD, array() );
197 }
198 $this->option_legacy_tools = WPDA::get_option( WPDA::OPTION_PLUGIN_LEGACY_TOOLS );
199 }
200
201 /**
202 * Add dashboard
203 *
204 * @param boolean $widget_mode True = user is allowed to manage dashboards.
205 *
206 * @return void
207 */
208 public static function add_dashboard( $widget_mode = false ) {
209 $dashboard = new WPDA_Dashboard($widget_mode);
210 $dashboard->dashboard();
211 }
212
213 /**
214 * Construct plugin dashboard
215 *
216 * @return void
217 */
218 public function dashboard() {
219 wp_enqueue_style( 'wpdataaccess_dashboard' );
220 wp_enqueue_script( 'wpdataaccess_dashboard' );
221 if ( WPDA::current_user_is_admin() ) {
222 $this->dashboard_default();
223 $this->dashboard_mobile();
224 }
225 if ( isset( $_REQUEST['page'] ) ) {
226 switch ( $_REQUEST['page'] ) {
227 case 'wpda_dashboard':
228 $this->toolbar();
229 $this->add_forms();
230 $this->tabs();
231 $this->columns();
232 $this->add_panels();
233 $this->dashboard_js();
234 break;
235 case WP_Data_Access_Admin::PAGE_MAIN:
236 if ( !isset( $_REQUEST['page_action'] ) ) {
237 $this->toolbar_wpda();
238 } elseif ( 'wpda_backup' === $_REQUEST['page_action'] && (!isset( $_REQUEST['action'] ) || 'remove' === $_REQUEST['action'] || 'update' === $_REQUEST['action'] || 'add' === $_REQUEST['action']) ) {
239 $this->toolbar_backup();
240 } elseif ( 'wpda_import_csv' === $_REQUEST['page_action'] ) {
241 $this->toolbar_import_csv();
242 }
243 break;
244 case WP_Data_Access_Admin::PAGE_APPS:
245 $this->toolbar_apps();
246 break;
247 case WP_Data_Access_Admin::PAGE_DESIGNER:
248 if ( !isset( $_REQUEST['action'] ) || 'new' !== $_REQUEST['action'] && 'edit' !== $_REQUEST['action'] ) {
249 $this->toolbar_designer();
250 }
251 break;
252 case WP_Data_Access_Admin::PAGE_PUBLISHER:
253 if ( (!isset( $_REQUEST['action'] ) || 'new' !== $_REQUEST['action'] && 'edit' !== $_REQUEST['action'] || isset( $_REQUEST['postaction'] ) && 'list' === $_REQUEST['postaction']) && !(isset( $_REQUEST['page_action'] ) && 'wpda_mngstl' === $_REQUEST['page_action']) ) {
254 $this->toolbar_publisher();
255 }
256 break;
257 case WP_Data_Access_Admin::PAGE_CHARTS:
258 $this->toolbar_charts();
259 break;
260 case WPDP::PAGE_MAIN:
261 if ( !isset( $_REQUEST['action'] ) || 'new' !== $_REQUEST['action'] && 'edit' !== $_REQUEST['action'] ) {
262 $this->toolbar_projects();
263 }
264 break;
265 case WPDP::PAGE_TEMPLATES:
266 if ( !isset( $_REQUEST['action'] ) || 'new' !== $_REQUEST['action'] && 'edit' !== $_REQUEST['action'] ) {
267 $this->toolbar_templates();
268 }
269 break;
270 }
271 }
272 if ( isset( $_GET['page_iaction'] ) ) {
273 // Perform interactive action to auto start user selected feature.
274 ?>
275 <script>
276 jQuery(function() {
277 const iaction = "<?php
278 // phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash
279 echo esc_attr( sanitize_text_field( $_GET['page_iaction'] ) );
280 // phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash
281 ?>";
282 switch (iaction) {
283 case "create_new_app":
284 var interval = setInterval(
285 function() {
286 if (window.ppActionCreateApp !== undefined) {
287 window.ppActionCreateApp();
288 clearInterval(interval);
289 }
290 }, 100);
291 break;
292 case "wpda_import_sql":
293 var interval = setInterval(
294 function() {
295 if (window.ppActionEnableImport !== undefined) {
296 window.ppActionEnableImport();
297 clearInterval(interval);
298 }
299 }, 100);
300 break;
301 case "manage_databases":
302 jQuery('#wpda_manage_databases').show();
303 jQuery('#local_database').focus();
304 break;
305 }
306 });
307 </script>
308 <?php
309 }
310 }
311
312 /**
313 * Get correct help url for current page
314 *
315 * @return string
316 */
317 protected function get_help_url() {
318 $help_url = 'https://docs.wpdataaccess.com/';
319 if ( isset( $_REQUEST['page'] ) ) {
320 switch ( $_REQUEST['page'] ) {
321 case \WP_Data_Access_Admin::PAGE_MAIN:
322 $help_url = 'https://docs.explorer.wpdataaccess.com/';
323 break;
324 case \WP_Data_Access_Admin::PAGE_APPS:
325 $help_url = 'https://docs.rad.wpdataaccess.com/';
326 break;
327 case \WP_Data_Access_Admin::PAGE_QUERY_BUILDER:
328 $help_url = 'https://docs.sql.wpdataaccess.com/';
329 break;
330 case \WP_Data_Access_Admin::PAGE_DESIGNER:
331 $help_url = 'https://docs.legacy.wpdataaccess.com/docs/data-designer-getting-started/';
332 break;
333 case \WP_Data_Access_Admin::PAGE_PUBLISHER:
334 $help_url = 'https://docs.legacy.wpdataaccess.com/docs/data-tables-getting-started/';
335 break;
336 case \WP_Data_Access_Admin::PAGE_DASHBOARD:
337 $help_url = 'https://docs.legacy.wpdataaccess.com/docs/bi-getting-started/';
338 break;
339 case \WP_Data_Access_Admin::PAGE_CHARTS:
340 $help_url = 'https://docs.legacy.wpdataaccess.com/docs/chart-widgets/';
341 break;
342 case WPDP::PAGE_MAIN:
343 $help_url = 'https://docs.legacy.wpdataaccess.com/docs/data-projects/';
344 break;
345 case WPDP::PAGE_TEMPLATES:
346 $help_url = 'https://docs.legacy.wpdataaccess.com/docs/project-templates/';
347 break;
348 case 'wpdataaccess':
349 $current_tab = ( isset( $_REQUEST['tab'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['tab'] ) ) : 'plugin' );
350 switch ( $current_tab ) {
351 case 'plugin':
352 $help_url = 'https://docs.settings.wpdataaccess.com/plugin.html';
353 break;
354 case 'pds':
355 $help_url = 'https://docs.settings.wpdataaccess.com/pds.html';
356 break;
357 case 'backend':
358 $help_url = 'https://docs.settings.wpdataaccess.com/back-end.html';
359 break;
360 case 'frontend':
361 $help_url = 'https://docs.settings.wpdataaccess.com/frond-end.html';
362 break;
363 case 'uninstall':
364 $help_url = 'https://docs.settings.wpdataaccess.com/uninstall.html';
365 break;
366 case 'repository':
367 $help_url = 'https://docs.settings.wpdataaccess.com/repository.html';
368 break;
369 case 'mail':
370 $help_url = 'https://docs.settings.wpdataaccess.com/mail.html';
371 break;
372 case 'drives':
373 $help_url = 'https://docs.settings.wpdataaccess.com/drives.html';
374 break;
375 case 'system':
376 $help_url = 'https://docs.settings.wpdataaccess.com/system-info.html';
377 break;
378 case 'legacy':
379 $vtab = ( isset( $_REQUEST['vtab'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['vtab'] ) ) : 'plugin' );
380 switch ( $vtab ) {
381 case 'backend':
382 $help_url = 'https://docs.settings.wpdataaccess.com/legacy-tools-back-end.html';
383 break;
384 case 'frontend':
385 $help_url = 'https://docs.settings.wpdataaccess.com/legacy-tools-front-end.html';
386 break;
387 case 'datatables':
388 $help_url = 'https://docs.settings.wpdataaccess.com/legacy-tools-data-tables.html';
389 break;
390 case 'dataforms':
391 $help_url = 'https://docs.settings.wpdataaccess.com/legacy-tools-data-forms.html';
392 break;
393 case 'dashboard':
394 $help_url = 'https://docs.settings.wpdataaccess.com/legacy-tools-dashboard.html';
395 break;
396 case 'databackup':
397 $help_url = 'https://docs.settings.wpdataaccess.com/legacy-tools-data-backup.html';
398 break;
399 case 'roles':
400 $help_url = 'https://docs.settings.wpdataaccess.com/legacy-tools-roles.html';
401 break;
402 default:
403 $help_url = 'https://docs.settings.wpdataaccess.com/legacy-tools-plugin.html';
404 }
405 break;
406 }
407 break;
408 }
409 }
410 return $help_url;
411 }
412
413 /**
414 * Construct default dashboard
415 *
416 * @return void
417 */
418 protected function dashboard_default() {
419 ?>
420 <div id="wpda-dashboard" style="display:none">
421 <div class="wpda-dashboard">
422 <div class="wpda-dashboard-group wpda-dashboard-group-administration">
423 <div class="icons">
424 <a class="wpda-dashboard-item wpda_tooltip_icons" href="<?php
425 echo esc_url( admin_url( 'admin.php' ) );
426 ?>?page=wpda_navi" title="Quick links and frequently asked questions">
427 <div class="fa-solid fa-house"></div>
428 <div class="label">Tool Guide</div>
429 </a>
430 <a class="wpda-dashboard-item wpda_tooltip_icons" href="<?php
431 echo esc_url( admin_url( 'admin.php' ) );
432 ?>?page=wpda_apps" title="Data-driven Rapid Application Development">
433 <div class="fa-solid">
434 <svg xmlns="http://www.w3.org/2000/svg" height="26px" width="26px" viewBox="4 4 16 16" fill="inherit">
435 <path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/>
436 </svg>
437 </div>
438 <div class="label">App Builder</div>
439 </a>
440 <a class="wpda-dashboard-item wpda_tooltip_icons" href="<?php
441 echo esc_url( admin_url( 'admin.php' ) );
442 ?>?page=wpda" title="Manage local and remote data and databases">
443 <div class="fa-solid fa-database"></div>
444 <div class="label">Explorer</div>
445 </a>
446 <a class="wpda-dashboard-item wpda_tooltip_icons" href="<?php
447 echo esc_url( admin_url( 'admin.php' ) );
448 ?>?page=wpda_query_builder" title="SQL Query Builder">
449 <div class="fa-solid fa-code"></div>
450 <div class="label">SQL</div>
451 </a>
452 </div>
453 <div class="subject">Data(base) Administration & App Development</div>
454 </div>
455 <div class="wpda-dashboard-group wpda-dashboard-group-projects"
456 <?php
457 if ( !$this->option_legacy_tools['tables'][0] && !$this->option_legacy_tools['forms'][0] && !$this->option_legacy_tools['templates'][0] && !$this->option_legacy_tools['designer'][0] && !$this->option_legacy_tools['dashboards'][0] && !$this->option_legacy_tools['charts'][0] ) {
458 echo 'style="display: none"';
459 }
460 ?>
461 >
462 <div class="icons">
463 <a class="wpda-dashboard-item wpda_tooltip_icons"
464 href="<?php
465 echo esc_url( admin_url( 'admin.php' ) );
466 ?>?page=wpda_publisher"
467 title="OLD Table Builder
468
469 Use App Builder to access the NEW Table Builder
470 "
471 <?php
472 if ( !$this->option_legacy_tools['tables'][0] ) {
473 echo 'style="display: none"';
474 }
475 ?>
476 >
477 <div class="fa-solid fa-table"></div>
478 <div class="label">Tables</div>
479 </a>
480 <a class="wpda-dashboard-item wpda_tooltip_icons"
481 href="<?php
482 echo esc_url( admin_url( 'admin.php' ) );
483 ?>?page=wpda_wpdp"
484 title="OLD Form Builder
485
486 Use App Builder to access the NEW Form Builder
487 "
488 <?php
489 if ( !$this->option_legacy_tools['forms'][0] ) {
490 echo 'style="display: none"';
491 }
492 ?>
493 >
494 <div class="fa-solid fa-wand-magic-sparkles"></div>
495 <div class="label">Forms</div>
496 </a>
497 <a class="wpda-dashboard-item wpda_tooltip_icons"
498 href="<?php
499 echo esc_url( admin_url( 'admin.php' ) );
500 ?>?page=wpda_templates"
501 title="OLD Form Templates
502
503 Customize forms using templates"
504 <?php
505 if ( !$this->option_legacy_tools['templates'][0] ) {
506 echo 'style="display: none"';
507 }
508 ?>
509 >
510 <div class="fa-solid fa-desktop"></div>
511 <div class="label">Templates</div>
512 </a>
513 <a class="wpda-dashboard-item wpda_tooltip_icons"
514 href="<?php
515 echo esc_url( admin_url( 'admin.php' ) );
516 ?>?page=wpda_designer"
517 title="Create database tables and indexes"
518 <?php
519 if ( !$this->option_legacy_tools['designer'][0] ) {
520 echo 'style="display: none"';
521 }
522 ?>
523 >
524 <div class="fa-solid fa-drafting-compass"></div>
525 <div class="label">Designer</div>
526 </a>
527 <?php
528 ?>
529 </div>
530 <div class="subject">Legacy Tools</div>
531 </div>
532 <div class="wpda-dashboard-group wpda-dashboard-group-settings">
533 <div class="icons">
534 <a class="wpda-dashboard-item wpda_tooltip_icons" href="<?php
535 echo esc_url( admin_url( 'options-general.php' ) );
536 ?>?page=wpdataaccess" title="Manage plugin user interface and behavior">
537 <div class="fa-solid fa-cog"></div>
538 <div class="label">Settings</div>
539 </a>
540 <?php
541 if ( wpda_freemius()->is_registered() ) {
542 ?>
543 <a class="wpda-dashboard-item wpda_tooltip_icons" href="<?php
544 echo esc_url( admin_url( 'admin.php' ) );
545 ?>?page=<?php
546 echo esc_attr( WP_Data_Access_Admin::MAIN_PAGE_SLUG );
547 ?>-account" title="Manage your WP Data Access account">
548 <div class="fa-solid fa-user"></div>
549 <div class="label">Account</div>
550 </a>
551 <?php
552 }
553 ?>
554 <a class="wpda-dashboard-item wpda_tooltip_icons" target="_blank" href="https://wpdataaccess.com/pricing/" title="Pricing, licensing and ordering">
555 <div class="fa-solid fa-hand-holding-usd"></div>
556 <div class="label">Pricing</div>
557 </a>
558 <a class="wpda-dashboard-item wpda_tooltip_icons" href="<?php
559 echo esc_url( admin_url( 'admin.php' ) );
560 ?>?page=<?php
561 echo esc_attr( WP_Data_Access_Admin::MAIN_PAGE_SLUG );
562 ?>-pricing" title="Upgrade your WP Data Access account">
563 <div class="fa-solid fa-gem"></div>
564 <div class="label">Upgrade</div>
565 </a>
566 <?php
567 if ( wpda_freemius()->is_free_plan() && !wpda_freemius()->is_trial() && !wpda_freemius()->is_trial_utilized() ) {
568 ?>
569 <a class="wpda-dashboard-item wpda_tooltip_icons" target="_blank" href="https://wpdataaccess.com/order/?l=0&b=trial" title="Get your 14-day free trial" target="_blank">
570 <div class="fa-solid fa-star"></div>
571 <div class="label">Free Trial</div>
572 </a>
573 <?php
574 }
575 ?>
576 <a class="wpda-dashboard-item wpda_tooltip_icons" href="<?php
577 echo esc_url( admin_url( 'admin.php' ) );
578 ?>?page=<?php
579 echo esc_attr( WP_Data_Access_Admin::MAIN_PAGE_SLUG );
580 ?>-affiliation" title="Become our ambassador and earn on every referral">
581 <div class="fa-solid fa-handshake"></div>
582 <div class="label">Affiliation</div>
583 </a>
584 </div>
585 <div class="subject">Plugin & User Management</div>
586 </div>
587 <div class="wpda-dashboard-group wpda-dashboard-group-support">
588 <div class="icons">
589 <a class="wpda-dashboard-item wpda_tooltip_icons" target="_blank" href="<?php
590 echo esc_url( $this->get_help_url() );
591 ?>" title="Context sensitive help">
592 <div class="fa-solid fa-question-circle"></div>
593 <div class="label">Docs</div>
594 </a>
595 <a class="wpda-dashboard-item wpda_tooltip_icons" target="_blank" href="https://wordpress.org/support/plugin/wp-data-access/" title="Public support forum">
596 <div class="fa-solid fa-life-ring"></div>
597 <div class="label">Forum</div>
598 </a>
599 <?php
600 ?>
601 </div>
602 <div class="subject">Help</div>
603 </div>
604 </div>
605 </div>
606 <?php
607 }
608
609 /**
610 * Construct mobile dashboard
611 *
612 * @return void
613 */
614 protected function dashboard_mobile() {
615 $premium_separator = 'wpda-separator';
616 ?>
617 <div id="wpda-dashboard-mobile" style="display:none">
618 <div id="wpda-dashboard-drop-down">
619 <div class="wpda_nav_toggle" onclick="toggleMenu()"><i class="fas fa-bars"></i></div>
620 <div class="wpda_nav_title">WP Data Access</div>
621 </div>
622 <ul>
623 <li class="menu-item"><a href="<?php
624 echo esc_url( admin_url( 'admin.php' ) );
625 ?>?page=wpda_navi"><i class="fas fa-house"></i> Tool Guide</a></li>
626 <li class="menu-item"><a href="<?php
627 echo esc_url( admin_url( 'admin.php' ) );
628 ?>?page=wpda_apps"><span style="display: inline-block; width: 20px"><svg xmlns="http://www.w3.org/2000/svg" height="12px" width="12px" viewBox="4 4 16 16" fill="inherit">
629 <path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/>
630 </svg></span> App Builder</a></li>
631 <li class="menu-item"><a href="<?php
632 echo esc_url( admin_url( 'admin.php' ) );
633 ?>?page=wpda"><i class="fas fa-database"></i> Data Explorer</a></li>
634 <li class="menu-item wpda-separator"><a href="<?php
635 echo esc_url( admin_url( 'admin.php' ) );
636 ?>?page=wpda_query_builder"><i class="fas fa-code"></i> SQL Query Builder</a></li>
637 <li class="menu-item"><a href="<?php
638 echo esc_url( admin_url( 'admin.php' ) );
639 ?>?page=wpda_publisher"><i class="fas fa-table"></i> Data Tables - Legacy</a></li>
640 <li class="menu-item"><a href="<?php
641 echo esc_url( admin_url( 'admin.php' ) );
642 ?>?page=wpda_wpdp"><i class="fas fa-wand-magic-sparkles"></i> Forms - Legacy</a></li>
643 <li class="menu-item"><a href="<?php
644 echo esc_url( admin_url( 'admin.php' ) );
645 ?>?page=wpda_templates"><i class="fas fa-desktop"></i> Templates - Legacy</a></li>
646 <li class="menu-item <?php
647 echo esc_attr( $premium_separator );
648 ?>"><a href="<?php
649 echo esc_url( admin_url( 'admin.php' ) );
650 ?>?page=wpda_designer"><i class="fas fa-drafting-compass"></i> Data Designer - Legacy</a></li>
651 <?php
652 ?>
653 <?php
654 ?>
655 <li class="menu-item"><a href="<?php
656 echo esc_url( admin_url( 'options-general.php' ) );
657 ?>?page=wpdataaccess"><i class="fas fa-cog"></i> Settings</a></li>
658 <?php
659 if ( wpda_freemius()->is_registered() ) {
660 ?>
661 <li class="menu-item"><a href="<?php
662 echo esc_url( admin_url( 'admin.php' ) );
663 ?>?page=<?php
664 echo esc_attr( WP_Data_Access_Admin::MAIN_PAGE_SLUG );
665 ?>-account"><i class="fas fa-user"></i> Account</a></li>
666 <?php
667 }
668 ?>
669 <li class="menu-item"><a target="_blank" href="https://wpdataaccess.com/pricing/" target="_blank"><i class="fas fa-hand-holding-usd"></i> Pricing</a></li>
670 <li class="menu-item"><a href="<?php
671 echo esc_url( admin_url( 'admin.php' ) );
672 ?>?page=<?php
673 echo esc_attr( WP_Data_Access_Admin::MAIN_PAGE_SLUG );
674 ?>-pricing"><i class="fas fa-gem"></i> Upgrade</a></li>
675 <?php
676 if ( wpda_freemius()->is_free_plan() && !wpda_freemius()->is_trial() && !wpda_freemius()->is_trial_utilized() ) {
677 ?>
678 <li class="menu-item"><a target="_blank" href="https://wpdataaccess.com/order/?l=0&b=trial" target="_blank"><i class="fas fa-star"></i> Free Trial</a></li>
679 <?php
680 }
681 ?>
682 <li class="menu-item wpda-separator"><a href="<?php
683 echo esc_url( admin_url( 'admin.php' ) );
684 ?>?page=<?php
685 echo esc_attr( WP_Data_Access_Admin::MAIN_PAGE_SLUG );
686 ?>-affiliation"><i class="fas fa-handshake"></i> Affiliation</a></li>
687 <li class="menu-item"><a target="_blank" href="https://docs.wpdataaccess.com/"><i class="fas fa-question-circle"></i> Online Documentation</a></li>
688 <li class="menu-item"><a target="_blank" href="https://wordpress.org/support/plugin/wp-data-access/"><i class="fas fa-life-ring"></i> Support Forum</a></li>
689 <?php
690 ?>
691 </ul>
692 </div>
693 <?php
694 }
695
696 /**
697 * Add dashboard tabs
698 *
699 * @return void
700 */
701 protected function tabs() {
702 }
703
704 /**
705 * Construct toolbar
706 *
707 * @return void
708 */
709 protected function toolbar() {
710 if ( $this->cannot_create_dashboard ) {
711 return;
712 }
713 $remove_columns_message = __( 'Remove columns outside of range? Widgets will no longer be available!', 'wp-data-access' );
714 ?>
715 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
716 <div class="wpda-nowrap">
717 <div>
718 <?php
719 if ( WPDA::current_user_is_admin() ) {
720 ?>
721 <div>
722 <a href="javascript:addPanel()"
723 class="wpda-dashboard-item wpda_tooltip"
724 title="Create new widget"
725 >
726 <i class="fas fa-folder-plus"></i>
727 <div>
728 Create widget
729 </div>
730 </a>
731 </div>
732 <?php
733 }
734 ?>
735 </div>
736 </div>
737 <div>
738 <?php
739 $this->get_promotions( 'toolbar' );
740 ?>
741 </div>
742 <div style="white-space:nowrap">
743 <div>
744 <div>
745 <a href="javascript:removeColumns(1)"
746 class="wpda-dashboard-item wpda_tooltip"
747 title="One column"
748 >
749 <i class="fas fa-dice-one"></i>
750 <div>
751 1 column
752 </div>
753 </a>
754 </div><div>
755 <a href="javascript:removeColumns(2); addColumns(2)"
756 class="wpda-dashboard-item wpda_tooltip"
757 title="Switch to two column layout"
758 >
759 <i class="fas fa-dice-two"></i>
760 <div>
761 2 columns
762 </div>
763 </a>
764 </div><div>
765 <a href="javascript:removeColumns(3); addColumns(3)"
766 class="wpda-dashboard-item wpda_tooltip"
767 title="Switch to three column layout"
768 >
769 <i class="fas fa-dice-three"></i>
770 <div>
771 3 columns
772 </div>
773 </a>
774 </div><div>
775 <a href="javascript:addColumns(4)"
776 class="wpda-dashboard-item wpda_tooltip"
777 title="Switch to four column layout"
778 >
779 <i class="fas fa-dice-four"></i>
780 <div>
781 4 columns
782 </div>
783 </a>
784 </div>
785 </div>
786 </div>
787 </div>
788 <?php
789 if ( wpda_freemius()->is_free_plan() ) {
790 ?>
791 <div class="wpda_dashboard_free_message">
792 <table>
793 <tr>
794 <td style="text-align:left">
795 The free version of WP Data Access has limited dashboard support.
796 Data Widgets can be added and moved, but not saved or shared.
797 Update to premium to analyse, report and share your data.
798 </td>
799 <td style="white-space:nowrap">
800 <a href="https://wpdataaccess.com/pricing/" target="_blank" class="button button-primary">UPGRADE TO PREMIUM</a>
801 <a href="https://docs.legacy.wpdataaccess.com/docs/bi-getting-started/" target="_blank" class="button">READ MORE</a>
802 </td>
803 </tr>
804 </table>
805 </div>
806 <?php
807 }
808 ?>
809 <script type="application/javascript">
810 function manageTabs() {
811 closePanel();
812 jQuery("#wpda-manage-tabs").show();
813 }
814 function noColumns() {
815 return jQuery(".wpda-dashboard-column").length;
816 }
817 function addColumns(colNum) {
818 if (noColumns()<colNum) {
819 for (var i=noColumns()+1; i<=colNum; i++) {
820 jQuery("#wpda-dashboard-content").append('<div id="wpda-dashboard-column-' + i + '" class="wpda-dashboard-column wpda-dashboard-column-' + i + '"></div>');
821 }
822 refreshPanels(colNum);
823 resetColumnSelection();
824 makeSortable();
825 saveDashBoard();
826 }
827 }
828 function removeColumns(colNum) {
829 if (noColumns()>colNum) {
830 if (confirm("<?php
831 echo esc_html( $remove_columns_message );
832 ?>")) {
833 noCols = noColumns();
834 for (var i=colNum+1; i<=noCols; i++) {
835 jQuery("#wpda-dashboard-column-" + i).remove();
836 }
837 refreshPanels(colNum);
838 makeSortable();
839 saveDashBoard();
840 }
841 }
842 }
843 function refreshPanels(colNum) {
844 for (var i=1; i<=4; i++) {
845 jQuery(".wpda-dashboard-column").removeClass("wpda-dashboard-column-" + i);
846 }
847 jQuery(".wpda-dashboard-column").addClass("wpda-dashboard-column-" + colNum);
848 refreshAllPanels();
849 }
850 jQuery(function(){
851 jQuery("#wpda_delete_new_dashboard_message").on("click", function() {
852 if (confirm("Remove message and link? This cannot be undone!")) {
853 jQuery.ajax({
854 type: "POST",
855 url: wpda_ajaxurl + "?action=wpda_remove_new_dashboard_message",
856 data: {
857 wp_nonce: wpda_wpnonce_save
858 }
859 }).done(
860 function(data) {
861 if (data==="OK") {
862 jQuery("#wpda_delete_new_dashboard_message_container").hide();
863 }
864 }
865 );
866 }
867 });
868 });
869 </script>
870 <?php
871 }
872
873 /**
874 * Data Explorer main page toolbar
875 *
876 * @return void
877 */
878 protected function toolbar_wpda() {
879 $schema_name = ( isset( $_REQUEST['wpdaschema_name'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['wpdaschema_name'] ) ) ) : '' );
880 ?>
881 <form id="wpda_new_design" style="display: none" method="post" action="?page=<?php
882 echo esc_attr( WP_Data_Access_Admin::PAGE_DESIGNER );
883 ?>">
884 <input type="hidden" name="action" value="create_table">
885 <input type="hidden" name="caller" value="dataexplorer">
886 <input type="hidden" name="_wpnonce" value="<?php
887 echo esc_attr( wp_create_nonce( "wpda-query-" . WPDA_Design_Table_Model::get_base_table_name() . "--" ) );
888 ?>">
889 </form>
890 <form id="wpda_goto_backup" style="display: none" method="post" action="?page=<?php
891 echo esc_attr( WP_Data_Access_Admin::PAGE_MAIN );
892 ?>&page_action=wpda_backup">
893 <input type="hidden" name="wpdaschema_name" value="<?php
894 echo esc_attr( $schema_name );
895 ?>">
896 </form>
897 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
898 <div class="wpda-nowrap">
899 <div>
900 <div>
901 <a href="<?php
902 echo esc_url( admin_url( 'admin.php' ) );
903 ?>?page=<?php
904 echo esc_attr( WP_Data_Access_Admin::PAGE_MAIN );
905 ?>&page_action=wpda_global_search"
906 class="wpda-dashboard-item wpda_tooltip"
907 title="Search and replace text in multiple databases and tables"
908 >
909 <i class="fas fa-search-plus"></i>
910 <div>
911 Search & Replace
912 </div>
913 </a>
914 </div><div>
915 <a href="javascript:jQuery('#wpda_new_design').submit()"
916 class="wpda-dashboard-item wpda_tooltip"
917 title="Create new table design"
918 >
919 <i class="fas fa-plus-circle"></i>
920 <div>
921 Create table design
922 </div>
923 </a>
924 </div>
925 </div><div>
926 <div>
927 <a onClick="window.ppActionEnableImport();"
928 href="javascript:void(0)"
929 class="wpda-dashboard-item wpda_tooltip"
930 title="Import and execute SQL script files"
931 >
932 <i class="fas fa-file-code"></i>
933 <div>
934 Import SQL files
935 </div>
936 </a>
937 </div><div>
938 <a href="<?php
939 echo esc_url( admin_url( 'admin.php' ) );
940 ?>?page=<?php
941 echo esc_attr( WP_Data_Access_Admin::PAGE_MAIN );
942 ?>&page_action=wpda_import_csv"
943 class="wpda-dashboard-item wpda_tooltip"
944 title="Import CSV files"
945 >
946 <i class="fas fa-file-csv"></i>
947 <div>
948 Import CSV files
949 </div>
950 </a>
951 </div><div>
952 <a onclick="window.ppActionEnableExport();"
953 href="javascript:void(0)"
954 class="wpda-dashboard-item wpda_tooltip"
955 title="Unattended scheduled exports"
956 >
957 <i class="fas fa-clock"></i>
958 <div>
959 Export
960 </div>
961 </a>
962 </div><?php
963 $wpda_db_options_activated = get_option( 'wpda_db_options_activated' );
964 if ( is_array( $wpda_db_options_activated ) && 0 < count( $wpda_db_options_activated ) ) {
965 // Show old Data Backup feature only if still in use
966 ?><div>
967 <a href="javascript:void(0)"
968 id="wpda_toolbar_icon_go_backup"
969 class="wpda-dashboard-item wpda_tooltip"
970 title="Data Backup - unattended exports"
971 >
972 <i class="fas fa-file-archive"></i>
973 <div>
974 Data Backup
975 </div>
976 </a>
977 </div><?php
978 }
979 ?>
980 </div><div>
981 <div>
982 <a onclick="jQuery('#wpda_manage_databases').show(); jQuery('#local_database').focus();"
983 href="javascript:void(0)"
984 class="wpda-dashboard-item wpda_tooltip"
985 title="Manage remote database connections and local databases"
986 >
987 <i id="wpda_toolbar_icon_add_database" class="fas fa-server"></i>
988 <div>
989 Databases
990 </div>
991 </a>
992 </div><?php
993 ?>
994 </div>
995 </div>
996 <div></div>
997 <?php
998 //$this->get_promotions('wpda');
999 ?>
1000 </div>
1001 <?php
1002 }
1003
1004 /**
1005 * Data Backup toolbar
1006 *
1007 * @return void
1008 */
1009 protected function toolbar_backup() {
1010 ?>
1011 <form id="wpda_new_backup" style="display: none" method="post" action="?page=<?php
1012 echo esc_attr( WP_Data_Access_Admin::PAGE_MAIN );
1013 ?>&page_action=wpda_backup">
1014 <input type="hidden" id="wpda_new_backup_wpdaschema_name" name="wpdaschema_name" value="">
1015 <input type="hidden" name="action" value="new">
1016 <input type="hidden" name="wp_nonce" value="<?php
1017 echo esc_attr( wp_create_nonce( 'wpda-backup-' . WPDA::get_current_user_login() ) );
1018 ?>"/>
1019 </form>
1020 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
1021 <div class="wpda-nowrap">
1022 <div>
1023 <div>
1024 <a href="javascript:void(0)"
1025 id="wpda_toolbar_icon_add_backup"
1026 class="wpda-dashboard-item wpda_tooltip"
1027 title="Create new data backup"
1028 >
1029 <i class="fas fa-plus-circle"></i>
1030 <div>
1031 Create backup
1032 </div>
1033 </a>
1034 </div>
1035 </div>
1036 </div>
1037 <?php
1038 $this->get_promotions( 'backup' );
1039 ?>
1040 </div>
1041 <?php
1042 }
1043
1044 /**
1045 * CSV import toolbar
1046 *
1047 * @return void
1048 */
1049 protected function toolbar_import_csv() {
1050 if ( !isset( $_REQUEST['action'] ) || '-1' === $_REQUEST['action'] || 'bulk-delete' === $_REQUEST['action'] || 'delete' === $_REQUEST['action'] ) {
1051 ?>
1052 <form id="wpda_upload_csv" style="display:none" method="post" action="?page=wpda&page_action=wpda_import_csv">
1053 <input type="hidden" name="action" value="upload">
1054 </form>
1055 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
1056 <div class="wpda-nowrap">
1057 <div>
1058 <div>
1059 <a href="javascript:jQuery('#wpda_upload_csv').submit()"
1060 class="wpda-dashboard-item wpda_tooltip"
1061 title="Upload new CSV File"
1062 >
1063 <i class="fas fa-plus-circle"></i>
1064 <div>
1065 Upload CSV file
1066 </div>
1067 </a>
1068 </div>
1069 </div>
1070 </div>
1071 <?php
1072 $this->get_promotions( 'csv' );
1073 ?>
1074 </div>
1075 <?php
1076 }
1077 }
1078
1079 /**
1080 * Data Apps toolbar.
1081 *
1082 * @return void
1083 */
1084 protected function toolbar_apps() {
1085 $has_apps = WPDA_App_Model::has_any();
1086 ?>
1087 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
1088 <div class="wpda-nowrap">
1089 <div>
1090 <div>
1091 <a href="javascript:window.ppActionCreateApp()"
1092 class="wpda-dashboard-item wpda_tooltip wpda-create-new-app"
1093 title="Create new app"
1094 >
1095 <i class="fas fa-plus-circle"></i>
1096 <div>
1097 Create New App
1098 </div>
1099 </a>
1100 </div><div>
1101 <a href="javascript:window.ppActionRenameDatabase()"
1102 class="wpda-dashboard-item wpda_tooltip wpda-rename-database"
1103 title="Rename Database"
1104 >
1105 <svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 2 24 24" stroke-linecap="round" stroke-linejoin="round" height="32px" width="32px" xmlns="http://www.w3.org/2000/svg">
1106 <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
1107 <path d="M4 6c0 1.657 3.582 3 8 3s8 -1.343 8 -3s-3.582 -3 -8 -3s-8 1.343 -8 3"></path>
1108 <path d="M4 6v6c0 1.657 3.582 3 8 3c.478 0 .947 -.016 1.402 -.046"></path>
1109 <path d="M20 12v-6"></path>
1110 <path d="M4 12v6c0 1.526 3.04 2.786 6.972 2.975"></path>
1111 <path d="M18.42 15.61a2.1 2.1 0 0 1 2.97 2.97l-3.39 3.42h-3v-3l3.42 -3.39z"></path>
1112 </svg>
1113 <div>
1114 Rename Database
1115 </div>
1116 </a>
1117 </div><?php
1118 ?>
1119 </div>
1120 </div>
1121 <div class="wpda-promotion" style="display: flex; align-items: center; gap: 5px; font-size: 16px;">
1122 <?php
1123 if ( !$has_apps ) {
1124 ?>
1125 <span>
1126 <strong>
1127 New to the App Builder? Watch the Getting Started tutorial! 👉
1128 </strong>
1129 </span><?php
1130 }
1131 ?><span>
1132 <a href="https://www.youtube.com/watch?v=j0MJvuMG7k8"
1133 target="_blank"
1134 class="wpda_tooltip"
1135 title="App Builder Getting Started tutorial"
1136 >
1137 <i class="fas fab fa-square-youtube"></i>
1138 </a>
1139 </span><span>
1140 <a href="https://docs.rad.wpdataaccess.com/"
1141 target="_blank"
1142 class="wpda_tooltip"
1143 title="Online App Builder documentation"
1144 >
1145 <i class="fas fa-circle-info"></i>
1146 </a>
1147 </span>
1148 </div>
1149 <?php
1150 // $this->get_promotions('apps');
1151 ?>
1152 </div>
1153 <?php
1154 }
1155
1156 /**
1157 * Data Designer toolbar
1158 *
1159 * @return void
1160 */
1161 protected function toolbar_designer() {
1162 ?>
1163 <form id="wpda_new_design" style="display: none" method="post" action="?page=<?php
1164 echo esc_attr( WP_Data_Access_Admin::PAGE_DESIGNER );
1165 ?>">
1166 <input type="hidden" name="action" value="edit">
1167 <input type="hidden" name="table_name" value="<?php
1168 echo esc_attr( WPDA_Design_Table_Model::get_base_table_name() );
1169 ?>">
1170 <input type="hidden" name="_wpnonce" value="<?php
1171 echo esc_attr( wp_create_nonce( "wpda-query-" . WPDA_Design_Table_Model::get_base_table_name() . "--" ) );
1172 ?>">
1173 </form>
1174 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
1175 <div class="wpda-nowrap">
1176 <div>
1177 <div>
1178 <a href="javascript:jQuery('#wpda_new_design').submit()"
1179 class="wpda-dashboard-item wpda_tooltip"
1180 title="Create new table design"
1181 >
1182 <i class="fas fa-plus-circle"></i>
1183 <div>
1184 Create table design
1185 </div>
1186 </a>
1187 </div><div>
1188 <a onclick="alert('This feature has been removed. Please use the Data Explorer import feature.')"
1189 href="javascript:void(0)"
1190 class="wpda-dashboard-item wpda_tooltip"
1191 title="Import table designs"
1192 >
1193 <i class="fas fa-code"></i>
1194 <div>
1195 Import table designs
1196 </div>
1197 </a>
1198 </div>
1199 </div>
1200 </div>
1201 <?php
1202 $this->get_promotions( 'designer' );
1203 ?>
1204 </div>
1205 <?php
1206 }
1207
1208 /**
1209 * Data Tables toolbar
1210 *
1211 * @return void
1212 */
1213 protected function toolbar_publisher() {
1214 ?>
1215 <form id="wpda_new_publication" style="display: none" method="post" action="?page=<?php
1216 echo esc_attr( WP_Data_Access_Admin::PAGE_PUBLISHER );
1217 ?>">
1218 <input type="hidden" id="wpda_new_publication_table_name" name="table_name" value="">
1219 <input type="hidden" name="action" value="new">
1220 </form>
1221 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
1222 <div class="wpda-nowrap">
1223 <div>
1224 <div>
1225 <a href="javascript:void(0)"
1226 id="wpda_toolbar_icon_add_publication"
1227 class="wpda-dashboard-item wpda_tooltip"
1228 title="Create new data table"
1229 >
1230 <i class="fas fa-plus-circle"></i>
1231 <div>
1232 Create data table
1233 </div>
1234 </a>
1235 </div><div>
1236 <a onclick="alert('This feature has been removed. Please use the Data Explorer import feature.')"
1237 href="javascript:void(0)"
1238 class="wpda-dashboard-item wpda_tooltip"
1239 title="Import data tables"
1240 >
1241 <i class="fas fa-code"></i>
1242 <div>
1243 Import data tables
1244 </div>
1245 </a>
1246 </div><?php
1247 ?>
1248 </div>
1249 </div>
1250 <?php
1251 $this->get_promotions( 'publisher' );
1252 ?>
1253 </div>
1254 <?php
1255 }
1256
1257 /**
1258 * Charts toolbar
1259 *
1260 * @return void
1261 */
1262 protected function toolbar_charts() {
1263 }
1264
1265 /**
1266 * Data Projects toolbar
1267 *
1268 * @return void
1269 */
1270 protected function toolbar_projects() {
1271 ?>
1272 <form id="wpda_new_project" style="display: none" method="post" action="?page=<?php
1273 echo esc_attr( WPDP::PAGE_MAIN );
1274 ?>">
1275 <input type="hidden" name="action" value="new">
1276 <input type="hidden" name="mode" value="edit">
1277 <input type="hidden" name="table_name" value="<?php
1278 echo esc_attr( WPDP_Project_Model::get_base_table_name() );
1279 ?>">
1280 </form>
1281 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
1282 <div class="wpda-nowrap">
1283 <div>
1284 <div>
1285 <a href="javascript:jQuery('#wpda_new_project').submit()"
1286 class="wpda-dashboard-item wpda_tooltip"
1287 title="Create new project"
1288 >
1289 <i class="fas fa-plus-circle"></i>
1290 <div>
1291 Create project
1292 </div>
1293 </a>
1294 </div><div>
1295 <a onclick="jQuery(alert('This feature has been removed. Please use the Data Explorer import feature.')).show()"
1296 href="javascript:void(0)"
1297 class="wpda-dashboard-item wpda_tooltip"
1298 title="Import projects"
1299 >
1300 <i class="fas fa-code"></i>
1301 <div>
1302 Import projects
1303 </div>
1304 </a>
1305 </div>
1306 </div>
1307 </div>
1308 <?php
1309 $this->get_promotions( 'projects' );
1310 ?>
1311 </div>
1312 <?php
1313 }
1314
1315 /**
1316 * Project Templates toolbar
1317 *
1318 * @return void
1319 */
1320 protected function toolbar_templates() {
1321 ?>
1322 <div id="wpda-dashboard-toolbar" class="wpda-dashboard-toolbar" style="display:none">
1323 <div class="wpda-nowrap">
1324 <div>
1325 <div>
1326 <a onclick="jQuery('#no_repository_buttons').hide(); jQuery('#add_table_to_repository').show()"
1327 href="javascript:void(0)"
1328 class="wpda-dashboard-item wpda_tooltip"
1329 title="Create new project template"
1330 >
1331 <i class="fas fa-plus-circle"></i>
1332 <div>
1333 Create project template
1334 </div>
1335 </a>
1336 </div>
1337 </div>
1338 </div>
1339 <?php
1340 $this->get_promotions( 'templates' );
1341 ?>
1342 </div>
1343 <?php
1344 }
1345
1346 /**
1347 * Widgets toolbar
1348 *
1349 * @return void
1350 */
1351 protected function add_forms() {
1352 ?>
1353 <div id="wpda-select-panel-type" class="wpda-add-panel" style="display: none">
1354 <form>
1355 <fieldset class="wpda_fieldset wpda_fieldset_dashboard">
1356 <legend>
1357 Create widget
1358 </legend>
1359 <div>
1360 <label>
1361 Widget type
1362 </label>
1363 <select id="wpda-select-panel-type-choice">
1364 <?php
1365 if ( class_exists( 'Code_Manager\\Code_Manager_Model' ) ) {
1366 ?>
1367 <option value="code">Custom Code</option>
1368 <?php
1369 }
1370 ?>
1371 <option value="chart" selected>Chart</option>
1372 <option value="pub">Data Table</option>
1373 <?php
1374 if ( class_exists( 'WPDataAccess\\Premium\\WPDAPRO_Dashboard\\WPDAPRO_Widget_Project' ) ) {
1375 ?>
1376 <option value="project">Data Project</option>
1377 <?php
1378 }
1379 ?>
1380 <option value="dbs">Database Info</option>
1381 </select>
1382 <?php
1383 if ( !class_exists( 'Code_Manager\\Code_Manager_Model' ) || !class_exists( 'WPDataAccess\\Premium\\WPDAPRO_Dashboard\\WPDAPRO_Widget_Project' ) ) {
1384 ?>
1385 <a href="https://docs.legacy.wpdataaccess.com/docs/bi-getting-started/" target="_blank">
1386 <i class="fas fa-question-circle pointer wpda_tooltip"
1387 style="font-size: 170%; vertical-align: middle"
1388 title="Your installation does not support all available widget types! Click to learn how to install more widget types..."></i>
1389 </a>
1390 <?php
1391 }
1392 ?>
1393 </div>
1394 </fieldset>
1395 <div class="wpda-panel-buttons">
1396 <span class="wpda-panel-buttons">
1397 <button id="wpda-select-panel-type-button" class="button button-primary">
1398 <i class="fas fa-check wpda_icon_on_button"></i>
1399 Next
1400 </button>
1401 <button id="wpda-select-panel-type-button-cancel" class="button button-secondary">
1402 <i class="fas fa-times-circle wpda_icon_on_button"></i>
1403 Cancel
1404 </button>
1405 </span>
1406 </div>
1407 </form>
1408 </div>
1409 <div id="wpda-add-panel" class="wpda-add-panel" style="display: none">
1410 <form>
1411 <fieldset class="wpda_fieldset wpda_fieldset_dashboard">
1412 <legend>
1413 Create widget
1414 </legend>
1415 <div>
1416 <label>
1417 Widget type
1418 </label>
1419 <input type="text" id="wpda-add-panel-type-show" readonly>
1420 <input type="hidden" id="wpda-add-panel-type">
1421 </div>
1422 <div>
1423 <label>
1424 Widget name
1425 </label>
1426 <input type="text" id="wpda-add-panel-name" required/>
1427 </div>
1428 <div id="wpda-panel-code" style="display: none">
1429 <label>
1430 Select shortcode
1431 </label>
1432 <select id="wpda-add-panel-code">
1433 <?php
1434 if ( class_exists( 'Code_Manager\\Code_Manager_Model' ) ) {
1435 $codes = \Code_Manager\Code_Manager_Model::get_active_shortcodes();
1436 foreach ( $codes as $code ) {
1437 ?>
1438 <option value="<?php
1439 echo esc_attr( $code['code_id'] );
1440 ?>"><?php
1441 echo esc_attr( $code['code_name'] ) . ' (' . esc_attr( $code['code_type'] ) . ')';
1442 ?></option>
1443 <?php
1444 }
1445 }
1446 ?>
1447 </select>
1448 </div>
1449 <div id="wpda-panel-project">
1450 <label>
1451 Select project
1452 </label>
1453 <select id="wpda-add-panel-project">
1454 <?php
1455 $projects = WPDP_Project_Model::get_project_list();
1456 foreach ( $projects as $project ) {
1457 ?>
1458 <option value="<?php
1459 echo esc_attr( $project['project_id'] );
1460 ?>"><?php
1461 echo esc_attr( $project['project_name'] ) . ' (project_id=' . esc_attr( $project['project_id'] ) . ')';
1462 ?></option>
1463 <?php
1464 }
1465 ?>
1466 </select>
1467 </div>
1468 <div id="wpda-panel-publication">
1469 <label>
1470 Select data table
1471 </label>
1472 <select id="wpda-add-panel-publication">
1473 <?php
1474 $pubs = WPDA_Publisher_Model::get_publication_list();
1475 foreach ( $pubs as $pub ) {
1476 ?>
1477 <option value="<?php
1478 echo esc_attr( $pub['pub_id'] );
1479 ?>"><?php
1480 echo esc_attr( $pub['pub_name'] ) . ' (pub_id=' . esc_attr( $pub['pub_id'] ) . ')';
1481 ?></option>
1482 <?php
1483 }
1484 ?>
1485 </select>
1486 </div>
1487 <div id="wpda-panel-dbms">
1488 <label>
1489 Select database
1490 </label>
1491 <select id="wpda-add-panel-dbms">
1492 <option value="wpdb" selected>WordPress database (
1493 <?php
1494 global $wpdb;
1495 echo esc_attr( $wpdb->dbname );
1496 ?>
1497 )</option>
1498 <?php
1499 $rdbs = WPDADB::get_remote_databases();
1500 ksort( $rdbs );
1501 // phpcs:ignore -- 8.1 proof
1502 foreach ( $rdbs as $key => $rdb ) {
1503 ?>
1504 <option value="<?php
1505 echo esc_attr( $key );
1506 ?>"><?php
1507 echo esc_attr( $key );
1508 ?></option>
1509 <?php
1510 }
1511 ?>
1512 </select>
1513 </div>
1514 <div>
1515 <label>
1516 Add to column
1517 </label>
1518 <select id="wpda-add-panel-column">
1519 <option value="1" selected>1</option>
1520 <option value="2">2</option>
1521 </select>
1522 <select id="wpda-add-panel-position">
1523 <option value="prepend" selected>Before</option>
1524 <option value="append">After</option>
1525 </select>
1526 </div>
1527 </fieldset>
1528 <div class="wpda-panel-buttons">
1529 <span class="wpda-panel-buttons">
1530 <button id="wpda-add-panel-button" class="button button-primary">
1531 <i class="fas fa-check wpda_icon_on_button"></i>
1532 Create
1533 </button>
1534 <button id="wpda-add-panel-button-back" class="button">
1535 <i class="fas fa-angle-left wpda_icon_on_button"></i>
1536 Back
1537 </button>
1538 <button id="wpda-add-panel-button-cancel" class="button button-secondary">
1539 <i class="fas fa-times-circle wpda_icon_on_button"></i>
1540 Cancel
1541 </button>
1542 </span>
1543 </div>
1544 </div>
1545 </form>
1546 <script type="application/javascript">
1547 jQuery(function() {
1548 jQuery("#wpda-select-panel-type-button").on("click", function() {
1549 jQuery("#wpda-panel-code").hide();
1550 jQuery("#wpda-panel-project").hide();
1551 jQuery("#wpda-panel-publication").hide();
1552 jQuery("#wpda-panel-dbms").hide();
1553
1554 jQuery("#wpda-add-panel-type-show").val(jQuery("#wpda-select-panel-type-choice option:selected").text());
1555 jQuery("#wpda-add-panel-type").val(jQuery("#wpda-select-panel-type-choice").val());
1556
1557 switch (jQuery("#wpda-select-panel-type-choice").val()) {
1558 case "code":
1559 jQuery("#wpda-panel-code").show();
1560 break;
1561 case "dbs":
1562 jQuery("#wpda-panel-dbms").show();
1563 break;
1564 case "project":
1565 jQuery("#wpda-panel-project").show();
1566 break;
1567 case "pub":
1568 jQuery("#wpda-panel-publication").show();
1569 break;
1570 }
1571
1572 jQuery("#wpda-select-panel-type").hide();
1573 jQuery("#wpda-add-panel").show();
1574
1575 return false;
1576 });
1577
1578 jQuery("#wpda-select-panel-type-button-cancel").on("click", function() {
1579 jQuery("#wpda-select-panel-type").hide();
1580
1581 return false;
1582 });
1583
1584 jQuery("#wpda-add-panel-button").on("click", function () {
1585 panelName = jQuery("#wpda-add-panel-name").val();
1586
1587 if (panelName=="") {
1588 alert("Widget name is required");
1589 } else {
1590 switch (jQuery("#wpda-add-panel-type").val()) {
1591 case "chart":
1592 addPanelChartToDashboard(
1593 "<?php
1594 echo esc_attr( $this->wp_nonce_add );
1595 ?>",
1596 panelName,
1597 null,
1598 null,
1599 jQuery("#wpda-add-panel-column").val(),
1600 jQuery("#wpda-add-panel-position").val(),
1601 );
1602 break;
1603 case "code":
1604 addPanelCodeToDashboard(
1605 "<?php
1606 echo esc_attr( $this->wp_nonce_add );
1607 ?>",
1608 panelName,
1609 jQuery("#wpda-add-panel-code").val(),
1610 jQuery("#wpda-add-panel-column").val(),
1611 jQuery("#wpda-add-panel-position").val(),
1612 );
1613 break;
1614 case "dbs":
1615 addPanelDbmsToDashboard(
1616 "<?php
1617 echo esc_attr( $this->wp_nonce_add );
1618 ?>",
1619 panelName,
1620 jQuery("#wpda-add-panel-dbms").val(),
1621 jQuery("#wpda-add-panel-column").val(),
1622 jQuery("#wpda-add-panel-position").val(),
1623 );
1624 break;
1625 case "project":
1626 addPanelProjectToDashboard(
1627 "<?php
1628 echo esc_attr( $this->wp_nonce_add );
1629 ?>",
1630 panelName,
1631 jQuery("#wpda-add-panel-project").val(),
1632 jQuery("#wpda-add-panel-column").val(),
1633 jQuery("#wpda-add-panel-position").val(),
1634 );
1635 break;
1636 case "pub":
1637 addPanelPublicationToDashboard(
1638 "<?php
1639 echo esc_attr( $this->wp_nonce_add );
1640 ?>",
1641 panelName,
1642 jQuery("#wpda-add-panel-publication").val(),
1643 jQuery("#wpda-add-panel-column").val(),
1644 jQuery("#wpda-add-panel-position").val(),
1645 );
1646 break;
1647 default:
1648 alert("Unknown panel type");
1649 }
1650 }
1651
1652 return false;
1653 });
1654
1655 jQuery("#wpda-add-panel-button-back").on("click", function() {
1656 jQuery("#wpda-add-panel").hide();
1657 jQuery("#wpda-select-panel-type").show();
1658
1659 return false;
1660 });
1661
1662 jQuery("#wpda-add-panel-button-cancel").on("click", function () {
1663 closePanel();
1664
1665 return false;
1666 });
1667 });
1668 </script>
1669 <?php
1670 }
1671
1672 /**
1673 * Add dashboard columns
1674 *
1675 * @return void
1676 */
1677 protected function columns() {
1678 ?>
1679 <div id="wpda-dashboard-content" class="wpda-dashboard-content">
1680 <?php
1681 // Following line requires PHP 7.
1682 // $last_key = array_key_last($this->dashboard_positions[0]); .
1683 $last_key = 1;
1684 if ( is_array( $this->dashboard_positions ) && count( $this->dashboard_positions ) > 0 ) {
1685 // phpcs:ignore -- 8.1 proof
1686 foreach ( $this->dashboard_positions[0] as $key => $val ) {
1687 $last_key = $key;
1688 }
1689 }
1690 $this->number_of_columns = $last_key;
1691 for ($i = 1; $i <= $this->number_of_columns; $i++) {
1692 ?>
1693 <div id="wpda-dashboard-column-<?php
1694 echo esc_attr( $i );
1695 ?>" class="wpda-dashboard-column wpda-dashboard-column-<?php
1696 echo esc_attr( $this->number_of_columns );
1697 ?>">
1698 </div>
1699 <?php
1700 }
1701 ?>
1702 </div>
1703 <?php
1704 }
1705
1706 /**
1707 * Add panels to dashboard
1708 *
1709 * @return void
1710 */
1711 protected function add_panels() {
1712 }
1713
1714 /**
1715 * Add panel
1716 *
1717 * @param string $dashboard_widget Widget name.
1718 * @param string $column Column name.
1719 * @param string $position Position.
1720 * @param string $widget_id Widget ID.
1721 * @return void
1722 */
1723 protected static function add_panel(
1724 $dashboard_widget,
1725 $column,
1726 $position,
1727 $widget_id = null
1728 ) {
1729 }
1730
1731 /**
1732 * Get available databases as option list
1733 *
1734 * @return string
1735 */
1736 private function get_databases() {
1737 // Get available databases.
1738 $dbs = WPDA_Dictionary_Lists::get_db_schemas();
1739 foreach ( $dbs as $db ) {
1740 $databases[] = $db['schema_name'];
1741 }
1742 global $wpdb;
1743 $database_options = '';
1744 foreach ( $databases as $database ) {
1745 $selected = ( WPDA::get_user_default_scheme() === $database ? 'selected' : '' );
1746 if ( $database === $wpdb->dbname ) {
1747 $database_text = "WordPress database ({$database})";
1748 } else {
1749 $database_text = $database;
1750 }
1751 $database_options .= '<option value="' . esc_attr( $database ) . '" ' . esc_attr( $selected ) . '>' . esc_attr( $database_text ) . '</option>';
1752 }
1753 // Return available databases as option list.
1754 return $database_options;
1755 }
1756
1757 /**
1758 * Add javascript functions
1759 *
1760 * @return void
1761 */
1762 public function dashboard_js() {
1763 ?>
1764 <script type="application/javascript">
1765 let wpda_wpnonce_save = "<?php
1766 echo esc_attr( wp_create_nonce( static::DASHBOARD_SAVE . WPDA::get_current_user_login() ) );
1767 ?>";
1768 let wpda_wpnonce_add = "<?php
1769 echo esc_attr( wp_create_nonce( WPDA_Widget::WIDGET_ADD . WPDA::get_current_user_login() ) );
1770 ?>";
1771 let wpda_wpnonce_qb = "<?php
1772 echo esc_attr( wp_create_nonce( 'wpda-query-builder-' . WPDA::get_current_user_id() ) );
1773 ?>";
1774 let wpda_wpnonce_refresh = "<?php
1775 echo esc_attr( wp_create_nonce( WPDA_Widget::WIDGET_REFRESH . WPDA::get_current_user_login() ) );
1776 ?>";
1777 let wpda_ajaxurl = "<?php
1778 echo esc_url( admin_url( 'admin-ajax.php' ) );
1779 ?>";
1780 let wpda_databases = '<?php
1781 // phpcs:disable WordPress.Security.EscapeOutput
1782 echo $this->get_databases();
1783 // phpcs:enable WordPress.Security.EscapeOutput
1784 ?>';
1785 let wpda_shared_dashboards = <?php
1786 echo json_encode( $this->shared_dashboards );
1787 // phpcs:ignore
1788 ?>;
1789
1790 function saveWidgetPositions() {} // Implemented in the premium version
1791 function saveDashBoard(callback) {
1792 saveWidgetPositions();
1793 jQuery.ajax({
1794 type: "POST",
1795 url: wpda_ajaxurl + "?action=wpda_save_dashboard",
1796 data: {
1797 wp_nonce: wpda_wpnonce_save,
1798 wpda_widgets: dashboardWidgets,
1799 wpda_positions: dashboardWidgetPosition,
1800 wpda_deleted: dashboardWidgetDeleted,
1801 wpda_tabname: "<?php
1802 echo esc_attr( $this->tab_name );
1803 ?>"
1804 }
1805 }).done(
1806 function(data) {
1807 dashboardWidgetDeleted = [];
1808 if (callback!==undefined) {
1809 callback();
1810 }
1811 }
1812 ).fail(
1813 function (msg) {
1814 console.log("WP Data Access error (saveDashBoard):", msg);
1815 }
1816 );
1817 }
1818 <?php
1819 ?>
1820 </script>
1821 <?php
1822 }
1823
1824 /**
1825 * Save dashboard and widgets
1826 *
1827 * @return void
1828 */
1829 public static function save() {
1830 $wp_nonce = ( isset( $_POST['wp_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wp_nonce'] ) ) : '' );
1831 if ( !wp_verify_nonce( $wp_nonce, static::DASHBOARD_SAVE . WPDA::get_current_user_login() ) ) {
1832 WPDA::sent_header( 'application/json' );
1833 static::msg( 'ERROR', 'Token expired, please refresh page' );
1834 wp_die();
1835 }
1836 // phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1837 $widgets = ( isset( $_POST['wpda_widgets'] ) ? WPDA::sanitize_text_field_array( $_POST['wpda_widgets'] ) : array() );
1838 // phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1839 $save = array();
1840 foreach ( $widgets as $widget ) {
1841 $save[$widget['widgetName']] = $widget;
1842 }
1843 update_user_meta( WPDA::get_current_user_id(), self::USER_DASHBOARD, $save );
1844 self::msg( 'SUCCESS', 'Widget succesfully saved' );
1845 wp_die();
1846 }
1847
1848 /**
1849 * Get list of all widgets
1850 *
1851 * @return void
1852 */
1853 public static function get_list() {
1854 $wp_nonce = ( isset( $_POST['wpda_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wpda_wpnonce'] ) ) : '' );
1855 if ( !wp_verify_nonce( $wp_nonce, WPDA_Widget::WIDGET_REFRESH . WPDA::get_current_user_login() ) ) {
1856 WPDA::sent_header( 'application/json' );
1857 static::msg( 'ERROR', 'Token expired, please refresh page' );
1858 wp_die();
1859 }
1860 // Placeholder: implemented in the premium version.
1861 echo '';
1862 wp_die();
1863 }
1864
1865 /**
1866 * Delete widget
1867 *
1868 * @return void
1869 */
1870 public static function delete_widget() {
1871 $wp_nonce = ( isset( $_POST['wpda_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wpda_wpnonce'] ) ) : '' );
1872 if ( !wp_verify_nonce( $wp_nonce, self::DASHBOARD_SAVE . WPDA::get_current_user_login() ) ) {
1873 WPDA::sent_header( 'application/json' );
1874 static::msg( 'ERROR', 'Token expired, please refresh page' );
1875 wp_die();
1876 }
1877 // Placeholder: implemented in the premium version.
1878 echo '';
1879 wp_die();
1880 }
1881
1882 /**
1883 * Edit chart
1884 *
1885 * @return void
1886 */
1887 public static function edit_chart() {
1888 $wp_nonce = ( isset( $_POST['wpda_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wpda_wpnonce'] ) ) : '' );
1889 if ( !wp_verify_nonce( $wp_nonce, WPDA_Widget::WIDGET_REFRESH . WPDA::get_current_user_login() ) ) {
1890 WPDA::sent_header( 'application/json' );
1891 static::msg( 'ERROR', 'Token expired, please refresh page' );
1892 wp_die();
1893 }
1894 // Placeholder: implemented in the premium version.
1895 echo '';
1896 wp_die();
1897 }
1898
1899 /**
1900 * Load widget via ajax
1901 *
1902 * @return void
1903 */
1904 public static function load_widget() {
1905 $wp_nonce = ( isset( $_POST['wpda_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wpda_wpnonce'] ) ) : '' );
1906 if ( !wp_verify_nonce( $wp_nonce, WPDA_Widget::WIDGET_REFRESH . WPDA::get_current_user_login() ) ) {
1907 WPDA::sent_header( 'application/json' );
1908 static::msg( 'ERROR', 'Token expired, please refresh page' );
1909 wp_die();
1910 }
1911 // Placeholder: implemented in the premium version.
1912 echo '';
1913 wp_die();
1914 }
1915
1916 /**
1917 * Construct tab name
1918 *
1919 * @param string $tab_name Original tab name.
1920 * @return string
1921 */
1922 public static function get_tab_name( $tab_name ) {
1923 return '_' . str_replace( ' ', '_', $tab_name );
1924 }
1925
1926 /**
1927 * Permanently remove plugin info message from dashboard
1928 *
1929 * @return void
1930 */
1931 public static function remove_new_dashboard_message() {
1932 WPDA::sent_header( 'text/html; charset=UTF-8' );
1933 $wp_nonce = ( isset( $_POST['wp_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wp_nonce'] ) ) : '' );
1934 if ( wp_verify_nonce( $wp_nonce, self::DASHBOARD_SAVE . WPDA::get_current_user_login() ) ) {
1935 // Permanently remove message from dashboard toolbar.
1936 update_user_meta( WPDA::get_current_user_id(), self::USER_NEW_MESSAGE, 'removed' );
1937 echo 'OK';
1938 } else {
1939 echo 'FAILED';
1940 }
1941 wp_die();
1942 }
1943
1944 /**
1945 * Construct ajax message
1946 *
1947 * @param string $status Status.
1948 * @param string $msg Message.
1949 * @return false|string
1950 */
1951 public static function msg( $status, $msg ) {
1952 $error = array(
1953 'status' => esc_attr( $status ),
1954 'msg' => $msg,
1955 );
1956 echo json_encode( $error );
1957 // phpcs:ignore WordPress.Security.EscapeOutput
1958 }
1959
1960 private function get_promotions( $tool ) {
1961 switch ( $tool ) {
1962 case 'publisher':
1963 case 'projects':
1964 case 'templates':
1965 case 'charts':
1966 $promotions = array(array(
1967 'This tool will be transitioned to the new App Builder. Please migrate on time.' => array(null, 'fa-lightbulb'),
1968 ));
1969 break;
1970 default:
1971 $promotions = array();
1972 }
1973 if ( count( $promotions ) > 0 ) {
1974 // phpcs:ignore -- 8.1 proof
1975 $promotion_index = random_int( 0, count( $promotions ) - 1 );
1976 $promotion = $promotions[$promotion_index];
1977 $promotion_text = key( $promotion );
1978 $promotion_url = $promotion[$promotion_text][0];
1979 $promotion_icon = $promotion[$promotion_text][1];
1980 ?>
1981 <div class="wpda-promotion">
1982 <span><i class="fas <?php
1983 echo esc_attr( $promotion_icon );
1984 ?>"></i></span>
1985 <?php
1986 echo esc_attr( $promotion_text );
1987 ?>
1988 <?php
1989 if ( null !== $promotion_url ) {
1990 ?>
1991 <a href="<?php
1992 echo esc_url( $promotion_url );
1993 ?>" target="_blank">Read more...</a>
1994 <?php
1995 }
1996 ?>
1997 </div>
1998 <?php
1999 }
2000 }
2001
2002 }
2003
2004 // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing