Initial Commit
This commit is contained in:
332
inc/rollback/class-rollback.php
Normal file
332
inc/rollback/class-rollback.php
Normal file
@ -0,0 +1,332 @@
|
||||
<?php
|
||||
/**
|
||||
* WP Ultimo Rollback
|
||||
*
|
||||
* Allows users to rollback WP Ultimo to the previous stable version.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Rollback
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Rollback;
|
||||
|
||||
use \WP_Ultimo\License;
|
||||
use \WP_Ultimo\Logger;
|
||||
use \WP_Ultimo\Rollback\Rollback_Plugin_Upgrader;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* WP Ultimo Rollback.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Rollback {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Holds the URL for serving build files.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $updates_url = 'https://licenses.nextpress.us/api/meta/wp-ultimo/';
|
||||
|
||||
/**
|
||||
* Holds the URL for download build files.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $download_url = 'https://licenses.nextpress.us/api/download/wp-ultimo/';
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
add_filter('network_admin_plugin_action_links', array($this, 'plugin_page_action_links'), 200, 4);
|
||||
|
||||
add_action('admin_init', array($this, 'handle_rollback_process'));
|
||||
|
||||
add_action('plugins_loaded', array($this, 'load_admin_page'));
|
||||
|
||||
} // end init;
|
||||
|
||||
/**
|
||||
* Loads the rollback admin page.
|
||||
*
|
||||
* @since 2.0.7
|
||||
* @return void
|
||||
*/
|
||||
public function load_admin_page() {
|
||||
/*
|
||||
* Loads the Rollback Pages
|
||||
*/
|
||||
new \WP_Ultimo\Admin_Pages\Rollback_Admin_Page();
|
||||
|
||||
} // end load_admin_page;
|
||||
|
||||
/**
|
||||
* Handle the Rollback action.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle_rollback_process() {
|
||||
|
||||
if (wu_request('action') !== 'rollback-wp-ultimo') {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* Run a couple of security checks here.
|
||||
* First we check for a valid referer and nonce.
|
||||
*/
|
||||
check_admin_referer('wp-ultimo-rollback', '_wpnonce');
|
||||
|
||||
/*
|
||||
* Then, we check for permissions.
|
||||
*/
|
||||
if (current_user_can('manage_network') === false) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* We're safe. Now we can build the URL...
|
||||
* First, reveal the API key.
|
||||
*/
|
||||
$license_key = rawurlencode(base64_decode((string) wu_request('n', '')));
|
||||
|
||||
$rollback_url = $this->get_versions_url('download', array(
|
||||
'rollback' => wu_request('type', 'latest-stable') === 'latest-stable',
|
||||
'version' => wu_request('version', wu_get_version()),
|
||||
'license_key' => $license_key,
|
||||
));
|
||||
|
||||
/*
|
||||
* Unhook shutdown hooks.
|
||||
*/
|
||||
if (class_exists(\ActionScheduler_QueueRunner::class)) {
|
||||
|
||||
\ActionScheduler_QueueRunner::instance()->unhook_dispatch_async_request();
|
||||
|
||||
} // end if;
|
||||
|
||||
$this->process_rollback(array(
|
||||
'url' => $rollback_url,
|
||||
));
|
||||
|
||||
} // end handle_rollback_process;
|
||||
|
||||
/**
|
||||
* Adds the rollback link to the WP Ultimo plugin omn the Plugin list table.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $actions Current actions.
|
||||
* @param string $plugin_file The path of the plugin file.
|
||||
* @param array $plugin_data Data about the plugin.
|
||||
* @param string $context Context of the table.
|
||||
* @return string New actions list.
|
||||
*/
|
||||
public function plugin_page_action_links($actions, $plugin_file, $plugin_data, $context) {
|
||||
|
||||
if (is_multisite() && (!is_network_admin() && !is_main_site())) {
|
||||
|
||||
return $actions;
|
||||
|
||||
} // end if;
|
||||
|
||||
if (!isset($plugin_data['Version'])) {
|
||||
|
||||
return $actions;
|
||||
|
||||
} // end if;
|
||||
|
||||
if ($plugin_file !== 'wp-multisite-waas/wp-multisite-waas.php') {
|
||||
|
||||
return $actions;
|
||||
|
||||
} // end if;
|
||||
|
||||
$actions['rollback'] = '<a href="' . wu_network_admin_url('wp-ultimo-rollback') . '">' . __('Rollback', 'wp-ultimo') . '</a>';
|
||||
|
||||
return $actions;
|
||||
|
||||
} // end plugin_page_action_links;
|
||||
|
||||
/**
|
||||
* Process the Rollback.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $args Arguments.
|
||||
* @return void
|
||||
*/
|
||||
public function process_rollback($args = array()) {
|
||||
|
||||
$plugin_file = 'wp-ultimo/wp-ultimo.php';
|
||||
|
||||
if (!class_exists(\Plugin_Upgrader_Skin::class)) {
|
||||
|
||||
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
|
||||
require_once wu_path('inc/rollback/class-rollback-plugin-upgrader.php');
|
||||
|
||||
} // end if;
|
||||
|
||||
$slug = 'wp-ultimo';
|
||||
|
||||
$nonce = "upgrade-plugin_{$slug}";
|
||||
$url = sprintf('index.php?page=wp-rollback&plugin_file=%s&action=upgrade-plugin', esc_url($plugin_file));
|
||||
|
||||
Logger::add('rollback-errors', sprintf('Rollback started... Download URL: %s', $url));
|
||||
|
||||
$plugin = $slug;
|
||||
$version = wu_get_version();
|
||||
|
||||
$title = '';
|
||||
|
||||
try {
|
||||
|
||||
$upgrader = new Rollback_Plugin_Upgrader(new Quiet_Plugin_Upgrader_Skin(compact('title', 'nonce', 'url', 'plugin', 'version')));
|
||||
|
||||
$results = $upgrader->rollback('wp-ultimo', array(
|
||||
'url' => $args['url'],
|
||||
));
|
||||
|
||||
if ($results) {
|
||||
|
||||
wp_redirect(network_admin_url('plugins.php?activate=1'));
|
||||
|
||||
exit;
|
||||
|
||||
} else {
|
||||
|
||||
$messages = implode('<br><br>', $upgrader->messages);
|
||||
|
||||
wp_die($messages);
|
||||
|
||||
} // end if;
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
// translators: %s is the error message captured.
|
||||
$error = new \WP_Error('maybe-error', sprintf(__('Something might have gone wrong doing the rollback. Check to see if the WP Ultimo version was downgraded or not on the plugins page. Error captured: %s.', 'wp-ultimo'), $e->getMessage()));
|
||||
|
||||
Logger::add('rollback-errors', $e->getMessage());
|
||||
|
||||
wp_die($error);
|
||||
|
||||
} // end try;
|
||||
|
||||
} // end process_rollback;
|
||||
|
||||
/**
|
||||
* Get the URLs we will need to use to rollback.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $action Action to add to the URL.
|
||||
* @param array $args Parameters to add.
|
||||
* @return string
|
||||
*/
|
||||
public function get_versions_url($action = 'download', $args = array()) {
|
||||
|
||||
$defaults = array(
|
||||
'version' => wu_get_version(),
|
||||
'rollback' => true,
|
||||
'license_key' => rawurlencode((string) License::get_instance()->get_license_key()),
|
||||
);
|
||||
|
||||
$url = $action === 'download' ? $this->download_url : $this->updates_url;
|
||||
|
||||
$rollback_url = add_query_arg(wp_parse_args($args, $defaults), $url);
|
||||
|
||||
return $rollback_url;
|
||||
|
||||
} // end get_versions_url;
|
||||
|
||||
/**
|
||||
* Get the available list of versions.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return array
|
||||
*/
|
||||
public function get_available_versions() {
|
||||
|
||||
$url = $this->get_versions_url('available_versions');
|
||||
|
||||
$response = wp_remote_get($url);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
|
||||
return $response;
|
||||
|
||||
} // end if;
|
||||
|
||||
$list = json_decode(wp_remote_retrieve_body($response));
|
||||
|
||||
if (is_object($list)) {
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* Clean up development builds.
|
||||
*/
|
||||
$list = array_filter($list, fn($item) => strpos((string) $item, 'beta') === false && strpos((string) $item, 'rc') === false);
|
||||
|
||||
$response_list = array();
|
||||
|
||||
$current_list = array_reverse(array_filter($list, fn($item) => strncmp((string) $item, '2.', strlen('2.')) === 0));
|
||||
|
||||
$response_list = array_slice($current_list, 0, 10);
|
||||
|
||||
if ($this->_is_legacy_network()) {
|
||||
|
||||
$legacy_list = array_reverse(array_filter($list, fn($item) => strncmp((string) $item, '1.', strlen('1.')) === 0));
|
||||
|
||||
$response_list = array_merge(array_slice($response_list, 0, 7), array_slice($legacy_list, 0, 3));
|
||||
|
||||
} // end if;
|
||||
|
||||
return $response_list;
|
||||
|
||||
} // end get_available_versions;
|
||||
|
||||
/**
|
||||
* Check if network have a legacy install to rollback.
|
||||
* FIXME: remove this and break Migrator::is_legacy_network in two methods.
|
||||
*
|
||||
* @since 2.0.11
|
||||
* @return bool
|
||||
*/
|
||||
private function _is_legacy_network() {
|
||||
|
||||
$plans = get_posts(array(
|
||||
'post_type' => 'wpultimo_plan',
|
||||
'numberposts' => 1,
|
||||
));
|
||||
|
||||
return !empty($plans);
|
||||
|
||||
} // end _is_legacy_network;
|
||||
|
||||
} // end class Rollback;
|
Reference in New Issue
Block a user