← All changes
|
WPDataAccess/Global_Search/WPDA_Global_Search.php
+67
-46
5.5.3
→
5.5.85
View file →
| @@ -79,8 +79,10 @@ | ||
| 79 | 79 | <?php |
| 80 | 80 | global $wpdb; |
| 81 | 81 | foreach ( $this->databases as $database ) { |
| 82 | 82 | $dbname = $database === $wpdb->dbname ? "WordPress database ({$esc_attr( $database )})" : esc_attr( $database ); |
| 83 | + | |
| 84 | + // phpcs:ignore PluginCheck.CodeAnalysis.Heredoc.NotAllowed | |
| 83 | 85 | $dbs = <<< EOL |
| 84 | 86 | <div class="selectionFrameBodyElement" |
| 85 | 87 | onclick="selectSchema('{$esc_attr( $database )}')" |
| 86 | 88 | id="{$esc_attr( $database )}" |
| @@ -85,12 +87,12 @@ | ||
| 85 | 87 | onclick="selectSchema('{$esc_attr( $database )}')" |
| 86 | 88 | id="{$esc_attr( $database )}" |
| 87 | 89 | > |
| 88 | 90 | <input type="checkbox" id="chk_{$esc_attr( $database )}" /> |
| 89 | - {$dbname} | |
| 91 | + {$esc_attr( $dbname )} | |
| 90 | 92 | </div> |
| 91 | 93 | EOL; |
| 92 | - echo $dbs; | |
| 94 | + echo $dbs; // phpcs:ignore WordPress.Security.EscapeOutput | |
| 93 | 95 | } |
| 94 | 96 | ?> |
| 95 | 97 | </div> |
| 96 | 98 | <div class="selectionFrameFooter"> |
| @@ -397,28 +399,32 @@ | ||
| 397 | 399 | totalMatches += n; |
| 398 | 400 | jQuery("#totalMatches").html(totalMatches); |
| 399 | 401 | } |
| 400 | 402 | |
| 403 | + function cleanId(id) { | |
| 404 | + return id.replaceAll(".", "\\.").replaceAll(":", "\\:") | |
| 405 | + } | |
| 406 | + | |
| 401 | 407 | function showTableResults(schemaName, tableName, rows) { |
| 402 | - jQuery(`#result_${schemaName}_${tableName}`).html(rows + " rows"); | |
| 403 | - jQuery(`#result_${schemaName}_${tableName}`).closest("a").find(".linkSpinner").hide(); | |
| 408 | + jQuery(cleanId(`#result_${schemaName}_${tableName}`)).html(rows + " rows"); | |
| 409 | + jQuery(cleanId(`#result_${schemaName}_${tableName}`)).closest("a").find(".linkSpinner").hide(); | |
| 404 | 410 | |
| 405 | 411 | if (parseInt(rows)!==NaN && parseInt(rows)>0) { |
| 406 | - jQuery(`#result_${schemaName}_${tableName}`).closest("div").find(".match").addClass("matches"); | |
| 412 | + jQuery(cleanId(`#result_${schemaName}_${tableName}`)).closest("div").find(".match").addClass("matches"); | |
| 407 | 413 | updateTotalMatches(parseInt(rows)); |
| 408 | - jQuery(`#result_${schemaName}_${tableName}`).closest("a").removeClass("disableLink"); | |
| 409 | - jQuery(`#view_${schemaName}_${tableName}`).closest("span").find("button").show(); | |
| 414 | + jQuery(cleanId(`#result_${schemaName}_${tableName}`)).closest("a").removeClass("disableLink"); | |
| 415 | + jQuery(cleanId(`#view_${schemaName}_${tableName}`)).closest("span").find("button").show(); | |
| 410 | 416 | } |
| 411 | 417 | } |
| 412 | 418 | |
| 413 | 419 | function submitForm(schemaName, tableName) { |
| 414 | 420 | if (jQuery("#matchesInNewTab").is(":checked")) { |
| 415 | - jQuery(`#view_${schemaName}_${tableName}`).attr("target", "_blank"); | |
| 421 | + jQuery(cleanId(`#view_${schemaName}_${tableName}`)).attr("target", "_blank"); | |
| 416 | 422 | } else { |
| 417 | - jQuery(`#view_${schemaName}_${tableName}`).removeAttr("target"); | |
| 423 | + jQuery(cleanId(`#view_${schemaName}_${tableName}`)).removeAttr("target"); | |
| 418 | 424 | } |
| 419 | 425 | |
| 420 | - jQuery(`#view_${schemaName}_${tableName}`).submit(); | |
| 426 | + jQuery(cleanId(`#view_${schemaName}_${tableName}`)).submit(); | |
| 421 | 427 | } |
| 422 | 428 | |
| 423 | 429 | function showTableOutput(schemaName, tableName, addReplaceButtons, searchString, searchCase, replaceString) { |
| 424 | 430 | let button = addReplaceButtons ? |
| @@ -431,13 +437,13 @@ | ||
| 431 | 437 | <i class="fas fa-table"></i> |
| 432 | 438 | ${tableName} |
| 433 | 439 | </span> |
| 434 | 440 | <span> |
| 435 | - <form id="view_${schemaName}_${tableName}" action="?page=wpda" method="post" style="display:none"> | |
| 436 | - <input type="hidden" name="wpdaschema_name" value="${schemaName}" /> | |
| 437 | - <input type="hidden" name="table_name" value="${tableName}" /> | |
| 438 | - <input type="hidden" name="wpda_s" value="${searchString}" /> | |
| 439 | - <input type="hidden" name="wpda_c" value="${searchCase}" /> | |
| 441 | + <form id="view_${schemaName}_${tableName}" action="?page=wpda_table" method="post" style="display:none"> | |
| 442 | + <input type="hidden" name="dbs" value="${schemaName}" /> | |
| 443 | + <input type="hidden" name="tbl" value="${tableName}" /> | |
| 444 | + <input type="hidden" name="s" value="${searchString}" /> | |
| 445 | + <input type="hidden" name="c" value="${searchCase}" /> | |
| 440 | 446 | </form> |
| 441 | 447 | <a href="javascript:submitForm('${schemaName}', '${tableName}')" class="disableLink"> |
| 442 | 448 | <span class="linkSpinner"> |
| 443 | 449 | <i class="fa fa-spinner fa-spin"></i> |
| @@ -498,12 +504,12 @@ | ||
| 498 | 504 | }); |
| 499 | 505 | } |
| 500 | 506 | |
| 501 | 507 | function showError(schemaName, tableName) { |
| 502 | - jQuery(`#result_${schemaName}_${tableName}`).html(""); | |
| 503 | - jQuery(`#result_${schemaName}_${tableName}`).closest("a").find(".linkSpinner").hide(); | |
| 508 | + jQuery(cleanId(`#result_${schemaName}_${tableName}`)).html(""); | |
| 509 | + jQuery(cleanId(`#result_${schemaName}_${tableName}`)).closest("a").find(".linkSpinner").hide(); | |
| 504 | 510 | |
| 505 | - jQuery(`#view_${schemaName}_${tableName}`).closest("span").append(` | |
| 511 | + jQuery(cleanId(`#view_${schemaName}_${tableName}`)).closest("span").append(` | |
| 506 | 512 | <span class="communication_error wpda_tooltip" title="Please check the console for more information"> |
| 507 | 513 | ERROR |
| 508 | 514 | <i class="fas fa-exclamation-triangle"></i> |
| 509 | 515 | </span> |
| @@ -513,9 +519,9 @@ | ||
| 513 | 519 | |
| 514 | 520 | function searchTable(schemaName, tableName, searchString, searchCase) { |
| 515 | 521 | jQuery.ajax({ |
| 516 | 522 | method: "POST", |
| 517 | - url: "<?php echo admin_url( 'admin-ajax.php?action=wpda_global_search' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>", | |
| 523 | + url: "<?php echo esc_url( admin_url( 'admin-ajax.php?action=wpda_global_search' ) ); ?>", | |
| 518 | 524 | data: { |
| 519 | 525 | n: "<?php echo esc_attr( wp_create_nonce( self::NONCE_SEED . WPDA::get_current_user_login() ) ); ?>", |
| 520 | 526 | sn: schemaName, |
| 521 | 527 | tn: tableName, |
| @@ -536,9 +542,9 @@ | ||
| 536 | 542 | |
| 537 | 543 | function replaceTable(schemaName, tableName, searchString, searchCase, replaceString) { |
| 538 | 544 | jQuery.ajax({ |
| 539 | 545 | method: "POST", |
| 540 | - url: "<?php echo admin_url( 'admin-ajax.php?action=wpda_global_replace' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>", | |
| 546 | + url: "<?php echo esc_url( admin_url( 'admin-ajax.php?action=wpda_global_replace' ) ); ?>", | |
| 541 | 547 | data: { |
| 542 | 548 | n: "<?php echo esc_attr( wp_create_nonce( self::NONCE_SEED . WPDA::get_current_user_login() ) ); ?>", |
| 543 | 549 | sn: schemaName, |
| 544 | 550 | tn: tableName, |
| @@ -611,9 +617,9 @@ | ||
| 611 | 617 | for (tableName in wpdaTables[schemaName]) { |
| 612 | 618 | wpdaTables[schemaName][tableName] = isChecked; |
| 613 | 619 | } |
| 614 | 620 | |
| 615 | - jQuery("#chk_" + schemaName).prop( | |
| 621 | + jQuery("#chk_" + cleanId(schemaName)).prop( | |
| 616 | 622 | "checked", |
| 617 | 623 | jQuery("#selectionTables .selectionFrameBody input[type=checkbox]:checked").length>0 |
| 618 | 624 | ); |
| 619 | 625 | |
| @@ -656,13 +662,13 @@ | ||
| 656 | 662 | } |
| 657 | 663 | |
| 658 | 664 | if (wpdaTables[schemaName][tableName]) { |
| 659 | 665 | // At least one table selected: enable search for current database |
| 660 | - jQuery("#chk_" + schemaName).prop("checked", true); | |
| 666 | + jQuery("#chk_" + cleanId(schemaName)).prop("checked", true); | |
| 661 | 667 | } else { |
| 662 | 668 | if (jQuery("#selectionTables .selectionFrameBody input[type=checkbox]:checked").length===0) { |
| 663 | 669 | // No tables selected: disable search for current database |
| 664 | - jQuery("#chk_" + schemaName).prop("checked", false); | |
| 670 | + jQuery("#chk_" + cleanId(schemaName)).prop("checked", false); | |
| 665 | 671 | } |
| 666 | 672 | } |
| 667 | 673 | } |
| 668 | 674 | |
| @@ -691,9 +697,9 @@ | ||
| 691 | 697 | jQuery("#selectionTables .selectionFrameBody").append(newTable); |
| 692 | 698 | } |
| 693 | 699 | |
| 694 | 700 | jQuery("#selectionDatabases .databaseSelected").removeClass("databaseSelected"); |
| 695 | - jQuery("#" + schemaName).addClass("databaseSelected"); | |
| 701 | + jQuery("#" + cleanId(schemaName)).addClass("databaseSelected"); | |
| 696 | 702 | |
| 697 | 703 | jQuery("#selectionTables .selectionFrameHeader input[type=checkbox]").prop("checked", false); |
| 698 | 704 | } |
| 699 | 705 | } |
| @@ -759,11 +765,11 @@ | ||
| 759 | 765 | |
| 760 | 766 | public static function search() { |
| 761 | 767 | self::check_request(); |
| 762 | 768 | |
| 763 | - $schema_name = sanitize_text_field( wp_unslash( $_POST['sn'] ) ); // phpcs:ignore WordPress.Security.NonceVerification | |
| 764 | - $table_name = sanitize_text_field( wp_unslash( $_POST['tn'] ) ); // phpcs:ignore WordPress.Security.NonceVerification | |
| 765 | - $search_value = sanitize_text_field( wp_unslash( $_POST['q'] ) ); // phpcs:ignore WordPress.Security.NonceVerification | |
| 769 | + $schema_name = sanitize_text_field( wp_unslash( $_POST['sn'] ) ); // phpcs:ignore | |
| 770 | + $table_name = sanitize_text_field( wp_unslash( $_POST['tn'] ) ); // phpcs:ignore | |
| 771 | + $search_value = sanitize_text_field( wp_unslash( $_POST['q'] ) ); // phpcs:ignore | |
| 766 | 772 | |
| 767 | 773 | $wpdadb = WPDADB::get_db_connection( $schema_name ); |
| 768 | 774 | if ( null !== $wpdadb ) { |
| 769 | 775 | $wpdadb->suppress_errors( true ); |
| @@ -779,15 +785,15 @@ | ||
| 779 | 785 | die(); |
| 780 | 786 | } |
| 781 | 787 | |
| 782 | 788 | // Determine case-sensitive search |
| 783 | - $search_case = 'true' === $_POST['c']; | |
| 789 | + $search_case = 'true' === $_POST['c']; // phpcs:ignore | |
| 784 | 790 | |
| 785 | 791 | // Perform query |
| 786 | 792 | $result = self::execute_query( $wpdadb, $schema_name, $table_name, $columns, $search_value, $search_case, true ); |
| 787 | 793 | |
| 788 | 794 | // Process query results |
| 789 | - if ( '' === $wpdadb->last_error && is_array( $result ) && count( $result ) > 0 ) {//phpcs:ignore - 8.1 proof | |
| 795 | + if ( '' === $wpdadb->last_error && is_array( $result ) && count( $result ) > 0 ) { // phpcs:ignore -- 8.1 proof | |
| 790 | 796 | WPDA::sent_header( 'application/json' ); |
| 791 | 797 | WPDA::sent_msg( 'OK', $result[0][0] ); |
| 792 | 798 | die(); |
| 793 | 799 | } |
| @@ -797,20 +803,35 @@ | ||
| 797 | 803 | die(); |
| 798 | 804 | } |
| 799 | 805 | |
| 800 | 806 | private static function execute_query( $wpdadb, $schema_name, $table_name, $columns, $search_value, $search_case, $just_count = false ) { |
| 801 | - $query = true === $just_count ? | |
| 802 | - 'select count(*) from `%1s`.`%1s`' : 'select * from `%1s`.`%1s`'; | |
| 807 | + if ( 'rdb:' === substr( $schema_name, 0, 4) ) { | |
| 808 | + // Remote database | |
| 809 | + $query = true === $just_count ? | |
| 810 | + 'select count(*) from `%1s`' : 'select * from `%1s`'; | |
| 803 | 811 | |
| 804 | - // Define query. | |
| 805 | - $query = $wpdadb->prepare( | |
| 806 | - $query, | |
| 807 | - array( | |
| 808 | - WPDA::remove_backticks( $schema_name ), | |
| 809 | - WPDA::remove_backticks( $table_name ), | |
| 810 | - ) | |
| 811 | - ); | |
| 812 | + // Define query. | |
| 813 | + $query = $wpdadb->prepare( | |
| 814 | + $query, | |
| 815 | + array( | |
| 816 | + WPDA::remove_backticks( $table_name ), | |
| 817 | + ) | |
| 818 | + ); | |
| 819 | + } else { | |
| 820 | + // Local database | |
| 821 | + $query = true === $just_count ? | |
| 822 | + 'select count(*) from `%1s`.`%1s`' : 'select * from `%1s`.`%1s`'; | |
| 812 | 823 | |
| 824 | + // Define query. | |
| 825 | + $query = $wpdadb->prepare( | |
| 826 | + $query, | |
| 827 | + array( | |
| 828 | + WPDA::remove_backticks( $schema_name ), | |
| 829 | + WPDA::remove_backticks( $table_name ), | |
| 830 | + ) | |
| 831 | + ); | |
| 832 | + } | |
| 833 | + | |
| 813 | 834 | // Construct where clause. |
| 814 | 835 | $where = WPDA::construct_where_clause( |
| 815 | 836 | $schema_name, |
| 816 | 837 | $table_name, |
| @@ -828,18 +849,18 @@ | ||
| 828 | 849 | |
| 829 | 850 | public static function replace() { |
| 830 | 851 | self::check_request(); |
| 831 | 852 | |
| 832 | - if ( ! isset( $_POST['r'] ) ) { | |
| 853 | + if ( ! isset( $_POST['r'] ) ) { // phpcs:ignore | |
| 833 | 854 | WPDA::sent_header( 'application/json' ); |
| 834 | 855 | WPDA::sent_msg( 'ERROR', 'Invalid arguments' ); |
| 835 | 856 | die(); |
| 836 | 857 | } |
| 837 | 858 | |
| 838 | - $schema_name = sanitize_text_field( wp_unslash( $_POST['sn'] ) ); // phpcs:ignore WordPress.Security.NonceVerification | |
| 839 | - $table_name = sanitize_text_field( wp_unslash( $_POST['tn'] ) ); // phpcs:ignore WordPress.Security.NonceVerification | |
| 840 | - $search_value = sanitize_text_field( wp_unslash( $_POST['q'] ) ); // phpcs:ignore WordPress.Security.NonceVerification | |
| 841 | - $replace_value = sanitize_text_field( wp_unslash( $_POST['r'] ) ); // phpcs:ignore WordPress.Security.NonceVerification | |
| 859 | + $schema_name = sanitize_text_field( wp_unslash( $_POST['sn'] ) ); // phpcs:ignore | |
| 860 | + $table_name = sanitize_text_field( wp_unslash( $_POST['tn'] ) ); // phpcs:ignore | |
| 861 | + $search_value = sanitize_text_field( wp_unslash( $_POST['q'] ) ); // phpcs:ignore | |
| 862 | + $replace_value = sanitize_text_field( wp_unslash( $_POST['r'] ) ); // phpcs:ignore | |
| 842 | 863 | |
| 843 | 864 | $wpdadb = WPDADB::get_db_connection( $schema_name ); |
| 844 | 865 | if ( null !== $wpdadb ) { |
| 845 | 866 | $wpdadb->suppress_errors( true ); |
| @@ -855,9 +876,9 @@ | ||
| 855 | 876 | die(); |
| 856 | 877 | } |
| 857 | 878 | |
| 858 | 879 | // Determine case-sensitive search |
| 859 | - if ( 'true' === $_POST['c'] ) { | |
| 880 | + if ( 'true' === $_POST['c'] ) { // phpcs:ignore | |
| 860 | 881 | // Case-sensitive search and replace |
| 861 | 882 | // Use built-in SQL replace function |
| 862 | 883 | |
| 863 | 884 | // Define query. |
| @@ -947,9 +968,9 @@ | ||
| 947 | 968 | // Update row |
| 948 | 969 | $wpdadb->update( |
| 949 | 970 | $table_name, |
| 950 | 971 | $update_values, |
| 951 | - //phpcs:ignore - 8.1 proof | |
| 972 | + // phpcs:ignore -- 8.1 proof | |
| 952 | 973 | ( is_array( $pk ) && count( $pk ) > 0 ? $pk_values : $result ) // fall back to all cols if no pk |
| 953 | 974 | ); |
| 954 | 975 | $rows_affected += $wpdadb->rows_affected; |
| 955 | 976 | } |