Last active
August 13, 2020 14:07
-
-
Save plaidpowered/9e4bd069b8ec990341f1cadf62615eef to your computer and use it in GitHub Desktop.
Mapping Additional Domains with WordPress Multisite
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class DomainMapper { | |
/** | |
* Where we store the fully qualified domain URL throughout the lifecycle of the WordPress stack. | |
*/ | |
private $domain = null; | |
/** | |
* Where we store the active site object discovered during the network_short_circuit function. | |
*/ | |
private $site = null; | |
public function __construct() { | |
add_filter( 'pre_get_site_by_path', array( $this, 'network_short_circuit' ), 10, 2 ); | |
add_filter( "blog_option_siteurl", array( $this, 'hijack_blog_option' ), 99, 2 ); | |
add_filter( "blog_option_home", array( $this, 'hijack_blog_option' ), 99, 2 ); | |
add_filter( "pre_option_siteurl", array( $this, 'hijack_get_option' ), 99, 1 ); | |
add_filter( "pre_option_home", array( $this, 'hijack_get_option' ), 99, 1 ); | |
add_filter( 'get_canonical_url', array( $this, 'assign_canonical_url', 11 ) ); | |
} | |
public function network_short_circuit( $site, $domain ) { | |
// first let's utilize WordPress's object cache to see if this domain has already been found | |
// why do a sql lookup if you don't need to? | |
$cached = wp_cache_get( 'domain_site__' . sanitize_title( $domain ) ); | |
if ( $cached !== false ) { | |
$this->setup_FQD( $domain ); | |
$this->site = $cached; | |
return $cached; | |
} | |
// The following commented code is how it works with my own setup. | |
// It will NOT work with yours, unless you're storing domains in the blogmeta table, | |
// so either do it exactly the same as me, or replace this query with your own process. | |
/* REPLACE: | |
$site_id = $wpdb->get_var( $wpdb->prepare( | |
"SELECT blog_id FROM {$wpdb->blogmeta} WHERE `meta_key` = 'domain' AND `meta_value` = %s", | |
$domain | |
) ); | |
*/ | |
if ( ! empty( $site_id ) ) { | |
$site = \WP_Site::get_instance( $site_id ); | |
$site->domain = $domain; | |
$this->site = $site; | |
$this->setup_FQD( $domain ); | |
} | |
// Store our discovery in the cache for quick lookup later. | |
wp_cache_set( 'domain_site__' . $domain, $site ); | |
return $site; | |
} | |
/** | |
* Stores the fully qualified domain address in our class for retrieval. | |
*/ | |
private function setup_FQD( $domain ) { | |
$protocol = ( ! empty($_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443 ) ? "https://" : "http://"; | |
$this->domain = $protocol . $domain; | |
} | |
public function hijack_blog_option( $value, $id ) { | |
if ( ! empty( $this->domain ) && absint( $id ) === $this->site->ID ) { | |
return $this->domain; | |
} | |
return $value; | |
} | |
public function hijack_get_option( $value ) { | |
if ( ! empty( $this->domain ) ) { | |
return $this->domain; | |
} | |
return $value; | |
} | |
/** | |
* From the get_canonical_url filter, assigns the correct domain to the canonical tag. | |
* Will require edits based on your WordPress configuration. | |
*/ | |
public function assign_canonical_url( $url ) { | |
// You'll need to figure out what the primary domain of each site is on your own, the | |
// following only works if you're storing the primary domain in the wp_blogmeta table. | |
/* REPLACE: | |
$primary_domain = get_site_meta( get_current_blog_id(), 'domain', true ); | |
*/ | |
if ( empty( $primary_domain ) ) { | |
return $url; | |
} | |
// I always force the https, but YMMV | |
return 'https://' . $primary_domain . $_SERVER['REQUEST_URI']; | |
} | |
} | |
new DomainMapper(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment