Skip to content

Commit

Permalink
Support arbitrary PHP extensions (#681)
Browse files Browse the repository at this point in the history
Adds support for loading arbitrary PHP extensions in the web version of
Playground using all three available APIs:

* Query API: `?php-extension-bundle=kitchen-sink`
* Blueprints: `{ "phpExtensionBundles": [ "kitchen-sink" ] }`

For now, it only switches between a barebones ~6MB PHP build and a
larger ~8MB with more extensions included. In the future, the internal
implementation will change and PHP extensions will be shipped and
downloaded separately – see
#673

1. Click the new "Load PHP extensions" checkbox in the configuration
modal
2. Go to /phpinfo.php and confirm that `gd`, `xml`, and `mbstring`
extensions are now available
3. Uncheck that checkbox
4. Confirm these extensions are no longer loaded

<img width="1251" alt="CleanShot 2023-10-11 at 19 50 14@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/4f341a98-6a3a-4b01-b406-03d3e2834a20">

Solves #655

cc @dmsnell @danielbachhuber @seanmorris
  • Loading branch information
adamziel committed Oct 12, 2023
1 parent 6308abf commit 84f1838
Show file tree
Hide file tree
Showing 60 changed files with 1,088 additions and 102 deletions.
30 changes: 20 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,26 @@
"lint": "nx run-many --all --target=lint",
"prepublishOnly": "npm run build",
"preview": "nx preview playground-website",
"recompile:php:web": "nx recompile-php:all php-wasm-web",
"recompile:php:web:5.6": "nx recompile-php php-wasm-web --PHP_VERSION=5.6",
"recompile:php:web:7.0": "nx recompile-php php-wasm-web --PHP_VERSION=7.0",
"recompile:php:web:7.1": "nx recompile-php php-wasm-web --PHP_VERSION=7.1",
"recompile:php:web:7.2": "nx recompile-php php-wasm-web --PHP_VERSION=7.2",
"recompile:php:web:7.3": "nx recompile-php php-wasm-web --PHP_VERSION=7.3",
"recompile:php:web:7.4": "nx recompile-php php-wasm-web --PHP_VERSION=7.4",
"recompile:php:web:8.0": "nx recompile-php php-wasm-web --PHP_VERSION=8.0",
"recompile:php:web:8.1": "nx recompile-php php-wasm-web --PHP_VERSION=8.1",
"recompile:php:web:8.2": "nx recompile-php php-wasm-web --PHP_VERSION=8.2",
"recompile:php:web:light": "nx recompile-php:light php-wasm-web ",
"recompile:php:web:light:5.6": "nx recompile-php:light php-wasm-web --PHP_VERSION=5.6",
"recompile:php:web:light:7.0": "nx recompile-php:light php-wasm-web --PHP_VERSION=7.0",
"recompile:php:web:light:7.1": "nx recompile-php:light php-wasm-web --PHP_VERSION=7.1",
"recompile:php:web:light:7.2": "nx recompile-php:light php-wasm-web --PHP_VERSION=7.2",
"recompile:php:web:light:7.3": "nx recompile-php:light php-wasm-web --PHP_VERSION=7.3",
"recompile:php:web:light:7.4": "nx recompile-php:light php-wasm-web --PHP_VERSION=7.4",
"recompile:php:web:light:8.0": "nx recompile-php:light php-wasm-web --PHP_VERSION=8.0",
"recompile:php:web:light:8.1": "nx recompile-php:light php-wasm-web --PHP_VERSION=8.1",
"recompile:php:web:light:8.2": "nx recompile-php:light php-wasm-web --PHP_VERSION=8.2",
"recompile:php:web:kitchen-sink": "nx recompile-php:kitchen-sink php-wasm-web",
"recompile:php:web:kitchen-sink:5.6": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=5.6",
"recompile:php:web:kitchen-sink:7.0": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=7.0",
"recompile:php:web:kitchen-sink:7.1": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=7.1",
"recompile:php:web:kitchen-sink:7.2": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=7.2",
"recompile:php:web:kitchen-sink:7.3": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=7.3",
"recompile:php:web:kitchen-sink:7.4": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=7.4",
"recompile:php:web:kitchen-sink:8.0": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=8.0",
"recompile:php:web:kitchen-sink:8.1": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=8.1",
"recompile:php:web:kitchen-sink:8.2": "nx recompile-php:kitchen-sink php-wasm-web --PHP_VERSION=8.2",
"recompile:php:node": "nx recompile-php:all php-wasm-node",
"recompile:php:node:5.6": "nx recompile-php php-wasm-node --PHP_VERSION=5.6",
"recompile:php:node:7.0": "nx recompile-php php-wasm-node --PHP_VERSION=7.0",
Expand Down
24 changes: 12 additions & 12 deletions packages/docs/site/docs/08-query-api/01-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ You can go ahead and try it out. The Playground will automatically install the t

## Available options

| Option | Default Value | Description |
| -------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `php` | `8.0` | Loads the specified PHP version. Supported values: `5.6`, `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `latest` |
| `wp` | `latest` | Loads the specified WordPress version. Supported values: `5.9`, `6.0`, `6.1`, `6.2`, `6.3`, `latest`, `nightly` |
| `plugin` | | Installs the specified plugin. Use the plugin name from the plugins directory URL, e.g. for a URL like `https://wordpress.org/plugins/wp-lazy-loading/`, the plugin name would be `wp-lazy-loading`. You can pre-install multiple plugins by saying `plugin=coblocks&plugin=wp-lazy-loading&…`. Installing a plugin automatically logs the user in as an admin |
| `theme` | | Installs the specified theme. Use the theme name from the themes directory URL, e.g. for a URL like `https://wordpress.org/themes/disco/`, the theme name would be `disco`. Installing a theme automatically logs the user in as an admin |
| `url` | `/wp-admin/` | Load the specified initial page displaying WordPress |
| `mode` | `seamless` | Displays WordPress on a full-page or wraps it in a browser UI |
| `lazy` | | Defer loading the Playground assets until someone clicks on the "Run" button |
| `login` | `1` | Logs the user in as an admin |
| `gutenberg-pr` | | Loads the specified Gutenberg Pull Request |
| `storage` | | Selects the storage for Playground: `none` gets erased on page refresh, `browser` is stored in the browser, and `device` is stored in the selected directory on a device. The last two protect the user from accidentally losing their work upon page refresh. |
| Option | Default Value | Description |
| ---------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `php` | `8.0` | Loads the specified PHP version. Supported values: `5.6`, `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `latest` |
| `php-extension-bundle` | | Loads a bundle of PHP extensions. Supported bundles: `kitchen-sink` (for gd, mbstring, libxml, xml, dom, simplexml, xmlreader, xmlwriter) |
| `plugin` | | Installs the specified plugin. Use the plugin name from the plugins directory URL, e.g. for a URL like `https://wordpress.org/plugins/wp-lazy-loading/`, the plugin name would be `wp-lazy-loading`. You can pre-install multiple plugins by saying `plugin=coblocks&plugin=wp-lazy-loading&…`. Installing a plugin automatically logs the user in as an admin |
| `theme` | | Installs the specified theme. Use the theme name from the themes directory URL, e.g. for a URL like `https://wordpress.org/themes/disco/`, the theme name would be `disco`. Installing a theme automatically logs the user in as an admin |
| `url` | `/wp-admin/` | Load the specified initial page displaying WordPress |
| `mode` | `seamless` | Displays WordPress on a full-page or wraps it in a browser UI |
| `lazy` | | Defer loading the Playground assets until someone clicks on the "Run" button |
| `login` | `1` | Logs the user in as an admin |
| `gutenberg-pr` | | Loads the specified Gutenberg Pull Request |
| `storage` | | Selects the storage for Playground: `none` gets erased on page refresh, `browser` is stored in the browser, and `device` is stored in the selected directory on a device. The last two protect the user from accidentally losing their work upon page refresh. |

For example, the following code embeds a Playground with a preinstalled Gutenberg plugin, and opens the post editor:

Expand Down
1 change: 1 addition & 0 deletions packages/docs/site/docs/09-blueprints-api/01-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Blueprints are JSON files for setting up your very own WordPress Playground inst
"php": "8.0",
"wp": "latest"
},
"phpExtensionBundles": ["kitchen-sink"],
"steps": [
{
"step": "login",
Expand Down
7 changes: 7 additions & 0 deletions packages/docs/site/docs/09-blueprints-api/03-data-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import BlueprintExample from '@site/src/components/Blueprints/BlueprintExample.m
"php": "7.4",
"wp": "5.9"
},
"phpExtensionBundles": ["kitchen-sink"],
"steps": [
{
"step": "login",
Expand Down Expand Up @@ -48,3 +49,9 @@ The `preferredVersions` property, unsurprisingly, declares the preferred of PHP

- `php` (string): The preferred PHP version to use. Defaults to 'latest'. Only accepts major versions like "7.4" or "8.0". Minor versions like "7.4.1" are not supported.
- `wp` (string): The preferred WordPress version to use. Defaults to 'latest'. Only accepts major versions like "5.9" or "6.0". Minor versions like "5.9.1" are not supported.

## PHP extensions

The `phpExtensionBundles` property is an array of PHP extension bundles to load. The following bundles are supported:

- `kitchen-sink`: Installs `gd`, `mbstring`, `libxml`, `xml`, `dom`, `simplexml`, `xmlreader`, `xmlwriter`
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const client = await startPlaygroundWeb({
wp: '6.3',
php: '8.0',
},
// Optional: downloads additional PHP extensions like DOMDocument, mbstring, etc.
extensionBundles: ['kitchen-sink'],
steps: [
{ step: 'login' },
{
Expand Down
18 changes: 12 additions & 6 deletions packages/php-wasm/compile/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const argParser = yargs(process.argv.slice(2))
.options({
PLATFORM: {
type: 'string',
choices: ['web', 'node'],
default: 'web',
choices: ['web-light', 'web-kitchen-sink', 'node'],
default: 'web-light',
description: 'The platform to build for',
},
DEBUG: {
Expand Down Expand Up @@ -44,7 +44,6 @@ const argParser = yargs(process.argv.slice(2))
WITH_CLI_SAPI: {
type: 'string',
choices: ['yes', 'no'],
default: 'yes',
description: 'Build with CLI SAPI',
},
WITH_OPENSSL: {
Expand Down Expand Up @@ -97,7 +96,13 @@ const platformDefaults = {
WITH_LIBZIP: 'yes',
WITH_SQLITE: 'yes',
},
web: {},
['web-light']: {},
['web-kitchen-sink']: {
WITH_LIBXML: 'yes',
WITH_LIBPNG: 'yes',
WITH_MBSTRING: 'yes',
WITH_WS_NETWORKING_PROXY: 'yes',
},
node: {
WITH_LIBXML: 'yes',
WITH_LIBPNG: 'yes',
Expand All @@ -109,7 +114,8 @@ const platformDefaults = {
WITH_WS_NETWORKING_PROXY: 'yes',
},
};
const platform = args.PLATFORM === 'node' ? 'node' : 'web';
const platform = args.PLATFORM;

/* eslint-disable prettier/prettier */
const getArg = (name) => {
let value =
Expand Down Expand Up @@ -170,7 +176,7 @@ await asyncSpawn(
'--build-arg',
getArg('WITH_WS_NETWORKING_PROXY'),
'--build-arg',
`EMSCRIPTEN_ENVIRONMENT=${platform}`,
`EMSCRIPTEN_ENVIRONMENT=${platform === 'node' ? 'node' : 'web'}`,
],
{ cwd: sourceDir, stdio: 'inherit' }
);
Expand Down
8 changes: 8 additions & 0 deletions packages/php-wasm/universal/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ export {
SupportedPHPVersionsList,
} from './supported-php-versions';
export type { SupportedPHPVersion } from './supported-php-versions';
export {
SupportedPHPExtensionsList,
SupportedPHPExtensionBundles,
} from './supported-php-extensions';
export type {
SupportedPHPExtension,
SupportedPHPExtensionBundle,
} from './supported-php-extensions';
export { BasePHP, __private__dont__use } from './base-php';
export { loadPHPRuntime } from './load-php-runtime';
export type {
Expand Down
10 changes: 10 additions & 0 deletions packages/php-wasm/universal/src/lib/supported-php-extensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const supportedPHPExtensions = ['mbstring', 'xml-bundle', 'gd'] as const;
export type SupportedPHPExtension = (typeof supportedPHPExtensions)[number];
export const SupportedPHPExtensionsList =
supportedPHPExtensions as any as SupportedPHPExtension[];

export const SupportedPHPExtensionBundles = {
'kitchen-sink': supportedPHPExtensions,
} as const;
export type SupportedPHPExtensionBundle =
keyof typeof SupportedPHPExtensionBundles;
Loading

0 comments on commit 84f1838

Please sign in to comment.