← All changes
|
modules/api-backups/classes/class-api-backups-utility.php
+71
-6
5.1.1
→
6.2.2
View file →
| @@ -7,12 +7,19 @@ | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | namespace MainWP\Dashboard\Module\ApiBackups; |
| 10 | 10 | |
| 11 | +use MainWP\Dashboard\MainWP_Credential_Render; | |
| 11 | 12 | use MainWP\Dashboard\MainWP_DB; |
| 12 | 13 | use MainWP\Dashboard\MainWP_Logger; |
| 13 | 14 | use MainWP\Dashboard\MainWP_System_Utility; |
| 14 | 15 | |
| 16 | +// Exit if accessed directly. | |
| 17 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 18 | + exit; | |
| 19 | +} | |
| 20 | + | |
| 21 | + | |
| 15 | 22 | /** |
| 16 | 23 | * Class Api_Backups_Utility |
| 17 | 24 | */ |
| 18 | 25 | class Api_Backups_Utility { //phpcs:ignore -- NOSONAR - multi methods. |
| @@ -214,9 +221,20 @@ | ||
| 214 | 221 | } |
| 215 | 222 | |
| 216 | 223 | $primaryBackup = MainWP_System_Utility::get_primary_backup(); |
| 217 | 224 | |
| 218 | - if ( 'module-api-backups' !== $primaryBackup ) { | |
| 225 | + $website = Api_Backups_Helper::get_website_by_id( $site_id ); | |
| 226 | + | |
| 227 | + $backup_method = ''; | |
| 228 | + if ( is_array( $website ) && isset( $website['primary_backup_method'] ) ) { | |
| 229 | + if ( '' === $website['primary_backup_method'] || 'global' === $website['primary_backup_method'] ) { | |
| 230 | + $backup_method = $primaryBackup; | |
| 231 | + } else { | |
| 232 | + $backup_method = $website['primary_backup_method']; | |
| 233 | + } | |
| 234 | + } | |
| 235 | + | |
| 236 | + if ( 'module-api-backups' !== $backup_method ) { | |
| 219 | 237 | return; |
| 220 | 238 | } |
| 221 | 239 | |
| 222 | 240 | $lasttime_backup = 0; |
| @@ -231,8 +249,22 @@ | ||
| 231 | 249 | } |
| 232 | 250 | } |
| 233 | 251 | } |
| 234 | 252 | } |
| 253 | + } elseif ( 'kinsta' === $backup_api ) { | |
| 254 | + $available_backups = is_array( $available_backups ) && ! empty( $available_backups ) ? $available_backups : array(); | |
| 255 | + if ( is_array( $available_backups ) ) { | |
| 256 | + foreach ( $available_backups as $backup ) { | |
| 257 | + if ( is_object( $backup ) && ! empty( $backup->created_at ) ) { | |
| 258 | + $milliseconds = $backup->created_at; | |
| 259 | + $epoch = $milliseconds / 1000; | |
| 260 | + $backup_time = strtotime( $epoch ); | |
| 261 | + if ( $backup_time > $lasttime_backup ) { | |
| 262 | + $lasttime_backup = $backup_time; | |
| 263 | + } | |
| 264 | + } | |
| 265 | + } | |
| 266 | + } | |
| 235 | 267 | } elseif ( 'cpanel_auto' === $backup_api ) { |
| 236 | 268 | if ( is_object( $available_backups ) && isset( $available_backups->data ) ) { |
| 237 | 269 | $available_backups_automatic_list = $available_backups->data; |
| 238 | 270 | } else { |
| @@ -550,10 +582,11 @@ | ||
| 550 | 582 | * Encrypt data. |
| 551 | 583 | * |
| 552 | 584 | * @param string $name name data. |
| 553 | 585 | * @param string $def_val default data. |
| 586 | + * @param string $opt_name Option name. | |
| 554 | 587 | */ |
| 555 | - public function get_api_key( $name, $def_val = '' ) { | |
| 588 | + public function get_api_key( $name, $def_val = '', $opt_name = '' ) { | |
| 556 | 589 | |
| 557 | 590 | $names = array( |
| 558 | 591 | 'vultr', |
| 559 | 592 | 'gridpane', |
| @@ -561,8 +594,9 @@ | ||
| 561 | 594 | 'digitalocean', |
| 562 | 595 | 'cloudways', |
| 563 | 596 | 'cpanel', |
| 564 | 597 | 'plesk', |
| 598 | + 'kinsta', | |
| 565 | 599 | ); |
| 566 | 600 | |
| 567 | 601 | if ( ! in_array( $name, $names ) ) { |
| 568 | 602 | return $def_val; |
| @@ -567,9 +601,14 @@ | ||
| 567 | 601 | if ( ! in_array( $name, $names ) ) { |
| 568 | 602 | return $def_val; |
| 569 | 603 | } |
| 570 | 604 | |
| 571 | - $encrypted = get_option( 'mainwp_api_backups_' . $name . '_api_key' ); | |
| 605 | + if ( ! empty( $opt_name ) ) { | |
| 606 | + $encrypted = get_option( 'mainwp_api_backups_' . $name . '_' . (string) $opt_name ); | |
| 607 | + } else { | |
| 608 | + $encrypted = get_option( 'mainwp_api_backups_' . $name . '_api_key' ); | |
| 609 | + } | |
| 610 | + | |
| 572 | 611 | if ( is_array( $encrypted ) && ! empty( $encrypted['file_key'] ) ) { |
| 573 | 612 | $key = $this->decrypt_api_keys( $encrypted ); |
| 574 | 613 | if ( ! empty( $key ) && is_string( $key ) ) { |
| 575 | 614 | return $key; |
| @@ -584,10 +623,11 @@ | ||
| 584 | 623 | * Encrypt data. |
| 585 | 624 | * |
| 586 | 625 | * @param string $name name data. |
| 587 | 626 | * @param string $value value data. |
| 627 | + * @param string $opt_name Option name. | |
| 588 | 628 | */ |
| 589 | - public function update_api_key( $name, $value ) { | |
| 629 | + public function update_api_key( $name, $value, $opt_name = '' ) { | |
| 590 | 630 | |
| 591 | 631 | $names = array( |
| 592 | 632 | 'vultr', |
| 593 | 633 | 'gridpane', |
| @@ -595,8 +635,9 @@ | ||
| 595 | 635 | 'digitalocean', |
| 596 | 636 | 'cloudways', |
| 597 | 637 | 'cpanel', |
| 598 | 638 | 'plesk', |
| 639 | + 'kinsta', | |
| 599 | 640 | ); |
| 600 | 641 | |
| 601 | 642 | if ( ! in_array( $name, $names ) ) { |
| 602 | 643 | return false; |
| @@ -601,9 +642,22 @@ | ||
| 601 | 642 | if ( ! in_array( $name, $names ) ) { |
| 602 | 643 | return false; |
| 603 | 644 | } |
| 604 | 645 | |
| 605 | - $opt_name = 'mainwp_api_backups_' . $name . '_api_key'; | |
| 646 | + // MWP-1543: settings forms render the sentinel ('••••••••') in the | |
| 647 | + // password input when a value is already stored. A submission that | |
| 648 | + // returns the sentinel unchanged means "leave existing value alone"; | |
| 649 | + // short-circuit before delete_option / encrypt so no overwrite happens. | |
| 650 | + if ( MainWP_Credential_Render::is_sentinel( $value ) ) { | |
| 651 | + return true; | |
| 652 | + } | |
| 653 | + | |
| 654 | + if ( ! empty( $opt_name ) ) { | |
| 655 | + $opt_name = 'mainwp_api_backups_' . $name . '_' . (string) $opt_name; | |
| 656 | + } else { | |
| 657 | + $opt_name = 'mainwp_api_backups_' . $name . '_api_key'; | |
| 658 | + } | |
| 659 | + | |
| 606 | 660 | $current = get_option( $opt_name ); |
| 607 | 661 | $key_file = ''; |
| 608 | 662 | |
| 609 | 663 | if ( is_array( $current ) && ! empty( $current['file_key'] ) ) { |
| @@ -644,8 +698,9 @@ | ||
| 644 | 698 | 'digitalocean', |
| 645 | 699 | 'cloudways', |
| 646 | 700 | 'cpanel', |
| 647 | 701 | 'plesk', |
| 702 | + 'kinsta', | |
| 648 | 703 | ); |
| 649 | 704 | |
| 650 | 705 | if ( ! in_array( $name, $names ) ) { |
| 651 | 706 | return $def_val; |
| @@ -687,8 +742,9 @@ | ||
| 687 | 742 | 'digitalocean', |
| 688 | 743 | 'cloudways', |
| 689 | 744 | 'cpanel', |
| 690 | 745 | 'plesk', |
| 746 | + 'kinsta', | |
| 691 | 747 | ); |
| 692 | 748 | |
| 693 | 749 | if ( ! in_array( $name, $names ) ) { |
| 694 | 750 | return false; |
| @@ -693,8 +749,16 @@ | ||
| 693 | 749 | if ( ! in_array( $name, $names ) ) { |
| 694 | 750 | return false; |
| 695 | 751 | } |
| 696 | 752 | |
| 753 | + // MWP-1543: same sentinel short-circuit as update_api_key(); the | |
| 754 | + // per-site Edit Site form renders the sentinel placeholder when a | |
| 755 | + // value already exists, and an unchanged submission must not | |
| 756 | + // overwrite the encrypted option with the sentinel string. | |
| 757 | + if ( MainWP_Credential_Render::is_sentinel( $value ) ) { | |
| 758 | + return true; | |
| 759 | + } | |
| 760 | + | |
| 697 | 761 | $opt_name = 'mainwp_api_backups_' . $name . '_api_key'; |
| 698 | 762 | $opt_encoded = Api_Backups_Helper::get_website_options( $website_id, array( $opt_name ) ); |
| 699 | 763 | if ( array_key_exists( $opt_name, $opt_encoded ) ) { |
| 700 | 764 | $current = json_decode( $opt_encoded[ $opt_name ], true ); |
| @@ -707,9 +771,10 @@ | ||
| 707 | 771 | } |
| 708 | 772 | |
| 709 | 773 | // If post $value is empty, delete option. |
| 710 | 774 | if ( empty( $value ) ) { |
| 711 | - delete_option( $opt_name ); | |
| 775 | + // Delete the site serviceapi key. | |
| 776 | + Api_Backups_Helper::update_website_option( $website_id, $opt_name, '' ); | |
| 712 | 777 | if ( ! empty( $key_file ) ) { |
| 713 | 778 | do_action( 'mainwp_delete_key_file', $key_file ); |
| 714 | 779 | } |
| 715 | 780 | return true; |