@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/index.js CHANGED
@@ -1,27 +1,517 @@
1
- import{joinPaths as a,phpVar as l}from"@php-wasm/util";import{createMemoizedFetch as _,unzipFile as d}from"@wp-playground/common";import{PHPRequestHandler as g,withPHPIniValues as f,PHP as h,setPhpIniEntries as w,writeFiles as m,proxyFileSystem as b,rotatePHPRuntime as y}from"@php-wasm/universal";import{logger as $}from"@php-wasm/logger";async function q(e){async function r(n,o){const s=new h(await e.createPhpRuntime());return e.sapiName&&s.setSapiName(e.sapiName),n&&(s.requestHandler=n),e.phpIniEntries&&w(s,e.phpIniEntries),o?(await T(s),await m(s,"/",e.createFiles||{}),await L(s,a(new URL(e.siteUrl).pathname,"phpinfo.php"))):b(await n.getPrimaryPhp(),s,["/tmp",n.documentRoot,"/internal/shared"]),e.spawnHandler&&await s.setSpawnHandler(e.spawnHandler(n.processManager)),y({php:s,cwd:n.documentRoot,recreateRuntime:e.createPhpRuntime,maxRequests:400}),s}const i=new g({phpFactory:async({isPrimary:n})=>r(i,n),documentRoot:e.documentRoot||"/wordpress",absoluteUrl:e.siteUrl,rewriteRules:S,getFileNotFoundAction:e.getFileNotFoundAction??E}),t=await i.getPrimaryPhp();if(e.hooks?.beforeWordPressFiles&&await e.hooks.beforeWordPressFiles(t),e.wordPressZip&&await v(t,await e.wordPressZip),e.constants)for(const n in e.constants)t.defineConstant(n,e.constants[n]);if(t.defineConstant("WP_HOME",e.siteUrl),t.defineConstant("WP_SITEURL",e.siteUrl),e.hooks?.beforeDatabaseSetup&&await e.hooks.beforeDatabaseSetup(t),e.sqliteIntegrationPluginZip&&await I(t,await e.sqliteIntegrationPluginZip),await c(t)||await P(t),!await c(t))throw new Error("WordPress installation has failed.");return i}async function c(e){return(await e.run({code:`<?php
2
- $wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
3
- if (!file_exists($wp_load)) {
4
- echo '0';
5
- exit;
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
- require $wp_load;
8
- echo is_blog_installed() ? '1' : '0';
9
- `,env:{DOCUMENT_ROOT:e.documentRoot}})).text==="1"}async function P(e){await f(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"}})),(await e.run({code:`<?php
10
- $wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
11
- if (!file_exists($wp_load)) {
12
- echo '0';
13
- exit;
480
+ function S(e) {
481
+ return {
482
+ type: "internal-redirect",
483
+ uri: "/index.php"
484
+ };
14
485
  }
15
- require $wp_load;
16
- $option_result = update_option(
17
- 'permalink_structure',
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
- `})).text;if(!t)throw new Error("Unable to read loaded WordPress version.");return R(t)}function R(e){if(/-(alpha|beta|RC)\d*-\d+$/.test(e))return"nightly";if(/-(beta|RC)\d*$/.test(e))return"beta";const t=e.match(/^(\d+\.\d+)(?:\.\d+)?$/);return t!==null?t[1]:e}const S=[{match:/^\/(.*?)(\/wp-(content|admin|includes)\/.*)/g,replacement:"$2"}];async function T(e){await e.mkdir("/internal/shared/mu-plugins"),await e.writeFile("/internal/shared/preload/env.php",`<?php
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
- `),await e.writeFile("/internal/shared/mu-plugins/1-auto-login.php",`<?php
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
- `),await e.writeFile("/internal/shared/mu-plugins/0-playground.php",`<?php
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
- ?>`),await e.writeFile("/internal/shared/preload/error-handler.php",`<?php
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
- })();`)}async function L(e,r="/phpinfo.php"){await e.writeFile("/internal/shared/preload/phpinfo.php",`<?php
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(r)} === $_SERVER['REQUEST_URI'] ) {
759
+ if ( ${l(i)} === $_SERVER['REQUEST_URI'] ) {
266
760
  phpinfo();
267
761
  exit;
268
762
  }
269
- `)}async function I(e,r){await e.isDir("/tmp/sqlite-database-integration")&&await e.rmdir("/tmp/sqlite-database-integration",{recursive:!0}),await e.mkdir("/tmp/sqlite-database-integration"),await d(e,r,"/tmp/sqlite-database-integration");const i="/internal/shared/sqlite-database-integration",t=await e.isDir("/tmp/sqlite-database-integration/sqlite-database-integration-main")?"/tmp/sqlite-database-integration/sqlite-database-integration-main":"/tmp/sqlite-database-integration/sqlite-database-integration-develop";await e.mv(t,i),await e.defineConstant("SQLITE_MAIN_FILE","1");const o=(await e.readFileAsText(a(i,"db.copy"))).replace("'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",l(i)).replace("'{SQLITE_PLUGIN}'",l(a(i,"load.php"))),s=a(await e.documentRoot,"wp-content/db.php"),u=`<?php
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(s)})) {
782
+ if(file_exists(${l(a)})) {
272
783
  return;
273
784
  }
274
- ?>`,p="/internal/shared/mu-plugins/sqlite-database-integration.php";await e.writeFile(p,u+o),await e.writeFile("/internal/shared/preload/0-sqlite.php",u+`<?php
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(p)};
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
- `),await e.writeFile("/internal/shared/mu-plugins/sqlite-test.php",`<?php
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
- `)}async function v(e,r){e.mkdir("/tmp/unzipped-wordpress"),await d(e,r,"/tmp/unzipped-wordpress"),e.fileExists("/tmp/unzipped-wordpress/wordpress.zip")&&await d(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(a(i,"wp-config-sample.php"))){const t=e.listFiles(i);if(t.length){const n=t[0];e.fileExists(a(i,n,"wp-config-sample.php"))&&(i=a(i,n))}}if(e.isDir(e.documentRoot)&&U(e.documentRoot,e)){for(const t of e.listFiles(i)){const n=a(i,t),o=a(e.documentRoot,t);e.mv(n,o)}e.rmdir(i,{recursive:!0})}else e.mv(i,e.documentRoot);!e.fileExists(a(e.documentRoot,"wp-config.php"))&&e.fileExists(a(e.documentRoot,"wp-config-sample.php"))&&e.writeFile(a(e.documentRoot,"wp-config.php"),e.readFileAsText(a(e.documentRoot,"/wp-config-sample.php")))}function U(e,r){const i=r.listFiles(e);return i.length===0||i.length===1&&i[0]==="playground-site-metadata.json"}const O=_(fetch);async function N(e="latest"){if(e.startsWith("https://")||e.startsWith("http://")){const t=await crypto.subtle.digest("SHA-1",new TextEncoder().encode(e)),n=Array.from(new Uint8Array(t)).map(o=>o.toString(16).padStart(2,"0")).join("");return{releaseUrl:e,version:"custom-"+n.substring(0,8),source:"inferred"}}else if(e==="trunk"||e==="nightly")return{releaseUrl:"https://wordpress.org/nightly-builds/wordpress-latest.zip",version:"nightly-"+new Date().toISOString().split("T")[0],source:"inferred"};let i=await(await O("https://api.wordpress.org/core/version-check/1.7/?channel=beta")).json();i=i.offers.filter(t=>t.response==="autoupdate");for(const t of i){if(e==="beta"&&t.version.includes("beta"))return{releaseUrl:t.download,version:t.version,source:"api"};if(e==="latest"&&!t.version.includes("beta"))return{releaseUrl:t.download,version:t.version,source:"api"};if(t.version.substring(0,e.length)===e)return{releaseUrl:t.download,version:t.version,source:"api"}}return{releaseUrl:`https://wordpress.org/wordpress-${e}.zip`,version:e,source:"inferred"}}export{q as bootWordPress,E as getFileNotFoundActionForWordPress,A as getLoadedWordPressVersion,L as preloadPhpInfoRoute,I as preloadSqliteIntegration,N as resolveWordPressRelease,T as setupPlatformLevelMuPlugins,v as unzipWordPress,R as versionStringToLoadedWordPressVersion,S as wordPressRewriteRules};
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