Escape everything that should be escaped. Add nonce checks where needed. Sanitize all inputs. Apply Code style changes across the codebase. Correct many deprecation notices. Optimize load order of many filters.
662 lines
15 KiB
PHP
662 lines
15 KiB
PHP
<?php
|
|
/**
|
|
* Base class that new host providers integrations must extend.
|
|
*
|
|
* @package WP_Ultimo
|
|
* @subpackage Integrations/Host_Providers
|
|
* @since 2.0.0
|
|
*/
|
|
|
|
namespace WP_Ultimo\Integrations\Host_Providers;
|
|
|
|
use WP_Ultimo\Helpers\WP_Config;
|
|
|
|
// Exit if accessed directly
|
|
defined('ABSPATH') || exit;
|
|
|
|
/**
|
|
* This base class should be extended to implement new host integrations for SSL and domains.
|
|
*/
|
|
abstract class Base_Host_Provider {
|
|
|
|
/**
|
|
* Holds the id of the integration.
|
|
*
|
|
* @var string
|
|
* @since 2.0.0
|
|
*/
|
|
protected $id;
|
|
|
|
/**
|
|
* Keeps the title of the integration.
|
|
*
|
|
* @var string
|
|
* @since 2.0.0
|
|
*/
|
|
protected $title;
|
|
|
|
/**
|
|
* Link to the tutorial teaching how to make this integration work.
|
|
*
|
|
* @var string
|
|
* @since 2.0.0
|
|
*/
|
|
protected $tutorial_link = '';
|
|
|
|
/**
|
|
* Array containing the features this integration supports.
|
|
*
|
|
* @var array
|
|
* @since 2.0.0
|
|
*/
|
|
protected $supports = [];
|
|
|
|
/**
|
|
* Constants that need to be present on wp-config.php for this integration to work.
|
|
* The values can be strings or array with constants to check for a match.
|
|
*
|
|
* @since 2.0.0
|
|
* @var array
|
|
*/
|
|
protected $constants = [];
|
|
|
|
/**
|
|
* Constants that are optional on wp-config.php.
|
|
*
|
|
* @since 2.0.0
|
|
* @var array
|
|
*/
|
|
protected $optional_constants = [];
|
|
|
|
/**
|
|
* Runs on singleton instantiation.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function init(): void {
|
|
|
|
add_filter('wu_domain_manager_get_integrations', [$this, 'self_register']);
|
|
|
|
add_action('init', [$this, 'add_to_integration_list']);
|
|
}
|
|
|
|
/**
|
|
* Loads the hooks and dependencies, but only if the hosting is enabled via is_enabled().
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
final public function __construct() {
|
|
|
|
if ($this->detect() && ! $this->is_enabled()) {
|
|
/*
|
|
* Adds an admin notice telling the admin that they should probably enable this integration.
|
|
*/
|
|
$this->alert_provider_detected();
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Only add hooks if the integration is enabled and correctly setup.
|
|
*/
|
|
if ($this->is_enabled()) {
|
|
/*
|
|
* Checks if everything was correctly setup.
|
|
*/
|
|
if ( ! $this->is_setup()) {
|
|
/*
|
|
* Adds an admin notice telling the admin that the provider is not correctly setup.
|
|
*/
|
|
$this->alert_provider_not_setup();
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Load the dependencies.
|
|
*/
|
|
$this->load_dependencies();
|
|
|
|
/*
|
|
* Initialize the hooks.
|
|
*/
|
|
$this->register_hooks();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Let the class register itself on the manager, allowing us to access the integrations later via the slug.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array $integrations List of integrations added so far.
|
|
* @return array
|
|
*/
|
|
final public function self_register($integrations) {
|
|
|
|
$integrations[ $this->get_id() ] = static::class;
|
|
|
|
return $integrations;
|
|
}
|
|
|
|
/**
|
|
* Get the list of enabled host integrations.
|
|
*
|
|
* @since 2.0.0
|
|
* @return array
|
|
*/
|
|
protected function get_enabled_list() {
|
|
|
|
return get_network_option(null, 'wu_host_integrations_enabled', []);
|
|
}
|
|
|
|
/**
|
|
* Check if this integration is enabled.
|
|
*
|
|
* @since 2.0.0
|
|
* @return boolean
|
|
*/
|
|
final public function is_enabled() {
|
|
|
|
$list = $this->get_enabled_list();
|
|
|
|
return wu_get_isset($list, $this->get_id(), false);
|
|
}
|
|
|
|
/**
|
|
* Enables this integration.
|
|
*
|
|
* @since 2.0.0
|
|
* @return boolean
|
|
*/
|
|
public function enable() {
|
|
|
|
$list = $this->get_enabled_list();
|
|
|
|
$list[ $this->get_id() ] = true;
|
|
|
|
return update_network_option(null, 'wu_host_integrations_enabled', $list);
|
|
}
|
|
|
|
/**
|
|
* Disables this integration.
|
|
*
|
|
* @since 2.0.0
|
|
* @return boolean
|
|
*/
|
|
public function disable() {
|
|
|
|
$list = $this->get_enabled_list();
|
|
|
|
$list[ $this->get_id() ] = false;
|
|
|
|
return update_network_option(null, 'wu_host_integrations_enabled', $list);
|
|
}
|
|
|
|
/**
|
|
* Adds the host to the list of integrations.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function add_to_integration_list(): void {
|
|
|
|
$slug = $this->get_id();
|
|
|
|
$html = $this->is_enabled() ? sprintf('<span class="wu-self-center wu-text-green-800 wu-mr-4"><span class="dashicons-wu-check"></span> %s</span>', __('Activated', 'wp-multisite-waas')) : '';
|
|
|
|
$url = wu_network_admin_url(
|
|
'wp-ultimo-hosting-integration-wizard',
|
|
[
|
|
'integration' => $slug,
|
|
]
|
|
);
|
|
|
|
$html .= sprintf('<a href="%s" class="button-primary">%s</a>', $url, __('Configuration', 'wp-multisite-waas'));
|
|
|
|
// translators: %s is the name of a host provider (e.g. Cloudways, WPMUDev, Closte...).
|
|
$title = sprintf(__('%s Integration', 'wp-multisite-waas'), $this->get_title());
|
|
|
|
$title .= sprintf(
|
|
"<span class='wu-normal-case wu-block wu-text-xs wu-font-normal wu-mt-1'>%s</span>",
|
|
__('Go to the setup wizard to setup this integration.', 'wp-multisite-waas')
|
|
);
|
|
|
|
wu_register_settings_field(
|
|
'integrations',
|
|
"integration_{$slug}",
|
|
[
|
|
'type' => 'note',
|
|
'title' => $title,
|
|
'desc' => $html,
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Adds an admin notice telling the admin that they should probably enable this integration.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function alert_provider_detected(): void {
|
|
|
|
if (WP_Ultimo()->is_loaded() === false) {
|
|
return;
|
|
}
|
|
|
|
// translators: %1$s will be replaced with the integration title. E.g. RunCloud
|
|
$message = sprintf(__('It looks like you are using %1$s as your hosting provider, yet the %1$s integration module is not active. In order for the domain mapping integration to work with %1$s, you might want to activate that module.', 'wp-multisite-waas'), $this->get_title());
|
|
|
|
$slug = $this->get_id();
|
|
|
|
$actions = [
|
|
'activate' => [
|
|
// translators: %s is the integration name.
|
|
'title' => sprintf(__('Activate %s', 'wp-multisite-waas'), $this->get_title()),
|
|
'url' => wu_network_admin_url(
|
|
'wp-ultimo-hosting-integration-wizard',
|
|
[
|
|
'integration' => $slug,
|
|
]
|
|
),
|
|
],
|
|
];
|
|
|
|
WP_Ultimo()->notices->add($message, 'info', 'network-admin', "should-enable-{$slug}-integration", $actions);
|
|
}
|
|
|
|
/**
|
|
* Adds an admin notice telling the admin that the provider is not correctly setup.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function alert_provider_not_setup(): void {
|
|
|
|
if (WP_Ultimo()->is_loaded() === false) {
|
|
return;
|
|
}
|
|
|
|
// translators: %1$s will be replaced with the integration title. E.g. RunCloud.
|
|
$message = sprintf(__('It looks like you are using %1$s as your hosting provider, yet the %1$s integration module was not properly setup. In order for the domain mapping integration to work with %1$s, you need to configure that module.', 'wp-multisite-waas'), $this->get_title());
|
|
|
|
$slug = $this->get_id();
|
|
|
|
$actions = [
|
|
'activate' => [
|
|
// translators: %s is the integration name
|
|
'title' => sprintf(__('Setup %s', 'wp-multisite-waas'), $this->get_title()),
|
|
'url' => wu_network_admin_url(
|
|
'wp-ultimo-hosting-integration-wizard',
|
|
[
|
|
'integration' => $slug,
|
|
'tab' => 'config',
|
|
]
|
|
),
|
|
],
|
|
];
|
|
|
|
WP_Ultimo()->notices->add($message, 'warning', 'network-admin', "should-setup-{$slug}-integration", $actions);
|
|
}
|
|
|
|
/**
|
|
* Get Fields for the integration.
|
|
*
|
|
* @since 2.0.0
|
|
* @return array
|
|
*/
|
|
public function get_fields() {
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Returns the integration id.
|
|
*
|
|
* @since 2.0.0
|
|
* @return string
|
|
*/
|
|
public function get_id() {
|
|
|
|
return $this->id;
|
|
}
|
|
|
|
/**
|
|
* Returns the integration title.
|
|
*
|
|
* @since 2.0.0
|
|
* @return string
|
|
*/
|
|
public function get_title() {
|
|
|
|
return $this->title;
|
|
}
|
|
|
|
/**
|
|
* Checks if a feature is supported, like auto-ssl for example.
|
|
*
|
|
* @since 2.0.0
|
|
* @param string $feature Feature to check.
|
|
* @return boolean
|
|
*/
|
|
public function supports($feature) {
|
|
|
|
return apply_filters('wu_hosting_support_supports', in_array($feature, $this->supports, true), $this);
|
|
}
|
|
|
|
/**
|
|
* Initializes the hooks.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function register_hooks(): void {
|
|
/*
|
|
* Hooks the event that is triggered when a new domain is added.
|
|
*/
|
|
add_action('wu_add_domain', [$this, 'on_add_domain'], 10, 2);
|
|
|
|
/*
|
|
* Hooks the event that is triggered when a domain is deleted.
|
|
*/
|
|
add_action('wu_remove_domain', [$this, 'on_remove_domain'], 10, 2);
|
|
|
|
/*
|
|
* Hooks the event that is triggered when a sub-domain is added.
|
|
*/
|
|
add_action('wu_add_subdomain', [$this, 'on_add_subdomain'], 10, 2);
|
|
|
|
/*
|
|
* Hooks the event that is triggered when a sub-domain is added.
|
|
*/
|
|
add_action('wu_remove_subdomain', [$this, 'on_remove_subdomain'], 10, 2);
|
|
|
|
/*
|
|
* Add additional hooks.
|
|
*/
|
|
$this->additional_hooks();
|
|
}
|
|
|
|
/**
|
|
* Lets integrations add additional hooks.
|
|
*
|
|
* @since 2.0.7
|
|
* @return void
|
|
*/
|
|
public function additional_hooks() {}
|
|
|
|
/**
|
|
* Can be used to load dependencies.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function load_dependencies() {}
|
|
|
|
/**
|
|
* Picks up on tips that a given host provider is being used.
|
|
*
|
|
* We use this to suggest that the user should activate an integration module.
|
|
*
|
|
* @since 2.0.0
|
|
* @return boolean
|
|
*/
|
|
abstract public function detect();
|
|
|
|
/**
|
|
* Checks if the integration is correctly setup after enabled.
|
|
*
|
|
* @since 2.0.0
|
|
* @return boolean
|
|
*/
|
|
public function is_setup() {
|
|
|
|
$all_set = true;
|
|
|
|
foreach ($this->constants as $constant) {
|
|
$constants = is_array($constant) ? $constant : [$constant];
|
|
|
|
$current = false;
|
|
|
|
foreach ($constants as $constant) {
|
|
if (defined($constant) && constant($constant)) {
|
|
$current = true;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
$all_set = $all_set && $current;
|
|
|
|
/*
|
|
* If any constant fail, bail.
|
|
*/
|
|
if (false === $all_set) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return $all_set;
|
|
}
|
|
|
|
/**
|
|
* Returns a list of missing constants configured on wp-config.php
|
|
*
|
|
* @since 2.0.14
|
|
* @return array
|
|
*/
|
|
public function get_missing_constants() {
|
|
|
|
$missing_constants = [];
|
|
|
|
foreach ($this->constants as $constant) {
|
|
$constants = is_array($constant) ? $constant : [$constant];
|
|
|
|
$current = false;
|
|
|
|
foreach ($constants as $constant) {
|
|
if (defined($constant) && constant($constant)) {
|
|
$current = true;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
$missing_constants = $current ? $missing_constants : array_merge($missing_constants, $constants);
|
|
}
|
|
|
|
return $missing_constants;
|
|
}
|
|
|
|
/**
|
|
* Returns a list of all constants, optional or not.
|
|
*
|
|
* @since 2.0.0
|
|
* @return array
|
|
*/
|
|
public function get_all_constants() {
|
|
|
|
$constants = [];
|
|
|
|
foreach ($this->constants as $constant) {
|
|
$current = is_array($constant) ? $constant : [$constant];
|
|
|
|
$constants = array_merge($constants, $current);
|
|
}
|
|
|
|
return array_merge($constants, $this->optional_constants);
|
|
}
|
|
|
|
/**
|
|
* Adds the constants with their respective values into the wp-config.php.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array $constant_values Key => Value of the necessary constants.
|
|
* @return void
|
|
*/
|
|
public function setup_constants($constant_values): void {
|
|
/*
|
|
* Important: This step is crucial, as it makes sure we clean up undesired constants.
|
|
* Removing this can allow insertion of arbitrary constants onto the wp-config.pp file
|
|
* and that should NEVER happen.
|
|
*
|
|
* Note that this is also performed on the get_constants_string.
|
|
*/
|
|
$values = shortcode_atts(array_flip($this->get_all_constants()), $constant_values);
|
|
|
|
foreach ($values as $constant => $value) {
|
|
WP_Config::get_instance()->inject_wp_config_constant($constant, $value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates a define string for manual insertion on-to wp-config.php.
|
|
*
|
|
* This is useful when the user is not willing to let WP Multisite WaaS inject the code,
|
|
* Or when the wp-config.php is not writable.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array $constant_values Key => Value of the necessary constants.
|
|
* @return string
|
|
*/
|
|
public function get_constants_string($constant_values) {
|
|
/*
|
|
* Initializes the array with an opening comment.
|
|
*/
|
|
$content = [
|
|
sprintf('// WP Multisite WaaS - Domain Mapping - %s', $this->get_title()),
|
|
];
|
|
|
|
/*
|
|
* Important: This step is crucial, as it makes sure we clean up undesired constants.
|
|
* Removing this can allow insertion of arbitrary constants onto the wp-config.php file
|
|
* and that should NEVER happen.
|
|
*/
|
|
$constant_values = shortcode_atts(array_flip($this->get_all_constants()), $constant_values);
|
|
|
|
/*
|
|
* Adds the constants, one by one.
|
|
*/
|
|
foreach ($constant_values as $constant => $value) {
|
|
$content[] = sprintf("define( '%s', '%s' );", $constant, $value);
|
|
}
|
|
|
|
/*
|
|
* Adds the final line.
|
|
*/
|
|
$content[] = sprintf('// WP Multisite WaaS - Domain Mapping - %s - End', $this->get_title());
|
|
|
|
return implode(PHP_EOL, $content);
|
|
}
|
|
|
|
/**
|
|
* Returns the explainer lines for the integration.
|
|
*
|
|
* @since 2.0.0
|
|
* @return array
|
|
*/
|
|
public function get_explainer_lines() {
|
|
|
|
$explainer_lines = [
|
|
'will' => [
|
|
// translators: %s is the name of the integration e.g. RunCloud
|
|
'send_domains' => sprintf(__('Send API calls to %s servers with domain names added to this network', 'wp-multisite-waas'), $this->get_title()),
|
|
],
|
|
'will_not' => [],
|
|
];
|
|
|
|
if ($this->supports('autossl')) {
|
|
|
|
// translators: %s is the name of the integration e.g. RunCloud
|
|
$explainer_lines['will'][] = sprintf(__('Fetch and install a SSL certificate on %s platform after the domain is added.', 'wp-multisite-waas'), $this->get_title());
|
|
} else {
|
|
|
|
// translators: %s is the name of the integration e.g. RunCloud
|
|
$explainer_lines['will_not'][] = sprintf(__('Fetch and install a SSL certificate on %s platform after the domain is added. This needs to be done manually.', 'wp-multisite-waas'), $this->get_title());
|
|
}
|
|
|
|
return $explainer_lines;
|
|
}
|
|
|
|
/**
|
|
* This method gets called when a new domain is mapped.
|
|
*
|
|
* @since 2.0.0
|
|
* @param string $domain The domain name being mapped.
|
|
* @param int $site_id ID of the site that is receiving that mapping.
|
|
* @return void
|
|
*/
|
|
abstract public function on_add_domain($domain, $site_id);
|
|
|
|
/**
|
|
* This method gets called when a mapped domain is removed.
|
|
*
|
|
* @since 2.0.0
|
|
* @param string $domain The domain name being removed.
|
|
* @param int $site_id ID of the site that is receiving that mapping.
|
|
* @return void
|
|
*/
|
|
abstract public function on_remove_domain($domain, $site_id);
|
|
|
|
/**
|
|
* This method gets called when a new subdomain is being added.
|
|
*
|
|
* This happens every time a new site is added to a network running on subdomain mode.
|
|
*
|
|
* @since 2.0.0
|
|
* @param string $subdomain The subdomain being added to the network.
|
|
* @param int $site_id ID of the site that is receiving that mapping.
|
|
* @return void
|
|
*/
|
|
abstract public function on_add_subdomain($subdomain, $site_id);
|
|
|
|
/**
|
|
* This method gets called when a new subdomain is being removed.
|
|
*
|
|
* This happens every time a new site is removed to a network running on subdomain mode.
|
|
*
|
|
* @since 2.0.0
|
|
* @param string $subdomain The subdomain being removed to the network.
|
|
* @param int $site_id ID of the site that is receiving that mapping.
|
|
* @return void
|
|
*/
|
|
abstract public function on_remove_subdomain($subdomain, $site_id);
|
|
|
|
/**
|
|
* Tests the connection with the API.
|
|
*
|
|
* Needs to be implemented by integrations.
|
|
*
|
|
* @since 2.0.0
|
|
* @return void
|
|
*/
|
|
public function test_connection(): void {
|
|
|
|
wp_send_json_success([]);
|
|
}
|
|
|
|
/**
|
|
* Returns the description of this integration.
|
|
*
|
|
* @since 2.0.0
|
|
* @return string
|
|
*/
|
|
public function get_description() {
|
|
|
|
return __('No description provided.', 'wp-multisite-waas');
|
|
}
|
|
|
|
/**
|
|
* Returns the logo for the integration.
|
|
*
|
|
* @since 2.0.0
|
|
* @return string
|
|
*/
|
|
public function get_logo() {
|
|
|
|
return '';
|
|
}
|
|
}
|