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

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

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