2025-03-16 01:03:10 +08:00
< ? php
/**
* Plugin Name : WP Domain Mapping
2025-03-21 11:00:48 +08:00
* Plugin URI : https :// wenpai . org / plugins / wp - domain - mapping /
2025-03-16 01:03:10 +08:00
* Description : Map any site on a WordPress website to another domain with enhanced management features .
2025-05-20 22:52:24 +08:00
* Version : 2.0 . 0
2025-03-16 01:03:10 +08:00
* Author : WPDomain . com
* Author URI : https :// wpdomain . com /
* Network : true
* License : GPL v2 or later
* License URI : https :// www . gnu . org / licenses / gpl - 2.0 . html
* Text Domain : wp - domain - mapping
* Domain Path : / languages
* Requires at least : 6.7 . 2
*/
2025-05-20 22:52:24 +08:00
// Prevent direct access
if ( ! defined ( 'ABSPATH' ) ) {
2025-04-15 09:58:06 +08:00
exit ;
}
2025-05-20 22:52:24 +08:00
// Define plugin constants
define ( 'WP_DOMAIN_MAPPING_VERSION' , '2.0.0' );
define ( 'WP_DOMAIN_MAPPING_DIR_URL' , plugin_dir_url ( __FILE__ ) );
define ( 'WP_DOMAIN_MAPPING_DIR_PATH' , plugin_dir_path ( __FILE__ ) );
define ( 'WP_DOMAIN_MAPPING_BASENAME' , plugin_basename ( __FILE__ ) );
2025-04-15 09:58:06 +08:00
2025-05-20 22:52:24 +08:00
/**
* Main Domain Mapping Class
*
* Handles the core functionality of the plugin
*/
class WP_Domain_Mapping {
/**
* Plugin instance
*
* @ var WP_Domain_Mapping
*/
private static $instance = null ;
/**
* Database table names
*
* @ var array
*/
private $tables = array ();
/**
* Get plugin instance
*
* @ return WP_Domain_Mapping
*/
public static function get_instance () {
if ( null === self :: $instance ) {
self :: $instance = new self ();
}
return self :: $instance ;
}
2025-04-15 09:58:06 +08:00
2025-05-20 22:52:24 +08:00
/**
* Constructor
*/
private function __construct () {
global $wpdb ;
// Define table name constants if not already defined
if ( ! defined ( 'WP_DOMAIN_MAPPING_TABLE_DOMAINS' ) ) {
define ( 'WP_DOMAIN_MAPPING_TABLE_DOMAINS' , 'domain_mapping' );
define ( 'WP_DOMAIN_MAPPING_TABLE_LOGINS' , 'domain_mapping_logins' );
define ( 'WP_DOMAIN_MAPPING_TABLE_LOGS' , 'domain_mapping_logs' );
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Set up table names
$this -> tables = array (
'domains' => $wpdb -> base_prefix . WP_DOMAIN_MAPPING_TABLE_DOMAINS ,
'logins' => $wpdb -> base_prefix . WP_DOMAIN_MAPPING_TABLE_LOGINS ,
'logs' => $wpdb -> base_prefix . WP_DOMAIN_MAPPING_TABLE_LOGS ,
);
2025-03-21 11:25:09 +08:00
2025-05-20 22:52:24 +08:00
// Initialize the plugin
$this -> init ();
}
2025-03-21 11:25:09 +08:00
2025-05-20 22:52:24 +08:00
/**
* Initialize plugin
*/
private function init () {
// Load text domain
add_action ( 'init' , array ( $this , 'load_textdomain' ) );
2025-03-21 11:25:09 +08:00
2025-05-20 22:52:24 +08:00
// Initialize plugin update checker
$this -> setup_updater ();
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Setup admin-related hooks
$this -> setup_admin_hooks ();
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Setup general hooks
$this -> setup_general_hooks ();
// Check plugin requirements on activation
register_activation_hook ( __FILE__ , array ( $this , 'plugin_activation' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Load plugin textdomain
*/
public function load_textdomain () {
load_plugin_textdomain ( 'wp-domain-mapping' , false , dirname ( plugin_basename ( __FILE__ ) ) . '/languages' );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Setup plugin updater
*/
private function setup_updater () {
// Only include the updater if the PUC library exists
if ( file_exists ( plugin_dir_path ( __FILE__ ) . 'lib/plugin-update-checker/plugin-update-checker.php' ) ) {
require_once plugin_dir_path ( __FILE__ ) . 'lib/plugin-update-checker/plugin-update-checker.php' ;
if ( class_exists ( 'YahnisElsts\PluginUpdateChecker\v5p3\PucFactory' ) ) {
\YahnisElsts\PluginUpdateChecker\v5p3\PucFactory :: buildUpdateChecker (
'https://updates.weixiaoduo.com/wp-domain-mapping.json' ,
__FILE__ ,
'wp-domain-mapping'
);
}
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Setup admin hooks
*/
private function setup_admin_hooks () {
// Add menu pages
add_action ( 'admin_menu' , array ( $this , 'add_admin_pages' ) );
add_action ( 'network_admin_menu' , array ( $this , 'add_network_admin_pages' ) );
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Add AJAX handlers
add_action ( 'wp_ajax_dm_handle_actions' , array ( $this , 'ajax_handle_actions' ) );
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Add domain link to sites list
add_filter ( 'manage_sites_action_links' , array ( $this , 'add_domain_link_to_sites' ), 10 , 2 );
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Add custom columns
add_filter ( 'wpmu_blogs_columns' , array ( $this , 'add_domain_mapping_columns' ) );
add_action ( 'manage_blogs_custom_column' , array ( $this , 'display_domain_mapping_column' ), 1 , 3 );
add_action ( 'manage_sites_custom_column' , array ( $this , 'display_domain_mapping_column' ), 1 , 3 );
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Handle user domain mapping actions
if ( isset ( $_GET [ 'page' ] ) && 'domainmapping' === $_GET [ 'page' ] ) {
add_action ( 'admin_init' , array ( $this , 'handle_user_domain_actions' ) );
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Setup general hooks
*/
private function setup_general_hooks () {
// Delete domain mappings when a blog is deleted
add_action ( 'delete_blog' , array ( $this , 'delete_blog_domain_mapping' ), 1 , 2 );
// Handle domain redirection
add_action ( 'template_redirect' , array ( $this , 'redirect_to_mapped_domain' ) );
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Handle admin area redirection
add_action ( 'admin_init' , array ( $this , 'redirect_admin' ) );
// Setup domain mapping filters if DOMAIN_MAPPING is defined
if ( defined ( 'DOMAIN_MAPPING' ) ) {
$this -> setup_domain_mapping_filters ();
} else {
add_filter ( 'admin_url' , array ( $this , 'domain_mapping_adminurl' ), 10 , 3 );
}
// Handle remote login
if ( isset ( $_GET [ 'dm' ] ) ) {
add_action ( 'template_redirect' , array ( $this , 'remote_login_js' ) );
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Setup domain mapping filters when DOMAIN_MAPPING is defined
*/
private function setup_domain_mapping_filters () {
add_filter ( 'plugins_url' , array ( $this , 'domain_mapping_plugins_uri' ), 1 );
add_filter ( 'theme_root_uri' , array ( $this , 'domain_mapping_themes_uri' ), 1 );
add_filter ( 'pre_option_siteurl' , array ( $this , 'domain_mapping_siteurl' ) );
add_filter ( 'pre_option_home' , array ( $this , 'domain_mapping_siteurl' ) );
add_filter ( 'the_content' , array ( $this , 'domain_mapping_post_content' ) );
add_action ( 'wp_head' , array ( $this , 'remote_login_js_loader' ) );
add_action ( 'login_head' , array ( $this , 'redirect_login_to_orig' ) );
add_action ( 'wp_logout' , array ( $this , 'remote_logout_loader' ), 9999 );
add_filter ( 'stylesheet_uri' , array ( $this , 'domain_mapping_post_content' ) );
add_filter ( 'stylesheet_directory' , array ( $this , 'domain_mapping_post_content' ) );
add_filter ( 'stylesheet_directory_uri' , array ( $this , 'domain_mapping_post_content' ) );
add_filter ( 'template_directory' , array ( $this , 'domain_mapping_post_content' ) );
add_filter ( 'template_directory_uri' , array ( $this , 'domain_mapping_post_content' ) );
add_filter ( 'plugins_url' , array ( $this , 'domain_mapping_post_content' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Actions to perform on plugin activation
*/
public function plugin_activation () {
// Create database tables
$this -> create_tables ();
// Initialize remote login hash
$this -> get_hash ();
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Add admin menu pages
*/
public function add_admin_pages () {
global $current_site , $wpdb , $wp_db_version ;
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
if ( ! isset ( $current_site ) && $wp_db_version >= 15260 ) {
add_action ( 'admin_notices' , array ( $this , 'domain_mapping_warning' ) );
return false ;
}
if ( isset ( $current_site -> path ) && $current_site -> path != " / " ) {
wp_die ( esc_html__ ( " The domain mapping plugin only works if the site is installed in /. This is a limitation of how virtual servers work and is very difficult to work around. " , 'wp-domain-mapping' ) );
}
if ( get_site_option ( 'dm_user_settings' ) && $current_site -> blog_id != $wpdb -> blogid && ! $this -> sunrise_warning ( false ) ) {
add_management_page (
__ ( 'Domain Mapping' , 'wp-domain-mapping' ),
__ ( 'Domain Mapping' , 'wp-domain-mapping' ),
'manage_options' ,
'domainmapping' ,
array ( $this , 'render_manage_page' )
);
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Add network admin menu pages
*/
public function add_network_admin_pages () {
add_submenu_page (
'settings.php' ,
__ ( 'Domain Mapping' , 'wp-domain-mapping' ),
__ ( 'Domain Mapping' , 'wp-domain-mapping' ),
'manage_network' ,
'domain-mapping' ,
array ( $this , 'render_admin_page' )
);
add_submenu_page (
'sites.php' ,
__ ( 'Domains' , 'wp-domain-mapping' ),
__ ( 'Domains' , 'wp-domain-mapping' ),
'manage_network' ,
'domains' ,
array ( $this , 'render_domains_admin' )
);
}
/**
* Check if sunrise . php is properly configured
*
* @ param bool $die Whether to die with an error message
* @ return bool True if there ' s a problem , false if everything is okay
*/
public function sunrise_warning ( $die = true ) {
if ( ! file_exists ( WP_CONTENT_DIR . '/sunrise.php' ) ) {
if ( ! $die ) return true ;
if ( $this -> is_site_admin () ) {
wp_die (
sprintf (
/* translators: %1$s: Content directory, %2$s: WordPress install path */
esc_html__ ( 'Please copy sunrise.php to %1$s/sunrise.php and ensure the SUNRISE definition is in %2$swp-config.php' , 'wp-domain-mapping' ),
esc_html ( WP_CONTENT_DIR ),
esc_html ( ABSPATH )
)
);
} else {
wp_die ( esc_html__ ( " This plugin has not been configured correctly yet. " , 'wp-domain-mapping' ) );
}
} elseif ( ! defined ( 'SUNRISE' ) ) {
if ( ! $die ) return true ;
if ( $this -> is_site_admin () ) {
wp_die (
sprintf (
/* translators: %s: WordPress install path */
esc_html__ ( 'Please uncomment the line <em>define( \'SUNRISE\', \'on\' );</em> or add it to your %swp-config.php' , 'wp-domain-mapping' ),
esc_html ( ABSPATH )
)
);
2025-03-16 01:03:10 +08:00
} else {
2025-05-20 22:52:24 +08:00
wp_die ( esc_html__ ( " This plugin has not been configured correctly yet. " , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
} elseif ( ! defined ( 'SUNRISE_LOADED' ) ) {
if ( ! $die ) return true ;
if ( $this -> is_site_admin () ) {
wp_die (
sprintf (
/* translators: %s: WordPress install path */
esc_html__ ( 'Please edit your %swp-config.php and move the line <em>define( \'SUNRISE\', \'on\' );</em> above the last require_once() in that file or make sure you updated sunrise.php.' , 'wp-domain-mapping' ),
esc_html ( ABSPATH )
)
);
} else {
wp_die ( esc_html__ ( " This plugin has not been configured correctly yet. " , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
}
return false ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Display warning message for network configuration
*/
public function domain_mapping_warning () {
echo '<div class="notice notice-error"><p><strong>' . esc_html__ ( 'Domain Mapping Disabled.' , 'wp-domain-mapping' ) . '</strong> ' .
sprintf (
/* translators: %s: URL to WordPress network creation documentation */
wp_kses (
__ ( 'You must <a href="%1$s">create a network</a> for it to work.' , 'wp-domain-mapping' ),
array ( 'a' => array ( 'href' => array () ) )
),
'http://codex.wordpress.org/Create_A_Network'
) . '</p></div>' ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Create required database tables
*/
public function create_tables () {
global $wpdb ;
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Only network admins can create tables
if ( ! $this -> is_site_admin () ) {
return ;
}
// Initialize remote login hash
$this -> get_hash ();
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Use static variable to prevent repeated execution
static $tables_created = false ;
if ( $tables_created ) {
return ;
}
$created = 0 ;
$charset_collate = $wpdb -> get_charset_collate ();
// Create domain_mapping table
if ( $wpdb -> get_var ( " SHOW TABLES LIKE ' { $this -> tables [ 'domains' ] } ' " ) != $this -> tables [ 'domains' ] ) {
$wpdb -> query ( " CREATE TABLE IF NOT EXISTS ` { $this -> tables [ 'domains' ] } ` (
`id` bigint ( 20 ) NOT NULL auto_increment ,
`blog_id` bigint ( 20 ) NOT NULL ,
`domain` varchar ( 255 ) NOT NULL ,
`active` tinyint ( 4 ) default '1' ,
PRIMARY KEY ( `id` ),
KEY `blog_id` ( `blog_id` , `domain` , `active` )
) $charset_collate ; " );
$created = 1 ;
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Create domain_mapping_logins table
if ( $wpdb -> get_var ( " SHOW TABLES LIKE ' { $this -> tables [ 'logins' ] } ' " ) != $this -> tables [ 'logins' ] ) {
$wpdb -> query ( " CREATE TABLE IF NOT EXISTS ` { $this -> tables [ 'logins' ] } ` (
`id` varchar ( 32 ) NOT NULL ,
`user_id` bigint ( 20 ) NOT NULL ,
`blog_id` bigint ( 20 ) NOT NULL ,
`t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP ,
PRIMARY KEY ( `id` )
) $charset_collate ; " );
$created = 1 ;
}
// Create domain_mapping_logs table
if ( $wpdb -> get_var ( " SHOW TABLES LIKE ' { $this -> tables [ 'logs' ] } ' " ) != $this -> tables [ 'logs' ] ) {
$wpdb -> query ( " CREATE TABLE IF NOT EXISTS ` { $this -> tables [ 'logs' ] } ` (
`id` bigint ( 20 ) NOT NULL auto_increment ,
`user_id` bigint ( 20 ) NOT NULL ,
`action` varchar ( 50 ) NOT NULL ,
`domain` varchar ( 255 ) NOT NULL ,
`blog_id` bigint ( 20 ) NOT NULL ,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP ,
PRIMARY KEY ( `id` )
) $charset_collate ; " );
$created = 1 ;
}
// If any table was created, show success message and mark as created
if ( $created ) {
add_action ( 'admin_notices' , function () {
echo '<div class="notice notice-success"><p><strong>' .
esc_html__ ( 'Domain mapping database tables created.' , 'wp-domain-mapping' ) .
'</strong></p></div>' ;
});
$tables_created = true ;
}
2025-03-16 01:03:10 +08:00
}
2025-03-21 11:00:48 +08:00
2025-05-20 22:52:24 +08:00
/**
* AJAX handler for domain actions
*/
public function ajax_handle_actions () {
check_ajax_referer ( 'domain_mapping' , 'nonce' );
if ( ! current_user_can ( 'manage_network' ) ) {
wp_send_json_error ( __ ( 'Permission denied.' , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
global $wpdb ;
$action = sanitize_text_field ( $_POST [ 'action_type' ] );
$domain = $this -> clean_domain ( sanitize_text_field ( isset ( $_POST [ 'domain' ] ) ? strtolower ( $_POST [ 'domain' ] ) : '' ) );
$blog_id = isset ( $_POST [ 'blog_id' ] ) ? absint ( $_POST [ 'blog_id' ] ) : 0 ;
$active = isset ( $_POST [ 'active' ] ) ? absint ( $_POST [ 'active' ] ) : 0 ;
$orig_domain = isset ( $_POST [ 'orig_domain' ] ) ? $this -> clean_domain ( sanitize_text_field ( $_POST [ 'orig_domain' ] ) ) : '' ;
$current_user_id = get_current_user_id ();
switch ( $action ) {
case 'save' :
if ( $blog_id != 0 && $blog_id != 1 ) {
// Validate domain format
if ( ! $this -> is_valid_domain ( $domain ) ) {
wp_send_json_error ( __ ( 'Invalid domain format.' , 'wp-domain-mapping' ) );
}
// Check if domain exists for another blog
$exists = $wpdb -> get_var ( $wpdb -> prepare (
" SELECT domain FROM { $this -> tables [ 'domains' ] } WHERE blog_id != %d AND domain = %s " ,
$blog_id , $domain
));
if ( null == $exists ) {
$wpdb -> query ( 'START TRANSACTION' );
try {
if ( empty ( $orig_domain ) ) {
// Insert new domain
$success = $wpdb -> insert (
$this -> tables [ 'domains' ],
array (
'blog_id' => $blog_id ,
'domain' => $domain ,
'active' => $active
),
array ( '%d' , '%s' , '%d' )
);
if ( $success ) {
// Log the action
$wpdb -> insert (
$this -> tables [ 'logs' ],
array (
'user_id' => $current_user_id ,
'action' => 'add' ,
'domain' => $domain ,
'blog_id' => $blog_id
),
array ( '%d' , '%s' , '%s' , '%d' )
);
$wpdb -> query ( 'COMMIT' );
wp_send_json_success ( __ ( 'Domain added successfully.' , 'wp-domain-mapping' ) );
} else {
$wpdb -> query ( 'ROLLBACK' );
wp_send_json_error ( __ ( 'Failed to add domain.' , 'wp-domain-mapping' ) );
}
} else {
// Update existing domain
$success = $wpdb -> update (
$this -> tables [ 'domains' ],
array (
'blog_id' => $blog_id ,
'domain' => $domain ,
'active' => $active
),
array ( 'domain' => $orig_domain ),
array ( '%d' , '%s' , '%d' ),
array ( '%s' )
);
if ( $success !== false ) {
// Log the action
$wpdb -> insert (
$this -> tables [ 'logs' ],
array (
'user_id' => $current_user_id ,
'action' => 'edit' ,
'domain' => $domain ,
'blog_id' => $blog_id
),
array ( '%d' , '%s' , '%s' , '%d' )
);
$wpdb -> query ( 'COMMIT' );
wp_send_json_success ( __ ( 'Domain updated successfully.' , 'wp-domain-mapping' ) );
} else {
$wpdb -> query ( 'ROLLBACK' );
wp_send_json_error ( __ ( 'No changes were made or update failed.' , 'wp-domain-mapping' ) );
}
}
} catch ( Exception $e ) {
$wpdb -> query ( 'ROLLBACK' );
wp_send_json_error ( __ ( 'An error occurred while saving domain.' , 'wp-domain-mapping' ) );
}
2025-03-16 01:03:10 +08:00
} else {
2025-05-20 22:52:24 +08:00
wp_send_json_error ( __ ( 'Domain already exists for another site.' , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
} else {
wp_send_json_error ( __ ( 'Invalid site ID.' , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
break ;
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
case 'delete' :
$domains = isset ( $_POST [ 'domains' ] ) ? array_map ( 'sanitize_text_field' , ( array ) $_POST [ 'domains' ] ) : array ( $domain );
$wpdb -> query ( 'START TRANSACTION' );
$deleted = 0 ;
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
try {
foreach ( $domains as $del_domain ) {
if ( empty ( $del_domain ) ) continue ;
// Get blog_id before deletion for logging
$affected_blog_id = $wpdb -> get_var ( $wpdb -> prepare (
" SELECT blog_id FROM { $this -> tables [ 'domains' ] } WHERE domain = %s " ,
$del_domain
));
if ( $affected_blog_id ) {
// Delete the domain
$result = $wpdb -> delete (
$this -> tables [ 'domains' ],
array ( 'domain' => $del_domain ),
array ( '%s' )
);
if ( $result ) {
$deleted ++ ;
// Log the action
$wpdb -> insert (
$this -> tables [ 'logs' ],
array (
'user_id' => $current_user_id ,
'action' => 'delete' ,
'domain' => $del_domain ,
'blog_id' => $affected_blog_id
),
array ( '%d' , '%s' , '%s' , '%d' )
);
}
}
}
if ( $deleted > 0 ) {
$wpdb -> query ( 'COMMIT' );
$message = sprintf (
_n (
'Domain deleted successfully.' ,
'%d domains deleted successfully.' ,
$deleted ,
'wp-domain-mapping'
),
$deleted
);
wp_send_json_success ( $message );
2025-03-16 01:03:10 +08:00
} else {
2025-05-20 22:52:24 +08:00
$wpdb -> query ( 'ROLLBACK' );
wp_send_json_error ( __ ( 'No domains were deleted.' , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
} catch ( Exception $e ) {
$wpdb -> query ( 'ROLLBACK' );
wp_send_json_error ( __ ( 'An error occurred while deleting domains.' , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
break ;
default :
wp_send_json_error ( __ ( 'Invalid action.' , 'wp-domain-mapping' ) );
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Handle user domain mapping actions
*/
public function handle_user_domain_actions () {
global $wpdb , $parent_file ;
$url = add_query_arg ( array ( 'page' => 'domainmapping' ), admin_url ( $parent_file ) );
if ( ! empty ( $_POST [ 'action' ] ) ) {
$domain = isset ( $_POST [ 'domain' ] ) ? sanitize_text_field ( $_POST [ 'domain' ] ) : '' ;
if ( empty ( $domain ) ) {
wp_die ( esc_html__ ( " You must enter a domain " , 'wp-domain-mapping' ) );
}
check_admin_referer ( 'domain_mapping' );
do_action ( 'dm_handle_actions_init' , $domain );
switch ( $_POST [ 'action' ] ) {
case " add " :
do_action ( 'dm_handle_actions_add' , $domain );
// Validate domain format
if ( ! $this -> is_valid_domain ( $domain ) ) {
wp_die ( esc_html__ ( " Invalid domain format " , 'wp-domain-mapping' ) );
}
// Check if domain already exists
$domain_exists = $wpdb -> get_row ( $wpdb -> prepare (
" SELECT blog_id FROM { $wpdb -> blogs } WHERE domain = %s OR (SELECT blog_id FROM { $this -> tables [ 'domains' ] } WHERE domain = %s) " ,
$domain , $domain
));
if ( null == $domain_exists ) {
// If primary, reset other domains to not primary
if ( isset ( $_POST [ 'primary' ] ) && $_POST [ 'primary' ] ) {
$wpdb -> update (
$this -> tables [ 'domains' ],
array ( 'active' => 0 ),
array ( 'blog_id' => $wpdb -> blogid ),
array ( '%d' ),
array ( '%d' )
);
}
// Insert new domain
$wpdb -> insert (
$this -> tables [ 'domains' ],
array (
'blog_id' => $wpdb -> blogid ,
'domain' => $domain ,
'active' => isset ( $_POST [ 'primary' ] ) ? 1 : 0
),
array ( '%d' , '%s' , '%d' )
);
wp_redirect ( add_query_arg ( array ( 'updated' => 'add' ), $url ) );
exit ;
} else {
wp_redirect ( add_query_arg ( array ( 'updated' => 'exists' ), $url ) );
exit ;
}
break ;
case " primary " :
do_action ( 'dm_handle_actions_primary' , $domain );
// Reset all domains to not primary
$wpdb -> update (
$this -> tables [ 'domains' ],
array ( 'active' => 0 ),
array ( 'blog_id' => $wpdb -> blogid ),
array ( '%d' ),
array ( '%d' )
);
// Check if domain is not the original domain
$orig_url = parse_url ( $this -> get_original_url ( 'siteurl' ) );
if ( $domain != $orig_url [ 'host' ] ) {
// Set the selected domain as primary
$wpdb -> update (
$this -> tables [ 'domains' ],
array ( 'active' => 1 ),
array (
'domain' => $domain ,
'blog_id' => $wpdb -> blogid
),
array ( '%d' ),
array ( '%s' , '%d' )
);
}
wp_redirect ( add_query_arg ( array ( 'updated' => 'primary' ), $url ) );
exit ;
break ;
}
} elseif ( isset ( $_GET [ 'action' ] ) && $_GET [ 'action' ] == 'delete' ) {
$domain = sanitize_text_field ( $_GET [ 'domain' ] );
if ( empty ( $domain ) ) {
wp_die ( esc_html__ ( " You must enter a domain " , 'wp-domain-mapping' ) );
}
check_admin_referer ( " delete " . $_GET [ 'domain' ] );
do_action ( 'dm_handle_actions_del' , $domain );
// Delete the domain
$wpdb -> delete (
$this -> tables [ 'domains' ],
array ( 'domain' => $domain ),
array ( '%s' )
);
wp_redirect ( add_query_arg ( array ( 'updated' => 'del' ), $url ) );
exit ;
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Render domains admin page
*/
public function render_domains_admin () {
global $wpdb , $current_site ;
if ( ! $this -> is_site_admin () ) {
return false ;
}
$this -> sunrise_warning ();
$this -> create_tables ();
if ( isset ( $current_site -> path ) && $current_site -> path != " / " ) {
wp_die ( sprintf (
esc_html__ ( " <strong>Warning!</strong> This plugin will only work if WordPress is installed in the root directory of your webserver. It is currently installed in '%s'. " , " wp-domain-mapping " ),
esc_html ( $current_site -> path )
));
}
$total_domains = $wpdb -> get_var ( " SELECT COUNT(*) FROM { $this -> tables [ 'domains' ] } " );
$primary_domains = $wpdb -> get_var ( " SELECT COUNT(*) FROM { $this -> tables [ 'domains' ] } WHERE active = 1 " );
$edit_row = false ;
if ( isset ( $_GET [ 'edit_domain' ] ) ) {
$edit_domain = sanitize_text_field ( $_GET [ 'edit_domain' ] );
$edit_row = $wpdb -> get_row ( $wpdb -> prepare (
" SELECT * FROM { $this -> tables [ 'domains' ] } WHERE domain = %s " ,
$edit_domain
));
}
// Load admin UI
require_once ( WP_DOMAIN_MAPPING_DIR_PATH . 'admin/domains-page.php' );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Render domain logs
*/
public function render_domain_logs () {
global $wpdb ;
$logs = $wpdb -> get_results ( " SELECT * FROM { $this -> tables [ 'logs' ] } ORDER BY timestamp DESC LIMIT 50 " );
if ( ! $logs ) {
echo '<p>' . esc_html__ ( 'No logs available.' , 'wp-domain-mapping' ) . '</p>' ;
return ;
}
// Load logs UI
require_once ( WP_DOMAIN_MAPPING_DIR_PATH . 'admin/logs-table.php' );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Render admin configuration page
*/
public function render_admin_page () {
global $wpdb , $current_site ;
if ( ! $this -> is_site_admin () ) {
return false ;
}
$this -> sunrise_warning ();
$this -> create_tables ();
if ( isset ( $current_site -> path ) && $current_site -> path != " / " ) {
wp_die ( sprintf (
esc_html__ ( " <strong>Warning!</strong> This plugin will only work if WordPress is installed in the root directory of your webserver. It is currently installed in '%s'. " , " wp-domain-mapping " ),
esc_html ( $current_site -> path )
));
}
// Initialize options if needed
if ( get_site_option ( 'dm_remote_login' , 'NA' ) == 'NA' ) {
add_site_option ( 'dm_remote_login' , 1 );
}
if ( get_site_option ( 'dm_redirect_admin' , 'NA' ) == 'NA' ) {
add_site_option ( 'dm_redirect_admin' , 1 );
}
if ( get_site_option ( 'dm_user_settings' , 'NA' ) == 'NA' ) {
add_site_option ( 'dm_user_settings' , 1 );
}
// Handle form submission
if ( ! empty ( $_POST [ 'action' ] ) && $_POST [ 'action' ] == 'update' ) {
check_admin_referer ( 'domain_mapping' );
// Validate and save IP addresses
$ipok = true ;
$ipaddresses = explode ( ',' , sanitize_text_field ( $_POST [ 'ipaddress' ] ) );
foreach ( $ipaddresses as $address ) {
if ( ( $ip = trim ( $address ) ) && ! filter_var ( $ip , FILTER_VALIDATE_IP ) ) {
$ipok = false ;
break ;
}
}
if ( $ipok ) {
update_site_option ( 'dm_ipaddress' , sanitize_text_field ( $_POST [ 'ipaddress' ] ) );
}
// Save remote login option
if ( intval ( $_POST [ 'always_redirect_admin' ] ) == 0 ) {
$_POST [ 'dm_remote_login' ] = 0 ;
}
update_site_option ( 'dm_remote_login' , intval ( $_POST [ 'dm_remote_login' ] ) );
// Validate and save CNAME
if ( ! preg_match ( '/(--|\.\.)/' , $_POST [ 'cname' ] ) && preg_match ( '|^([a-zA-Z0-9-\.])+$|' , $_POST [ 'cname' ] ) ) {
update_site_option ( 'dm_cname' , sanitize_text_field ( $_POST [ 'cname' ] ) );
} else {
update_site_option ( 'dm_cname' , '' );
}
// Save other options
update_site_option ( 'dm_301_redirect' , isset ( $_POST [ 'permanent_redirect' ] ) ? intval ( $_POST [ 'permanent_redirect' ] ) : 0 );
update_site_option ( 'dm_redirect_admin' , isset ( $_POST [ 'always_redirect_admin' ] ) ? intval ( $_POST [ 'always_redirect_admin' ] ) : 0 );
update_site_option ( 'dm_user_settings' , isset ( $_POST [ 'dm_user_settings' ] ) ? intval ( $_POST [ 'dm_user_settings' ] ) : 0 );
update_site_option ( 'dm_no_primary_domain' , isset ( $_POST [ 'dm_no_primary_domain' ] ) ? intval ( $_POST [ 'dm_no_primary_domain' ] ) : 0 );
// Add settings saved notice
add_settings_error (
'dm_settings' ,
'settings_updated' ,
__ ( 'Settings saved.' , 'wp-domain-mapping' ),
'updated'
);
}
// Load admin UI
require_once ( WP_DOMAIN_MAPPING_DIR_PATH . 'admin/settings-page.php' );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Render user management page
*/
public function render_manage_page () {
global $wpdb , $parent_file ;
if ( isset ( $_GET [ 'updated' ] ) ) {
do_action ( 'dm_echo_updated_msg' );
}
$this -> sunrise_warning ();
if ( ! get_site_option ( 'dm_ipaddress' ) && ! get_site_option ( 'dm_cname' ) ) {
if ( $this -> is_site_admin () ) {
echo wp_kses (
__ ( " Please set the IP address or CNAME of your server in the <a href='wpmu-admin.php?page=domain-mapping'>site admin page</a>. " , 'wp-domain-mapping' ),
array ( 'a' => array ( 'href' => array () ) )
);
} else {
esc_html_e ( " This plugin has not been configured correctly yet. " , 'wp-domain-mapping' );
}
return false ;
}
$protocol = is_ssl () ? 'https://' : 'http://' ;
$domains = $wpdb -> get_results ( $wpdb -> prepare (
" SELECT * FROM { $this -> tables [ 'domains' ] } WHERE blog_id = %d " ,
$wpdb -> blogid
), ARRAY_A );
// Load user UI
require_once ( WP_DOMAIN_MAPPING_DIR_PATH . 'admin/user-page.php' );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Add " Domains " link to sites list
*
* @ param array $actions The row actions
* @ param int $blog_id The blog ID
* @ return array Modified actions
*/
public function add_domain_link_to_sites ( $actions , $blog_id ) {
$domains_url = add_query_arg (
array ( 'page' => 'domains' , 'blog_id' => $blog_id ),
network_admin_url ( 'sites.php' )
);
$actions [ 'domains' ] = '<a href="' . esc_url ( $domains_url ) . '">' .
esc_html__ ( 'Domains' , 'wp-domain-mapping' ) . '</a>' ;
return $actions ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Add domain mapping columns to sites list
*
* @ param array $columns The columns
* @ return array Modified columns
*/
public function add_domain_mapping_columns ( $columns ) {
$columns [ 'map' ] = __ ( 'Mapping' );
return $columns ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Display domain mapping column content
*
* @ param string $column The column name
* @ param int $blog_id The blog ID
*/
public function display_domain_mapping_column ( $column , $blog_id ) {
global $wpdb ;
static $maps = false ;
if ( $column == 'map' ) {
if ( $maps === false ) {
$work = $wpdb -> get_results ( " SELECT blog_id, domain FROM { $this -> tables [ 'domains' ] } ORDER BY blog_id " );
$maps = array ();
if ( $work ) {
foreach ( $work as $blog ) {
$maps [ $blog -> blog_id ][] = $blog -> domain ;
}
}
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
if ( ! empty ( $maps [ $blog_id ] ) && is_array ( $maps [ $blog_id ] ) ) {
foreach ( $maps [ $blog_id ] as $blog ) {
echo esc_html ( $blog ) . '<br />' ;
}
}
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Delete blog domain mappings when a blog is deleted
*
* @ param int $blog_id The blog ID
* @ param bool $drop Whether to drop tables
*/
public function delete_blog_domain_mapping ( $blog_id , $drop ) {
global $wpdb ;
if ( $blog_id && $drop ) {
$domains = $wpdb -> get_col ( $wpdb -> prepare (
" SELECT domain FROM { $this -> tables [ 'domains' ] } WHERE blog_id = %d " ,
$blog_id
));
do_action ( 'dm_delete_blog_domain_mappings' , $domains );
$wpdb -> delete (
$this -> tables [ 'domains' ],
array ( 'blog_id' => $blog_id ),
array ( '%d' )
);
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Redirect to mapped domain
*/
public function redirect_to_mapped_domain () {
global $current_blog , $wpdb ;
if ( is_main_site () || ( isset ( $_GET [ 'preview' ] ) && $_GET [ 'preview' ] == 'true' ) ||
( isset ( $_POST [ 'customize' ] ) && isset ( $_POST [ 'theme' ] ) && $_POST [ 'customize' ] == 'on' ) ) {
return ;
}
$protocol = is_ssl () ? 'https://' : 'http://' ;
$url = $this -> domain_mapping_siteurl ( false );
if ( $url && $url != untrailingslashit ( $protocol . $current_blog -> domain . $current_blog -> path ) ) {
$redirect = get_site_option ( 'dm_301_redirect' ) ? '301' : '302' ;
if ( ( defined ( 'VHOST' ) && constant ( " VHOST " ) != 'yes' ) ||
( defined ( 'SUBDOMAIN_INSTALL' ) && constant ( 'SUBDOMAIN_INSTALL' ) == false ) ) {
$_SERVER [ 'REQUEST_URI' ] = str_replace ( $current_blog -> path , '/' , $_SERVER [ 'REQUEST_URI' ] );
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
wp_redirect ( $url . $_SERVER [ 'REQUEST_URI' ], $redirect );
exit ;
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Redirect admin area if needed
*/
public function redirect_admin () {
if ( strpos ( $_SERVER [ 'REQUEST_URI' ], 'wp-admin/admin-ajax.php' ) !== false ) {
return ;
}
if ( get_site_option ( 'dm_redirect_admin' ) ) {
$url = $this -> get_original_url ( 'siteurl' );
if ( false === strpos ( $url , $_SERVER [ 'HTTP_HOST' ] ) ) {
wp_redirect ( untrailingslashit ( $url ) . $_SERVER [ 'REQUEST_URI' ] );
exit ;
}
} else {
global $current_blog ;
$url = $this -> domain_mapping_siteurl ( false );
$request_uri = str_replace ( $current_blog -> path , '/' , $_SERVER [ 'REQUEST_URI' ] );
if ( false === strpos ( $url , $_SERVER [ 'HTTP_HOST' ] ) ) {
wp_redirect ( str_replace ( '//wp-admin' , '/wp-admin' , trailingslashit ( $url ) . $request_uri ) );
exit ;
2025-03-16 01:03:10 +08:00
}
}
}
2025-05-20 22:52:24 +08:00
/**
* Redirect login to original domain
*/
public function redirect_login_to_orig () {
if ( ! get_site_option ( 'dm_remote_login' ) ||
( isset ( $_GET [ 'action' ] ) && $_GET [ 'action' ] == 'logout' ) ||
isset ( $_GET [ 'loggedout' ] ) ) {
return ;
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
$url = $this -> get_original_url ( 'siteurl' );
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
if ( $url != site_url () ) {
$url .= " /wp-login.php " ;
echo " <script type='text/javascript'> \n window.location = ' " . esc_url ( $url ) . " '</script> " ;
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Handle logout across domains
*/
public function remote_logout_loader () {
global $current_site , $current_blog , $wpdb ;
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
$protocol = is_ssl () ? 'https://' : 'http://' ;
$hash = $this -> get_hash ();
$key = md5 ( time () );
$wpdb -> insert (
$this -> tables [ 'logins' ],
array (
'id' => $key ,
'user_id' => 0 ,
'blog_id' => $current_blog -> blog_id ,
't' => current_time ( 'mysql' )
),
array ( '%s' , '%d' , '%d' , '%s' )
);
if ( get_site_option ( 'dm_redirect_admin' ) ) {
wp_redirect ( $protocol . $current_site -> domain . $current_site -> path .
" ?dm= { $hash } &action=logout&blogid= { $current_blog -> blog_id } &k= { $key } &t= " . mt_rand () );
exit ;
2025-03-16 01:03:10 +08:00
}
}
2025-05-20 22:52:24 +08:00
/**
* Handle remote login JS
*/
public function remote_login_js () {
global $current_blog , $current_user , $wpdb ;
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
if ( 0 == get_site_option ( 'dm_remote_login' ) ) {
return ;
}
$hash = $this -> get_hash ();
$protocol = is_ssl () ? 'https://' : 'http://' ;
if ( $_GET [ 'dm' ] == $hash ) {
if ( $_GET [ 'action' ] == 'load' ) {
if ( ! is_user_logged_in () ) {
2025-03-16 01:03:10 +08:00
exit ;
2025-05-20 22:52:24 +08:00
}
$key = md5 ( time () . mt_rand () );
$wpdb -> insert (
$this -> tables [ 'logins' ],
array (
'id' => $key ,
'user_id' => $current_user -> ID ,
'blog_id' => $_GET [ 'blogid' ],
't' => current_time ( 'mysql' )
),
array ( '%s' , '%d' , '%d' , '%s' )
);
$url = add_query_arg (
array (
'action' => 'login' ,
'dm' => $hash ,
'k' => $key ,
't' => mt_rand ()
),
$_GET [ 'back' ]
);
echo " window.location = ' " . esc_url ( $url ) . " ' " ;
exit ;
} elseif ( $_GET [ 'action' ] == 'login' ) {
$details = $wpdb -> get_row ( $wpdb -> prepare (
" SELECT * FROM { $this -> tables [ 'logins' ] } WHERE id = %s AND blog_id = %d " ,
$_GET [ 'k' ], $wpdb -> blogid
));
if ( $details ) {
if ( $details -> blog_id == $wpdb -> blogid ) {
$wpdb -> delete (
$this -> tables [ 'logins' ],
array ( 'id' => $_GET [ 'k' ] ),
array ( '%s' )
);
$wpdb -> query ( $wpdb -> prepare (
" DELETE FROM { $this -> tables [ 'logins' ] } WHERE t < %s " ,
date ( 'Y-m-d H:i:s' , time () - 120 )
));
wp_set_auth_cookie ( $details -> user_id );
wp_redirect ( remove_query_arg (
array ( 'dm' , 'action' , 'k' , 't' ),
$protocol . $current_blog -> domain . $_SERVER [ 'REQUEST_URI' ]
));
exit ;
} else {
wp_die ( esc_html__ ( " Incorrect or out of date login key " , 'wp-domain-mapping' ) );
}
2025-03-16 01:03:10 +08:00
} else {
2025-05-20 22:52:24 +08:00
wp_die ( esc_html__ ( " Unknown login key " , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
} elseif ( $_GET [ 'action' ] == 'logout' ) {
$details = $wpdb -> get_row ( $wpdb -> prepare (
" SELECT * FROM { $this -> tables [ 'logins' ] } WHERE id = %s AND blog_id = %d " ,
$_GET [ 'k' ], $_GET [ 'blogid' ]
));
if ( $details ) {
$wpdb -> delete (
$this -> tables [ 'logins' ],
array ( 'id' => $_GET [ 'k' ] ),
array ( '%s' )
);
$blog = get_blog_details ( $_GET [ 'blogid' ] );
wp_clear_auth_cookie ();
wp_redirect ( trailingslashit ( $blog -> siteurl ) . " wp-login.php?loggedout=true " );
exit ;
} else {
wp_die ( esc_html__ ( " Unknown logout key " , 'wp-domain-mapping' ) );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
}
2025-03-16 01:03:10 +08:00
}
}
2025-05-20 22:52:24 +08:00
/**
* Add JS loader for remote login
*/
public function remote_login_js_loader () {
global $current_site , $current_blog ;
if ( 0 == get_site_option ( 'dm_remote_login' ) || is_user_logged_in () ) {
return ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
$protocol = is_ssl () ? 'https://' : 'http://' ;
$hash = $this -> get_hash ();
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
echo " <script src=' " . esc_url ( $protocol . $current_site -> domain . $current_site -> path .
" ?dm= { $hash } &action=load&blogid= { $current_blog -> blog_id } &siteid= { $current_blog -> site_id } &t= " .
mt_rand () . " &back= " . urlencode ( $protocol . $current_blog -> domain . $_SERVER [ 'REQUEST_URI' ] ) ) .
" ' type='text/javascript'></script> " ;
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
/**
* Map domain for site URL
*
* @ param string $setting The setting value
* @ return string The mapped URL
*/
public function domain_mapping_siteurl ( $setting ) {
global $wpdb , $current_blog ;
static $return_url = array ();
// Check if already cached
if ( isset ( $return_url [ $wpdb -> blogid ] ) ) {
if ( $return_url [ $wpdb -> blogid ] !== false ) {
2025-03-16 01:03:10 +08:00
return $return_url [ $wpdb -> blogid ];
}
2025-05-20 22:52:24 +08:00
return $setting ;
}
$s = $wpdb -> suppress_errors ();
// Handle primary domain checking based on settings
if ( get_site_option ( 'dm_no_primary_domain' ) == 1 ) {
if ( isset ( $_SERVER [ 'HTTP_HOST' ] ) ) {
$domain = $wpdb -> get_var ( $wpdb -> prepare (
" SELECT domain FROM { $this -> tables [ 'domains' ] } WHERE blog_id = %d AND domain = %s LIMIT 1 " ,
$wpdb -> blogid , $_SERVER [ 'HTTP_HOST' ]
));
if ( null == $domain ) {
$return_url [ $wpdb -> blogid ] = untrailingslashit ( $this -> get_original_url ( " siteurl " ) );
return $return_url [ $wpdb -> blogid ];
}
}
2025-03-16 01:03:10 +08:00
} else {
2025-05-20 22:52:24 +08:00
$domain = $wpdb -> get_var ( $wpdb -> prepare (
" SELECT domain FROM { $this -> tables [ 'domains' ] } WHERE blog_id = %d AND active = 1 LIMIT 1 " ,
$wpdb -> blogid
));
if ( null == $domain ) {
$return_url [ $wpdb -> blogid ] = untrailingslashit ( $this -> get_original_url ( " siteurl " ) );
2025-03-16 01:03:10 +08:00
return $return_url [ $wpdb -> blogid ];
}
}
2025-05-20 22:52:24 +08:00
$wpdb -> suppress_errors ( $s );
2025-03-16 01:03:10 +08:00
$protocol = is_ssl () ? 'https://' : 'http://' ;
2025-05-20 22:52:24 +08:00
if ( $domain ) {
$return_url [ $wpdb -> blogid ] = untrailingslashit ( $protocol . $domain );
2025-03-16 01:03:10 +08:00
$setting = $return_url [ $wpdb -> blogid ];
} else {
$return_url [ $wpdb -> blogid ] = false ;
}
2025-05-20 22:52:24 +08:00
return $setting ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Get the original URL for a site
*
* @ param string $url_type The URL type ( siteurl or home )
* @ param int $blog_id The blog ID
* @ return string The original URL
*/
public function get_original_url ( $url_type , $blog_id = 0 ) {
global $wpdb ;
$id = $blog_id ? : $wpdb -> blogid ;
static $orig_urls = array ();
if ( ! isset ( $orig_urls [ $id ] ) ) {
// Remove filter to avoid infinite loop
if ( defined ( 'DOMAIN_MAPPING' ) ) {
remove_filter ( 'pre_option_' . $url_type , array ( $this , 'domain_mapping_siteurl' ) );
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
$orig_url = $blog_id == 0 ? get_option ( $url_type ) : get_blog_option ( $blog_id , $url_type );
$orig_url = is_ssl () ? str_replace ( " http:// " , " https:// " , $orig_url ) : str_replace ( " https:// " , " http:// " , $orig_url );
$orig_urls [ $id ] = $orig_url ;
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Restore filter
if ( defined ( 'DOMAIN_MAPPING' ) ) {
add_filter ( 'pre_option_' . $url_type , array ( $this , 'domain_mapping_siteurl' ) );
}
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
return $orig_urls [ $id ];
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Map domain for admin URL
*
* @ param string $url The URL
* @ param string $path The path
* @ param int $blog_id The blog ID
* @ return string The mapped URL
*/
public function domain_mapping_adminurl ( $url , $path , $blog_id = 0 ) {
$index = strpos ( $url , '/wp-admin' );
if ( $index !== false ) {
$url = $this -> get_original_url ( 'siteurl' , $blog_id ) . substr ( $url , $index );
if ( ( is_ssl () || force_ssl_admin () ) && 0 === strpos ( $url , 'http://' ) ) {
$url = 'https://' . substr ( $url , 7 );
}
}
return $url ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Map domains in post content
*
* @ param string $post_content The post content
* @ return string The mapped content
*/
public function domain_mapping_post_content ( $post_content ) {
$orig_url = $this -> get_original_url ( 'siteurl' );
$url = $this -> domain_mapping_siteurl ( 'NA' );
if ( $url == 'NA' ) {
return $post_content ;
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
return str_replace ( $orig_url , $url , $post_content );
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
/**
* Map domains in plugin URLs
*
* @ param string $full_url The full URL
* @ param string $path The path
* @ param string $plugin The plugin
* @ return string The mapped URL
*/
public function domain_mapping_plugins_uri ( $full_url , $path = null , $plugin = null ) {
return get_option ( 'siteurl' ) . substr ( $full_url , stripos ( $full_url , PLUGINDIR ) - 1 );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Map domains in theme URLs
*
* @ param string $full_url The full URL
* @ return string The mapped URL
*/
public function domain_mapping_themes_uri ( $full_url ) {
return str_replace ( $this -> get_original_url ( 'siteurl' ), get_option ( 'siteurl' ), $full_url );
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
/**
* Get the domain mapping hash
*
* @ return string The hash
*/
public function get_hash () {
$remote_login_hash = get_site_option ( 'dm_hash' );
if ( null == $remote_login_hash ) {
$remote_login_hash = md5 ( time () );
update_site_option ( 'dm_hash' , $remote_login_hash );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
return $remote_login_hash ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Check if user is a site admin
*
* @ return bool True if user is a site admin
*/
public function is_site_admin () {
return current_user_can ( 'manage_network' );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Clean domain name
*
* @ param string $domain The domain
* @ return string The cleaned domain
*/
public function clean_domain ( $domain ) {
// Remove protocol
$domain = preg_replace ( '#^https?://#' , '' , $domain );
// Remove trailing slash
$domain = rtrim ( $domain , '/' );
// Convert to punycode for IDN
if ( function_exists ( 'idn_to_ascii' ) && preg_match ( '/[^a-z0-9\-\.]/i' , $domain ) ) {
$domain = idn_to_ascii ( $domain );
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
return $domain ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Validate a domain name
*
* @ param string $domain The domain
* @ return bool True if valid
*/
public function is_valid_domain ( $domain ) {
// Basic validation
return ( bool ) preg_match ( '/^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,}$/i' , $domain );
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
/**
* Get IDN warning message
*
* @ return string The warning message
*/
public function idn_warning () {
return sprintf (
/* translators: %s: URL to punycode converter */
__ ( 'International Domain Names should be in <a href="%s" target="_blank">punycode</a> format.' , 'wp-domain-mapping' ),
" https://www.punycoder.com/ "
);
}
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
/**
* Ensure URL has protocol
*
* @ param string $domain The domain
* @ return string The URL with protocol
*/
public function ensure_protocol ( $domain ) {
if ( preg_match ( '#^https?://#' , $domain ) ) {
return $domain ;
}
return 'http://' . $domain ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
/**
* Default updated messages
*/
public function echo_default_updated_msg () {
if ( ! isset ( $_GET [ 'updated' ] ) ) {
return ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
switch ( $_GET [ 'updated' ] ) {
case " add " :
$msg = __ ( 'New domain added.' , 'wp-domain-mapping' );
break ;
case " exists " :
$msg = __ ( 'New domain already exists.' , 'wp-domain-mapping' );
break ;
case " primary " :
$msg = __ ( 'New primary domain.' , 'wp-domain-mapping' );
break ;
case " del " :
$msg = __ ( 'Domain deleted.' , 'wp-domain-mapping' );
break ;
default :
return ;
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
echo " <div class='notice notice-success'><p> " . esc_html ( $msg ) . " </p></div> " ;
2025-03-16 01:03:10 +08:00
}
}
2025-05-20 22:52:24 +08:00
// Initialize the plugin
function wp_domain_mapping_init () {
// Add default updated messages action
add_action ( 'dm_echo_updated_msg' , array ( WP_Domain_Mapping :: get_instance (), 'echo_default_updated_msg' ) );
2025-03-16 01:03:10 +08:00
2025-05-20 22:52:24 +08:00
// Initialize the plugin
return WP_Domain_Mapping :: get_instance ();
2025-03-16 01:03:10 +08:00
}
2025-05-20 22:52:24 +08:00
wp_domain_mapping_init ();
// Include admin UI templates
require_once ( WP_DOMAIN_MAPPING_DIR_PATH . 'includes/admin-ui.php' );