PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
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 +180 -32 6.0.11 → 6.2.2 View file →
@@ -30,8 +30,10 @@
30 30 class Api_Backups_3rd_Party { //phpcs:ignore -- NOSONAR - multi methods.
31 31
32 32 // phpcs:disable WordPress.DB.RestrictedFunctions, Generic.Metrics.CyclomaticComplexity, WordPress.WP.AlternativeFunctions, WordPress.PHP.NoSilencedErrors -- Using cURL functions.
33 33
34 + const CLOUDWAYS_API_URL = 'https://api.cloudways.com/api/v2';
35 +
34 36 /**
35 37 * Public static variable to hold the single instance of the class.
36 38 *
37 39 * @var mixed Default null
@@ -39,8 +41,15 @@
39 41 protected static $instance = null;
40 42
41 43
42 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 + /**
43 52 * Public static variable.
44 53 */
45 54 const OPERATION = '/operation/'; // to clean code.
46 55
@@ -533,9 +542,9 @@
533 542 $available_backups = array();
534 543 }
535 544
536 545 if ( empty( $backup_api ) ) {
537 - $title = esc_html__( 'No API Backup Solution has been chosen.', 'mainwp' );
546 + $title = esc_html__( 'No API Backup Solution has been chosen.', 'mainwp' );
538 547 /* translators: %1$s: Link to API Backups Settings page, %2$s: Link to Child Site Settings page */
539 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' );
540 549 $message = sprintf(
541 550 $msg_format,
@@ -541,9 +550,9 @@
541 550 $msg_format,
542 551 '<a href="' . esc_url( admin_url( 'admin.php?page=SettingsApiBackups' ) ) . '">' . esc_html__( 'API Backups Settings', 'mainwp' ) . '</a>',
543 552 '<a href="' . esc_url( admin_url( 'admin.php?page=managesites&id=' . intval( $website_id ) ) ) . '">' . esc_html__( 'Child Site &rarr; Settings page', 'mainwp' ) . '</a>'
544 553 );
545 - $icon = '<em data-emoji=":closed_lock_with_key:" class="big"></em>';
554 + $icon = '<em data-emoji=":closed_lock_with_key:" class="big"></em>';
546 555 \MainWP\Dashboard\MainWP_UI::render_empty_page_placeholder( $title, $message, $icon );
547 556 } else {
548 557 $columns = 'one';
549 558 if ( 'cpanel' === $backup_api || 'plesk' === $backup_api ) {
@@ -719,9 +728,10 @@
719 728 <div class="ui info message">
720 729 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-module-api-backups-info-message"></i>
721 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>
722 731 </div>
723 - <?php endif;
732 + <?php
733 + endif;
724 734 $el_id_wp_1 = $website['id'];
725 735 ?>
726 736 <table id="mainwp-siteid-<?php echo intval( $el_id_wp_1 ); ?>-table" class="ui mainwp-api-backup-table table" style="width:100%">
727 737 <thead>
@@ -1650,8 +1660,32 @@
1650 1660 <?php
1651 1661 } // END if.
1652 1662 }
1653 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 +
1654 1688 /*********************************************************************************
1655 1689 * Cloudways API Methods.
1656 1690 **********************************************************************************/
1657 1691
@@ -1664,11 +1698,68 @@
1664 1698 * 2. Enter in your account email address and API Key below.
1665 1699 *
1666 1700 * @param string $method GET|POST|PUT|DELETE.
1667 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.
1668 1759 * @param string $accessToken Access token generated using OAuth Call.
1669 1760 * @param array $post Optional post data for the call.
1670 - * @return object Output from CW API.
1761 + * @return object|false Output from CW API.
1671 1762 */
1672 1763 public static function call_cloudways_api( $method, $url, $accessToken, $post = array() ) {
1673 1764 $baseURL = 'https://api.cloudways.com/api/v1';
1674 1765
@@ -1697,12 +1788,14 @@
1697 1788 $output = curl_exec( $ch );
1698 1789
1699 1790 $httpcode = (string) curl_getinfo( $ch, CURLINFO_HTTP_CODE );
1700 1791
1792 + curl_close( $ch );
1793 +
1701 1794 if ( '200' !== $httpcode ) {
1702 1795 return false;
1703 1796 }
1704 - curl_close( $ch );
1797 +
1705 1798 return json_decode( $output );
1706 1799 }
1707 1800
1708 1801 /**
@@ -1737,13 +1830,19 @@
1737 1830 *
1738 1831 * @return mixed Returns available list of servers.
1739 1832 */
1740 1833 public static function fetch_cloudways_server_list() { //phpcs:ignore -- NOSONAR - complex.
1741 - // Grab access token.
1742 - $accessToken = static::fetch_cloudways_access_token();
1743 1834
1744 - // Fetch Server List.
1745 - $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 +
1746 1845 if ( ! array_key_exists( 'servers', $serverList ) ) {
1747 1846 return;
1748 1847 }
1749 1848 // Return the server list.
@@ -1859,21 +1958,34 @@
1859 1958 'server_id' => $server_id,
1860 1959 'app_id' => $app_id,
1861 1960 );
1862 1961
1863 - // Grab Cloudways access token.
1864 - $accessToken = static::fetch_cloudways_access_token();
1962 + $accessToken = '';
1865 1963
1866 - // Send Payload & create backup.
1867 - $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 {
1868 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 +
1869 1975 $success = true;
1870 1976
1871 1977 if ( true !== $api_response['status'] ) {
1872 1978 $success = false;
1873 1979 } else {
1874 - // Save current backup operation.
1875 - $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 +
1876 1988 $backup_operation = wp_json_encode( $backup_operation['operation'] );
1877 1989 Api_Backups_Helper::update_website_option( $website_id, 'mainwp_3rd_party_cloudways_backup_operation', $backup_operation );
1878 1990
1879 1991 // Save Timestamp.
@@ -1922,13 +2034,19 @@
1922 2034 // Current backup operation.
1923 2035 $backup_operation = isset( $site_options['mainwp_3rd_party_cloudways_backup_operation'] ) ? $site_options['mainwp_3rd_party_cloudways_backup_operation'] : null;
1924 2036 $operation_id = json_decode( $backup_operation, true )['id'];
1925 2037
1926 - // Grab Cloudways access token.
1927 - $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 {
1928 2042
1929 - // Send Payload & list backups. https://api.cloudways.com/api/v1/operation/{id}.
1930 - $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 + }
1931 2049 $backup_polling_response = $operation_polling->operation;
1932 2050
1933 2051 // If backup has not been completed yet, sleep for 30 seconds and check again.
1934 2052 // If backup has been completed, save the backup operation results.
@@ -1964,10 +2082,8 @@
1964 2082 // Grab $_GET['data'] from url if not Ajax call.
1965 2083 $website_id = isset( $_GET['id'] ) ? intval( $_GET['id'] ) : 0; //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended
1966 2084 }
1967 2085
1968 - // Grab Cloudways access token.
1969 - $accessToken = static::fetch_cloudways_access_token();
1970 2086
1971 2087 // Grab needed site options from WP_MAINWP_WP_OPTIONS table.
1972 2088 $site_options = Api_Backups_Helper::get_website_options(
1973 2089 $website_id,
@@ -1978,18 +2094,31 @@
1978 2094 );
1979 2095 $server_id = isset( $site_options['mainwp_3rd_party_instance_id'] ) ? $site_options['mainwp_3rd_party_instance_id'] : null;
1980 2096 $app_id = isset( $site_options['mainwp_3rd_party_app_id'] ) ? $site_options['mainwp_3rd_party_app_id'] : null;
1981 2097
1982 - // Grab Backup operation from API.
1983 - $backup_operation = static::call_cloudways_api( 'GET', '/app/manage/backup?server_id=' . $server_id . '&app_id=' . $app_id, $accessToken );
1984 - $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 + }
1985 2107
2108 + $operation_id = $backup_operation->operation_id;
2109 +
1986 2110 sleep( 3 ); // REQUIRED! Wait 3 seconds for cURL connection to be closed before opening a new one.
1987 2111
1988 - // Send Payload & list backups. https://api.cloudways.com/api/v1/operation/{id}.
1989 - $operation_polling = static::call_cloudways_api( 'GET', static::OPERATION . $operation_id, $accessToken );
1990 - $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 + }
1991 2118
2119 + $operation = $operation_polling->operation;
2120 +
1992 2121 // Save backup operation.
1993 2122 Api_Backups_Helper::update_website_option( $website_id, 'mainwp_3rd_party_cloudways_available_backups', $operation->parameters );
1994 2123
1995 2124 Api_Backups_Utility::save_lasttime_backup( $website_id, $operation->parameters, 'cloudways' );
@@ -2037,13 +2166,17 @@
2037 2166 'time' => $backup_date,
2038 2167 'type' => 'complete',
2039 2168 );
2040 2169
2041 - // Grab Cloudways access token.
2042 - $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();
2043 2175
2044 - // Send Payload & create backup.
2045 - $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 + }
2046 2179
2047 2180 // Handle API response.
2048 2181 if ( 1 !== (int) $api_response->status ) {
2049 2182 wp_die( 'false' );
@@ -2234,8 +2367,16 @@
2234 2367 return Api_Backups_Utility::get_instance()->get_api_key( 'cloudways' );
2235 2368 }
2236 2369
2237 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 + /**
2238 2379 * Method get_cpanel_account_password().
2239 2380 */
2240 2381 public static function get_cpanel_account_password() {
2241 2382 return Api_Backups_Utility::get_instance()->get_api_key( 'cpanel' );
@@ -3491,8 +3632,15 @@
3491 3632 * @return array Output from cPanel API.
3492 3633 */
3493 3634 public static function call_plesk_api( $method, $url, $baseurl, $api_key, $backup_data = array() ) {
3494 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 +
3495 3643 $curl = curl_init();
3496 3644
3497 3645 $api_Key = $api_key;
3498 3646 curl_setopt_array(
@@ -3497,9 +3645,9 @@
3497 3645 $api_Key = $api_key;
3498 3646 curl_setopt_array(
3499 3647 $curl,
3500 3648 array(
3501 - CURLOPT_URL => $baseurl . $url,
3649 + CURLOPT_URL => $full_url,
3502 3650 CURLOPT_RETURNTRANSFER => true,
3503 3651 CURLOPT_ENCODING => '',
3504 3652 CURLOPT_MAXREDIRS => 10,
3505 3653 CURLOPT_TIMEOUT => 0,