PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.85
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.85
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
← All changes | public/class-wp-data-access-public.php +135 -207 5.5.36 → 5.5.85 View file →
@@ -19,8 +19,9 @@
19 19 *
20 20 * @author Peter Schulz
21 21 * @since 1.0.0
22 22 */
23 +// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- verified on page
23 24 class WP_Data_Access_Public {
24 25 /**
25 26 * Add stylesheets to front-end
26 27 *
@@ -110,10 +111,10 @@
110 111 );
111 112 // SAVING SPACE - According to the plugin guidelines it is allowed to include external fonts:
112 113 // https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/#8-plugins-may-not-send-executable-code-via-third-party-systems .
113 114 // Load fontawesome icons.
115 + // phpcs:disable WordPress.WP.EnqueuedResourceParameters.MissingVersion
114 116 wp_register_style(
115 - // phpcs:ignore WordPress.WP.EnqueuedResourceParameters
116 117 'wpda_fontawesome_icons',
117 118 WPDA::CDN_FONTAWESOME . 'all.min.css',
118 119 array(),
119 120 null,
@@ -254,11 +255,12 @@
254 255 *
255 256 * @since 1.0.0
256 257 */
257 258 public function register_shortcodes() {
259 + add_shortcode( 'wpda_app', array($this, 'wpda_app') );
258 260 add_shortcode( 'wpda_app_builder', array($this, 'wpda_app_builder') );
259 - add_shortcode( 'wpda_app', array($this, 'wpda_app') );
260 261 add_shortcode( 'wpda_data_explorer', array($this, 'wpda_data_explorer') );
262 + add_shortcode( 'wpda_query_builder', array($this, 'wpda_query_builder') );
261 263 add_shortcode( 'wpdataaccess', array($this, 'wpdataaccess') );
262 264 add_shortcode( 'wpdadiehard', array($this, 'wpdadiehard') );
263 265 }
264 266
@@ -286,9 +288,9 @@
286 288 return $editing;
287 289 }
288 290 if ( isset( $_POST['is_fb_preview'], $_GET['et_pb_preview'] ) && 'true' === $_POST['is_fb_preview'] && 'true' === $_GET['et_pb_preview'] ) {
289 291 // Divi Visual Builder preview not working!
290 - // Styles are not properly loaded into the Divi Visual Builder.
292 + // Dynamic resources are not properly loaded into the Divi Visual Builder.
291 293 ob_start();
292 294 ?>
293 295 <div style="width: 100%; border: 1px solid #ccc; padding: 50px; display: grid; gap: 20px; background-color: rgb(249,249,249); border-radius: 5px;">
294 296 <div>
@@ -308,10 +310,18 @@
308 310 'fullscreen' => false,
309 311 'filter_field_name' => null,
310 312 'filter_field_value' => null,
311 313 ), $atts );
314 + $shortcode_params = array();
315 + foreach ( $atts as $key => $value ) {
316 + if ( !key_exists( $key, $wp_atts ) ) {
317 + $shortcode_params[$key] = $value;
318 + }
319 + }
320 + $shortcode_params['pwa'] = false;
321 + // Shortcode not allowed to use parameter pwa
312 322 ob_start();
313 - $app = new WPDataAccess\Data_Apps\WPDA_App_Container($wp_atts);
323 + $app = new WPDataAccess\Data_Apps\WPDA_App_Container($wp_atts, $shortcode_params);
314 324 $app->show();
315 325 return ob_get_clean();
316 326 }
317 327
@@ -331,8 +341,25 @@
331 341 $explorer->show();
332 342 return ob_get_clean();
333 343 }
334 344
345 + public function wpda_query_builder( $atts ) {
346 + $editing = WPDA::is_editing_post();
347 + if ( false !== $editing ) {
348 + // Prevent errors when user is editing a post.
349 + return $editing;
350 + }
351 + $atts = array_change_key_case( (array) $atts, CASE_LOWER );
352 + //phpcs:ignore - 8.1 proof
353 + $wp_atts = shortcode_atts( array(
354 + 'feedback' => false,
355 + ), $atts );
356 + ob_start();
357 + $qb = new WPDataAccess\Data_Apps\WPDA_Query_Builder($wp_atts);
358 + $qb->show();
359 + return ob_get_clean();
360 + }
361 +
335 362 /**
336 363 * Implementation of shortcode 'wpdataaccess'
337 364 *
338 365 * Checks the values entered on validity (as far as possible) and builds the table based on the given table name,
@@ -425,26 +452,14 @@
425 452 global $wpdb;
426 453 $atts = array_change_key_case( (array) $atts, CASE_LOWER );
427 454 //phpcs:ignore - 8.1 proof
428 455 $wp_atts = shortcode_atts( array(
429 - 'project_id' => '',
430 - 'page_id' => '',
431 - 'schema_name' => $wpdb->dbname,
432 - 'table_name' => '',
433 - 'title' => '',
434 - 'subtitle' => '',
435 - 'bulk_actions_enabled' => false,
436 - 'search_box_enabled' => false,
437 - 'bulk_export_enabled' => false,
438 - 'show_view_link' => 'on',
439 - 'allow_insert' => 'off',
440 - 'allow_update' => 'off',
441 - 'allow_delete' => 'off',
442 - 'allow_import' => 'off',
456 + 'project_id' => '',
457 + 'page_id' => '',
443 458 ), $atts );
444 - if ( '' === $wp_atts['project_id'] && '' === $wp_atts['page_id'] && '' === $wp_atts['table_name'] ) {
445 - // Either a Data Project page (project_id and page_id) or a table name must be provided.
446 - return __( 'ERROR: Missing argument(s) [(project_id and page_id) or table_name]', 'wp-data-access' );
459 + if ( '' === $wp_atts['project_id'] && '' === $wp_atts['page_id'] ) {
460 + // Dashboard menu feature was removed. Parameter table_name no longer valid.
461 + return __( 'ERROR: Missing argument(s) [project_id and page_id]', 'wp-data-access' );
447 462 }
448 463 // Sanitize database values.
449 464 $wp_atts['project_id'] = sanitize_text_field( wp_unslash( $wp_atts['project_id'] ) );
450 465 // input var okay.
@@ -449,46 +464,8 @@
449 464 $wp_atts['project_id'] = sanitize_text_field( wp_unslash( $wp_atts['project_id'] ) );
450 465 // input var okay.
451 466 $wp_atts['page_id'] = sanitize_text_field( wp_unslash( $wp_atts['page_id'] ) );
452 467 // input var okay.
453 - $wp_atts['schema_name'] = sanitize_text_field( wp_unslash( $wp_atts['schema_name'] ) );
454 - // input var okay.
455 - $wp_atts['table_name'] = sanitize_text_field( wp_unslash( $wp_atts['table_name'] ) );
456 - // input var okay.
457 - // Set default parameter values.
458 - $bulk_actions_enabled = false;
459 - $search_box_enabled = false;
460 - $bulk_export_enabled = false;
461 - $show_view_link = 'on';
462 - $allow_insert = 'off';
463 - $allow_update = 'off';
464 - $allow_delete = 'off';
465 - $allow_import = 'off';
466 - // Check arguments.
467 - if ( 'true' === $wp_atts['bulk_actions_enabled'] ) {
468 - $bulk_actions_enabled = true;
469 - }
470 - if ( 'true' === $wp_atts['search_box_enabled'] ) {
471 - $search_box_enabled = true;
472 - }
473 - if ( 'true' === $wp_atts['bulk_export_enabled'] ) {
474 - $bulk_export_enabled = true;
475 - }
476 - if ( 'false' === $wp_atts['show_view_link'] ) {
477 - $show_view_link = 'off';
478 - }
479 - if ( 'true' === $wp_atts['allow_insert'] ) {
480 - $allow_insert = 'on';
481 - }
482 - if ( 'true' === $wp_atts['allow_update'] ) {
483 - $allow_update = 'on';
484 - }
485 - if ( 'true' === $wp_atts['allow_delete'] ) {
486 - $allow_delete = 'on';
487 - }
488 - if ( 'true' === $wp_atts['allow_import'] ) {
489 - $allow_import = 'on';
490 - }
491 468 $default_where = '';
492 469 if ( isset( $atts['filter_field_name'] ) && isset( $atts['filter_field_value'] ) ) {
493 470 $filter_field_name = str_replace( '`', '', sanitize_text_field( wp_unslash( $atts['filter_field_name'] ) ) );
494 471 // input var okay.
@@ -500,41 +477,15 @@
500 477 //phpcs:ignore - 8.1 proof
501 478 if ( count( $filter_field_name_array ) === count( $filter_field_value_array ) ) {
502 479 //phpcs:ignore - 8.1 proof
503 480 // Add filter to where clause.
481 + // phpcs:disable Generic.CodeAnalysis.ForLoopWithTestFunctionCall, Squiz.PHP.DisallowSizeFunctionsInLoops, WordPress.DB.PreparedSQLPlaceholders
504 482 for ($i = 0; $i < count( $filter_field_name_array ); $i++) {
505 - // phpcs:ignore Generic.CodeAnalysis.ForLoopWithTestFunctionCall, Squiz.PHP.DisallowSizeFunctionsInLoops
506 - $default_where .= (( '' === $default_where ? '' : ' and ' )) . $wpdb->prepare(
507 - ' `%1s` like %s ',
508 - // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
509 - array(WPDA::remove_backticks( $filter_field_name_array[$i] ), $filter_field_value_array[$i])
510 - );
483 + $default_where .= (( '' === $default_where ? '' : ' and ' )) . $wpdb->prepare( ' `%1s` like %s ', array(WPDA::remove_backticks( $filter_field_name_array[$i] ), $filter_field_value_array[$i]) );
511 484 }
485 + // phpcs:enable Generic.CodeAnalysis.ForLoopWithTestFunctionCall, Squiz.PHP.DisallowSizeFunctionsInLoops, WordPress.DB.PreparedSQLPlaceholders
512 486 }
513 487 }
514 - // Is this a Data Projects page or a table administration page?
515 - if ( '' !== $wp_atts['project_id'] && '' !== $wp_atts['page_id'] ) {
516 - // phpcs:ignore Generic.CodeAnalysis.EmptyStatement
517 - // Request for Data Projects page (check is performed in WPDP_List_Page).
518 - } else {
519 - // Request for table administration page.
520 - // Check schema name.
521 - if ( 'sys' === $wp_atts['schema_name'] || 'mysql' === $wp_atts['schema_name'] || 'information_schema' === $wp_atts['schema_name'] ) {
522 - // No access to MySQL databases (meta data)!
523 - return __( 'ERROR: No access to MySQL meta data', 'wp-data-access' );
524 - }
525 - // Check database table name.
526 - if ( '' === $wp_atts['table_name'] ) {
527 - // Table name must be provided! No database administration in the public area!
528 - return __( 'ERROR: Missing argument [table_name]', 'wp-data-access' );
529 - }
530 - // Check if table exists (to prevent sql injection) and access is granted.
531 - $wpda_dictionary_checks = new WPDA_Dictionary_Exist($wp_atts['schema_name'], $wp_atts['table_name']);
532 - if ( !$wpda_dictionary_checks->table_exists( true, false ) ) {
533 - // Table not found.
534 - return '<p>' . __( 'ERROR: Invalid table name or not authorized', 'wp-data-access' ) . '</p>';
535 - }
536 - }
537 488 // Make sure user has access to necessary (fake) classes and functions in the frontend.
538 489 require_once plugin_dir_path( __DIR__ ) . 'wp-data-access-diehard.php';
539 490 // Make sure all style and JS is available.
540 491 wp_enqueue_script( 'wpda_admin_scripts' );
@@ -561,134 +512,109 @@
561 512 do_action( 'wpda_wpdadiehard_prepare' );
562 513 ob_start();
563 514 // Set page argument to allow public access.
564 515 $_REQUEST['page'] = 'diehard';
565 - if ( '' !== $wp_atts['project_id'] && '' !== $wp_atts['page_id'] ) {
566 - // Show Data Projects page (check is performed in WPDP_List_Page).
567 - // Get page values.
568 - $project_page = $wpdb->get_results( $wpdb->prepare( "\n select * from {$wpdb->prefix}wpda_project_page\n where project_id = %d\n and page_id = %d\n \t", array($wp_atts['project_id'], $wp_atts['page_id']) ), 'ARRAY_A' );
569 - // db call ok; no-cache ok.
570 - if ( 0 === $wpdb->num_rows ) {
571 - // This should never happen as it was already tested before.
572 - return __( 'ERROR: Data Project page not found [need a valid project_id and page_id]', 'wp-data-access' );
573 - }
574 - if ( 'off' !== WPDA::get_option( WPDA::OPTION_WPDA_USE_ROLES_IN_SHORTCODE ) ) {
575 - // Check if user has role.
576 - $user_roles = WPDA::get_current_user_roles();
577 - if ( false === $user_roles ) {
578 - // Cannot determine the user role(s). Not able to show project menus.
579 - return __( 'ERROR: No access [could not determine user role]', 'wp-data-access' );
516 + // Show Data Projects page (check is performed in WPDP_List_Page).
517 + // Get page values.
518 + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- plugin table
519 + $project_page = $wpdb->get_results( $wpdb->prepare( "\n select * from {$wpdb->prefix}wpda_project_page\n where project_id = %d\n and page_id = %d\n \t", array($wp_atts['project_id'], $wp_atts['page_id']) ), 'ARRAY_A' );
520 + // db call ok; no-cache ok.
521 + // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
522 + if ( 0 === $wpdb->num_rows ) {
523 + // This should never happen as it was already tested before.
524 + return __( 'ERROR: Data Project page not found [need a valid project_id and page_id]', 'wp-data-access' );
525 + }
526 + // Check if user has role.
527 + $user_roles = WPDA::get_current_user_roles();
528 + if ( false === $user_roles ) {
529 + // Cannot determine the user role(s). Not able to show project menus.
530 + return __( 'ERROR: No access [could not determine user role]', 'wp-data-access' );
531 + }
532 + $user_has_role = in_array( 'administrator', $user_roles, true );
533 + if ( !$user_has_role && '' !== $project_page[0]['page_role'] && null !== $project_page[0]['page_role'] ) {
534 + $user_role_array = explode( ',', $project_page[0]['page_role'] );
535 + foreach ( $user_role_array as $user_role_array_item ) {
536 + $user_has_role = in_array( $user_role_array_item, $user_roles, true );
537 + if ( $user_has_role ) {
538 + break;
580 539 }
581 - $user_has_role = false;
582 - if ( '' === $project_page[0]['page_role'] || null === $project_page[0]['page_role'] ) {
583 - $user_has_role = in_array( 'administrator', $user_roles, true );
584 - //phpcs:ignore - 8.1 proof
585 - } else {
586 - $user_role_array = explode( ',', $project_page[0]['page_role'] );
587 - //phpcs:ignore - 8.1 proof
588 - foreach ( $user_role_array as $user_role_array_item ) {
589 - $user_has_role = in_array( $user_role_array_item, $user_roles, true );
590 - //phpcs:ignore - 8.1 proof
591 - if ( $user_has_role ) {
592 - break;
593 - }
594 - }
595 - }
596 - if ( !$user_has_role ) {
597 - return __( 'ERROR: No access [missing role]', 'wp-data-access' );
598 - }
599 540 }
600 - // Determine plugin classes to be used.
601 - if ( 'static' === $project_page[0]['page_type'] ) {
602 - return '';
603 - } elseif ( 'table' === $project_page[0]['page_type'] ) {
604 - $list_view_class = 'WPDataProjects\\List_Table\\WPDP_List_View';
605 - $list_table_class = 'WPDataProjects\\List_Table\\WPDP_List_Table';
606 - $edit_form_class = 'WPDataProjects\\Simple_Form\\WPDP_Simple_Form';
541 + }
542 + if ( !$user_has_role ) {
543 + return __( 'ERROR: No access [missing role]', 'wp-data-access' );
544 + }
545 + // Determine plugin classes to be used.
546 + if ( 'static' === $project_page[0]['page_type'] ) {
547 + return '';
548 + } elseif ( 'table' === $project_page[0]['page_type'] ) {
549 + $list_view_class = 'WPDataProjects\\List_Table\\WPDP_List_View';
550 + $list_table_class = 'WPDataProjects\\List_Table\\WPDP_List_Table';
551 + $edit_form_class = 'WPDataProjects\\Simple_Form\\WPDP_Simple_Form';
552 + } else {
553 + $list_view_class = 'WPDataProjects\\Parent_Child\\WPDP_Parent_List_View';
554 + $list_table_class = 'WPDataProjects\\Parent_Child\\WPDP_Parent_List_Table';
555 + $edit_form_class = 'WPDataProjects\\Parent_Child\\WPDP_Parent_Form';
556 + }
557 + if ( null !== $project_page[0]['page_where'] && '' !== $project_page[0]['page_where'] ) {
558 + if ( 'where' === substr( str_replace( ' ', '', $project_page[0]['page_where'] ), 0, 5 ) ) {
559 + $where_clause = " {$project_page[0]['page_where']}";
607 560 } else {
608 - $list_view_class = 'WPDataProjects\\Parent_Child\\WPDP_Parent_List_View';
609 - $list_table_class = 'WPDataProjects\\Parent_Child\\WPDP_Parent_List_Table';
610 - $edit_form_class = 'WPDataProjects\\Parent_Child\\WPDP_Parent_Form';
561 + $where_clause = " where {$project_page[0]['page_where']} ";
611 562 }
612 - if ( null !== $project_page[0]['page_where'] && '' !== $project_page[0]['page_where'] ) {
613 - if ( 'where' === substr( str_replace( ' ', '', $project_page[0]['page_where'] ), 0, 5 ) ) {
614 - $where_clause = " {$project_page[0]['page_where']}";
615 - } else {
616 - $where_clause = " where {$project_page[0]['page_where']} ";
617 - }
618 - $where_clause = WPDA::substitute_environment_vars( $where_clause );
563 + $where_clause = WPDA::substitute_environment_vars( $where_clause );
564 + } else {
565 + $where_clause = '';
566 + }
567 + if ( '' === $default_where ) {
568 + $default_where = $where_clause;
569 + } else {
570 + if ( '' === $where_clause ) {
571 + $default_where = " where {$default_where} ";
619 572 } else {
620 - $where_clause = '';
573 + $default_where = " {$where_clause} and {$default_where} ";
621 574 }
622 - if ( '' === $default_where ) {
623 - $default_where = $where_clause;
624 - } else {
625 - if ( '' === $where_clause ) {
626 - $default_where = " where {$default_where} ";
627 - } else {
628 - $default_where = " {$where_clause} and {$default_where} ";
629 - }
630 - }
631 - $default_orderby = $project_page[0]['page_orderby'];
632 - // Prepare arguments.
633 - $args = array(
634 - 'page_hook_suffix' => 'WPDA_WPDP',
635 - 'wpdaschema_name' => $project_page[0]['page_schema_name'],
636 - 'table_name' => $project_page[0]['page_table_name'],
637 - 'list_table_class' => $list_table_class,
638 - 'edit_form_class' => $edit_form_class,
639 - 'project_id' => $wp_atts['project_id'],
640 - 'page_id' => $wp_atts['page_id'],
641 - 'default_where' => $default_where,
642 - 'where_clause' => $default_where,
643 - 'orderby_clause' => $default_orderby,
644 - );
645 - if ( 'view' === $project_page[0]['page_mode'] ) {
646 - $args['allow_update'] = 'off';
647 - $args['allow_import'] = 'off';
648 - }
649 - if ( 'no' === $project_page[0]['page_allow_insert'] ) {
650 - $args['allow_insert'] = 'off';
651 - $args['allow_import'] = 'off';
652 - }
653 - if ( 'no' === $project_page[0]['page_allow_delete'] ) {
654 - $args['allow_delete'] = 'off';
655 - }
656 - if ( 'only' === $project_page[0]['page_allow_insert'] ) {
657 - $args['action'] = 'new';
658 - $args['allow_insert'] = 'only';
659 - $args['allow_update'] = 'off';
660 - $args['allow_import'] = 'off';
661 - $args['allow_delete'] = 'off';
662 - }
663 - if ( 'no' === $project_page[0]['page_allow_import'] ) {
664 - $args['allow_import'] = 'off';
665 - }
666 - if ( 'no' === $project_page[0]['page_allow_bulk'] ) {
667 - $args['bulk_actions_enabled'] = false;
668 - }
669 - // Show page.
670 - $project_page_view = new $list_view_class($args);
671 - $project_page_view->show();
672 - } else {
673 - // Show table administration page.
674 - $media_manager = new WPDA_List_View(array(
675 - 'wpdaschema_name' => $wp_atts['schema_name'],
676 - 'table_name' => $wp_atts['table_name'],
677 - 'title' => $wp_atts['title'],
678 - 'subtitle' => $wp_atts['subtitle'],
679 - 'bulk_actions_enabled' => $bulk_actions_enabled,
680 - 'search_box_enabled' => $search_box_enabled,
681 - 'bulk_export_enabled' => $bulk_export_enabled,
682 - 'show_view_link' => $show_view_link,
683 - 'allow_insert' => $allow_insert,
684 - 'allow_update' => $allow_update,
685 - 'allow_delete' => $allow_delete,
686 - 'allow_import' => $allow_import,
687 - 'default_where' => $default_where,
688 - ));
689 - $media_manager->show();
690 575 }
576 + $default_orderby = $project_page[0]['page_orderby'];
577 + // Prepare arguments.
578 + $args = array(
579 + 'page_hook_suffix' => 'WPDA_WPDP',
580 + 'wpdaschema_name' => $project_page[0]['page_schema_name'],
581 + 'table_name' => $project_page[0]['page_table_name'],
582 + 'list_table_class' => $list_table_class,
583 + 'edit_form_class' => $edit_form_class,
584 + 'project_id' => $wp_atts['project_id'],
585 + 'page_id' => $wp_atts['page_id'],
586 + 'default_where' => $default_where,
587 + 'where_clause' => $default_where,
588 + 'orderby_clause' => $default_orderby,
589 + );
590 + if ( 'view' === $project_page[0]['page_mode'] ) {
591 + $args['allow_update'] = 'off';
592 + $args['allow_import'] = 'off';
593 + }
594 + if ( 'no' === $project_page[0]['page_allow_insert'] ) {
595 + $args['allow_insert'] = 'off';
596 + $args['allow_import'] = 'off';
597 + }
598 + if ( 'no' === $project_page[0]['page_allow_delete'] ) {
599 + $args['allow_delete'] = 'off';
600 + }
601 + if ( 'only' === $project_page[0]['page_allow_insert'] ) {
602 + $args['action'] = 'new';
603 + $args['allow_insert'] = 'only';
604 + $args['allow_update'] = 'off';
605 + $args['allow_import'] = 'off';
606 + $args['allow_delete'] = 'off';
607 + }
608 + if ( 'no' === $project_page[0]['page_allow_import'] ) {
609 + $args['allow_import'] = 'off';
610 + }
611 + if ( 'no' === $project_page[0]['page_allow_bulk'] ) {
612 + $args['bulk_actions_enabled'] = false;
613 + }
614 + // Show page.
615 + $project_page_view = new $list_view_class($args);
616 + $project_page_view->show();
691 617 ?>
692 618 <script type='text/javascript'>
693 619 // JS variable commonL10n is used in loaded scripts, copied from wp_default_scripts for responsive support
694 620 /* <![CDATA[ */
@@ -728,4 +654,6 @@
728 654 return ob_get_clean();
729 655 }
730 656
731 657 }
658 +
659 +// phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing