Last active
February 13, 2018 08:32
-
-
Save toleabivol/0322558cc4615ebeae9518f4030b7d1e to your computer and use it in GitHub Desktop.
Update extension for Unyson Theme Update service
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
<?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