← All changes
|
modules/api-backups/classes/class-api-backups-3rd-party.php
+180
-32
6.1.1
→
6.2.1
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 → 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, |