plugin = $plugin; $this->home_url = $this->get_home_url(); parent::__construct(); } /** * Get home URL. * * @return string */ private function get_home_url() { $home_url = get_option( 'home' ); if ( is_multisite() && $this->plugin->is_network_activated ) { // Make sure always use the network URL in API communication $current_site = get_current_site(); $home_url = 'http://' . $current_site->domain; } return untrailingslashit( set_url_scheme( $home_url, 'http' ) ); } /** * Generate the API URL * * @param string $request * @param array $args * * @return string */ function get_url( $request, $args = array() ) { $url = $this->api_url; $args['request'] = $request; $args['product'] = $this->plugin->slug; $args['version'] = $this->plugin->version; $args['locale'] = urlencode( get_locale() ); $args['php_version'] = urlencode( phpversion() ); $args['wordpress_version'] = urlencode( get_bloginfo( 'version' ) ); $args = apply_filters( $this->plugin->prefix . '_' . $request . '_request_args', $args ); if ( false !== get_site_transient( 'dbrains_temporarily_disable_ssl' ) && 0 === strpos( $this->api_url, 'https://' ) ) { $url = substr_replace( $url, 'http', 0, 5 ); } $url = add_query_arg( $args, $url ); return esc_url_raw( $url ); } /** * Main function for communicating with the Delicious Brains API. * * @param string $request * @param array $args * * @return mixed */ function api_request( $request, $args = array() ) { if ( ( $check = $this->check_api_down() ) ) { return $check; } $url = $this->get_url( $request, $args ); $response = $this->get( $url ); if ( is_wp_error( $response ) || (int) $response['response']['code'] < 200 || (int) $response['response']['code'] > 399 ) { // Couldn't connect successfully to the API $this->log_error( $response ); if ( true === $this->is_api_down() ) { // API is down return $this->check_api_down(); } return $this->connection_failed_response(); } return $response['body']; } /** * Return a warning notice if the API is down as a response to an API request * * @return bool|mixed|string|void */ function check_api_down() { $trans = get_site_transient( 'dbrains_api_down' ); if ( false !== $trans ) { $api_down_message = sprintf( '
', $trans ); return json_encode( array( 'dbrains_api_down' => $api_down_message ) ); } return false; } /** * Return a connection failed notice as a response to an API request * * @return string */ protected function connection_failed_response() { $connection_failed_message = __( 'Could not connect to deliciousbrains.com — You will not receive update notifications or be able to activate your license until this is fixed.' ); $connection_failed_message .= '';
if ( defined( 'WP_HTTP_BLOCK_EXTERNAL' ) && WP_HTTP_BLOCK_EXTERNAL ) {
$url_parts = parse_url( $this->api_base );
$host = $url_parts['host'];
if ( ! defined( 'WP_ACCESSIBLE_HOSTS' ) || strpos( WP_ACCESSIBLE_HOSTS, $host ) === false ) {
$connection_failed_message .= sprintf( __( 'We\'ve detected that WP_HTTP_BLOCK_EXTERNAL is enabled and the host %1$s has not been added to WP_ACCESSIBLE_HOSTS. Please disable WP_HTTP_BLOCK_EXTERNAL or add %1$s to WP_ACCESSIBLE_HOSTS to continue. More information' ), esc_attr( $host ), 'https://deliciousbrains.com/wp-migrate-db-pro/doc/wp_http_block_external/' );
}
} else {
$disable_ssl_url = $this->admin_url( $this->plugin->settings_url_path . '&nonce=' . wp_create_nonce( $this->plugin->prefix . '-disable-ssl' ) . '&' . $this->plugin->prefix . '-disable-ssl=1' );
$connection_failed_message .= sprintf( __( 'This issue is often caused by an improperly configured SSL server (https). We recommend fixing the SSL configuration on your server, but if you need a quick fix you can %2$s' ), 'https://deliciousbrains.com/wp-migrate-db-pro/doc/could-not-connect-deliciousbrains-com/', sprintf( '%2$s', $disable_ssl_url, __( 'temporarily disable SSL for connections to deliciousbrains.com.' ) ) );
}
return json_encode( array( 'errors' => array( 'connection_failed' => $connection_failed_message ) ) );
}
/**
* Is the Delicious Brains API down?
*
* If not available then a 'dbrains_api_down' transient will be set with an appropriate message.
*
* @return bool
*/
protected function is_api_down() {
if ( false !== get_site_transient( 'dbrains_api_down' ) ) {
return true;
}
$response = $this->get( $this->api_status_url );
// Can't get to api status url so fall back to normal failure handling.
if ( is_wp_error( $response ) || 200 != (int) $response['response']['code'] || empty( $response['body'] ) ) {
return false;
}
$json = json_decode( $response['body'], true );
// Can't decode json so fall back to normal failure handling.
if ( ! $json ) {
return false;
}
// Decoded JSON data doesn't seem to be the format we expect or is not down, so fall back to normal failure handling.
if ( ! isset( $json['api']['status'] ) || 'down' != $json['api']['status'] ) {
return false;
}
$message = $this->get_down_message( $json['api'] );
set_site_transient( 'dbrains_api_down', $message, $this->transient_retry_timeout );
return true;
}
/**
* Form the error message about the API being down
*
* @param array $response
*
* @return string
*/
protected function get_down_message( $response ) {
$message = __( "Delicious Brains API is Down — Unfortunately we're experiencing some problems with our server." );
if ( ! empty( $response['updated'] ) ) {
$updated = $response['updated'];
$updated_ago = sprintf( _x( '%s ago', 'ex. 2 hours ago' ), human_time_diff( strtotime( $updated ) ) );
}
if ( ! empty( $response['message'] ) ) {
$message .= '
';
$message .= __( "Here's the most recent update on its status" );
if ( ! empty( $updated_ago ) ) {
$message .= ' (' . $updated_ago . ')';
}
$message .= ': ' . $response['message'] . '';
}
return $message;
}
/**
* Default request arguments passed to an HTTP request
*
* @return array
*
* @see wp_remote_request() For more information on the available arguments.
*/
protected function get_default_request_args() {
return array(
'timeout' => 10,
'blocking' => true,
'sslverify' => $this->verify_ssl(),
);
}
/**
* Retrieve the url to the admin area for the site.
* Handles if the plugin is a network activated plugin.
*
* @param string $path Optional path relative to the admin url
*
* @return string|void
*/
public function admin_url( $path ) {
if ( $this->plugin->is_network_activated ) {
$url = network_admin_url( $path );
} else {
$url = admin_url( $path );
}
return $url;
}
/**
* Error log method
*
* phpcs:disable WordPress.PHP.DevelopmentFunctions
*
* @param mixed $error
* @param bool $additional_error_var
*/
function log_error( $error, $additional_error_var = false ) {
error_log( print_r( $error, true ) );
}
/**
* Use SSL verification for requests
*
* @return bool
*/
function verify_ssl() {
return false;
}
}