Skip to content

Commit 65ec501

Browse files
youknowriadt-hamano
authored andcommitted
Add phpMyAdmin support to wp-env Playground runtime (#75532)
Co-authored-by: youknowriad <youknowriad@git.wordpress.org> Co-authored-by: t-hamano <wildworks@git.wordpress.org>
1 parent 2388cb9 commit 65ec501

File tree

10 files changed

+1057
-384
lines changed

10 files changed

+1057
-384
lines changed

package-lock.json

Lines changed: 943 additions & 365 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/env/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
### New Features
1818

19+
- Added `phpmyadmin` boolean configuration option to enable phpMyAdmin. Setting `phpmyadminPort` also enables phpMyAdmin for backward compatibility.
20+
- Added phpMyAdmin support to the Playground runtime. When enabled, phpMyAdmin is available at `http://localhost:<port>/phpmyadmin`.
1921
- Added `status` command that shows comprehensive environment information including running state, URLs, ports, configuration, and paths.
2022
- Added `--config` global option to specify a custom configuration file path, enabling multiple parallel environments from the same directory.
2123
- Added `testsEnvironment` configuration option. Set to `false` to skip creating test containers (`tests-mysql`, `tests-wordpress`, `tests-cli`, `tests-phpmyadmin`), reducing resource usage when test isolation is achieved via separate config files.

packages/env/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ $ wp-env start --runtime=playground
4141
| Requires Docker | Yes | No |
4242
| Xdebug | Yes | Yes |
4343
| SPX profiling | Yes | No |
44-
| phpMyAdmin | Yes | No |
44+
| phpMyAdmin | Yes | Yes |
4545
| MySQL database | Yes | No (SQLite) |
4646
| Multisite | Yes | Yes |
4747
| Custom PHP version | Yes | Yes |
@@ -596,7 +596,8 @@ You can customize the WordPress installation, plugins and themes that the develo
596596
| `"config"` | `Object` | See below. | Mapping of wp-config.php constants to their desired values. |
597597
| `"mappings"` | `Object` | `"{}"` | Mapping of WordPress directories to local directories to be mounted in the WordPress instance. |
598598
| `"mysqlPort"` | `integer` | `null` (randomly assigned) | The MySQL port number to expose. |
599-
| `"phpmyadminPort"` | `integer` | `null` | The port number for phpMyAdmin. If provided, you'll access phpMyAdmin through: http://localhost:<port> |
599+
| `"phpmyadmin"` | `boolean` | `false` | Whether to enable phpMyAdmin for database management. |
600+
| `"phpmyadminPort"` | `integer` | `null` (randomly assigned) | The port number for phpMyAdmin (Docker only). Setting this also enables phpMyAdmin. |
600601
| `"multisite"` | `boolean` | `false` | Whether to set up a multisite installation. |
601602
| `"lifecycleScripts"` | `Object` | `"{}"` | Mapping of commands that should be executed at certain points in the lifecycle. |
602603

@@ -785,7 +786,7 @@ You can tell `wp-env` to use a custom port number so that your instance does not
785786
These can also be set via environment variables:
786787

787788
- `WP_ENV_PORT` to override the web server's port.
788-
- phpMyAdmin is not enabled by default, but its port can also be overridden via `WP_ENV_PHPMYADMIN_PORT`.
789+
- phpMyAdmin is not enabled by default. Enable it with `"phpmyadmin": true` in `.wp-env.json`. The Docker runtime port can also be overridden via `WP_ENV_PHPMYADMIN_PORT`.
789790
- By default, MySQL isn't exposed to the host, which means no chance of port conflicts. But this can also be overridden via `WP_ENV_MYSQL_PORT`.
790791

791792
### Specific PHP Version

packages/env/lib/config/parse-config.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ const mergeConfigs = require( './merge-configs' );
5151
* @property {WPSource[]} themeSources Themes to load in the environment.
5252
* @property {number} port The port to use.
5353
* @property {number} mysqlPort The port to use for MySQL. Random if empty.
54-
* @property {number} phpmyadminPort The port to use for phpMyAdmin. If empty, disabled phpMyAdmin.
54+
* @property {boolean} phpmyadmin Whether to enable phpMyAdmin.
55+
* @property {number} phpmyadminPort The port to use for phpMyAdmin. Random if empty.
5556
* @property {boolean} multisite Whether to set up a multisite installation.
5657
* @property {Object} config Mapping of wp-config.php constants to their desired values.
5758
* @property {Object.<string, WPSource>} mappings Mapping of WordPress directories to local directories which should be mounted.
@@ -89,6 +90,7 @@ const DEFAULT_ENVIRONMENT_CONFIG = {
8990
port: 8888,
9091
testsPort: 8889,
9192
mysqlPort: null,
93+
phpmyadmin: false,
9294
phpmyadminPort: null,
9395
multisite: false,
9496
mappings: {},
@@ -306,6 +308,7 @@ function getEnvironmentVarOverrides( cacheDirectoryPath ) {
306308
if ( overrides.phpmyadminPort ) {
307309
overrideConfig.env.development.phpmyadminPort =
308310
overrides.phpmyadminPort;
311+
overrideConfig.env.development.phpmyadmin = true;
309312
}
310313

311314
if ( overrides.testsPort ) {
@@ -496,8 +499,17 @@ async function parseEnvironmentConfig(
496499
parsedConfig.mysqlPort = config.mysqlPort;
497500
}
498501

502+
if ( config.phpmyadmin !== undefined ) {
503+
parsedConfig.phpmyadmin = config.phpmyadmin;
504+
}
505+
499506
if ( config.phpmyadminPort !== undefined ) {
500507
parsedConfig.phpmyadminPort = config.phpmyadminPort;
508+
// Backward compat: setting phpmyadminPort implies phpmyadmin: true
509+
// unless phpmyadmin was explicitly set.
510+
if ( config.phpmyadmin === undefined ) {
511+
parsedConfig.phpmyadmin = true;
512+
}
501513
}
502514

503515
if ( config.multisite !== undefined ) {

packages/env/lib/config/test/__snapshots__/config-integration.js.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ exports[`Config Integration should load local and override configuration files 1
3333
"multisite": false,
3434
"mysqlPort": 23306,
3535
"phpVersion": null,
36+
"phpmyadmin": false,
3637
"phpmyadminPort": null,
3738
"pluginSources": [],
3839
"port": 999,
@@ -64,6 +65,7 @@ exports[`Config Integration should load local and override configuration files 1
6465
"multisite": false,
6566
"mysqlPort": 23307,
6667
"phpVersion": null,
68+
"phpmyadmin": false,
6769
"phpmyadminPort": null,
6870
"pluginSources": [],
6971
"port": 456,
@@ -116,6 +118,7 @@ exports[`Config Integration should load local configuration file 1`] = `
116118
"multisite": false,
117119
"mysqlPort": 13306,
118120
"phpVersion": null,
121+
"phpmyadmin": false,
119122
"phpmyadminPort": null,
120123
"pluginSources": [],
121124
"port": 123,
@@ -147,6 +150,7 @@ exports[`Config Integration should load local configuration file 1`] = `
147150
"multisite": false,
148151
"mysqlPort": 23307,
149152
"phpVersion": null,
153+
"phpmyadmin": false,
150154
"phpmyadminPort": null,
151155
"pluginSources": [],
152156
"port": 8889,
@@ -199,6 +203,7 @@ exports[`Config Integration should use default configuration 1`] = `
199203
"multisite": false,
200204
"mysqlPort": null,
201205
"phpVersion": null,
206+
"phpmyadmin": false,
202207
"phpmyadminPort": null,
203208
"pluginSources": [],
204209
"port": 8888,
@@ -230,6 +235,7 @@ exports[`Config Integration should use default configuration 1`] = `
230235
"multisite": false,
231236
"mysqlPort": null,
232237
"phpVersion": null,
238+
"phpmyadmin": false,
233239
"phpmyadminPort": null,
234240
"pluginSources": [],
235241
"port": 8889,
@@ -282,6 +288,7 @@ exports[`Config Integration should use environment variables over local and over
282288
"multisite": false,
283289
"mysqlPort": 23306,
284290
"phpVersion": null,
291+
"phpmyadmin": false,
285292
"phpmyadminPort": null,
286293
"pluginSources": [],
287294
"port": 12345,
@@ -314,6 +321,7 @@ exports[`Config Integration should use environment variables over local and over
314321
"multisite": false,
315322
"mysqlPort": 23307,
316323
"phpVersion": null,
324+
"phpmyadmin": false,
317325
"phpmyadminPort": null,
318326
"pluginSources": [],
319327
"port": 61234,

packages/env/lib/config/test/parse-config.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const DEFAULT_CONFIG = {
2222
port: 8888,
2323
testsPort: 8889,
2424
mysqlPort: null,
25+
phpmyadmin: false,
2526
phpmyadminPort: null,
2627
multisite: false,
2728
phpVersion: null,
@@ -416,6 +417,7 @@ describe( 'parseConfig', () => {
416417
},
417418
env: {
418419
development: {
420+
phpmyadmin: true,
419421
phpmyadminPort: 9001,
420422
},
421423
},
@@ -428,6 +430,38 @@ describe( 'parseConfig', () => {
428430
const expected = {
429431
development: {
430432
...DEFAULT_CONFIG.env.development,
433+
phpmyadmin: true,
434+
phpmyadminPort: 9001,
435+
},
436+
tests: DEFAULT_CONFIG.env.tests,
437+
};
438+
expect( parsed.env ).toEqual( expected );
439+
} );
440+
441+
it( 'should infer phpmyadmin: true when phpmyadminPort is set', async () => {
442+
readRawConfigFile.mockImplementation( async ( configFile ) => {
443+
if ( configFile === '/test/gutenberg/.wp-env.json' ) {
444+
return {
445+
core: 'WordPress/WordPress#Test',
446+
phpVersion: '1.0',
447+
lifecycleScripts: {
448+
afterStart: 'test',
449+
},
450+
env: {
451+
development: {
452+
phpmyadminPort: 9001,
453+
},
454+
},
455+
};
456+
}
457+
} );
458+
459+
const parsed = await parseConfig( '/test/gutenberg', '/cache' );
460+
461+
const expected = {
462+
development: {
463+
...DEFAULT_CONFIG.env.development,
464+
phpmyadmin: true,
431465
phpmyadminPort: 9001,
432466
},
433467
tests: DEFAULT_CONFIG.env.tests,

packages/env/lib/runtime/docker/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ class DockerRuntime {
241241
: [],
242242
} );
243243

244-
if ( fullConfig.env.development.phpmyadminPort ) {
244+
if ( fullConfig.env.development.phpmyadmin ) {
245245
await dockerCompose.upOne( 'phpmyadmin', {
246246
...dockerComposeConfig,
247247
commandOptions: shouldConfigureWp
@@ -250,7 +250,7 @@ class DockerRuntime {
250250
} );
251251
}
252252

253-
if ( testsEnabled && fullConfig.env.tests.phpmyadminPort ) {
253+
if ( testsEnabled && fullConfig.env.tests.phpmyadmin ) {
254254
await dockerCompose.upOne( 'tests-phpmyadmin', {
255255
...dockerComposeConfig,
256256
commandOptions: shouldConfigureWp
@@ -312,7 +312,7 @@ class DockerRuntime {
312312
dockerComposeConfig
313313
);
314314

315-
const phpmyadminPort = fullConfig.env.development.phpmyadminPort
315+
const phpmyadminPort = fullConfig.env.development.phpmyadmin
316316
? await this._getPublicDockerPort(
317317
'phpmyadmin',
318318
80,
@@ -335,7 +335,7 @@ class DockerRuntime {
335335
3306,
336336
dockerComposeConfig
337337
);
338-
const testsPhpmyadminPort = fullConfig.env.tests.phpmyadminPort
338+
const testsPhpmyadminPort = fullConfig.env.tests.phpmyadmin
339339
? await this._getPublicDockerPort(
340340
'tests-phpmyadmin',
341341
80,
@@ -726,7 +726,7 @@ class DockerRuntime {
726726
);
727727
isRunning = true;
728728

729-
if ( fullConfig.env.development.phpmyadminPort ) {
729+
if ( fullConfig.env.development.phpmyadmin ) {
730730
phpmyadminPort = await this._getPublicDockerPort(
731731
'phpmyadmin',
732732
80,

packages/env/lib/runtime/playground/index.js

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class PlaygroundRuntime {
4848
testsEnvironment: false, // Single environment only
4949
xdebug: true, // Supported via --xdebug flag
5050
spx: false, // Not supported in WebAssembly
51-
phpMyAdmin: false, // Supported on playground.wordpress.net but not in CLI yet
51+
phpMyAdmin: true, // Supported via --phpmyadmin CLI flag
5252
multisite: true, // Supported via Blueprint
5353
customPhpVersion: true, // Supported via --php flag
5454
persistentDatabase: false, // Could be supported via mounts (not yet implemented)
@@ -170,6 +170,10 @@ class PlaygroundRuntime {
170170
cliArgs.push( '--verbosity', 'debug' );
171171
}
172172

173+
if ( envConfig.phpmyadmin ) {
174+
cliArgs.push( '--phpmyadmin' );
175+
}
176+
173177
if ( xdebug ) {
174178
cliArgs.push( '--xdebug' );
175179
}
@@ -184,12 +188,27 @@ class PlaygroundRuntime {
184188
// Create write stream for log file
185189
const logFileStream = await fs.open( logFile, 'w' );
186190

191+
// Resolve the CLI binary directly so that it is found even when
192+
// the package is nested inside workspace node_modules (where npx
193+
// cannot discover it).
194+
const cliPackageJson = require.resolve(
195+
'@wp-playground/cli/package.json'
196+
);
197+
const cliEntryPoint = path.join(
198+
path.dirname( cliPackageJson ),
199+
'wp-playground.js'
200+
);
201+
187202
return new Promise( ( resolve, reject ) => {
188-
const child = spawn( 'npx', [ '@wp-playground/cli', ...cliArgs ], {
189-
detached: true,
190-
stdio: [ 'ignore', logFileStream.fd, logFileStream.fd ],
191-
env: { ...process.env, FORCE_COLOR: '0' },
192-
} );
203+
const child = spawn(
204+
process.execPath,
205+
[ cliEntryPoint, ...cliArgs ],
206+
{
207+
detached: true,
208+
stdio: [ 'ignore', logFileStream.fd, logFileStream.fd ],
209+
env: { ...process.env, FORCE_COLOR: '0' },
210+
}
211+
);
193212

194213
// Store child process reference
195214
this.serverProcess = child;
@@ -241,8 +260,17 @@ class PlaygroundRuntime {
241260
.then( async () => {
242261
spinner.text = `WordPress Playground started at ${ siteUrl }`;
243262

244-
const message =
245-
'WordPress development site started at ' + siteUrl;
263+
const phpmyadminUrl = envConfig.phpmyadmin
264+
? `${ siteUrl }/phpmyadmin`
265+
: null;
266+
267+
const message = [
268+
'WordPress development site started at ' + siteUrl,
269+
phpmyadminUrl &&
270+
`phpMyAdmin started at ${ phpmyadminUrl }`,
271+
]
272+
.filter( Boolean )
273+
.join( '\n' );
246274

247275
resolve( {
248276
message,
@@ -449,6 +477,10 @@ class PlaygroundRuntime {
449477
runtime: 'playground',
450478
urls: {
451479
development: isRunning ? `http://localhost:${ port }` : null,
480+
phpmyadmin:
481+
isRunning && envConfig.phpmyadmin
482+
? `http://localhost:${ port }/phpmyadmin`
483+
: null,
452484
},
453485
ports: {
454486
development: port,

packages/env/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
},
4545
"dependencies": {
4646
"@inquirer/prompts": "^7.2.0",
47-
"@wp-playground/cli": "^3.0.0",
47+
"@wp-playground/cli": "^3.0.48",
4848
"chalk": "^4.0.0",
4949
"copy-dir": "^1.3.0",
5050
"cross-spawn": "^7.0.6",

schemas/json/wp-env.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,13 @@
6363
"type": "object",
6464
"default": {}
6565
},
66+
"phpmyadmin": {
67+
"description": "Whether to enable phpMyAdmin for database management.",
68+
"type": "boolean",
69+
"default": false
70+
},
6671
"phpmyadminPort": {
67-
"description": "The port number to access phpMyAdmin.",
72+
"description": "The port number to access phpMyAdmin. Setting this also enables phpMyAdmin.",
6873
"type": "integer"
6974
},
7075
"multisite": {
@@ -82,6 +87,7 @@
8287
"port",
8388
"config",
8489
"mappings",
90+
"phpmyadmin",
8591
"phpmyadminPort",
8692
"multisite"
8793
]

0 commit comments

Comments
 (0)