Remove all code related to purchasing a license

This commit is contained in:
David Stone
2024-12-07 01:16:47 -07:00
parent 450931b405
commit d87425cfab
21 changed files with 4 additions and 4343 deletions

View File

@ -1,553 +0,0 @@
<?php
/**
* WP Multisite WaaS Dashboard Admin Page.
*
* @package WP_Ultimo
* @subpackage Admin_Pages
* @since 2.0.0
*/
namespace WP_Ultimo\Admin_Pages;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* WP Multisite WaaS Dashboard Admin Page.
*/
class Addons_Admin_Page extends Wizard_Admin_Page {
/**
* Holds the ID for this page, this is also used as the page slug.
*
* @var string
*/
protected $id = 'wp-ultimo-addons';
/**
* Is this a top-level menu or a submenu?
*
* @since 1.8.2
* @var string
*/
protected $type = 'submenu';
/**
* Menu position. This is only used for top-level menus
*
* @since 1.8.2
* @var integer
*/
protected $position = 999;
/**
* Is this a top-level menu or a submenu?
*
* @since 1.8.2
* @var string
*/
protected $parent = 'wp-ultimo';
/**
* If this number is greater than 0, a badge with the number will be displayed alongside the menu title
*
* @since 1.8.2
* @var integer
*/
protected $badge_count = 0;
/**
* Holds the admin panels where this page should be displayed, as well as which capability to require.
*
* To add a page to the regular admin (wp-admin/), use: 'admin_menu' => 'capability_here'
* To add a page to the network admin (wp-admin/network), use: 'network_admin_menu' => 'capability_here'
* To add a page to the user (wp-admin/user) admin, use: 'user_admin_menu' => 'capability_here'
*
* @since 2.0.0
* @var array
*/
protected $supported_panels = array(
'network_admin_menu' => 'wu_read_settings',
);
/**
* Should we hide admin notices on this page?
*
* @since 2.0.0
* @var boolean
*/
protected $hide_admin_notices = false;
/**
* Should we force the admin menu into a folded state?
*
* @since 2.0.0
* @var boolean
*/
protected $fold_menu = false;
/**
* Holds the section slug for the URLs.
*
* @since 2.0.0
* @var string
*/
protected $section_slug = 'tab';
/**
* Defines if the step links on the side are clickable or not.
*
* @since 2.0.0
* @var boolean
*/
protected $clickable_navigation = true;
/**
* Caches the list of add-ons.
*
* @since 2.0.0
* @var null|array
*/
protected $addons;
/**
* Allow child classes to add hooks to be run once the page is loaded.
*
* @see https://codex.wordpress.org/Plugin_API/Action_Reference/load-(page)
* @since 1.8.2
* @return void
*/
public function init() {
parent::init();
add_action('wp_ajax_serve_addons_list', array($this, 'serve_addons_list'));
} // end init;
/**
* Register forms
*
* @since 2.0.0
* @return void
*/
public function register_forms() {
wu_register_form('addon_more_info', array(
'render' => array($this, 'display_more_info'),
'handler' => array($this, 'install_addon'),
));
} // end register_forms;
/**
* Displays the more info tab.
*
* @since 2.0.0
* @return void
*/
public function display_more_info() {
$addon_slug = wu_request('addon');
$addon = wu_get_isset($this->get_addons_list(), $addon_slug);
$upgrade_url = wu_network_admin_url('wp-ultimo-pricing', array(
'checkout' => 'true',
'plan_id' => '4675',
'plan_name' => 'wpultimo',
'billing_cycle' => 'annual',
'pricing_id' => '3849',
'currency' => 'usd',
));
wu_get_template('base/addons/details', array(
'upgrade_url' => $upgrade_url,
'addon' => (object) $addon,
'addon_slug' => $addon_slug,
'license' => \WP_Ultimo\License::get_instance(),
));
do_action('wu_form_scripts', false);
} // end display_more_info;
/**
* Installs a given add-on.
*
* @since 2.0.0
* @return void
*/
public function install_addon() {
if (!current_user_can('manage_network_plugins')) {
$error = new \WP_Error('error', __('You do not have enough permissions to perform this task.', 'wp-ultimo'));
wp_send_json_error($error);
} // end if;
$addon_slug = wu_request('addon');
$addon = wu_get_isset($this->get_addons_list(), $addon_slug);
$download_url = add_query_arg(array(
'action' => 'download',
'slug' => $addon_slug,
'beta_program' => 2,
'license_key' => rawurlencode((string) \WP_Ultimo\License::get_instance()->get_license_key()),
), 'https://versions.nextpress.co/updates/');
/**
* We check if the URL is one of our websites
*/
$allowed_sites = array(
'http://nextpress.co', 'https://nextpress.co', // New Domain
'http://versions.nextpress.co', 'https://versions.nextpress.co', // New Domain
'http://weare732.com', 'https://weare732.com' // Old Updates Domain
);
if (defined('WP_DEBUG') && WP_DEBUG) {
$allowed_sites[] = 'http://localhost';
$allowed_sites[] = 'http://wp-ultimo.local';
} // end if;
$allowed = false;
foreach ($allowed_sites as $allowed_site) {
if (strncmp($download_url, $allowed_site, strlen($allowed_site)) === 0) {
$allowed = true;
break;
} // end if;
} // end foreach;
if ($allowed) {
// includes necessary for Plugin_Upgrader and Plugin_Installer_Skin
include_once(ABSPATH . 'wp-admin/includes/file.php');
include_once(ABSPATH . 'wp-admin/includes/misc.php');
include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
$skin = new \Automatic_Upgrader_Skin(array());
$upgrader = new \Plugin_Upgrader($skin);
add_filter('https_ssl_verify', '__return_false', 2000);
$results = $upgrader->install($download_url);
remove_filter('https_ssl_verify', '__return_false', 2000);
if (is_wp_error($results)) {
wp_send_json_error($results);
} // end if;
$messages = $upgrader->skin->get_upgrade_messages();
if (!in_array($upgrader->strings['process_success'], $messages, true)) {
$error = new \WP_Error('error', array_pop($messages));
wp_send_json_error($error);
} // end if;
wp_send_json_success(array(
'redirect_url' => add_query_arg(array(
's' => urlencode((string) $addon['name']),
), network_admin_url('plugins.php')),
));
} else {
$error = new \WP_Error('insecure-url', __('You are trying to download an add-on from an insecure URL', 'wp-ultimo'));
wp_send_json_error($error);
} // end if;
} // end install_addon;
/**
* Enqueue the necessary scripts.
*
* @since 2.0.0
* @return void
*/
public function register_scripts() {
wp_enqueue_style('theme');
wp_register_script('wu-addons', wu_get_asset('addons.js', 'js'), array('jquery', 'wu-vue', 'underscore'), wu_get_version(), true);
wp_localize_script('wu-addons', 'wu_addons', array(
'search' => wu_request('s', ''),
'category' => wu_request('tab', 'all'),
'i18n' => array(
'all' => __('All Add-ons', 'wp-ultimo'),
),
));
wp_enqueue_script('wu-addons');
} // end register_scripts;
/**
* Fetches the list of add-ons available.
*
* @since 2.0.0
* @return array
*/
protected function get_addons_list() {
/*
* Checks if we have a cached version.
*/
if (is_array($this->addons)) {
return $this->addons;
} // end if;
/*
* Check for local cache.
*/
if (!wu_is_debug()) {
$addons_list = get_site_transient('wu-addons-list');
if (is_array($addons_list) && !empty($addons_list)) {
$this->addons = $addons_list;
return $this->addons;
} // end if;
} // end if;
$base_url = 'https://versions.nextpress.co/updates/';
$remote_url = add_query_arg(array(
'slug' => 'wp-ultimo',
'action' => 'addons',
'installed_version' => wu_get_version(),
), $base_url);
if (defined('WP_ULTIMO_DEVELOPER_KEY') && WP_ULTIMO_DEVELOPER_KEY) {
$remote_url = add_query_arg('developer_key', WP_ULTIMO_DEVELOPER_KEY, $remote_url);
} // end if;
$response = wp_remote_get($remote_url, array(
'sslverify' => false,
));
if (is_wp_error($response)) {
return array();
} // end if;
$data = wp_remote_retrieve_body($response);
$data = json_decode($data, true);
if (!is_array($data)) {
return array();
} // end if;
/*
* Adds missing keys
*/
foreach ($data as $slug => $item) {
/*
* Checks if this is a free add-on.
*/
$item['free'] = wu_get_isset($item, 'free', false);
/*
* Checks if the plugin is installed.
*/
$item['installed'] = $this->is_plugin_installed($slug);
$this->addons[$slug] = $item;
} // end foreach;
set_transient('wu-addons-list', $this->addons, 2 * DAY_IN_SECONDS);
return $this->addons;
} // end get_addons_list;
/**
* Checks if a given plugin is installed.
*
* @since 2.0.0
* @param string $plugin_slug The plugin slug to check.
* @return boolean
*/
public function is_plugin_installed($plugin_slug) {
$plugin_keys = array_keys(get_plugins());
$installed_plugins = implode(' - ', $plugin_keys);
return stristr($installed_plugins, $plugin_slug) !== false;
} // end is_plugin_installed;
/**
* Gets the list of addons from the remote server.
*
* @since 2.0.0
* @return void
*/
public function serve_addons_list() {
$addons_list = $this->get_addons_list();
wp_send_json_success($addons_list);
} // end serve_addons_list;
/**
* Returns the title of the page.
*
* @since 2.0.0
* @return string Title of the page.
*/
public function get_title() {
return __('Add-ons', 'wp-ultimo');
} // end get_title;
/**
* Returns the title of menu for this page.
*
* @since 2.0.0
* @return string Menu label of the page.
*/
public function get_menu_title() {
return __('Add-ons', 'wp-ultimo');
} // end get_menu_title;
/**
* Every child class should implement the output method to display the contents of the page.
*
* @since 1.8.2
* @return void
*/
public function output() {
$more_info_url = wu_get_form_url('addon_more_info', array(
'width' => 768,
'addon' => 'ADDON_SLUG',
));
wu_get_template('base/addons', array(
'screen' => get_current_screen(),
'page' => $this,
'classes' => '',
'sections' => $this->get_sections(),
'current_section' => $this->get_current_section(),
'clickable_navigation' => $this->clickable_navigation,
'more_info_url' => $more_info_url,
'license' => \WP_Ultimo\License::get_instance(),
));
} // end output;
/**
* Returns the list of settings sections.
*
* @since 2.0.0
* @return array
*/
public function get_sections() {
return array(
'all' => array(
'title' => __('All Add-ons', 'wp-ultimo'),
'icon' => 'dashicons-wu-grid',
),
'premium' => array(
'title' => __('Premium', 'wp-ultimo'),
'icon' => 'dashicons-wu-rocket',
),
'free' => array(
'title' => __('Free', 'wp-ultimo'),
'icon' => 'dashicons-wu-pin',
),
'gateways' => array(
'title' => __('Gateways', 'wp-ultimo'),
'icon' => 'dashicons-wu-credit-card',
),
'growth' => array(
'title' => __('Growth & Scaling', 'wp-ultimo'),
'icon' => 'dashicons-wu-line-graph',
),
'integrations' => array(
'title' => __('Integrations', 'wp-ultimo'),
'icon' => 'dashicons-wu-power-plug',
),
'customization' => array(
'title' => __('Customization', 'wp-ultimo'),
'icon' => 'dashicons-wu-edit',
),
'admin theme' => array(
'title' => __('Admin Themes', 'wp-ultimo'),
'icon' => 'dashicons-wu-palette',
),
'monetization' => array(
'title' => __('Monetization', 'wp-ultimo'),
'icon' => 'dashicons-wu-credit',
),
'migrators' => array(
'title' => __('Migrators', 'wp-ultimo'),
'icon' => 'dashicons-wu-publish',
),
'separator' => array(
'separator' => true,
),
'marketplace' => array(
'title' => __('Marketplace', 'wp-ultimo'),
'icon' => 'dashicons-wu-shop',
),
);
} // end get_sections;
/**
* Default handler for step submission. Simply redirects to the next step.
*
* @since 2.0.0
* @return void
*/
public function default_handler() {
WP_Ultimo()->settings->save_settings($_POST);
wp_redirect(add_query_arg('updated', 1, wu_get_current_url()));
exit;
} // end default_handler;
} // end class Addons_Admin_Page;

View File

@ -12,12 +12,6 @@ namespace WP_Ultimo\Admin_Pages;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\License;
use \WP_Ultimo\Installers\Migrator;
use \WP_Ultimo\Installers\Core_Installer;
use \WP_Ultimo\Installers\Default_Content_Installer;
use \WP_Ultimo\Logger;
/**
* WP Multisite WaaS Dashboard Admin Page.
*/

View File

