detect() && ! $this->is_enabled()) { /* * Adds an admin notice telling the admin that they should probably enable this integration. */ return $this->alert_provider_detected(); } /* * 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. */ return $this->alert_provider_not_setup(); } /* * 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(' %s', __('Activated', 'wp-ultimo')) : ''; $url = wu_network_admin_url( 'wp-ultimo-hosting-integration-wizard', [ 'integration' => $slug, ] ); $html .= sprintf('%s', $url, __('Configuration', 'wp-ultimo')); // translators: %s is the name of a host provider (e.g. Cloudways, WPMUDev, Closte...). $title = sprintf(__('%s Integration', 'wp-ultimo'), $this->get_title()); $title .= sprintf( "%s", __('Go to the setup wizard to setup this integration.', 'wp-ultimo') ); 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-ultimo'), $this->get_title()); $slug = $this->get_id(); $actions = [ 'activate' => [ // translators: %s is the integration name. 'title' => sprintf(__('Activate %s', 'wp-ultimo'), $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-ultimo'), $this->get_title()); $slug = $this->get_id(); $actions = [ 'activate' => [ // translators: %s is the integration name 'title' => sprintf(__('Setup %s', 'wp-ultimo'), $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 string */ 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-ultimo'), $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-ultimo'), $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-ultimo'), $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-ultimo'); } /** * Returns the logo for the integration. * * @since 2.0.0 * @return string */ public function get_logo() { return ''; } }