Skip to content

Commit f0d6ea4

Browse files
committed
Allow configuring default constants in WP config
1 parent 890c861 commit f0d6ea4

File tree

7 files changed

+82
-3
lines changed

7 files changed

+82
-3
lines changed

packages/playground/cli/src/blueprints-v1/blueprints-v1-handler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export class BlueprintsV1Handler {
142142
mountsBeforeWpInstall,
143143
mountsAfterWpInstall,
144144
wordPressZip: wordPressZip && (await wordPressZip!.arrayBuffer()),
145+
wpConfigDefaultConstants: this.args.wpConfigDefaultConstants,
145146
sqliteIntegrationPluginZip:
146147
await sqliteIntegrationPluginZip?.arrayBuffer(),
147148
firstProcessId: 0,

packages/playground/cli/src/blueprints-v1/worker-thread-v1.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export type WorkerBootOptions = {
5050
export type PrimaryWorkerBootOptions = WorkerBootOptions & {
5151
wpVersion?: string;
5252
wordPressZip?: ArrayBuffer;
53+
wpConfigDefaultConstants?: Record<string, string | number | boolean | null>;
5354
sqliteIntegrationPluginZip?: ArrayBuffer;
5455
dataSqlPath?: string;
5556
};
@@ -129,6 +130,7 @@ export class PlaygroundCliBlueprintV1Worker extends PHPWorker {
129130
mountsAfterWpInstall,
130131
phpVersion: php = RecommendedPHPVersion,
131132
wordPressZip,
133+
wpConfigDefaultConstants,
132134
sqliteIntegrationPluginZip,
133135
firstProcessId,
134136
processIdSpaceLength,
@@ -182,6 +184,7 @@ export class PlaygroundCliBlueprintV1Worker extends PHPWorker {
182184
wordPressZip !== undefined
183185
? new File([wordPressZip], 'wordpress.zip')
184186
: undefined,
187+
wpConfigDefaultConstants,
185188
sqliteIntegrationPluginZip:
186189
sqliteIntegrationPluginZip !== undefined
187190
? new File(

packages/playground/cli/src/blueprints-v2/worker-thread-v2.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
type ParsedBlueprintV2String,
2828
type RawBlueprintV2Data,
2929
} from '@wp-playground/blueprints';
30-
import { bootRequestHandler } from '@wp-playground/wordpress';
30+
import { bootRequestHandler, ensureWpConfig } from '@wp-playground/wordpress';
3131
import { existsSync } from 'fs';
3232
import path from 'path';
3333
import { rootCertificates } from 'tls';
@@ -250,6 +250,17 @@ export class PlaygroundCliBlueprintV2Worker extends PHPWorker {
250250
return;
251251
}
252252

253+
/*
254+
* Add required constants to "wp-config.php" if they are not already defined.
255+
* This is needed, because some WordPress backups and exports may not include
256+
* definitions for some of the necessary constants.
257+
*/
258+
await ensureWpConfig(
259+
primaryPhp,
260+
primaryPhp.requestHandler!.documentRoot,
261+
args.wpConfigDefaultConstants
262+
);
263+
253264
await this.runBlueprintV2(args);
254265
}
255266

packages/playground/cli/src/run-cli.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,20 @@ export async function parseOptionsAndRunCLI() {
153153
type: 'boolean',
154154
default: false,
155155
})
156+
.option('wp-config-default-constants', {
157+
describe:
158+
'Configure default constant values to use in "wp-config.php", in case the constants are missing. Encoded as JSON string.',
159+
type: 'string',
160+
coerce: (value: string) => {
161+
try {
162+
return JSON.parse(value);
163+
} catch (e /* eslint-disable-line @typescript-eslint/no-unused-vars */) {
164+
throw new Error(
165+
'Invalid JSON string for --wp-config-default-constants'
166+
);
167+
}
168+
},
169+
})
156170
.option('skip-wordpress-setup', {
157171
describe:
158172
'Do not download, unzip, and install WordPress. Useful for mounting a pre-configured WordPress directory at /wordpress.',
@@ -420,6 +434,7 @@ export interface RunCLIArgs {
420434
xdebug?: boolean;
421435
experimentalDevtools?: boolean;
422436
'experimental-blueprints-v2-runner'?: boolean;
437+
wpConfigDefaultConstants?: Record<string, string | number | boolean | null>;
423438

424439
// --------- Blueprint V1 args -----------
425440
skipWordPressSetup?: boolean;

packages/playground/wordpress/src/boot.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ export interface BootWordPressOptions {
126126
dataSqlPath?: string;
127127
/** Zip with the WordPress installation to extract in /wordpress. */
128128
wordPressZip?: File | Promise<File> | undefined;
129+
/**
130+
* Default constant values to use in "wp-config.php", in case they are missing.
131+
*/
132+
wpConfigDefaultConstants?: Record<string, string | number | boolean | null>;
129133
/** Preloaded SQLite integration plugin. */
130134
sqliteIntegrationPluginZip?: File | Promise<File>;
131135
/**
@@ -186,7 +190,11 @@ export async function bootWordPress(
186190
* This is needed, because some WordPress backups and exports may not include
187191
* definitions for some of the necessary constants.
188192
*/
189-
await ensureWpConfig(php, requestHandler.documentRoot);
193+
await ensureWpConfig(
194+
php,
195+
requestHandler.documentRoot,
196+
options.wpConfigDefaultConstants
197+
);
190198
// Run "before database" hooks to mount/copy more files in
191199
if (options.hooks?.beforeDatabaseSetup) {
192200
await options.hooks.beforeDatabaseSetup(php);

packages/playground/wordpress/src/test/wp-config.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,40 @@ if ( ! defined( 'ABSPATH' ) ) {
246246
require_once ABSPATH . 'wp-settings.php';
247247
`);
248248
});
249+
250+
it('should allow configuring default constants', async () => {
251+
php.writeFile(
252+
wpConfigPath,
253+
`<?php
254+
echo json_encode([
255+
'DB_NAME' => DB_NAME,
256+
'DB_USER' => DB_USER,
257+
'CUSTOM_CONSTANT' => CUSTOM_CONSTANT,
258+
'WP_DEBUG' => WP_DEBUG,
259+
]);`
260+
);
261+
262+
await ensureWpConfig(php, documentRoot, {
263+
DB_NAME: 'custom-name',
264+
CUSTOM_CONSTANT: 'custom-value',
265+
});
266+
267+
const rewritten = php.readFileAsText(wpConfigPath);
268+
expect(rewritten).toContain(`define( 'DB_NAME', 'custom-name' );`);
269+
expect(rewritten).toContain(`define( 'DB_USER', 'wordpress' );`);
270+
expect(rewritten).toContain(
271+
`define( 'CUSTOM_CONSTANT', 'custom-value' );`
272+
);
273+
expect(rewritten).toContain(`define( 'WP_DEBUG', false );`);
274+
275+
const response = await php.run({ code: rewritten });
276+
expect(response.json).toEqual({
277+
DB_NAME: 'custom-name',
278+
DB_USER: 'wordpress',
279+
CUSTOM_CONSTANT: 'custom-value',
280+
WP_DEBUG: false,
281+
});
282+
});
249283
});
250284

251285
describe('defineWpConfigConstants', () => {

packages/playground/wordpress/src/wp-config.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import wpConfigTransformer from './wp-config-transformer.php?raw';
1414
*/
1515
export async function ensureWpConfig(
1616
php: UniversalPHP,
17-
documentRoot: string
17+
documentRoot: string,
18+
defaultConstants: Record<string, string | number | boolean | null> = {}
1819
): Promise<void> {
1920
const wpConfigPath = joinPaths(documentRoot, 'wp-config.php');
2021

@@ -35,6 +36,7 @@ export async function ensureWpConfig(
3536
LOGGED_IN_SALT: 'put your unique phrase here',
3637
NONCE_SALT: 'put your unique phrase here',
3738
WP_DEBUG: false,
39+
...defaultConstants,
3840
};
3941

4042
/**
@@ -63,6 +65,11 @@ export async function ensureWpConfig(
6365
);
6466
}
6567

68+
// When we still don't have a wp-config.php file, there's nothing to be done.
69+
if (!php.fileExists(wpConfigPath)) {
70+
return;
71+
}
72+
6673
// Ensure required constants are defined.
6774
const js = phpVars({ wpConfigPath, constants: defaults });
6875
const result = await php.run({

0 commit comments

Comments
 (0)