@ -1,170 +0,0 @@
<?php
/**
* WP Multisite WaaS Rollback Admin Page.
*
* @package WP_Ultimo
* @subpackage Admin_Pages
* @since 2.0.0
*/
namespace WP_Ultimo\Admin_Pages;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* WP Multisite WaaS Rollback Admin Page.
*/
class Rollback_Admin_Page extends Base_Admin_Page {
/**
* Holds the ID for this page, this is also used as the page slug.
*
* @var string
*/
protected $id = 'wp-ultimo-rollback';
/**
* Is this a top-level menu or a submenu?
*
* @since 1.8.2
* @var string
*/
protected $type = 'submenu';
/**
* Is this a top-level menu or a submenu?
*
* @since 1.8.2
* @var string
*/
protected $parent = 'none';
/**
* This page has no parent, so we need to highlight another sub-menu.
*
* @since 2.0.0
* @var string
*/
protected $highlight_menu_slug = 'wp-ultimo-settings';
/**
* Should we hide admin notices on this page?
*
* @since 2.0.0
* @var boolean
*/
protected $hide_admin_notices = true;
/**
* Should we force the admin menu into a folded state?
*
* @since 2.0.0
* @var boolean
*/
protected $fold_menu = false;
/**
* Holds the admin panels where this page should be displayed, as well as which capability to require.
*
* To add a page to the regular admin (wp-admin/), use: 'admin_menu' => 'capability_here'
* To add a page to the network admin (wp-admin/network), use: 'network_admin_menu' => 'capability_here'
* To add a page to the user (wp-admin/user) admin, use: 'user_admin_menu' => 'capability_here'
*
* @since 2.0.0
* @var array
*/
protected $supported_panels = array(
'network_admin_menu' => 'manage_network',
);
/**
* Creates the page with the necessary hooks.
*
* @since 1.8.2
*/
public function __construct() {
if (WP_Ultimo()->is_loaded() === false) {
$this->highlight_menu_slug = 'wp-ultimo-setup';
} // end if;
parent::__construct();
} // end __construct;
/**
* Returns the title of the page.
*
* @since 2.0.0
* @return string Title of the page.
*/
public function get_title() {
return __('Rollback', 'wp-ultimo');
} // end get_title;
/**
* Returns the title of menu for this page.
*
* @since 2.0.0
* @return string Menu label of the page.
*/
public function get_menu_title() {
return __('Rollback', 'wp-ultimo');
} // end get_menu_title;
/**
* Allows admins to rename the sub-menu (first item) for a top-level page.
*
* @since 2.0.0
* @return string False to use the title menu or string with sub-menu title.
*/
public function get_submenu_title() {
return __('Rollback', 'wp-ultimo');
} // end get_submenu_title;
/**
* Registers the necessary scripts.
*
* @since 2.0.0
* @return void
*/
public function register_scripts() {
/*
* If Ultimo is not yet loaded, we need to register vue.
*/
if (WP_Ultimo()->is_loaded() === false) {
wp_register_script('wu-vue', wu_get_asset('lib/vue.js', 'js'), false, wu_get_version());
} // end if;
wp_enqueue_script('wu-vue');
} // end register_scripts;
/**
* Every child class should implement the output method to display the contents of the page.
*
* @since 1.8.2
* @return void
*/
public function output() {
wu_get_template('rollback/rollback', array(
'n' => \WP_Ultimo\License::get_instance()->get_license_key(),
'versions' => \WP_Ultimo\Rollback\Rollback::get_instance()->get_available_versions(),
'page' => $this,
));
} // end output;
} // end class Rollback_Admin_Page;

View File

