forked from humanmade/Mercator
/
mercator.php
197 lines (168 loc) · 5.05 KB
/
mercator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
<?php
/**
* Mercator
*
* WordPress multisite domain mapping for the modern era.
*
* @package Mercator
*/
namespace Mercator;
/**
* Current version of Mercator.
*/
const VERSION = '0.1';
require __DIR__ . '/class-mapping.php';
// Allow skipping bootstrap checks if you *really* know what you're doing.
// This lets Mercator run after muplugins_loaded, which you might need if you're
// doing unit tests.
if ( defined( 'MERCATOR_SKIP_CHECKS' ) && MERCATOR_SKIP_CHECKS ) {
startup();
}
else {
run_preflight();
}
/**
* Perform preflight checks for Mercator
*
* Checks that we can actually run Mercator, then attaches the relevant actions
* and filters to make it useful.
*/
function run_preflight() {
// Are we installing? Bail if so.
if ( defined( 'WP_INSTALLING' ) ) {
return;
}
// Are we still in sunrise stage?
if ( did_action( 'muplugins_loaded' ) ) {
warn_with_message( 'Mercator must be loaded in your <code>sunrise.php</code>. Check out the <a href="https://github.com/humanmade/Mercator/wiki/Installation">installation instructions</a>.' );
return;
}
// Are we actually on multisite?
if ( ! is_multisite() ) {
warn_with_message( 'Mercator requires WordPress to be in <a href="http://codex.wordpress.org/Create_A_Network">multisite mode</a>.' );
return;
}
// Are we running a good version of WP?
if ( ! function_exists( 'get_site_by_path' ) ) {
warn_with_message( 'Mercator requires <a href="https://wordpress.org/download/">WordPress 3.9</a> or newer. Update now.' );
return;
}
// Check for COOKIE_DOMAIN definition
//
// Note that this can't be an admin notice, as you'd never be able to log in
// to see it.
if ( defined( 'COOKIE_DOMAIN' ) ) {
status_header( 500 );
header( 'X-Mercator: COOKIE_DOMAIN' );
wp_die( 'The constant <code>COOKIE_DOMAIN</code> is defined (probably in <code>wp-config.php</code>). Please remove or comment out that <code>define()</code> line.' );
}
// M: We have clearance, Clarence.
// O: Roger, Roger. What's our Vector Victor?
startup();
}
/**
* Attach Mercator into WordPress
*
* Imagine this as attaching the strings to the puppet.
*/
function startup() {
// Define the table variables
if ( empty( $GLOBALS['wpdb']->dmtable ) ) {
$GLOBALS['wpdb']->dmtable = $GLOBALS['wpdb']->base_prefix . 'domain_mapping';
$GLOBALS['wpdb']->ms_global_tables[] = 'domain_mapping';
}
// Ensure cache is shared
wp_cache_add_global_groups( array( 'domain_mapping' ) );
// Actually hook in!
add_filter( 'pre_get_site_by_path', __NAMESPACE__ . '\\check_domain_mapping', 10, 2 );
add_action( 'admin_init', __NAMESPACE__ . '\\load_admin', -100 );
}
/**
* Warn the user via the admin panels.
*
* @param string $message Message to use in the warning.
*/
function warn_with_message( $message ) {
add_action( 'all_admin_notices', function () use ( $message ) {
echo '<div class="error"><p>' . $message . '</p></div>';
} );
}
/**
* Check if a domain has a mapping available
*
* @param stdClass|null $site Site object if already found, null otherwise
* @param string $domain Domain we're looking for
* @return stdClass|null Site object if already found, null otherwise
*/
function check_domain_mapping( $site, $domain ) {
// Have we already matched? (Allows other plugins to match first)
if ( ! empty( $site ) ) {
return $site;
}
global $wpdb;
// Grab both WWW and no-WWW
if ( strpos( $domain, 'www.' ) === 0 ) {
$www = $domain;
$nowww = substr( $domain, 4 );
}
else {
$nowww = $domain;
$www = 'www.' . $domain;
}
$mapping = Mapping::get_by_domain( array( $www, $nowww ) );
if ( empty( $mapping ) || is_wp_error( $mapping ) ) {
return $site;
}
// Ignore non-active domains
if ( ! $mapping->is_active() ) {
return $site;
}
// Fetch the actual data for the site
$mapped_site = $mapping->get_site();
if ( empty( $mapped_site ) ) {
return $site;
}
// Note: This is only for backwards compatibility with WPMU Domain Mapping,
// do not rely on this constant in new code.
defined( 'DOMAIN_MAPPING' ) or define( 'DOMAIN_MAPPING', 1 );
return $mapped_site;
}
/**
* Check the Mercator mapping table
*
* @return string|boolean One of 'exists' (table already existed), 'created' (table was created), or false if could not be created
*/
function check_table() {
global $wpdb;
$schema = "CREATE TABLE {$wpdb->dmtable} (
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)
KEY domain (domain)
);";
if ( ! function_exists( 'dbDelta' ) ) {
if ( ! is_admin() ) {
return false;
}
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
}
$result = dbDelta( $schema );
if ( empty( $result ) ) {
// No changes, database already exists and is up-to-date
return 'exists';
}
return 'created';
}
/**
* Load administration functions
*
* We do this here rather than just including it to avoid extra load on
* non-admin pages.
*/
function load_admin() {
require_once __DIR__ . '/admin.php';
require_once __DIR__ . '/inc/admin/class-alias-list-table.php';
}