@wp-playground/wordpress 3.1.20 → 3.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/boot.d.ts +7 -0
- package/database-prerequisites.d.ts +9 -0
- package/index.cjs +1651 -193
- package/index.cjs.map +1 -1
- package/index.d.ts +7 -2
- package/index.js +2719 -441
- package/index.js.map +1 -1
- package/legacy-wp/legacy-boot.d.ts +39 -0
- package/legacy-wp/legacy-fixes.d.ts +86 -0
- package/legacy-wp/legacy-mu-plugins.d.ts +21 -0
- package/legacy-wp/legacy-sqlite-preload.d.ts +13 -0
- package/legacy-wp/mysql-shims.d.ts +18 -0
- package/package.json +8 -7
- package/platform-mu-plugins.d.ts +11 -0
- package/sqlite-preload-loader.d.ts +8 -0
package/index.cjs
CHANGED
|
@@ -1,4 +1,1586 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("@php-wasm/universal"),o=require("@php-wasm/util"),g=require("@wp-playground/common"),h=require("@php-wasm/logger");async function O(e){await e.writeFile("/internal/shared/mu-plugins/0-playground.php",`<?php
|
|
2
|
+
|
|
3
|
+
// Save WordPress environment information to a file.
|
|
4
|
+
// Named function (not a closure) so this file parses on PHP 5.2.
|
|
5
|
+
function playground_save_wp_env_info() {
|
|
6
|
+
if (defined('DB_ENGINE') && DB_ENGINE === 'sqlite') {
|
|
7
|
+
$db_info = array(
|
|
8
|
+
'type' => 'sqlite',
|
|
9
|
+
'path' => FQDB,
|
|
10
|
+
'driver_path' => defined('WP_MYSQL_ON_SQLITE_LOADER_PATH')
|
|
11
|
+
? WP_MYSQL_ON_SQLITE_LOADER_PATH
|
|
12
|
+
: dirname(SQLITE_MAIN_FILE) . '/wp-pdo-mysql-on-sqlite.php',
|
|
13
|
+
);
|
|
14
|
+
} else {
|
|
15
|
+
$db_info = array(
|
|
16
|
+
'type' => 'mysql',
|
|
17
|
+
// TODO: Save MySQL connection config.
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
$wp_env = array('db' => $db_info);
|
|
21
|
+
$wp_env_php = sprintf('<?php return %s;', var_export($wp_env, true));
|
|
22
|
+
$wp_env_file = '/internal/shared/wp-env.php';
|
|
23
|
+
if (!file_exists($wp_env_file) || file_get_contents($wp_env_file) !== $wp_env_php ) {
|
|
24
|
+
file_put_contents($wp_env_file, $wp_env_php);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
add_action('wp_loaded', 'playground_save_wp_env_info');
|
|
28
|
+
|
|
29
|
+
// Needed because gethostbyname( 'wordpress.org' ) returns
|
|
30
|
+
// a private network IP address for some reason.
|
|
31
|
+
function playground_allowed_redirect_hosts( $deprecated = '' ) {
|
|
32
|
+
return array(
|
|
33
|
+
'wordpress.org',
|
|
34
|
+
'api.wordpress.org',
|
|
35
|
+
'downloads.wordpress.org',
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
add_filter( 'allowed_redirect_hosts', 'playground_allowed_redirect_hosts' );
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Prevents wp_http_validate_url() from universally failing.
|
|
42
|
+
*
|
|
43
|
+
* wp_http_validate_url() calls gethostbyname() to verify whether the host
|
|
44
|
+
* is external. If it is internal, the URL validation fails and WordPress
|
|
45
|
+
* refuses to make a request.
|
|
46
|
+
*
|
|
47
|
+
* However, in EMscripten, gethostbyname() returns a private network IP address.
|
|
48
|
+
* This causes wp_http_validate_url() to return false for all URLs.
|
|
49
|
+
*
|
|
50
|
+
* This filter ensures that all URLs are considered external. In production
|
|
51
|
+
* environments, this would be considered a security risk. However, Playground
|
|
52
|
+
* already provides multiple code execution vectors as features (e.g. Blueprints).
|
|
53
|
+
*
|
|
54
|
+
* If someone wants to poke around local IP addresses, they already have multiple
|
|
55
|
+
* tools at their disposal. Therefore, this is not a real security risk in context
|
|
56
|
+
* of WordPress Playground or Playground CLI.
|
|
57
|
+
*/
|
|
58
|
+
add_filter('http_request_host_is_external', '__return_true');
|
|
59
|
+
|
|
60
|
+
// Support pretty permalinks
|
|
61
|
+
add_filter( 'got_url_rewrite', '__return_true' );
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Flush rewrite rules on the first real WordPress request.
|
|
65
|
+
*
|
|
66
|
+
* During boot, we set permalink_structure in the database
|
|
67
|
+
* but can't flush rewrite rules at that point because WordPress
|
|
68
|
+
* isn't fully bootstrapped — post types and taxonomies haven't
|
|
69
|
+
* been registered yet, so the generated rules are incomplete.
|
|
70
|
+
*
|
|
71
|
+
* This hook fires on 'init' at a very late priority, after all
|
|
72
|
+
* post types and taxonomies are registered. It checks if the
|
|
73
|
+
* rewrite_rules option is empty (meaning rules were never
|
|
74
|
+
* flushed) and if permalink_structure is set, then flushes once.
|
|
75
|
+
* A flag file prevents repeated flushes on subsequent requests.
|
|
76
|
+
*/
|
|
77
|
+
function playground_maybe_flush_rewrite_rules() {
|
|
78
|
+
$flag = '/internal/shared/.rewrite-rules-flushed';
|
|
79
|
+
if (file_exists($flag)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!function_exists('get_option')) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
$structure = get_option('permalink_structure');
|
|
86
|
+
if (empty($structure)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
$rules = get_option('rewrite_rules');
|
|
90
|
+
if (!empty($rules)) {
|
|
91
|
+
@file_put_contents($flag, '1');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
global $wp_rewrite;
|
|
95
|
+
if (!isset($wp_rewrite) && class_exists('WP_Rewrite')) {
|
|
96
|
+
$wp_rewrite = new WP_Rewrite();
|
|
97
|
+
}
|
|
98
|
+
if (isset($wp_rewrite) && method_exists($wp_rewrite, 'flush_rules')) {
|
|
99
|
+
$wp_rewrite->flush_rules();
|
|
100
|
+
}
|
|
101
|
+
@file_put_contents($flag, '1');
|
|
102
|
+
}
|
|
103
|
+
add_action('init', 'playground_maybe_flush_rewrite_rules', 99999);
|
|
104
|
+
|
|
105
|
+
// Create the fonts directory if missing
|
|
106
|
+
if(!file_exists(WP_CONTENT_DIR . '/fonts')) {
|
|
107
|
+
mkdir(WP_CONTENT_DIR . '/fonts');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
$log_file = WP_CONTENT_DIR . '/debug.log';
|
|
111
|
+
if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
|
|
112
|
+
if ( is_string( WP_DEBUG_LOG ) ) {
|
|
113
|
+
$log_file = WP_DEBUG_LOG;
|
|
114
|
+
}
|
|
115
|
+
ini_set('error_log', $log_file);
|
|
116
|
+
} else {
|
|
117
|
+
ini_set('log_errors', '0');
|
|
118
|
+
}
|
|
119
|
+
define('ERROR_LOG_FILE', $log_file);
|
|
120
|
+
?>`),await e.writeFile("/internal/shared/mu-plugins/sitemap-redirect.php",`<?php
|
|
121
|
+
/**
|
|
122
|
+
* Redirect sitemap.xml to wp-sitemap.xml for non-root installations.
|
|
123
|
+
*
|
|
124
|
+
* WordPress seems to only generate the sitemap.xml → wp-sitemap.xml rewrite
|
|
125
|
+
* rule when installed at the domain root. This mu-plugin handles the
|
|
126
|
+
* redirect for non-root installations.
|
|
127
|
+
*/
|
|
128
|
+
if (isset($_SERVER['REQUEST_URI'])) {
|
|
129
|
+
$site_url = site_url();
|
|
130
|
+
$parsed = parse_url($site_url);
|
|
131
|
+
$base_path = isset($parsed['path']) ? rtrim($parsed['path'], '/') : '';
|
|
132
|
+
|
|
133
|
+
$request_uri = $_SERVER['REQUEST_URI'];
|
|
134
|
+
if (
|
|
135
|
+
$request_uri === $base_path . '/sitemap.xml' ||
|
|
136
|
+
strpos($request_uri, $base_path . '/sitemap.xml?') === 0 ||
|
|
137
|
+
strpos($request_uri, $base_path . '/sitemap.xml/') === 0
|
|
138
|
+
) {
|
|
139
|
+
$query_string = strpos($request_uri, '?') !== false ? substr($request_uri, strpos($request_uri, '?')) : '';
|
|
140
|
+
header('Location: ' . $base_path . '/wp-sitemap.xml' . $query_string, true, 301);
|
|
141
|
+
exit;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
`),await e.writeFile("/internal/shared/mu-plugins/inline-tinymce-content-css.php",`<?php
|
|
145
|
+
function playground_inline_tinymce_content_css($settings) {
|
|
146
|
+
if (empty($settings['content_css'])) return $settings;
|
|
147
|
+
$css_urls = explode(',', $settings['content_css']);
|
|
148
|
+
$inline_css = '';
|
|
149
|
+
$doc_root = isset($_SERVER['DOCUMENT_ROOT'])
|
|
150
|
+
? $_SERVER['DOCUMENT_ROOT'] : '/wordpress';
|
|
151
|
+
foreach ($css_urls as $url) {
|
|
152
|
+
$url = trim($url);
|
|
153
|
+
if (!$url) continue;
|
|
154
|
+
$parsed = parse_url($url);
|
|
155
|
+
if (!isset($parsed['path'])) continue;
|
|
156
|
+
$path = preg_replace('#^/scope:[^/]+#', '', $parsed['path']);
|
|
157
|
+
$file = $doc_root . $path;
|
|
158
|
+
if (file_exists($file)) {
|
|
159
|
+
$inline_css .= @file_get_contents($file) . "\\n";
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if ($inline_css !== '') {
|
|
163
|
+
if (!empty($settings['content_style'])) {
|
|
164
|
+
$inline_css = $settings['content_style'] . "\\n" . $inline_css;
|
|
165
|
+
}
|
|
166
|
+
$settings['content_style'] = $inline_css;
|
|
167
|
+
$settings['content_css'] = '';
|
|
168
|
+
}
|
|
169
|
+
return $settings;
|
|
170
|
+
}
|
|
171
|
+
add_filter('tiny_mce_before_init', 'playground_inline_tinymce_content_css');
|
|
172
|
+
`)}function N(e){return`
|
|
173
|
+
/**
|
|
174
|
+
* Loads the SQLite integration plugin before WordPress is loaded
|
|
175
|
+
* and without creating a drop-in "db.php" file.
|
|
176
|
+
*
|
|
177
|
+
* Technically, it creates a global $wpdb object whose only two
|
|
178
|
+
* purposes are to:
|
|
179
|
+
*
|
|
180
|
+
* * Exist – because the require_wp_db() WordPress function won't
|
|
181
|
+
* connect to MySQL if $wpdb is already set.
|
|
182
|
+
* * Load the SQLite integration plugin the first time it's used
|
|
183
|
+
* and replace the global $wpdb reference with the SQLite one.
|
|
184
|
+
*
|
|
185
|
+
* This lets Playground keep the WordPress installation clean and
|
|
186
|
+
* solves dillemas like:
|
|
187
|
+
*
|
|
188
|
+
* * Should we include db.php in Playground exports?
|
|
189
|
+
* * Should we remove db.php from Playground imports?
|
|
190
|
+
* * How should we treat stale db.php from long-lived OPFS sites?
|
|
191
|
+
*
|
|
192
|
+
* @see https://github.com/WordPress/wordpress-playground/discussions/1379 for
|
|
193
|
+
* more context.
|
|
194
|
+
*/
|
|
195
|
+
class Playground_SQLite_Integration_Loader {
|
|
196
|
+
public function __call($name, $arguments) {
|
|
197
|
+
$this->load_sqlite_integration();
|
|
198
|
+
if($GLOBALS['wpdb'] === $this) {
|
|
199
|
+
throw new Exception('Infinite loop detected in $wpdb – SQLite integration plugin could not be loaded');
|
|
200
|
+
}
|
|
201
|
+
return call_user_func_array(
|
|
202
|
+
array($GLOBALS['wpdb'], $name),
|
|
203
|
+
$arguments
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
public function __get($name) {
|
|
207
|
+
$this->load_sqlite_integration();
|
|
208
|
+
if($GLOBALS['wpdb'] === $this) {
|
|
209
|
+
throw new Exception('Infinite loop detected in $wpdb – SQLite integration plugin could not be loaded');
|
|
210
|
+
}
|
|
211
|
+
return $GLOBALS['wpdb']->$name;
|
|
212
|
+
}
|
|
213
|
+
public function __set($name, $value) {
|
|
214
|
+
$this->load_sqlite_integration();
|
|
215
|
+
if($GLOBALS['wpdb'] === $this) {
|
|
216
|
+
throw new Exception('Infinite loop detected in $wpdb – SQLite integration plugin could not be loaded');
|
|
217
|
+
}
|
|
218
|
+
$GLOBALS['wpdb']->$name = $value;
|
|
219
|
+
}
|
|
220
|
+
protected function load_sqlite_integration() {
|
|
221
|
+
${e}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* The Query Monitor plugin short-circuits in the CLI SAPI. However, in Playground,
|
|
226
|
+
* the SAPI is always "cli" at the moment. Let's set a constant to disable the CLI
|
|
227
|
+
* detection.
|
|
228
|
+
*
|
|
229
|
+
* @see https://github.com/WordPress/sqlite-database-integration/pull/212
|
|
230
|
+
* @see https://github.com/WordPress/sqlite-database-integration/pull/215
|
|
231
|
+
*/
|
|
232
|
+
define('QM_TESTS', true);
|
|
233
|
+
$wpdb = $GLOBALS['wpdb'] = new Playground_SQLite_Integration_Loader();
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* WordPress is capable of using a preloaded global $wpdb. However, if
|
|
237
|
+
* it cannot find the drop-in db.php plugin it still checks whether
|
|
238
|
+
* the mysqli_connect() function exists even though it's not used.
|
|
239
|
+
*
|
|
240
|
+
* What WordPress demands, Playground shall provide.
|
|
241
|
+
*/
|
|
242
|
+
`}const W=`
|
|
243
|
+
if (function_exists('is_user_logged_in') && is_user_logged_in()) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (headers_sent()) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Legacy auto-login never redirects; it populates $_COOKIE
|
|
251
|
+
// in-process for the current request and relies on
|
|
252
|
+
// setcookie() / wp_set_auth_cookie() to persist across
|
|
253
|
+
// requests via HttpCookieStore.
|
|
254
|
+
|
|
255
|
+
// WP 2.5+
|
|
256
|
+
if (function_exists('wp_set_current_user') && function_exists('wp_set_auth_cookie')) {
|
|
257
|
+
$user = function_exists('get_user_by')
|
|
258
|
+
? get_user_by('login', $user_name)
|
|
259
|
+
: (function_exists('get_userdatabylogin')
|
|
260
|
+
? get_userdatabylogin($user_name) : null);
|
|
261
|
+
if (!$user) return;
|
|
262
|
+
|
|
263
|
+
wp_set_current_user($user->ID, $user->user_login);
|
|
264
|
+
// Populate $_COOKIE in-process so auth_redirect() and
|
|
265
|
+
// wp_verify_nonce() see the session for the remainder
|
|
266
|
+
// of this request; wp_set_auth_cookie() also emits
|
|
267
|
+
// Set-Cookie for subsequent requests.
|
|
268
|
+
wp_set_auth_cookie($user->ID);
|
|
269
|
+
if (function_exists('wp_generate_auth_cookie')) {
|
|
270
|
+
$_pg_exp = time() + 172800;
|
|
271
|
+
if (defined('AUTH_COOKIE'))
|
|
272
|
+
$_COOKIE[AUTH_COOKIE] = wp_generate_auth_cookie($user->ID, $_pg_exp, 'auth');
|
|
273
|
+
if (defined('SECURE_AUTH_COOKIE'))
|
|
274
|
+
$_COOKIE[SECURE_AUTH_COOKIE] = wp_generate_auth_cookie($user->ID, $_pg_exp, 'secure_auth');
|
|
275
|
+
if (defined('LOGGED_IN_COOKIE'))
|
|
276
|
+
$_COOKIE[LOGGED_IN_COOKIE] = wp_generate_auth_cookie($user->ID, $_pg_exp, 'logged_in');
|
|
277
|
+
}
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// WP 1.5–2.4
|
|
282
|
+
if (defined('USER_COOKIE') && defined('PASS_COOKIE')) {
|
|
283
|
+
$_pg_pass_cookie = md5(md5('password'));
|
|
284
|
+
$_COOKIE[USER_COOKIE] = $user_name;
|
|
285
|
+
$_COOKIE[PASS_COOKIE] = $_pg_pass_cookie;
|
|
286
|
+
if (!headers_sent()) {
|
|
287
|
+
$_pg_exp = time() + 172800;
|
|
288
|
+
setcookie(USER_COOKIE, $user_name, $_pg_exp, '/');
|
|
289
|
+
setcookie(PASS_COOKIE, $_pg_pass_cookie, $_pg_exp, '/');
|
|
290
|
+
}
|
|
291
|
+
$GLOBALS['current_user'] = null;
|
|
292
|
+
if (function_exists('get_currentuserinfo')) {
|
|
293
|
+
get_currentuserinfo();
|
|
294
|
+
}
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// WP 1.0–1.2: cookies are usually already set by
|
|
299
|
+
// playground_legacy_set_auth_cookies_early() in env.php,
|
|
300
|
+
// but WP 1.0–1.2 reads its user state from globals (no
|
|
301
|
+
// WP_User), so populate those explicitly here.
|
|
302
|
+
$cookiehash = defined('COOKIEHASH')
|
|
303
|
+
? COOKIEHASH
|
|
304
|
+
: (isset($GLOBALS['cookiehash']) && $GLOBALS['cookiehash']
|
|
305
|
+
? $GLOBALS['cookiehash']
|
|
306
|
+
: (function_exists('get_settings')
|
|
307
|
+
? md5(get_settings('siteurl'))
|
|
308
|
+
: ''));
|
|
309
|
+
if ($cookiehash) {
|
|
310
|
+
$_pg_user_cookie_name = 'wordpressuser_' . $cookiehash;
|
|
311
|
+
$_pg_pass_cookie_name = 'wordpresspass_' . $cookiehash;
|
|
312
|
+
$_pg_pass_cookie_value = md5(md5('password'));
|
|
313
|
+
$_COOKIE[$_pg_user_cookie_name] = $user_name;
|
|
314
|
+
$_COOKIE[$_pg_pass_cookie_name] = $_pg_pass_cookie_value;
|
|
315
|
+
if (!headers_sent()) {
|
|
316
|
+
$_pg_exp = time() + 172800;
|
|
317
|
+
setcookie($_pg_user_cookie_name, $user_name, $_pg_exp, '/');
|
|
318
|
+
setcookie($_pg_pass_cookie_name, $_pg_pass_cookie_value, $_pg_exp, '/');
|
|
319
|
+
}
|
|
320
|
+
if (function_exists('get_userdatabylogin')) {
|
|
321
|
+
$userdata = get_userdatabylogin($user_name);
|
|
322
|
+
if ($userdata) {
|
|
323
|
+
$GLOBALS['user_login'] = $user_name;
|
|
324
|
+
$GLOBALS['userdata'] = $userdata;
|
|
325
|
+
$GLOBALS['user_level'] = isset($userdata->user_level) ? (int) $userdata->user_level : 10;
|
|
326
|
+
$GLOBALS['user_ID'] = $userdata->ID;
|
|
327
|
+
$GLOBALS['user_email'] = isset($userdata->user_email) ? $userdata->user_email : '';
|
|
328
|
+
$GLOBALS['user_url'] = isset($userdata->user_url) ? $userdata->user_url : '';
|
|
329
|
+
$GLOBALS['user_nickname'] = isset($userdata->user_nickname) ? $userdata->user_nickname : $user_name;
|
|
330
|
+
$GLOBALS['user_pass_md5'] = md5(isset($userdata->user_pass) ? $userdata->user_pass : '');
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
`;async function G(e){await e.mkdir("/internal/shared/mu-plugins"),await e.writeFile("/internal/shared/auto_prepend_file.php",`<?php
|
|
336
|
+
// Polyfill the PHP 4 superglobals WP 1.0–2.5 still reads (removed
|
|
337
|
+
// in PHP 5.4). Bind by reference so later writes to $_COOKIE
|
|
338
|
+
// reach $HTTP_COOKIE_VARS, which WP 1.0's get_currentuserinfo()
|
|
339
|
+
// consults.
|
|
340
|
+
$GLOBALS['HTTP_GET_VARS'] = &$_GET;
|
|
341
|
+
$GLOBALS['HTTP_POST_VARS'] = &$_POST;
|
|
342
|
+
$GLOBALS['HTTP_COOKIE_VARS'] = &$_COOKIE;
|
|
343
|
+
$GLOBALS['HTTP_SERVER_VARS'] = &$_SERVER;
|
|
344
|
+
if (isset($_FILES)) $GLOBALS['HTTP_POST_FILES'] = &$_FILES;
|
|
345
|
+
if (isset($_ENV)) $GLOBALS['HTTP_ENV_VARS'] = &$_ENV;
|
|
346
|
+
if (isset($_SESSION)) $GLOBALS['HTTP_SESSION_VARS'] = &$_SESSION;
|
|
347
|
+
// Top-level names register_globals=On used to expose. WP 1.0
|
|
348
|
+
// reads $PHP_SELF / $REMOTE_ADDR directly instead of $_SERVER.
|
|
349
|
+
if (isset($_SERVER['PHP_SELF'])) $GLOBALS['PHP_SELF'] = $_SERVER['PHP_SELF'];
|
|
350
|
+
if (isset($_SERVER['REMOTE_ADDR'])) $GLOBALS['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
|
|
351
|
+
if (isset($_SERVER['REQUEST_URI'])) $GLOBALS['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
|
|
352
|
+
// Default SERVER_PROTOCOL for scripts invoked outside an HTTP
|
|
353
|
+
// request (e.g. php.run() during boot/fixups) — legacy WP reads
|
|
354
|
+
// it unconditionally in places like wp_redirect().
|
|
355
|
+
if (!isset($_SERVER['SERVER_PROTOCOL'])) {
|
|
356
|
+
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
|
|
357
|
+
}
|
|
358
|
+
if(file_exists('/internal/shared/consts.json')) {
|
|
359
|
+
$consts = json_decode(file_get_contents('/internal/shared/consts.json'), true);
|
|
360
|
+
if ($consts) {
|
|
361
|
+
foreach ($consts as $const => $value) {
|
|
362
|
+
if (!defined($const) && is_scalar($value)) {
|
|
363
|
+
define($const, $value);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
foreach (glob('/internal/shared/preload/*.php') as $file) {
|
|
369
|
+
require_once $file;
|
|
370
|
+
}
|
|
371
|
+
// Buffer early output so a stray PHP notice doesn't commit the
|
|
372
|
+
// response headers before the auto-login mu-plugin gets a chance
|
|
373
|
+
// to call wp_set_auth_cookie() / setcookie() on the init hook —
|
|
374
|
+
// otherwise nonce validation breaks on POST requests. PHP flushes
|
|
375
|
+
// the buffer at script end so output still reaches the browser.
|
|
376
|
+
ob_start();
|
|
377
|
+
`),await e.writeFile("/internal/shared/preload/env.php",`<?php
|
|
378
|
+
// Reads $wp_version from the WordPress install on disk. Falls back
|
|
379
|
+
// to '1.0' so callers can use version_compare() unconditionally.
|
|
380
|
+
function _playground_detect_wp_version() {
|
|
381
|
+
static $version = null;
|
|
382
|
+
if ($version !== null) return $version;
|
|
383
|
+
$doc_root = isset($_SERVER['DOCUMENT_ROOT'])
|
|
384
|
+
? $_SERVER['DOCUMENT_ROOT'] : '/wordpress';
|
|
385
|
+
$version_path = $doc_root . '/wp-includes/version.php';
|
|
386
|
+
$wp_version = '1.0';
|
|
387
|
+
if (file_exists($version_path)) {
|
|
388
|
+
include $version_path;
|
|
389
|
+
}
|
|
390
|
+
$version = $wp_version;
|
|
391
|
+
return $version;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Returns 'wp10', 'wp12', or 'wp15' based on the WP version on
|
|
395
|
+
// disk — the three $wp_filter shapes apply_filters() understands.
|
|
396
|
+
function _playground_detect_wp_hook_format() {
|
|
397
|
+
static $format = null;
|
|
398
|
+
if ($format !== null) return $format;
|
|
399
|
+
$wp_version = _playground_detect_wp_version();
|
|
400
|
+
if (version_compare($wp_version, '1.5', '>=')) {
|
|
401
|
+
$format = 'wp15';
|
|
402
|
+
} elseif (version_compare($wp_version, '1.2', '>=')) {
|
|
403
|
+
$format = 'wp12';
|
|
404
|
+
} else {
|
|
405
|
+
$format = 'wp10';
|
|
406
|
+
}
|
|
407
|
+
return $format;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Adds filters/actions before WordPress is loaded by writing the
|
|
411
|
+
// $wp_filter shape the target version expects. $function_to_add
|
|
412
|
+
// MUST be a string (no closures).
|
|
413
|
+
function playground_add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
|
|
414
|
+
global $wp_filter;
|
|
415
|
+
$fmt = _playground_detect_wp_hook_format();
|
|
416
|
+
if ($fmt === 'wp10') {
|
|
417
|
+
$wp_filter[$tag][] = $function_to_add;
|
|
418
|
+
} elseif ($fmt === 'wp12') {
|
|
419
|
+
$wp_filter[$tag][$priority][] = $function_to_add;
|
|
420
|
+
} else {
|
|
421
|
+
$wp_filter[$tag][$priority][$function_to_add] = array(
|
|
422
|
+
'function' => $function_to_add,
|
|
423
|
+
'accepted_args' => $accepted_args
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function playground_add_action( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
|
|
428
|
+
playground_add_filter( $tag, $function_to_add, $priority, $accepted_args );
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Set WP 1.0–2.4 auth cookies before WordPress loads — by the time
|
|
432
|
+
// the init hook fires (and on WP 1.0–1.2 it may not fire at all on
|
|
433
|
+
// the front page) WordPress has already read $_COOKIE. setcookie()
|
|
434
|
+
// also persists them across requests via HttpCookieStore.
|
|
435
|
+
// WP 2.5+ uses the HMAC auth cookie scheme and doesn't read these
|
|
436
|
+
// wordpressuser_/wordpresspass_ cookies at all — bail there so we
|
|
437
|
+
// don't write inert cookies the runtime would have to clean up.
|
|
438
|
+
function playground_legacy_set_auth_cookies_early() {
|
|
439
|
+
if (!defined('PLAYGROUND_AUTO_LOGIN_AS_USER')) return;
|
|
440
|
+
if (isset($_COOKIE['playground_auto_login_already_logged_out'])) return;
|
|
441
|
+
if (version_compare(_playground_detect_wp_version(), '2.5', '>=')) return;
|
|
442
|
+
|
|
443
|
+
foreach ($_COOKIE as $name => $_) {
|
|
444
|
+
if (strncmp($name, 'wordpressuser_', 14) === 0) return;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
$user_name = PLAYGROUND_AUTO_LOGIN_AS_USER;
|
|
448
|
+
$pass_md5 = md5(md5('password'));
|
|
449
|
+
|
|
450
|
+
// Read siteurl from SQLite so the cookie hash matches what
|
|
451
|
+
// WP 1.0–2.4 derives from get_settings('siteurl').
|
|
452
|
+
$siteurl = null;
|
|
453
|
+
$db_path = defined('DB_DIR') ? DB_DIR . '.ht.sqlite' : '';
|
|
454
|
+
if ($db_path && class_exists('PDO') && file_exists($db_path)) {
|
|
455
|
+
try {
|
|
456
|
+
$pdo = new PDO('sqlite:' . $db_path);
|
|
457
|
+
$stmt = $pdo->query("SELECT option_value FROM wp_options WHERE option_name = 'siteurl' LIMIT 1");
|
|
458
|
+
if ($stmt) $siteurl = $stmt->fetchColumn();
|
|
459
|
+
$pdo = null;
|
|
460
|
+
} catch (Exception $e) {}
|
|
461
|
+
}
|
|
462
|
+
if (!$siteurl && defined('WP_SITEURL')) $siteurl = WP_SITEURL;
|
|
463
|
+
if (!$siteurl) return;
|
|
464
|
+
|
|
465
|
+
$cookiehash = md5($siteurl);
|
|
466
|
+
$user_cookie_name = 'wordpressuser_' . $cookiehash;
|
|
467
|
+
$pass_cookie_name = 'wordpresspass_' . $cookiehash;
|
|
468
|
+
$_COOKIE[$user_cookie_name] = $user_name;
|
|
469
|
+
$_COOKIE[$pass_cookie_name] = $pass_md5;
|
|
470
|
+
|
|
471
|
+
if (!headers_sent()) {
|
|
472
|
+
$exp = time() + 172800;
|
|
473
|
+
setcookie($user_cookie_name, $user_name, $exp, '/');
|
|
474
|
+
setcookie($pass_cookie_name, $pass_md5, $exp, '/');
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
playground_legacy_set_auth_cookies_early();
|
|
478
|
+
|
|
479
|
+
// WP < 4.0 emits YEAR(post_date)='2026' AND MONTH(post_date)='4'
|
|
480
|
+
// against MySQL's loose type coercion. The SQLite driver's UDFs
|
|
481
|
+
// return integers and SQLite is strictly typed (4 != '4'), so
|
|
482
|
+
// strip quotes around numeric RHS values to keep both sides ints.
|
|
483
|
+
function playground_fix_sqlite_date_comparisons($query) {
|
|
484
|
+
if (
|
|
485
|
+
stripos($query, 'YEAR') === false &&
|
|
486
|
+
stripos($query, 'MONTH') === false &&
|
|
487
|
+
stripos($query, 'DAY') === false
|
|
488
|
+
) {
|
|
489
|
+
return $query;
|
|
490
|
+
}
|
|
491
|
+
return preg_replace(
|
|
492
|
+
'/\\b(YEAR|MONTH|DAYOFMONTH|DAY)\\s*\\(([^)]+)\\)\\s*=\\s*\\'(\\d+)\\'/i',
|
|
493
|
+
'$1($2) = $3',
|
|
494
|
+
$query
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
playground_add_filter( 'query', 'playground_fix_sqlite_date_comparisons' );
|
|
498
|
+
|
|
499
|
+
// WP 2.2+ checks WP_SITEURL/WP_HOME inside get_option(); WP <2.2
|
|
500
|
+
// doesn't, so backfill the same behaviour via the option filters
|
|
501
|
+
// to keep admin links on the Playground-scoped URL.
|
|
502
|
+
function playground_override_siteurl($value) {
|
|
503
|
+
if (defined('WP_SITEURL')) {
|
|
504
|
+
return WP_SITEURL;
|
|
505
|
+
}
|
|
506
|
+
return $value;
|
|
507
|
+
}
|
|
508
|
+
function playground_override_home($value) {
|
|
509
|
+
if (defined('WP_HOME')) {
|
|
510
|
+
return WP_HOME;
|
|
511
|
+
}
|
|
512
|
+
return $value;
|
|
513
|
+
}
|
|
514
|
+
playground_add_filter( 'option_siteurl', 'playground_override_siteurl' );
|
|
515
|
+
playground_add_filter( 'option_home', 'playground_override_home' );
|
|
516
|
+
|
|
517
|
+
// Load mu-plugins last so customer mu-plugins win — and so they
|
|
518
|
+
// can't depend on muplugins_loaded. WP < 2.8 doesn't fire that
|
|
519
|
+
// action at all, so init -1000 acts as a fallback (the $loaded
|
|
520
|
+
// flag keeps it idempotent).
|
|
521
|
+
playground_add_action( 'muplugins_loaded', 'playground_load_mu_plugins', 0 );
|
|
522
|
+
playground_add_action( 'init', 'playground_load_mu_plugins', -1000 );
|
|
523
|
+
function playground_load_mu_plugins() {
|
|
524
|
+
static $loaded = false;
|
|
525
|
+
if ($loaded) return;
|
|
526
|
+
$loaded = true;
|
|
527
|
+
$mu_plugins_dir = '/internal/shared/mu-plugins';
|
|
528
|
+
if(!is_dir($mu_plugins_dir)){
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
$mu_plugins = glob( $mu_plugins_dir . '/*.php' );
|
|
532
|
+
sort( $mu_plugins );
|
|
533
|
+
global $wp_version;
|
|
534
|
+
$is_legacy_wp = isset($wp_version) && version_compare($wp_version, '2.8', '<');
|
|
535
|
+
foreach ( $mu_plugins as $mu_plugin ) {
|
|
536
|
+
// Loaded separately by the preload lazy loader or db.php.
|
|
537
|
+
if (strpos($mu_plugin, 'sqlite-database-integration') !== false) {
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
// WP < 2.8 crashes on closures in hooks and lacks
|
|
541
|
+
// site_url() (added 2.6). 1-auto-login.php is written
|
|
542
|
+
// without either, so it's the only mu-plugin we load
|
|
543
|
+
// on legacy WP.
|
|
544
|
+
if ($is_legacy_wp) {
|
|
545
|
+
if (strpos($mu_plugin, '1-auto-login.php') === false) {
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
require_once $mu_plugin;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// PHP 5.x's foreach over $wp_filter['init'] iterates a copy,
|
|
553
|
+
// so add_action() calls made by the mu-plugin we just loaded
|
|
554
|
+
// won't fire on this same init run. Call them directly.
|
|
555
|
+
if ($is_legacy_wp) {
|
|
556
|
+
if (function_exists('playground_auto_login_redirect_target')) {
|
|
557
|
+
playground_auto_login_redirect_target();
|
|
558
|
+
}
|
|
559
|
+
if (function_exists('playground_auto_login')) {
|
|
560
|
+
playground_auto_login();
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
`),await e.writeFile("/internal/shared/mu-plugins/1-auto-login.php",`<?php
|
|
565
|
+
/**
|
|
566
|
+
* Returns the username to auto-login as, if any.
|
|
567
|
+
* @return string|false
|
|
568
|
+
*/
|
|
569
|
+
function playground_get_username_for_auto_login() {
|
|
570
|
+
if ( defined('PLAYGROUND_AUTO_LOGIN_AS_USER') && !isset($_COOKIE['playground_auto_login_already_happened']) ) {
|
|
571
|
+
return PLAYGROUND_AUTO_LOGIN_AS_USER;
|
|
572
|
+
}
|
|
573
|
+
if ( defined('PLAYGROUND_FORCE_AUTO_LOGIN_ENABLED') && isset($_GET['playground_force_auto_login_as_user']) ) {
|
|
574
|
+
return $_GET['playground_force_auto_login_as_user'];
|
|
575
|
+
}
|
|
576
|
+
return false;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
function playground_auto_login() {
|
|
580
|
+
if (empty($_SERVER['REQUEST_URI'])) {
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
$user_name = playground_get_username_for_auto_login();
|
|
584
|
+
if ( false === $user_name ) {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if ((function_exists('wp_doing_ajax') && wp_doing_ajax()) || defined('REST_REQUEST')) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
${W}
|
|
591
|
+
}
|
|
592
|
+
add_action('init', 'playground_auto_login', 1);
|
|
593
|
+
|
|
594
|
+
function playground_auto_login_redirect_target() {
|
|
595
|
+
if(strpos($_SERVER['REQUEST_URI'], '?playground-redirection-handler') !== false) {
|
|
596
|
+
$next = $_GET['next'];
|
|
597
|
+
header('Location: ' . $next, true, 302);
|
|
598
|
+
exit;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
add_action('init', 'playground_auto_login_redirect_target', 1);
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Disable the Site Admin Email Verification Screen for any session started
|
|
605
|
+
* via autologin.
|
|
606
|
+
*/
|
|
607
|
+
if (function_exists('add_filter')) {
|
|
608
|
+
add_filter('admin_email_check_interval', 'playground_disable_admin_email_check');
|
|
609
|
+
}
|
|
610
|
+
function playground_disable_admin_email_check($interval) {
|
|
611
|
+
if(false === playground_get_username_for_auto_login()) {
|
|
612
|
+
return 0;
|
|
613
|
+
}
|
|
614
|
+
return $interval;
|
|
615
|
+
}
|
|
616
|
+
`),await O(e),await e.writeFile("/internal/shared/preload/error-handler.php",`<?php
|
|
617
|
+
$GLOBALS['_playground_consts'] = array();
|
|
618
|
+
if (file_exists('/internal/shared/consts.json')) {
|
|
619
|
+
$GLOBALS['_playground_consts'] = @json_decode(file_get_contents('/internal/shared/consts.json'), true);
|
|
620
|
+
if (!is_array($GLOBALS['_playground_consts'])) { $GLOBALS['_playground_consts'] = array(); }
|
|
621
|
+
$GLOBALS['_playground_consts'] = array_keys($GLOBALS['_playground_consts']);
|
|
622
|
+
}
|
|
623
|
+
function _playground_error_handler($severity, $message, $file, $line) {
|
|
624
|
+
$playground_consts = $GLOBALS['_playground_consts'];
|
|
625
|
+
${M}
|
|
626
|
+
return false;
|
|
627
|
+
}
|
|
628
|
+
set_error_handler('_playground_error_handler');`)}const M=`
|
|
629
|
+
// http_api_transports is deprecated since 6.4.0 but Playground's
|
|
630
|
+
// networking layer still registers it for wp_http_supports().
|
|
631
|
+
// @see https://core.trac.wordpress.org/ticket/37708
|
|
632
|
+
if (
|
|
633
|
+
strpos($message, "http_api_transports") !== false &&
|
|
634
|
+
strpos($message, "since version 6.4.0 with no alternative available") !== false
|
|
635
|
+
) {
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
// Playground predefines constants (SITE_URL, WP_DEBUG, …) that
|
|
639
|
+
// wp-config.php is allowed to redefine; ours take precedence.
|
|
640
|
+
if (strpos($message, "already defined") !== false) {
|
|
641
|
+
foreach($playground_consts as $const) {
|
|
642
|
+
if(strpos($message, "Constant $const already defined") !== false) {
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
// Legacy WP (2.0–3.5) assigns props on uninitialised vars,
|
|
648
|
+
// valid in PHP 4 but E_WARNING since 5.x. Unfixable in core —
|
|
649
|
+
// Playground ships unmodified WordPress releases.
|
|
650
|
+
if (strpos($message, "Creating default object from empty value") !== false) {
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
// WP 2.8's dashboard widget calls get_error_string() on a
|
|
654
|
+
// null SimplePie when feed HTTP requests fail in WASM.
|
|
655
|
+
if (strpos($message, "get_error_string() on null") !== false ||
|
|
656
|
+
strpos($message, "get_error_string() on a non-object") !== false) {
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
// Don't complain about WordPress.org connection errors when
|
|
660
|
+
// the runtime isn't using fetch().
|
|
661
|
+
if (
|
|
662
|
+
(
|
|
663
|
+
! defined('USE_FETCH_FOR_REQUESTS') ||
|
|
664
|
+
! USE_FETCH_FOR_REQUESTS
|
|
665
|
+
) &&
|
|
666
|
+
strpos($message, "WordPress could not establish a secure connection to WordPress.org") !== false)
|
|
667
|
+
{
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
`;async function H(e,t){const i=E(e,t);if(i===null)return;const n=parseFloat(i);if(!Number.isFinite(n)||n<5||n>=6.2)return;const s=o.joinPaths(t,"wp-includes/load.php");if(!e.fileExists(s))return;const r=e.readFileAsText(s),a=r.replace("extension_loaded( 'mysqli' )","function_exists( 'mysqli_connect' )");a!==r&&await e.writeFile(s,a)}function E(e,t){const i=o.joinPaths(t,"wp-includes/version.php");if(!e.fileExists(i))return null;const s=e.readFileAsText(i).match(/\$wp_version\s*=\s*['"]([^'"]+)['"]/);return s?s[1]:null}const B=22527,T="E_ALL & ~8192 & ~2048";async function j(e,t){await te(e,t),await ie(e,t),await se(e,t),await le(e,t),await _e(e,t),await we(e,t),await ue(e,t),await he(e,t),await K(e,t),await Y(e,t);const i=E(e,t);if(i===null)return;const n=parseFloat(i);Number.isFinite(n)&&(n<1.2&&(await ne(e,t),await ee(e,t)),n<1.5&&await Q(e,t),1.5<=n&&n<2&&await fe(e,t),n<2&&(await z(e,t),await oe(e,t)),2.1<=n&&n<2.3&&await J(e,t),n<2.5&&await de(e,t),n<2.8&&(await ge(e,t),await me(e,t)),2.9<=n&&n<3.6&&await X(e,t),3.3<=n&&n<3.4&&await Z(e,t),n>=4.7&&await V(e,t))}async function V(e,t){const i=o.joinPaths(t,"wp-content/themes");if(e.isDir(i))for(const n of e.listFiles(i)){const s=o.joinPaths(i,n,"searchform.php");e.fileExists(s)&&e.unlink(s)}}async function X(e,t){const i=o.joinPaths(t,"wp-admin/includes/dashboard.php");if(e.fileExists(i)){let r=e.readFileAsText(i);if(r.includes("function wp_dashboard_primary()")&&!r.includes("/* pg_no_rss */")){for(const a of["wp_dashboard_primary","wp_dashboard_secondary","wp_dashboard_plugins"])r=r.replace(new RegExp(`function ${a}\\(\\)\\s*\\{`),`function ${a}() { /* pg_no_rss */ return;`);await e.writeFile(i,r)}}const n=o.joinPaths(t,"wp-admin/admin.php");if(e.fileExists(n)){let r=e.readFileAsText(n);r.includes("do_action('admin_init');")&&!r.includes("/* pg_admin_init_cleanup */")&&(r=r.replace("do_action('admin_init');",`/* pg_admin_init_cleanup */
|
|
671
|
+
if (function_exists('remove_action')) {
|
|
672
|
+
@remove_action('admin_init', '_maybe_update_plugins');
|
|
673
|
+
@remove_action('admin_init', '_maybe_update_themes');
|
|
674
|
+
@remove_action('admin_init', '_maybe_update_core');
|
|
675
|
+
@remove_action('admin_init', 'wp_version_check');
|
|
676
|
+
@remove_action('admin_init', 'wp_update_plugins');
|
|
677
|
+
@remove_action('admin_init', 'wp_update_themes');
|
|
678
|
+
}
|
|
679
|
+
do_action('admin_init');`),await e.writeFile(n,r))}const s=o.joinPaths(t,"wp-admin/includes/update.php");if(e.fileExists(s)){let r=e.readFileAsText(s);if(!r.includes("/* pg_admin_no_updates */")){for(const a of["wp_plugin_update_rows","wp_plugin_update_row","wp_theme_update_rows","wp_theme_update_row","wp_update_plugins","wp_update_themes"]){const l=new RegExp(`function ${a}\\s*\\([^)]*\\)\\s*\\{`);l.test(r)&&(r=r.replace(l,_=>_+" /* pg_admin_no_updates */ return;"))}await e.writeFile(s,r)}}for(const r of[o.joinPaths(t,"wp-includes/SimplePie/File.php"),o.joinPaths(t,"wp-includes/class-simplepie.php")]){if(!e.fileExists(r))continue;let a=e.readFileAsText(r);a.includes("function SimplePie_File(")&&!a.includes("/* pg_no_fetch */")&&(a=a.replace(/function SimplePie_File\([^)]*\)\s*\{/,l=>l+`
|
|
680
|
+
/* pg_no_fetch */
|
|
681
|
+
$this->error = 'Network requests disabled in Playground';
|
|
682
|
+
$this->success = false;
|
|
683
|
+
return;`),await e.writeFile(r,a))}}async function Y(e,t){const i=[["function wp_new_blog_notification","pg_no_blog_notification"],["function wp_install_maybe_enable_pretty_permalinks","pg_no_permalink_check"]],n=[o.joinPaths(t,"wp-admin/includes/upgrade.php"),o.joinPaths(t,"wp-admin/upgrade-functions.php")];for(const s of n){if(!e.fileExists(s))continue;let r=e.readFileAsText(s),a=!1;for(const[l,_]of i){if(r.includes(`/* ${_} */`))continue;const c=r.indexOf(l);if(c===-1)continue;const u=r.indexOf("{",c);u!==-1&&(r=r.substring(0,u+1)+` /* ${_} */ return;`+r.substring(u+1),a=!0)}a&&await e.writeFile(s,r)}}async function K(e,t){const i=o.joinPaths(t,"wp-load.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i);if(!n.includes("error_reporting(")||n.includes("~8192")&&n.includes("~2048"))return;const s=n.replace(/error_reporting\(([^)]+)\)/g,(r,a)=>`error_reporting((${a}) & ~8192 & ~2048)`);await e.writeFile(i,s)}async function Q(e,t){const i=o.joinPaths(t,"wp-admin/menu.php");if(e.fileExists(i)){const r=e.readFileAsText(i);if(!r.includes("/* pg_wp10_logo_link */")){const a='<h1 id="wphead"><a href="http://wordpress.org" rel="external">WordPress</a></h1>';if(r.includes(a)){const l=r.replace(a,'<h1 id="wphead"><a href="#" rel="external">WordPress</a></h1> <!-- pg_wp10_logo_link -->');l!==r&&await e.writeFile(i,l)}}}const n=o.joinPaths(t,"wp-admin/admin-header.php");if(e.fileExists(n)){const r=e.readFileAsText(n);if(!r.includes("/* pg_wp12_logo_link */")){const a='<a href="http://wordpress.org" rel="external"',l="</a>",_=r.indexOf(a);if(_!==-1){const c=r.indexOf(l,_);if(c!==-1){const u=r.substring(0,_)+'<a href="#">WordPress</a><!-- pg_wp12_logo_link -->'+r.substring(c+l.length);u!==r&&await e.writeFile(n,u)}}}}const s=o.joinPaths(t,"wp-admin/admin-footer.php");if(e.fileExists(s)){const r=e.readFileAsText(s);if(!r.includes("/* pg_wp10_footer_link */")){const a=r.replace('<a href="http://wordpress.org">WordPress</a>',"WordPress<!-- pg_wp10_footer_link -->").replace('<a href="http://wordpress.org/">WordPress</a>',"WordPress<!-- pg_wp10_footer_link -->");a!==r&&await e.writeFile(s,a)}}}async function z(e,t){const i=o.joinPaths(t,"wp-admin/edit.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i);if(n.includes("/* pg_wp10_post_title_edit */"))return;let s=n;const r='<strong><a href="<?php permalink_link(); ?>" rel="permalink"><?php the_title() ?></a></strong>';s.includes(r)&&(s=s.replace(r,'<strong><a href="post.php?action=edit&post=<?php echo $id /* pg_wp10_post_title_edit */ ?>"><?php the_title() ?></a></strong>'));const a='<td><a href="<?php the_permalink(); ?>" rel="permalink">';s.includes(a)&&(s=s.replace(a,'<td><a href="post.php?action=edit&post=<?php echo $id /* pg_wp10_post_title_edit */ ?>">'));const l=`<td><?php the_title() ?>
|
|
684
|
+
<?php if ('private' == $post->post_status) _e(' - <strong>Private</strong>'); ?></td>`;s.includes(l)&&(s=s.replace(l,`<td><a href="post.php?action=edit&post=<?php echo $id /* pg_wp10_post_title_edit */ ?>"><?php the_title() ?></a>
|
|
685
|
+
<?php if ('private' == $post->post_status) _e(' - <strong>Private</strong>'); ?></td>`)),s!==n&&await e.writeFile(i,s)}async function Z(e,t){const i=o.joinPaths(t,"wp-admin/includes/screen.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i);if(!n.includes("self::$this->_help_sidebar"))return;const s=n.replace(/self::\$this->_help_sidebar/g,"$this->_help_sidebar");s!==n&&await e.writeFile(i,s)}async function J(e,t){const i=o.joinPaths(t,"wp-admin/plugins.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i);if(n.includes("/* pg_wp21_active_plugins_array */"))return;const s="$current = get_option('active_plugins');";if(!n.includes(s))return;const r=n.replace(s,s+`
|
|
686
|
+
if (!is_array($current)) $current = array(); /* pg_wp21_active_plugins_array */`);r!==n&&await e.writeFile(i,r)}async function ee(e,t){const i=o.joinPaths(t,"wp-login.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i),s="AND user_pass = '$password'";if(!n.includes(s)||n.includes("pg_wp10_plain_or_md5"))return;let r=n.replace(s,"AND (user_pass = '$password' OR user_pass = MD5('$password')) /* pg_wp10_plain_or_md5 */");r=r.replace("$login->user_pass == $password","($login->user_pass == $password || $login->user_pass == md5($password))"),r!==n&&await e.writeFile(i,r)}async function te(e,t){const i=o.joinPaths(t,"wp-includes");if(!e.isDir(i))return;const n=o.joinPaths(i,"version.php");e.fileExists(n)||await e.writeFile(n,"<?php $wp_version = '1.0';")}async function ne(e,t){const i=o.joinPaths(t,"wp-blog-header.php");if(e.fileExists(i)){const s=e.readFileAsText(i),r=`$where .= ' AND (post_status = "publish"';`;s.includes(r)&&await e.writeFile(i,s.replace(r,`$where .= " AND (post_status = 'publish'";`))}const n=o.joinPaths(t,"wp-includes/vars.php");if(e.fileExists(n)){const s=e.readFileAsText(n),r="add_filter('all', 'wptexturize');";s.includes(r)&&await e.writeFile(n,s.replace(r,`// ${r} // Disabled by Playground: mangles SQL literals.`))}}async function ie(e,t){const i=o.joinPaths(t,"wp-load.php");e.fileExists(i)||await e.writeFile(i,`<?php
|
|
687
|
+
if ( !defined('ABSPATH') ) {
|
|
688
|
+
define('ABSPATH', dirname(__FILE__) . '/');
|
|
689
|
+
}
|
|
690
|
+
require_once(ABSPATH . 'wp-config.php');
|
|
691
|
+
`)}async function se(e,t){const i=o.joinPaths(t,"wp-settings.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i);let s=n;s=s.replace(/if\s*\(\s*!extension_loaded\('mysql'\)\s*\)\s*\n\s*die/,`if ( false ) // Patched for SQLite
|
|
692
|
+
die`),s=s.replace(/error_reporting\(([^)]+)\)/g,(r,a)=>a.includes("~8192")&&a.includes("~2048")?r:`error_reporting((${a}) & ~8192 & ~2048)`),s=s.replace(/set_magic_quotes_runtime\(\s*0\s*\)\s*;/g,"// set_magic_quotes_runtime(0); // Removed"),s.includes("function_exists('get_magic_quotes_gpc')")||(s=s.replace(/get_magic_quotes_gpc\(\)/g,"(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())")),s=s.replace(/=\s*&\s*new\b/g,"= new"),s=s.replace(/\$HTTP_SERVER_VARS/g,"$_SERVER"),!s.includes("WP_CONTENT_DIR")&&s.includes("define('WPINC'")&&(s=s.replace(/define\('WPINC',\s*'wp-includes'\);/,`define('WPINC', 'wp-includes');
|
|
693
|
+
if (!defined('WP_CONTENT_DIR')) define('WP_CONTENT_DIR', ABSPATH . 'wp-content');`)),s=s.replace(/unset\(\s*\$wp_filter\s*,/,"unset("),s=re(s),s=ae(s),s!==n&&await e.writeFile(i,s)}function re(e){const t=e.indexOf("installed WP");if(t===-1)return e;const i=e.lastIndexOf("die(",t);if(i===-1)return e;let n=0;for(let s=i+3;s<e.length;s++)if(e[s]==="(")n++;else if(e[s]===")"&&(n--,n===0)){let r=s+1;return e[r]===";"&&r++,e.substring(0,i)+"true; /* die removed by Playground */"+e.substring(r)}return e}function ae(e){return e.replace("do_action('init');",`// Remove hooks that make outbound HTTP requests (crash WASM).
|
|
694
|
+
if (function_exists('remove_action')) {
|
|
695
|
+
@remove_action('init', 'wp_cron');
|
|
696
|
+
@remove_action('init', 'wp_version_check');
|
|
697
|
+
@remove_action('init', 'wp_update_plugins');
|
|
698
|
+
@remove_action('init', 'wp_update_themes');
|
|
699
|
+
@remove_action('admin_init', '_maybe_update_plugins');
|
|
700
|
+
@remove_action('admin_init', '_maybe_update_themes');
|
|
701
|
+
@remove_action('admin_init', 'wp_version_check');
|
|
702
|
+
@remove_action('admin_init', 'wp_update_plugins');
|
|
703
|
+
@remove_action('admin_init', 'wp_update_themes');
|
|
704
|
+
@remove_action('load-plugins.php', 'wp_update_plugins');
|
|
705
|
+
@remove_action('load-update.php', 'wp_update_plugins');
|
|
706
|
+
@remove_action('load-update.php', 'wp_update_themes');
|
|
707
|
+
@remove_action('load-themes.php', 'wp_update_themes');
|
|
708
|
+
@remove_action('wp_update_plugins', 'wp_update_plugins');
|
|
709
|
+
@remove_action('wp_version_check', 'wp_version_check');
|
|
710
|
+
}
|
|
711
|
+
if (function_exists('add_filter')) {
|
|
712
|
+
function _pg_disable_curl() { return false; }
|
|
713
|
+
function _pg_disable_streams() { return false; }
|
|
714
|
+
@add_filter('use_curl_transport', '_pg_disable_curl');
|
|
715
|
+
@add_filter('use_streams_transport', '_pg_disable_streams');
|
|
716
|
+
@add_filter('use_ftp_transport', '_pg_disable_curl');
|
|
717
|
+
@add_filter('use_fsockopen_transport', '_pg_disable_streams');
|
|
718
|
+
}
|
|
719
|
+
do_action('init');`)}async function oe(e,t){const i=o.joinPaths(t,"wp-includes/functions.php");if(!e.fileExists(i))return;let n=e.readFileAsText(i),s=!1;n.includes("$all_options->{$option->option_name}")&&!n.includes("$all_options = new stdClass")&&(n=n.replace("foreach ($options as $option) {",`$all_options = new stdClass;
|
|
720
|
+
foreach ($options as $option) {`),s=!0),s&&await e.writeFile(i,n)}async function le(e,t){const i=o.joinPaths(t,"wp-admin/install.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i);let s=n;const r=o.joinPaths(t,"wp-admin");s=s.replace(/'\.\.\/(wp-config\.php)'/g,`'${t}/$1'`).replace(/'\.\.\/(wp-load\.php)'/g,`'${t}/$1'`).replace(/'\.\/(upgrade-functions\.php)'/g,`'${r}/$1'`).replace(/'(upgrade-functions\.php)'/g,`'${r}/$1'`).replace(/'\.\/(includes\/upgrade\.php)'/g,`'${r}/$1'`).replace(/'\.\.\/(wp-includes\/[^']+)'/g,`'${t}/$1'`),s=s.replace(/\$HTTP_GET_VARS/g,"$_GET").replace(/\$HTTP_POST_VARS/g,"$_POST"),s!==n&&await e.writeFile(i,s)}async function _e(e,t){const i=o.joinPaths(t,"wp-includes/wp-db.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i);let s=n;s.includes("isset($wpdb)")||(s=s.replace("$wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);","if ( !isset($wpdb) ) { $wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST); }")),s.includes("db_connect")||(s=s.replace(/\$this->dbh\s*=\s*@mysql_connect\(\$dbhost\s*,\s*\$dbuser\s*,\s*\$dbpassword(?:\s*,\s*true)?\);/,'if (method_exists($this, "db_connect")) { $this->dbname = $dbname; $this->db_connect(); } else { $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword); }')),s=ce(s),s!==n&&await e.writeFile(i,s)}function ce(e){const t=[];if(e.includes("function set_prefix")||t.push(`
|
|
721
|
+
function set_prefix($prefix) {
|
|
722
|
+
$this->prefix = $prefix;
|
|
723
|
+
$tables = array('posts', 'users', 'categories', 'post2cat', 'comments', 'link2cat', 'links', 'options', 'postmeta', 'usermeta', 'terms', 'term_taxonomy', 'term_relationships');
|
|
724
|
+
foreach ($tables as $t) {
|
|
725
|
+
$this->$t = $prefix . $t;
|
|
726
|
+
}
|
|
727
|
+
return $prefix;
|
|
728
|
+
}`),e.includes("function timer_start")||t.push(`
|
|
729
|
+
function timer_start() {
|
|
730
|
+
$this->time_start = microtime(true);
|
|
731
|
+
return true;
|
|
732
|
+
}`),e.includes("function timer_stop")||t.push(`
|
|
733
|
+
function timer_stop() {
|
|
734
|
+
return microtime(true) - $this->time_start;
|
|
735
|
+
}`),e.includes("function init_charset")||t.push(`
|
|
736
|
+
function init_charset() {
|
|
737
|
+
if (defined('DB_CHARSET')) $this->charset = DB_CHARSET;
|
|
738
|
+
if (defined('DB_COLLATE')) $this->collate = DB_COLLATE;
|
|
739
|
+
}`),e.includes("function bail")||t.push(`
|
|
740
|
+
function bail($message, $error_code = '500') {
|
|
741
|
+
die($message);
|
|
742
|
+
}`),e.includes("function check_connection")||t.push(`
|
|
743
|
+
function check_connection($allow_bail = true) {
|
|
744
|
+
return true;
|
|
745
|
+
}`),t.length===0)return e;const i=e.match(/^(\s*})\s*\n+(\$wpdb|\?>\s*$|if\s*\(\s*!\s*isset\(\s*\$wpdb\s*\))/m);if(!i||i.index===void 0)return e;const n=`
|
|
746
|
+
// Polyfills added by WordPress Playground.
|
|
747
|
+
`+t.join(`
|
|
748
|
+
`)+`
|
|
749
|
+
|
|
750
|
+
`;return e.substring(0,i.index)+n+e.substring(i.index)}async function ue(e,t){const i=a=>{let l=a,_=0;for(;l.startsWith("../");)_++,l=l.slice(3);for(;l.startsWith("./");)l=l.slice(2);let c="dirname(__FILE__)";for(let u=0;u<_;u++)c=`dirname(${c})`;return`${c} . '/${l}'`},n=o.joinPaths(t,"wp-admin");if(e.isDir(n))for(const a of e.listFiles(n)){if(!a.endsWith(".php"))continue;const l=o.joinPaths(n,a),_=e.readFileAsText(l),c=_.replace(/((?:require|include)(?:_once)?)\s*\(\s*(['"])(\.\.\/[^'"]+)\2\s*\)/g,(u,d,$,p)=>`${d}(${i(p)})`).replace(/((?:require|include)(?:_once)?)\s*\(\s*(['"])(\.\/[^'"]+)\2\s*\)/g,(u,d,$,p)=>`${d}(${i(p)})`).replace(/((?:require|include)(?:_once)?)\s*\(\s*(['"])([a-z][\w-]*\.php)\2\s*\)/g,(u,d,$,p)=>`${d}(${i(p)})`).replace(/((?:require|include)(?:_once)?)\s+(['"])(\.\.\/[^'"]+)\2/g,(u,d,$,p)=>`${d}(${i(p)})`).replace(/((?:require|include)(?:_once)?)\s+(['"])(\.\/[^'"]+)\2/g,(u,d,$,p)=>`${d}(${i(p)})`).replace(/((?:require|include)(?:_once)?)\s+(['"])([a-z][\w-]*\.php)\2/g,(u,d,$,p)=>`${d}(${i(p)})`).replace(/ABSPATH\s*\.\s*'\/wp-/g,"ABSPATH . 'wp-");c!==_&&await e.writeFile(l,c)}const s=o.joinPaths(t,"wp-admin/index.php");if(e.fileExists(s)){let a=e.readFileAsText(s);a.includes("get_settings('siteurl')")&&(a=a.replace(/get_settings\('siteurl'\)\s*\.\s*'\/wp-admin\//g,"'"),await e.writeFile(s,a))}const r=o.joinPaths(t,"wp-admin/menu.php");if(e.fileExists(r)){const a=e.readFileAsText(r),l="file('./menu.txt')";a.includes(l)&&await e.writeFile(r,a.replace(l,"file(dirname(__FILE__) . '/menu.txt')"))}}async function de(e,t){const i=o.joinPaths(t,"wp-admin/admin-functions.php");if(!e.fileExists(i))return;const n=e.readFileAsText(i);if(!n.includes("function check_admin_referer()")||!n.includes("$_SERVER['HTTP_REFERER']"))return;const s=pe(n,"check_admin_referer",`
|
|
751
|
+
do_action('check_admin_referer', '');
|
|
752
|
+
`);s!==n&&await e.writeFile(i,s)}function pe(e,t,i){const n=`function ${t}()`,s=e.indexOf(n);if(s===-1)return e;const r=e.indexOf("{",s+n.length);if(r===-1)return e;let a=1;for(let l=r+1;l<e.length;l++){const _=e[l];if(_==="{")a++;else if(_==="}"&&(a--,a===0))return e.substring(0,r+1)+i+e.substring(l)}return e}async function fe(e,t){const i=o.joinPaths(t,"wp-admin/index.php");if(e.fileExists(i)){const n=e.readFileAsText(i),s=n.replace(/AND post_date_gmt < '\$today'/,"");s!==n&&await e.writeFile(i,s)}await $e(e,t)}async function $e(e,t){const i=o.joinPaths(t,"wp-includes/rss-functions.php");if(!e.fileExists(i))return;let n=e.readFileAsText(i);!/^\s*error\s*\(/m.test(n)||/^function\s+error\s*\(/m.test(n)||(n=n.replace(/^(<\?php\s*)/,`$1
|
|
753
|
+
if (!function_exists('error')) {
|
|
754
|
+
function error($msg = '', $lvl = E_USER_WARNING) {
|
|
755
|
+
if (defined('MAGPIE_DEBUG') && MAGPIE_DEBUG) {
|
|
756
|
+
trigger_error($msg, $lvl);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
`),await e.writeFile(i,n))}async function he(e,t){const i=o.joinPaths(t,"wp-login.php");if(!e.fileExists(i))return;let n=e.readFileAsText(i),s=!1;for(const r of["log","pwd"]){const a=new RegExp(`(\\bname=(['"])${r}\\2)(?![^>]*data-1p-ignore)`);a.test(n)&&(n=n.replace(a,"$1 data-1p-ignore"),s=!0)}s&&await e.writeFile(i,n)}async function ge(e,t){const i=o.joinPaths(t,"wp-admin/admin.php");if(e.fileExists(i)){const s=e.readFileAsText(i);if(s.includes("auth_redirect()")){const r=`
|
|
761
|
+
// Playground: populate auth cookies and force admin user before auth_redirect.
|
|
762
|
+
if (defined('PLAYGROUND_AUTO_LOGIN_AS_USER')) {
|
|
763
|
+
if (function_exists('is_user_logged_in') && is_user_logged_in()) {
|
|
764
|
+
// On WP < 4.0, wp_set_auth_cookie() does not update $_COOKIE
|
|
765
|
+
// in-process — auth_redirect() reads $_COOKIE, so re-emit.
|
|
766
|
+
if (function_exists('wp_generate_auth_cookie') && defined('LOGGED_IN_COOKIE') && empty($_COOKIE[LOGGED_IN_COOKIE])) {
|
|
767
|
+
$_pg_uid = wp_get_current_user()->ID;
|
|
768
|
+
$_pg_exp = time() + 172800;
|
|
769
|
+
$_COOKIE[AUTH_COOKIE] = wp_generate_auth_cookie($_pg_uid, $_pg_exp, 'auth');
|
|
770
|
+
if (defined('SECURE_AUTH_COOKIE'))
|
|
771
|
+
$_COOKIE[SECURE_AUTH_COOKIE] = wp_generate_auth_cookie($_pg_uid, $_pg_exp, 'secure_auth');
|
|
772
|
+
$_COOKIE[LOGGED_IN_COOKIE] = wp_generate_auth_cookie($_pg_uid, $_pg_exp, 'logged_in');
|
|
773
|
+
}
|
|
774
|
+
} else {
|
|
775
|
+
${A("PLAYGROUND_AUTO_LOGIN_AS_USER")}
|
|
776
|
+
// WP 2.0-2.4: kses_init() runs during do_action('init') inside
|
|
777
|
+
// wp-settings.php and caches $current_user as WP_User(0) when
|
|
778
|
+
// no cookies were set yet. Reset and re-evaluate so capability
|
|
779
|
+
// checks see the user we just authenticated.
|
|
780
|
+
if (!function_exists('wp_generate_auth_cookie')) {
|
|
781
|
+
$GLOBALS['current_user'] = null;
|
|
782
|
+
if (function_exists('get_currentuserinfo')) {
|
|
783
|
+
get_currentuserinfo();
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
// Force admin caps in-memory: if populate_roles() never ran
|
|
788
|
+
// (e.g. WP 2.0, or WP 2.5 installs that crashed before writing
|
|
789
|
+
// roles), the user has no caps and every current_user_can() fails.
|
|
790
|
+
$_pg_cu = isset($GLOBALS['current_user']) ? $GLOBALS['current_user'] : null;
|
|
791
|
+
if ($_pg_cu && isset($_pg_cu->ID) && $_pg_cu->ID > 0 && empty($_pg_cu->allcaps['read'])) {
|
|
792
|
+
// Respect a DB-stored user_level so a blueprint that auto-logs
|
|
793
|
+
// in as a lower-privilege user doesn't silently get level 10.
|
|
794
|
+
$_pg_db_level = isset($_pg_cu->user_level)
|
|
795
|
+
? (int) $_pg_cu->user_level
|
|
796
|
+
: null;
|
|
797
|
+
if ($_pg_db_level === null && isset($_pg_user) && $_pg_user) {
|
|
798
|
+
$_pg_db_level = isset($_pg_user->user_level)
|
|
799
|
+
? (int) $_pg_user->user_level
|
|
800
|
+
: null;
|
|
801
|
+
}
|
|
802
|
+
$_pg_cu->user_level = $_pg_db_level !== null ? $_pg_db_level : 10;
|
|
803
|
+
$_pg_effective_level = $_pg_cu->user_level;
|
|
804
|
+
$_pg_caps = array('read');
|
|
805
|
+
for ($_pg_i = 0; $_pg_i <= $_pg_effective_level; $_pg_i++) {
|
|
806
|
+
$_pg_caps[] = 'level_' . $_pg_i;
|
|
807
|
+
}
|
|
808
|
+
if ($_pg_effective_level >= 10) {
|
|
809
|
+
$_pg_caps = array_merge($_pg_caps, array(
|
|
810
|
+
'switch_themes','edit_themes','activate_plugins',
|
|
811
|
+
'edit_plugins','edit_users','edit_files','manage_options',
|
|
812
|
+
'moderate_comments','manage_categories','manage_links',
|
|
813
|
+
'upload_files','import','unfiltered_html','edit_posts',
|
|
814
|
+
'edit_others_posts','edit_published_posts','publish_posts',
|
|
815
|
+
'edit_pages'));
|
|
816
|
+
}
|
|
817
|
+
foreach ($_pg_caps as $_pg_c) {
|
|
818
|
+
$_pg_cu->allcaps[$_pg_c] = true;
|
|
819
|
+
}
|
|
820
|
+
if ($_pg_effective_level >= 10) {
|
|
821
|
+
$_pg_cu->caps = array('administrator' => true);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
`,a=s.replace("auth_redirect();",r+"auth_redirect();");a!==s&&await e.writeFile(i,a)}}const n=o.joinPaths(t,"wp-admin/auth.php");if(e.fileExists(n)){const s=e.readFileAsText(n);if(s.includes("$cookiehash")&&!s.includes("Playground: bypass auth")){const r=`<?php
|
|
826
|
+
require_once(ABSPATH . 'wp-config.php');
|
|
827
|
+
// Playground: bypass auth and manually populate user globals.
|
|
828
|
+
global $user_login, $userdata, $user_level, $user_ID,
|
|
829
|
+
$user_nickname, $user_email, $user_url, $user_pass_md5, $cookiehash;
|
|
830
|
+
$__pg_user_login = defined('PLAYGROUND_AUTO_LOGIN_AS_USER')
|
|
831
|
+
? PLAYGROUND_AUTO_LOGIN_AS_USER
|
|
832
|
+
: 'admin';
|
|
833
|
+
$__pg_cookiehash = defined('COOKIEHASH')
|
|
834
|
+
? COOKIEHASH
|
|
835
|
+
: (isset($cookiehash) && $cookiehash
|
|
836
|
+
? $cookiehash
|
|
837
|
+
: md5(function_exists('get_settings') ? get_settings('siteurl') : ''));
|
|
838
|
+
if ($__pg_cookiehash) {
|
|
839
|
+
$_COOKIE['wordpressuser_' . $__pg_cookiehash] = $__pg_user_login;
|
|
840
|
+
}
|
|
841
|
+
if (function_exists('get_userdatabylogin')) {
|
|
842
|
+
$__pg_userdata = get_userdatabylogin($__pg_user_login);
|
|
843
|
+
if ($__pg_userdata) {
|
|
844
|
+
$user_login = $__pg_user_login;
|
|
845
|
+
$userdata = $__pg_userdata;
|
|
846
|
+
$user_level = isset($__pg_userdata->user_level)
|
|
847
|
+
? (int) $__pg_userdata->user_level
|
|
848
|
+
: 10;
|
|
849
|
+
$user_ID = $__pg_userdata->ID;
|
|
850
|
+
$user_nickname = isset($__pg_userdata->user_nickname)
|
|
851
|
+
? $__pg_userdata->user_nickname
|
|
852
|
+
: $__pg_user_login;
|
|
853
|
+
$user_email = isset($__pg_userdata->user_email)
|
|
854
|
+
? $__pg_userdata->user_email
|
|
855
|
+
: '';
|
|
856
|
+
$user_url = isset($__pg_userdata->user_url)
|
|
857
|
+
? $__pg_userdata->user_url
|
|
858
|
+
: '';
|
|
859
|
+
$user_pass_md5 = md5(
|
|
860
|
+
isset($__pg_userdata->user_pass) ? $__pg_userdata->user_pass : ''
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
?>`;r!==s&&await e.writeFile(n,r)}}}async function me(e,t){const i=o.joinPaths(t,"wp-admin/admin-ajax.php");if(!e.fileExists(i))return;let n=e.readFileAsText(i);if(!n.includes("is_user_logged_in"))return;const s=`
|
|
865
|
+
// Playground: authenticate admin user for AJAX requests on WP < 2.8.
|
|
866
|
+
if (defined('PLAYGROUND_AUTO_LOGIN_AS_USER')) {
|
|
867
|
+
${A("PLAYGROUND_AUTO_LOGIN_AS_USER")}
|
|
868
|
+
}
|
|
869
|
+
`;n=n.replace(/if\s*\(\s*!\s*is_user_logged_in\(\)\s*\)/,s+"if ( !is_user_logged_in() )"),await e.writeFile(i,n)}function A(e){return`
|
|
870
|
+
$_pg_user = null;
|
|
871
|
+
if (function_exists('wp_generate_auth_cookie')) {
|
|
872
|
+
$_pg_user = function_exists('get_user_by')
|
|
873
|
+
? get_user_by('login', ${e})
|
|
874
|
+
: (function_exists('get_userdatabylogin')
|
|
875
|
+
? get_userdatabylogin(${e}) : null);
|
|
876
|
+
if ($_pg_user) {
|
|
877
|
+
wp_set_current_user($_pg_user->ID, $_pg_user->user_login);
|
|
878
|
+
$_pg_exp = time() + 172800;
|
|
879
|
+
if (defined('AUTH_COOKIE'))
|
|
880
|
+
$_COOKIE[AUTH_COOKIE] = wp_generate_auth_cookie($_pg_user->ID, $_pg_exp, 'auth');
|
|
881
|
+
if (defined('SECURE_AUTH_COOKIE'))
|
|
882
|
+
$_COOKIE[SECURE_AUTH_COOKIE] = wp_generate_auth_cookie($_pg_user->ID, $_pg_exp, 'secure_auth');
|
|
883
|
+
if (defined('LOGGED_IN_COOKIE'))
|
|
884
|
+
$_COOKIE[LOGGED_IN_COOKIE] = wp_generate_auth_cookie($_pg_user->ID, $_pg_exp, 'logged_in');
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
`}async function we(e,t){const i=E(e,t);if(i===null)return;const n=parseFloat(i);if(!Number.isFinite(n)||n>=3.3)return;const s=o.joinPaths(t,"wp-admin/includes/schema.php");if(!e.fileExists(s))return;const r=e.readFileAsText(s);/\$wp_queries\s*=\s*"CREATE TABLE/.test(r)&&!r.includes("function wp_get_db_schema")&&await Ee(e,t,s,r)}async function Ee(e,t,i,n){const s=n.match(/\$wp_queries\s*=\s*"CREATE TABLE/);if(!s||s.index===void 0)return;const r=s.index,a='";',l=n.indexOf(a,r);if(l===-1)return;const _=l+a.length,u=`function wp_get_db_schema( $scope = 'all', $blog_id = null ) {
|
|
888
|
+
global $wpdb, $wp_queries, $charset_collate;
|
|
889
|
+
$charset_collate = '';
|
|
890
|
+
if ( ! empty($wpdb->charset) )
|
|
891
|
+
$charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
|
|
892
|
+
if ( ! empty($wpdb->collate) )
|
|
893
|
+
$charset_collate .= " COLLATE $wpdb->collate";
|
|
894
|
+
${n.substring(r,_)}
|
|
895
|
+
return $wp_queries;
|
|
896
|
+
}`,d=n.substring(0,r)+u+n.substring(_);await e.writeFile(i,d);const $=o.joinPaths(t,"wp-admin/includes/upgrade.php");if(e.fileExists($)){const p=e.readFileAsText($),P=p.replace(/(\$alterations\s*=\s*dbDelta\(\s*\$wp_queries\s*\))/g,"if ( function_exists('wp_get_db_schema') ) { $wp_queries = wp_get_db_schema(); } $1");P!==p&&await e.writeFile($,P)}}function Te(){return`<?php
|
|
897
|
+
// @playground-managed — Playground-generated db.php.
|
|
898
|
+
// WP < 3.0 loads only db.php and skips wp-db.php, so we pull
|
|
899
|
+
// in the wpdb class definition explicitly.
|
|
900
|
+
if (defined('ABSPATH') && defined('WPINC') && !class_exists('wpdb', false)) {
|
|
901
|
+
require_once(ABSPATH . WPINC . '/wp-db.php');
|
|
902
|
+
}
|
|
903
|
+
// Old wpdb (WP < 3.0) has no db_connect() and calls mysql_connect()
|
|
904
|
+
// inline, so the SQLite driver never gets a chance to attach. Load
|
|
905
|
+
// the integration here and reinitialise to swap the dbh in place.
|
|
906
|
+
if (
|
|
907
|
+
class_exists('wpdb', false) &&
|
|
908
|
+
isset($GLOBALS['wpdb']) &&
|
|
909
|
+
!($GLOBALS['wpdb'] instanceof wpdb) &&
|
|
910
|
+
!method_exists('wpdb', 'db_connect') &&
|
|
911
|
+
file_exists('/internal/shared/mu-plugins/sqlite-database-integration.php')
|
|
912
|
+
) {
|
|
913
|
+
require_once '/internal/shared/mu-plugins/sqlite-database-integration.php';
|
|
914
|
+
if (
|
|
915
|
+
isset($GLOBALS['wpdb']) &&
|
|
916
|
+
$GLOBALS['wpdb'] instanceof wpdb &&
|
|
917
|
+
method_exists($GLOBALS['wpdb'], 'reinitialize_sqlite')
|
|
918
|
+
) {
|
|
919
|
+
$GLOBALS['wpdb']->reinitialize_sqlite();
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
// Remaining mysqli_* stubs not covered by the 0-sqlite.php preload.
|
|
923
|
+
// WP 4.x's extension_loaded('mysqli') check expects these to exist.
|
|
924
|
+
if (!function_exists('mysqli_real_connect')) {
|
|
925
|
+
function mysqli_real_connect() { return true; }
|
|
926
|
+
}
|
|
927
|
+
if (!function_exists('mysqli_error')) {
|
|
928
|
+
function mysqli_error() { return ''; }
|
|
929
|
+
}
|
|
930
|
+
if (!function_exists('mysqli_errno')) {
|
|
931
|
+
function mysqli_errno() { return 0; }
|
|
932
|
+
}
|
|
933
|
+
if (!function_exists('mysqli_query')) {
|
|
934
|
+
function mysqli_query() { return false; }
|
|
935
|
+
}
|
|
936
|
+
if (!function_exists('mysqli_set_charset')) {
|
|
937
|
+
function mysqli_set_charset() { return true; }
|
|
938
|
+
}
|
|
939
|
+
if (!function_exists('mysqli_select_db')) {
|
|
940
|
+
function mysqli_select_db() { return true; }
|
|
941
|
+
}
|
|
942
|
+
if (!function_exists('mysqli_close')) {
|
|
943
|
+
function mysqli_close() { return true; }
|
|
944
|
+
}
|
|
945
|
+
`}async function Le(e,t){let i=null;const n=o.joinPaths(e.documentRoot,"wp-includes/version.php");if(e.fileExists(n)){const r=e.readFileAsText(n).match(/\$wp_version\s*=\s*['"]([^'"]+)['"]/);r&&(i=r[1])}const s=i!==null&&parseFloat(i)<3.5;try{await e.run({code:`<?php
|
|
946
|
+
// WP_INSTALLING bypasses WP 1.x's "not installed" die() in wp-settings.php.
|
|
947
|
+
define('WP_INSTALLING', true);
|
|
948
|
+
error_reporting(${T});
|
|
949
|
+
ini_set('display_errors', '0');
|
|
950
|
+
ob_start();
|
|
951
|
+
$_pg_db_path = getenv('DOCUMENT_ROOT') . '/wp-content/database/.ht.sqlite';
|
|
952
|
+
if (!file_exists($_pg_db_path)) { exit; }
|
|
953
|
+
$_pg_pdo = new PDO('sqlite:' . $_pg_db_path);
|
|
954
|
+
$_pg_check = $_pg_pdo->query("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='wp_users'")->fetchColumn();
|
|
955
|
+
$_pg_pdo = null;
|
|
956
|
+
if (!$_pg_check) { exit; }
|
|
957
|
+
$wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
|
|
958
|
+
if (!file_exists($wp_load)) { exit; }
|
|
959
|
+
require $wp_load;
|
|
960
|
+
ob_clean();
|
|
961
|
+
global $wpdb;
|
|
962
|
+
if (!isset($wpdb) || !method_exists($wpdb, 'query')) { exit; }
|
|
963
|
+
|
|
964
|
+
// Persist the scoped siteurl/home to the DB so parse_request()
|
|
965
|
+
// strips the scope prefix from REQUEST_URI. Filters alone
|
|
966
|
+
// (env.php) aren't enough on WP < 2.2.
|
|
967
|
+
$_pg_opts = !empty($wpdb->options) ? $wpdb->options : $GLOBALS['table_prefix'] . 'options';
|
|
968
|
+
try {
|
|
969
|
+
$_pg_url = getenv('PLAYGROUND_SITE_URL');
|
|
970
|
+
if ($_pg_url) {
|
|
971
|
+
$_pg_current = $wpdb->get_var("SELECT option_value FROM {$_pg_opts} WHERE option_name = 'siteurl'");
|
|
972
|
+
if ($_pg_current !== $_pg_url) {
|
|
973
|
+
$wpdb->query("UPDATE {$_pg_opts} SET option_value = '{$_pg_url}' WHERE option_name = 'siteurl'");
|
|
974
|
+
$wpdb->query("UPDATE {$_pg_opts} SET option_value = '{$_pg_url}' WHERE option_name = 'home'");
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
} catch (Exception $e) {}
|
|
978
|
+
|
|
979
|
+
// $wpdb->users exists on WP 1.5+; older WP needs the prefix.
|
|
980
|
+
$users_table = !empty($wpdb->users) ? $wpdb->users : $GLOBALS['table_prefix'] . 'users';
|
|
981
|
+
|
|
982
|
+
// WP 1.0/1.2 installers often leave the users table or admin row missing.
|
|
983
|
+
$wpdb->query("CREATE TABLE IF NOT EXISTS {$users_table} (
|
|
984
|
+
ID int(10) unsigned NOT NULL auto_increment,
|
|
985
|
+
user_login varchar(20) NOT NULL default '',
|
|
986
|
+
user_pass varchar(64) NOT NULL default '',
|
|
987
|
+
user_firstname varchar(50) NOT NULL default '',
|
|
988
|
+
user_lastname varchar(50) NOT NULL default '',
|
|
989
|
+
user_nickname varchar(50) NOT NULL default '',
|
|
990
|
+
user_icq int(10) unsigned NOT NULL default '0',
|
|
991
|
+
user_email varchar(100) NOT NULL default '',
|
|
992
|
+
user_url varchar(100) NOT NULL default '',
|
|
993
|
+
user_ip varchar(15) NOT NULL default '',
|
|
994
|
+
user_domain varchar(200) NOT NULL default '',
|
|
995
|
+
user_browser varchar(200) NOT NULL default '',
|
|
996
|
+
dateYMDhour datetime NOT NULL default '0000-00-00 00:00:00',
|
|
997
|
+
user_level int(2) unsigned NOT NULL default '0',
|
|
998
|
+
user_aim varchar(50) NOT NULL default '',
|
|
999
|
+
user_msn varchar(100) NOT NULL default '',
|
|
1000
|
+
user_yim varchar(50) NOT NULL default '',
|
|
1001
|
+
user_idmode varchar(20) NOT NULL default '',
|
|
1002
|
+
PRIMARY KEY (ID),
|
|
1003
|
+
UNIQUE KEY user_login (user_login)
|
|
1004
|
+
)");
|
|
1005
|
+
if (!$wpdb->get_var("SELECT COUNT(*) FROM {$users_table}")) {
|
|
1006
|
+
$now = date('Y-m-d H:i:s');
|
|
1007
|
+
$wpdb->query(
|
|
1008
|
+
"INSERT INTO {$users_table} (ID, user_login, user_pass, user_email, user_level, dateYMDhour, user_nickname) " .
|
|
1009
|
+
"VALUES (1, 'admin', MD5('password'), 'admin@localhost.com', 10, '{$now}', 'admin')"
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
$wpdb->query(
|
|
1013
|
+
"UPDATE {$users_table} SET user_pass = MD5('password') WHERE user_login = 'admin'"
|
|
1014
|
+
);
|
|
1015
|
+
|
|
1016
|
+
// populate_roles() can fail on SQLite; seed the admin role and caps directly.
|
|
1017
|
+
$p = $GLOBALS['table_prefix'];
|
|
1018
|
+
$roles_key = $p . 'user_roles';
|
|
1019
|
+
try {
|
|
1020
|
+
$has_roles = $wpdb->get_var(
|
|
1021
|
+
"SELECT COUNT(*) FROM {$p}options WHERE option_name = '{$roles_key}'"
|
|
1022
|
+
);
|
|
1023
|
+
} catch (Exception $e) {
|
|
1024
|
+
$has_roles = 0;
|
|
1025
|
+
}
|
|
1026
|
+
if (!$has_roles) {
|
|
1027
|
+
$roles = array('administrator' => array(
|
|
1028
|
+
'name' => 'Administrator',
|
|
1029
|
+
'capabilities' => array(
|
|
1030
|
+
'switch_themes'=>true, 'edit_themes'=>true,
|
|
1031
|
+
'activate_plugins'=>true, 'edit_plugins'=>true,
|
|
1032
|
+
'edit_users'=>true, 'edit_files'=>true,
|
|
1033
|
+
'manage_options'=>true, 'moderate_comments'=>true,
|
|
1034
|
+
'manage_categories'=>true, 'manage_links'=>true,
|
|
1035
|
+
'upload_files'=>true, 'import'=>true,
|
|
1036
|
+
'unfiltered_html'=>true, 'edit_posts'=>true,
|
|
1037
|
+
'edit_others_posts'=>true, 'edit_published_posts'=>true,
|
|
1038
|
+
'publish_posts'=>true, 'edit_pages'=>true,
|
|
1039
|
+
'read'=>true, 'level_10'=>true, 'level_9'=>true,
|
|
1040
|
+
'level_8'=>true, 'level_7'=>true, 'level_6'=>true,
|
|
1041
|
+
'level_5'=>true, 'level_4'=>true, 'level_3'=>true,
|
|
1042
|
+
'level_2'=>true, 'level_1'=>true, 'level_0'=>true,
|
|
1043
|
+
'edit_others_pages'=>true, 'edit_published_pages'=>true,
|
|
1044
|
+
'publish_pages'=>true, 'delete_pages'=>true,
|
|
1045
|
+
'delete_others_pages'=>true, 'delete_published_pages'=>true,
|
|
1046
|
+
'delete_posts'=>true, 'delete_others_posts'=>true,
|
|
1047
|
+
'delete_published_posts'=>true, 'delete_private_posts'=>true,
|
|
1048
|
+
'edit_private_posts'=>true, 'read_private_posts'=>true,
|
|
1049
|
+
'delete_private_pages'=>true, 'edit_private_pages'=>true,
|
|
1050
|
+
'read_private_pages'=>true,
|
|
1051
|
+
)
|
|
1052
|
+
));
|
|
1053
|
+
$wpdb->query("INSERT INTO {$p}options (option_name, option_value, autoload) VALUES ('{$roles_key}', '" . addslashes(serialize($roles)) . "', 'yes')");
|
|
1054
|
+
}
|
|
1055
|
+
$um = isset($wpdb->usermeta) ? $wpdb->usermeta : $p . 'usermeta';
|
|
1056
|
+
try {
|
|
1057
|
+
$has_cap = $wpdb->get_var("SELECT COUNT(*) FROM {$um} WHERE user_id=1 AND meta_key='{$p}capabilities'");
|
|
1058
|
+
if (!$has_cap) {
|
|
1059
|
+
$cap_val = addslashes(serialize(array('administrator' => true)));
|
|
1060
|
+
$wpdb->query("INSERT INTO {$um} (user_id, meta_key, meta_value) VALUES (1, '{$p}capabilities', '{$cap_val}')");
|
|
1061
|
+
}
|
|
1062
|
+
$has_level = $wpdb->get_var("SELECT COUNT(*) FROM {$um} WHERE user_id=1 AND meta_key='{$p}user_level'");
|
|
1063
|
+
if (!$has_level) {
|
|
1064
|
+
$wpdb->query("INSERT INTO {$um} (user_id, meta_key, meta_value) VALUES (1, '{$p}user_level', '10')");
|
|
1065
|
+
}
|
|
1066
|
+
} catch (Exception $e) {}
|
|
1067
|
+
|
|
1068
|
+
// Seed default content when the install left the posts table empty.
|
|
1069
|
+
$posts_table = !empty($wpdb->posts) ? $wpdb->posts : $GLOBALS['table_prefix'] . 'posts';
|
|
1070
|
+
$has_posts = false;
|
|
1071
|
+
try { $has_posts = (bool)$wpdb->get_var("SELECT COUNT(*) FROM {$posts_table}"); } catch (Exception $e) {}
|
|
1072
|
+
if (!$has_posts) {
|
|
1073
|
+
$now = date('Y-m-d H:i:s');
|
|
1074
|
+
$now_gmt = gmdate('Y-m-d H:i:s');
|
|
1075
|
+
if (isset($wpdb->categories)) {
|
|
1076
|
+
$wpdb->query("INSERT INTO {$wpdb->categories} (cat_ID, cat_name, category_nicename, category_description, category_parent) VALUES (1, 'Uncategorized', 'uncategorized', '', 0)");
|
|
1077
|
+
}
|
|
1078
|
+
// Columns common to WP 1.0+.
|
|
1079
|
+
$wpdb->query("INSERT INTO {$posts_table} (ID, post_author, post_date, post_date_gmt, post_content, post_title, post_excerpt, post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_content_filtered) VALUES (1, 1, '{$now}', '{$now_gmt}', 'Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!', 'Hello world!', '', 'publish', 'open', 'open', '', 'hello-world', '', '', '{$now}', '{$now_gmt}', '')");
|
|
1080
|
+
if (isset($wpdb->comments)) {
|
|
1081
|
+
$wpdb->query("INSERT INTO {$wpdb->comments} (comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_author_IP, comment_date, comment_date_gmt, comment_content, comment_karma, comment_approved, comment_agent, comment_type, comment_parent, user_id) VALUES (1, 'Mr WordPress', '', 'http://wordpress.org', '127.0.0.1', '{$now}', '{$now_gmt}', 'Hi, this is a comment. To delete a comment, just log in and view the post comments. There you will have the option to edit or delete them.', 0, '1', '', '', 0, 0)");
|
|
1082
|
+
}
|
|
1083
|
+
if (isset($wpdb->post2cat)) {
|
|
1084
|
+
$wpdb->query("INSERT INTO {$wpdb->post2cat} (rel_id, post_id, category_id) VALUES (1, 1, 1)");
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
`,env:{DOCUMENT_ROOT:e.documentRoot,PLAYGROUND_SITE_URL:t||""}})}catch(r){h.logger.warn("Legacy WP post-install fixups failed (non-fatal):",r)}if(s)try{await e.run({code:`<?php
|
|
1088
|
+
$db_dir = getenv('DOCUMENT_ROOT') . '/wp-content/database/';
|
|
1089
|
+
if (!is_dir($db_dir)) { @mkdir($db_dir, 0777, true); }
|
|
1090
|
+
$db_path = $db_dir . '.ht.sqlite';
|
|
1091
|
+
$pdo = new PDO('sqlite:' . $db_path);
|
|
1092
|
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
1093
|
+
|
|
1094
|
+
$prefix = 'wp_';
|
|
1095
|
+
$table = $prefix . 'users';
|
|
1096
|
+
try {
|
|
1097
|
+
$count = $pdo->query("SELECT COUNT(*) FROM {$table}")->fetchColumn();
|
|
1098
|
+
} catch (Exception $e) {
|
|
1099
|
+
$pdo->exec("CREATE TABLE IF NOT EXISTS {$table} (
|
|
1100
|
+
ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1101
|
+
user_login TEXT NOT NULL DEFAULT '',
|
|
1102
|
+
user_pass TEXT NOT NULL DEFAULT '',
|
|
1103
|
+
user_nickname TEXT NOT NULL DEFAULT '',
|
|
1104
|
+
user_email TEXT NOT NULL DEFAULT '',
|
|
1105
|
+
user_url TEXT NOT NULL DEFAULT '',
|
|
1106
|
+
user_ip TEXT NOT NULL DEFAULT '',
|
|
1107
|
+
user_domain TEXT NOT NULL DEFAULT '',
|
|
1108
|
+
user_browser TEXT NOT NULL DEFAULT '',
|
|
1109
|
+
dateYMDhour TEXT NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
1110
|
+
user_level INTEGER NOT NULL DEFAULT 0,
|
|
1111
|
+
user_idmode TEXT NOT NULL DEFAULT '',
|
|
1112
|
+
user_firstname TEXT NOT NULL DEFAULT '',
|
|
1113
|
+
user_lastname TEXT NOT NULL DEFAULT '',
|
|
1114
|
+
user_icq INTEGER NOT NULL DEFAULT 0,
|
|
1115
|
+
user_aim TEXT NOT NULL DEFAULT '',
|
|
1116
|
+
user_msn TEXT NOT NULL DEFAULT '',
|
|
1117
|
+
user_yim TEXT NOT NULL DEFAULT ''
|
|
1118
|
+
)");
|
|
1119
|
+
$count = 0;
|
|
1120
|
+
}
|
|
1121
|
+
if ($count == 0) {
|
|
1122
|
+
$now = date('Y-m-d H:i:s');
|
|
1123
|
+
// SECURITY: md5('password') matches WP 1.0-1.2's single-md5
|
|
1124
|
+
// scheme so auto-login works without a blueprint password.
|
|
1125
|
+
// Safe only inside the Playground WASM sandbox.
|
|
1126
|
+
$pass = md5('password');
|
|
1127
|
+
try {
|
|
1128
|
+
$col_info = $pdo->query("PRAGMA table_info({$table})")->fetchAll(PDO::FETCH_ASSOC);
|
|
1129
|
+
$known = array(
|
|
1130
|
+
'ID' => '1', 'user_login' => "'admin'",
|
|
1131
|
+
'user_pass' => "'{$pass}'", 'user_email' => "'admin@localhost.com'",
|
|
1132
|
+
'user_level' => '10', 'dateYMDhour' => "'{$now}'",
|
|
1133
|
+
'user_nickname' => "'admin'", 'user_nicename' => "'admin'",
|
|
1134
|
+
'user_registered' => "'{$now}'", 'user_status' => '0',
|
|
1135
|
+
);
|
|
1136
|
+
$ins_cols = array(); $ins_vals = array();
|
|
1137
|
+
foreach ($col_info as $ci) {
|
|
1138
|
+
$cn = $ci['name'];
|
|
1139
|
+
$ins_cols[] = $cn;
|
|
1140
|
+
if (isset($known[$cn])) {
|
|
1141
|
+
$ins_vals[] = $known[$cn];
|
|
1142
|
+
} elseif ($ci['dflt_value'] !== null) {
|
|
1143
|
+
$ins_vals[] = $ci['dflt_value'];
|
|
1144
|
+
} elseif (stripos($ci['type'], 'int') !== false) {
|
|
1145
|
+
$ins_vals[] = '0';
|
|
1146
|
+
} else {
|
|
1147
|
+
$ins_vals[] = "''";
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
$pdo->exec("INSERT INTO {$table} (" . implode(',', $ins_cols) . ") VALUES (" . implode(',', $ins_vals) . ")");
|
|
1151
|
+
} catch (Exception $e) {}
|
|
1152
|
+
} else {
|
|
1153
|
+
// See SECURITY note above.
|
|
1154
|
+
$pass = md5('password');
|
|
1155
|
+
try { $pdo->exec("UPDATE {$table} SET user_pass = '{$pass}' WHERE user_login = 'admin'"); } catch (Exception $e) {}
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// WP 1.0-1.2 install often leaves these tables missing because
|
|
1159
|
+
// the SQLite driver can't translate the old-style CREATE TABLEs.
|
|
1160
|
+
$now = date('Y-m-d H:i:s');
|
|
1161
|
+
$now_gmt = gmdate('Y-m-d H:i:s');
|
|
1162
|
+
$tables_sql = array(
|
|
1163
|
+
'posts' => "CREATE TABLE IF NOT EXISTS {$prefix}posts (
|
|
1164
|
+
ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1165
|
+
post_author INTEGER NOT NULL DEFAULT 0,
|
|
1166
|
+
post_date TEXT NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
1167
|
+
post_date_gmt TEXT NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
1168
|
+
post_content TEXT NOT NULL DEFAULT '',
|
|
1169
|
+
post_title TEXT NOT NULL DEFAULT '',
|
|
1170
|
+
post_category INTEGER NOT NULL DEFAULT 0,
|
|
1171
|
+
post_excerpt TEXT NOT NULL DEFAULT '',
|
|
1172
|
+
post_status TEXT NOT NULL DEFAULT 'publish',
|
|
1173
|
+
comment_status TEXT NOT NULL DEFAULT 'open',
|
|
1174
|
+
ping_status TEXT NOT NULL DEFAULT 'open',
|
|
1175
|
+
post_password TEXT NOT NULL DEFAULT '',
|
|
1176
|
+
post_name TEXT NOT NULL DEFAULT '',
|
|
1177
|
+
to_ping TEXT NOT NULL DEFAULT '',
|
|
1178
|
+
pinged TEXT NOT NULL DEFAULT '',
|
|
1179
|
+
post_modified TEXT NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
1180
|
+
post_modified_gmt TEXT NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
1181
|
+
post_content_filtered TEXT NOT NULL DEFAULT '',
|
|
1182
|
+
post_parent INTEGER NOT NULL DEFAULT 0,
|
|
1183
|
+
menu_order INTEGER NOT NULL DEFAULT 0,
|
|
1184
|
+
post_mime_type TEXT NOT NULL DEFAULT ''
|
|
1185
|
+
)",
|
|
1186
|
+
'categories' => "CREATE TABLE IF NOT EXISTS {$prefix}categories (
|
|
1187
|
+
cat_ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1188
|
+
cat_name TEXT NOT NULL DEFAULT '',
|
|
1189
|
+
category_nicename TEXT NOT NULL DEFAULT '',
|
|
1190
|
+
category_description TEXT NOT NULL DEFAULT '',
|
|
1191
|
+
category_parent INTEGER NOT NULL DEFAULT 0
|
|
1192
|
+
)",
|
|
1193
|
+
'post2cat' => "CREATE TABLE IF NOT EXISTS {$prefix}post2cat (
|
|
1194
|
+
rel_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1195
|
+
post_id INTEGER NOT NULL DEFAULT 0,
|
|
1196
|
+
category_id INTEGER NOT NULL DEFAULT 0
|
|
1197
|
+
)",
|
|
1198
|
+
'comments' => "CREATE TABLE IF NOT EXISTS {$prefix}comments (
|
|
1199
|
+
comment_ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1200
|
+
comment_post_ID INTEGER NOT NULL DEFAULT 0,
|
|
1201
|
+
comment_author TEXT NOT NULL DEFAULT '',
|
|
1202
|
+
comment_author_email TEXT NOT NULL DEFAULT '',
|
|
1203
|
+
comment_author_url TEXT NOT NULL DEFAULT '',
|
|
1204
|
+
comment_author_IP TEXT NOT NULL DEFAULT '',
|
|
1205
|
+
comment_date TEXT NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
1206
|
+
comment_date_gmt TEXT NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
1207
|
+
comment_content TEXT NOT NULL DEFAULT '',
|
|
1208
|
+
comment_karma INTEGER NOT NULL DEFAULT 0,
|
|
1209
|
+
comment_approved TEXT NOT NULL DEFAULT '1',
|
|
1210
|
+
comment_agent TEXT NOT NULL DEFAULT '',
|
|
1211
|
+
comment_type TEXT NOT NULL DEFAULT '',
|
|
1212
|
+
comment_parent INTEGER NOT NULL DEFAULT 0,
|
|
1213
|
+
user_id INTEGER NOT NULL DEFAULT 0
|
|
1214
|
+
)",
|
|
1215
|
+
'options' => "CREATE TABLE IF NOT EXISTS {$prefix}options (
|
|
1216
|
+
option_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1217
|
+
blog_id INTEGER NOT NULL DEFAULT 0,
|
|
1218
|
+
option_name TEXT NOT NULL DEFAULT '',
|
|
1219
|
+
option_can_override TEXT NOT NULL DEFAULT 'Y',
|
|
1220
|
+
option_type INTEGER NOT NULL DEFAULT 1,
|
|
1221
|
+
option_value TEXT NOT NULL DEFAULT '',
|
|
1222
|
+
option_width INTEGER NOT NULL DEFAULT 20,
|
|
1223
|
+
option_height INTEGER NOT NULL DEFAULT 8,
|
|
1224
|
+
option_description TEXT NOT NULL DEFAULT '',
|
|
1225
|
+
option_admin_level INTEGER NOT NULL DEFAULT 1,
|
|
1226
|
+
autoload TEXT NOT NULL DEFAULT 'yes'
|
|
1227
|
+
)",
|
|
1228
|
+
'postmeta' => "CREATE TABLE IF NOT EXISTS {$prefix}postmeta (
|
|
1229
|
+
meta_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1230
|
+
post_id INTEGER NOT NULL DEFAULT 0,
|
|
1231
|
+
meta_key TEXT NOT NULL DEFAULT '',
|
|
1232
|
+
meta_value TEXT NOT NULL DEFAULT ''
|
|
1233
|
+
)",
|
|
1234
|
+
'links' => "CREATE TABLE IF NOT EXISTS {$prefix}links (
|
|
1235
|
+
link_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1236
|
+
link_url TEXT NOT NULL DEFAULT '',
|
|
1237
|
+
link_name TEXT NOT NULL DEFAULT '',
|
|
1238
|
+
link_image TEXT NOT NULL DEFAULT '',
|
|
1239
|
+
link_target TEXT NOT NULL DEFAULT '',
|
|
1240
|
+
link_category INTEGER NOT NULL DEFAULT 0,
|
|
1241
|
+
link_description TEXT NOT NULL DEFAULT '',
|
|
1242
|
+
link_visible TEXT NOT NULL DEFAULT 'Y',
|
|
1243
|
+
link_owner INTEGER NOT NULL DEFAULT 1,
|
|
1244
|
+
link_rating INTEGER NOT NULL DEFAULT 0,
|
|
1245
|
+
link_updated TEXT NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
1246
|
+
link_rel TEXT NOT NULL DEFAULT '',
|
|
1247
|
+
link_notes TEXT NOT NULL DEFAULT '',
|
|
1248
|
+
link_rss TEXT NOT NULL DEFAULT ''
|
|
1249
|
+
)",
|
|
1250
|
+
'linkcategories' => "CREATE TABLE IF NOT EXISTS {$prefix}linkcategories (
|
|
1251
|
+
cat_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1252
|
+
cat_name TEXT NOT NULL DEFAULT '',
|
|
1253
|
+
auto_toggle TEXT NOT NULL DEFAULT 'N',
|
|
1254
|
+
show_images TEXT NOT NULL DEFAULT 'Y',
|
|
1255
|
+
show_description TEXT NOT NULL DEFAULT 'N',
|
|
1256
|
+
show_rating TEXT NOT NULL DEFAULT 'Y',
|
|
1257
|
+
show_updated TEXT NOT NULL DEFAULT 'Y',
|
|
1258
|
+
sort_order TEXT NOT NULL DEFAULT 'name',
|
|
1259
|
+
sort_desc TEXT NOT NULL DEFAULT 'ASC',
|
|
1260
|
+
text_before_link TEXT NOT NULL DEFAULT '<li>',
|
|
1261
|
+
text_after_link TEXT NOT NULL DEFAULT '<br />',
|
|
1262
|
+
text_after_all TEXT NOT NULL DEFAULT '</li>',
|
|
1263
|
+
list_limit INTEGER NOT NULL DEFAULT -1
|
|
1264
|
+
)",
|
|
1265
|
+
'optiongroups' => "CREATE TABLE IF NOT EXISTS {$prefix}optiongroups (
|
|
1266
|
+
group_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1267
|
+
group_name TEXT NOT NULL DEFAULT '',
|
|
1268
|
+
group_desc TEXT DEFAULT '',
|
|
1269
|
+
group_longdesc TEXT DEFAULT ''
|
|
1270
|
+
)",
|
|
1271
|
+
'optiongroup_options' => "CREATE TABLE IF NOT EXISTS {$prefix}optiongroup_options (
|
|
1272
|
+
group_id INTEGER NOT NULL DEFAULT 0,
|
|
1273
|
+
option_id INTEGER NOT NULL DEFAULT 0,
|
|
1274
|
+
seq INTEGER NOT NULL DEFAULT 0,
|
|
1275
|
+
PRIMARY KEY (group_id, option_id)
|
|
1276
|
+
)"
|
|
1277
|
+
);
|
|
1278
|
+
foreach ($tables_sql as $t => $sql) {
|
|
1279
|
+
try { $pdo->exec($sql); } catch (Exception $e) {}
|
|
1280
|
+
}
|
|
1281
|
+
// Backfill columns that WP 1.0-1.2 installs leave off but later code paths read.
|
|
1282
|
+
$alter_cols = array(
|
|
1283
|
+
'categories' => array(
|
|
1284
|
+
'category_nicename' => "TEXT NOT NULL DEFAULT ''",
|
|
1285
|
+
'category_description' => "TEXT NOT NULL DEFAULT ''",
|
|
1286
|
+
'category_parent' => "INTEGER NOT NULL DEFAULT 0",
|
|
1287
|
+
'category_count' => "INTEGER NOT NULL DEFAULT 0",
|
|
1288
|
+
),
|
|
1289
|
+
// WP 1.5+ get_comments_number() reads comment_count off wp_posts.
|
|
1290
|
+
'posts' => array(
|
|
1291
|
+
'comment_count' => "INTEGER NOT NULL DEFAULT 0",
|
|
1292
|
+
),
|
|
1293
|
+
);
|
|
1294
|
+
foreach ($alter_cols as $t => $cols_to_add) {
|
|
1295
|
+
try {
|
|
1296
|
+
$existing = $pdo->query("PRAGMA table_info({$prefix}{$t})")->fetchAll(PDO::FETCH_COLUMN, 1);
|
|
1297
|
+
foreach ($cols_to_add as $col => $type) {
|
|
1298
|
+
if (!in_array($col, $existing)) {
|
|
1299
|
+
$pdo->exec("ALTER TABLE {$prefix}{$t} ADD COLUMN {$col} {$type}");
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
} catch (Exception $e) {}
|
|
1303
|
+
}
|
|
1304
|
+
// Dynamic column detection because the schema differs across WP 1.x.
|
|
1305
|
+
try {
|
|
1306
|
+
if (!$pdo->query("SELECT COUNT(*) FROM {$prefix}posts")->fetchColumn()) {
|
|
1307
|
+
$post_cols = $pdo->query("PRAGMA table_info({$prefix}posts)")->fetchAll(PDO::FETCH_COLUMN, 1);
|
|
1308
|
+
$post_vals = array(
|
|
1309
|
+
'ID' => '1', 'post_author' => '1',
|
|
1310
|
+
'post_date' => "'{$now}'", 'post_date_gmt' => "'{$now_gmt}'",
|
|
1311
|
+
'post_content' => "'Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!'",
|
|
1312
|
+
'post_title' => "'Hello world!'", 'post_excerpt' => "''",
|
|
1313
|
+
'post_status' => "'publish'", 'comment_status' => "'open'",
|
|
1314
|
+
'ping_status' => "'open'", 'post_password' => "''",
|
|
1315
|
+
'post_name' => "'hello-world'", 'to_ping' => "''", 'pinged' => "''",
|
|
1316
|
+
'post_modified' => "'{$now}'", 'post_modified_gmt' => "'{$now_gmt}'",
|
|
1317
|
+
'post_content_filtered' => "''",
|
|
1318
|
+
);
|
|
1319
|
+
$ins_c = array(); $ins_v = array();
|
|
1320
|
+
foreach ($post_vals as $c => $v) {
|
|
1321
|
+
if (in_array($c, $post_cols)) { $ins_c[] = $c; $ins_v[] = $v; }
|
|
1322
|
+
}
|
|
1323
|
+
if ($ins_c) $pdo->exec("INSERT INTO {$prefix}posts (" . implode(',', $ins_c) . ") VALUES (" . implode(',', $ins_v) . ")");
|
|
1324
|
+
}
|
|
1325
|
+
} catch (Exception $e) {}
|
|
1326
|
+
try {
|
|
1327
|
+
if (!$pdo->query("SELECT COUNT(*) FROM {$prefix}categories")->fetchColumn()) {
|
|
1328
|
+
$pdo->exec("INSERT INTO {$prefix}categories (cat_ID, cat_name, category_nicename, category_description, category_parent) VALUES (1, 'Uncategorized', 'uncategorized', '', 0)");
|
|
1329
|
+
}
|
|
1330
|
+
} catch (Exception $e) {}
|
|
1331
|
+
try {
|
|
1332
|
+
$env_site = getenv('PLAYGROUND_SITE_URL');
|
|
1333
|
+
$site = $env_site ? $env_site : 'http://localhost';
|
|
1334
|
+
if (!$pdo->query("SELECT COUNT(*) FROM {$prefix}options WHERE option_name='siteurl'")->fetchColumn()) {
|
|
1335
|
+
$pdo->exec("INSERT INTO {$prefix}options (option_name, option_value) VALUES ('siteurl', '{$site}')");
|
|
1336
|
+
$pdo->exec("INSERT INTO {$prefix}options (option_name, option_value) VALUES ('blogname', 'My WordPress Website')");
|
|
1337
|
+
$pdo->exec("INSERT INTO {$prefix}options (option_name, option_value) VALUES ('blogdescription', 'Just another WordPress weblog')");
|
|
1338
|
+
$pdo->exec("INSERT INTO {$prefix}options (option_name, option_value) VALUES ('home', '{$site}')");
|
|
1339
|
+
}
|
|
1340
|
+
// Overwrite the placeholder 'http://localhost' with the scoped URL.
|
|
1341
|
+
if ($env_site) {
|
|
1342
|
+
$pdo->exec("UPDATE {$prefix}options SET option_value = '{$env_site}' WHERE option_name = 'siteurl'");
|
|
1343
|
+
$pdo->exec("UPDATE {$prefix}options SET option_value = '{$env_site}' WHERE option_name = 'home'");
|
|
1344
|
+
}
|
|
1345
|
+
// populate_options() sets template/stylesheet; backfill if it crashed.
|
|
1346
|
+
if (!$pdo->query("SELECT COUNT(*) FROM {$prefix}options WHERE option_name='template'")->fetchColumn()) {
|
|
1347
|
+
$themes_dir = getenv('DOCUMENT_ROOT') . '/wp-content/themes/';
|
|
1348
|
+
$tpl = 'default';
|
|
1349
|
+
if (is_dir($themes_dir)) {
|
|
1350
|
+
$entries = glob($themes_dir . '*', GLOB_ONLYDIR);
|
|
1351
|
+
if ($entries) {
|
|
1352
|
+
foreach ($entries as $e) {
|
|
1353
|
+
$name = basename($e);
|
|
1354
|
+
if ($name === '.' || $name === '..') continue;
|
|
1355
|
+
if (file_exists($e . '/style.css')) {
|
|
1356
|
+
$tpl = $name;
|
|
1357
|
+
break;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
$pdo->exec("INSERT INTO {$prefix}options (option_name, option_value, autoload) VALUES ('template', '{$tpl}', 'yes')");
|
|
1363
|
+
$pdo->exec("INSERT INTO {$prefix}options (option_name, option_value, autoload) VALUES ('stylesheet', '{$tpl}', 'yes')");
|
|
1364
|
+
}
|
|
1365
|
+
// Without a correct db_version, WP 2.0-2.5 admin redirects to upgrade.php.
|
|
1366
|
+
$version_path = getenv('DOCUMENT_ROOT') . '/wp-includes/version.php';
|
|
1367
|
+
if (file_exists($version_path)) {
|
|
1368
|
+
$wp_db_version = 0;
|
|
1369
|
+
include $version_path;
|
|
1370
|
+
if ($wp_db_version > 0) {
|
|
1371
|
+
$has_dbv = $pdo->query("SELECT COUNT(*) FROM {$prefix}options WHERE option_name='db_version'")->fetchColumn();
|
|
1372
|
+
if (!$has_dbv) {
|
|
1373
|
+
$pdo->exec("INSERT INTO {$prefix}options (option_name, option_value, autoload) VALUES ('db_version', '{$wp_db_version}', 'yes')");
|
|
1374
|
+
} else {
|
|
1375
|
+
$pdo->exec("UPDATE {$prefix}options SET option_value = '{$wp_db_version}' WHERE option_name = 'db_version'");
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
} catch (Exception $e) {}
|
|
1380
|
+
`,env:{DOCUMENT_ROOT:e.documentRoot,PLAYGROUND_SITE_URL:t||""}})}catch(r){h.logger.warn("Legacy WP PDO fallback failed (non-fatal):",r)}}const ye=`
|
|
1381
|
+
// Connection stubs — wpdb::__construct bails on a falsy return.
|
|
1382
|
+
if (!function_exists('mysqli_connect')) {
|
|
1383
|
+
function mysqli_connect() { return true; }
|
|
1384
|
+
}
|
|
1385
|
+
if (!function_exists('mysqli_init')) {
|
|
1386
|
+
function mysqli_init() { return true; }
|
|
1387
|
+
}
|
|
1388
|
+
if (!function_exists('mysql_connect')) {
|
|
1389
|
+
function mysql_connect() { return true; }
|
|
1390
|
+
}
|
|
1391
|
+
if (!function_exists('mysql_select_db')) {
|
|
1392
|
+
function mysql_select_db() { return true; }
|
|
1393
|
+
}
|
|
1394
|
+
// WordPress < 3.0 wpdb::__construct calls mysql_set_charset directly.
|
|
1395
|
+
if (!function_exists('mysql_set_charset')) {
|
|
1396
|
+
function mysql_set_charset() { return true; }
|
|
1397
|
+
}
|
|
1398
|
+
// Functional mysql_* stubs that delegate to $wpdb (SQLite driver).
|
|
1399
|
+
$GLOBALS['_mysql_results'] = array();
|
|
1400
|
+
$GLOBALS['_mysql_result_id'] = 0;
|
|
1401
|
+
if (!function_exists('mysql_query')) {
|
|
1402
|
+
function mysql_query($query, $link = null) {
|
|
1403
|
+
global $wpdb;
|
|
1404
|
+
if (isset($wpdb) && method_exists($wpdb, 'query')) {
|
|
1405
|
+
$wpdb->query($query);
|
|
1406
|
+
if (preg_match('/^\\s*(SELECT|SHOW|DESCRIBE|EXPLAIN)/i', $query)) {
|
|
1407
|
+
$rows = isset($wpdb->last_result) ? $wpdb->last_result : array();
|
|
1408
|
+
$id = ++$GLOBALS['_mysql_result_id'];
|
|
1409
|
+
$GLOBALS['_mysql_results'][$id] = array(
|
|
1410
|
+
'rows' => $rows,
|
|
1411
|
+
'index' => 0,
|
|
1412
|
+
);
|
|
1413
|
+
return $id;
|
|
1414
|
+
}
|
|
1415
|
+
return true;
|
|
1416
|
+
}
|
|
1417
|
+
return false;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
if (!function_exists('mysql_error')) {
|
|
1421
|
+
function mysql_error($link = null) {
|
|
1422
|
+
global $wpdb;
|
|
1423
|
+
if (isset($wpdb) && isset($wpdb->last_error)) {
|
|
1424
|
+
return $wpdb->last_error;
|
|
1425
|
+
}
|
|
1426
|
+
return '';
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
if (!function_exists('mysql_list_tables')) {
|
|
1430
|
+
function mysql_list_tables($db = '', $link = null) {
|
|
1431
|
+
global $wpdb;
|
|
1432
|
+
if (isset($wpdb) && method_exists($wpdb, 'get_results')) {
|
|
1433
|
+
$tables = $wpdb->get_results(
|
|
1434
|
+
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
|
|
1435
|
+
);
|
|
1436
|
+
$rows = array();
|
|
1437
|
+
if ($tables) {
|
|
1438
|
+
foreach ($tables as $t) {
|
|
1439
|
+
$obj = new stdClass();
|
|
1440
|
+
$obj->name = is_object($t) ? $t->name : $t['name'];
|
|
1441
|
+
$rows[] = $obj;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
$id = ++$GLOBALS['_mysql_result_id'];
|
|
1445
|
+
$GLOBALS['_mysql_results'][$id] = array(
|
|
1446
|
+
'rows' => $rows,
|
|
1447
|
+
'index' => 0,
|
|
1448
|
+
);
|
|
1449
|
+
return $id;
|
|
1450
|
+
}
|
|
1451
|
+
return false;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
if (!function_exists('mysql_fetch_row')) {
|
|
1455
|
+
function mysql_fetch_row($result) {
|
|
1456
|
+
if (!isset($GLOBALS['_mysql_results'][$result])) return null;
|
|
1457
|
+
$r = &$GLOBALS['_mysql_results'][$result];
|
|
1458
|
+
if ($r['index'] >= count($r['rows'])) return null;
|
|
1459
|
+
$row = $r['rows'][$r['index']++];
|
|
1460
|
+
return array_values((array)$row);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
if (!function_exists('mysql_fetch_object')) {
|
|
1464
|
+
function mysql_fetch_object($result) {
|
|
1465
|
+
if (!isset($GLOBALS['_mysql_results'][$result])) return null;
|
|
1466
|
+
$r = &$GLOBALS['_mysql_results'][$result];
|
|
1467
|
+
if ($r['index'] >= count($r['rows'])) return null;
|
|
1468
|
+
return (object)(array)$r['rows'][$r['index']++];
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
if (!function_exists('mysql_num_rows')) {
|
|
1472
|
+
function mysql_num_rows($result) {
|
|
1473
|
+
if (isset($GLOBALS['_mysql_results'][$result])) {
|
|
1474
|
+
return count($GLOBALS['_mysql_results'][$result]['rows']);
|
|
1475
|
+
}
|
|
1476
|
+
return 0;
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
if (!function_exists('mysql_get_server_info')) {
|
|
1480
|
+
function mysql_get_server_info() { return '8.0.0'; }
|
|
1481
|
+
}
|
|
1482
|
+
if (!function_exists('mysql_affected_rows')) {
|
|
1483
|
+
function mysql_affected_rows() {
|
|
1484
|
+
global $wpdb;
|
|
1485
|
+
if (isset($wpdb) && isset($wpdb->rows_affected)) {
|
|
1486
|
+
return $wpdb->rows_affected;
|
|
1487
|
+
}
|
|
1488
|
+
return 0;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
if (!function_exists('mysql_insert_id')) {
|
|
1492
|
+
function mysql_insert_id() {
|
|
1493
|
+
global $wpdb;
|
|
1494
|
+
if (isset($wpdb) && isset($wpdb->insert_id)) {
|
|
1495
|
+
return $wpdb->insert_id;
|
|
1496
|
+
}
|
|
1497
|
+
return 0;
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
if (!function_exists('mysql_free_result')) {
|
|
1501
|
+
function mysql_free_result($result) {
|
|
1502
|
+
unset($GLOBALS['_mysql_results'][$result]);
|
|
1503
|
+
return true;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
if (!function_exists('mysql_num_fields')) {
|
|
1507
|
+
function mysql_num_fields($result) {
|
|
1508
|
+
if (isset($GLOBALS['_mysql_results'][$result])
|
|
1509
|
+
&& !empty($GLOBALS['_mysql_results'][$result]['rows'])) {
|
|
1510
|
+
return count((array)$GLOBALS['_mysql_results'][$result]['rows'][0]);
|
|
1511
|
+
}
|
|
1512
|
+
return 0;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
if (!function_exists('mysql_real_escape_string')) {
|
|
1516
|
+
function mysql_real_escape_string($s) { return addslashes($s); }
|
|
1517
|
+
}
|
|
1518
|
+
if (!function_exists('mysql_escape_string')) {
|
|
1519
|
+
function mysql_escape_string($s) { return addslashes($s); }
|
|
1520
|
+
}`;async function Pe(e,t,i={}){await e.isDir("/tmp/sqlite-database-integration")&&await e.rmdir("/tmp/sqlite-database-integration",{recursive:!0}),await e.mkdir("/tmp/sqlite-database-integration"),await g.unzipFile(e,t,"/tmp/sqlite-database-integration");const n="/internal/shared/sqlite-database-integration",s=`/tmp/sqlite-database-integration/${(await e.listFiles("/tmp/sqlite-database-integration"))[0]}`;await e.mv(s,n),await be(e,n),await e.defineConstant("SQLITE_MAIN_FILE","1");let a=(await e.readFileAsText(o.joinPaths(n,"db.copy"))).replace("'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",o.phpVar(n)).replace("'{SQLITE_PLUGIN}'",o.phpVar(o.joinPaths(n,"load.php")));a=a.replace(/^add_action\(/gm,'function_exists("add_action") && add_action(');const l=o.joinPaths(await e.documentRoot,"wp-content/db.php"),_="/internal/shared/mu-plugins/sqlite-database-integration.php",c=`
|
|
1521
|
+
if(file_exists(${o.phpVar(l)})) {
|
|
1522
|
+
$_pg_db_php = @file_get_contents(${o.phpVar(l)});
|
|
1523
|
+
if (strpos($_pg_db_php, '@playground-managed') === false) {
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
unset($_pg_db_php);
|
|
1527
|
+
}
|
|
1528
|
+
`;await e.writeFile(_,`<?php
|
|
1529
|
+
${c}?>`+a),await e.writeFile("/internal/shared/preload/0-sqlite.php",Oe(c,_)),await e.writeFile("/internal/shared/mu-plugins/sqlite-test.php",`<?php
|
|
1530
|
+
global $wpdb;
|
|
1531
|
+
if(!($wpdb instanceof WP_SQLite_DB)) {
|
|
1532
|
+
var_dump(isset($wpdb));
|
|
1533
|
+
die("SQLite integration not loaded " . get_class($wpdb));
|
|
1534
|
+
}
|
|
1535
|
+
`)}async function be(e,t){const i=o.joinPaths(t,"wp-includes/database/sqlite/class-wp-pdo-mysql-on-sqlite.php");if(!await e.fileExists(i))return;const n=await e.readFileAsText(i),s=n.replace(/\$active_sql_modes\s*=\s*array\s*\([^)]*\)\s*;/,"$active_sql_modes = array();");s!==n&&await e.writeFile(i,s)}function Oe(e,t){return`<?php
|
|
1536
|
+
${e}?>
|
|
1537
|
+
<?php
|
|
1538
|
+
// Shim __() etc. only for WP < 1.2 (no l10n layer; the SQLite
|
|
1539
|
+
// plugin calls __() from print_error()). WP 1.2–1.4 ship
|
|
1540
|
+
// wp-l10n.php and WP 1.5+ ships l10n.php — defining the shims
|
|
1541
|
+
// then would fatal on redeclare.
|
|
1542
|
+
$_pg_doc_root = isset($_SERVER['DOCUMENT_ROOT'])
|
|
1543
|
+
? $_SERVER['DOCUMENT_ROOT'] : '/wordpress';
|
|
1544
|
+
if (
|
|
1545
|
+
!file_exists($_pg_doc_root . '/wp-includes/l10n.php')
|
|
1546
|
+
&& !file_exists($_pg_doc_root . '/wp-includes/wp-l10n.php')
|
|
1547
|
+
) {
|
|
1548
|
+
if (!function_exists('__')) {
|
|
1549
|
+
function __($text, $domain = null) { return $text; }
|
|
1550
|
+
}
|
|
1551
|
+
if (!function_exists('_e')) {
|
|
1552
|
+
function _e($text, $domain = null) { echo $text; }
|
|
1553
|
+
}
|
|
1554
|
+
if (!function_exists('esc_html__')) {
|
|
1555
|
+
function esc_html__($text, $domain = null) {
|
|
1556
|
+
return htmlspecialchars($text, ENT_QUOTES);
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
if (!function_exists('esc_html_e')) {
|
|
1560
|
+
function esc_html_e($text, $domain = null) {
|
|
1561
|
+
echo htmlspecialchars($text, ENT_QUOTES);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
?>
|
|
1566
|
+
<?php
|
|
1567
|
+
${N(`require_once ${o.phpVar(t)};
|
|
1568
|
+
if (
|
|
1569
|
+
isset($GLOBALS['wpdb']) &&
|
|
1570
|
+
method_exists($GLOBALS['wpdb'], 'reinitialize_sqlite')
|
|
1571
|
+
) {
|
|
1572
|
+
$GLOBALS['wpdb']->reinitialize_sqlite();
|
|
1573
|
+
}`)}
|
|
1574
|
+
${ye}
|
|
1575
|
+
if (PHP_MAJOR_VERSION < 7) {
|
|
1576
|
+
// E_DEPRECATED (8192) / E_STRICT (2048) are PHP 5.3+ symbols;
|
|
1577
|
+
// LEGACY_WP_ERROR_REPORTING_PHP_EXPR uses numeric literals.
|
|
1578
|
+
$level = ${T};
|
|
1579
|
+
error_reporting($level);
|
|
1580
|
+
ini_set('error_reporting', $level);
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
`}const S=`<?php
|
|
2
1584
|
|
|
3
1585
|
/**
|
|
4
1586
|
* Transforms the "wp-config.php" file.
|
|
@@ -469,21 +2051,63 @@ class WP_Config_Transformer {
|
|
|
469
2051
|
&& ( T_WHITESPACE === $token[0] || T_COMMENT === $token[0] || T_DOC_COMMENT === $token[0] );
|
|
470
2052
|
}
|
|
471
2053
|
}
|
|
472
|
-
`;async function
|
|
473
|
-
$wp_config_path = ${
|
|
2054
|
+
`;async function v(e,t){const i=o.joinPaths(t,"wp-config.php");!e.fileExists(i)&&e.fileExists(o.joinPaths(t,"wp-config-sample.php"))&&await e.writeFile(i,await e.readFileAsBuffer(o.joinPaths(t,"wp-config-sample.php"))),e.fileExists(i)&&await Ae(e,i,{DB_NAME:"wordpress"})}async function Ne(e,t,i){const n=o.phpVars({wpConfigPath:t,constants:i});if((await e.run({code:`${S}
|
|
2055
|
+
$wp_config_path = ${n.wpConfigPath};
|
|
474
2056
|
$transformer = WP_Config_Transformer::from_file($wp_config_path);
|
|
475
|
-
$transformer->define_constants(${
|
|
2057
|
+
$transformer->define_constants(${n.constants});
|
|
476
2058
|
$transformer->to_file($wp_config_path);
|
|
477
|
-
`})).errors.length>0)throw new Error("Failed to rewrite constants in wp-config.php.")}async function
|
|
478
|
-
$transformer = WP_Config_Transformer::from_file(${
|
|
2059
|
+
`})).errors.length>0)throw new Error("Failed to rewrite constants in wp-config.php.")}async function Ae(e,t,i){const n=Object.keys(i),s=o.phpVars({wpConfigPath:t,constantNames:n}),r=await e.run({code:`${S}
|
|
2060
|
+
$transformer = WP_Config_Transformer::from_file(${s.wpConfigPath});
|
|
479
2061
|
$missing = [];
|
|
480
|
-
foreach (${
|
|
2062
|
+
foreach (${s.constantNames} as $name) {
|
|
481
2063
|
if (!$transformer->constant_exists($name)) {
|
|
482
2064
|
$missing[] = $name;
|
|
483
2065
|
}
|
|
484
2066
|
}
|
|
485
2067
|
echo json_encode($missing);
|
|
486
|
-
`});if(
|
|
2068
|
+
`});if(r.errors.length>0)throw new Error("Failed to check wp-config.php for constants.");let a;try{a=JSON.parse(r.text)}catch{throw new Error(`Failed to parse wp-config.php constant check output: ${r.text}`)}for(const l of a)await e.defineConstant(l,i[l])}async function w(e,{usesSqlite:t,hasCustomDatabasePath:i}){const n=await e.getPrimaryPhp();if(n.isFile("/internal/shared/preload/0-sqlite.php"))return;const s=o.joinPaths(e.documentRoot,"wp-content/mu-plugins/sqlite-database-integration");if(!n.isDir(s)&&!t&&!i&&!Se(n))throw new Error("Error connecting to the MySQL database.")}function Se(e){const t=o.joinPaths(e.documentRoot,"wp-config.php");if(!e.isFile(t))return!1;const i=e.readFileAsText(t),n=i.match(/define\s*\(\s*['"]DB_NAME['"]\s*,\s*['"]([^'"]*)['"]/),s=i.match(/define\s*\(\s*['"]DB_USER['"]\s*,\s*['"]([^'"]*)['"]/);return!n||!s?!1:n[1]!=="database_name_here"&&s[1]!=="username_here"}const x=["fsockopen","pfsockopen","curl_init","curl_exec","curl_multi_exec","mail"];function ve(e,t){var r,a;if(!f.isLegacyPHPVersion(t.phpVersion))return;const i=(((r=t.phpIniEntries)==null?void 0:r.disable_functions)??"").split(",").map(l=>l.trim()).filter(l=>l),s={disable_functions:Array.from(new Set([...i,...x])).join(","),allow_url_fopen:"0"};(a=t.phpIniEntries)!=null&&a["date.timezone"]||(s["date.timezone"]="UTC"),f.setPhpIniEntries(e,s)}async function xe(e,t){var a,l;const i=await e.getPrimaryPhp();if((a=t.hooks)!=null&&a.beforeWordPressFiles&&await t.hooks.beforeWordPressFiles(i),t.wordPressZip&&await y(i,await t.wordPressZip),t.constants)for(const _ in t.constants)i.defineConstant(_,t.constants[_]);i.defineConstant("WP_HOME",t.siteUrl),i.defineConstant("WP_SITEURL",t.siteUrl),await Re(i,e.documentRoot),await j(i,e.documentRoot),(l=t.hooks)!=null&&l.beforeDatabaseSetup&&await t.hooks.beforeDatabaseSetup(i);let n=!1;t.sqliteIntegrationPluginZip&&(n=!0,await L(i,await t.sqliteIntegrationPluginZip,{phpVersion:t.phpVersion}),await Ue(i,e.documentRoot));const s=t.wordpressInstallMode??"download-and-install",r=!!t.dataSqlPath;return(s==="download-and-install"||s==="install-from-existing-files"||s==="install-from-existing-files-if-needed")&&(await w(e,{usesSqlite:n,hasCustomDatabasePath:r}),await ke(i,e)),e}async function Re(e,t){const i=o.joinPaths(t,"wp-config.php"),n=o.joinPaths(t,"wp-config-sample.php");!e.fileExists(i)&&e.fileExists(n)&&await e.writeFile(i,await e.readFileAsBuffer(n))}async function Ue(e,t){const i=o.joinPaths(t,"wp-content"),n=o.joinPaths(i,"db.php");e.isDir(i)&&!e.fileExists(n)&&await e.writeFile(n,Te())}async function ke(e,t){try{await Ie(e)}catch(i){h.logger.warn("Legacy PHP WordPress installation error:",i)}await Le(e,t.absoluteUrl)}async function Ie(e){var r,a,l,_,c,u;const t=Ce(e,e.documentRoot);if(t!==null){const d=parseFloat(t);if(d<2.1)return;if(d<=3){await Fe(e);return}}const i={disable_functions:x.join(","),allow_url_fopen:"0",error_reporting:String(B)},n=await f.withPHPIniValues(e,i,async()=>await e.request({url:"/wp-admin/install.php?step=2",method:"POST",body:{language:"en",prefix:"wp_",weblog_title:"My WordPress Website",user_name:"admin",admin_password:"password",admin_password2:"password",Submit:"Install WordPress",pw_weak:"1",admin_email:"admin@localhost.com"}}));if(!(((r=n.text)==null?void 0:r.includes("Success"))||((a=n.text)==null?void 0:a.includes("successful"))||((l=n.text)==null?void 0:l.includes("Finished"))||((_=n.text)==null?void 0:_.includes("Already Installed"))||((c=n.text)==null?void 0:c.includes("already have WordPress installed"))||!1))throw new Error(`Failed to install WordPress – installer responded with "${(u=n.text)==null?void 0:u.substring(0,100)}"`);await De(e)}async function De(e){try{(await e.run({code:`<?php
|
|
2069
|
+
$db_dir = getenv('DOCUMENT_ROOT') . '/wp-content/database/';
|
|
2070
|
+
$db_path = $db_dir . '.ht.sqlite';
|
|
2071
|
+
if (!file_exists($db_path)) { echo '0'; exit; }
|
|
2072
|
+
$pdo = new PDO('sqlite:' . $db_path);
|
|
2073
|
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
2074
|
+
$nice_permalinks = '/%year%/%monthnum%/%day%/%postname%/';
|
|
2075
|
+
$stmt = $pdo->prepare(
|
|
2076
|
+
"UPDATE wp_options SET option_value = :val WHERE option_name = 'permalink_structure'"
|
|
2077
|
+
);
|
|
2078
|
+
$stmt->execute(array(':val' => $nice_permalinks));
|
|
2079
|
+
if ($stmt->rowCount() === 0) {
|
|
2080
|
+
$stmt = $pdo->prepare(
|
|
2081
|
+
"INSERT INTO wp_options (option_name, option_value, autoload) VALUES ('permalink_structure', :val, 'yes')"
|
|
2082
|
+
);
|
|
2083
|
+
$stmt->execute(array(':val' => $nice_permalinks));
|
|
2084
|
+
}
|
|
2085
|
+
$check = $pdo->query(
|
|
2086
|
+
"SELECT option_value FROM wp_options WHERE option_name = 'permalink_structure'"
|
|
2087
|
+
)->fetchColumn();
|
|
2088
|
+
echo $check === $nice_permalinks ? '1' : '0';
|
|
2089
|
+
`,env:{DOCUMENT_ROOT:e.documentRoot}})).text!=="1"&&h.logger.warn("Failed to default to pretty permalinks after WP install.")}catch{h.logger.warn("Failed to set pretty permalinks after WP install (non-fatal).")}}async function Fe(e){try{await e.run({code:`<?php
|
|
2090
|
+
define('WP_INSTALLING', true);
|
|
2091
|
+
error_reporting(${T});
|
|
2092
|
+
ini_set('display_errors', '0');
|
|
2093
|
+
ob_start();
|
|
2094
|
+
require getenv('DOCUMENT_ROOT') . '/wp-load.php';
|
|
2095
|
+
ob_clean();
|
|
2096
|
+
if (file_exists(ABSPATH . 'wp-admin/includes/upgrade.php')) {
|
|
2097
|
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
|
2098
|
+
} elseif (file_exists(ABSPATH . 'wp-admin/upgrade-functions.php')) {
|
|
2099
|
+
require_once ABSPATH . 'wp-admin/upgrade-functions.php';
|
|
2100
|
+
}
|
|
2101
|
+
if (function_exists('make_db_current_silent')) {
|
|
2102
|
+
make_db_current_silent();
|
|
2103
|
+
}
|
|
2104
|
+
// Seed essential options/roles when the loader exposes
|
|
2105
|
+
// them. The PDO fallback in runPostInstallLegacyFixups
|
|
2106
|
+
// backfills anything missing if either call dies.
|
|
2107
|
+
if (function_exists('populate_options')) populate_options();
|
|
2108
|
+
if (function_exists('populate_roles')) populate_roles();
|
|
2109
|
+
echo 'OK';
|
|
2110
|
+
`,env:{DOCUMENT_ROOT:e.documentRoot}})}catch(t){h.logger.warn("runDbDeltaOnly failed (non-fatal):",t)}}function Ce(e,t){const i=o.joinPaths(t,"wp-includes/version.php");if(!e.fileExists(i))return null;const s=e.readFileAsText(i).match(/\$wp_version\s*=\s*['"]([^'"]+)['"]/);return s?s[1]:null}async function qe(e){const t=await U(e);return await R(t,e),t}async function R(e,t){var a,l;if(f.isLegacyPHPVersion(t.phpVersion))return xe(e,t);const i=await e.getPrimaryPhp();if((a=t.hooks)!=null&&a.beforeWordPressFiles&&await t.hooks.beforeWordPressFiles(i),t.wordPressZip&&await y(i,await t.wordPressZip),t.constants)for(const _ in t.constants)i.defineConstant(_,t.constants[_]);t.dataSqlPath&&(i.defineConstant("DB_DIR",o.dirname(t.dataSqlPath)),i.defineConstant("DB_FILE",o.basename(t.dataSqlPath))),i.defineConstant("WP_HOME",t.siteUrl),i.defineConstant("WP_SITEURL",t.siteUrl),await v(i,e.documentRoot),(l=t.hooks)!=null&&l.beforeDatabaseSetup&&await t.hooks.beforeDatabaseSetup(i);let n=!1;t.sqliteIntegrationPluginZip&&(n=!0,await L(i,await t.sqliteIntegrationPluginZip,{phpVersion:t.phpVersion}),await H(i,e.documentRoot));const s=t.wordpressInstallMode??"download-and-install",r=!!t.dataSqlPath;if(["download-and-install","install-from-existing-files"].includes(s)){await w(e,{usesSqlite:n,hasCustomDatabasePath:r});try{await b(i)}catch(_){throw r||await m(e),_}r||await m(e)}else if(s==="install-from-existing-files-if-needed"){if(await w(e,{usesSqlite:n,hasCustomDatabasePath:r}),!await k(i))try{await b(i)}catch(_){throw r||await m(e),_}r||await m(e)}return e}async function m(e){const t=await e.getPrimaryPhp();if(await We(t))return;if(t.isFile("/internal/shared/preload/0-sqlite.php"))throw new Error("Error connecting to the SQLite database.");const n=o.joinPaths(e.documentRoot,"wp-content/mu-plugins/sqlite-database-integration");throw t.isDir(n)?new Error("Error connecting to the SQLite database."):new Error("Error connecting to the MySQL database.")}async function U(e){const t=e.spawnHandler??f.sandboxedSpawnHandlerFactory;async function i(s,r=!1){const a=await e.createPhpRuntime(r),l=new f.PHP(a);if(e.sapiName&&l.setSapiName(e.sapiName),s&&(l.requestHandler=s),e.phpIniEntries&&f.setPhpIniEntries(l,e.phpIniEntries),ve(l,{phpVersion:e.phpVersion,phpIniEntries:e.phpIniEntries}),l.defineConstant("WP_SQLITE_AST_DRIVER",!0),e.constants)for(const _ in e.constants)l.defineConstant(_,e.constants[_]);return r&&!l.isFile("/internal/.boot-files-written")&&(await C(l,{phpVersion:e.phpVersion}),await f.writeFiles(l,"/",e.createFiles||{}),await q(l,o.joinPaths(new URL(e.siteUrl).pathname,"phpinfo.php")),await f.writeFiles(l,"/internal",{".boot-files-written":""})),t&&await l.setSpawnHandler(t(s?()=>s.instanceManager.acquirePHPInstance():void 0)),l.enableRuntimeRotation({recreateRuntime:e.createPhpRuntime,maxRequests:400}),e.onPHPInstanceCreated&&await e.onPHPInstanceCreated(l,{isPrimary:r}),l}const n=new f.PHPRequestHandler({documentRoot:e.documentRoot||"/wordpress",absoluteUrl:e.siteUrl,rewriteRules:F,pathAliases:e.pathAliases,getFileNotFoundAction:e.getFileNotFoundAction??I,cookieStore:e.cookieStore,php:e.maxPhpInstances===1?await i(void 0,!0):void 0,phpFactory:e.maxPhpInstances!==1?async({isPrimary:s})=>i(n,s):void 0,maxPhpInstances:e.maxPhpInstances});return n}async function k(e){return(await e.run({code:`<?php
|
|
487
2111
|
ob_start();
|
|
488
2112
|
$wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
|
|
489
2113
|
if (!file_exists($wp_load)) {
|
|
@@ -494,7 +2118,7 @@ class WP_Config_Transformer {
|
|
|
494
2118
|
ob_clean();
|
|
495
2119
|
echo is_blog_installed() ? '1' : '0';
|
|
496
2120
|
ob_end_flush();
|
|
497
|
-
`,env:{DOCUMENT_ROOT:
|
|
2121
|
+
`,env:{DOCUMENT_ROOT:e.documentRoot}})).text==="1"}async function b(e){var n;const t=await f.withPHPIniValues(e,{disable_functions:"fsockopen",allow_url_fopen:"0"},async()=>await e.request({url:"/wp-admin/install.php?step=2",method:"POST",body:{language:"en",prefix:"wp_",weblog_title:"My WordPress Website",user_name:"admin",admin_password:"password",admin_password2:"password",Submit:"Install WordPress",pw_weak:"1",admin_email:"admin@localhost.com"}}));if(!await k(e))throw new Error(`Failed to install WordPress – installer responded with "${(n=t.text)==null?void 0:n.substring(0,100)}"`);(await e.run({code:`<?php
|
|
498
2122
|
ob_start();
|
|
499
2123
|
$wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
|
|
500
2124
|
if (!file_exists($wp_load)) {
|
|
@@ -514,7 +2138,7 @@ class WP_Config_Transformer {
|
|
|
514
2138
|
echo '0';
|
|
515
2139
|
}
|
|
516
2140
|
ob_end_flush();
|
|
517
|
-
`,env:{DOCUMENT_ROOT:
|
|
2141
|
+
`,env:{DOCUMENT_ROOT:e.documentRoot}})).text!=="1"&&h.logger.warn("Failed to default to pretty permalinks after WP install.")}function I(e){return{type:"internal-redirect",uri:"/index.php"}}async function We(e){return(await e.run({code:`<?php
|
|
518
2142
|
ob_start();
|
|
519
2143
|
$wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
|
|
520
2144
|
if (!file_exists($wp_load)) {
|
|
@@ -525,10 +2149,10 @@ class WP_Config_Transformer {
|
|
|
525
2149
|
ob_clean();
|
|
526
2150
|
echo $wpdb->check_connection( false ) ? '1' : '0';
|
|
527
2151
|
ob_end_flush();
|
|
528
|
-
`,env:{DOCUMENT_ROOT:
|
|
529
|
-
require '${
|
|
2152
|
+
`,env:{DOCUMENT_ROOT:e.documentRoot}})).text==="1"}async function Ge(e){const{php:t,reap:i}=await e.instanceManager.acquirePHPInstance();try{const s=(await t.run({code:`<?php
|
|
2153
|
+
require '${e.documentRoot}/wp-includes/version.php';
|
|
530
2154
|
echo $wp_version;
|
|
531
|
-
`})).text;if(!
|
|
2155
|
+
`})).text;if(!s)throw new Error("Unable to read loaded WordPress version.");return D(s)}finally{i()}}function D(e){if(/-(alpha|beta|RC)\d*-\d+$/.test(e))return"trunk";if(/-(beta|RC)\d*$/.test(e))return"beta";const n=e.match(/^(\d+\.\d+)(?:\.\d+)?$/);return n!==null?n[1]:e}const F=[{match:new RegExp("^(/[_0-9a-zA-Z-]+)?(/wp-(content|admin|includes)/.*)"),replacement:"$2"}];async function C(e,t={}){if(f.isLegacyPHPVersion(t.phpVersion))return G(e);await e.mkdir("/internal/shared/mu-plugins"),await e.writeFile("/internal/shared/preload/env.php",`<?php
|
|
532
2156
|
|
|
533
2157
|
// Allow adding filters/actions prior to loading WordPress.
|
|
534
2158
|
// $function_to_add MUST be a string.
|
|
@@ -555,7 +2179,7 @@ class WP_Config_Transformer {
|
|
|
555
2179
|
require_once $mu_plugin;
|
|
556
2180
|
}
|
|
557
2181
|
}
|
|
558
|
-
`),await
|
|
2182
|
+
`),await e.writeFile("/internal/shared/mu-plugins/1-auto-login.php",`<?php
|
|
559
2183
|
/**
|
|
560
2184
|
* Returns the username to auto-login as, if any.
|
|
561
2185
|
* @return string|false
|
|
@@ -709,105 +2333,7 @@ class WP_Config_Transformer {
|
|
|
709
2333
|
}
|
|
710
2334
|
return $interval;
|
|
711
2335
|
});
|
|
712
|
-
`),await
|
|
713
|
-
|
|
714
|
-
// Save WordPress environment information to a file.
|
|
715
|
-
add_action('wp_loaded', function() {
|
|
716
|
-
if (defined('DB_ENGINE') && DB_ENGINE === 'sqlite') {
|
|
717
|
-
$db_info = array(
|
|
718
|
-
'type' => 'sqlite',
|
|
719
|
-
'path' => FQDB,
|
|
720
|
-
'driver_path' => defined('WP_MYSQL_ON_SQLITE_LOADER_PATH')
|
|
721
|
-
? WP_MYSQL_ON_SQLITE_LOADER_PATH
|
|
722
|
-
: dirname(SQLITE_MAIN_FILE) . '/wp-pdo-mysql-on-sqlite.php',
|
|
723
|
-
);
|
|
724
|
-
} else {
|
|
725
|
-
$db_info = array(
|
|
726
|
-
'type' => 'mysql',
|
|
727
|
-
// TODO: Save MySQL connection config.
|
|
728
|
-
);
|
|
729
|
-
}
|
|
730
|
-
$wp_env = array('db' => $db_info);
|
|
731
|
-
$wp_env_php = sprintf('<?php return %s;', var_export($wp_env, true));
|
|
732
|
-
$wp_env_file = '/internal/shared/wp-env.php';
|
|
733
|
-
if (!file_exists($wp_env_file) || file_get_contents($wp_env_file) !== $wp_env_php ) {
|
|
734
|
-
file_put_contents($wp_env_file, $wp_env_php);
|
|
735
|
-
}
|
|
736
|
-
});
|
|
737
|
-
|
|
738
|
-
// Needed because gethostbyname( 'wordpress.org' ) returns
|
|
739
|
-
// a private network IP address for some reason.
|
|
740
|
-
add_filter( 'allowed_redirect_hosts', function( $deprecated = '' ) {
|
|
741
|
-
return array(
|
|
742
|
-
'wordpress.org',
|
|
743
|
-
'api.wordpress.org',
|
|
744
|
-
'downloads.wordpress.org',
|
|
745
|
-
);
|
|
746
|
-
} );
|
|
747
|
-
|
|
748
|
-
/**
|
|
749
|
-
* Prevents wp_http_validate_url() from universally failing.
|
|
750
|
-
*
|
|
751
|
-
* wp_http_validate_url() calls gethostbyname() to verify whether the host
|
|
752
|
-
* is external. If it is internal, the URL validation fails and WordPress
|
|
753
|
-
* refuses to make a request.
|
|
754
|
-
*
|
|
755
|
-
* However, in EMscripten, gethostbyname() returns a private network IP address.
|
|
756
|
-
* This causes wp_http_validate_url() to return false for all URLs.
|
|
757
|
-
*
|
|
758
|
-
* This filter ensures that all URLs are considered external. In production
|
|
759
|
-
* environments, this would be considered a security risk. However, Playground
|
|
760
|
-
* already provides multiple code execution vectors as features (e.g. Blueprints).
|
|
761
|
-
*
|
|
762
|
-
* If someone wants to poke around local IP addresses, they already have multiple
|
|
763
|
-
* tools at their disposal. Therefore, this is not a real security risk in context
|
|
764
|
-
* of WordPress Playground or Playground CLI.
|
|
765
|
-
*/
|
|
766
|
-
add_filter('http_request_host_is_external', '__return_true');
|
|
767
|
-
|
|
768
|
-
// Support pretty permalinks
|
|
769
|
-
add_filter( 'got_url_rewrite', '__return_true' );
|
|
770
|
-
|
|
771
|
-
// Create the fonts directory if missing
|
|
772
|
-
if(!file_exists(WP_CONTENT_DIR . '/fonts')) {
|
|
773
|
-
mkdir(WP_CONTENT_DIR . '/fonts');
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
$log_file = WP_CONTENT_DIR . '/debug.log';
|
|
777
|
-
if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
|
|
778
|
-
if ( is_string( WP_DEBUG_LOG ) ) {
|
|
779
|
-
$log_file = WP_DEBUG_LOG;
|
|
780
|
-
}
|
|
781
|
-
ini_set('error_log', $log_file);
|
|
782
|
-
} else {
|
|
783
|
-
ini_set('log_errors', '0');
|
|
784
|
-
}
|
|
785
|
-
define('ERROR_LOG_FILE', $log_file);
|
|
786
|
-
?>`),await t.writeFile("/internal/shared/mu-plugins/sitemap-redirect.php",`<?php
|
|
787
|
-
/**
|
|
788
|
-
* Redirect sitemap.xml to wp-sitemap.xml for non-root installations.
|
|
789
|
-
*
|
|
790
|
-
* WordPress seems to only generate the sitemap.xml → wp-sitemap.xml rewrite
|
|
791
|
-
* rule when installed at the domain root. This mu-plugin handles the
|
|
792
|
-
* redirect for non-root installations.
|
|
793
|
-
*/
|
|
794
|
-
if (isset($_SERVER['REQUEST_URI'])) {
|
|
795
|
-
$site_url = site_url();
|
|
796
|
-
$parsed = parse_url($site_url);
|
|
797
|
-
$base_path = isset($parsed['path']) ? rtrim($parsed['path'], '/') : '';
|
|
798
|
-
|
|
799
|
-
$request_uri = $_SERVER['REQUEST_URI'];
|
|
800
|
-
if (
|
|
801
|
-
$request_uri === $base_path . '/sitemap.xml' ||
|
|
802
|
-
strpos($request_uri, $base_path . '/sitemap.xml?') === 0 ||
|
|
803
|
-
strpos($request_uri, $base_path . '/sitemap.xml/') === 0
|
|
804
|
-
) {
|
|
805
|
-
$query_string = strpos($request_uri, '?') !== false ? substr($request_uri, strpos($request_uri, '?')) : '';
|
|
806
|
-
header('Location: ' . $base_path . '/wp-sitemap.xml' . $query_string, true, 301);
|
|
807
|
-
exit;
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
`),await t.writeFile("/internal/shared/preload/error-handler.php",`<?php
|
|
2336
|
+
`),await O(e),await e.writeFile("/internal/shared/preload/error-handler.php",`<?php
|
|
811
2337
|
(function() {
|
|
812
2338
|
$playground_consts = [];
|
|
813
2339
|
if(file_exists('/internal/shared/consts.json')) {
|
|
@@ -855,97 +2381,29 @@ class WP_Config_Transformer {
|
|
|
855
2381
|
}
|
|
856
2382
|
return false;
|
|
857
2383
|
});
|
|
858
|
-
})();`)}async function
|
|
2384
|
+
})();`)}async function q(e,t="/phpinfo.php"){await e.writeFile("/internal/shared/preload/phpinfo.php",`<?php
|
|
859
2385
|
// Render PHPInfo if the requested page is /phpinfo.php
|
|
860
|
-
if ( isset($_SERVER['REQUEST_URI']) && ${
|
|
2386
|
+
if ( isset($_SERVER['REQUEST_URI']) && ${o.phpVar(t)} === $_SERVER['REQUEST_URI'] ) {
|
|
861
2387
|
phpinfo();
|
|
862
2388
|
exit;
|
|
863
2389
|
}
|
|
864
|
-
`)}async function
|
|
2390
|
+
`)}async function L(e,t,i={}){if(f.isLegacyPHPVersion(i.phpVersion))return Pe(e,t,i);await e.isDir("/tmp/sqlite-database-integration")&&await e.rmdir("/tmp/sqlite-database-integration",{recursive:!0}),await e.mkdir("/tmp/sqlite-database-integration"),await g.unzipFile(e,t,"/tmp/sqlite-database-integration");const n="/internal/shared/sqlite-database-integration",s=`/tmp/sqlite-database-integration/${(await e.listFiles("/tmp/sqlite-database-integration"))[0]}`;await e.mv(s,n);const r=o.joinPaths(n,"wp-includes/sqlite/class-wp-sqlite-db.php");if(await e.fileExists(r)){const d=await e.readFileAsText(r),$=d.replace("private $allow_unsafe_unquoted_parameters","protected $allow_unsafe_unquoted_parameters");$!==d&&await e.writeFile(r,$)}await e.defineConstant("SQLITE_MAIN_FILE","1");const l=(await e.readFileAsText(o.joinPaths(n,"db.copy"))).replace("'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",o.phpVar(n)).replace("'{SQLITE_PLUGIN}'",o.phpVar(o.joinPaths(n,"load.php"))),_=o.joinPaths(await e.documentRoot,"wp-content/db.php"),c=`<?php
|
|
865
2391
|
// Do not preload this if WordPress comes with a custom db.php file.
|
|
866
|
-
if(file_exists(${
|
|
2392
|
+
if(file_exists(${o.phpVar(_)})) {
|
|
867
2393
|
return;
|
|
868
2394
|
}
|
|
869
|
-
?>`,
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
*
|
|
875
|
-
* Technically, it creates a global $wpdb object whose only two
|
|
876
|
-
* purposes are to:
|
|
877
|
-
*
|
|
878
|
-
* * Exist – because the require_wp_db() WordPress function won't
|
|
879
|
-
* connect to MySQL if $wpdb is already set.
|
|
880
|
-
* * Load the SQLite integration plugin the first time it's used
|
|
881
|
-
* and replace the global $wpdb reference with the SQLite one.
|
|
882
|
-
*
|
|
883
|
-
* This lets Playground keep the WordPress installation clean and
|
|
884
|
-
* solves dillemas like:
|
|
885
|
-
*
|
|
886
|
-
* * Should we include db.php in Playground exports?
|
|
887
|
-
* * Should we remove db.php from Playground imports?
|
|
888
|
-
* * How should we treat stale db.php from long-lived OPFS sites?
|
|
889
|
-
*
|
|
890
|
-
* @see https://github.com/WordPress/wordpress-playground/discussions/1379 for
|
|
891
|
-
* more context.
|
|
892
|
-
*/
|
|
893
|
-
class Playground_SQLite_Integration_Loader {
|
|
894
|
-
public function __call($name, $arguments) {
|
|
895
|
-
$this->load_sqlite_integration();
|
|
896
|
-
if($GLOBALS['wpdb'] === $this) {
|
|
897
|
-
throw new Exception('Infinite loop detected in $wpdb – SQLite integration plugin could not be loaded');
|
|
898
|
-
}
|
|
899
|
-
return call_user_func_array(
|
|
900
|
-
array($GLOBALS['wpdb'], $name),
|
|
901
|
-
$arguments
|
|
902
|
-
);
|
|
903
|
-
}
|
|
904
|
-
public function __get($name) {
|
|
905
|
-
$this->load_sqlite_integration();
|
|
906
|
-
if($GLOBALS['wpdb'] === $this) {
|
|
907
|
-
throw new Exception('Infinite loop detected in $wpdb – SQLite integration plugin could not be loaded');
|
|
908
|
-
}
|
|
909
|
-
return $GLOBALS['wpdb']->$name;
|
|
910
|
-
}
|
|
911
|
-
public function __set($name, $value) {
|
|
912
|
-
$this->load_sqlite_integration();
|
|
913
|
-
if($GLOBALS['wpdb'] === $this) {
|
|
914
|
-
throw new Exception('Infinite loop detected in $wpdb – SQLite integration plugin could not be loaded');
|
|
2395
|
+
?>`,u="/internal/shared/mu-plugins/sqlite-database-integration.php";await e.writeFile(u,c+l),await e.writeFile("/internal/shared/preload/0-sqlite.php",Me(c,u)),await e.writeFile("/internal/shared/mu-plugins/sqlite-test.php",`<?php
|
|
2396
|
+
global $wpdb;
|
|
2397
|
+
if(!($wpdb instanceof WP_SQLite_DB)) {
|
|
2398
|
+
var_dump(isset($wpdb));
|
|
2399
|
+
die("SQLite integration not loaded " . get_class($wpdb));
|
|
915
2400
|
}
|
|
916
|
-
|
|
917
|
-
}
|
|
918
|
-
protected function load_sqlite_integration() {
|
|
919
|
-
require_once ${r.phpVar(c)};
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
/**
|
|
923
|
-
* The Query Monitor plugin short-circuits in the CLI SAPI. However, in Playground,
|
|
924
|
-
* the SAPI is always "cli" at the moment. Let's set a constant to disable the CLI
|
|
925
|
-
* detection.
|
|
926
|
-
*
|
|
927
|
-
* @see https://github.com/WordPress/sqlite-database-integration/pull/212
|
|
928
|
-
* @see https://github.com/WordPress/sqlite-database-integration/pull/215
|
|
929
|
-
*/
|
|
930
|
-
define('QM_TESTS', true);
|
|
931
|
-
$wpdb = $GLOBALS['wpdb'] = new Playground_SQLite_Integration_Loader();
|
|
2401
|
+
`)}function Me(e,t){return e+`<?php
|
|
932
2402
|
|
|
933
|
-
|
|
934
|
-
* WordPress is capable of using a preloaded global $wpdb. However, if
|
|
935
|
-
* it cannot find the drop-in db.php plugin it still checks whether
|
|
936
|
-
* the mysqli_connect() function exists even though it's not used.
|
|
937
|
-
*
|
|
938
|
-
* What WordPress demands, Playground shall provide.
|
|
939
|
-
*/
|
|
2403
|
+
${N(`require_once ${o.phpVar(t)};`)}
|
|
940
2404
|
if(!function_exists('mysqli_connect')) {
|
|
941
2405
|
function mysqli_connect() {}
|
|
942
2406
|
}
|
|
943
2407
|
|
|
944
|
-
`),await t.
|
|
945
|
-
global $wpdb;
|
|
946
|
-
if(!($wpdb instanceof WP_SQLite_DB)) {
|
|
947
|
-
var_dump(isset($wpdb));
|
|
948
|
-
die("SQLite integration not loaded " . get_class($wpdb));
|
|
949
|
-
}
|
|
950
|
-
`)}async function R(t,e){t.mkdir("/tmp/unzipped-wordpress"),await p.unzipFile(t,e,"/tmp/unzipped-wordpress"),t.fileExists("/tmp/unzipped-wordpress/wordpress.zip")&&await p.unzipFile(t,"/tmp/unzipped-wordpress/wordpress.zip","/tmp/unzipped-wordpress");let n=t.fileExists("/tmp/unzipped-wordpress/wordpress")?"/tmp/unzipped-wordpress/wordpress":t.fileExists("/tmp/unzipped-wordpress/build")?"/tmp/unzipped-wordpress/build":"/tmp/unzipped-wordpress";if(!t.fileExists(r.joinPaths(n,"wp-config-sample.php"))){const a=t.listFiles(n);if(a.length){const s=a[0];t.fileExists(r.joinPaths(n,s,"wp-config-sample.php"))&&(n=r.joinPaths(n,s))}}const i=(a,s,l)=>{if(l.isDir(a)&&l.isDir(s))for(const o of l.listFiles(a)){const c=r.joinPaths(a,o),S=r.joinPaths(s,o);i(c,S,l)}else{if(l.fileExists(s)){const o=a.replace(/^\/tmp\/unzipped-wordpress\//,"/");_.logger.warn(`Cannot unzip WordPress files at ${s}: ${o} already exists.`);return}l.mv(a,s)}};i(n,t.documentRoot,t),t.fileExists(n)&&t.rmdir(n,{recursive:!0}),!t.fileExists(r.joinPaths(t.documentRoot,"wp-config.php"))&&t.fileExists(r.joinPaths(t.documentRoot,"wp-config-sample.php"))&&t.writeFile(r.joinPaths(t.documentRoot,"wp-config.php"),t.readFileAsText(r.joinPaths(t.documentRoot,"/wp-config-sample.php")))}const q=p.createMemoizedFetch(fetch),A="https://github.com/WordPress/WordPress/archive/refs/heads/master.zip";async function U(t="latest"){if(t===null)t="latest";else if(t.startsWith("https://")||t.startsWith("http://")){const i=await crypto.subtle.digest("SHA-1",new TextEncoder().encode(t)),a=Array.from(new Uint8Array(i)).map(s=>s.toString(16).padStart(2,"0")).join("");return{releaseUrl:t,version:"custom-"+a.substring(0,8),source:"inferred"}}else if(t==="trunk"||t==="nightly"){const i=new Date().toISOString().split("T")[0];return{releaseUrl:`${A}?ts=${i}`,version:"trunk",source:"inferred"}}let n=await(await q("https://api.wordpress.org/core/version-check/1.7/?channel=beta")).json();n=n.offers.filter(i=>i.response==="autoupdate");for(const i of n){if(t==="beta"&&(i.version.includes("beta")||i.version.includes("RC")))return{releaseUrl:i.download,version:i.version,source:"api"};if(t==="latest"&&!i.version.includes("beta")&&!i.version.includes("RC"))return{releaseUrl:i.download,version:i.version,source:"api"};if(i.version.substring(0,t.length)===t)return{releaseUrl:i.download,version:i.version,source:"api"}}return t.match(/^\d+\.\d+\.0$/)&&(t=t.split(".").slice(0,2).join(".")),{releaseUrl:`https://wordpress.org/wordpress-${t}.zip`,version:t,source:"inferred"}}exports.bootRequestHandler=w;exports.bootWordPress=m;exports.bootWordPressAndRequestHandler=L;exports.defineWpConfigConstants=I;exports.ensureWpConfig=g;exports.getFileNotFoundActionForWordPress=k;exports.getLoadedWordPressVersion=O;exports.preloadPhpInfoRoute=E;exports.preloadSqliteIntegration=v;exports.resolveWordPressRelease=U;exports.setupPlatformLevelMuPlugins=T;exports.unzipWordPress=R;exports.versionStringToLoadedWordPressVersion=y;exports.wordPressRewriteRules=b;
|
|
2408
|
+
`}async function y(e,t){e.mkdir("/tmp/unzipped-wordpress"),await g.unzipFile(e,t,"/tmp/unzipped-wordpress"),e.fileExists("/tmp/unzipped-wordpress/wordpress.zip")&&await g.unzipFile(e,"/tmp/unzipped-wordpress/wordpress.zip","/tmp/unzipped-wordpress");let i=e.fileExists("/tmp/unzipped-wordpress/wordpress")?"/tmp/unzipped-wordpress/wordpress":e.fileExists("/tmp/unzipped-wordpress/build")?"/tmp/unzipped-wordpress/build":"/tmp/unzipped-wordpress";if(!e.fileExists(o.joinPaths(i,"wp-config-sample.php"))){const s=e.listFiles(i);if(s.length){const r=s[0];e.fileExists(o.joinPaths(i,r,"wp-config-sample.php"))&&(i=o.joinPaths(i,r))}}const n=(s,r,a)=>{if(a.isDir(s)&&a.isDir(r))for(const l of a.listFiles(s)){const _=o.joinPaths(s,l),c=o.joinPaths(r,l);n(_,c,a)}else{if(a.fileExists(r)){const l=s.replace(/^\/tmp\/unzipped-wordpress\//,"/");h.logger.warn(`Cannot unzip WordPress files at ${r}: ${l} already exists.`);return}a.mv(s,r)}};n(i,e.documentRoot,e),e.fileExists(i)&&e.rmdir(i,{recursive:!0}),!e.fileExists(o.joinPaths(e.documentRoot,"wp-config.php"))&&e.fileExists(o.joinPaths(e.documentRoot,"wp-config-sample.php"))&&e.writeFile(o.joinPaths(e.documentRoot,"wp-config.php"),e.readFileAsText(o.joinPaths(e.documentRoot,"/wp-config-sample.php")))}const He=g.createMemoizedFetch(fetch),Be="https://github.com/WordPress/WordPress/archive/refs/heads/master.zip";async function je(e="latest"){if(e===null)e="latest";else if(e.startsWith("https://")||e.startsWith("http://")){const n=await crypto.subtle.digest("SHA-1",new TextEncoder().encode(e)),s=Array.from(new Uint8Array(n)).map(r=>r.toString(16).padStart(2,"0")).join("");return{releaseUrl:e,version:"custom-"+s.substring(0,8),source:"inferred"}}else if(e==="trunk"||e==="nightly"){const n=new Date().toISOString().split("T")[0];return{releaseUrl:`${Be}?ts=${n}`,version:"trunk",source:"inferred"}}let i=await(await He("https://api.wordpress.org/core/version-check/1.7/?channel=beta")).json();i=i.offers.filter(n=>n.response==="autoupdate");for(const n of i){if(e==="beta"&&(n.version.includes("beta")||n.version.includes("RC")))return{releaseUrl:n.download,version:n.version,source:"api"};if(e==="latest"&&!n.version.includes("beta")&&!n.version.includes("RC"))return{releaseUrl:n.download,version:n.version,source:"api"};if(n.version.substring(0,e.length)===e)return{releaseUrl:n.download,version:n.version,source:"api"}}return e.match(/^\d+\.\d+\.0$/)&&(e=e.split(".").slice(0,2).join(".")),{releaseUrl:`https://wordpress.org/wordpress-${e}.zip`,version:e,source:"inferred"}}exports.bootRequestHandler=U;exports.bootWordPress=R;exports.bootWordPressAndRequestHandler=qe;exports.defineWpConfigConstants=Ne;exports.ensureWpConfig=v;exports.getFileNotFoundActionForWordPress=I;exports.getLoadedWordPressVersion=Ge;exports.preloadPhpInfoRoute=q;exports.preloadSqliteIntegration=L;exports.resolveWordPressRelease=je;exports.setupPlatformLevelMuPlugins=C;exports.unzipWordPress=y;exports.versionStringToLoadedWordPressVersion=D;exports.wordPressRewriteRules=F;
|
|
951
2409
|
//# sourceMappingURL=index.cjs.map
|