api_url = rtrim( $api_url, '/' ); $this->plugin_slug = $plugin_slug; $this->plugin_basename = $plugin_basename; $this->current_version = $current_version; // Hook into the update check process. add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_updates' ) ); // Hook into the plugin information screen. add_filter( 'plugins_api', array( $this, 'plugin_information' ), 10, 3 ); } /** * Check for plugin updates. * * @param object $transient The update transient. * @return object The modified transient. */ public function check_for_updates( $transient ) { if ( empty( $transient->checked ) ) { return $transient; } $remote_info = $this->get_remote_info(); if ( $remote_info && isset( $remote_info->version ) && version_compare( $this->current_version, $remote_info->version, '<' ) ) { $update_obj = new \stdClass(); $update_obj->slug = $this->plugin_slug; $update_obj->plugin = $this->plugin_basename; $update_obj->new_version = $remote_info->version; $update_obj->url = $remote_info->homepage; $update_obj->package = $remote_info->package; $transient->response[ $this->plugin_basename ] = $update_obj; } return $transient; } /** * Provide plugin information for the "View details" screen. * * @param false|object|array $result The result object. * @param string $action The type of information being requested. * @param object $args Plugin API arguments. * @return false|object The modified result object or false. */ public function plugin_information( $result, $action, $args ) { // Check if this is a request for our plugin. if ( 'plugin_information' !== $action || ! isset( $args->slug ) || $args->slug !== $this->plugin_slug ) { return $result; } $remote_info = $this->get_remote_info(); if ( $remote_info ) { // The remote info is already in the correct format. return $remote_info; } return $result; } /** * Retrieve remote plugin information from the API. * * @return object|false The plugin information object or false on failure. */ private function get_remote_info() { $transient_key = 'version_pilot_update_' . $this->plugin_slug; $cached_info = get_site_transient( $transient_key ); if ( false !== $cached_info ) { return $cached_info; } /** * Filter to provide authentication credentials for the update request. * * @since 1.0.0 * @param array $credentials { * An array of credentials. * * @type string $user The username or member ID. * @type string $key The API key or license key. * } * @param string $plugin_slug The slug of the plugin being updated. */ $credentials = apply_filters( 'version_pilot_client_auth_credentials', array( 'user' => '', 'key' => '', ), $this->plugin_slug ); $local_site_host = wp_parse_url( home_url(), PHP_URL_HOST ); $client_api_host = wp_parse_url( $this->api_url, PHP_URL_HOST ); $use_local_method = ( $local_site_host === $client_api_host ) && class_exists( '\Wowown\VersionPilot\Includes\Version_Pilot_REST_API' ); $remote_info = false; if ( $use_local_method ) { $api_server = new \Wowown\VersionPilot\Includes\Version_Pilot_REST_API(); $request = new \WP_REST_Request( 'GET', '/version-pilot/v1/plugins/' . $this->plugin_slug ); $request->set_url_params( array( 'slug' => $this->plugin_slug ) ); $request->set_query_params( array( 'client_version' => $this->current_version ) ); // Add authentication headers if provided. if ( ! empty( $credentials['user'] ) ) { $request->set_header( 'x-wvpu-user', $credentials['user'] ); } if ( ! empty( $credentials['key'] ) ) { $request->set_header( 'x-wvpu-key', $credentials['key'] ); } $response = $api_server->get_plugin_data( $request ); if ( is_wp_error( $response ) || ! is_object( $response ) || ! method_exists( $response, 'get_data' ) ) { return false; } $response_data = $response->get_data(); if ( ! is_array( $response_data ) || empty( $response_data['version'] ) ) { return false; } $remote_info = (object) $response_data; } else { // If the server class doesn't exist, proceed with the remote HTTP request. $request_url = $this->api_url . '/wp-json/version-pilot/v1/plugins/' . $this->plugin_slug; $request_url = add_query_arg( 'client_version', $this->current_version, $request_url ); $args = array( 'timeout' => 10, 'headers' => array() ); // Add authentication headers if provided. if ( ! empty( $credentials['user'] ) ) { $args['headers']['X-Wvpu-User'] = $credentials['user']; } if ( ! empty( $credentials['key'] ) ) { $args['headers']['X-Wvpu-Key'] = $credentials['key']; } $response = wp_remote_get( $request_url, $args ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { return false; } $remote_info = json_decode( wp_remote_retrieve_body( $response ), true ); if ( json_last_error() !== JSON_ERROR_NONE || empty( $remote_info['version'] ) ) { return false; } $remote_info = (object) $remote_info; } if ( ! is_object( $remote_info ) ) { return false; } // Cache the response for 12 hours. set_site_transient( $transient_key, $remote_info, 12 * HOUR_IN_SECONDS ); return $remote_info; } } endif;