Skip to content

Instantly share code, notes, and snippets.

@toleabivol
Last active February 13, 2018 08:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toleabivol/0322558cc4615ebeae9518f4030b7d1e to your computer and use it in GitHub Desktop.
Save toleabivol/0322558cc4615ebeae9518f4030b7d1e to your computer and use it in GitHub Desktop.
Update extension for Unyson Theme Update service
<?php if (!defined('FW')) die('Forbidden');
/**
* Nex Update
*/
class FW_Extension_Nex_Update extends FW_Ext_Update_Service
{
/**
* How long to cache server responses
* @var int seconds
*/
private $transient_expiration = DAY_IN_SECONDS;
private $download_timeout = 300;
/**
* Used when there is internet connection problems
* To prevent site being blocked on every refresh, this fake version will be cached in the transient
* @var string
*/
private $fake_latest_version = '0.0.0';
/**
* @internal
*/
protected function _init()
{
}
/**
* @param string $append
* @return string
*/
private function get_nexthemes_api_url($append)
{
return apply_filters('fw_nexthemes_api_url', 'https://nexthemes.co/obfuscatedapipath/?source=yyy&key=xxx') . $append;
}
private function fetch_latest_version()
{
/**
* If at least one request failed, do not do any other requests, to prevent site being blocked on every refresh.
* This may happen on localhost when develop your theme and you have no internet connection.
* Then this method will return a fake '0.0.0' version, it will be cached by the transient
* and will not bother you until the transient will expire, then a new request will be made.
* @var bool
*/
static $no_internet_connection = false;
if ($no_internet_connection) {
return $this->fake_latest_version;
}
$http = new WP_Http();
$response = $http->get(
$this->get_nexthemes_api_url('&action=fetch_theme_version&theme_slug=' . NEX_SUBTHEME_SLUG)
);
unset($http);
if (is_wp_error($response)) {
if ($response->get_error_code() === 'http_request_failed') {
$no_internet_connection = true;
}
return $response;
}
if (($response_code = intval(wp_remote_retrieve_response_code($response))) !== 200) {
if ($response_code === 403) {
$json_response = json_decode($response['body'], true);
if ($json_response) {
return new WP_Error(
'fw_ext_update_nex_fetch_releases_failed',
__('nex error:', 'nex') .' '. $json_response['message']
);
}
}
if ($response_code) {
return new WP_Error(
'fw_ext_update_nex_fetch_releases_failed',
sprintf(
__( 'Failed to access nex repository "%s" releases. (Response code: %d)', 'nex' ),
NEX_SUBTHEME_SLUG, $response_code
)
);
} else {
return new WP_Error(
'fw_ext_update_nex_fetch_releases_failed',
sprintf(
__( 'Failed to access nex repository "%s" releases.', 'nex' ),
NEX_SUBTHEME_SLUG
)
);
}
}
$release = json_decode($response['body'], true);
unset($response);
if (empty($release)) {
return new WP_Error(
'fw_ext_update_nex_fetch_no_releases',
sprintf(__('No releases found for "%s".', 'nex'), NEX_SUBTHEME_SLUG)
);
}
if (!empty($release['result']) && $release['result'] !== 'success') {
return new WP_Error(
'fw_ext_update_nex_fetch_api_failed',
sprintf(__('Api failed : "%s".', 'nex'), $release['message'])
);
}
return $release['message'];
}
/**
* Get repository latest release version
*
* @param bool $force_check Bypass cache
* @param string $title Used in messages
*
* @return string|WP_Error
*/
private function get_latest_version($force_check, $title)
{
$transient_id = 'nex_upd'; // the length must be 45 characters or less
if ($force_check) {
delete_site_transient($transient_id);
$cache = array();
} else {
$cache = get_site_transient($transient_id);
if ($cache === false) {
$cache = array();
} elseif (isset($cache[$title])) {
return $cache[$title];
}
}
$latest_version = $this->fetch_latest_version();
if (empty($latest_version)) {
return new WP_Error(
'fw_ext_update_nex_failed_fetch_latest_version',
sprintf(
__('Failed to fetch %s latest version from nex.', 'nex'),
$title
)
);
}
if (is_wp_error($latest_version)) {
/**
* Internet connection problems
* Cache fake version to prevent requests to nexthemes on every refresh.
*/
$cache = array_merge($cache, array($title => $this->fake_latest_version));
/**
* Show the error to the user because it is not visible elsewhere
*/
FW_Flash_Messages::add(
'fw_ext_nex_update_error',
$latest_version->get_error_message(),
'error'
);
} else {
$cache = array_merge($cache, array($title => $latest_version));
}
set_site_transient(
$transient_id,
$cache,
$this->transient_expiration
);
return $latest_version;
}
/**
* @param string $theme_slug
* @param string $version Requested version to download
* @param string $wp_filesystem_download_directory Allocated temporary empty directory
* @param string $title Used in messages
*
* @return string|WP_Error Path to the downloaded directory
*/
private function download($theme_slug, $version, $wp_filesystem_download_directory, $title)
{
if(!defined('NEX_SUBTHEME_LICENSE') || empty(NEX_SUBTHEME_LICENSE)) {
return new WP_Error(
'fw_ext_update_nex_download_no_license',
__('no license found.', 'nex')
);
}
//get latest version and bypass catch
$version = $this->get_latest_version(true, $title);
$http = new WP_Http();
$response = $http->request(
$this->get_nexthemes_api_url('&action=downloadTheme&themeVersion='.$version.'&themeSlug=' . NEX_SUBTHEME_SLUG . ),
array(
'timeout' => $this->download_timeout,
)
);
unset($http);
if (intval(wp_remote_retrieve_response_code($response)) !== 200) {
return new WP_Error(
'fw_ext_update_nex_download_failed',
sprintf(__('Cannot download %s zip.', 'nex'), $title)
);
}
$api = json_decode(wp_remote_retrieve_body( $response ));
if (!empty($api->result) && $api->result !== 'success' && !empty($api->message)) {
return new WP_Error(
'fw_ext_update_nex_download_api_error',
sprintf(__('Nexthemes API error: %s .', 'nex'), $api->message)
);
}
/** @var WP_Filesystem_Base $wp_filesystem */
global $wp_filesystem;
$zip_path = $wp_filesystem_download_directory .'/temp.zip';
// save zip to file
if (!$wp_filesystem->put_contents($zip_path, $response['body'])) {
return new WP_Error(
'fw_ext_update_github_save_download_failed',
sprintf(__('Cannot save %s zip.', 'nex'), $title)
);
}
unset($response);
$unzip_result = unzip_file(
FW_WP_Filesystem::filesystem_path_to_real_path($zip_path),
$wp_filesystem_download_directory
);
if (is_wp_error($unzip_result)) {
return $unzip_result;
}
// remove zip file
if (!$wp_filesystem->delete($zip_path, false, 'f')) {
return new WP_Error(
'fw_ext_update_github_remove_downloaded_zip_failed',
sprintf(__('Cannot remove %s zip.', 'nex'), $title)
);
}
$unzipped_dir_files = $wp_filesystem->dirlist($wp_filesystem_download_directory);
if (!$unzipped_dir_files) {
return new WP_Error(
'fw_ext_update_github_unzipped_dir_fail',
__('Cannot access the unzipped directory files.', 'nex')
);
}
/**
* get first found directory
* (if everything worked well, there should be only one directory)
*/
foreach ($unzipped_dir_files as $folder) {
if ($folder['type'] == 'd') {
return $wp_filesystem_download_directory .'/'. $folder['name'];
}
}
return new WP_Error(
'fw_ext_update_nex_unzipped_dir_not_found',
sprintf(__('The unzipped %s directory not found.', 'nex'), $title)
);
}
/**
* {@inheritdoc}
* @internal
*/
public function _get_theme_latest_version($force_check)
{
return $this->get_latest_version(
$force_check,
NEX_SUBTHEME_SLUG
);
}
/**
* {@inheritdoc}
* @internal
*/
public function _download_theme($version, $wp_filesystem_download_directory)
{
return $this->download(
NEX_SUBTHEME_SLUG,
$version,
$wp_filesystem_download_directory,
NEX_SUBTHEME_SLUG
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment