Initial Commit

This commit is contained in:
David Stone
2024-11-30 18:24:12 -07:00
commit e8f7955c1c
5432 changed files with 1397750 additions and 0 deletions

View File

@ -0,0 +1,179 @@
<?php
/**
* Helper class for domain mapping functionality.
*
* @package WP_Ultimo
* @subpackage Domain_Mapping
* @since 2.0.0
*/
namespace WP_Ultimo\Domain_Mapping;
use WP_Ultimo\Dependencies\Spatie\SslCertificate\SslCertificate;
use WP_Ultimo\Dependencies\Psr\Log\LogLevel;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Helper class for domain mapping functionality.
*
* @since 2.0.0
*/
class Helper {
/**
* List of API endpoints we can use to check the remote IP address.
*
* @var array
*/
static $providers = array(
'https://ipv4.canihazip.com/s',
'https://ipv4.icanhazip.com/',
'https://api.ipify.org/',
);
/**
* Static-only class.
*/
private function __construct() {} // end __construct;
/**
* Checks if we are in development mode.
*
* @todo this needs to be migrate somewhere else, where it can be accessed by everyone.
* @since 2.0.0
* @return boolean
*/
public static function is_development_mode() {
$site_url = site_url();
$is_development_mode = preg_match('#(localhost|staging.*\.|\.local|\.test)#', $site_url);
/**
* Allow plugin developers to add additional tests
* for development mode.
*
* @since 2.0.0
*
* @param bool $is_development_mode The current development status.
* @param string $site_url The site URL.
* @return bool
*/
return apply_filters('wu_is_development_mode', $is_development_mode, $site_url);
} // end is_development_mode;
/**
* Gets the local IP address of the network.
*
* Sometimes, this will be the same address as the public one, but we need different methods.
*
* @since 2.0.0
* @return string|bool
*/
public static function get_local_network_ip() {
return isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : false;
} // end get_local_network_ip;
/**
* Gets the public IP address of the network using an external HTTP call.
*
* The reason why this IP can't be determined locally is because proxies like
* Cloudflare and others will mask the real domain address.
* By default, we cache the values in a transient for 10 days.
*
* @since 2.0.0
* @return string
*/
public static function get_network_public_ip() {
if (self::is_development_mode()) {
$local_ip = self::get_local_network_ip();
/**
* See more about this filter below, on this same method.
*/
return apply_filters('wu_get_network_public_ip', $local_ip, true);
} // end if;
$_ip_address = get_site_transient('wu_public_network_ip');
if (!$_ip_address) {
$ip_address = false;
foreach (self::$providers as $provider_url) {
$response = wp_remote_get($provider_url, array(
'timeout' => 5,
));
if (!is_wp_error($response)) {
$ip_address = trim(wp_remote_retrieve_body($response));
continue;
} // end if;
} // end foreach;
set_site_transient('wu_public_network_ip', $ip_address, 10 * DAY_IN_SECONDS);
$_ip_address = $ip_address;
} // end if;
/**
* Allow developers to change the public IP address of the network.
*
* This is displayed to the customer/users when new domains are mapped
* and need DNS records configured.
*
* This is useful in cases where a load balancer might be present and IP might vary.
*
* @see https://wpultimo.feedbear.com/boards/bug-reports/posts/network-ip-filter-required
*
* @param string $_ip_address The public IP address.
* @param bool $local True if this is a local network (localhost, .dev, etc.), false otherwise.
* @return string The new IP address.
*/
return apply_filters('wu_get_network_public_ip', $_ip_address, false);
} // end get_network_public_ip;
/**
* Checks if a given domain name has a valid associated SSL certificate.
*
* @since 2.0.0
*
* @param string $domain Domain name, e.g. google.com.
* @return boolean
*/
public static function has_valid_ssl_certificate($domain = '') {
$is_valid = false;
try {
$certificate = SslCertificate::createForHostName($domain);
$is_valid = $certificate->isValid($domain); // returns bool;
} catch (\Exception $e) {
// translators: %s is the error message returned by the checker.
wu_log_add('domain-ssl-checks', sprintf(__('Certificate Invalid: %s', 'wp-ultimo'), $e->getMessage()), LogLevel::ERROR);
} // end try;
return $is_valid;
} // end has_valid_ssl_certificate;
} // end class Helper;

View File

@ -0,0 +1,209 @@
<?php
/**
* Handles redirects to the primary domain of a site with mappings
*
* @package WP_Ultimo
* @subpackage Domain_Mapping
* @since 2.0.0
*/
namespace WP_Ultimo\Domain_Mapping;
use WP_Ultimo\Domain_Mapping;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Handles redirects to the primary domain of a site with mappings
*
* @since 2.0.0
*/
class Primary_Domain {
use \WP_Ultimo\Traits\Singleton;
/**
* Adds the hooks
*
* @since 2.0.0
* @return void
*/
public function init() {
add_action('wu_domain_mapping_load', array($this, 'add_hooks'), -20);
} // end init;
/**
* Adds the necessary hooks.
*
* @since 2.0.0
* @return void
*/
public function add_hooks() {
add_action('template_redirect', array($this, 'redirect_to_primary_domain'));
add_action('admin_init', array($this, 'maybe_redirect_to_mapped_or_network_domain'));
add_action('login_init', array($this, 'maybe_redirect_to_mapped_or_network_domain'));
} // end add_hooks;
/**
* Redirects the site to its primary mapped domain, if any.
*
* @since 2.0.0
* @return void
*/
public function redirect_to_primary_domain() {
$should_redirect = true;
if (is_preview()) {
$should_redirect = false;
} // end if;
if (is_customize_preview()) {
$should_redirect = false;
} // end if;
/**
* Allow developers to short-circuit the redirection, preventing it
* from happening.
*
* @since 2.0.0
* @param $should_redirect If we should redirect or not.
*
* @return bool
*/
if (apply_filters('wu_should_redirect_to_primary_domain', $should_redirect) === false) {
return;
} // end if;
if (!function_exists('wu_get_domains')) {
return;
} // end if;
$domains = wu_get_domains(array(
'blog_id' => get_current_blog_id(),
'primary_domain' => 1,
'active' => 1,
'domain__not_in' => array($_SERVER['HTTP_HOST']),
));
if (empty($domains)) {
return;
} // end if;
$primary_domain = $domains[0];
if ($_SERVER['HTTP_HOST'] !== $primary_domain->get_domain() && $primary_domain->is_active()) {
$url = wu_get_current_url();
$new_url = Domain_Mapping::get_instance()->replace_url($url, $primary_domain);
wp_redirect(set_url_scheme($new_url));
exit;
} // end if;
} // end redirect_to_primary_domain;
/**
* Handles redirects to mapped ot network domain for the admin panel.
*
* @since 2.0.0
* @return void
*/
public function maybe_redirect_to_mapped_or_network_domain() {
if ($_SERVER['REQUEST_METHOD'] !== 'GET' || wp_doing_ajax()) {
return;
} // end if;
/*
* The visitor is actively trying to logout. Let them do it!
*/
if (wu_request('action', 'nothing') === 'logout' || wu_request('loggedout')) {
return;
} // end if;
$site = wu_get_current_site();
$mapped_domain = $site->get_primary_mapped_domain();
if (!$mapped_domain) {
return;
} // end if;
$redirect_settings = wu_get_setting('force_admin_redirect', 'both');
if ($redirect_settings === 'both') {
return;
} // end if;
$current_url = wp_parse_url(wu_get_current_url());
$mapped_url = wp_parse_url($mapped_domain->get_url());
$current_url_to_compare = $current_url['host'];
$mapped_url_to_compare = $mapped_url['host'];
$query_args = array();
if (wu_get_isset($current_url, 'query')) {
wp_parse_str($current_url['query'], $query_args);
} // end if;
$redirect_url = false;
if ($redirect_settings === 'force_map' && $current_url_to_compare !== $mapped_url_to_compare) {
$redirect_url = Domain_Mapping::get_instance()->replace_url(wu_get_current_url(), $mapped_domain);
$query_args = array_map(fn($value) => Domain_Mapping::get_instance()->replace_url($value, $mapped_domain), $query_args);
} elseif ($redirect_settings === 'force_network' && $current_url_to_compare === $mapped_url_to_compare) {
$redirect_url = wu_restore_original_url(wu_get_current_url(), $site->get_id());
$query_args = array_map(fn($value) => wu_restore_original_url($value, $site->get_id()), $query_args);
} // end if;
if ($redirect_url) {
wp_redirect(add_query_arg($query_args, $redirect_url));
exit;
} // end if;
} // end maybe_redirect_to_mapped_or_network_domain;
} // end class Primary_Domain;

View File

@ -0,0 +1,30 @@
<?php
/**
* Deprecated Single Sign-On.
*
* This file is here to prevent fatal errors from
* being thrown when updating from versions before 2.0.11
* to versions after 2.0.11.
*
* @deprecated
* @see \WP_Ultimo\SSO
* @package WP_Ultimo\Domain_Mapping\SSO
* @since 2.0.0
*/
namespace WP_Ultimo\Domain_Mapping\SSO;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Handles Sign-sign on.
*
* @deprecated
* @since 2.0.0
*/
class SSO {
use \WP_Ultimo\Traits\Singleton;
} // end class SSO;