-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'vupdater-backed-as-previous' into develop
updater-backed-as-previous
- Loading branch information
Showing
2 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,262 @@ | ||
<?php | ||
|
||
namespace Appsero; | ||
|
||
use stdClass; | ||
|
||
/** | ||
* Appsero Updater | ||
* | ||
* This class will show new updates project | ||
*/ | ||
class Updater { | ||
|
||
/** | ||
* Appsero\Client | ||
* | ||
* @var object | ||
*/ | ||
protected $client; | ||
|
||
/** | ||
* Cache key | ||
* | ||
* @var string | ||
*/ | ||
protected $cache_key; | ||
|
||
/** | ||
* Initialize the class | ||
* | ||
* @param Appsero\Client | ||
*/ | ||
public function __construct( Client $client ) { | ||
$this->client = $client; | ||
$this->cache_key = 'appsero_' . md5( $this->client->slug ) . '_version_info'; | ||
|
||
// Run hooks. | ||
if ( $this->client->type === 'plugin' ) { | ||
$this->run_plugin_hooks(); | ||
} elseif ( $this->client->type === 'theme' ) { | ||
$this->run_theme_hooks(); | ||
} | ||
} | ||
|
||
/** | ||
* Set up WordPress filter to hooks to get update. | ||
* | ||
* @return void | ||
*/ | ||
public function run_plugin_hooks() { | ||
add_filter( 'pre_set_site_transient_update_plugins', [ $this, 'check_plugin_update' ] ); | ||
add_filter( 'plugins_api', [ $this, 'plugins_api_filter' ], 10, 3 ); | ||
} | ||
|
||
/** | ||
* Set up WordPress filter to hooks to get update. | ||
* | ||
* @return void | ||
*/ | ||
public function run_theme_hooks() { | ||
add_filter( 'pre_set_site_transient_update_themes', [ $this, 'check_theme_update' ] ); | ||
} | ||
|
||
/** | ||
* Check for Update for this specific project | ||
*/ | ||
public function check_plugin_update( $transient_data ) { | ||
global $pagenow; | ||
|
||
if ( ! is_object( $transient_data ) ) { | ||
$transient_data = new stdClass(); | ||
} | ||
|
||
if ( 'plugins.php' === $pagenow && is_multisite() ) { | ||
return $transient_data; | ||
} | ||
|
||
if ( ! empty( $transient_data->response ) && ! empty( $transient_data->response[ $this->client->basename ] ) ) { | ||
return $transient_data; | ||
} | ||
|
||
$version_info = $this->get_version_info(); | ||
|
||
if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) { | ||
unset( $version_info->sections ); | ||
|
||
// If new version available then set to `response` | ||
if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) { | ||
$transient_data->response[ $this->client->basename ] = $version_info; | ||
} else { | ||
// If new version is not available then set to `no_update` | ||
$transient_data->no_update[ $this->client->basename ] = $version_info; | ||
} | ||
|
||
$transient_data->last_checked = time(); | ||
$transient_data->checked[ $this->client->basename ] = $this->client->project_version; | ||
} | ||
|
||
return $transient_data; | ||
} | ||
|
||
/** | ||
* Get version info from database | ||
* | ||
* @return object or Boolean | ||
*/ | ||
private function get_cached_version_info() { | ||
global $pagenow; | ||
|
||
// If updater page then fetch from API now | ||
if ( 'update-core.php' === $pagenow ) { | ||
return false; // Force to fetch data | ||
} | ||
|
||
$value = get_transient( $this->cache_key ); | ||
|
||
if ( ! $value && ! isset( $value->name ) ) { | ||
return false; // Cache is expired | ||
} | ||
|
||
// We need to turn the icons into an array | ||
if ( isset( $value->icons ) ) { | ||
$value->icons = (array) $value->icons; | ||
} | ||
|
||
// We need to turn the banners into an array | ||
if ( isset( $value->banners ) ) { | ||
$value->banners = (array) $value->banners; | ||
} | ||
|
||
if ( isset( $value->sections ) ) { | ||
$value->sections = (array) $value->sections; | ||
} | ||
|
||
return $value; | ||
} | ||
|
||
/** | ||
* Set version info to database | ||
*/ | ||
private function set_cached_version_info( $value ) { | ||
if ( ! $value ) { | ||
return; | ||
} | ||
|
||
set_transient( $this->cache_key, $value, 3 * HOUR_IN_SECONDS ); | ||
} | ||
|
||
/** | ||
* Get plugin info from Appsero | ||
*/ | ||
private function get_project_latest_version() { | ||
$license = $this->client->license()->get_license(); | ||
|
||
$params = [ | ||
'version' => $this->client->project_version, | ||
'name' => $this->client->name, | ||
'slug' => $this->client->slug, | ||
'basename' => $this->client->basename, | ||
'license_key' => ! empty( $license ) && isset( $license['key'] ) ? $license['key'] : '', | ||
]; | ||
|
||
$route = 'update/' . $this->client->hash . '/check'; | ||
|
||
$response = $this->client->send_request( $params, $route, true ); | ||
|
||
if ( is_wp_error( $response ) ) { | ||
return false; | ||
} | ||
|
||
$response = json_decode( wp_remote_retrieve_body( $response ) ); | ||
|
||
if ( ! isset( $response->slug ) ) { | ||
return false; | ||
} | ||
|
||
if ( isset( $response->icons ) ) { | ||
$response->icons = (array) $response->icons; | ||
} | ||
|
||
if ( isset( $response->banners ) ) { | ||
$response->banners = (array) $response->banners; | ||
} | ||
|
||
if ( isset( $response->sections ) ) { | ||
$response->sections = (array) $response->sections; | ||
} | ||
|
||
return $response; | ||
} | ||
|
||
/** | ||
* Updates information on the "View version x.x details" page with custom data. | ||
* | ||
* @param mixed $data | ||
* @param string $action | ||
* @param object $args | ||
* | ||
* @return object $data | ||
*/ | ||
public function plugins_api_filter( $data, $action = '', $args = null ) { | ||
if ( $action !== 'plugin_information' ) { | ||
return $data; | ||
} | ||
|
||
if ( ! isset( $args->slug ) || ( $args->slug !== $this->client->slug ) ) { | ||
return $data; | ||
} | ||
|
||
return $this->get_version_info(); | ||
} | ||
|
||
/** | ||
* Check theme upate | ||
*/ | ||
public function check_theme_update( $transient_data ) { | ||
global $pagenow; | ||
|
||
if ( ! is_object( $transient_data ) ) { | ||
$transient_data = new stdClass(); | ||
} | ||
|
||
if ( 'themes.php' === $pagenow && is_multisite() ) { | ||
return $transient_data; | ||
} | ||
|
||
if ( ! empty( $transient_data->response ) && ! empty( $transient_data->response[ $this->client->slug ] ) ) { | ||
return $transient_data; | ||
} | ||
|
||
$version_info = $this->get_version_info(); | ||
|
||
if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) { | ||
// If new version available then set to `response` | ||
if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) { | ||
$transient_data->response[ $this->client->slug ] = (array) $version_info; | ||
} else { | ||
// If new version is not available then set to `no_update` | ||
$transient_data->no_update[ $this->client->slug ] = (array) $version_info; | ||
} | ||
|
||
$transient_data->last_checked = time(); | ||
$transient_data->checked[ $this->client->slug ] = $this->client->project_version; | ||
} | ||
|
||
return $transient_data; | ||
} | ||
|
||
/** | ||
* Get version information | ||
*/ | ||
private function get_version_info() { | ||
$version_info = $this->get_cached_version_info(); | ||
|
||
if ( false === $version_info ) { | ||
$version_info = $this->get_project_latest_version(); | ||
$this->set_cached_version_info( $version_info ); | ||
} | ||
|
||
return $version_info; | ||
} | ||
} |