@wp-playground/wordpress 1.0.28 → 1.1.0
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/LICENSE +339 -0
- package/boot.d.ts +25 -1
- package/index.cjs +696 -0
- package/index.cjs.map +1 -0
- package/index.d.ts +2 -1
- package/index.js +661 -42
- package/index.js.map +1 -1
- package/package.json +29 -16
- package/rewrite-wp-config.d.ts +22 -0
package/index.js
CHANGED
|
@@ -1,27 +1,517 @@
|
|
|
1
|
-
import{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { phpVars as _, joinPaths as r, phpVar as l } from "@php-wasm/util";
|
|
2
|
+
import { createMemoizedFetch as c, unzipFile as p } from "@wp-playground/common";
|
|
3
|
+
import { PHPRequestHandler as h, PHP as g, setPhpIniEntries as $, writeFiles as w, proxyFileSystem as m, rotatePHPRuntime as b, withPHPIniValues as y } from "@php-wasm/universal";
|
|
4
|
+
import { logger as k } from "@php-wasm/logger";
|
|
5
|
+
const P = `<?php
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Rewrites the wp-config.php file to ensure specific constants are defined
|
|
9
|
+
* with specific values.
|
|
10
|
+
*
|
|
11
|
+
* Example:
|
|
12
|
+
*
|
|
13
|
+
* \`\`\`php
|
|
14
|
+
* <?php
|
|
15
|
+
* define('WP_DEBUG', true);
|
|
16
|
+
* // The third define() argument is also supported:
|
|
17
|
+
* define('SAVEQUERIES', false, true);
|
|
18
|
+
*
|
|
19
|
+
* // Expression
|
|
20
|
+
* define(true ? 'WP_DEBUG_LOG' : 'WP_DEBUG_LOG', 123);
|
|
21
|
+
*
|
|
22
|
+
* // Guarded expressions shouldn't be wrapped twice
|
|
23
|
+
* if(!defined(1 ? 'A' : 'B')) {
|
|
24
|
+
* define(1 ? 'A' : 'B', 0);
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* // More advanced expression
|
|
28
|
+
* define((function() use($x) {
|
|
29
|
+
* return [$x, 'a'];
|
|
30
|
+
* })(), 123);
|
|
31
|
+
* \`\`\`
|
|
32
|
+
*
|
|
33
|
+
* Rewritten with
|
|
34
|
+
*
|
|
35
|
+
* $constants = [
|
|
36
|
+
* 'WP_DEBUG' => false,
|
|
37
|
+
* 'WP_DEBUG_LOG' => true,
|
|
38
|
+
* 'SAVEQUERIES' => true,
|
|
39
|
+
* 'NEW_CONSTANT' => "new constant",
|
|
40
|
+
* ];
|
|
41
|
+
*
|
|
42
|
+
* \`\`\`php
|
|
43
|
+
* <?php
|
|
44
|
+
* define('WP_DEBUG_LOG',true);
|
|
45
|
+
* define('NEW_CONSTANT','new constant');
|
|
46
|
+
* ?><?php
|
|
47
|
+
* define('WP_DEBUG',false);
|
|
48
|
+
* // The third define() argument is also supported:
|
|
49
|
+
* define('SAVEQUERIES',true, true);
|
|
50
|
+
*
|
|
51
|
+
* // Expression
|
|
52
|
+
* if(!defined($const ? 'WP_DEBUG_LOG' : 'WP_DEBUG_LOG')) {
|
|
53
|
+
* define($const ? 'WP_DEBUG_LOG' : 'WP_DEBUG_LOG', 123);
|
|
54
|
+
* }
|
|
55
|
+
*
|
|
56
|
+
* // Guarded expressions shouldn't be wrapped twice
|
|
57
|
+
* if(!defined(1 ? 'A' : 'B')) {
|
|
58
|
+
* define(1 ? 'A' : 'B', 0);
|
|
59
|
+
* }
|
|
60
|
+
*
|
|
61
|
+
* // More advanced expression
|
|
62
|
+
* if(!defined((function() use($x) {
|
|
63
|
+
* return [$x, 'a'];
|
|
64
|
+
* })())) {
|
|
65
|
+
* define((function() use($x) {
|
|
66
|
+
* return [$x, 'a'];
|
|
67
|
+
* })(), 123);
|
|
68
|
+
* }
|
|
69
|
+
* \`\`\`
|
|
70
|
+
*
|
|
71
|
+
* @param mixed $content A PHP file content.
|
|
72
|
+
* @param array $constants An array of constants to define.
|
|
73
|
+
* @param bool $when_already_defined Optional. What to do if the constant is already defined.
|
|
74
|
+
* Possible values are:
|
|
75
|
+
* 'rewrite' - Rewrite the constant, using the new value.
|
|
76
|
+
* 'skip' - Skip the definition, keeping the existing value.
|
|
77
|
+
* Default: 'rewrite'
|
|
78
|
+
* @return string
|
|
79
|
+
*/
|
|
80
|
+
function rewrite_wp_config_to_define_constants($content, $constants = [], $when_already_defined = 'rewrite')
|
|
81
|
+
{
|
|
82
|
+
$tokens = array_reverse(token_get_all($content));
|
|
83
|
+
$output = [];
|
|
84
|
+
$defined_expressions = [];
|
|
85
|
+
|
|
86
|
+
// Look through all the tokens and find the define calls
|
|
87
|
+
do {
|
|
88
|
+
$buffer = [];
|
|
89
|
+
$name_buffer = [];
|
|
90
|
+
$value_buffer = [];
|
|
91
|
+
$third_arg_buffer = [];
|
|
92
|
+
|
|
93
|
+
// Capture everything until the define call into output.
|
|
94
|
+
// Capturing the define call into a buffer.
|
|
95
|
+
// Example:
|
|
96
|
+
// <?php echo 'a'; define (
|
|
97
|
+
// ^^^^^^^^^^^^^^^^^^^^^^
|
|
98
|
+
// output |buffer
|
|
99
|
+
while ($token = array_pop($tokens)) {
|
|
100
|
+
if (is_array($token) && $token[0] === T_STRING && (strtolower($token[1]) === 'define' || strtolower($token[1]) === 'defined')) {
|
|
101
|
+
$buffer[] = $token;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
$output[] = $token;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Maybe we didn't find a define call and reached the end of the file?
|
|
108
|
+
if (!count($tokens)) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Keep track of the "defined" expressions that are already accounted for
|
|
113
|
+
if($token[1] === 'defined') {
|
|
114
|
+
$output[] = $token;
|
|
115
|
+
$defined_expression = [];
|
|
116
|
+
$open_parenthesis = 0;
|
|
117
|
+
// Capture everything up to the opening parenthesis, including the parenthesis
|
|
118
|
+
// e.g. defined (
|
|
119
|
+
// ^^^^
|
|
120
|
+
while ($token = array_pop($tokens)) {
|
|
121
|
+
$output[] = $token;
|
|
122
|
+
if ($token === "(") {
|
|
123
|
+
++$open_parenthesis;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Capture everything up to the closing parenthesis, including the parenthesis
|
|
129
|
+
// e.g. defined (
|
|
130
|
+
// ^^^^
|
|
131
|
+
while ($token = array_pop($tokens)) {
|
|
132
|
+
$output[] = $token;
|
|
133
|
+
if ($token === ")") {
|
|
134
|
+
--$open_parenthesis;
|
|
135
|
+
}
|
|
136
|
+
if ($open_parenthesis === 0) {
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
$defined_expression[] = $token;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
$defined_expressions[] = stringify_tokens(skip_whitespace($defined_expression));
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Capture everything up to the opening parenthesis, including the parenthesis
|
|
147
|
+
// e.g. define (
|
|
148
|
+
// ^^^^
|
|
149
|
+
while ($token = array_pop($tokens)) {
|
|
150
|
+
$buffer[] = $token;
|
|
151
|
+
if ($token === "(") {
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Capture the first argument – it's the first expression after the opening
|
|
157
|
+
// parenthesis and before the comma:
|
|
158
|
+
// Examples:
|
|
159
|
+
// define("WP_DEBUG", true);
|
|
160
|
+
// ^^^^^^^^^^^
|
|
161
|
+
//
|
|
162
|
+
// define(count([1,2]) > 2 ? 'WP_DEBUG' : 'FOO', true);
|
|
163
|
+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
164
|
+
$open_parenthesis = 0;
|
|
165
|
+
while ($token = array_pop($tokens)) {
|
|
166
|
+
$buffer[] = $token;
|
|
167
|
+
if ($token === "(" || $token === "[" || $token === "{") {
|
|
168
|
+
++$open_parenthesis;
|
|
169
|
+
} elseif ($token === ")" || $token === "]" || $token === "}") {
|
|
170
|
+
--$open_parenthesis;
|
|
171
|
+
} elseif ($token === "," && $open_parenthesis === 0) {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Don't capture the comma as a part of the constant name
|
|
176
|
+
$name_buffer[] = $token;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Capture everything until the closing parenthesis
|
|
180
|
+
// define("WP_DEBUG", true);
|
|
181
|
+
// ^^^^^^
|
|
182
|
+
$open_parenthesis = 0;
|
|
183
|
+
$is_second_argument = true;
|
|
184
|
+
while ($token = array_pop($tokens)) {
|
|
185
|
+
$buffer[] = $token;
|
|
186
|
+
if ($token === ")" && $open_parenthesis === 0) {
|
|
187
|
+
// Final parenthesis of the define call.
|
|
188
|
+
break;
|
|
189
|
+
} else if ($token === "(" || $token === "[" || $token === "{") {
|
|
190
|
+
++$open_parenthesis;
|
|
191
|
+
} elseif ($token === ")" || $token === "]" || $token === "}") {
|
|
192
|
+
--$open_parenthesis;
|
|
193
|
+
} elseif ($token === "," && $open_parenthesis === 0) {
|
|
194
|
+
// This define call has more than 2 arguments! The third one is the
|
|
195
|
+
// boolean value indicating $is_case_insensitive. Let's continue capturing
|
|
196
|
+
// to $third_arg_buffer.
|
|
197
|
+
$is_second_argument = false;
|
|
198
|
+
}
|
|
199
|
+
if ($is_second_argument) {
|
|
200
|
+
$value_buffer[] = $token;
|
|
201
|
+
} else {
|
|
202
|
+
$third_arg_buffer[] = $token;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Capture until the semicolon
|
|
207
|
+
// define("WP_DEBUG", true) ;
|
|
208
|
+
// ^^^
|
|
209
|
+
while ($token = array_pop($tokens)) {
|
|
210
|
+
$buffer[] = $token;
|
|
211
|
+
if ($token === ";") {
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Decide whether $name_buffer is a constant name or an expression
|
|
217
|
+
$name_token = null;
|
|
218
|
+
$name_token_index = $token;
|
|
219
|
+
$name_is_literal = true;
|
|
220
|
+
foreach ($name_buffer as $k => $token) {
|
|
221
|
+
if (is_array($token)) {
|
|
222
|
+
if ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_DOC_COMMENT) {
|
|
223
|
+
continue;
|
|
224
|
+
} else if ($token[0] === T_STRING || $token[0] === T_CONSTANT_ENCAPSED_STRING) {
|
|
225
|
+
$name_token = $token;
|
|
226
|
+
$name_token_index = $k;
|
|
227
|
+
} else {
|
|
228
|
+
$name_is_literal = false;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
} else if ($token !== "(" && $token !== ")") {
|
|
232
|
+
$name_is_literal = false;
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// We can't handle expressions as constant names. Let's wrap that define
|
|
238
|
+
// call in an if(!defined()) statement, just in case it collides with
|
|
239
|
+
// a constant name.
|
|
240
|
+
if (!$name_is_literal) {
|
|
241
|
+
// Ensure the defined expression is not already accounted for
|
|
242
|
+
foreach ($defined_expressions as $defined_expression) {
|
|
243
|
+
if ($defined_expression === stringify_tokens(skip_whitespace($name_buffer))) {
|
|
244
|
+
$output = array_merge($output, $buffer);
|
|
245
|
+
continue 2;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
$output = array_merge(
|
|
249
|
+
$output,
|
|
250
|
+
["if(!defined("],
|
|
251
|
+
$name_buffer,
|
|
252
|
+
[")) {\\n "],
|
|
253
|
+
['define('],
|
|
254
|
+
$name_buffer,
|
|
255
|
+
[','],
|
|
256
|
+
$value_buffer,
|
|
257
|
+
$third_arg_buffer,
|
|
258
|
+
[");"],
|
|
259
|
+
["\\n}\\n"]
|
|
260
|
+
);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Yay, we have a literal constant name in the buffer now. Let's
|
|
265
|
+
// get its value:
|
|
266
|
+
$name = eval('return ' . $name_token[1] . ';');
|
|
267
|
+
|
|
268
|
+
// If the constant name is not in the list of constants we're looking,
|
|
269
|
+
// we can ignore it.
|
|
270
|
+
if (!array_key_exists($name, $constants)) {
|
|
271
|
+
$output = array_merge($output, $buffer);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// If "$when_already_defined" is set to 'skip', ignore the definition, and
|
|
276
|
+
// remove the constant from the list so it doesn't get added to the output.
|
|
277
|
+
if ('skip' === $when_already_defined) {
|
|
278
|
+
$output = array_merge($output, $buffer);
|
|
279
|
+
unset($constants[$name]);
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// We now have a define() call that defines a constant we're looking for.
|
|
284
|
+
// Let's rewrite its value to the one
|
|
285
|
+
$output = array_merge(
|
|
286
|
+
$output,
|
|
287
|
+
['define('],
|
|
288
|
+
$name_buffer,
|
|
289
|
+
[','],
|
|
290
|
+
[var_export($constants[$name], true)],
|
|
291
|
+
$third_arg_buffer,
|
|
292
|
+
[");"]
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
// Remove the constant from the list so we can process any remaining
|
|
296
|
+
// constants later.
|
|
297
|
+
unset($constants[$name]);
|
|
298
|
+
} while (count($tokens));
|
|
299
|
+
|
|
300
|
+
// Add any constants that weren't found in the file
|
|
301
|
+
if (count($constants)) {
|
|
302
|
+
$prepend = [
|
|
303
|
+
"<?php \\n"
|
|
304
|
+
];
|
|
305
|
+
foreach ($constants as $name => $value) {
|
|
306
|
+
$prepend = array_merge(
|
|
307
|
+
$prepend,
|
|
308
|
+
[
|
|
309
|
+
"define(",
|
|
310
|
+
var_export($name, true),
|
|
311
|
+
',',
|
|
312
|
+
var_export($value, true),
|
|
313
|
+
");\\n"
|
|
314
|
+
]
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
$prepend[] = "?>";
|
|
318
|
+
$output = array_merge(
|
|
319
|
+
$prepend,
|
|
320
|
+
$output
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Translate the output tokens back into a string
|
|
325
|
+
return stringify_tokens($output);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function stringify_tokens($tokens) {
|
|
329
|
+
$output = '';
|
|
330
|
+
foreach ($tokens as $token) {
|
|
331
|
+
if (is_array($token)) {
|
|
332
|
+
$output .= $token[1];
|
|
333
|
+
} else {
|
|
334
|
+
$output .= $token;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return $output;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function skip_whitespace($tokens) {
|
|
341
|
+
$output = [];
|
|
342
|
+
foreach ($tokens as $token) {
|
|
343
|
+
if (is_array($token) && ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_DOC_COMMENT)) {
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
$output[] = $token;
|
|
347
|
+
}
|
|
348
|
+
return $output;
|
|
349
|
+
}
|
|
350
|
+
`;
|
|
351
|
+
async function E(e, i, t, n = "rewrite") {
|
|
352
|
+
const o = _({ wpConfigPath: i, constants: t, whenAlreadyDefined: n });
|
|
353
|
+
if ((await e.run({
|
|
354
|
+
code: `<?php ob_start(); ?>
|
|
355
|
+
${P}
|
|
356
|
+
$wp_config_path = ${o.wpConfigPath};
|
|
357
|
+
$wp_config = file_get_contents($wp_config_path);
|
|
358
|
+
$new_wp_config = rewrite_wp_config_to_define_constants($wp_config, ${o.constants}, ${o.whenAlreadyDefined});
|
|
359
|
+
$return_value = file_put_contents($wp_config_path, $new_wp_config);
|
|
360
|
+
ob_clean();
|
|
361
|
+
echo false === $return_value ? '0' : '1';
|
|
362
|
+
ob_end_flush();
|
|
363
|
+
`
|
|
364
|
+
})).text !== "1")
|
|
365
|
+
throw new Error("Failed to rewrite constants in wp-config.php.");
|
|
366
|
+
}
|
|
367
|
+
async function T(e, i) {
|
|
368
|
+
const t = r(i, "wp-config.php"), n = {
|
|
369
|
+
DB_NAME: "wordpress"
|
|
370
|
+
};
|
|
371
|
+
!e.fileExists(t) && e.fileExists(r(i, "wp-config-sample.php")) && await e.writeFile(
|
|
372
|
+
t,
|
|
373
|
+
await e.readFileAsBuffer(
|
|
374
|
+
r(i, "wp-config-sample.php")
|
|
375
|
+
)
|
|
376
|
+
), await E(e, t, n, "skip");
|
|
377
|
+
}
|
|
378
|
+
async function N(e) {
|
|
379
|
+
var o, d;
|
|
380
|
+
async function i(a, u) {
|
|
381
|
+
const s = new g(await e.createPhpRuntime());
|
|
382
|
+
return e.sapiName && s.setSapiName(e.sapiName), a && (s.requestHandler = a), e.phpIniEntries && $(s, e.phpIniEntries), u ? (await L(s), await w(s, "/", e.createFiles || {}), await I(
|
|
383
|
+
s,
|
|
384
|
+
r(new URL(e.siteUrl).pathname, "phpinfo.php")
|
|
385
|
+
)) : m(await a.getPrimaryPhp(), s, [
|
|
386
|
+
"/tmp",
|
|
387
|
+
a.documentRoot,
|
|
388
|
+
"/internal/shared"
|
|
389
|
+
]), e.spawnHandler && await s.setSpawnHandler(
|
|
390
|
+
e.spawnHandler(a.processManager)
|
|
391
|
+
), b({
|
|
392
|
+
php: s,
|
|
393
|
+
cwd: a.documentRoot,
|
|
394
|
+
recreateRuntime: e.createPhpRuntime,
|
|
395
|
+
maxRequests: 400
|
|
396
|
+
}), s;
|
|
397
|
+
}
|
|
398
|
+
const t = new h({
|
|
399
|
+
phpFactory: async ({ isPrimary: a }) => i(t, a),
|
|
400
|
+
documentRoot: e.documentRoot || "/wordpress",
|
|
401
|
+
absoluteUrl: e.siteUrl,
|
|
402
|
+
rewriteRules: x,
|
|
403
|
+
getFileNotFoundAction: e.getFileNotFoundAction ?? S,
|
|
404
|
+
cookieStore: e.cookieStore
|
|
405
|
+
}), n = await t.getPrimaryPhp();
|
|
406
|
+
if ((o = e.hooks) != null && o.beforeWordPressFiles && await e.hooks.beforeWordPressFiles(n), e.wordPressZip && await W(n, await e.wordPressZip), e.constants)
|
|
407
|
+
for (const a in e.constants)
|
|
408
|
+
n.defineConstant(a, e.constants[a]);
|
|
409
|
+
if (n.defineConstant("WP_HOME", e.siteUrl), n.defineConstant("WP_SITEURL", e.siteUrl), await T(n, t.documentRoot), (d = e.hooks) != null && d.beforeDatabaseSetup && await e.hooks.beforeDatabaseSetup(n), e.sqliteIntegrationPluginZip && await U(
|
|
410
|
+
n,
|
|
411
|
+
await e.sqliteIntegrationPluginZip
|
|
412
|
+
), await f(n) || await R(n), !await f(n))
|
|
413
|
+
throw new Error("WordPress installation has failed.");
|
|
414
|
+
return t;
|
|
415
|
+
}
|
|
416
|
+
async function f(e) {
|
|
417
|
+
return (await e.run({
|
|
418
|
+
code: `<?php
|
|
419
|
+
ob_start();
|
|
420
|
+
$wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
|
|
421
|
+
if (!file_exists($wp_load)) {
|
|
422
|
+
echo '-1';
|
|
423
|
+
exit;
|
|
424
|
+
}
|
|
425
|
+
require $wp_load;
|
|
426
|
+
ob_clean();
|
|
427
|
+
echo is_blog_installed() ? '1' : '0';
|
|
428
|
+
ob_end_flush();
|
|
429
|
+
`,
|
|
430
|
+
env: {
|
|
431
|
+
DOCUMENT_ROOT: e.documentRoot
|
|
432
|
+
}
|
|
433
|
+
})).text === "1";
|
|
434
|
+
}
|
|
435
|
+
async function R(e) {
|
|
436
|
+
await y(
|
|
437
|
+
e,
|
|
438
|
+
{
|
|
439
|
+
disable_functions: "fsockopen",
|
|
440
|
+
allow_url_fopen: "0"
|
|
441
|
+
},
|
|
442
|
+
async () => await e.request({
|
|
443
|
+
url: "/wp-admin/install.php?step=2",
|
|
444
|
+
method: "POST",
|
|
445
|
+
body: {
|
|
446
|
+
language: "en",
|
|
447
|
+
prefix: "wp_",
|
|
448
|
+
weblog_title: "My WordPress Website",
|
|
449
|
+
user_name: "admin",
|
|
450
|
+
admin_password: "password",
|
|
451
|
+
// The installation wizard demands typing the same password twice
|
|
452
|
+
admin_password2: "password",
|
|
453
|
+
Submit: "Install WordPress",
|
|
454
|
+
pw_weak: "1",
|
|
455
|
+
admin_email: "admin@localhost.com"
|
|
456
|
+
}
|
|
457
|
+
})
|
|
458
|
+
), (await e.run({
|
|
459
|
+
code: `<?php
|
|
460
|
+
ob_start();
|
|
461
|
+
$wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
|
|
462
|
+
if (!file_exists($wp_load)) {
|
|
463
|
+
echo '0';
|
|
464
|
+
exit;
|
|
465
|
+
}
|
|
466
|
+
require $wp_load;
|
|
467
|
+
$option_result = update_option(
|
|
468
|
+
'permalink_structure',
|
|
469
|
+
'/%year%/%monthnum%/%day%/%postname%/'
|
|
470
|
+
);
|
|
471
|
+
ob_clean();
|
|
472
|
+
echo $option_result ? '1' : '0';
|
|
473
|
+
ob_end_flush();
|
|
474
|
+
`,
|
|
475
|
+
env: {
|
|
476
|
+
DOCUMENT_ROOT: e.documentRoot
|
|
477
|
+
}
|
|
478
|
+
})).text !== "1" && k.warn("Failed to default to pretty permalinks after WP install.");
|
|
6
479
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
echo '0';
|
|
13
|
-
exit;
|
|
480
|
+
function S(e) {
|
|
481
|
+
return {
|
|
482
|
+
type: "internal-redirect",
|
|
483
|
+
uri: "/index.php"
|
|
484
|
+
};
|
|
14
485
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
'/%year%/%monthnum%/%day%/%postname%/'
|
|
19
|
-
);
|
|
20
|
-
echo $option_result ? '1' : '0';
|
|
21
|
-
`,env:{DOCUMENT_ROOT:e.documentRoot}})).text!=="1"&&$.warn("Failed to default to pretty permalinks after WP install.")}function E(e){return{type:"internal-redirect",uri:"/index.php"}}async function A(e){const t=(await(await e.getPrimaryPhp()).run({code:`<?php
|
|
486
|
+
async function q(e) {
|
|
487
|
+
const n = (await (await e.getPrimaryPhp()).run({
|
|
488
|
+
code: `<?php
|
|
22
489
|
require '${e.documentRoot}/wp-includes/version.php';
|
|
23
490
|
echo $wp_version;
|
|
24
|
-
`
|
|
491
|
+
`
|
|
492
|
+
})).text;
|
|
493
|
+
if (!n)
|
|
494
|
+
throw new Error("Unable to read loaded WordPress version.");
|
|
495
|
+
return v(n);
|
|
496
|
+
}
|
|
497
|
+
function v(e) {
|
|
498
|
+
if (/-(alpha|beta|RC)\d*-\d+$/.test(e))
|
|
499
|
+
return "nightly";
|
|
500
|
+
if (/-(beta|RC)\d*$/.test(e))
|
|
501
|
+
return "beta";
|
|
502
|
+
const n = e.match(/^(\d+\.\d+)(?:\.\d+)?$/);
|
|
503
|
+
return n !== null ? n[1] : e;
|
|
504
|
+
}
|
|
505
|
+
const x = [
|
|
506
|
+
{
|
|
507
|
+
match: /^\/(.*?)(\/wp-(content|admin|includes)\/.*)/g,
|
|
508
|
+
replacement: "$2"
|
|
509
|
+
}
|
|
510
|
+
];
|
|
511
|
+
async function L(e) {
|
|
512
|
+
await e.mkdir("/internal/shared/mu-plugins"), await e.writeFile(
|
|
513
|
+
"/internal/shared/preload/env.php",
|
|
514
|
+
`<?php
|
|
25
515
|
|
|
26
516
|
// Allow adding filters/actions prior to loading WordPress.
|
|
27
517
|
// $function_to_add MUST be a string.
|
|
@@ -48,7 +538,10 @@ echo $option_result ? '1' : '0';
|
|
|
48
538
|
require_once $mu_plugin;
|
|
49
539
|
}
|
|
50
540
|
}
|
|
51
|
-
`
|
|
541
|
+
`
|
|
542
|
+
), await e.writeFile(
|
|
543
|
+
"/internal/shared/mu-plugins/1-auto-login.php",
|
|
544
|
+
`<?php
|
|
52
545
|
/**
|
|
53
546
|
* Returns the username to auto-login as, if any.
|
|
54
547
|
* @return string|false
|
|
@@ -179,7 +672,10 @@ echo $option_result ? '1' : '0';
|
|
|
179
672
|
}
|
|
180
673
|
return $interval;
|
|
181
674
|
});
|
|
182
|
-
`
|
|
675
|
+
`
|
|
676
|
+
), await e.writeFile(
|
|
677
|
+
"/internal/shared/mu-plugins/0-playground.php",
|
|
678
|
+
`<?php
|
|
183
679
|
// Needed because gethostbyname( 'wordpress.org' ) returns
|
|
184
680
|
// a private network IP address for some reason.
|
|
185
681
|
add_filter( 'allowed_redirect_hosts', function( $deprecated = '' ) {
|
|
@@ -201,7 +697,10 @@ echo $option_result ? '1' : '0';
|
|
|
201
697
|
$log_file = WP_CONTENT_DIR . '/debug.log';
|
|
202
698
|
define('ERROR_LOG_FILE', $log_file);
|
|
203
699
|
ini_set('error_log', $log_file);
|
|
204
|
-
?>`
|
|
700
|
+
?>`
|
|
701
|
+
), await e.writeFile(
|
|
702
|
+
"/internal/shared/preload/error-handler.php",
|
|
703
|
+
`<?php
|
|
205
704
|
(function() {
|
|
206
705
|
$playground_consts = [];
|
|
207
706
|
if(file_exists('/internal/shared/consts.json')) {
|
|
@@ -209,17 +708,6 @@ echo $option_result ? '1' : '0';
|
|
|
209
708
|
$playground_consts = array_keys($playground_consts);
|
|
210
709
|
}
|
|
211
710
|
set_error_handler(function($severity, $message, $file, $line) use($playground_consts) {
|
|
212
|
-
/**
|
|
213
|
-
* This is a temporary workaround to hide the 32bit integer warnings that
|
|
214
|
-
* appear when using various time related function, such as strtotime and mktime.
|
|
215
|
-
* Examples of the warnings that are displayed:
|
|
216
|
-
*
|
|
217
|
-
* Warning: mktime(): Epoch doesn't fit in a PHP integer in <file>
|
|
218
|
-
* Warning: strtotime(): Epoch doesn't fit in a PHP integer in <file>
|
|
219
|
-
*/
|
|
220
|
-
if (strpos($message, "fit in a PHP integer") !== false) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
711
|
/**
|
|
224
712
|
* Networking support in Playground registers a http_api_transports filter.
|
|
225
713
|
*
|
|
@@ -260,18 +748,44 @@ echo $option_result ? '1' : '0';
|
|
|
260
748
|
}
|
|
261
749
|
return false;
|
|
262
750
|
});
|
|
263
|
-
})();`
|
|
751
|
+
})();`
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
async function I(e, i = "/phpinfo.php") {
|
|
755
|
+
await e.writeFile(
|
|
756
|
+
"/internal/shared/preload/phpinfo.php",
|
|
757
|
+
`<?php
|
|
264
758
|
// Render PHPInfo if the requested page is /phpinfo.php
|
|
265
|
-
if ( ${l(
|
|
759
|
+
if ( ${l(i)} === $_SERVER['REQUEST_URI'] ) {
|
|
266
760
|
phpinfo();
|
|
267
761
|
exit;
|
|
268
762
|
}
|
|
269
|
-
`
|
|
763
|
+
`
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
async function U(e, i) {
|
|
767
|
+
await e.isDir("/tmp/sqlite-database-integration") && await e.rmdir("/tmp/sqlite-database-integration", {
|
|
768
|
+
recursive: !0
|
|
769
|
+
}), await e.mkdir("/tmp/sqlite-database-integration"), await p(e, i, "/tmp/sqlite-database-integration");
|
|
770
|
+
const t = "/internal/shared/sqlite-database-integration", n = `/tmp/sqlite-database-integration/${(await e.listFiles("/tmp/sqlite-database-integration"))[0]}`;
|
|
771
|
+
await e.mv(n, t), e.defineConstant("WP_SQLITE_AST_DRIVER", !0), await e.defineConstant("SQLITE_MAIN_FILE", "1");
|
|
772
|
+
const d = (await e.readFileAsText(
|
|
773
|
+
r(t, "db.copy")
|
|
774
|
+
)).replace(
|
|
775
|
+
"'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",
|
|
776
|
+
l(t)
|
|
777
|
+
).replace(
|
|
778
|
+
"'{SQLITE_PLUGIN}'",
|
|
779
|
+
l(r(t, "load.php"))
|
|
780
|
+
), a = r(await e.documentRoot, "wp-content/db.php"), u = `<?php
|
|
270
781
|
// Do not preload this if WordPress comes with a custom db.php file.
|
|
271
|
-
if(file_exists(${l(
|
|
782
|
+
if(file_exists(${l(a)})) {
|
|
272
783
|
return;
|
|
273
784
|
}
|
|
274
|
-
?>`,
|
|
785
|
+
?>`, s = "/internal/shared/mu-plugins/sqlite-database-integration.php";
|
|
786
|
+
await e.writeFile(s, u + d), await e.writeFile(
|
|
787
|
+
"/internal/shared/preload/0-sqlite.php",
|
|
788
|
+
u + `<?php
|
|
275
789
|
|
|
276
790
|
/**
|
|
277
791
|
* Loads the SQLite integration plugin before WordPress is loaded
|
|
@@ -321,7 +835,7 @@ class Playground_SQLite_Integration_Loader {
|
|
|
321
835
|
$GLOBALS['wpdb']->$name = $value;
|
|
322
836
|
}
|
|
323
837
|
protected function load_sqlite_integration() {
|
|
324
|
-
require_once ${l(
|
|
838
|
+
require_once ${l(s)};
|
|
325
839
|
}
|
|
326
840
|
}
|
|
327
841
|
$wpdb = $GLOBALS['wpdb'] = new Playground_SQLite_Integration_Loader();
|
|
@@ -337,11 +851,116 @@ if(!function_exists('mysqli_connect')) {
|
|
|
337
851
|
function mysqli_connect() {}
|
|
338
852
|
}
|
|
339
853
|
|
|
340
|
-
`
|
|
854
|
+
`
|
|
855
|
+
), await e.writeFile(
|
|
856
|
+
"/internal/shared/mu-plugins/sqlite-test.php",
|
|
857
|
+
`<?php
|
|
341
858
|
global $wpdb;
|
|
342
859
|
if(!($wpdb instanceof WP_SQLite_DB)) {
|
|
343
860
|
var_dump(isset($wpdb));
|
|
344
861
|
die("SQLite integration not loaded " . get_class($wpdb));
|
|
345
862
|
}
|
|
346
|
-
`
|
|
863
|
+
`
|
|
864
|
+
);
|
|
865
|
+
}
|
|
866
|
+
async function W(e, i) {
|
|
867
|
+
e.mkdir("/tmp/unzipped-wordpress"), await p(e, i, "/tmp/unzipped-wordpress"), e.fileExists("/tmp/unzipped-wordpress/wordpress.zip") && await p(
|
|
868
|
+
e,
|
|
869
|
+
"/tmp/unzipped-wordpress/wordpress.zip",
|
|
870
|
+
"/tmp/unzipped-wordpress"
|
|
871
|
+
);
|
|
872
|
+
let t = e.fileExists("/tmp/unzipped-wordpress/wordpress") ? "/tmp/unzipped-wordpress/wordpress" : e.fileExists("/tmp/unzipped-wordpress/build") ? "/tmp/unzipped-wordpress/build" : "/tmp/unzipped-wordpress";
|
|
873
|
+
if (!e.fileExists(r(t, "wp-config-sample.php"))) {
|
|
874
|
+
const n = e.listFiles(t);
|
|
875
|
+
if (n.length) {
|
|
876
|
+
const o = n[0];
|
|
877
|
+
e.fileExists(
|
|
878
|
+
r(t, o, "wp-config-sample.php")
|
|
879
|
+
) && (t = r(t, o));
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
if (e.isDir(e.documentRoot) && O(e.documentRoot, e)) {
|
|
883
|
+
for (const n of e.listFiles(t)) {
|
|
884
|
+
const o = r(t, n), d = r(e.documentRoot, n);
|
|
885
|
+
e.mv(o, d);
|
|
886
|
+
}
|
|
887
|
+
e.rmdir(t, { recursive: !0 });
|
|
888
|
+
} else
|
|
889
|
+
e.mv(t, e.documentRoot);
|
|
890
|
+
!e.fileExists(r(e.documentRoot, "wp-config.php")) && e.fileExists(r(e.documentRoot, "wp-config-sample.php")) && e.writeFile(
|
|
891
|
+
r(e.documentRoot, "wp-config.php"),
|
|
892
|
+
e.readFileAsText(
|
|
893
|
+
r(e.documentRoot, "/wp-config-sample.php")
|
|
894
|
+
)
|
|
895
|
+
);
|
|
896
|
+
}
|
|
897
|
+
function O(e, i) {
|
|
898
|
+
const t = i.listFiles(e);
|
|
899
|
+
return t.length === 0 || t.length === 1 && // TODO: use a constant from a site storage package
|
|
900
|
+
t[0] === "playground-site-metadata.json";
|
|
901
|
+
}
|
|
902
|
+
const C = c(fetch);
|
|
903
|
+
async function B(e = "latest") {
|
|
904
|
+
if (e.startsWith("https://") || e.startsWith("http://")) {
|
|
905
|
+
const n = await crypto.subtle.digest(
|
|
906
|
+
"SHA-1",
|
|
907
|
+
new TextEncoder().encode(e)
|
|
908
|
+
), o = Array.from(new Uint8Array(n)).map((d) => d.toString(16).padStart(2, "0")).join("");
|
|
909
|
+
return {
|
|
910
|
+
releaseUrl: e,
|
|
911
|
+
version: "custom-" + o.substring(0, 8),
|
|
912
|
+
source: "inferred"
|
|
913
|
+
};
|
|
914
|
+
} else if (e === "trunk" || e === "nightly")
|
|
915
|
+
return {
|
|
916
|
+
releaseUrl: "https://wordpress.org/nightly-builds/wordpress-latest.zip",
|
|
917
|
+
version: "nightly-" + (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
918
|
+
source: "inferred"
|
|
919
|
+
};
|
|
920
|
+
let t = await (await C(
|
|
921
|
+
"https://api.wordpress.org/core/version-check/1.7/?channel=beta"
|
|
922
|
+
)).json();
|
|
923
|
+
t = t.offers.filter(
|
|
924
|
+
(n) => n.response === "autoupdate"
|
|
925
|
+
);
|
|
926
|
+
for (const n of t) {
|
|
927
|
+
if (e === "beta" && n.version.includes("beta"))
|
|
928
|
+
return {
|
|
929
|
+
releaseUrl: n.download,
|
|
930
|
+
version: n.version,
|
|
931
|
+
source: "api"
|
|
932
|
+
};
|
|
933
|
+
if (e === "latest" && !n.version.includes("beta"))
|
|
934
|
+
return {
|
|
935
|
+
releaseUrl: n.download,
|
|
936
|
+
version: n.version,
|
|
937
|
+
source: "api"
|
|
938
|
+
};
|
|
939
|
+
if (n.version.substring(0, e.length) === e)
|
|
940
|
+
return {
|
|
941
|
+
releaseUrl: n.download,
|
|
942
|
+
version: n.version,
|
|
943
|
+
source: "api"
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
return {
|
|
947
|
+
releaseUrl: `https://wordpress.org/wordpress-${e}.zip`,
|
|
948
|
+
version: e,
|
|
949
|
+
source: "inferred"
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
export {
|
|
953
|
+
N as bootWordPress,
|
|
954
|
+
E as defineWpConfigConstants,
|
|
955
|
+
T as ensureWpConfig,
|
|
956
|
+
S as getFileNotFoundActionForWordPress,
|
|
957
|
+
q as getLoadedWordPressVersion,
|
|
958
|
+
I as preloadPhpInfoRoute,
|
|
959
|
+
U as preloadSqliteIntegration,
|
|
960
|
+
B as resolveWordPressRelease,
|
|
961
|
+
L as setupPlatformLevelMuPlugins,
|
|
962
|
+
W as unzipWordPress,
|
|
963
|
+
v as versionStringToLoadedWordPressVersion,
|
|
964
|
+
x as wordPressRewriteRules
|
|
965
|
+
};
|
|
347
966
|
//# sourceMappingURL=index.js.map
|