PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
← All changes | modules/api-backups/classes/class-api-backups-3rd-party.php +893 -197 5.1 → 6.2.1 View file →
@@ -10,9 +10,15 @@
10 10
11 11 use WP_Error;
12 12 use MainWP\Dashboard\MainWP_DB;
13 13 use MainWP\Dashboard\MainWP_Extensions_Handler;
14 +use MainWP\Dashboard\MainWP_Site_Open;
14 15
16 +// Exit if accessed directly.
17 +if ( ! defined( 'ABSPATH' ) ) {
18 + exit;
19 +}
20 +
15 21 /**
16 22 * Class Api_Backups_3rd_Party
17 23 *
18 24 * This class is responsible for handling the 3rd party API requests for each available backup provider.
@@ -24,8 +30,10 @@
24 30 class Api_Backups_3rd_Party { //phpcs:ignore -- NOSONAR - multi methods.
25 31
26 32 // phpcs:disable WordPress.DB.RestrictedFunctions, Generic.Metrics.CyclomaticComplexity, WordPress.WP.AlternativeFunctions, WordPress.PHP.NoSilencedErrors -- Using cURL functions.
27 33
34 + const CLOUDWAYS_API_URL = 'https://api.cloudways.com/api/v2';
35 +
28 36 /**
29 37 * Public static variable to hold the single instance of the class.
30 38 *
31 39 * @var mixed Default null
@@ -33,8 +41,15 @@
33 41 protected static $instance = null;
34 42
35 43
36 44 /**
45 + * Public static variable to hold the saved access token value.
46 + *
47 + * @var mixed Default null
48 + */
49 + protected static $access_token = null;
50 +
51 + /**
37 52 * Public static variable.
38 53 */
39 54 const OPERATION = '/operation/'; // to clean code.
40 55
@@ -155,8 +170,14 @@
155 170 do_action( 'mainwp_ajax_add_action', 'plesk_action_create_backup', array( &$this, 'ajax_plesk_action_create_backup' ) );
156 171 do_action( 'mainwp_ajax_add_action', 'plesk_action_restore_backup', array( &$this, 'ajax_plesk_action_restore_backup' ) );
157 172 do_action( 'mainwp_ajax_add_action', 'plesk_action_delete_backup', array( &$this, 'ajax_plesk_action_delete_backup' ) );
158 173
174 + // Kinsta Ajax.
175 + do_action( 'mainwp_ajax_add_action', 'kinsta_action_refresh_available_backups', array( &$this, 'ajax_kinsta_action_refresh_available_backups' ) );
176 + do_action( 'mainwp_ajax_add_action', 'kinsta_action_create_backup', array( &$this, 'ajax_kinsta_action_create_backup' ) );
177 + do_action( 'mainwp_ajax_add_action', 'kinsta_action_restore_backup', array( &$this, 'ajax_kinsta_action_restore_backup' ) );
178 + do_action( 'mainwp_ajax_add_action', 'kinsta_action_delete_backup', array( &$this, 'ajax_kinsta_action_delete_backup' ) );
179 +
159 180 // Backup selected sites.
160 181 do_action( 'mainwp_ajax_add_action', 'action_backup_selected_sites', array( &$this, 'action_backup_selected_sites' ) );
161 182
162 183 // Fire off Cloudways & Gridpane ID auto lookup on site addition.
@@ -296,9 +317,9 @@
296 317 <div class="mainwp-sub-header">
297 318 <div class="ui grid">
298 319 <div class="ui two column row">
299 320 <div class="middle aligned column ui">
300 - <button id="action_backup_selected_sites" class="ui green mini button"><?php esc_html_e( 'Backup Selected Sites', 'mainwp' ); ?></button>
321 + <button id="action_backup_selected_sites" class="ui green mini button disabled"><?php esc_html_e( 'Backup Selected Sites', 'mainwp' ); ?></button>
301 322 </div>
302 323 <div class="right aligned middle aligned column">
303 324 <a href="admin.php?page=SettingsApiBackups" class="ui mini green basic button"><?php esc_html_e( 'Manage API Backups Settings', 'mainwp' ); ?></a>
304 325 </div>
@@ -304,18 +325,11 @@
304 325 </div>
305 326 </div>
306 327 </div>
307 328 </div>
308 - <div class="ui segment" id="mainwp-3rd-party-api-backups">
309 - <?php if ( Api_Backups_Utility::show_mainwp_message( 'mainwp-module-api-backups-info-message' ) ) : ?>
310 - <div class="ui info message">
311 - <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-module-api-backups-info-message"></i>
312 - <div><?php esc_html_e( 'This page will list the last backups created by the API Backups Extension for each Child Site that is setup with an API provider.', 'mainwp' ); ?></div>
313 - </div>
314 - <?php endif; ?>
329 + <div class="ui padded segment" id="mainwp-3rd-party-api-backups">
315 330 <?php static::action_notifications(); ?>
316 331 <?php static::render_api_backups_table( '3rd-party-api-backups' ); ?>
317 -
318 332 </div>
319 333 <?php
320 334 }
321 335
@@ -347,11 +361,9 @@
347 361 <input id="cb-select-all-top" type="checkbox"/>
348 362 </span>
349 363 </th>
350 364 <th scope="col"><?php esc_html_e( 'Site', 'mainwp' ); ?></th>
351 - <th scope="col" class="no-sort collapsing"><i class="sign in alternate icon"></i></th>
352 - <th scope="col"><?php esc_html_e( 'URL', 'mainwp' ); ?></th>
353 - <th scope="col"><?php esc_html_e( 'Provider', 'mainwp' ); ?></th>
365 + <th scope="col"><?php esc_html_e( 'API Provider', 'mainwp' ); ?></th>
354 366 <th scope="col"><?php esc_html_e( 'Last Manual Backup Date', 'mainwp' ); ?></th>
355 367 <th scope="col" class="no-sort collapsing"></th>
356 368 </tr>
357 369 </thead>
@@ -396,29 +408,33 @@
396 408 <label for="table-checkbox"></label>
397 409 </span>
398 410 <?php endif; ?>
399 411 </td>
400 - <td><a href="admin.php?page=ManageSitesApiBackups&id=<?php echo intval( $website->id ); ?>"><?php esc_html_e( $website->name, 'mainwp' ); ?></a> <span class="running"></span></td>
401 412 <td>
402 - <a href="<?php echo 'admin.php?page=SiteOpen&newWindow=yes&websiteid=' . intval( $website->id ); ?>&_opennonce=<?php echo esc_attr( wp_create_nonce( 'mainwp-admin-nonce' ) ); ?>" target="_blank">
403 - <i class="sign in alternate icon"></i>
404 - </a>
413 + <div>
414 + <a href="<?php MainWP_Site_Open::get_open_site_admin_link( $website->id, true ); //phpcs:ignore -- ok. ?>" target="_blank">
415 + <i class="sign in alternate icon"></i>
416 + </a>
417 + <a href="admin.php?page=ManageSitesApiBackups&id=<?php echo intval( $website->id ); ?>"><?php echo esc_html( $website->name ); ?></a> <span class="running"></span>
418 + </div>
419 + <span class="ui small text">
420 + <a href="<?php echo esc_url( $website->url ); ?>" target="_blank" class="ui grey text"><?php echo esc_url( $website->url ); ?></a>
421 + </span>
405 422 </td>
406 - <td><a href="<?php echo esc_url( $website->url ); ?>" target="_blank"><?php echo esc_url( $website->url ); ?></a></td>
407 - <td><?php esc_html_e( $api_provider, 'mainwp' ); ?></td>
423 + <td><?php echo esc_html( $api_provider ); ?></td>
408 424 <td class="last-backup-date" ><?php echo ( $last_backup ) ? esc_html( $last_backup ) : esc_html__( 'Awaiting first backup', 'mainwp' ); ?></td>
409 425 <td class="collapsing not-selectable">
410 426 <i class="ui notched circle loading icon" style="display:none;"></i>
411 - <div class="ui left pointing dropdown icon mini basic green button" style="z-index: 999">
412 - <a href="javascript:void(0)"><i class="ellipsis horizontal icon"></i></a>
427 + <div class="ui right pointing dropdown" style="z-index: 999">
428 + <a href="javascript:void(0)"><i class="ellipsis vertical icon"></i></a>
413 429 <div class="menu">
414 430 <?php if ( 'cPanel' === $api_provider ) : ?>
415 - <a class="mainwp_3rd_party_api_<?php esc_attr_e( $api_provider_options ); ?>_action_full_backup item"
431 + <a class="mainwp_3rd_party_api_<?php echo esc_attr( $api_provider_options ); ?>_action_full_backup item"
416 432 website_id="<?php echo intval( $website->id ); ?>" href="javascript:void(0)">
417 433 <?php esc_html_e( 'Backup', 'mainwp' ); ?>
418 434 </a>
419 435 <?php elseif ( 'None' !== $api_provider && 'cPanel' !== $api_provider ) : ?>
420 - <a class="mainwp_3rd_party_api_<?php esc_attr_e( $api_provider_options, 'mainwp' ); ?>_action_backup item"
436 + <a class="mainwp_3rd_party_api_<?php echo esc_attr( $api_provider_options ); ?>_action_backup item"
421 437 website_id="<?php echo intval( $website->id ); ?>" href="javascript:void(0)">
422 438 <?php esc_html_e( 'Backup', 'mainwp' ); ?>
423 439 </a>
424 440 <?php endif; ?>
@@ -452,9 +468,9 @@
452 468 "drawCallback": function( settings ) {
453 469 setTimeout(() => {
454 470 jQuery('#mainwp-3rd-party-backups-table .ui.checkbox').checkbox();
455 471 jQuery('.mainwp-api-backup-table .ui.dropdown').dropdown();
456 - mainwp_datatable_fix_menu_overflow();
472 + mainwp_datatable_fix_menu_overflow('#mainwp-3rd-party-backups-table');
457 473 }, 1000);
458 474 },
459 475 select: {
460 476 items: 'row',
@@ -473,13 +489,12 @@
473 489 .nodes()
474 490 .to$().find('td.check-column .ui.checkbox' ).checkbox('set unchecked');
475 491 }
476 492 }).on( 'columns-reordered', function () {
477 - console.log('columns-reordered');
478 493 setTimeout(() => {
479 494 jQuery( '#mainwp-3rd-party-backups-table .ui.dropdown' ).dropdown();
480 495 jQuery( '#mainwp-3rd-party-backups-table .ui.checkbox' ).checkbox();
481 - mainwp_datatable_fix_menu_overflow();
496 + mainwp_datatable_fix_menu_overflow('#mainwp-3rd-party-backups-table');
482 497 mainwp_table_check_columns_init(); // ajax: to fix checkbox all.
483 498 }, 1000);
484 499 });
485 500 } );
@@ -527,47 +542,29 @@
527 542 $available_backups = array();
528 543 }
529 544
530 545 if ( empty( $backup_api ) ) {
546 + $title = esc_html__( 'No API Backup Solution has been chosen.', 'mainwp' );
547 + /* translators: %1$s: Link to API Backups Settings page, %2$s: Link to Child Site Settings page */
548 + $msg_format = __( 'Please double check that you have set the API Key on the %1$s page and have set the Instance ID on the %2$s page.', 'mainwp' );
549 + $message = sprintf(
550 + $msg_format,
551 + '<a href="' . esc_url( admin_url( 'admin.php?page=SettingsApiBackups' ) ) . '">' . esc_html__( 'API Backups Settings', 'mainwp' ) . '</a>',
552 + '<a href="' . esc_url( admin_url( 'admin.php?page=managesites&id=' . intval( $website_id ) ) ) . '">' . esc_html__( 'Child Site &rarr; Settings page', 'mainwp' ) . '</a>'
553 + );
554 + $icon = '<em data-emoji=":closed_lock_with_key:" class="big"></em>';
555 + \MainWP\Dashboard\MainWP_UI::render_empty_page_placeholder( $title, $message, $icon );
556 + } else {
557 + $columns = 'one';
558 + if ( 'cpanel' === $backup_api || 'plesk' === $backup_api ) {
559 + $columns = 'two';
560 + }
531 561 ?>
532 - <div class="ui placeholder segment">
533 - <div class="ui icon header">
534 - <i class="key icon"></i>
535 - <?php
536 - printf(
537 - esc_html__(
538 - '%1$sNo API Backup Solution has been chosen.%2$s
539 - Please double check that you have set the %3$sAPI Key%4$s
540 - on the %5$s page%6$s
541 - and have set the %7$sInstance ID%8$s on the %9$s page.',
542 - 'mainwp'
543 - ),
544 - '<em>',
545 - '</em> <br/><br>',
546 - '<em>',
547 - '</em>',
548 - '<a href="admin.php?page=SettingsApiBackups">API Backups Settings</a>',
549 - '</br>',
550 - '<em>',
551 - '</em>',
552 - '<a href="admin.php?page=managesites&id=' . intval( $website_id ) . '">Child Site -> Edit</a>'
553 - );
554 - ?>
555 - </div>
556 - </div>
557 - <?php } else { ?>
558 -
559 - <?php
560 - $columns = 'one';
561 - if ( 'cpanel' === $backup_api || 'plesk' === $backup_api ) {
562 - $columns = 'two';
563 - }
564 - ?>
565 - <div class="mainwp-sub-header">
562 + <div class="mainwp-actions-bar">
566 563 <div class="ui grid">
567 564 <div class="ui <?php echo esc_html( $columns ); ?> column row">
568 565 <div class="middle aligned column ui">
569 - <?php if ( 'cpanel' === $backup_api ) : ?>
566 + <?php if ( 'cpanel' === $backup_api ) : ?>
570 567 <div id="mainwp_api_cpanel_backup_tabs" class="ui top attached tabular menu">
571 568 <div class="active item" data-tab="cpanel-native"><i class="fitted cpanel big icon"></i></div>
572 569 <div class="item" data-tab="cpanel-wp-toolkit"><i class="fitted wordpress big icon"></i></div><?php //phpcs:ignore -- skip wordpress.?>
573 570 </div>
@@ -573,31 +570,31 @@
573 570 </div>
574 571 <?php endif; ?>
575 572 </div>
576 573 <div class="right aligned middle aligned column">
577 - <?php if ( 'cpanel' === $backup_api ) : ?>
578 - <button id="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_create_full_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini green button"><?php esc_html_e( 'Backup Files &amp; Database', 'mainwp' ); ?></button>
579 - <button id="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_create_wptk_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini green button hidden"><?php esc_html_e( 'Backup Now', 'mainwp' ); ?></button>
574 + <?php if ( 'cpanel' === $backup_api ) : ?>
575 + <button id="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_create_full_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini green button"><?php esc_html_e( 'Backup Files &amp; Database', 'mainwp' ); ?></button>
576 + <button id="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_create_wptk_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini green button hidden"><?php esc_html_e( 'Backup Now', 'mainwp' ); ?></button>
580 577 <?php else : ?>
581 - <button id="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_individual_create_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini green button"><?php esc_html_e( 'Backup Now', 'mainwp' ); ?></button>
578 + <button id="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_individual_create_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini green button"><?php esc_html_e( 'Backup Now', 'mainwp' ); ?></button>
582 579 <?php endif; ?>
583 - <button id="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_refresh_available_backups" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini green button"><?php esc_html_e( 'Refresh Available Backups', 'mainwp' ); ?></button>
580 + <button id="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_refresh_available_backups" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini green button"><?php esc_html_e( 'Refresh Available Backups', 'mainwp' ); ?></button>
584 581
585 - <?php // Render DigitalOcean specific action buttons. ?>
586 - <?php
587 - if ( 'digitalocean' === $backup_api ) {
588 - // Grab Linode instance id.
589 - $digitalocean_droplet_id = Api_Backups_Helper::get_website_options(
590 - $website,
591 - array(
592 - 'mainwp_3rd_party_instance_id',
593 - )
594 - );
595 - $droplet_id = isset( $digitalocean_droplet_id['mainwp_3rd_party_instance_id'] ) ? $digitalocean_droplet_id['mainwp_3rd_party_instance_id'] : null;
596 - ?>
582 + <?php // Render DigitalOcean specific action buttons. ?>
583 + <?php
584 + if ( 'digitalocean' === $backup_api ) {
585 + // Grab Linode instance id.
586 + $digitalocean_droplet_id = Api_Backups_Helper::get_website_options(
587 + $website,
588 + array(
589 + 'mainwp_3rd_party_instance_id',
590 + )
591 + );
592 + $droplet_id = isset( $digitalocean_droplet_id['mainwp_3rd_party_instance_id'] ) ? $digitalocean_droplet_id['mainwp_3rd_party_instance_id'] : null;
593 + ?>
597 594 <a href="https://cloud.digitalocean.com/droplets/<?php echo esc_attr( $droplet_id ); ?>/snapshots" target="_blank" class="ui mini button">
598 595 <i class="external icon"></i>
599 - <?php esc_html_e( 'View on DigitalOcean', 'mainwp' ); ?>
596 + <?php esc_html_e( 'View on DigitalOcean', 'mainwp' ); ?>
600 597 </a>
601 598 <?php } ?>
602 599 <?php // Render Linode specific action buttons. ?>
603 600 <?php
@@ -610,9 +607,9 @@
610 607 )
611 608 );
612 609 $instance_id = isset( $linode_instance_id['mainwp_3rd_party_instance_id'] ) ? $linode_instance_id['mainwp_3rd_party_instance_id'] : null;
613 610 ?>
614 - <button id="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_cancel_backups" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini button"><?php esc_html_e( 'Disable & Remove Backups on This Linode', 'mainwp' ); ?></button>
611 + <button id="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_cancel_backups" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini button"><?php esc_html_e( 'Disable & Remove Backups on This Linode', 'mainwp' ); ?></button>
615 612 <a href="https://cloud.linode.com/linodes/<?php echo esc_attr( $instance_id ); ?>/backup" target="_blank" class="ui mini button">
616 613 <i class="external icon"></i>
617 614 <?php esc_html_e( 'View on Akamai (Linode)', 'mainwp' ); ?>
618 615 </a>
@@ -623,9 +620,9 @@
623 620 // Grab Cloudways app id.
624 621 $site_options = Api_Backups_Helper::get_website_options( $website, array( 'mainwp_3rd_party_app_id' ) );
625 622 $app_id = isset( $site_options['mainwp_3rd_party_app_id'] ) ? $site_options['mainwp_3rd_party_app_id'] : null;
626 623 ?>
627 - <button id="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_delete_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini button"><?php esc_html_e( 'Delete 24hr Restore Point', 'mainwp' ); ?></button>
624 + <button id="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_delete_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui mini button"><?php esc_html_e( 'Delete 24hr Restore Point', 'mainwp' ); ?></button>
628 625 <a href="https://platform.cloudways.com/apps/<?php echo esc_attr( $app_id ); ?>/restore" target="_blank" class="ui mini button">
629 626 <i class="external icon"></i>
630 627 <?php esc_html_e( 'View on Cloudways', 'mainwp' ); ?>
631 628 </a>
@@ -652,9 +649,9 @@
652 649 </div>
653 650 </div>
654 651 </div>
655 652 </div>
656 - <div class="ui segment">
653 + <div class="ui padded segment">
657 654
658 655 <?php // Render action notifications. I get replaced by JS. ?>
659 656 <div id="mainwp-api-backups-message-zone" class="ui message" style="display: none;">
660 657 <i class="icon close"></i>
@@ -715,9 +712,159 @@
715 712 <div><?php esc_html_e( ' This page allows you to back up and restore your currently available Vultr backups.', 'mainwp' ); ?></div>
716 713 </div>
717 714 <?php endif; ?>
718 715 <?php } ?>
716 + <?php // Display Kinsta Table. ?>
717 + <?php
718 + if ( 'kinsta' === $backup_api ) {
719 719
720 + if ( is_object( $available_backups ) ) {
721 + $available_backups = $available_backups->environment->backups;
722 + } else {
723 + $available_backups = array();
724 + }
725 +
726 + ?>
727 + <?php if ( Api_Backups_Utility::show_mainwp_message( 'mainwp-module-api-backups-info-message' ) ) : ?>
728 + <div class="ui info message">
729 + <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-module-api-backups-info-message"></i>
730 + <div><?php esc_html_e( 'You can create up to 5 manual backups. Each manual backup will be stored for 14 days.', 'mainwp' ); ?></div>
731 + </div>
732 + <?php
733 + endif;
734 + $el_id_wp_1 = $website['id'];
735 + ?>
736 + <table id="mainwp-siteid-<?php echo intval( $el_id_wp_1 ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
737 + <thead>
738 + <tr>
739 + <th scope="col"><?php esc_html_e( 'Backup Name', 'mainwp' ); ?></th>
740 + <th scope="col"><?php esc_html_e( 'Note', 'mainwp' ); ?></th>
741 + <th scope="col"><?php esc_html_e( 'Type', 'mainwp' ); ?></th>
742 + <th scope="col"><?php esc_html_e( 'Date Created', 'mainwp' ); ?></th>
743 + <th scope="col" class="no-sort collapsing"></th>
744 + <th scope="col" class="no-sort collapsing"></th>
745 + </tr>
746 + </thead>
747 + <tbody>
748 + <?php foreach ( $available_backups as $backup ) { ?>
749 + <?php
750 + // Convert Kinsta backup date to human readable format.
751 + $backup_date = Api_Backups_Utility::format_timestamp( intval( $backup->created_at / 1000 ) );
752 + ?>
753 + <tr>
754 + <td class="collapsing"><?php echo esc_html( $backup->name ); ?></td>
755 + <td class="collapsing"><?php echo esc_html( $backup->note ); ?></td>
756 + <td class="collapsing"><?php echo esc_html( $backup->type ); ?></td>
757 + <td class="collapsing"><?php echo esc_html( $backup_date ); ?></td>
758 + <td></td>
759 + <td class="collapsing right aligned">
760 + <button id="kinsta_restore_button" class="ui circular icon button mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_restore_backup item"
761 + website_id="<?php echo intval( $website['id'] ); ?>"
762 + backup_id="<?php echo intval( $backup->id ); ?>"
763 + data-tooltip="<?php esc_attr_e( 'Restore Backup', 'mainwp' ); ?>"
764 + data-inverted=""
765 + data-position="top center">
766 + <i class="undo icon"></i>
767 + </button>
768 + <button id="kinsta_delete_button" class="ui circular icon button mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_delete_backup item"
769 + website_id="<?php echo intval( $website['id'] ); ?>"
770 + backup_id="<?php echo intval( $backup->id ); ?>"
771 + data-tooltip="<?php esc_attr_e( 'Delete Backup', 'mainwp' ); ?>"
772 + data-inverted=""
773 + data-position="top center">
774 + <i class="trash icon"></i>
775 + </button>
776 + </td>
777 + </tr>
778 + <?php } ?>
779 + </tbody>
780 + <tfoot>
781 + <tr>
782 + <th scope="col"><?php esc_html_e( 'Backup Name', 'mainwp' ); ?></th>
783 + <th scope="col"><?php esc_html_e( 'Environment', 'mainwp' ); ?></th>
784 + <th scope="col"><?php esc_html_e( 'Type', 'mainwp' ); ?></th>
785 + <th scope="col"><?php esc_html_e( 'Date Created', 'mainwp' ); ?></th>
786 + <th scope="col" class="no-sort collapsing"></th>
787 + <th scope="col" class="no-sort collapsing"></th>
788 + </tr>
789 + </tfoot>
790 + </table>
791 + <div class="ui divider hidden"></div>
792 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
793 + <thead>
794 + <tr>
795 + <th scope="col" colspan="3">
796 + <div class="ui equal width grid">
797 + <div class="left aligned middle aligned column">
798 + <?php esc_html_e( 'Downloadable Backups', 'mainwp' ); ?>
799 + </div>
800 + </div>
801 + </th>
802 + </tr>
803 + <tr>
804 + <th scope="col"><?php esc_html_e( 'Created', 'mainwp' ); ?></th>
805 + <th scope="col"><?php esc_html_e( 'Expiry', 'mainwp' ); ?></th>
806 + <th scope="col" class="no-sort collapsing"></th>
807 + </tr>
808 + </thead>
809 + <tbody>
810 + <?php
811 + // Grab Downloadable Backups.
812 + $site_options = Api_Backups_Helper::get_website_options( $website, array( 'mainwp_3rd_party_kinsta_downloadable_backups' ) );
813 + $downloadable_backups = isset( $site_options['mainwp_3rd_party_kinsta_downloadable_backups'] ) ? $site_options['mainwp_3rd_party_kinsta_downloadable_backups'] : '';
814 + $downloadable_backups = json_decode( $downloadable_backups );
815 + ?>
816 + <?php if ( is_object( $downloadable_backups ) ) { ?>
817 + <?php foreach ( $downloadable_backups->environment->downloadable_backups as $backup ) { ?>
818 + <?php
819 +
820 + // Convert Kinsta backup dates to human readable format.
821 + $created_date = Api_Backups_Utility::format_timestamp( intval( $backup->created_at / 1000 ) );
822 + $expiry_date = Api_Backups_Utility::format_timestamp( intval( $backup->expires_at / 1000 ) );
823 +
824 + // Check if backup is expired, disable row including download button.
825 + if ( intval( $backup->expires_at / 1000 ) > time() ) {
826 +
827 + ?>
828 +
829 + <tr>
830 + <td class="collapsing"><?php echo esc_html( $created_date ); ?></td>
831 + <td class="collapsing"><?php echo esc_html( $expiry_date ); ?></td>
832 + <td>
833 + <a class="kinsta_download" href="<?php echo esc_attr( $backup->download_link ); ?>" target="_blank">
834 + <button class="ui right labeled icon button">
835 + <i class="right download icon"></i>
836 + <?php echo esc_html__( 'Download', 'mainwp' ); ?>
837 + </button>
838 + </a>
839 + </td>
840 + </tr>
841 + <?php } else { ?>
842 + <tr class="disabled">
843 + <td class="collapsing"><?php echo esc_html( $created_date ); ?></td>
844 + <td class="collapsing"><?php echo esc_html( $expiry_date ); ?></td>
845 + <td>
846 + <a class="kinsta_download" href="<?php echo esc_attr( $backup->download_link ); ?>" target="_blank">
847 + <button class="ui right labeled icon button disabled">
848 + <i class="right download icon"></i>
849 + <?php echo esc_html__( 'Download', 'mainwp' ); ?>
850 + </button>
851 + </a>
852 + </td>
853 + </tr>
854 + <?php } ?>
855 + <?php } ?>
856 + <?php } ?>
857 + </tbody>
858 + <tfoot>
859 + <tr>
860 + <th scope="col"><?php esc_html_e( 'Created', 'mainwp' ); ?></th>
861 + <th scope="col"><?php esc_html_e( 'Expiry', 'mainwp' ); ?></th>
862 + <th scope="col" class="no-sort collapsing"></th>
863 + </tr>
864 + </tfoot>
865 + </table>
866 + <?php } ?>
720 867 <?php // Display Plesk Table. ?>
721 868 <?php
722 869 if ( 'plesk' === $backup_api ) {
723 870 // Grab available cPanel Automatic Backups or set to empty array.
@@ -726,9 +873,9 @@
726 873 } else {
727 874 $available_backups = array();
728 875 }
729 876 ?>
730 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
877 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
731 878 <thead>
732 879 <tr>
733 880 <th scope="col"><?php esc_html_e( 'Backup Name', 'mainwp' ); ?></th>
734 881 <th scope="col"><?php esc_html_e( 'Date Created', 'mainwp' ); ?></th>
@@ -752,9 +899,9 @@
752 899 $installation_id = $opts['mainwp_plesk_installation_id'] ?? '';
753 900 }
754 901 ?>
755 902 <tr>
756 - <td class="collapsing"><?php esc_html_e( $backup->value->fileName->value ); ?></td>
903 + <td class="collapsing"><?php echo esc_html( $backup->value->fileName->value ); ?></td>
757 904 <td class="collapsing"><?php echo esc_html( $backup_date ); ?></td>
758 905 <td></td>
759 906 <td class="collapsing right aligned">
760 907 <button id="plesk_restore_button" class="ui circular mini icon button mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_restore_backup item"
@@ -778,9 +925,9 @@
778 925 <a id="plesk_download_button" class="ui circular mini icon button mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_downlaod_backup item"
779 926 installation_id="<?php echo intval( $installation_id ); ?>"
780 927 website_id="<?php echo intval( $website['id'] ); ?>"
781 928 backup_name="<?php echo esc_attr( $backup->value->fileName->value ); ?>"
782 - href="admin.php?page=SiteOpen&websiteid=<?php echo intval( $website['id'] ); ?>&dirdl=<?php echo esc_attr( rawurlencode( $dirdl ) ); ?>&filedl=<?php echo esc_attr( rawurlencode( $backup->value->fileName->value ) ); ?>&_opennonce=<?php echo esc_html( wp_create_nonce( 'mainwp-admin-nonce' ) ); ?>"
929 + href="<?php MainWP_Site_Open::get_open_site_admin_link( $website['id'], true ); //phpcs:ignore -- ok. ?>&dirdl=<?php echo esc_attr( rawurlencode( $dirdl ) ); ?>&filedl=<?php echo esc_attr( rawurlencode( $backup->value->fileName->value ) ); ?>"
783 930 data-tooltip="<?php esc_attr_e( 'Download Backup', 'mainwp' ); ?>"
784 931 data-inverted=""
785 932 data-position="top center"
786 933 target="_blank">
@@ -854,9 +1001,9 @@
854 1001 $available_manual_database_backups = array();
855 1002 }
856 1003 ?>
857 1004 <div class="ui bottom attached active tab" data-tab="cpanel-native">
858 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
1005 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
859 1006 <thead>
860 1007 <tr>
861 1008 <th scope="col" colspan="4">
862 1009 <?php esc_html_e( 'Automatic Host Backups', 'mainwp' ); ?>
@@ -871,11 +1018,11 @@
871 1018 </thead>
872 1019 <tbody>
873 1020 <?php foreach ( $available_backups_automatic_list as $backup ) { ?>
874 1021 <tr>
875 - <td><?php esc_html_e( $backup->backupID ); ?></td>
876 - <td><?php esc_html_e( ucfirst( $backup->backupType ), 'mainwp' ); ?></td>
877 - <td><?php echo esc_html_e( $backup->path ); ?></td>
1022 + <td><?php echo esc_html( $backup->backupID ); ?></td>
1023 + <td><?php echo esc_html( ucfirst( $backup->backupType ) ); ?></td>
1024 + <td><?php echo esc_html( $backup->path ); ?></td>
878 1025 <td>
879 1026 <a id="cpanel_automatic_backup_button" class="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_restore_backup item"
880 1027 website_id="<?php echo intval( $website['id'] ); ?>"
881 1028 backup_type="<?php echo esc_attr( 'automatic' ); ?>"
@@ -900,9 +1047,9 @@
900 1047 </tr>
901 1048 </tfoot>
902 1049 </table>
903 1050 <div class="ui divider hidden"></div>
904 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
1051 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
905 1052 <thead>
906 1053 <tr>
907 1054 <th scope="col" colspan="3">
908 1055 <div class="ui equal width grid">
@@ -909,9 +1056,12 @@
909 1056 <div class="left aligned middle aligned column">
910 1057 <?php esc_html_e( 'Manual Account Backups', 'mainwp' ); ?>
911 1058 </div>
912 1059 <div class="right aligned middle aligned column">
913 - <button id="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_individual_create_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui primary elastic green button"><?php esc_html_e( 'Backup', 'mainwp' ); ?></button>
1060 + <?php
1061 + $el_id_cp_api = $backup_api;
1062 + ?>
1063 + <button id="mainwp_3rd_party_api_<?php echo esc_attr( $el_id_cp_api ); ?>_action_individual_create_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui primary elastic green button"><?php esc_html_e( 'Backup', 'mainwp' ); ?></button>
914 1064 </div>
915 1065 </div>
916 1066 </th>
917 1067 </tr>
@@ -917,9 +1067,9 @@
917 1067 </tr>
918 1068 <tr>
919 1069 <th scope="col" ><?php esc_html_e( 'Backup Name', 'mainwp' ); ?></th>
920 1070 <th scope="col" ><?php esc_html_e( 'Date Created', 'mainwp' ); ?></th>
921 - <th scope="col" ="no-sort collapsing"></th>
1071 + <th scope="col" class="no-sort collapsing"></th>
922 1072 </tr>
923 1073 </thead>
924 1074 <tbody>
925 1075 <?php foreach ( $available_backups_manual_list as $backup ) { ?>
@@ -927,15 +1077,15 @@
927 1077 $my_unix_timestamp = $backup->timestamp;
928 1078 $backup_date = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $my_unix_timestamp ), get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
929 1079 ?>
930 1080 <tr>
931 - <td class="collapsing"><?php esc_html_e( $backup->file_name ); ?></td>
932 - <td class="collapsing"><?php esc_html_e( $backup_date ); ?></td>
1081 + <td class="collapsing"><?php echo esc_html( $backup->file_name ); ?></td>
1082 + <td class="collapsing"><?php echo esc_html( $backup_date ); ?></td>
933 1083 <td>
934 1084 <?php
935 1085 $file_path = $backup->absolute_dir . '/';
936 1086 ?>
937 - <a class="open_newwindow_wpadmin" href="admin.php?page=SiteOpen&websiteid=<?php echo intval( $website['id'] ); ?>&dirdl=<?php echo esc_attr( rawurlencode( $file_path ) ); ?>&filedl=<?php echo esc_attr( rawurlencode( $backup->file_name ) ); ?>&_opennonce=<?php echo esc_html( wp_create_nonce( 'mainwp-admin-nonce' ) ); ?>" target="_blank">
1087 + <a class="open_newwindow_wpadmin" href="<?php MainWP_Site_Open::get_open_site_admin_link( $website['id'], true ); //phpcs:ignore -- ok. ?>&dirdl=<?php echo esc_attr( rawurlencode( $file_path ) ); ?>&filedl=<?php echo esc_attr( rawurlencode( $backup->file_name ) ); ?>" target="_blank">
938 1088 <button class="ui right labeled icon button">
939 1089 <i class="right download icon"></i>
940 1090 <?php echo esc_html__( 'Download', 'mainwp' ); ?>
941 1091 </button>
@@ -952,9 +1102,9 @@
952 1102 </tr>
953 1103 </tfoot>
954 1104 </table>
955 1105 <div class="ui divider hidden"></div>
956 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
1106 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
957 1107 <thead>
958 1108 <tr>
959 1109 <th scope="col" colspan="3">
960 1110 <div class="ui equal width grid">
@@ -961,9 +1111,9 @@
961 1111 <div class="left aligned middle aligned column">
962 1112 <?php esc_html_e( 'Manual Database Backups', 'mainwp' ); ?>
963 1113 </div>
964 1114 <div class="right aligned middle aligned column">
965 - <button id="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_create_database_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui primary elastic green button"><?php esc_html_e( 'Backup', 'mainwp' ); ?></button>
1115 + <button id="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_create_database_backup" website_id="<?php echo intval( $website['id'] ); ?>" class="ui primary elastic green button"><?php esc_html_e( 'Backup', 'mainwp' ); ?></button>
966 1116 </div>
967 1117 </div>
968 1118 </th>
969 1119 </tr>
@@ -979,10 +1129,10 @@
979 1129 $my_unix_timestamp = $backup->timestamp;
980 1130 $backup_date = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $my_unix_timestamp ), get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
981 1131 ?>
982 1132 <tr>
983 - <td class="collapsing"><?php esc_html_e( $backup->file_name ); ?></td>
984 - <td class="collapsing"><?php esc_html_e( $backup_date ); ?></td>
1133 + <td class="collapsing"><?php echo esc_html( $backup->file_name ); ?></td>
1134 + <td class="collapsing"><?php echo esc_html( $backup_date ); ?></td>
985 1135 <td>
986 1136 <a id="database_backup_button" class="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_restore_database_backup item"
987 1137 website_id="<?php echo intval( $website['id'] ); ?>"
988 1138 backup_path="<?php echo esc_attr( $backup->absolute_dir ); ?>"
@@ -1060,9 +1210,9 @@
1060 1210 $my_unix_timestamp = strtotime( $backup->value->createdAt->value );
1061 1211 $backup_date = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $my_unix_timestamp ), get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
1062 1212 ?>
1063 1213 <tr>
1064 - <td class=""><?php esc_html_e( $backup->value->fileName->value ); ?></td>
1214 + <td class=""><?php echo esc_html( $backup->value->fileName->value ); ?></td>
1065 1215 <td class=""><?php echo esc_html( $backup_date ); ?></td>
1066 1216 <td></td>
1067 1217 <td class="right aligned">
1068 1218 <button class="ui mini icon button mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_restore_wptk_backup item"
@@ -1083,9 +1233,9 @@
1083 1233 ?>
1084 1234 <button class="ui mini icon button mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_download_wptk_backup item"
1085 1235 website_id="<?php echo intval( $website['id'] ); ?>"
1086 1236 backup_name="<?php echo esc_attr( $backup->value->fileName->value ); ?>"
1087 - href="admin.php?page=SiteOpen&websiteid=<?php echo intval( $website['id'] ); ?>&dirdl=<?php echo esc_attr( rawurlencode( $dirdl ) ); ?>&filedl=<?php echo esc_attr( rawurlencode( $backup->value->fileName->value ) ); ?>&_opennonce=<?php echo esc_html( wp_create_nonce( 'mainwp-admin-nonce' ) ); ?>"
1237 + href="<?php MainWP_Site_Open::get_open_site_admin_link( $website['id'], true ); //phpcs:ignore -- ok. ?>&dirdl=<?php echo esc_attr( rawurlencode( $dirdl ) ); ?>&filedl=<?php echo esc_attr( rawurlencode( $backup->value->fileName->value ) ); ?>"
1088 1238 data-tooltip="<?php esc_attr_e( 'Download Backup', 'mainwp' ); ?>"
1089 1239 data-inverted=""
1090 1240 data-position="top center">
1091 1241 <i class="download icon"></i>
@@ -1111,33 +1261,14 @@
1111 1261 </tr>
1112 1262 </tfoot>
1113 1263 </table>
1114 1264 <?php else : // Display message if WP-Toolkit is not enabled. ?>
1115 - <div class="ui placeholder segment">
1116 - <div class="ui icon header">
1117 - <i class="key icon"></i>
1118 - <?php
1119 - printf(
1120 - esc_html__(
1121 - '%1$sThe WP-Toolkit API has not been enabled.%2$s
1122 - Please double check that you have set the cPanel %3$sAPI Key%4$s
1123 - on the %5$s page%6$s
1124 - and have enabled the %7$sWP Toolkit API%8$s on the %9$s page.',
1125 - 'mainwp'
1126 - ),
1127 - '<em>',
1128 - '</em> <br/><br>',
1129 - '<em>',
1130 - '</em>',
1131 - '<a href="admin.php?page=SettingsApiBackups">API Backups Settings</a>',
1132 - '</br>',
1133 - '<em>',
1134 - '</em>',
1135 - '<a href="admin.php?page=managesites&id=' . intval( $website_id ) . '">Child Site -> Edit</a>'
1136 - );
1137 - ?>
1138 - </div>
1139 - </div>
1265 + <?php
1266 + $title = esc_html__( 'The WP-Toolkit API has not been enabled.', 'mainwp' );
1267 + $message = esc_html__( 'Please double check that you have set the cPanel API Key on the API Backups Settings page and have enabled the WP Toolkit API on the Child Site -> Edit page.', 'mainwp' );
1268 + $icon = '<em data-emoji=":closed_lock_with_key:" class="big"></em>';
1269 + \MainWP\Dashboard\MainWP_UI::render_empty_page_placeholder( $title, $message, $icon );
1270 + ?>
1140 1271 <?php endif; ?>
1141 1272 </div>
1142 1273 <?php } ?>
1143 1274 <?php // Display GridPane Table. ?>
@@ -1153,9 +1284,9 @@
1153 1284 } else {
1154 1285 $available_backups_manual_list = array();
1155 1286 }
1156 1287 ?>
1157 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
1288 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
1158 1289 <thead>
1159 1290 <tr>
1160 1291 <th scope="col" ><?php esc_html_e( 'GridPane Backup Name', 'mainwp' ); ?></th>
1161 1292 <th scope="col" ><?php esc_html_e( 'Type', 'mainwp' ); ?></th>
@@ -1165,9 +1296,9 @@
1165 1296 </thead>
1166 1297 <tbody>
1167 1298 <?php foreach ( $available_backups_automatic_list as $backup ) { ?>
1168 1299 <tr>
1169 - <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php esc_html_e( $backup ); ?></td>
1300 + <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php echo esc_html( $backup ); ?></td>
1170 1301 <td><?php esc_html_e( 'Automatic', 'mainwp' ); ?></td>
1171 1302 <td></td>
1172 1303 <td class="collapsing right aligned">
1173 1304 <a class="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_restore_backup ui mini icon button"
@@ -1188,9 +1319,9 @@
1188 1319 </tr>
1189 1320 <?php } ?>
1190 1321 <?php foreach ( $available_backups_manual_list as $backup ) { ?>
1191 1322 <tr>
1192 - <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php esc_html_e( $backup ); ?></td>
1323 + <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php echo esc_html( $backup ); ?></td>
1193 1324 <td><?php esc_html_e( 'Manual', 'mainwp' ); ?></td>
1194 1325 <td></td>
1195 1326 <td class="collapsing right aligned">
1196 1327 <a class="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_restore_backup ui mini icon button"
@@ -1199,9 +1330,9 @@
1199 1330 backup_name="<?php echo esc_attr( $backup ); ?>"
1200 1331 href="javascript:void(0)">
1201 1332 <i class="undo icon"></i>
1202 1333 </a>
1203 - <a class="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_delete_backup ui mini icon button"
1334 + <a class="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_delete_backup ui mini icon button"
1204 1335 website_id="<?php echo intval( $website['id'] ); ?>"
1205 1336 backup_type="<?php echo esc_attr( 'manual' ); ?>"
1206 1337 backup_name="<?php echo esc_attr( $backup ); ?>"
1207 1338 href="javascript:void(0)">
@@ -1232,9 +1363,9 @@
1232 1363 $available_backups = array();
1233 1364 }
1234 1365
1235 1366 ?>
1236 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
1367 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
1237 1368 <thead>
1238 1369 <tr>
1239 1370 <th scope="col" ><?php esc_html_e( 'Cloudways Backup Type', 'mainwp' ); ?></th>
1240 1371 <th scope="col" ><?php esc_html_e( 'Date Created', 'mainwp' ); ?></th>
@@ -1277,9 +1408,9 @@
1277 1408 } else {
1278 1409 $available_backups_list = array();
1279 1410 }
1280 1411 ?>
1281 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
1412 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
1282 1413 <thead>
1283 1414 <tr>
1284 1415 <th scope="col" ><?php esc_html_e( 'Vultr Backup Label', 'mainwp' ); ?></th>
1285 1416 <th scope="col" ><?php esc_html_e( 'Size', 'mainwp' ); ?></th>
@@ -1329,9 +1460,9 @@
1329 1460 snapshot_id="<?php echo esc_attr( $backup->id ); ?>"
1330 1461 href="javascript:void(0)">
1331 1462 <i class="undo icon"></i>
1332 1463 </a>
1333 - <a class="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_delete_backup ui mini icon button"
1464 + <a class="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_delete_backup ui mini icon button"
1334 1465 website_id="<?php echo intval( $website['id'] ); ?>"
1335 1466 snapshot_id="<?php echo esc_attr( $backup->id ); ?>"
1336 1467 href="javascript:void(0)">
1337 1468 <i class="trash icon"></i>
@@ -1370,9 +1501,9 @@
1370 1501 } else {
1371 1502 $available_backups_snapshot_list = array();
1372 1503 }
1373 1504 ?>
1374 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
1505 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
1375 1506 <thead>
1376 1507 <tr>
1377 1508 <th scope="col" ><?php esc_html_e( 'Akamai (Linode) Backup Type', 'mainwp' ); ?></th>
1378 1509 <th scope="col" ><?php esc_html_e( 'Date Created', 'mainwp' ); ?></th>
@@ -1384,9 +1515,9 @@
1384 1515 </thead>
1385 1516 <tbody>
1386 1517 <?php foreach ( $available_backups_automatic_list as $backup ) { ?>
1387 1518 <tr>
1388 - <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php esc_html_e( $backup->type ); ?></td>
1519 + <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php echo esc_html( $backup->type ); ?></td>
1389 1520 <td><?php echo esc_html( Api_Backups_Utility::format_timestamp( strtotime( $backup->created ) ) ); ?></td>
1390 1521 <td class="operation_status"><?php echo esc_html( $backup->status ); ?></td>
1391 1522 <td></td>
1392 1523 <td></td>
@@ -1403,9 +1534,9 @@
1403 1534 <?php } ?>
1404 1535 <?php foreach ( $available_backups_snapshot_list as $backup ) { ?>
1405 1536 <?php if ( null !== $backup ) { ?>
1406 1537 <tr>
1407 - <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php esc_html_e( $backup->type ); ?></td>
1538 + <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php echo esc_html( $backup->type ); ?></td>
1408 1539 <td><?php echo esc_html( Api_Backups_Utility::format_timestamp( strtotime( $backup->created ) ) ); ?></td>
1409 1540 <td><?php echo esc_html( $backup->status ); ?></td>
1410 1541 <td></td>
1411 1542 <td></td>
@@ -1444,9 +1575,9 @@
1444 1575 if ( ! is_array( $available_backups ) ) {
1445 1576 $available_backups = array();
1446 1577 }
1447 1578 ?>
1448 - <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
1579 + <table id="mainwp-siteid-<?php echo intval( $website['id'] ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%"> <?php // NOSONAR - id ok. ?>
1449 1580 <thead>
1450 1581 <tr>
1451 1582 <th scope="col" ><?php esc_html_e( 'DigitalOcean Backup Label', 'mainwp' ); ?></th>
1452 1583 <th scope="col" ><?php esc_html_e( 'Size', 'mainwp' ); ?></th>
@@ -1457,9 +1588,9 @@
1457 1588 </thead>
1458 1589 <tbody>
1459 1590 <?php foreach ( $available_backups as $backup ) { ?>
1460 1591 <tr>
1461 - <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php esc_html_e( $backup->name ); ?></td>
1592 + <td><i class="ui notched circle loading icon" style="display:none;"></i> <?php echo esc_html( $backup->name ); ?></td>
1462 1593 <td><?php echo intval( $backup->size_gigabytes ); ?>GB</td>
1463 1594 <td><?php echo esc_html( Api_Backups_Utility::format_timestamp( strtotime( $backup->created_at ) ) ); ?></td>
1464 1595 <td></td>
1465 1596 <td class="collapsing right aligned">
@@ -1468,9 +1599,9 @@
1468 1599 snapshot_id="<?php echo esc_attr( $backup->id ); ?>"
1469 1600 href="javascript:void(0)">
1470 1601 <i class="undo icon"></i>
1471 1602 </a>
1472 - <a class="mainwp_3rd_party_api_<?php esc_attr_e( $backup_api ); ?>_action_delete_backup ui mini icon button"
1603 + <a class="mainwp_3rd_party_api_<?php echo esc_attr( $backup_api ); ?>_action_delete_backup ui mini icon button"
1473 1604 website_id="<?php echo intval( $website['id'] ); ?>"
1474 1605 snapshot_id="<?php echo esc_attr( $backup->id ); ?>"
1475 1606 href="javascript:void(0)">
1476 1607 <i class="trash icon"></i>
@@ -1514,28 +1645,10 @@
1514 1645 jQuery('.mainwp-api-backup-table .ui.checkbox').checkbox();
1515 1646 jQuery('.mainwp-api-backup-table .ui.dropdown').dropdown();
1516 1647 mainwp_datatable_fix_menu_overflow('.mainwp-api-backup-table', -55, 10 );
1517 1648 }, 1000);
1518 - },
1519 - select: {
1520 - items: 'row',
1521 - style: 'multi+shift',
1522 - selector: 'tr>td:not(.not-selectable)'
1523 1649 }
1524 - } ).on('select', function (e, dt, type, indexes) {
1525 - if( 'row' == type ){
1526 - dt.rows(indexes)
1527 - .nodes()
1528 - .to$().find('td.check-column .ui.checkbox' ).checkbox('set checked');
1529 - }
1530 - }).on('deselect', function (e, dt, type, indexes) {
1531 - if( 'row' == type ){
1532 - dt.rows(indexes)
1533 - .nodes()
1534 - .to$().find('td.check-column .ui.checkbox' ).checkbox('set unchecked');
1535 - }
1536 - }).on( 'columns-reordered', function () {
1537 - console.log('columns-reordered');
1650 + } ).on( 'columns-reordered', function () {
1538 1651 setTimeout(() => {
1539 1652 jQuery( '.mainwp-api-backup-table .ui.dropdown' ).dropdown();
1540 1653 jQuery( '.mainwp-api-backup-table .ui.checkbox' ).checkbox();
1541 1654 mainwp_datatable_fix_menu_overflow('.mainwp-api-backup-table', -55, 10 );
@@ -1544,11 +1657,35 @@
1544 1657 });
1545 1658 } );
1546 1659 </script>
1547 1660 <?php
1548 - } // END if.
1661 + } // END if.
1549 1662 }
1550 1663
1664 + /**
1665 + * Fetch Cloudways oAuth Access Token.
1666 + *
1667 + * Fetch the Cloudways oAuth access token from the given API credentials.
1668 + *
1669 + * @return mixed Return Cloudways Access Token.
1670 + */
1671 + public static function get_saved_v2_access_token() {
1672 + if ( null === static::$access_token ) {
1673 + static::$access_token = self::get_cloudways_access_token();
1674 + }
1675 + return static::$access_token;
1676 + }
1677 + /**
1678 + * Fetch Cloudways oAuth Access Token.
1679 + *
1680 + * Fetch the Cloudways oAuth access token from the given API credentials.
1681 + *
1682 + * @return mixed Return Cloudways Access Token.
1683 + */
1684 + public static function is_access_token_v2() {
1685 + return ! empty( self::get_saved_v2_access_token() );
1686 + }
1687 +
1551 1688 /*********************************************************************************
1552 1689 * Cloudways API Methods.
1553 1690 **********************************************************************************/
1554 1691
@@ -1561,11 +1698,68 @@
1561 1698 * 2. Enter in your account email address and API Key below.
1562 1699 *
1563 1700 * @param string $method GET|POST|PUT|DELETE.
1564 1701 * @param string $url relative URL for the call.
1702 + * @param array $post Optional post data for the call.
1703 + * @return object|false Output from CW API.
1704 + */
1705 + public static function call_cloudways_api_v2( $method, $url, $post = array() ) {
1706 +
1707 + $access_token = self::get_saved_v2_access_token();
1708 +
1709 + $ch = curl_init();
1710 +
1711 + curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method );
1712 + curl_setopt( $ch, CURLOPT_URL, self::CLOUDWAYS_API_URL . $url );
1713 + curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
1714 +
1715 + curl_setopt(
1716 + $ch,
1717 + CURLOPT_HTTPHEADER,
1718 + array(
1719 + 'Authorization: Bearer ' . $access_token,
1720 + 'Accept: application/json',
1721 + )
1722 + );
1723 +
1724 + // Set Post Parameters.
1725 + $encoded = '';
1726 + if ( count( $post ) ) {
1727 + foreach ( $post as $name => $value ) {
1728 + $encoded .= rawurlencode( $name ) . '=' . rawurlencode( $value ) . '&';
1729 + }
1730 +
1731 + $encoded = substr( $encoded, 0, strlen( $encoded ) - 1 );
1732 +
1733 + curl_setopt( $ch, CURLOPT_POSTFIELDS, $encoded );
1734 + curl_setopt( $ch, CURLOPT_POST, 1 );
1735 + }
1736 +
1737 + $output = curl_exec( $ch );
1738 + $httpcode = (int) curl_getinfo( $ch, CURLINFO_HTTP_CODE );
1739 +
1740 + curl_close( $ch );
1741 +
1742 + if ( 200 !== $httpcode ) {
1743 + return false;
1744 + }
1745 +
1746 + return json_decode( $output );
1747 + }
1748 +
1749 + /**
1750 + * Call Cloudways API, Authenticate & perform given method.
1751 + *
1752 + * Use this function to contact CW API
1753 + * We use OAuth, an open standard for authorization. Here are the steps involved:
1754 + * 1. Get your API Key from here: https://platform.cloudways.com/api
1755 + * 2. Enter in your account email address and API Key below.
1756 + *
1757 + * @param string $method GET|POST|PUT|DELETE.
1758 + * @param string $url relative URL for the call.
1565 1759 * @param string $accessToken Access token generated using OAuth Call.
1566 1760 * @param array $post Optional post data for the call.
1567 - * @return object Output from CW API.
1761 + * @return object|false Output from CW API.
1568 1762 */
1569 1763 public static function call_cloudways_api( $method, $url, $accessToken, $post = array() ) {
1570 1764 $baseURL = 'https://api.cloudways.com/api/v1';
1571 1765
@@ -1594,12 +1788,14 @@
1594 1788 $output = curl_exec( $ch );
1595 1789
1596 1790 $httpcode = (string) curl_getinfo( $ch, CURLINFO_HTTP_CODE );
1597 1791
1792 + curl_close( $ch );
1793 +
1598 1794 if ( '200' !== $httpcode ) {
1599 1795 return false;
1600 1796 }
1601 - curl_close( $ch );
1797 +
1602 1798 return json_decode( $output );
1603 1799 }
1604 1800
1605 1801 /**
@@ -1634,13 +1830,19 @@
1634 1830 *
1635 1831 * @return mixed Returns available list of servers.
1636 1832 */
1637 1833 public static function fetch_cloudways_server_list() { //phpcs:ignore -- NOSONAR - complex.
1638 - // Grab access token.
1639 - $accessToken = static::fetch_cloudways_access_token();
1640 1834
1641 - // Fetch Server List.
1642 - $serverList = (array) static::call_cloudways_api( 'GET', '/server', $accessToken );
1835 + if ( static::is_access_token_v2() ) {
1836 + $serverList = (array) static::call_cloudways_api_v2( 'GET', '/server' );
1837 + } else {
1838 + // Grab access token.
1839 + $accessToken = static::fetch_cloudways_access_token();
1840 +
1841 + // Fetch Server List.
1842 + $serverList = (array) static::call_cloudways_api( 'GET', '/server', $accessToken );
1843 + }
1844 +
1643 1845 if ( ! array_key_exists( 'servers', $serverList ) ) {
1644 1846 return;
1645 1847 }
1646 1848 // Return the server list.
@@ -1756,21 +1958,34 @@
1756 1958 'server_id' => $server_id,
1757 1959 'app_id' => $app_id,
1758 1960 );
1759 1961
1760 - // Grab Cloudways access token.
1761 - $accessToken = static::fetch_cloudways_access_token();
1962 + $accessToken = '';
1762 1963
1763 - // Send Payload & create backup.
1764 - $api_response = (array) static::call_cloudways_api( 'POST', '/app/manage/takeBackup', $accessToken, $data );
1964 + if ( static::is_access_token_v2() ) {
1965 + $api_response = (array) static::call_cloudways_api_v2( 'POST', '/app/manage/takeBackup', $data );
1966 + } else {
1765 1967
1968 + // Grab Cloudways access token.
1969 + $accessToken = static::fetch_cloudways_access_token();
1970 +
1971 + // Send Payload & create backup.
1972 + $api_response = (array) static::call_cloudways_api( 'POST', '/app/manage/takeBackup', $accessToken, $data );
1973 + }
1974 +
1766 1975 $success = true;
1767 1976
1768 1977 if ( true !== $api_response['status'] ) {
1769 1978 $success = false;
1770 1979 } else {
1771 - // Save current backup operation.
1772 - $backup_operation = (array) static::call_cloudways_api( 'GET', static::OPERATION . $api_response['operation_id'], $accessToken );
1980 + if ( static::is_access_token_v2() ) {
1981 + // Save current backup operation.
1982 + $backup_operation = (array) static::call_cloudways_api_v2( 'GET', static::OPERATION . $api_response['operation_id'] );
1983 + } else {
1984 + // Save current backup operation.
1985 + $backup_operation = (array) static::call_cloudways_api( 'GET', static::OPERATION . $api_response['operation_id'], $accessToken );
1986 + }
1987 +
1773 1988 $backup_operation = wp_json_encode( $backup_operation['operation'] );
1774 1989 Api_Backups_Helper::update_website_option( $website_id, 'mainwp_3rd_party_cloudways_backup_operation', $backup_operation );
1775 1990
1776 1991 // Save Timestamp.
@@ -1819,13 +2034,19 @@
1819 2034 // Current backup operation.
1820 2035 $backup_operation = isset( $site_options['mainwp_3rd_party_cloudways_backup_operation'] ) ? $site_options['mainwp_3rd_party_cloudways_backup_operation'] : null;
1821 2036 $operation_id = json_decode( $backup_operation, true )['id'];
1822 2037
1823 - // Grab Cloudways access token.
1824 - $accessToken = static::fetch_cloudways_access_token();
2038 + if ( static::is_access_token_v2() ) {
2039 + // Send Payload & list backups. https://api.cloudways.com/api/v1/operation/{id}.
2040 + $operation_polling = static::call_cloudways_api_v2( 'GET', static::OPERATION . $operation_id );
2041 + } else {
1825 2042
1826 - // Send Payload & list backups. https://api.cloudways.com/api/v1/operation/{id}.
1827 - $operation_polling = static::call_cloudways_api( 'GET', static::OPERATION . $operation_id, $accessToken );
2043 + // Grab Cloudways access token.
2044 + $accessToken = static::fetch_cloudways_access_token();
2045 +
2046 + // Send Payload & list backups. https://api.cloudways.com/api/v1/operation/{id}.
2047 + $operation_polling = static::call_cloudways_api( 'GET', static::OPERATION . $operation_id, $accessToken );
2048 + }
1828 2049 $backup_polling_response = $operation_polling->operation;
1829 2050
1830 2051 // If backup has not been completed yet, sleep for 30 seconds and check again.
1831 2052 // If backup has been completed, save the backup operation results.
@@ -1861,10 +2082,8 @@
1861 2082 // Grab $_GET['data'] from url if not Ajax call.
1862 2083 $website_id = isset( $_GET['id'] ) ? intval( $_GET['id'] ) : 0; //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended
1863 2084 }
1864 2085
1865 - // Grab Cloudways access token.
1866 - $accessToken = static::fetch_cloudways_access_token();
1867 2086
1868 2087 // Grab needed site options from WP_MAINWP_WP_OPTIONS table.
1869 2088 $site_options = Api_Backups_Helper::get_website_options(
1870 2089 $website_id,
@@ -1875,18 +2094,31 @@
1875 2094 );
1876 2095 $server_id = isset( $site_options['mainwp_3rd_party_instance_id'] ) ? $site_options['mainwp_3rd_party_instance_id'] : null;
1877 2096 $app_id = isset( $site_options['mainwp_3rd_party_app_id'] ) ? $site_options['mainwp_3rd_party_app_id'] : null;
1878 2097
1879 - // Grab Backup operation from API.
1880 - $backup_operation = static::call_cloudways_api( 'GET', '/app/manage/backup?server_id=' . $server_id . '&app_id=' . $app_id, $accessToken );
1881 - $operation_id = $backup_operation->operation_id;
2098 + if ( static::is_access_token_v2() ) {
2099 + // Grab Backup operation from API.
2100 + $backup_operation = static::call_cloudways_api_v2( 'GET', '/app/manage/backup?server_id=' . $server_id . '&app_id=' . $app_id );
2101 + } else {
2102 + // Grab Cloudways access token.
2103 + $accessToken = static::fetch_cloudways_access_token();
2104 + // Grab Backup operation from API.
2105 + $backup_operation = static::call_cloudways_api( 'GET', '/app/manage/backup?server_id=' . $server_id . '&app_id=' . $app_id, $accessToken );
2106 + }
1882 2107
2108 + $operation_id = $backup_operation->operation_id;
2109 +
1883 2110 sleep( 3 ); // REQUIRED! Wait 3 seconds for cURL connection to be closed before opening a new one.
1884 2111
1885 - // Send Payload & list backups. https://api.cloudways.com/api/v1/operation/{id}.
1886 - $operation_polling = static::call_cloudways_api( 'GET', static::OPERATION . $operation_id, $accessToken );
1887 - $operation = $operation_polling->operation;
2112 + if ( static::is_access_token_v2() ) {
2113 + $operation_polling = static::call_cloudways_api_v2( 'GET', static::OPERATION . $operation_id );
2114 + } else {
2115 + // Send Payload & list backups. https://api.cloudways.com/api/v1/operation/{id}.
2116 + $operation_polling = static::call_cloudways_api( 'GET', static::OPERATION . $operation_id, $accessToken );
2117 + }
1888 2118
2119 + $operation = $operation_polling->operation;
2120 +
1889 2121 // Save backup operation.
1890 2122 Api_Backups_Helper::update_website_option( $website_id, 'mainwp_3rd_party_cloudways_available_backups', $operation->parameters );
1891 2123
1892 2124 Api_Backups_Utility::save_lasttime_backup( $website_id, $operation->parameters, 'cloudways' );
@@ -1934,13 +2166,17 @@
1934 2166 'time' => $backup_date,
1935 2167 'type' => 'complete',
1936 2168 );
1937 2169
1938 - // Grab Cloudways access token.
1939 - $accessToken = static::fetch_cloudways_access_token();
2170 + if ( static::is_access_token_v2() ) {
2171 + $api_response = static::call_cloudways_api_v2( 'POST', '/app/manage/restore', $data );
2172 + } else {
2173 + // Grab Cloudways access token.
2174 + $accessToken = static::fetch_cloudways_access_token();
1940 2175
1941 - // Send Payload & create backup.
1942 - $api_response = static::call_cloudways_api( 'POST', '/app/manage/restore', $accessToken, $data );
2176 + // Send Payload & create backup.
2177 + $api_response = static::call_cloudways_api( 'POST', '/app/manage/restore', $accessToken, $data );
2178 + }
1943 2179
1944 2180 // Handle API response.
1945 2181 if ( 1 !== (int) $api_response->status ) {
1946 2182 wp_die( 'false' );
@@ -2131,8 +2367,16 @@
2131 2367 return Api_Backups_Utility::get_instance()->get_api_key( 'cloudways' );
2132 2368 }
2133 2369
2134 2370 /**
2371 + * Method get_cloudways_access_token().
2372 + */
2373 + public static function get_cloudways_access_token() {
2374 + return Api_Backups_Utility::get_instance()->get_api_key( 'cloudways', '', 'access_token' );
2375 + }
2376 +
2377 +
2378 + /**
2135 2379 * Method get_cpanel_account_password().
2136 2380 */
2137 2381 public static function get_cpanel_account_password() {
2138 2382 return Api_Backups_Utility::get_instance()->get_api_key( 'cpanel' );
@@ -2145,22 +2389,28 @@
2145 2389 return Api_Backups_Utility::get_instance()->get_api_key( 'plesk' );
2146 2390 }
2147 2391
2148 2392 /**
2393 + * Method get_kinsta_api_key().
2394 + */
2395 + public static function get_kinsta_api_key() {
2396 + return Api_Backups_Utility::get_instance()->get_api_key( 'kinsta' );
2397 + }
2398 +
2399 + /**
2149 2400 * Vultr: action create snapshot.
2150 2401 *
2151 2402 * Create a snapshot on the selected Vultr server.
2152 2403 *
2153 2404 * This function is also called before any update. During this time a backup will be
2154 - * Created but no updates will be made this time around. A new update will need to be manually triggered.
2405 + * created but no updates will be made this time around. A new update will need to be manually triggered.
2155 2406 *
2156 - * @param int $website_id Website ID.
2157 - * @param string $backup_api Backup api.
2158 - * @param bool $ret_val Return output or not.
2407 + * @param int $website_id website id.
2408 + * @param string $backup_api backup api.
2159 2409 *
2160 - * @return mixed
2410 + * @return mixed result.
2161 2411 */
2162 - public static function vultr_action_create_snapshot( $website_id = '', $backup_api = '', $ret_val = false ) {
2412 + public static function vultr_action_create_snapshot( $website_id = '', $backup_api = '' ) {
2163 2413
2164 2414 // Grab $_POST data if set else use args.
2165 2415 $website_id = isset( $_POST['website_id'] ) ? intval( $_POST['website_id'] ) : intval( $website_id ); //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended
2166 2416 $backup_api = isset( $_POST['backup_api'] ) ? wp_unslash( $_POST['backup_api'] ) : $backup_api; //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
@@ -2634,10 +2884,8 @@
2634 2884 // Send Payload & create backup.
2635 2885 $backup_response = static::call_gridpane_api( 'POST', '/backups/' . $site_id, $accessToken, $backup_data );
2636 2886 $backup_status = json_decode( $backup_response );
2637 2887
2638 - // DON'T REMOVE THIS LINE - for debugging.
2639 - // error_log(print_r($backup_response, true));.
2640 2888 $success = false;
2641 2889 $error = false;
2642 2890 // Store Last Backup timestamp.
2643 2891 if ( $backup_status && ! empty( $backup_status->success ) ) {
@@ -2645,9 +2893,9 @@
2645 2893 $local_time = current_datetime();
2646 2894 $current_time = $local_time->getTimestamp() + $local_time->getOffset();
2647 2895 Api_Backups_Helper::update_website_option( $website_id, 'mainwp_3rd_party_gridpane_last_backup', $current_time );
2648 2896 } else {
2649 - $error = new WP_Error( $backup_status->error->code, __( $backup_status->error->message, 'mainwp' ) );
2897 + $error = new WP_Error( $backup_status->error->code, $backup_status->error->message );
2650 2898 }
2651 2899
2652 2900 if ( $ret_val ) {
2653 2901 return $backup_status;
@@ -2916,9 +3164,9 @@
2916 3164 }
2917 3165
2918 3166 // Handle response.
2919 3167 if ( isset( $linode_response->errors ) ) {
2920 - $error = new WP_Error( '400', __( $linode_response->errors['0']->reason, 'mainwp' ) );
3168 + $error = new WP_Error( '400', $linode_response->errors['0']->reason );
2921 3169 // Return AJAX.
2922 3170 if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
2923 3171 wp_send_json_error( $error );
2924 3172
@@ -3384,8 +3632,15 @@
3384 3632 * @return array Output from cPanel API.
3385 3633 */
3386 3634 public static function call_plesk_api( $method, $url, $baseurl, $api_key, $backup_data = array() ) {
3387 3635
3636 + // To fix double slash issue in url if exists. If url starts with / and baseurl ends with /, then remove the last slash from baseurl.
3637 + if ( '/' === substr( $url, 0, 1 ) && '/' === substr( $baseurl, -1 ) ) {
3638 + $baseurl = rtrim( $baseurl, '/' );
3639 + }
3640 +
3641 + $full_url = $baseurl . $url;
3642 +
3388 3643 $curl = curl_init();
3389 3644
3390 3645 $api_Key = $api_key;
3391 3646 curl_setopt_array(
@@ -3390,9 +3645,9 @@
3390 3645 $api_Key = $api_key;
3391 3646 curl_setopt_array(
3392 3647 $curl,
3393 3648 array(
3394 - CURLOPT_URL => $baseurl . $url,
3649 + CURLOPT_URL => $full_url,
3395 3650 CURLOPT_RETURNTRANSFER => true,
3396 3651 CURLOPT_ENCODING => '',
3397 3652 CURLOPT_MAXREDIRS => 10,
3398 3653 CURLOPT_TIMEOUT => 0,
@@ -4770,8 +5025,449 @@
4770 5025 // Return AJAX.
4771 5026 if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
4772 5027 // Store Last Backup timestamp.
4773 5028 if ( '200' === (string) $api_response['httpCode'] && empty( $errors ) ) {
5029 + wp_send_json( 'true' );
5030 + } else {
5031 + wp_die( 'false' );
5032 + }
5033 + }
5034 + }
5035 +
5036 + /*********************************************************************************
5037 + * Kinsta API Methods.
5038 + **********************************************************************************/
5039 +
5040 + /**
5041 + * Kinsta: action refresh available backups.
5042 + *
5043 + * Refresh available backups for the selected server.
5044 + *
5045 + * @return void
5046 + */
5047 + public function ajax_kinsta_action_refresh_available_backups() {
5048 + Api_Backups_Helper::security_nonce( 'kinsta_action_refresh_available_backups' );
5049 + static::kinsta_action_refresh_available_backups();
5050 + die();
5051 + }
5052 +
5053 + /**
5054 + * Kinsta: action create backup.
5055 + *
5056 + * Create backup for the selected server.
5057 + *
5058 + * @return void
5059 + */
5060 + public function ajax_kinsta_action_create_backup() {
5061 + Api_Backups_Helper::security_nonce( 'kinsta_action_create_backup' );
5062 + static::kinsta_action_create_backup();
5063 + die();
5064 + }
5065 +
5066 + /**
5067 + * Kinsta: action delete backup.
5068 + *
5069 + * Create backup for the selected server.
5070 + *
5071 + * @return void
5072 + */
5073 + public function ajax_kinsta_action_delete_backup() {
5074 + Api_Backups_Helper::security_nonce( 'kinsta_action_delete_backup' );
5075 + static::kinsta_action_delete_backup();
5076 + die();
5077 + }
5078 +
5079 + /**
5080 + * Kinsta: action restore backup.
5081 + *
5082 + * Restore backup for the selected server.
5083 + *
5084 + * @return void
5085 + */
5086 + public function ajax_kinsta_action_restore_backup() {
5087 + Api_Backups_Helper::security_nonce( 'kinsta_action_restore_backup' );
5088 + static::kinsta_action_restore_backup(); // ajax call.
5089 + die();
5090 + }
5091 +
5092 + /**
5093 + *
5094 + * Kinsta: Authentication.
5095 + *
5096 + * Grab needed authentication credentials for Kinsta API - either from global settings or individual settings.
5097 + *
5098 + * @param int $website_id Website ID.
5099 + *
5100 + * @return array
5101 + */
5102 + public static function get_kinsta_authentication_credentials( $website_id = null ) { //phpcs:ignore -- NOSONAR - complex.
5103 +
5104 + $kinsta_authentication_credentials = array();
5105 +
5106 + // Grab website_id & from Ajax post if $website_id is not set.
5107 + if ( empty( $website_id ) ) {
5108 + if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
5109 + // Grab : $_POST['data'] submit values.
5110 + $website_id = isset( $_POST['website_id'] ) ? intval( $_POST['website_id'] ) : 0; //phpcs:ignore -- nonce verified.
5111 + } else {
5112 + // Grab : $_GET['data'] from url if not Ajax call.
5113 + $website_id = isset( $_GET['id'] ) ? intval( $_GET['id'] ) : 0; //phpcs:ignore -- nonce verified.
5114 + }
5115 + }
5116 +
5117 + // Global / Individual check.
5118 + $global_individual_check = Api_Backups_Helper::get_website_options( $website_id, array( 'mainwp_enable_kinsta_individual' ) );
5119 + $mainwp_enable_kinsta_individual = isset( $global_individual_check['mainwp_enable_kinsta_individual'] ) ? $global_individual_check['mainwp_enable_kinsta_individual'] : '0';
5120 +
5121 + if ( 'on' === $mainwp_enable_kinsta_individual ) {
5122 + // Grab cPanel baseurl, username & password.
5123 + $kinsta_baseurl = 'https://api.kinsta.com/v2';
5124 +
5125 + // Grab Kinsta password.
5126 + $kinsta_api_key = Api_Backups_Utility::get_instance()->get_child_api_key( $website_id, 'kinsta' );
5127 +
5128 + // Grab Kinsta Account Email.
5129 + $account_email = Api_Backups_Helper::get_website_options( $website_id, array( 'mainwp_kinsta_account_email' ) );
5130 + $kinsta_account_email = isset( $account_email['mainwp_kinsta_account_email'] ) ? $account_email['mainwp_kinsta_account_email'] : null;
5131 +
5132 + // Grab Kinsta Company ID.
5133 + $company_id = Api_Backups_Helper::get_website_options( $website_id, array( 'mainwp_kinsta_company_id' ) );
5134 + $kinsta_company_id = isset( $company_id['mainwp_kinsta_company_id'] ) ? $company_id['mainwp_kinsta_company_id'] : null;
5135 +
5136 + // Grab Kinsta Environment ID.
5137 + $environment_id = Api_Backups_Helper::get_website_options( $website_id, array( 'mainwp_kinsta_environment_id' ) );
5138 + $kinsta_environment_id = isset( $environment_id['mainwp_kinsta_environment_id'] ) ? $environment_id['mainwp_kinsta_environment_id'] : null;
5139 +
5140 + } elseif ( '0' === $mainwp_enable_kinsta_individual ) {
5141 + // Grab Kinsta baseurl, username & password.
5142 + $kinsta_baseurl = 'https://api.kinsta.com/v2';
5143 +
5144 + // Grab Kinsta password.
5145 + $kinsta_api_key = static::get_kinsta_api_key();
5146 +
5147 + // Grab Kinsta Account Email.
5148 + $kinsta_account_email = get_option( 'mainwp_kinsta_api_account_email' );
5149 +
5150 + // Grab Kinsta Company ID.
5151 + $kinsta_company_id = get_option( 'mainwp_kinsta_company_id' );
5152 +
5153 + // Grab Kinsta Environment ID.
5154 + $environment_id = Api_Backups_Helper::get_website_options( $website_id, array( 'mainwp_kinsta_environment_id' ) );
5155 + $kinsta_environment_id = isset( $environment_id['mainwp_kinsta_environment_id'] ) ? $environment_id['mainwp_kinsta_environment_id'] : null;
5156 + }
5157 +
5158 + // Build array.
5159 + $kinsta_authentication_credentials[] = array(
5160 + 'kinsta_baseurl' => $kinsta_baseurl,
5161 + 'kinsta_api_key' => $kinsta_api_key,
5162 + 'kinsta_environment_id' => $kinsta_environment_id,
5163 + 'website_id' => $website_id,
5164 + 'kinsta_company_id' => $kinsta_company_id,
5165 + 'kinsta_company_email' => $kinsta_account_email,
5166 + );
5167 +
5168 + return $kinsta_authentication_credentials;
5169 + }
5170 +
5171 + /**
5172 + * Call Kinsta API, Authenticate & perform given method.
5173 + *
5174 + * @param string $method GET|POST|PUT|DELETE.
5175 + * @param string $url API endpoint for the call.
5176 + * @param string $baseurl baseurl.
5177 + * @param string $api_key Kinsta API Key.
5178 + * @param string $action action.
5179 + * @param string $backup_data action.
5180 + *
5181 + * @return array Output from cPanel API.
5182 + */
5183 + public static function call_kinsta_api( $method, $url, $baseurl, $api_key, $action = '', $backup_data = array() ) {
5184 +
5185 + $curl = curl_init();
5186 +
5187 + $api_Key = $api_key;
5188 + curl_setopt_array(
5189 + $curl,
5190 + array(
5191 + CURLOPT_URL => $baseurl . $url,
5192 + CURLOPT_RETURNTRANSFER => true,
5193 + CURLOPT_ENCODING => '',
5194 + CURLOPT_MAXREDIRS => 10,
5195 + CURLOPT_TIMEOUT => 0,
5196 + CURLOPT_FOLLOWLOCATION => true,
5197 + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
5198 + CURLOPT_CUSTOMREQUEST => $method,
5199 + CURLOPT_POSTFIELDS => $backup_data,
5200 + CURLOPT_HTTPHEADER => array(
5201 + 'Content-Type: application/json',
5202 + "Authorization: Bearer $api_Key",
5203 + ),
5204 + )
5205 + );
5206 +
5207 + $resp = curl_exec( $curl );
5208 + $httpCode = (string) curl_getinfo( $curl, CURLINFO_HTTP_CODE );
5209 +
5210 + $response['httpCode'] = $httpCode;
5211 + $response['response'] = $resp;
5212 +
5213 + if ( '202' !== $httpCode && '200' !== $httpCode ) {
5214 + $response['status'] = 'false';
5215 + } else {
5216 + $response['status'] = 'true';
5217 + }
5218 +
5219 + // Log API call.
5220 + $payload = "[Status] $httpCode :: [Action] $action :: [EndPoint] $baseurl$url";
5221 + $payload_response = "[Status] $httpCode :: [Action] $action :: [Response] $resp";
5222 + Api_Backups_Utility::log_debug( $payload );
5223 + Api_Backups_Utility::log_debug( $payload_response );
5224 +
5225 + curl_close( $curl );
5226 + return $response;
5227 + }
5228 +
5229 + /**
5230 + *
5231 + * Kinsta: Action get User ID.
5232 + *
5233 + * Get the User Id from the given Company ID & Email address.
5234 + *
5235 + * @return array
5236 + */
5237 + public static function kinsta_action_get_user_id() {
5238 +
5239 + // Authenticate kinsta account.
5240 + $kinsta_authentication_credentials = static::get_kinsta_authentication_credentials();
5241 + $kinsta_baseurl = $kinsta_authentication_credentials[0]['kinsta_baseurl'];
5242 + $kinsta_api_key = $kinsta_authentication_credentials[0]['kinsta_api_key'];
5243 + $kinsta_company_id = $kinsta_authentication_credentials[0]['kinsta_company_id'];
5244 + $kinsta_company_email = $kinsta_authentication_credentials[0]['kinsta_company_email'];
5245 +
5246 + $payload_url = '/company/' . $kinsta_company_id . '/users';
5247 +
5248 + // Send Payload.
5249 + $api_response = static::call_kinsta_api( 'GET', $payload_url, $kinsta_baseurl, $kinsta_api_key, '' );
5250 +
5251 + // Decode Response.
5252 + $response = json_decode( $api_response['response'] );
5253 + $company = $response->company;
5254 + $company_users = $company->users;
5255 +
5256 + // Grab correct user ID.
5257 + foreach ( $company_users as $user ) {
5258 + if ( $kinsta_company_email === $user->user->email ) {
5259 + $user_id = $user->user->id;
5260 + }
5261 + }
5262 +
5263 + // Return user id.
5264 + return $user_id;
5265 + }
5266 +
5267 + /**
5268 + *
5269 + * Kinsta: Action refresh available backups.
5270 + *
5271 + * Save backups to DB for the selected server.
5272 + *
5273 + * @param array $credentials Kinsta credentials.
5274 + * @param bool $return_result Return or not.
5275 + *
5276 + * @return mixed
5277 + */
5278 + public static function kinsta_action_refresh_available_backups( $credentials = array(), $return_result = false ) {
5279 +
5280 + // Authenticate kinsta account.
5281 + $kinsta_authentication_credentials = empty( $credentials ) || ! is_array( $credentials ) ? static::get_kinsta_authentication_credentials() : $credentials;
5282 + $kinsta_baseurl = $kinsta_authentication_credentials[0]['kinsta_baseurl'];
5283 + $kinsta_api_key = $kinsta_authentication_credentials[0]['kinsta_api_key'];
5284 + $kinsta_env_id = $kinsta_authentication_credentials[0]['kinsta_environment_id'];
5285 + $website_id = $kinsta_authentication_credentials[0]['website_id'];
5286 + $downloadable_backups = '';
5287 +
5288 + $action = 'kinsta_action_refresh_available_backups';
5289 +
5290 + // Grab backup meta.
5291 + $api_response = static::call_kinsta_api( 'GET', '/sites/environments/' . $kinsta_env_id . '/backups', $kinsta_baseurl, $kinsta_api_key, $action );
5292 +
5293 + $success = false;
5294 +
5295 + if ( 'true' === $api_response['status'] ) {
5296 + $all_backups = $api_response['response'];
5297 + Api_Backups_Helper::update_website_option( $website_id, 'mainwp_3rd_party_kinsta_available_backups', $all_backups );
5298 + Api_Backups_Utility::save_lasttime_backup( $website_id, $all_backups, 'kinsta' );
5299 +
5300 + $action = 'kinsta_action_refresh_available_backups_downloadable';
5301 +
5302 + $downloadable_backups = static::call_kinsta_api( 'GET', '/sites/environments/' . $kinsta_env_id . '/downloadable-backups', $kinsta_baseurl, $kinsta_api_key, $action );
5303 + $success = true;
5304 + } else {
5305 + Api_Backups_Utility::log_debug( 'Kinsta API Error: ' . $api_response['response'] );
5306 + }
5307 + if ( $downloadable_backups ) {
5308 + if ( 'true' === $downloadable_backups['status'] ) {
5309 + $downloadable_backups = $downloadable_backups['response'];
5310 + Api_Backups_Helper::update_website_option( $website_id, 'mainwp_3rd_party_kinsta_downloadable_backups', $downloadable_backups );
5311 + }
5312 + } else {
5313 + Api_Backups_Utility::log_debug( 'Kinsta API Error: There was an issue while refreshing available backups.' );
5314 + }
5315 +
5316 + if ( $return_result ) {
5317 + return $success;
5318 + }
5319 +
5320 + // Return AJAX.
5321 + if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
5322 + // Store Last Backup timestamp.
5323 + if ( 'true' === $api_response['status'] ) {
5324 + wp_send_json( 'true' );
5325 + } else {
5326 + wp_die( 'false' );
5327 + }
5328 + }
5329 + }
5330 +
5331 + /**
5332 + *
5333 + * Kinsta: Action create manual backup.
5334 + *
5335 + * Create a Plesk Backup.
5336 + *
5337 + * @param bool $resturn_values resturn values.
5338 + * @param int $site_id website id.
5339 + *
5340 + * @return mixed result.
5341 + */
5342 + public static function kinsta_action_create_backup( $resturn_values = false, $site_id = null ) {
5343 +
5344 + // Authenticate kinsta account.
5345 + $kinsta_authentication_credentials = static::get_kinsta_authentication_credentials( $site_id );
5346 + $kinsta_baseurl = $kinsta_authentication_credentials[0]['kinsta_baseurl'];
5347 + $kinsta_api_key = $kinsta_authentication_credentials[0]['kinsta_api_key'];
5348 + $kinsta_env_id = $kinsta_authentication_credentials[0]['kinsta_environment_id'];
5349 + $website_id = $kinsta_authentication_credentials[0]['website_id'];
5350 +
5351 + // Grab Child Site options.
5352 + $website = Api_Backups_Helper::get_website_by_id( $website_id );
5353 +
5354 + // Prepare Backup Payload.
5355 + $backup_data = array(
5356 + 'tag' => 'MainWP API Backups - ' . $website['name'],
5357 + );
5358 + $backup_data = wp_json_encode( $backup_data );
5359 +
5360 + // Send Payload & create backup.
5361 + $api_response = static::call_kinsta_api( 'POST', '/sites/environments/' . $kinsta_env_id . '/manual-backups', $kinsta_baseurl, $kinsta_api_key, $backup_data );
5362 +
5363 + if ( is_array( $api_response ) && isset( $api_response['status'] ) && 'true' === $api_response['status'] ) {
5364 + // Save Timestamp.
5365 + $local_time = current_datetime();
5366 + $current_time = $local_time->getTimestamp() + $local_time->getOffset();
5367 + Api_Backups_Helper::update_website_option( $website_id, 'mainwp_3rd_party_kinsta_last_backup', $current_time );
5368 + }
5369 +
5370 + if ( $resturn_values ) {
5371 + return $api_response;
5372 + }
5373 +
5374 + // Return AJAX.
5375 + if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
5376 + // Store Last Backup timestamp.
5377 + if ( 'true' === $api_response['status'] ) {
5378 + wp_send_json( 'true' );
5379 + } else {
5380 + wp_die( 'false' );
5381 + }
5382 + }
5383 + }
5384 +
5385 + /**
5386 + *
5387 + * Kinsta: Action create manual backup.
5388 + *
5389 + * Create a Plesk Backup.
5390 + *
5391 + * @param bool $return_values return values.
5392 + *
5393 + * @return array
5394 + */
5395 + public static function kinsta_action_delete_backup( $return_values = false ) {
5396 +
5397 + $backup_id = isset( $_POST['backup_id'] ) ? wp_unslash( $_POST['backup_id'] ) : ''; //phpcs:ignore -- nonce verified.
5398 +
5399 + // Authenticate kinsta account.
5400 + $kinsta_authentication_credentials = static::get_kinsta_authentication_credentials();
5401 + $kinsta_baseurl = $kinsta_authentication_credentials[0]['kinsta_baseurl'];
5402 + $kinsta_api_key = $kinsta_authentication_credentials[0]['kinsta_api_key'];
5403 +
5404 + $payload_url = '/sites/environments/backups/' . $backup_id;
5405 +
5406 + // Send Payload & create backup.
5407 + $api_response = static::call_kinsta_api( 'DELETE', $payload_url, $kinsta_baseurl, $kinsta_api_key, '' );
5408 +
5409 + if ( is_array( $api_response ) && isset( $api_response['status'] ) && 'true' === $api_response['status'] ) {
5410 + static::kinsta_action_refresh_available_backups( $kinsta_authentication_credentials, true );
5411 + }
5412 +
5413 + if ( $return_values ) {
5414 + return $api_response;
5415 + }
5416 +
5417 + // Return AJAX.
5418 + if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
5419 + // Store Last Backup timestamp.
5420 + if ( 'true' === $api_response['status'] ) {
5421 + wp_send_json( 'true' );
5422 + } else {
5423 + wp_die( 'false' );
5424 + }
5425 + }
5426 + }
5427 +
5428 + /**
5429 + *
5430 + * Kinsta: Action restore manual backup.
5431 + *
5432 + * Restore a selected Backup.
5433 + *
5434 + * @param bool $return_values return or not.
5435 + *
5436 + * @return array
5437 + */
5438 + public static function kinsta_action_restore_backup( $return_values = false ) {
5439 +
5440 + $backup_id = isset( $_POST['backup_id'] ) ? intval( $_POST['backup_id'] ) : 0; //phpcs:ignore -- nonce verified.
5441 +
5442 + // Authenticate kinsta account.
5443 + $kinsta_authentication_credentials = static::get_kinsta_authentication_credentials();
5444 + $kinsta_baseurl = $kinsta_authentication_credentials[0]['kinsta_baseurl'];
5445 + $kinsta_api_key = $kinsta_authentication_credentials[0]['kinsta_api_key'];
5446 + $kinsta_env_id = $kinsta_authentication_credentials[0]['kinsta_environment_id'];
5447 +
5448 + $company_user_id = static::kinsta_action_get_user_id();
5449 +
5450 + $payload_url = '/sites/environments/' . $kinsta_env_id . '/backups/restore';
5451 +
5452 + // Prepare Backup Payload.
5453 + $backup_data = array(
5454 + 'backup_id' => $backup_id,
5455 + 'notified_user_id' => $company_user_id,
5456 + );
5457 + $backup_data = wp_json_encode( $backup_data );
5458 +
5459 + // Send Payload & create backup.
5460 + $api_response = static::call_kinsta_api( 'POST', $payload_url, $kinsta_baseurl, $kinsta_api_key, '', $backup_data );
5461 +
5462 + if ( $return_values ) {
5463 + return $api_response;
5464 + }
5465 +
5466 + // Return AJAX.
5467 + if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
5468 + // Store Last Backup timestamp.
5469 + if ( 'true' === $api_response['status'] ) {
4774 5470 wp_send_json( 'true' );
4775 5471 } else {
4776 5472 wp_die( 'false' );
4777 5473 }