123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- <?php
- if ( ! class_exists( "Yoast_Update_Manager", false ) ) {
- class Yoast_Update_Manager {
- /**
- * @var Yoast_Product
- */
- protected $product;
- /**
- * @var Yoast_License_Manager
- */
- protected $license_manager;
- /**
- * @var string
- */
- protected $error_message = '';
- /**
- * @var object
- */
- protected $update_response = null;
- /**
- * @var string The transient name storing the API response
- */
- private $response_transient_key = '';
- /**
- * @var string The transient name that stores failed request tries
- */
- private $request_failed_transient_key = '';
- /**
- * Constructor
- *
- * @param Yoast_Product $product The product.
- * @param Yoast_License_Manager $license_manager The License Manager.
- */
- public function __construct( Yoast_Product $product, $license_manager ) {
- $this->product = $product;
- $this->license_manager = $license_manager;
- // generate transient names
- $this->response_transient_key = $this->product->get_transient_prefix() . '-update-response';
- $this->request_failed_transient_key = $this->product->get_transient_prefix() . '-update-request-failed';
- // maybe delete transient
- $this->maybe_delete_transients();
- }
- /**
- * Deletes the various transients
- * If we're on the update-core.php?force-check=1 page
- */
- private function maybe_delete_transients() {
- global $pagenow;
- if ( $pagenow === 'update-core.php' && isset( $_GET['force-check'] ) ) {
- delete_transient( $this->response_transient_key );
- delete_transient( $this->request_failed_transient_key );
- }
- }
- /**
- * If the update check returned a WP_Error, show it to the user
- */
- public function show_update_error() {
- if ( $this->error_message === '' ) {
- return;
- }
- ?>
- <div class="notice notice-error yoast-notice-error">
- <p><?php printf( __( '%s failed to check for updates because of the following error: <em>%s</em>', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->error_message ); ?></p>
- </div>
- <?php
- }
- /**
- * Calls the API and, if successfull, returns the object delivered by the API.
- *
- * @uses get_bloginfo()
- * @uses wp_remote_post()
- * @uses is_wp_error()
- *
- * @return false||object
- */
- private function call_remote_api() {
- // only check if the failed transient is not set (or if it's expired)
- if ( get_transient( $this->request_failed_transient_key ) !== false ) {
- return false;
- }
- // start request process
- global $wp_version;
- // set a transient to prevent failed update checks on every page load
- // this transient will be removed if a request succeeds
- set_transient( $this->request_failed_transient_key, 'failed', 10800 );
- // setup api parameters
- $api_params = array(
- 'edd_action' => 'get_version',
- 'license' => $this->license_manager->get_license_key(),
- 'item_name' => $this->product->get_item_name(),
- 'wp_version' => $wp_version,
- 'item_version' => $this->product->get_version(),
- 'url' => $this->license_manager->get_url(),
- 'slug' => $this->product->get_slug(),
- );
- // Add product ID from product if it is implemented.
- if ( method_exists( $this->product, 'get_product_id' ) ) {
- $product_id = $this->product->get_product_id();
- if ( $product_id > 0 ) {
- $api_params['product_id'] = $this->product->get_product_id();
- }
- }
- // setup request parameters
- $request_params = array(
- 'method' => 'POST',
- 'body' => $api_params
- );
- require_once dirname( __FILE__ ) . '/class-api-request.php';
- $request = new Yoast_API_Request( $this->product->get_api_url(), $request_params );
- if ( $request->is_valid() !== true ) {
- // show error message
- $this->error_message = $request->get_error_message();
- add_action( 'admin_notices', array( $this, 'show_update_error' ) );
- return false;
- }
- // request succeeded, delete transient indicating a request failed
- delete_transient( $this->request_failed_transient_key );
- // decode response
- $response = $request->get_response();
- // check if response returned that a given site was inactive
- if ( isset( $response->license_check ) && ! empty( $response->license_check ) && $response->license_check != 'valid' ) {
- // deactivate local license
- $this->license_manager->set_license_status( 'invalid' );
- // show notice to let the user know we deactivated his/her license
- $this->error_message = __( "This site has not been activated properly on yoast.com and thus cannot check for future updates. Please activate your site with a valid license key.", $this->product->get_text_domain() );
- /**
- * Filter: 'yoast-show-license-notice' - Show the license notice.
- *
- * @api bool $show True if notices should be shown.
- */
- if ( apply_filters( 'yoast-show-license-notice', true ) ) {
- add_action( 'admin_notices', array( $this, 'show_update_error' ) );
- }
- }
- $response->sections = maybe_unserialize( $response->sections );
- // store response
- set_transient( $this->response_transient_key, $response, 10800 );
- return $response;
- }
- /**
- * Gets the remote product data (from the EDD API)
- *
- * - If it was previously fetched in the current requests, this gets it from the instance property
- * - Next, it tries the 3-hour transient
- * - Next, it calls the remote API and stores the result
- *
- * @return object
- */
- protected function get_remote_data() {
- // always use property if it's set
- if ( null !== $this->update_response ) {
- return $this->update_response;
- }
- // get cached remote data
- $data = $this->get_cached_remote_data();
- // if cache is empty or expired, call remote api
- if ( $data === false ) {
- $data = $this->call_remote_api();
- }
- $this->update_response = $data;
- return $data;
- }
- /**
- * Gets the remote product data from a 3-hour transient
- *
- * @return bool|mixed
- */
- private function get_cached_remote_data() {
- $data = get_transient( $this->response_transient_key );
- if ( $data ) {
- return $data;
- }
- return false;
- }
- }
- }
|