-
Notifications
You must be signed in to change notification settings - Fork 4
/
wpmu-db-clone.php
186 lines (149 loc) · 5.86 KB
/
wpmu-db-clone.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
<?php
/**
* Quicksilver action to update the sites
*/
use Symfony\Component\Process\Process;
require_once __DIR__ . '/vendor/autoload.php';
/**
* Edit these domains to match your site's configuration.
*
* If your test or dev sites have a custom domain and support
* wildcard subdomains, include them as well.
*/
$domains = [
'live' => 'mydomain.com',
'lando' => $site . '.lndo.site',
'default' => $env . '-' . $site . '.pantheonsite.io',
];
/**
* Run a command through Symfony's process
*
* @param string $cmd The command to run.
* @param bool $async Whether to run the command sync or async.
* @return Symfony\Component\Process\Process;
*/
function run_wp_cli( $cmd, $async = false ) {
$cmd = array_merge( [ 'wp' ], (array) $cmd, [ '--skip-plugins', '--skip-themes', '--quiet' ] );
$process = new Process( $cmd );
$process->setTimeout( 60 * 10 );
if ( $async ) {
$process->start();
} else {
$process->mustRun();
}
return $process;
}
/**
* Clean out done processes
*
* @param array $processes Array of Symfony processes.
* @return array Original processes, with complete ones filtered out.
*/
function clean_processes( $processes ) {
foreach ( $processes as $key => $process ) {
if ( $process->isTerminated() ) {
if ( ! $process->isSuccessful() ) {
echo $process->getErrorOutput();
}
unset( $processes[ $key ] );
}
}
return $processes;
}
echo 'Replacing domain names in wp_blogs table' . PHP_EOL;
$env = getenv( 'PANTHEON_ENVIRONMENT' );
$site = getenv( 'PANTHEON_SITE_NAME' );
// If we don't have a pantheon environment, bail.
if ( empty( $env ) ) {
echo "Missing environment information. Aborting.";
return;
}
// If the database isn't coming from the live site, skip processing.
// We can't trust that we know what to set the blog path to if it's not the live database.
if ( 'live' === $env ) {
echo "Database is being cloned to live environment." . PHP_EOL;
echo "Manually update the wp_blogs and wp_site tables.";
return;
}
// Figure out what the domain is for the current site.
$domain_new = $domains[ $env ] ?: $domains['default'];
// Should we move to a subdirectory setup?
// pantheonsite.io doesn't support subdomains, so we need to move to subdirectory
$is_subdirectory = stristr( $domain_new, 'pantheonsite.io' );
// Get the primary blog's domain.
$process = run_wp_cli( [ 'db', 'query', 'SELECT domain FROM wp_blogs WHERE site_id=1 AND blog_id=1;', '--skip-column-names', "--url={$domains['live']}" ] );
$domain_orig = trim( $process->getOutput() );
// If the database isn't coming from the live site, skip processing.
// We can't trust that we know what to set the blog path to if it's not the live database.
if ( $domains['live'] !== $domain_orig ) {
echo "Origin database isn't from live, skipping table processing.";
return;
}
// Get the list of sites.
$process = run_wp_cli( [ 'db', 'query', 'SELECT blog_id, domain, path FROM wp_blogs WHERE site_id=1', '--skip-column-names', "--url={$domains['live']}" ] );
$blogs = explode( PHP_EOL, $process->getOutput() );
// Update wp_site domain to the new domain.
run_wp_cli( [ 'db', 'query', "UPDATE wp_site SET domain='{$domain_new}', path='/' WHERE id=1", "--url={$domains['live']}" ], true );
$processes = [];
// Update individual site urls.
foreach ( $blogs as $blog_raw ) {
$blog = explode( "\t", $blog_raw );
$blog_id = intval( $blog[0] );
// If the blog ID isn't a positive integer, something's not right. Skip it.
if ( 0 >= $blog_id ) {
continue;
}
$blog_domain_orig = $blog[1];
$blog_path_orig = $blog[2];
echo "Processing site #$blog_id {$blog_domain_orig}{$blog_path_orig}\n";
if ( $is_subdirectory ) {
// Convert URLs to a subdirectory pattern.
// site.com => test-site.pantheonsite.io
// blog.site.com => test-site.pantheonsite.io/blog/
// blog.site.com/dir/ => test-site.pantheonsite.io/blog-dir/
// blog.com => test-site.pantheonsite.io/blog-com/
// blog.com/dir/ => test-site.pantheonsite.io/blog-com-dir/
// Process URLs to a subdirectory format.
$blog_domain_new = $domain_new;
if ( 1 == $blog_id ) {
// First blog gets a path of just /
$blog_path_new = '/';
} else {
// All other blogs get a path made of the subdomain and original path.
$blog_path_new = str_replace( '.' . $domain_orig, '', $blog_domain_orig ) . $blog_path_orig;
// Convert to a single subdirectory.
$blog_path_new = '/' . str_replace( ['.', '/' ], '-', $blog_path_new );
$blog_path_new = rtrim( $blog_path_new, '-' ) . '/';
}
} else {
// Process URLs to a subdomain format.
$blog_path_new = $blog_path_orig;
if ( 1 === $blog_id ) {
$blog_domain_new = $domain_new;
} else {
// First, remove the live domain from the site's original domain
$subdir = str_replace( ".{$domains['live']}", '', $blog_domain_orig );
// For edge cases of sub-sub domains or fully unique domains, swap dots to dashes.
$subdir = str_replace( '.', '-', $subdir );
$blog_domain_new = "{$subdir}.{$domain_new}";
}
}
// Update wp_blogs record.
run_wp_cli( [ 'db', 'query', "UPDATE wp_blogs SET domain='{$blog_domain_new}', path='{$blog_path_new}' WHERE site_id=1 AND blog_id={$blog_id}", "--url={$domains['live']}" ], false );
// Run search-replace on all of the blog's tables.
// Search-replace limited to just the blog's tables for speed.
$blog_url_orig = trim( "{$blog_domain_orig}{$blog_path_orig}", '/' );
$blog_url_new = trim( "{$blog_domain_new}{$blog_path_new}", '/' );
$processes[] = run_wp_cli( [ 'search-replace', "//$blog_url_orig", "//$blog_url_new", "--url=$blog_url_new", '--skip-tables=wp_blogs,wp_site' ], true );
while ( count ( $processes ) > 100 ) {
$processes = clean_processes( $processes );
sleep( 1 );
}
}
// Wait for all processes to finish.
while ( ! empty( $processes ) ) {
$processes = clean_processes( $processes );
sleep( 1 );
printf( '%d processes executing', count( $processes ) );
echo PHP_EOL;
}