/** * Download an extension * * global $wp_filesystem; must me initialized * * @param string $extension_name * @param array $data Extension data from the "available extensions" array * @return string|WP_Error WP Filesystem path to the downloaded directory */ private function download($extension_name, $data) { $wp_error_id = 'fw_extension_download'; if (empty($data['download'])) { return new WP_Error($wp_error_id, sprintf(__('Extension "%s" has no download sources.', 'fw'), $this->get_extension_title($extension_name))); } /** @var WP_Filesystem_Base $wp_filesystem */ global $wp_filesystem; $wp_fs_tmp_dir = FW_WP_Filesystem::real_path_to_filesystem_path($this->get_tmp_dir()); if ($wp_filesystem->exists($wp_fs_tmp_dir)) { // just in case it already exists, clear everything, it may contain old files if (!$wp_filesystem->rmdir($wp_fs_tmp_dir, true)) { return new WP_Error($wp_error_id, sprintf(__('Cannot remove temporary directory: %s', 'fw'), $wp_fs_tmp_dir)); } } if (!FW_WP_Filesystem::mkdir_recursive($wp_fs_tmp_dir)) { return new WP_Error($wp_error_id, sprintf(__('Cannot create temporary directory: %s', 'fw'), $wp_fs_tmp_dir)); } foreach ($data['download'] as $source => $source_data) { switch ($source) { case 'github': if (empty($source_data['user_repo'])) { return new WP_Error($wp_error_id, sprintf(__('"%s" extension github source "user_repo" parameter is required', 'fw'), $this->get_extension_title($extension_name))); } $transient_name = 'fw_ext_mngr_gh_dl'; $transient_ttl = HOUR_IN_SECONDS; $cache = get_site_transient($transient_name); if ($cache === false) { $cache = array(); } if (isset($cache[$source_data['user_repo']])) { $download_link = $cache[$source_data['user_repo']]['zipball_url']; } else { $http = new WP_Http(); $response = $http->get(apply_filters('fw_github_api_url', 'https://api.github.com') . '/repos/' . $source_data['user_repo'] . '/releases/latest'); unset($http); $response_code = intval(wp_remote_retrieve_response_code($response)); if ($response_code !== 200) { if ($response_code === 403) { $json_response = json_decode($response['body'], true); if ($json_response) { return new WP_Error($wp_error_id, __('Github error:', 'fw') . ' ' . $json_response['message']); } } elseif ($response_code) { return new WP_Error($wp_error_id, sprintf(__('Failed to access Github repository "%s" releases. (Response code: %d)', 'fw'), $source_data['user_repo'], $response_code)); } elseif (is_wp_error($response)) { return new WP_Error($wp_error_id, sprintf(__('Failed to access Github repository "%s" releases. (%s)', 'fw'), $source_data['user_repo'], $response->get_error_message())); } else { return new WP_Error($wp_error_id, sprintf(__('Failed to access Github repository "%s" releases.', 'fw'), $source_data['user_repo'])); } } $release = json_decode($response['body'], true); unset($response); if (empty($release)) { return new WP_Error($wp_error_id, sprintf(__('"%s" extension github repository "%s" has no releases.', 'fw'), $this->get_extension_title($extension_name), $source_data['user_repo'])); } $cache[$source_data['user_repo']] = array('zipball_url' => 'https://github.com/' . $source_data['user_repo'] . '/archive/' . $release['tag_name'] . '.zip', 'tag_name' => $release['tag_name']); set_site_transient($transient_name, $cache, $transient_ttl); $download_link = $cache[$source_data['user_repo']]['zipball_url']; unset($release); } $http = new WP_Http(); $response = $http->request($download_link, array('timeout' => $this->download_timeout)); unset($http); if (($response_code = intval(wp_remote_retrieve_response_code($response))) !== 200) { if ($response_code) { return new WP_Error($wp_error_id, sprintf(__('Cannot download the "%s" extension zip. (Response code: %d)', 'fw'), $this->get_extension_title($extension_name), $response_code)); } elseif (is_wp_error($response)) { return new WP_Error($wp_error_id, sprintf(__('Cannot download the "%s" extension zip. %s', 'fw'), $this->get_extension_title($extension_name), $response->get_error_message())); } else { return new WP_Error($wp_error_id, sprintf(__('Cannot download the "%s" extension zip.', 'fw'), $this->get_extension_title($extension_name))); } } $zip_path = $wp_fs_tmp_dir . '/temp.zip'; // save zip to file if (!$wp_filesystem->put_contents($zip_path, $response['body'])) { return new WP_Error($wp_error_id, sprintf(__('Cannot save the "%s" extension zip.', 'fw'), $this->get_extension_title($extension_name))); } unset($response); $unzip_result = unzip_file(FW_WP_Filesystem::filesystem_path_to_real_path($zip_path), $wp_fs_tmp_dir); if (is_wp_error($unzip_result)) { return $unzip_result; } // remove zip file if (!$wp_filesystem->delete($zip_path, false, 'f')) { return new WP_Error($wp_error_id, sprintf(__('Cannot remove the "%s" extension downloaded zip.', 'fw'), $this->get_extension_title($extension_name))); } $unzipped_dir_files = $wp_filesystem->dirlist($wp_fs_tmp_dir); if (!$unzipped_dir_files) { return new WP_Error($wp_error_id, __('Cannot access the unzipped directory files.', 'fw')); } /** * get first found directory * (if everything worked well, there should be only one directory) */ foreach ($unzipped_dir_files as $file) { if ($file['type'] == 'd') { return $wp_fs_tmp_dir . '/' . $file['name']; } } return new WP_Error($wp_error_id, sprintf(__('The unzipped "%s" extension directory not found.', 'fw'), $this->get_extension_title($extension_name))); break; default: return new WP_Error($wp_error_id, sprintf(__('Unknown "%s" extension download source "%s"', 'fw'), $this->get_extension_title($extension_name), $source)); } } }
/** * {@inheritdoc} * @internal */ public function _download_framework($version, $wp_filesystem_download_directory) { /** @var WP_Filesystem_Base $wp_filesystem */ global $wp_filesystem; $user_slash_repo = fw()->manifest->get($this->manifest_key); $http = new WP_Http(); $response = $http->get('https://api.github.com/repos/' . $user_slash_repo . '/releases'); unset($http); if (wp_remote_retrieve_response_code($response) !== 200) { return new WP_Error('fw_ext_update_github_framework_download_releases_failed', __('Failed to access Github repository releases.', 'fw')); } $releases = json_decode($response['body'], true); unset($response); if (empty($releases)) { return new WP_Error('fw_ext_update_github_framework_download_no_releases', __('Github repository has no releases.', 'fw')); } $release = false; foreach ($releases as $_release) { if ($_release['tag_name'] === $version) { $release = $_release; } } if (empty($release)) { return new WP_Error('fw_ext_update_github_framework_download_not_existing_release', sprintf(__('Requested version (release) for download does not exists "%s".', 'fw'), $version)); } $http = new WP_Http(); $response = $http->request($release['zipball_url'], array('timeout' => $this->download_timeout)); unset($http); if (wp_remote_retrieve_response_code($response) !== 200) { return new WP_Error('fw_ext_update_github_framework_download_failed', __('Failed to download framework zip.', 'fw')); } $zip_path = $wp_filesystem_download_directory . '/temp.zip'; // save zip to file $wp_filesystem->put_contents($zip_path, $response['body']); unset($response); unzip_file(FW_WP_Filesystem::filesystem_path_to_real_path($zip_path), $wp_filesystem_download_directory); // remove zip file $wp_filesystem->delete($zip_path, false, 'f'); $unzipped_dir = $wp_filesystem->dirlist($wp_filesystem_download_directory); $unzipped_dir = $wp_filesystem_download_directory . '/' . key($unzipped_dir); return $unzipped_dir; }
private function perform_zip_download(FW_Ext_Download_Source $download_source, array $opts, $wp_fs_tmp_dir) { $wp_error_id = 'fw_extension_download'; /** @var WP_Filesystem_Base $wp_filesystem */ global $wp_filesystem; $zip_path = $wp_fs_tmp_dir . '/temp.zip'; $download_result = $download_source->download($opts, $zip_path); /** * Pass further the error, if the service returned one. */ if (is_wp_error($download_result)) { return $download_result; } $extension_name = $opts['extension_name']; $unzip_result = unzip_file(FW_WP_Filesystem::filesystem_path_to_real_path($zip_path), $wp_fs_tmp_dir); if (is_wp_error($unzip_result)) { return $unzip_result; } // remove zip file if (!$wp_filesystem->delete($zip_path, false, 'f')) { return new WP_Error($wp_error_id, sprintf(__('Cannot remove the "%s" extension downloaded zip.', 'fw'), $this->get_extension_title($extension_name))); } $unzipped_dir_files = $wp_filesystem->dirlist($wp_fs_tmp_dir); if (!$unzipped_dir_files) { return new WP_Error($wp_error_id, __('Cannot access the unzipped directory files.', 'fw')); } /** * get first found directory * (if everything worked well, there should be only one directory) */ foreach ($unzipped_dir_files as $file) { if ($file['type'] == 'd') { return $wp_fs_tmp_dir . '/' . $file['name']; } } return new WP_Error($wp_error_id, sprintf(__('The unzipped "%s" extension directory not found.', 'fw'), $this->get_extension_title($extension_name))); }
/** * @param string $user_slash_repo Github 'user/repo' * @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($user_slash_repo, $version, $wp_filesystem_download_directory, $title) { $http = new WP_Http(); $response = $http->get($this->get_github_api_url('/repos/' . $user_slash_repo . '/releases/tags/' . $version)); unset($http); $response_code = intval(wp_remote_retrieve_response_code($response)); if ($response_code !== 200) { if ($response_code === 403) { $json_response = json_decode($response['body'], true); if ($json_response) { return new WP_Error('fw_ext_update_github_download_releases_failed', __('Github error:', 'fw') . ' ' . $json_response['message']); } } if ($response_code) { return new WP_Error('fw_ext_update_github_download_releases_failed', sprintf(__('Failed to access Github repository "%s" releases. (Response code: %d)', 'fw'), $user_slash_repo, $response_code)); } else { return new WP_Error('fw_ext_update_github_download_releases_failed', sprintf(__('Failed to access Github repository "%s" releases.', 'fw'), $user_slash_repo)); } } $release = json_decode($response['body'], true); unset($response); if (empty($release)) { return new WP_Error('fw_ext_update_github_download_no_release', sprintf(__('%s github repository "%s" does not have the "%s" release.', 'fw'), $title, $user_slash_repo, $version)); } $http = new WP_Http(); $response = $http->request('https://github.com/' . $user_slash_repo . '/archive/' . $release['tag_name'] . '.zip', array('timeout' => $this->download_timeout)); unset($http); if (intval(wp_remote_retrieve_response_code($response)) !== 200) { return new WP_Error('fw_ext_update_github_download_failed', sprintf(__('Cannot download %s zip.', 'fw'), $title)); } /** @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.', 'fw'), $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.', 'fw'), $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.', 'fw')); } /** * get first found directory * (if everything worked well, there should be only one directory) */ foreach ($unzipped_dir_files as $file) { if ($file['type'] == 'd') { return $wp_filesystem_download_directory . '/' . $file['name']; } } return new WP_Error('fw_ext_update_github_unzipped_dir_not_found', sprintf(__('The unzipped %s directory not found.', 'fw'), $title)); }