@ -135,21 +135,11 @@ class Settings_Admin_Page extends Wizard_Admin_Page {
parent::register_widgets();
wu_register_settings_side_panel('general', array(
'title' => __('Add-ons', 'wp-ultimo'),
'render' => array($this, 'render_addons_side_panel'),
));
wu_register_settings_side_panel('login-and-registration', array(
'title' => __('Checkout Forms', 'wp-ultimo'),
'render' => array($this, 'render_checkout_forms_side_panel'),
));
wu_register_settings_side_panel('integrations', array(
'title' => __('Add-ons', 'wp-ultimo'),
'render' => array($this, 'render_addons_side_panel'),
));
wu_register_settings_side_panel('sites', array(
'title' => __('Template Previewer', 'wp-ultimo'),
'render' => array($this, 'render_site_template_side_panel'),
@ -165,11 +155,6 @@ class Settings_Admin_Page extends Wizard_Admin_Page {
'render' => array($this, 'render_invoice_side_panel'),
));
wu_register_settings_side_panel('payment-gateways', array(
'title' => __('Additional Gateways', 'wp-ultimo'),
'render' => array($this, 'render_gateways_addons_side_panel'),
));
wu_register_settings_side_panel('emails', array(
'title' => __('System Emails', 'wp-ultimo'),
'render' => array($this, 'render_system_emails_side_panel'),
@ -180,172 +165,8 @@ class Settings_Admin_Page extends Wizard_Admin_Page {
'render' => array($this, 'render_email_template_side_panel'),
));
wu_register_settings_side_panel('all', array(
'title' => __('Your License', 'wp-ultimo'),
'render' => array($this, 'render_account_side_panel'),
'show' => array(\WP_Ultimo\License::get_instance(), 'is_not_whitelabel'),
));
} // end register_widgets;
// phpcs:disable
/**
* Renders the addons side panel
*
* @since 2.0.0
* @return void
*/
public function render_addons_side_panel() { ?>
<div class="wu-widget-inset">
<div class="wu-p-4">
<span class="wu-text-gray-700 wu-font-bold wu-uppercase wu-tracking-wide wu-text-xs">
<?php _e('WP Multisite WaaS Add-ons', 'wp-ultimo'); ?>
</span>
<div class="wu-py-2">
<img class="wu-w-full" alt="<?php esc_attr_e('WP Multisite WaaS Add-ons', 'wp-ultimo'); ?>" src="<?php echo wu_get_asset('sidebar/add-ons.png'); ?>">
</div>
<p class="wu-text-gray-600 wu-p-0 wu-m-0">
<?php _e('You can extend WP Multisite WaaS\'s functionality by installing one of our add-ons!', 'wp-ultimo'); ?>
</p>
</div>
<div class="wu-p-4 wu-bg-gray-100 wu-border-solid wu-border-0 wu-border-t wu-border-gray-300">
<a class="button wu-w-full wu-text-center" href="<?php echo wu_network_admin_url('wp-ultimo-addons'); ?>">
<?php _e('Check our Add-ons &rarr;', 'wp-ultimo'); ?>
</a>
</div>
</div>
<?php
} // end render_addons_side_panel;
/**
* Renders the account side panel
*
* @since 2.0.0
* @return void
*/
public function render_account_side_panel() {
$customer = \WP_Ultimo\License::get_instance()->get_customer();
$license = \WP_Ultimo\License::get_instance()->get_license();
?>
<div class="wu-widget-inset">
<?php if (empty($customer) || empty($license)) : ?>
<div class="wu-p-4">
<span class="wu-p-2 wu-bg-red-100 wu-text-red-600 wu-rounded wu-block">
<?php _e('Your copy of WP Multisite WaaS is not currently active. That means you will not have access to plugin updates and add-ons.', 'wp-ultimo'); ?>
</span>
</div>
<div class="wu-p-4 wu-bg-gray-100 wu-border-solid wu-border-0 wu-border-t wu-border-gray-300">
<a id="wu-activate-license-key-button" class="button wu-w-full wu-text-center wubox" title="<?php esc_attr_e('Activate WP Multisite WaaS', 'wp-ultimo'); ?>" href="<?php echo wu_get_form_url('license_activation'); ?>">
<?php _e('Activate WP Multisite WaaS &rarr;', 'wp-ultimo'); ?>
</a>
</div>
<?php else : ?>
<div class="wu-p-4">
<span class="wu-text-gray-700 wu-font-bold wu-uppercase wu-tracking-wide wu-text-xs">
<?php _e('Registered to', 'wp-ultimo'); ?>
</span>
<p class="wu-text-gray-700 wu-p-0 wu-m-0 wu-mt-2">
<?php printf('%s %s', $customer->first, $customer->last); ?>
<span class="wu-text-xs wu-text-gray-600 wu-block"><?php echo $customer->email; ?></span>
<span class="
wu-flex wu-items-center wu-justify-between
wu-border wu-border-solid wu-border-gray-300 wu-rounded
wu-bg-gray-100 wu-text-gray-600
wu-py-1 wu-px-2
wu-mt-3
wu-text-xs
">
<?php echo substr_replace((string) $license->secret_key, str_repeat('*', 16), 4, 24); ?>
<a
title="<?php esc_attr_e('Deactivate WP Multisite WaaS License', 'wp-ultimo'); ?>"
class="dashicons dashicons-trash wu-text-red-600 wubox"
href="<?php echo wu_get_form_url('license_deactivation'); ?>"
></a>
</span>
</p>
</div>
<!-- <?php if (current_user_can('wu_license')) : ?>
<div class="wu-p-4 wu-bg-gray-100 wu-border-solid wu-border-0 wu-border-t wu-border-gray-300">
<a id="wu-manage-account-button" class="button wu-w-full wu-text-center wubox" href="<?php echo wu_get_form_url('license_activation'); ?>">
<?php _e('Manage your Account &rarr;', 'wp-ultimo'); ?>
</a>
</div>
<?php endif; ?> -->
<?php endif; ?>
</div>
<?php
} // end render_account_side_panel;
/**
* Renders the addons side panel
*
* @since 2.0.0
* @return void
*/
public function render_gateways_addons_side_panel() { ?>
<div class="wu-widget-inset">
<div class="wu-p-4">
<span class="wu-text-gray-700 wu-font-bold wu-uppercase wu-tracking-wide wu-text-xs">
<?php _e('Accept Payments wherever you are', 'wp-ultimo'); ?>
</span>
<div class="wu-py-2">
<img class="wu-w-full" alt="<?php esc_attr_e('Accept payments wherever you are', 'wp-ultimo'); ?>" src="<?php echo wu_get_asset('sidebar/gateway-add-ons.png'); ?>">
</div>
<p class="wu-text-gray-600 wu-p-0 wu-m-0">
<?php _e('We are constantly adding support to new payment gateways that can be installed as add-ons.', 'wp-ultimo'); ?>
</p>
</div>
<div class="wu-p-4 wu-bg-gray-100 wu-border-solid wu-border-0 wu-border-t wu-border-gray-300">
<a class="button wu-w-full wu-text-center" href="<?php echo wu_network_admin_url('wp-ultimo-addons', array('tab' => 'gateways')); ?>">
<?php _e('Check our supported Gateways &rarr;', 'wp-ultimo'); ?>
</a>
</div>
</div>
<?php
} // end render_gateways_addons_side_panel;
/**
* Renders the addons side panel
*

View File

@ -12,7 +12,6 @@ namespace WP_Ultimo\Admin_Pages;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\License;
use \WP_Ultimo\Installers\Migrator;
use \WP_Ultimo\Installers\Core_Installer;
use \WP_Ultimo\Installers\Default_Content_Installer;
@ -76,22 +75,6 @@ class Setup_Wizard_Admin_Page extends Wizard_Admin_Page {
'network_admin_menu' => 'manage_network',
);
/**
* The customer license, if it exists.
*
* @since 2.0.0
* @var object
*/
public $license;
/**
* The customer object, if it exists.
*
* @since 2.0.0
* @var object
*/
public $customer;
/**
* Is this an old install migrating.
*
@ -202,10 +185,6 @@ class Setup_Wizard_Admin_Page extends Wizard_Admin_Page {
parent::page_loaded();
$this->license = \WP_Ultimo\License::get_instance()->get_license();
$this->customer = \WP_Ultimo\License::get_instance()->get_customer();
$this->set_settings();
} // end page_loaded;
@ -354,8 +333,6 @@ class Setup_Wizard_Admin_Page extends Wizard_Admin_Page {
*/
public function get_sections() {
$allowed = \WP_Ultimo\License::get_instance()->allowed();
$sections = array(
'welcome' => array(
'title' => __('Welcome', 'wp-ultimo'),
@ -434,7 +411,6 @@ class Setup_Wizard_Admin_Page extends Wizard_Admin_Page {
$message_lines = array(
'Hi there,',
sprintf('My name is %s.', $user->display_name),
sprintf('License Key: %s', License::get_instance()->get_license_key()),
'I tried to migrate my network from version 1 to version 2, but was not able to do it successfully...',
'Here are the error messages I got:',
sprintf('```%s%s%s```', PHP_EOL, implode(PHP_EOL, $errors), PHP_EOL),
@ -603,64 +579,6 @@ class Setup_Wizard_Admin_Page extends Wizard_Admin_Page {
} // end get_payment_settings;
/**
* Shows the description and possible error.
*
* @since 2.0.0
* @return string
*/
public function _desc_and_validation_error() {
ob_start();
echo __('Your license key starts with "sk_".', 'wp-ultimo');
$error = wu_request('error', false);
if ($error) :
// phpcs:disable ?>
<span class="wu-text-red-500 wu-ml-1">
&mdash; <?php echo is_string($error) ? $error : __('Invalid License Key.', 'wp-ultimo'); ?>
</span>
<?php
endif;
return ob_get_clean();
} // end _desc_and_validation_error;
/**
* Displays the block about the current license.
*
* @since 2.0.0
* @return string
*/
public function _current_license() {
ob_start();
if (\WP_Ultimo\License::get_instance()->allowed()) : // phpcs:ignore ?>
<span class="wu-py-4 wu-px-6 wu-bg-green-100 wu-block wu-text-green-500">
<?php printf(__('Your license key was already validated, %1$s. To change your license, go to our <a href="%2$s" class="wu-no-underline">Settings Page</a>.', 'wp-ultimo'), $this->customer->first, wu_network_admin_url('wp-ultimo-settings')); ?>
</span>
<?php
// phpcs:enable
endif;
return ob_get_clean();
} // end _current_license;
/**
* Render the installation steps table.
*

View File

@ -327,32 +327,6 @@ class System_Info_Admin_Page extends Base_Admin_Page {
} // end foreach;
$array_license_data = array();
$customer = \WP_Ultimo\License::get_instance()->get_customer();
$license = \WP_Ultimo\License::get_instance()->get_license();
if (!empty($customer) && !empty($license)) {
$array_license_data = array(
'username' => array(
'tooltip' => '',
'title' => 'Username',
'value' => vsprintf('%s %s', array( $customer->first, $customer->last ) ),
),
'email' => array(
'tooltip' => '',
'title' => 'E-mail',
'value' => $customer->email,
),
'license-key' => array(
'tooltip' => '',
'title' => 'License Key',
'value' => substr_replace((string) $license->secret_key, str_repeat('*', 16), 4, 24),
),
);
} // end if;
return apply_filters('wu_system_info_data', array(
'WordPress and System Settings' => array(
'wp-ultimo-version' => array(
@ -591,8 +565,6 @@ class System_Info_Admin_Page extends Base_Admin_Page {
$wpultimo_settings
),
'Defined Constants' => $array_constants,
'License' => $array_license_data
));
} // end get_data;

View File

@ -1,348 +0,0 @@
<?php
/**
* Manages WP Multisite WaaS Core Updates.
*
* @package WP_Ultimo
* @subpackage Core Updates
* @since 2.0.0
*/
namespace WP_Ultimo;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Manages WP Multisite WaaS Core Updates.
*
* @since 2.0.0
*/
class Core_Updates {
use \WP_Ultimo\Traits\Singleton;
/**
* @var string
*/
protected string $cache_key = 'wu_core_update';
/**
* @var string
*/
protected string $plugin_slug;
/**
* Use a local cache to avoid multiple requests to the API.
*
* Only disable this for debugging
*
* @var boolean
*/
protected bool $cache_allowed = true;
/**
* @var string
*/
protected string $version;
/**
* @var string
*/
protected string $plugin_id;
/**
* @var string
*/
protected string $plugin_url = 'https://wpultimo.com';
/**
* Initializes the class.
*
* @since 2.0.0
* @return void
*/
public function init() {
// Ensure we load the version even without wu_get_version available.
$this->version = class_exists(\WP_Ultimo::class) ? \WP_Ultimo::VERSION : '';
/**
* As WP Multisite WaaS needs to load in wp-ultimo/ directory to work with Sunrise
* we can assume the plugin as wp-ultimo/wp-ultimo.php. if it's a mu-plugin
* we will assume as wp-ultimo.php.
*
* At this point WPMU_PLUGIN_DIR is not defined yet.
*/
$is_mu = strpos(__DIR__, '/mu-plugins/wp-multisite-waas/') !== false;
$this->plugin_id = $is_mu ? 'wp-multisite-waas.php' : 'wp-multisite-waas/wp-multisite-waas.php';
$this->plugin_slug = 'wp-multisite-waas/wp-multisite-waas.php';
/**
* Check for a WP Multisite WaaS Core Updates.
*/
add_action('upgrader_process_complete', array($this, 'maybe_add_core_update_hooks'), 10, 2);
/**
* Update process hooks.
*/
add_filter('plugins_api', array($this, 'get_plugin_info'), 20, 3);
add_filter('site_transient_update_plugins', array($this, 'check_for_update'));
add_action('upgrader_process_complete', array($this, 'purge_update_cache'), 10, 2);
} // end init;
/**
* Checks if a WP Multisite WaaS core update is being performed and triggers an action if that's the case.
*
* @since 2.0.0
*
* @param \WP_Upgrader $u The upgrader instance.
* @param array $i Upgrade info.
* @return void
*/
public function maybe_add_core_update_hooks($u, $i) {
$is_a_wp_ultimo_update = false;
if (!empty($u->result) && in_array('wp-multisite-waas.php', $u->result['source_files'], true)) {
$is_a_wp_ultimo_update = true;
} elseif (isset($i['plugins']) && is_array($i['plugins'])) {
if (in_array('wp-multisite-waas/wp-multisite-waas.php', $i['plugins'], true)) {
$is_a_wp_ultimo_update = true;
} // end if;
} // end if;
if ($is_a_wp_ultimo_update) {
function_exists('wu_log_add') && wu_log_add('wp-ultimo-core', __('Updating WP Multisite WaaS Core...', 'wp-ultimo'));
try {
/**
* Triggers an action that be used to perform
* tasks on a core update.
*
* @since 2.0.0
*/
do_action('wu_core_update');
} catch (\Throwable $exception) {
// Nothing to do in here.
} // end try;
} // end if;
} // end maybe_add_core_update_hooks;
/**
* Override the WordPress request to return the correct plugin info.
*
* @see https://developer.wordpress.org/reference/hooks/plugins_api/
*
* @since 2.4.0
*
* @param false|object|array $result The result object or array. Default false.
* @param string $action The type of information being requested from the Plugin Install API.
* @param object $args Plugin API arguments.
* @return false|object|array
*/
public function get_plugin_info($result, $action, $args) {
if ('plugin_information' !== $action) {
return $result;
} // end if;
if ($this->plugin_slug !== $args->slug) {
return $result;
} // end if;
$remote = $this->info_request();
if (!$remote || !$remote->success || empty($remote->update)) {
return false;
} // end if;
$plugin_data = get_plugin_data(__FILE__);
$result = $remote->update;
$result->name = $plugin_data['Name'];
$result->slug = $this->plugin_slug;
$result->sections = (array) $result->sections;
return $result;
} // end get_plugin_info;
/**
* Override the WordPress request to check if an update is available.
*
* @see https://make.wordpress.org/core/2020/07/30/recommended-usage-of-the-updates-api-to-support-the-auto-updates-ui-for-plugins-and-themes-in-wordpress-5-5/
*
* @since 2.4.0
*
* @param object $transient The transient data.
* @return object
*/
public function check_for_update($transient) {
if (empty($transient->checked)) {
return $transient;
} // end if;
$res = (object) array(
'id' => $this->plugin_id,
'slug' => $this->plugin_slug,
'plugin' => $this->plugin_id,
'new_version' => $this->version,
'url' => $this->plugin_url,
'package' => '',
'icons' => array(),
'banners' => array(),
'banners_rtl' => array(),
'tested' => '',
'requires_php' => '',
'compatibility' => new \stdClass(),
);
$remote = $this->info_request();
if (
$remote && $remote->success && !empty($remote->update)
&& version_compare($this->version, $remote->update->version, '<')
) {
$res->new_version = $remote->update->version;
$res->package = property_exists($remote->update, 'download_url') ? $remote->update->download_url : '';
$transient->response[$res->plugin] = $res;
} else {
$transient->no_update[$res->plugin] = $res;
} // end if;
return $transient;
} // end check_for_update;
/**
* When the update is complete, purge the cache.
*
* @see https://developer.wordpress.org/reference/hooks/upgrader_process_complete/
*
* @since 2.4.0
*
* @param WP_Upgrader $upgrader The upgrader instance.
* @param array $options Upgrade info.
* @return void
*/
public function purge_update_cache($upgrader, $options) {
if (
$this->cache_allowed
&& 'update' === $options['action']
&& 'plugin' === $options['type']
&& !empty($options['plugins'])
) {
foreach ($options['plugins'] as $plugin) {
if ($plugin === $this->plugin_id) {
delete_transient($this->cache_key);
} // end if;
} // end foreach;
} // end if;
} // end purge_update_cache;
/**
* Fetch the update info from the remote server.
*
* @since 2.4.0
*
* @return object|bool
*/
protected function info_request() {
$license = \WP_Ultimo\License::get_instance();
$license_key = $license->get_license_key();
$remote = get_transient($this->cache_key);
if (false !== $remote && $this->cache_allowed) {
if ('error' === $remote) {
return false;
} // end if;
return json_decode($remote);
} // end if;
// WP Ultimo endpoint
$api_url = 'https://licenses.nextpress.us/api/meta/wp-ultimo/';
if ($license_key) {
$api_url = add_query_arg(array(
'license_key' => rawurlencode($license_key),
), $api_url);
} // end if;
$remote = wp_remote_get(
$api_url,
array(
'timeout' => 5,
)
);
if (
is_wp_error($remote)
|| 200 !== wp_remote_retrieve_response_code($remote)
|| empty(wp_remote_retrieve_body($remote))
) {
set_transient($this->cache_key, 'error', MINUTE_IN_SECONDS * 10);
return false;
} // end if;
$payload = wp_remote_retrieve_body($remote);
$response = new \stdClass();
$response->success = true;
$response->update = json_decode($payload);
set_transient($this->cache_key, json_encode($response), DAY_IN_SECONDS);
return $response;
} // end info_request;
} // end class Core_Updates;

View File

@ -1,692 +0,0 @@
<?php
/**
* License Handler
*
* Handles WP Multisite WaaS activation.
*
* @package WP_Ultimo
* @subpackage License
* @since 2.0.0
*/
namespace WP_Ultimo;
use WP_Site;
use WP_Ultimo\Dependencies\Psr\Log\LogLevel;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Handles WP Multisite WaaS activation.
*
* @since 2.0.0
*/
class License {
use \WP_Ultimo\Traits\Singleton;
/**
* The option key used to store the license data.
*
* @var string
*/
protected string $option_key = 'license_key';
/**
* Instantiate the necessary hooks.
*
* @since 2.0.0
* @return void
*/
public function init() {
/*
* Register forms for license activation.
*/
$this->register_forms();
$this->setup_activator();
} // end init;
/**
* Request a support signature to the API.
*
* This confirms ownership of the license and allows us
* to display past conversations with confidence that the
* customer is who they say they is.
*
* @since 2.0.7
* @return string|\WP_Error
*/
public function request_support_signature() {
$signature_url = wu_with_license_key('https://api.wpultimo.com/signature');
$response = wp_remote_get($signature_url);
if (is_wp_error($response)) {
return $response;
} // end if;
$body = wp_remote_retrieve_body($response);
$data = (array) json_decode($body, true);
$signature = wu_get_isset($data, 'signature', 'no_signature');
return $signature;
} // end request_support_signature;
/**
* Registers the form and handler to license activation.
*
* @since 2.0.0
* @return void
*/
public function register_forms() {
if (function_exists('wu_register_form')) {
add_filter('removable_query_args', array($this, 'add_activation_to_removable_query_list'));
add_action('load-wp-ultimo_page_wp-ultimo-settings', array($this, 'add_successful_activation_message'));
wu_register_form('license_activation', array(
'render' => array($this, 'render_activation_form'),
'handler' => array($this, 'handle_activation_form'),
));
wu_register_form('license_deactivation', array(
'render' => array($this, 'render_deactivation_form'),
'handler' => array($this, 'handle_deactivation_form'),
));
} // end if;
} // end register_forms;
/**
* Adds our query arg to the removable list.
*
* @since 2.0.0
*
* @param array $args The current list of removable query args.
* @return array
*/
public function add_activation_to_removable_query_list($args) {
$args[] = 'wp-ultimo-activation';
return $args;
} // end add_activation_to_removable_query_list;
/**
* Adds a successful message when activation is successful.
*
* @since 2.0.0
* @return void
*/
public function add_successful_activation_message() {
if (wu_request('wp-ultimo-activation') === 'success') {
WP_Ultimo()->notices->add(__('WP Multisite WaaS successfully activated!', 'wp-ultimo'), 'success', 'network-admin', false, array());
} // end if;
} // end add_successful_activation_message;
/**
* Render the license activation form.
*
* @since 2.0.0
* @return void
*/
public function render_activation_form() {
$fields = array(
'license_key' => array(
'type' => 'text',
'title' => __('Your License Key', 'wp-ultimo'),
'desc' => __('Enter your license key here. You received your license key via email when you completed your purchase. Your license key usually starts with "sk_".', 'wp-ultimo'),
'placeholder' => __('e.g. sk_******************', 'wp-ultimo'),
),
'submit_button' => array(
'type' => 'submit',
'title' => __('Activate', 'wp-ultimo'),
'placeholder' => __('Activate', 'wp-ultimo'),
'value' => 'save',
'classes' => 'button button-primary wu-w-full',
'wrapper_classes' => 'wu-items-end',
'html_attr' => array(
'v-bind:disabled' => '!confirmed',
),
),
);
$form = new \WP_Ultimo\UI\Form('total-actions', $fields, array(
'views' => 'admin-pages/fields',
'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0',
'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid',
));
$form->render();
} // end render_activation_form;
/**
* Handle license activation form submission.
*
* @since 2.0.0
* @return void
*/
public function handle_activation_form() {
$license = License::get_instance();
$activation_results = $license->activate(wu_request('license_key'));
if (isset($activation_results->error)) {
$activation_results = new \WP_Error('error', $activation_results->error);
} // end if;
if (is_wp_error($activation_results)) {
wp_send_json_error($activation_results);
} // end if;
wp_send_json_success(array(
'redirect_url' => add_query_arg('wp-ultimo-activation', 'success', wu_get_current_url()),
));
} // end handle_activation_form;
/**
* Render the license activation form.
*
* @since 2.0.0
* @return void
*/
public function render_deactivation_form() {
$fields = array(
'confirm' => array(
'type' => 'toggle',
'title' => __('Confirm the remove of your license key', 'wp-ultimo'),
'desc' => __('This action can not be undone.', 'wp-ultimo'),
'html_attr' => array(
'v-model' => 'confirmed',
),
),
'submit_button' => array(
'type' => 'submit',
'title' => __('Remove License', 'wp-ultimo'),
'value' => 'save',
'classes' => 'button button-primary wu-w-full',
'wrapper_classes' => 'wu-items-end',
'html_attr' => array(
'v-bind:disabled' => '!confirmed',
),
),
);
$form = new \WP_Ultimo\UI\Form('total-actions', $fields, array(
'views' => 'admin-pages/fields',
'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0',
'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid',
'html_attr' => array(
'data-wu-app' => 'true',
'data-state' => wu_convert_to_state(array(
'confirmed' => false,
)),
),
));
$form->render();
} // end render_deactivation_form;
/**
* Handle license activation form submission.
*
* @since 2.0.0
* @return void
*/
public function handle_deactivation_form() {
$license = License::get_instance();
if (!$this->deactivate()) {
$activation_results = new \WP_Error('error', __('Error deactivating license.', 'wp-ultimo'));
wp_send_json_error($activation_results);
} // end if;
wp_send_json_success(array(
'redirect_url' => wu_get_current_url(),
));
} // end handle_deactivation_form;
/**
* Sets up the activator instance.
*
* @since 2.0.0
* @return void
*/
protected function setup_activator() {
if (!defined('WP_ULTIMO_PLUGIN_DIR') || defined('WP_TESTS_MULTISITE')) {
return;
} // end if;
if (!(is_main_site()) && !is_network_admin()) {
return;
} // end if;
if (!$this->allowed() && defined('WP_ULTIMO_LICENSE_KEY') && WP_ULTIMO_LICENSE_KEY) {
/**
* Checks if init has run. If so, delay execution.
*
* @since 2.0.11
*/
$action = did_action('init') ? 'shutdown' : 'init';
add_action($action, function() {
$this->activate(WP_ULTIMO_LICENSE_KEY);
});
} // end if;
} // end setup_activator;
/**
* Tries to perform a license activation.
*
* @since 2.0.0
*
* @param string $license_key The customer license key.
* @return bool|\WP_Error
*/
public function activate($license_key) {
if (!$license_key) {
return new \WP_Error('missing-license', __('License key is required.', 'wp-ultimo'));
} // end if;
try {
$response = $this->license_api_request('/activate', array(
'license_key' => $license_key,
'instance_name' => defined('DOMAIN_CURRENT_SITE') ? DOMAIN_CURRENT_SITE : get_home_url(wu_get_main_site_id()),
), 'POST');
if ($response->error) {
return new \WP_Error('invalid-license', $response->error);
} // end if;
wu_save_option($this->option_key, $response);
} catch (\Throwable $e) {
wu_log_add('license', $e->getMessage(), LogLevel::ERROR);
return new \WP_Error('general-error', __('An unexpected error occurred.', 'wp-ultimo'));
} // end try;
return true;
} // end activate;
/**
* Deactivated the current license.
*
* @since 2.0.11
* @return bool
*/
public function deactivate(): bool {
try {
$license = wu_get_option($this->option_key);
if (!$license) {
return false;
} // end if;
$response = $this->license_api_request('/deactivate', array(
'license_key' => $license->secret_key,
'instance_id' => $license->instance,
), 'POST');
wu_save_option($this->option_key, false);
} catch (\Throwable $e) {
return false;
} // end try;
return true;
} // end deactivate;
/**
* Checks if this copy of the plugin was activated.
*
* @since 2.0.0
*
* @todo: Check if we should use the plan here and if we should use the product ID.
*
* @param string $plan Plan to check against.
* @return bool
*/
public function allowed($plan = 'wpultimo') {
$license = $this->get_license();
if ($this->get_license() === false) {
return false;
} // end if;
return $license->valid;
} // end allowed;
/**
* Returns the customer of the current license.
*
* @since 2.0.0
* @return object|false
*/
public function get_customer() {
$license = $this->get_license();
if ($license === false) {
return false;
} // end if;
return $license->customer;
} // end get_customer;
/**
* Returns the license object.
*
* @since 2.0.0
* @return object|false
*/
public function get_license() {
$license = wu_get_option($this->option_key, null) ?? $this->get_fs_license();
if (!$license) {
return false;
} // end if;
if ($license->timestamp + 86400 < time()) {
try {
$validated_license = $this->license_api_request('/validate', array(
'license_key' => $license->secret_key,
'instance_id' => $license->instance,
), 'POST');
} catch (\Throwable $e) {
wu_log_add('license', $e->getMessage(), LogLevel::ERROR);
return false;
} // end try;
$validated_license->secret_key = $license->secret_key;
$validated_license->instance = $license->instance;
wu_save_option($this->option_key, $validated_license);
$license = $validated_license;
} // end if;
return $license;
} // end get_license;
/**
* Returns a license based om freemius license.
*
* @return object|false
*/
protected function get_fs_license() {
$account = get_blog_option(get_main_site_id(), 'fs_accounts');
if (empty($account) || !isset($account['sites']) || !isset($account['sites']['wp-ultimo'])) {
return false;
} // end if;
$account_site = get_object_vars($account['sites']['wp-ultimo']);
$license_id = $account_site['license_id'];
$fs_accounts = get_site_option('fs_accounts', array());
$fs_id = 2963;
if (empty($fs_accounts) || !isset($fs_accounts['all_licenses']) || !isset($fs_accounts['all_licenses'][$fs_id])) {
return false;
} // end if;
$licenses = $fs_accounts['all_licenses'][$fs_id];
foreach ($licenses as $fs_license) {
$fs_license = get_object_vars($fs_license);
if ($fs_license['id'] === $license_id) {
$license = new \stdClass();
$license->timestamp = 0;
$license->secret_key = $fs_license['secret_key'];
$license->instance = $fs_license['id'];
return $license;
} // end if;
} // end foreach;
return false;
} // end get_fs_license;
/**
* Returns the license key used to activate this copy.
*
* @since 2.0.0
* @return string|false
*/
public function get_license_key() {
$license = $this->get_license();
return $license && $license->secret_key ? $license->secret_key : false;
} // end get_license_key;
/**
* Checks if the white-label mode was activated.
*
* @since 2.0.0
* @return boolean
*/
public function is_whitelabel() {
$license = $this->get_license();
return $license ? $license->is_whitelabeled : false;
} // end is_whitelabel;
/**
* Inverse of the is_whitelabel. Used in callbacks.
*
* @since 2.0.0
* @return boolean
*/
public function is_not_whitelabel() {
return !$this->is_whitelabel();
} // end is_not_whitelabel;
/**
* Returns the license key set as constant if it exists.
*
* @since 2.0.0
* @return false|string
*/
public function has_license_key_defined_as_constant() {
return defined('WP_ULTIMO_LICENSE_KEY') ? WP_ULTIMO_LICENSE_KEY : false;
} // end has_license_key_defined_as_constant;
/**
* Sends a request to license API
*
* @since 2.4.0
* @param string $endpoint Endpoint to send the call to.
* @param array $data Array containing the params to the call.
* @param string $method HTTP method to use.
* @return object
*/
protected function license_api_request(string $endpoint, array $data, $method = 'GET') {
$data['version'] = wu_get_isset($data, 'version', wu_get_version());
$url = 'https://licenses.nextpress.us/api/licenses' . $endpoint;
$post_fields = array(
'blocking' => true,
'timeout' => 10,
'method' => $method,
'body' => $data,
'headers' => array(
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
),
);
if ($method === 'GET') {
$url = add_query_arg($data, $url);
$post_fields['body'] = null;
} // end if;
$response = wp_remote_request($url, $post_fields);
if (is_wp_error($response)) {
throw new \Exception($response->get_error_message());
} // end if;
$body = json_decode(wp_remote_retrieve_body($response));
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Exception(json_last_error_msg());
} // end if;
return $this->build_license_from_response($body);
} // end license_api_request;
/**
* Build a license object from the API response.
*
* @since 2.4.0
*
* @param object $response Response from the API.
* @return object
*/
protected function build_license_from_response(object $response): object {
$status = array(
'active',
'trial',
'lifetime',
'golden-ticket',
);
$license = new \stdClass();
$license->is_whitelabeled = false;
$license->timestamp = time();
$license->secret_key = property_exists($response, 'key') ? $response->key : null;
$license->valid = property_exists($response, 'status') ? in_array($response->status, $status, true) : false;
$license->instance = property_exists($response, 'instance') ? $response->instance : null;
$license->error = property_exists($response, 'error') ? $response->error : null;
$name = explode(' ', property_exists($response, 'customer') ? $response->customer->name : '', 2);
$license->customer = new \stdClass();
$license->customer->email = property_exists($response, 'customer') ? $response->customer->email : null;
$license->customer->first = $name[0];
$license->customer->last = isset($name[1]) ? $name[1] : '';
if (!$license->valid) {
$response->status = property_exists($response, 'status') ? $response->status : null;
switch ($response->status) {
case 'expired':
$license->error = __('License key expired', 'wp-ultimo');
break;
case 'limit-quota':
$license->error = __('License key limit reached', 'wp-ultimo');
break;
default:
$license->error = __('Invalid license key', 'wp-ultimo');
break;
}
} // end if;
return $license;
} // end build_license_from_response;
} // end class License;

View File

@ -177,11 +177,6 @@ class Sunrise {
*/
\WP_Ultimo\Sunrise::load_dependencies();
/*
* Handles WP Multisite WaaS core updates
*/
\WP_Ultimo\Core_Updates::get_instance();
/*
* Adds backwards compatibility code for the domain mapping.
*/

View File

@ -1,388 +0,0 @@
<?php
/**
* Manages WP Multisite WaaS v1 Unsupported notices and other checks.
*
* @package WP_Ultimo
* @subpackage Unsupported
* @since 2.0.5
*/
namespace WP_Ultimo;
use WP_Ultimo\Installers\Migrator;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Manages WP Multisite WaaS v1 Unsupported notices and other checks.
*
* @since 2.0.5
*/
class Unsupported {
/**
* Keeps track of add-ons that if left activated would cause WP Multisite WaaS to crash.
*
* @var array
*/
protected static $unloaded = array();
/**
* Keeps track of add-ons that although supported, can be upgraded.
*
* @var array
*/
protected static $upgradeable = array();
/**
* Keeps track of add-ons that need a upgrader check install created for them.
*
* @var array
*/
protected static $to_upgrade = array();
/**
* Initializes the checks and warning messages.
*
* @since 2.0.5
* @return void
*/
public static function init() {
add_action('plugins_loaded', array('\WP_Ultimo\Unsupported', 'unload_unsupported_addons'), 0);
add_action('plugins_loaded', array('\WP_Ultimo\Unsupported', 'force_updater'), 20);
add_action('in_admin_header', array('\WP_Ultimo\Unsupported', 'maybe_add_notices'), 0);
} // end init;
/**
* Unloads add-ons that are no longer supported, when possible.
*
* @since 2.0.5
* @return void
*/
public static function unload_unsupported_addons() {
/**
* List of unsupported add-ons.
*
* The key is a class to check for the existence of the old add-on.
* The value is an array that contains the info about the callback that registers the add-on code,
* followed by a boolean flag that let's us know if there's a upload available.
*
* For historical reasons, we'll override keys as versions progress,
* just so we can have a timeline of feature parity for future comparison.
*
* @since 2.0.5 Original list.
*/
$unsupported_v1_addons = array(
/*
* @since 2.0.5
*/
'\WP_Ultimo_WC' => array('plugins_loaded', 'wu_wc_init', 10, true),
'\WU_Multiple_Logins' => false,
'\WP_Ultimo_Blocks' => array('plugins_loaded', 'wp_ultimo_blocks_init', 20, false),
'\WU_Ultimo_Domain_Seller' => array('plugins_loaded', 'wu_domain_seller_init', 1, false),
'\WP_Ultimo_PS_Migrator' => array('plugins_loaded', 'wu_ps_migrator_init', 1, false),
);
/**
* List of supported add-ons with upgrades available.
*
* @since 2.0.5
*/
$supported_but_upgradable = array(
'\WP_Ultimo_PTM',
);
foreach ($unsupported_v1_addons as $base_class => $init_info) {
if (class_exists($base_class)) {
list($hook, $function, $priority, $upgradeable) = $init_info;
self::$unloaded[] = $base_class;
if ($hook) {
remove_action($hook, $function, $priority);
} // end if;
if ($upgradeable) {
self::$to_upgrade[] = $base_class;
} // end if;
} // end if;
} // end foreach;
foreach ($supported_but_upgradable as $base_class) {
if (class_exists($base_class)) {
self::$upgradeable[] = $base_class;
self::$to_upgrade[] = $base_class;
} // end if;
} // end foreach;
} // end unload_unsupported_addons;
/**
* Install the newer version of the plugin updater for add-ons that can already be updated.
*
* @since 2.0.5
* @return void
*/
public static function force_updater() {
global $pagenow;
if ($pagenow !== 'plugins.php') {
return;
}
if (WP_Ultimo()->is_loaded() === false || !is_network_admin()) {
return;
} // end if;
$license_key = \WP_Ultimo\License::get_instance()->get_license_key();
if (!$license_key) {
return;
} // end if;
foreach (self::$to_upgrade as $addon_to_upgrade) {
$info = self::replace_with($addon_to_upgrade);
if ($info && wu_get_isset($info, 'slug', false)) {
try {
$url = add_query_arg(array(
'action' => 'get_metadata',
'slug' => $info['slug'],
'beta_program' => 2,
), 'https://versions.nextpress.co/updates/');
$url = wu_with_license_key($url);
$guess_plugin_path = WP_PLUGIN_DIR . '/' . $info['slug'] . '/' . $info['slug'] . '.php';
if (file_exists($guess_plugin_path)) {
$checker = \Puc_v4_Factory::buildUpdateChecker($url, $guess_plugin_path, $info['slug']);
} // end if;
} catch (\Throwable $exception) {
// Nothing to do.
} // end try;
} // end if;
} // end foreach;
} // end force_updater;
/**
* Maybe add necessary admin notices about installing WP Multisite WaaS version 2.
*
* @since 2.0.5
* @return void
*/
public static function maybe_add_notices() {
if (wu_request('page') === 'wp-ultimo-setup') {
return;
} // end if;
$message = array();
$plugins_page_a = sprintf('<a href="%s">%s</a>', network_admin_url('plugins.php'), __('plugins', 'wp-ultimo'));
/**
* Firstly, lets check if we already run the migration.
* We found some cases that the migration not worked as expected and the option checked in Migrator::is_migration_done()
* is not added. So for this verification we also need to see if we already run the setup.
*/
if (Migrator::is_migration_done() === false && Requirements::run_setup() === false) {
$message[] = '<p>' . __('It seems that you have not run the WP Multisite WaaS upgrader yet. That is the first thing we need to do.', 'wp-ultimo') . '</p>';
$message[] = sprintf('<a class="button" href="%s">%s</a>', network_admin_url('admin.php?page=wp-ultimo-setup'), __('Visit the Installer to finish the upgrade &rarr;', 'wp-ultimo'));
} // end if;
if (count(self::$unloaded) > 0) {
if ($message) {
$message[] = '<hr style="margin: 18px 0 10px 0;">';
} // end if;
$message[] = '<p>' . __('To make sure you do not experience any crashes on your network, we checked the add-ons installed and deactivated the ones that could cause problems in their currently installed version - or that are no longer supported.', 'wp-ultimo') . '</p><p>' . __('These add-ons include:', 'wp-ultimo') . '</p><ol>';
foreach (self::$unloaded as $unloaded_addon) {
$info = self::replace_with($unloaded_addon);
if ($info) {
$desc = sprintf($info['desc'], $plugins_page_a);
$message[] = sprintf('<li><strong>%s</strong>: %s</li>', $info['name'], $desc);
} // end if;
} // end foreach;
$message[] = '</ol>';
} // end if;
if (count(self::$upgradeable) > 0) {
$message[] = '<p>' . __('Other add-ons that you have installed at the moment are still supported, but have new versions with full compatibility with version 2.0:', 'wp-ultimo') . '</p><ol>';
foreach (self::$upgradeable as $upgradeable_addon) {
$info = self::replace_with($upgradeable_addon);
if ($info) {
$desc = sprintf($info['desc'], $plugins_page_a);
$message[] = sprintf('<li><strong>%s</strong>: %s</li>', $info['name'], $desc);
} // end if;
} // end foreach;
$message[] = '</ol>';
} // end if;
if (empty($message)) {
return;
} // end if;
if ($message && count($message) === 2) {
$message[] = '<div style="height: 12px;">&nbsp;</div>';
} // end if;
$message = array_merge(array('<p>' . __('<strong>Thanks for updating to WP Multisite WaaS version 2.0</strong>!', 'wp-ultimo') . '</p>'), $message);
$message = implode('', $message);
if (WP_Ultimo()->is_loaded()) {
WP_Ultimo()->notices->add($message, 'warning', 'network-admin');
} else {
self::fallback_admin_notice_display($message, 'warning');
} // end if;
} // end maybe_add_notices;
/**
* A fallback way to display admin notices when WP Multisite WaaS is not fully loaded yet.
*
* @since 2.0.5
*
* @param string $message The message to display.
* @param string $type The type of notice. Defaults to warning.
* @return void
*/
public static function fallback_admin_notice_display($message, $type = 'warning') {
printf('<div class="notice notice-%s">%s</div>', $type, $message);
} // end fallback_admin_notice_display;
/**
* Keeps a list of useful info for the add-ons that needed change.
*
* @since 2.0.5
*
* @param string $addon The addon to get the info for.
* @return array
*/
public static function replace_with($addon) {
$replace_with = array(
'\WP_Ultimo_WC' => array(
'name' => __('WooCommerce Integration', 'wp-ultimo'),
'replacement' => 'update',
'slug' => 'wp-ultimo-woocommerce',
'version' => '2.0.0',
// translators: %s is a link to the plugins page.
'desc' => __('A new version with full support for WP Multisite WaaS 2.0 is already out. An update will appear on your %s page.', 'wp-ultimo'),
),
'\WP_Ultimo_PTM' => array(
'name' => __('Plugin and Theme Manager', 'wp-ultimo'),
'replacement' => 'update',
'slug' => 'wp-ultimo-plugin-and-theme-manager',
'version' => '2.0.0',
// translators: %s is a link to the plugins page.
'desc' => __('Although still supported, a new version fully compatible with WP Multisite WaaS 2.0 is available. An update will appear on your %s page.', 'wp-ultimo'),
),
'\WU_Multiple_Logins' => array(
'name' => __('Multiple Accounts', 'wp-ultimo'),
'replacement' => 'core',
'version' => '2.0.0',
'desc' => __('Multiple Accounts is now part of WP Multisite WaaS core. It needs to be activated on WP Multisite WaaS → Settings → Login and Registration, though. You can safely remove this add-on after turning the new option on.', 'wp-ultimo'),
),
'\WP_Ultimo_Blocks' => array(
'name' => __('Blocks', 'wp-ultimo'),
'replacement' => 'core',
'version' => '2.0.0',
// translators: %s is a link to the plugins page.
'desc' => __('Blocks are now part of WP Multisite WaaS core, although with different blocks available. You can safely delete this add-on on your %s page.', 'wp-ultimo'),
),
'\WU_Ultimo_Domain_Seller' => array(
'name' => __('Domain Seller', 'wp-ultimo'),
'replacement' => 'soon',
'version' => '2.0.0',
'desc' => __('A new version of Domain Seller is coming out soon with full support for 2.0', 'wp-ultimo'),
),
'\WP_Ultimo_PS_Migrator' => array(
'name' => __('Pro Sites Migrator', 'wp-ultimo'),
'replacement' => 'not-planned',
'version' => false,
'desc' => __('There are no plans to release a new version of Pro Sites Migrator at the moment.', 'wp-ultimo'),
),
);
return wu_get_isset($replace_with, $addon, false);
} // end replace_with;
} // end class Unsupported;

View File

@ -116,18 +116,6 @@ final class WP_Ultimo {
*/
require_once wu_path('inc/deprecated/deprecated.php');
/**
* Runs a number of checks and instructs users coming from the previous
* version about what steps they need to take to finish the upgrade to version 2.
*
* - Links to the installer, if version 2 was not properly activated;
* - Unloads incompatible add-ons, offering explanations when available;
* - Re-adds the updater for add-ons that have new versions available.
*
* @since 2.0.5
*/
\WP_Ultimo\Unsupported::init();
/*
* The only core components we need to load
* before every other public api are the options
@ -157,11 +145,6 @@ final class WP_Ultimo {
*/
$this->settings = WP_Ultimo\Settings::get_instance();
/*
* Rollbacks Support
*/
\WP_Ultimo\Rollback\Rollback::get_instance();
/*
* Check if the WP Multisite WaaS requirements are present.
*
@ -319,7 +302,6 @@ final class WP_Ultimo {
require_once wu_path('inc/functions/sort.php');
require_once wu_path('inc/functions/debug.php');
require_once wu_path('inc/functions/reflection.php');
require_once wu_path('inc/functions/licensing.php');
require_once wu_path('inc/functions/scheduler.php');
require_once wu_path('inc/functions/session.php');
require_once wu_path('inc/functions/documentation.php');
@ -783,11 +765,6 @@ final class WP_Ultimo {
new WP_Ultimo\Admin_Pages\Webhook_Edit_Admin_Page();
/*
* Moves the addon pages to the bottom
*/
new WP_Ultimo\Admin_Pages\Addons_Admin_Page();
/*
* Loads the Jobs Pages
*/
@ -938,11 +915,6 @@ final class WP_Ultimo {
*/
WP_Ultimo\Managers\Cache_Manager::get_instance();
/*
* License handler
*/
WP_Ultimo\License::get_instance();
/**
* Loads views overrides
*/

View File

@ -1,30 +0,0 @@
<?php
/**
* Licensing Functions
*
* @package WP_Ultimo\Functions
* @since 2.0.0
*/
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Adds the license key to a given URL.
*
* @since 2.0.0
*
* @param string $url URL to attach the license key to.
* @return string
*/
function wu_with_license_key($url) {
$license_key = '';
$license = \WP_Ultimo\License::get_instance();
$license_key = $license->get_license_key();
return add_query_arg('license_key', rawurlencode((string) $license_key), $url);
} // end wu_with_license_key;

View File

@ -29,14 +29,8 @@ class Screenshot {
* @param string $domain Original site domain.
*/
public static function api_url($domain): string {
$domain = esc_url($domain);
$url = wu_with_license_key(sprintf('https://api.wpultimo.com/screenshot?url=%s', $domain));
return $url . '&ext=.png';
} // end api_url;
return 'https://image.thum.io/get/' . $domain;
}
/**
* Takes in a URL and creates it as an attachment.
*

View File

@ -1,123 +0,0 @@
<?php
/**
* WP Multisite WaaS Rollback
*
* Allows users to rollback WP Multisite WaaS to the previous stable version.
*
* @package WP_Ultimo
* @subpackage Rollback
* @since 2.0.0
*/
namespace WP_Ultimo\Rollback;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Our own upgrader skin implementation that does not display errors.
*
* @since 2.0.0
*/
class Quiet_Plugin_Upgrader_Skin extends \Plugin_Upgrader_Skin {
/**
* Silence is golden...
*
* @since 2.0.0
* @return void
*/
public function header() {} // end header;
/**
* Silence is golden...
*
* @since 2.0.0
* @return void
*/
public function footer() {} // end footer;
/**
* Print errors.
*
* @since 2.0.0
*
* @param string|WP_Error $errors Errors.
* @return void
*/
public function error($errors) {
if (is_string($errors)) {
$this->feedback($errors);
} elseif (is_wp_error($errors) && $errors->has_errors()) {
foreach ($errors->get_error_messages() as $message) {
if ($errors->get_error_data() && is_string($errors->get_error_data())) {
$this->feedback($message . ' ' . esc_html(strip_tags($errors->get_error_data())));
} else {
$this->feedback($message);
} // end if;
} // end foreach;
} // end if;
} // end error;
/**
* Passes messages down to the upgrader class.
*
* @since 2.0.0
*
* @param string $string The error message.
* @param mixed ...$args other arguments.
* @return void
*/
public function feedback($string, ...$args) {
if (isset($this->upgrader->strings[$string])) {
$string = $this->upgrader->strings[$string];
} // end if;
if (strpos((string) $string, '%') !== false) {
if ($args ) {
$args = array_map('strip_tags', $args);
$args = array_map('esc_html', $args);
$string = vsprintf($string, $args);
} // end if;
} // end if;
if (empty($string)) {
return;
} // end if;
$this->upgrader->messages[] = $string;
} // end feedback;
/**
* Removes output.
*
* @since 2.0.0
*
* @param string $type it doesn't matter.
* @return void
*/
protected function decrement_update_count($type) {} // end decrement_update_count;
} // end class Quiet_Plugin_Upgrader_Skin;

View File

@ -1,105 +0,0 @@
<?php
/**
* WP Multisite WaaS Rollback Plugin Upgrader
*
* Class that extends the WP Core Plugin_Upgrader found in core to do rollbacks.
* Modified to fit WP Multisite WaaS needs.
*
* @package WP_Ultimo
* @subpackage Rollback
* @since 2.0.0
*/
namespace WP_Ultimo\Rollback;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* WP Multisite WaaS Rollback Plugin Upgrader
*
* @since 2.0.0
*/
class Rollback_Plugin_Upgrader extends \Plugin_Upgrader {
/**
* Holds messages.
*
* @since 2.0.0
* @var array
*/
public $messages = array();
/**
* Plugin rollback.
*
* @param string $plugin Plugin Slug.
* @param array $args Arguments.
* @return mixed[]|bool|\WP_Error
*/
public function rollback($plugin, $args = array()) {
$defaults = array(
'clear_update_cache' => true,
'url' => '',
);
$parsed_args = wp_parse_args($args, $defaults);
$this->init();
$this->upgrade_strings();
// TODO: Add final check to make sure plugin exists
if (0) {
$this->skin->before();
$this->skin->set_result(false);
$this->skin->error('up_to_date');
$this->skin->after();
return false;
} // end if;
$plugin_slug = $this->skin->plugin;
$plugin_version = $this->skin->options['version'];
$url = $args['url'];
add_filter('upgrader_pre_install', array($this, 'deactivate_plugin_before_upgrade'), 10, 2);
add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4);
$this->run(array(
'package' => $url,
'destination' => WP_PLUGIN_DIR,
'clear_destination' => true,
'clear_working' => true,
'hook_extra' => array(
'plugin' => $plugin,
'type' => 'plugin',
'action' => 'update',
),
));
// Cleanup our hooks, in case something else does a upgrade on this connection.
remove_filter('upgrader_pre_install', array($this, 'deactivate_plugin_before_upgrade'));
remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'));
if (!$this->result || is_wp_error($this->result)) {
return false;
} // end if;
// Force refresh of plugin update information.
wp_clean_plugins_cache($parsed_args['clear_update_cache']);
return true;
} // end rollback;
} // end class Rollback_Plugin_Upgrader;

View File

@ -1,332 +0,0 @@
<?php
/**
* WP Multisite WaaS Rollback
*
* Allows users to rollback WP Multisite WaaS 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 Multisite WaaS 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 Multisite WaaS 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 Multisite WaaS 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;

View File

@ -10,8 +10,6 @@
namespace WP_Ultimo\UI;
use WP_Ultimo\Logger;
use WP_Ultimo\UI\Base_Element;
use WP_Ultimo\License;
// Exit if accessed directly
defined('ABSPATH') || exit;
@ -62,7 +60,7 @@ class Jumper {
*/
protected function is_jumper_enabled() {
return apply_filters('wu_is_jumper_enabled', wu_get_setting('enable_jumper', true) && License::get_instance()->allowed() && current_user_can('manage_network'));
return apply_filters('wu_is_jumper_enabled', wu_get_setting('enable_jumper', true) && current_user_can('manage_network'));
} // end is_jumper_enabled;

View File

@ -9,10 +9,6 @@
namespace WP_Ultimo\UI;
use WP_Ultimo\Logger;
use WP_Ultimo\UI\Base_Element;
use WP_Ultimo\License;
// Exit if accessed directly
defined('ABSPATH') || exit;
@ -39,7 +35,6 @@ class Toolbox {
/**
* Checks if we should add the toolbox or not.
*
* @todo fix the check for license activation.
* @since 2.0.0
* @return boolean
*/
@ -55,7 +50,7 @@ class Toolbox {
} // end if;
return apply_filters('wu_is_toolbox_enabled', wu_get_setting('enable_jumper', true) && License::get_instance()->allowed() && $can_see_toolbox && !is_network_admin());
return apply_filters('wu_is_toolbox_enabled', wu_get_setting('enable_jumper', true) && $can_see_toolbox && !is_network_admin());
} // end is_toolbox_enabled;

View File

@ -1,375 +0,0 @@
<?php
/**
* Add-ons list page.
*
* @since 2.0.0
*/
?>
<style>
body .theme-browser .theme .theme-name {
height: auto;
}
</style>
<div id="wp-ultimo-wrap" class="<?php wu_wrap_use_container() ?> wrap wu-wrap <?php echo esc_attr($classes); ?>">
<h1 class="wp-heading-inline">
<?php echo $page->get_title(); ?> <span v-cloak v-if="count > 0" class="title-count theme-count" v-text="count"></span>
<?php
/**
* You can filter the get_title_link using wu_page_list_get_title_link, see class-wu-page-list.php
*
* @since 1.8.2
*/
foreach ($page->get_title_links() as $action_link) :
$action_classes = isset($action_link['classes']) ? $action_link['classes'] : '';
?>
<a title="<?php echo esc_attr($action_link['label']); ?>" href="<?php echo esc_url($action_link['url']); ?>" class="page-title-action <?php echo esc_attr($action_classes); ?>">
<?php if ($action_link['icon']) : ?>
<span class="dashicons dashicons-<?php echo esc_attr($action_link['icon']); ?> wu-text-sm wu-align-middle wu-h-4 wu-w-4">
&nbsp;
</span>
<?php endif; ?>
<?php echo $action_link['label']; ?>
</a>
<?php endforeach; ?>
<?php
/**
* Allow plugin developers to add additional buttons to list pages
*
* @since 1.8.2
* @param WU_Page WP Multisite WaaS Page instance
*/
do_action('wu_page_addon_after_title', $page);
?>
</h1>
<?php if (wu_request('updated')) : ?>
<div id="message" class="updated notice wu-admin-notice notice-success is-dismissible below-h2">
<p><?php _e('Settings successfully saved.', 'wp-ultimo') ?></p>
</div>
<?php endif; ?>
<hr class="wp-header-end">
<form method="post">
<div id="poststuff" class="md:wu-flex">
<div class="wu-w-full md:wu-w-4/12 lg:wu-w-2/12">
<div class="wu-py-4 wu-relative" id="search-addons">
<input
type="text"
placeholder="<?php esc_attr_e('Search Add-ons', 'wp-ultimo'); ?>"
class="wu-w-full"
v-model="search"
>
</div>
<!-- Navigator -->
<ul id="addons-menu">
<li class="md:wu-hidden wu-p-4 wu-font-bold wu-uppercase wu-text-xs wu-text-gray-700">
<?php _e('Menu', 'wp-ultimo'); ?>
</li>
<?php
/**
* We need to set a couple of flags in here to control clickable navigation elements.
* This flag makes sure only steps the user already went through are clickable.
*/
$is_pre_current_section = true;
?>
<?php foreach ($sections as $section_name => $section) : ?>
<?php
/**
* Updates the flag after the current section is looped.
*/
if ($current_section === $section_name) {
$is_pre_current_section = false;
} // end if;
?>
<?php if (wu_get_isset($section, 'separator')) : ?>
<!-- Separator Item -->
<li class="wu-sticky wu-py-2 wu-px-4">&nbsp;</li>
<?php else : ?>
<!-- Menu Item -->
<li class="wu-sticky">
<!-- Menu Link -->
<a
href="<?php echo esc_url($page->get_section_link($section_name)); ?>"
class="wu-block wu-py-2 wu-px-4 wu-no-underline wu-text-sm wu-rounded wu-text-gray-600 hover:wu-text-gray-700"
:class="category === '<?php echo esc_attr($section_name); ?>' ? 'wu-bg-gray-300 wu-text-gray-800' : 'wu-text-gray-600 hover:wu-text-gray-700'"
@click.prevent="set_category('<?php echo esc_attr($section_name); ?>')"
>
<span class="<?php echo esc_attr($section['icon']); ?> wu-align-text-bottom wu-mr-1"></span>
<?php echo $section['title']; ?>
</a>
<!-- End Menu Link -->
<?php if (!empty($section['sub-sections'])) : ?>
<!-- Sub-menu -->
<ul class="classes" v-show="false" v-cloak>
<?php foreach ($section['sub-sections'] as $sub_section_name => $sub_section) : ?>
<li class="classes">
<a href="<?php echo esc_url($page->get_section_link($section_name)."#".$sub_section_name); ?>" class="wu-block wu-py-2 wu-px-4 wu-no-underline wu-text-gray-500 hover:wu-text-gray-600 wu-text-sm">
&rarr; <?php echo $sub_section['title']; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<!-- End Sub-menu -->
<?php endif; ?>
</li>
<!-- End Menu Item -->
<?php endif; ?>
<?php endforeach; ?>
</ul>
<!-- End Navigator -->
<div class="wu-mt-10 wu-p-4">
<div>
<span class="wu-bg-orange-600 wu-text-gray-100 wu-text-xs wu-inline-block wu-rounded wu-py-1 wu-px-2 wu-font-bold wu-uppercase wu-opacity-50">
<?php _e('Beta', 'wp-ultimo'); ?>
</span>
<span class="wu-block wu-mt-2 wu-text-xs wu-text-gray-600"><?php _e('Ready for testing, but not necessarily production-ready.', 'wp-ultimo'); ?></span>
</div>
<div class="wu-mt-4">
<span class="wu-bg-gray-800 wu-text-gray-200 wu-text-xs wu-inline-block wu-rounded wu-py-1 wu-px-2 wu-font-bold wu-uppercase wu-opacity-50">
<?php _e('Coming Soon', 'wp-ultimo'); ?>
</span>
<span class="wu-block wu-mt-2 wu-text-xs wu-text-gray-600"><?php _e('In active development, but not yet available.', 'wp-ultimo'); ?></span>
</div>
<div class="wu-mt-4">
<span class="wu-bg-purple-800 wu-text-gray-200 wu-text-xs wu-inline-block wu-rounded wu-py-1 wu-px-2 wu-font-bold wu-uppercase wu-opacity-50">
<?php _e('Legacy', 'wp-ultimo'); ?>
</span>
<span class="wu-block wu-mt-2 wu-text-xs wu-text-gray-600"><?php _e('Developed for 1.X, but compatible with 2.X.', 'wp-ultimo'); ?></span>
</div>
</div>
</div>
<div class="wu-w-full md:wu-w-8/12 lg:wu-w-10/12 md:wu-pl-4 metabox-holder">
<div id="wu-addon" class="wu-relative">
<!--
<div class="wp-filter" v-cloak>
<ul class="filter-links">
<li :class="category == 'all' ? '' : 'selector-inactive'">
<a
v-cloak
href="#"
:class="category == 'all' ? 'current wu-font-medium' : ''"
@click.prevent="category = 'all'"
>{{ i18n.all }}</a>
</li>
<li
v-for="_category in categories"
:class="category == _category ? '' : 'selector-inactive'"
>
<a
v-cloak
href="#"
:class="category == _category.toLowerCase() ? 'current wu-font-medium' : ''"
@click.prevent="category = _category.toLowerCase()"
>{{ _category }}</a>
</li>
</ul>
</div> -->
<div class="theme-browser rendered">
<div v-if="loading"
class="">
<?php echo wu_render_empty_state(array(
'message' => __("Loading...", 'wp-ultimo'),
'sub_message' => __('We are fetching the list of WP Multisite WaaS add-ons.', 'wp-ultimo'),
'link_url' => false,
)); ?>
</div>
<div class="themes wp-clearfix wu-grid wu-gap-6 wu-grid-cols-1 sm:wu-grid-cols-2 lg:wu-grid-cols-3">
<div
class="theme wu-col-span-1"
style="width: 100% !important; margin: 0 !important;"
tabindex="0"
v-cloak
v-for="addon in addons_list"
:data-slug="addon.slug"
>
<div class="theme-screenshot wu-bg-gray-100">
<img :class="addon.available ? '' : 'wu-opacity-50'" :src="addon.image_url" :alt="addon.name" />
</div>
<span class="wu-absolute wu-m-6 wu-bg-gray-800 wu-text-gray-200 wu-text-xs wu-inline-block wu-rounded wu-top-0 wu-right-0 wu-py-1 wu-px-2 wu-font-bold wu-uppercase" v-cloak v-if="!addon.available">
<?php _e('Coming Soon', 'wp-ultimo'); ?>
</span>
<span class="wu-absolute wu-m-6 wu-bg-purple-800 wu-text-gray-200 wu-text-xs wu-inline-block wu-rounded wu-top-0 wu-right-0 wu-py-1 wu-px-2 wu-font-bold wu-uppercase" v-cloak v-show="addon.legacy">
<?php _e('Legacy', 'wp-ultimo'); ?>
</span>
<span class="wu-absolute wu-m-6 wu-bg-orange-600 wu-text-gray-100 wu-text-xs wu-inline-block wu-rounded wu-top-0 wu-right-0 wu-py-1 wu-px-2 wu-font-bold wu-uppercase" v-cloak v-show="addon.beta">
<?php _e('Beta', 'wp-ultimo'); ?>
</span>
<a
class="more-details wubox wu-no-underline"
:title="addon.name"
:href="'<?php echo $more_info_url; ?>'.replace('ADDON_SLUG', addon.slug)"
>
<?php _e('Add-on Details', 'wp-ultimo'); ?>
</a>
<div class="theme-author">
<?php _e('By WP Ultimo', 'wp-ultimo'); ?>
</div>
<h2 class="theme-name" :id="addon.slug" :class="addon.available ? '' : 'wu-opacity-50'" >
{{ addon.name }}
<div class="wu-pt-1 wu-block">
<span
v-cloak
class="wu-text-gray-600 wu-font-normal wu-text-xs"
v-if="addon.free"
>
<?php _e('Free Add-on', 'wp-ultimo'); ?>
</span>
<span
v-cloak
class="wu-text-gray-600 wu-font-normal wu-text-xs"
v-else
>
<?php _e('Premium Add-on', 'wp-ultimo'); ?>
</span>
<span
v-cloak
class="wu-ml-2 wu-text-green-600 wu-font-normal wu-text-xs"
v-if="addon.installed"
>
<span class="dashicons-wu-check"></span>
<?php _e('Installed', 'wp-ultimo'); ?>
</span>
</div>
</h2>
</div>
</div>
</div>
<div class="theme-overlay"></div>
<div
v-cloak
v-if="! loading && addons_list.length == 0"
>
<?php echo wu_render_empty_state(array(
'message' => __("No add-ons found...", 'wp-ultimo'),
'sub_message' => __('Check the search terms or navigate between categories to see what add-ons we have available.', 'wp-ultimo'),
'link_label' => __('See all add-ons', 'wp-ultimo'),
'link_url' => remove_query_arg('tab'),
'link_classes' => '',
'link_icon' => 'dashicons-wu-reply',
)); ?>
</div>
</div>
</div>
</div>
<?php
/**
* Allow plugin developers to add scripts to the bottom of the page
*
* @since 1.8.2
* @param WU_Page WP Multisite WaaS Page instance
*/
do_action('wu_page_addon_footer', $page);
?>
</form>
</div>

View File

@ -1,712 +0,0 @@
<?php
/**
* Add-on details modal.
*
* @since 2.0.0
*/
?>
<style type="text/css">
#plugin-information {
position: static;
}
#plugin-information-footer {
height: auto !important;
}
#plugin-information-title.with-banner {
background-position: center;
background-image: url("<?php echo $addon->image_url; ?>");
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
#plugin-information-title.with-banner {
background-position: center;
background-image: url("<?php echo $addon->image_url; ?>");
}
}
</style>
<div id="plugin-information">
<div id="plugin-information-scrollable">
<div id="plugin-information-title" class="with-banner">
<div class="vignette"></div>
<h2><?php echo $addon->name; ?></h2>
</div>
<div id="plugin-information-tabs" class="with-banner">
<a name="description" href="#" class="current">
<?php _e('Description', 'wp-ultimo'); ?>
</a>
<!--
<a name="faq" href="#">
<?php _e('FAQ', 'wp-ultimo'); ?>
</a>
<a name="changelog" href="#">
<?php _e('Changelog', 'wp-ultimo'); ?>
</a>
<a name="screenshots" href="#">
<?php _e('Screenshots', 'wp-ultimo'); ?>
</a>
<a name="reviews" href="#">
<?php _e('Reviews', 'wp-ultimo'); ?>
</a>
-->
</div>
<div id="plugin-information-content" class="with-banner">
<div class="fyi">
<ul>
<li>
<strong><?php _e('Author:', 'wp-ultimo'); ?></strong>
<a class="wu-no-underline" href="<?php echo $addon->author_url; ?>" target="_blank">
<?php echo $addon->author; ?>
</a>
</li>
<!-- <li><strong>Version:</strong> 1.6</li>
<li><strong>Last Updated:</strong> 2 months ago</li>
<li>
<strong>Requires WordPress Version:</strong>
4.9 or higher
</li>
<li><strong>Compatible up to:</strong> 5.5.1</li> -->
<?php if (isset($addon->requires_version)) : ?>
<li>
<strong><?php _e('Requires WP Ultimo Version:', 'wp-ultimo'); ?></strong>
<?php echo sprintf(__('%s or higher', 'wp-ultimo'), $addon->requires_version); ?>
</li>
<?php endif; ?>
<li>
<a class="wu-no-underline" target="_blank" href="https://wpultimo.com/addons?addon=<?php echo $addon_slug; ?>">
<?php _e('See on the Oficial Site »', 'wp-ultimo'); ?>
</a>
</li>
</ul>
<!--
<h3>Average Rating</h3>
<div class="star-rating">
<span class="screen-reader-text">5.0 rating based on 890 ratings</span>
<div class="star star-full" aria-hidden="true"></div>
<div class="star star-full" aria-hidden="true"></div>
<div class="star star-full" aria-hidden="true"></div>
<div class="star star-full" aria-hidden="true"></div>
<div class="star star-full" aria-hidden="true"></div>
</div>
<p aria-hidden="true" class="fyi-description">
(based on 890 ratings)
</p>
<h3>Reviews</h3>
<p class="fyi-description">Read all reviews on WordPress.org or write your own!</p>
<div class="counter-container">
<span class="counter-label"> <a href="https://wordpress.org/support/plugin/classic-editor/reviews/?filter=5" target="_blank" aria-label="Reviews with 5 stars: 859. Opens in a new tab.">5 stars</a> </span>
<span class="counter-back">
<span class="counter-bar" style="width: 88.795505617978px;"></span>
</span>
<span class="counter-count" aria-hidden="true">859</span>
</div>
<div class="counter-container">
<span class="counter-label"> <a href="https://wordpress.org/support/plugin/classic-editor/reviews/?filter=4" target="_blank" aria-label="Reviews with 4 stars: 15. Opens in a new tab.">4 stars</a> </span>
<span class="counter-back">
<span class="counter-bar" style="width: 1.5505617977528px;"></span>
</span>
<span class="counter-count" aria-hidden="true">15</span>
</div>
<div class="counter-container">
<span class="counter-label"> <a href="https://wordpress.org/support/plugin/classic-editor/reviews/?filter=3" target="_blank" aria-label="Reviews with 3 stars: 6. Opens in a new tab.">3 stars</a> </span>
<span class="counter-back">
<span class="counter-bar" style="width: 0.62022471910112px;"></span>
</span>
<span class="counter-count" aria-hidden="true">6</span>
</div>
<div class="counter-container">
<span class="counter-label"> <a href="https://wordpress.org/support/plugin/classic-editor/reviews/?filter=2" target="_blank" aria-label="Reviews with 2 stars: 1. Opens in a new tab.">2 stars</a> </span>
<span class="counter-back">
<span class="counter-bar" style="width: 0.10337078651685px;"></span>
</span>
<span class="counter-count" aria-hidden="true">1</span>
</div>
<div class="counter-container">
<span class="counter-label"> <a href="https://wordpress.org/support/plugin/classic-editor/reviews/?filter=1" target="_blank" aria-label="Reviews with 1 star: 9. Opens in a new tab.">1 star</a> </span>
<span class="counter-back">
<span class="counter-bar" style="width: 0.93033707865169px;"></span>
</span>
<span class="counter-count" aria-hidden="true">9</span>
</div>
<h3>Contributors</h3>
<ul class="contributors">
<li>
<a href="https://profiles.wordpress.org/wordpressdotorg" target="_blank">
<img src="https://secure.gravatar.com/avatar/61ee2579b8905e62b4b4045bdc92c11a?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />WordPress.org
</a>
</li>
<li>
<a href="https://profiles.wordpress.org/azaozz" target="_blank">
<img src="https://secure.gravatar.com/avatar/4e84843ebff0918d72ade21c6ee7b1e4?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />Andrew Ozz
</a>
</li>
<li>
<a href="https://profiles.wordpress.org/melchoyce" target="_blank">
<img src="https://secure.gravatar.com/avatar/9ffb8027a6f8cb090148a2ea8310b64f?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />Mel Choyce-Dwan
</a>
</li>
<li>
<a href="https://profiles.wordpress.org/chanthaboune" target="_blank">
<img src="https://secure.gravatar.com/avatar/da526066c9f187ca1e16263158d2e9a3?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />Josepha
</a>
</li>
<li>
<a href="https://profiles.wordpress.org/alexislloyd" target="_blank">
<img src="https://secure.gravatar.com/avatar/41261ee7861fe1331bf1cd32bb24f4ea?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />Alexis Lloyd
</a>
</li>
<li>
<a href="https://profiles.wordpress.org/pento" target="_blank">
<img src="https://secure.gravatar.com/avatar/1ad9e5c98d81c6815a65dab5b6e1f669?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />Gary Pendergast
</a>
</li>
<li>
<a href="https://profiles.wordpress.org/youknowriad" target="_blank">
<img src="https://secure.gravatar.com/avatar/9929daa7594d5afa910a777ccb9e88e4?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />Riad Benguella
</a>
</li>
<li>
<a href="https://profiles.wordpress.org/desrosj" target="_blank">
<img src="https://secure.gravatar.com/avatar/f22c0ec09eb5a6df4da4239a37dbdf9d?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />Jonathan Desrosiers
</a>
</li>
<li>
<a href="https://profiles.wordpress.org/luciano-croce" target="_blank">
<img src="https://secure.gravatar.com/avatar/e598c948e82a783e0f40634c0766c965?s=36&amp;d=monsterid&amp;r=g" width="18" height="18" alt="" />luciano-croce
</a>
</li>
</ul> -->
</div>
<div id="section-holder">
<!-- Description Section -->
<div id="section-description" class="section" style="display: block; min-height: 200px;">
<?php echo $addon->description; ?>
</div>
<!-- /Description Section -->
<!-- <div id="section-faq" class="section" style="display: none;">
<h4>
Default settings
</h4>
<p></p>
<p>
When activated this plugin will restore the previous (“classic”) WordPress editor and hide the new block editor (“Gutenberg”).<br />
These settings can be changed at the Settings =&gt; Writing screen.
</p>
<p></p>
<h4>
Default settings for network installation
</h4>
<p></p>
<p>There are two options:</p>
<ul>
<li>
When network-activated this plugin will set the classic editor as default and prevent site administrators and users from changing editors.<br />
The settings can be changed and default network-wide editor can be selected on the Network Settings screen.
</li>
<li>When not network-activated each site administrator will be able to activate the plugin and choose options for their users.</li>
</ul>
<p></p>
<h4>
Cannot find the “Switch to classic editor” link
</h4>
<p></p>
<p>It is in the main block editor menu, see this <a href="https://ps.w.org/classic-editor/assets/screenshot-7.png?rev=2023480" target="_blank">screenshot</a>.</p>
<p></p>
</div> -->
<!-- <div id="section-changelog" class="section" style="display: none;">
<h4>1.6</h4>
<ul>
<li>Updated for WordPress 5.5.</li>
<li>Fixed minor issues with calling deprecated functions, needlessly registering uninstall hook, and capitalization of some strings.</li>
</ul>
<h4>1.5</h4>
<ul>
<li>Updated for WordPress 5.2 and Gutenberg 5.3.</li>
<li>Enhanced and fixed the “open posts in the last editor used to edit them” logic.</li>
<li>Fixed adding post state so it can easily be accessed from other plugins.</li>
</ul>
<h4>1.4</h4>
<ul>
<li>On network installations removed the restriction for only network activation.</li>
<li>Added support for network administrators to choose the default network-wide editor.</li>
<li>Fixed the settings link in the warning on network About screen.</li>
<li>Properly added the “Switch to classic editor” menu item to the block editor menu.</li>
</ul>
<h4>1.3</h4>
<ul>
<li>Fixed removal of the “Try Gutenberg” dashboard widget.</li>
<li>Fixed condition for displaying of the after upgrade notice on the “Whats New” screen. Shown when the classic editor is selected and users cannot switch editors.</li>
</ul>
<h4>1.2</h4>
<ul>
<li>Fixed switching editors from the Add New (post) screen before a draft post is saved.</li>
<li>Fixed typo that was appending the edit URL to the <code>classic-editor</code> query var.</li>
<li>Changed detecting of WordPress 5.0 to not use version check. Fixes a bug when testing 5.1-alpha.</li>
<li>Changed the default value of the option to allow users to switch editors to false.</li>
<li>Added disabling of the Gutenberg plugin and lowered the required WordPress version to 4.9.</li>
<li>Added <code>classic_editor_network_default_settings</code> filter.</li>
</ul>
<h4>1.1</h4>
<p>Fixed a bug where it may attempt to load the block editor for post types that do not support editor when users are allowed to switch editors.</p>
<h4>1.0</h4>
<ul>
<li>Updated for WordPress 5.0.</li>
<li>Changed all “Gutenberg” names/references to “block editor”.</li>
<li>Refreshed the settings UI.</li>
<li>
Removed disabling of the Gutenberg plugin. This was added for testing in WordPress 4.9. Users who want to continue following the development of Gutenberg in WordPress 5.0 and beyond will not need another plugin
to disable it.
</li>
<li>Added support for per-user settings of default editor.</li>
<li>Added support for admins to set the default editor for the site.</li>
<li>Added support for admins to allow users to change their default editor.</li>
<li>Added support for network admins to prevent site admins from changing the default settings.</li>
<li>Added support to store the last editor used for each post and open it next time. Enabled when users can choose default editor.</li>
<li>Added “post editor state” in the listing of posts on the Posts screen. Shows the editor that will be opened for the post. Enabled when users can choose default editor.</li>
<li>
Added <code>classic_editor_enabled_editors_for_post</code> and <code>classic_editor_enabled_editors_for_post_type</code> filters. Can be used by other plugins to control or override the editor used for a
particular post of post type.
</li>
<li>Added <code>classic_editor_plugin_settings</code> filter. Can be used by other plugins to override the settings and disable the settings UI.</li>
</ul>
<h4>0.5</h4>
<ul>
<li>Updated for Gutenberg 4.1 and WordPress 5.0-beta1.</li>
<li>Removed some functionality that now exists in Gutenberg.</li>
<li>Fixed redirecting back to the classic editor after looking at post revisions.</li>
</ul>
<h4>0.4</h4>
<ul>
<li>Fixed removing of the “Try Gutenberg” call-out when the Gutenberg plugin is not activated.</li>
<li>Fixed to always show the settings and the settings link in the plugins list table.</li>
<li>Updated the readme text.</li>
</ul>
<h4>0.3</h4>
<ul>
<li>Updated the option from a checkbox to couple of radio buttons, seems clearer. Thanks to @designsimply for the label text suggestions.</li>
<li>Some general updates and cleanup.</li>
</ul>
<h4>0.2</h4>
<ul>
<li>Update for Gutenberg 1.9.</li>
<li>Remove warning and automatic deactivation when Gutenberg is not active.</li>
</ul>
<h4>0.1</h4>
<p>Initial release.</p>
</div> -->
<!-- <div id="section-screenshots" class="section" style="display: none;">
<ol>
<li>
<a href="https://ps.w.org/classic-editor/assets/screenshot-1.png?rev=1998671" target="_blank">
<img src="https://ps.w.org/classic-editor/assets/screenshot-1.png?rev=1998671" alt="Admin settings on the Settings -> Writing screen." />
</a>
<p>Admin settings on the Settings -&gt; Writing screen.</p>
</li>
<li>
<a href="https://ps.w.org/classic-editor/assets/screenshot-2.png?rev=1998671" target="_blank">
<img src="https://ps.w.org/classic-editor/assets/screenshot-2.png?rev=1998671" alt="User settings on the Profile screen. Visible when the users are allowed to switch editors." />
</a>
<p>User settings on the Profile screen. Visible when the users are allowed to switch editors.</p>
</li>
<li>
<a href="https://ps.w.org/classic-editor/assets/screenshot-3.png?rev=1998671" target="_blank">
<img src="https://ps.w.org/classic-editor/assets/screenshot-3.png?rev=1998671" alt='"Action links" to choose alternative editor. Visible when the users are allowed to switch editors.' />
</a>
<p>"Action links" to choose alternative editor. Visible when the users are allowed to switch editors.</p>
</li>
<li>
<a href="https://ps.w.org/classic-editor/assets/screenshot-4.png?rev=1998671" target="_blank">
<img
src="https://ps.w.org/classic-editor/assets/screenshot-4.png?rev=1998671"
alt="Link to switch to the block editor while editing a post in the classic editor. Visible when the users are allowed to switch editors."
/>
</a>
<p>Link to switch to the block editor while editing a post in the classic editor. Visible when the users are allowed to switch editors.</p>
</li>
<li>
<a href="https://ps.w.org/classic-editor/assets/screenshot-5.png?rev=1998671" target="_blank">
<img
src="https://ps.w.org/classic-editor/assets/screenshot-5.png?rev=1998671"
alt="Link to switch to the classic editor while editing a post in the block editor. Visible when the users are allowed to switch editors."
/>
</a>
<p>Link to switch to the classic editor while editing a post in the block editor. Visible when the users are allowed to switch editors.</p>
</li>
<li>
<a href="https://ps.w.org/classic-editor/assets/screenshot-6.png?rev=1998671" target="_blank">
<img src="https://ps.w.org/classic-editor/assets/screenshot-6.png?rev=1998671" alt="Network settings to select the default editor for the network and allow site admins to change it." />
</a>
<p>Network settings to select the default editor for the network and allow site admins to change it.</p>
</li>
<li>
<a href="https://ps.w.org/classic-editor/assets/screenshot-7.png?rev=2023480" target="_blank">
<img src="https://ps.w.org/classic-editor/assets/screenshot-7.png?rev=2023480" alt='The "Switch to classic editor" link.' />
</a>
<p>The "Switch to classic editor" link.</p>
</li>
</ol>
</div> -->
<!-- <div id="section-reviews" class="section" style="display: none;">
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>Great!</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/sandrardillard" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/46635dba153f976268f9f9206c8de3eb?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/sandrardillard" target="_blank">sandrardillard</a> on <span class="review-date">October 4, 2020</span>
</p>
</div>
</div>
<div class="review-body">Nice tool!</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>Best Editor Out</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/rechtvanhuyssteen" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/61569e7b98df7fa0e961638f2fe4e493?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/rechtvanhuyssteen" target="_blank">rechtvanhuyssteen</a> on <span class="review-date">September 30, 2020</span>
</p>
</div>
</div>
<div class="review-body">The best, can we get it updateted for latest WP seems to conflict with some other plugins after update. Will never use another plugin except this for editing. Well done</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>Must need plugin</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/adeebc" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/68cee995a65b40da73d51818576c9007?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/adeebc" target="_blank">adeebc</a> on <span class="review-date">September 30, 2020</span>
</p>
</div>
</div>
<div class="review-body">I'm using WordPress because of this editor. Classic Editor changed my life. I'm using this plugin for more than 50 websites.</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>Must have</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/cleoni" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/1e5d1686cc26b244794744b07cb74ee4?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/cleoni" target="_blank">cleoni</a> on <span class="review-date">September 24, 2020</span>
</p>
</div>
</div>
<div class="review-body">Must have plugin. Watch out, it seems it currently does not work under WP 5.5 due to deprecated jquery methods.</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>Until at least 2022</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/kirbyfoster" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/5eda3070b8145f285e03561e7bccb249?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/kirbyfoster" target="_blank">kirbyfoster</a> on <span class="review-date">September 23, 2020</span>
</p>
</div>
</div>
<div class="review-body">
Thankfully this is still available on WP. However it states that 'Classic Editor is an official WordPress plugin, and will be fully supported and maintained until at least 2022' What's going to happen after 2022?
Am I going to have to rewrite my websites? Maybe I ought to start looking at other options instead of WP? Gutenberg is really starting to piss me off. I wish I'd never heard of WP and instead just use html/css/js
like I used to do.
</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>So much better!</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/sknydrinks" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/368188434b0840cba8c31e15a8208132?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/sknydrinks" target="_blank">sknydrinks</a> on <span class="review-date">September 21, 2020</span>
</p>
</div>
</div>
<div class="review-body">This is so much better. Thank you!</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>Please go back to Classic Editor</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/passegua" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/4c8f34536195de842099db7de654dc64?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/passegua" target="_blank">passegua</a> on <span class="review-date">September 17, 2020</span>
</p>
</div>
</div>
<div class="review-body">Please get rid of Gutenberg horrible Block Editor! Please ask WordPress user about it, no one uses block editor! Please please go back to the beautiful classic editor!</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>BROKEN</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-empty"></span><span class="star dashicons dashicons-star-empty"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/lexiol" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/06251c1360f2d474b199c130c7ce509c?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/lexiol" target="_blank">Lexiol</a> on <span class="review-date">September 13, 2020</span>
</p>
</div>
</div>
<div class="review-body">Not sure how to remove my review</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>I still use the classic editor</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/janejsmaster" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/8a823e5639bc30c2ac79be5168d82285?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/janejsmaster" target="_blank">Jane (janejsmaster)</a> on <span class="review-date">September 10, 2020</span>
</p>
</div>
</div>
<div class="review-body">
I still prefer the classic editor compared to the Gutenberg one. The classic editor is what we have used for years and I hope it will always be maintained by its developers. Many of us still depend on it
everyday.
</div>
</div>
<div class="review">
<div class="review-head">
<div class="reviewer-info">
<div class="review-title-section">
<h4>Gave up</h4>
<div class="star-rating">
<div class="wporg-ratings">
<span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span><span class="star dashicons dashicons-star-filled"></span>
<span class="star dashicons dashicons-star-empty"></span><span class="star dashicons dashicons-star-empty"></span>
</div>
</div>
</div>
<p>
By
<a href="https://profiles.wordpress.org/kielce" target="_blank">
<img alt="" src="https://secure.gravatar.com/avatar/036809f4dfd63fcf041af812ac28a4cb?s=16&amp;d=monsterid&amp;r=g" class="avatar avatar-16 photo" />
</a>
<a href="https://profiles.wordpress.org/kielce" target="_blank">kielce</a> on <span class="review-date">September 8, 2020</span>
</p>
</div>
</div>
<div class="review-body">I gave up on Classic Editor and shifted to the "Disable Gutenberg" plugin months ago. "Disable Gutenberg" has no issues with the WordPress 5.5 update.</div>
</div>
</div> -->
</div>
</div>
</div>
<div id="plugin-information-footer">
<?php if (!$addon->free) : ?>
<span class="wu-text-green-800 wu-inline-block wu-py-1">
<?php _e('This is a Premium Add-on.', 'wp-ultimo'); ?>
</span>
<?php endif; ?>
<form id="plugin-install" class="wu_form">
<?php if ($addon->installed) : ?>
<button
disabled="disabled"
data-slug="<?php echo $addon_slug; ?>"
class="button button-disabled right"
>
<?php _e('Already Installed', 'wp-ultimo'); ?>
</button>
<?php else : ?>
<?php if ($addon->available) : ?>
<?php if ($license->allowed('wpultimo') || $addon->free) : ?>
<button
type="submit"
name="install"
data-slug="<?php echo $addon_slug; ?>"
class="button button-primary right"
>
<?php _e('Install Now', 'wp-ultimo'); ?>
</button>
<?php else : ?>
<a
href="<?php echo $upgrade_url; ?>"
class="button button-primary right"
>
<?php _e('Upgrade your License', 'wp-ultimo'); ?>
</a>
<?php endif; ?>
<?php endif; ?>
<input type="hidden" name="action" value="wu_form_handler">
<input type="hidden" name="addon" value="<?php echo $addon_slug; ?>">
<input type="hidden" name="wu-when" value="<?php echo base64_encode('after_setup_theme'); ?>">
<?php wp_nonce_field('wu_form_addon_more_info'); ?>
<?php endif; ?>
</div>
</div>

View File

@ -1,170 +0,0 @@
<?php
/**
* Rollback view.
*
* @since 2.0.0
*/
?>
<div id="wp-ultimo-wrap" class="<?php wu_wrap_use_container(); ?> wrap wu-wrap">
<h1 class="wp-heading-inline">
<?php echo $page->get_title(); ?>
<?php
/**
* You can filter the get_title_link using wu_page_list_get_title_link, see class-wu-page-list.php
*
* @since 1.8.2
*/
foreach ($page->get_title_links() as $action_link) :
$action_classes = isset($action_link['classes']) ? $action_link['classes'] : '';
?>
<a title="<?php echo esc_attr($action_link['label']); ?>" href="<?php echo esc_url($action_link['url']); ?>" class="page-title-action <?php echo esc_attr($action_classes); ?>">
<?php if ($action_link['icon']) : ?>
<span class="dashicons dashicons-<?php echo esc_attr($action_link['icon']); ?> wu-text-sm wu-align-middle wu-h-4 wu-w-4">
&nbsp;
</span>
<?php endif; ?>
<?php echo $action_link['label']; ?>
</a>
<?php endforeach; ?>
<?php
/**
* Allow plugin developers to add
*
* @since 1.8.2
* @param WU_Page WP Multisite WaaS Page instance
*/
do_action('wu_page_rollback_after_title', $page);
?>
</h1>
<form method="post" action="<?php echo network_admin_url('admin.php'); ?>">
<table class="form-table">
<tbody>
<tr>
<th scope="row"><?php _e('Rollback to', 'wp-ultimo'); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text">
<span><?php _e('Rollback to', 'wp-ultimo'); ?></span>
</legend>
<p>
<label>
<input name="type" type="radio" value="latest-stable" v-model="type">
<?php printf(__('Last stable version before the currently installed - Currently Installed: <code> %s </code>', 'wp-ultimo'), WP_Ultimo()->version); ?>
</label>
<br>
<label>
<input name="type" type="radio" value="select-version" v-model="type">
<?php _e('Select the version manually', 'wp-ultimo'); ?>
</label>
</p>
</fieldset>
</td>
</tr>
<tr v-cloak v-if="type== 'select-version'">
<th scope="row"><?php _e('Available Versions', 'wp-ultimo'); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text">
<span><?php _e('Available Versions', 'wp-ultimo'); ?></span>
</legend>
<p>
<?php if (is_array($versions)) : ?>
<?php foreach ($versions as $version) : ?>
<label>
<input name="version" type="radio" value="<?php echo $version; ?>" v-model="version" <?php disabled($version == WP_Ultimo()->version); ?>>
<code><?php echo $version; ?></code>
<?php echo $version == WP_Ultimo()->version ? __(' - Current Version', 'wp-ultimo') : ''; ?>
</label>
<br>
<?php endforeach; ?>
<?php else : ?>
<label>
<?php _e('You need to activate your copy to have access to Rollbacks.', 'wp-ultimo'); ?>
</label>
<?php endif; ?>
</p>
</fieldset>
</td>
</tr>
<tr v-cloak v-if="type == 'latest-stable' || (type == 'select-version' && version)">
<th scope="row"><?php _e('Confirm Rollback', 'wp-ultimo'); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text"><span><?php _e('Confirm Rollback', 'wp-ultimo'); ?></span></legend>
<?php if (is_array($versions)) : ?>
<label for="confirm">
<input v-model="confirm" name="confirm" type="checkbox" id="confirm" value="0">
<span v-if="version">
<?php printf(__('I understand the risks and I want to rollback to WP Ultimo version %s', 'wp-ultimo'), '<code>{{version}}</code>'); ?>
</span>
<span v-if="!version">
<?php printf(__('I understand the risks and I want to rollback to the last stable version before <code> %s </code>', 'wp-ultimo'), WP_Ultimo()->version); ?>
</span>
</label>
<?php else : ?>
<label>
<?php _e('You need to activate your copy to have access to Rollbacks.', 'wp-ultimo'); ?>
</label>
<?php endif; ?>
</fieldset>
</td>
</tr>
</tbody>
</table>
<?php wp_nonce_field('wp-ultimo-rollback'); ?>
<input type="hidden" name="action" value="rollback-wp-ultimo">
<input type="hidden" name="n" value="<?php echo esc_attr(base64_encode($n)); ?>">
<p class="submit">
<input v-on:click="block" v-bind:disabled="!confirm" type="submit" name="submit" id="submit" class="button button-primary button-large wu-ml-auto"
value="<?php _e('Rollback', 'wp-ultimo'); ?>">
</p>
</form>
</div>
<script>
(function($) {
$(document).ready(function() {
rollback = new Vue({
el: '#wp-ultimo-wrap',
data: {
confirm: false,
type: <?php echo json_encode(wu_request('type', false)); ?>,
version: <?php echo json_encode(wu_request('version', wu_get_version())); ?>,
},
methods: {
block: function() {
wu_block_ui('#wpcontent');
}
}
});
});
})(jQuery);
</script>