Skip to content

Commit fad3ccf

Browse files
authored
Blueprints: Rename importFile to importWxr, switch to humanmade/WordPress importer (#1192)
The importFile step works by interacting with HTML form like a user would. Problem is, the WXR importer requires some interactions with the forms which we fake by adjusting the POST data before submitting the form. This approach causes a number of issues listed below. More context: #1183. ## Implementation Refactors the importFile Blueprint step to: * Be named importWxz. The old name continues to work, though. * Use the humanmade/WordPress-Importer for importing content – it is more reliable than the official wordpress-importer and has a convenient PHP API. * Drop WXZ support – it's a maintenance burden and doesn't add clear value. * Remove dependency on DOMParser – this step should now work in `wp-now` ## Testing instructions 1. Go to http://localhost:5400/website-server/?import-wxr=https://raw.githubusercontent.com/helgatheviking/Simple-User-Listing/3e38ea3eb3a057424fbae4305cba2fd9f73d896b/demo-content/demo-content.xml&php=8.0&wp=6.5&storage=none&php-extension-bundle=kitchen-sink 2. Confirm the "Simple User Listing Block" page was created 3. Confirm in wp-admin a bunch of user accounts were created 4. Confirm in wp-admin the WordPress Importer plugin was installed Closes #1183 Closes #379 Closes #1158 Closes #1161 cc @dmsnell
1 parent 8d12b9b commit fad3ccf

File tree

805 files changed

+156368
-158473
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

805 files changed

+156368
-158473
lines changed

packages/docs/site/docs/02-start-using/01-index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,13 @@ You can specify major versions like `wp=6.2` or `php=8.1` and expect the most re
101101

102102
:::
103103

104-
## Import a WXZ or a WXR file
104+
## Import a WXR file
105105

106-
You can import a WordPress export file by uploading a WXZ, or WXR file in [/wp-admin/](https://playground.wordpress.net/wp-admin/).
106+
You can import a WordPress export file by uploading a WXR file in [/wp-admin/](https://playground.wordpress.net/wp-admin/).
107107

108108
You can also use [JSON Blueprints](../09-blueprints-api/01-index.md). See [getting started with Blueprints](../09-blueprints-api/01-index.md) to learn more.
109109

110-
This is different from the import feature described above. The import feature exports the entire site, including the database. This import feature imports a WXR or WXZ file into an existing site.
110+
This is different from the import feature described above. The import feature exports the entire site, including the database. This import feature imports a WXR file into an existing site.
111111

112112
## Build apps with WordPress Playground
113113

packages/docs/site/docs/03-build-an-app/01-index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ You can still showcase it on Playground by using [JSON Blueprints](../09-bluepri
7171
}
7272
},
7373
{
74-
"step": "importFile",
74+
"step": "importWxr",
7575
"pluginZipFile": {
7676
"resource": "url",
77-
"url": "https://your-site.com/starter-content.wxz"
77+
"url": "https://your-site.com/starter-content.wxr"
7878
}
7979
}
8080
]

packages/docs/site/docs/08-query-api/01-index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ You can go ahead and try it out. The Playground will automatically install the t
3737
| `multisite` | `no` | Enables the WordPress multisite mode. |
3838
| `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. |
3939
| `import-site` | | Imports site files and database from a zip file specified by URL. |
40-
| `import-content` | | Imports site content from a WXR or WXZ file specified by URL. It uses the WordPress Importer, so the default admin user must be logged in. |
40+
| `import-wxr` | | Imports site content from a WXR file specified by URL. It uses the WordPress Importer, so the default admin user must be logged in. |
4141

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

packages/docs/site/docs/09-blueprints-api/08-examples.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ blueprint={{
9999
}
100100
},
101101
{
102-
"step": "importFile",
102+
"step": "importWxr",
103103
"file": {
104104
"resource": "url",
105-
"url": "https://your-site.com/starter-content.wxz"
105+
"url": "https://your-site.com/starter-content.wxr"
106106
}
107107
},
108108
{

packages/playground/blueprints/public/blueprint-schema.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,33 @@
519519
},
520520
"required": ["step"]
521521
},
522+
{
523+
"type": "object",
524+
"additionalProperties": false,
525+
"properties": {
526+
"progress": {
527+
"type": "object",
528+
"properties": {
529+
"weight": {
530+
"type": "number"
531+
},
532+
"caption": {
533+
"type": "string"
534+
}
535+
},
536+
"additionalProperties": false
537+
},
538+
"step": {
539+
"type": "string",
540+
"const": "importWxr"
541+
},
542+
"file": {
543+
"$ref": "#/definitions/FileReference",
544+
"description": "The file to import"
545+
}
546+
},
547+
"required": ["file", "step"]
548+
},
522549
{
523550
"type": "object",
524551
"additionalProperties": false,

packages/playground/blueprints/src/lib/compile.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const { wpCLI, ...otherStepHandlers } = allStepHandlers;
2020
const keyedStepHandlers = {
2121
...otherStepHandlers,
2222
'wp-cli': wpCLI,
23+
importFile: otherStepHandlers.importWxr,
2324
};
2425

2526
import Ajv from 'ajv';
@@ -86,6 +87,16 @@ export function compileBlueprint(
8687
...blueprint,
8788
steps: (blueprint.steps || []).filter(isStepDefinition),
8889
};
90+
// Convert legacy importFile steps to importWxr
91+
for (const step of blueprint.steps!) {
92+
if (typeof step === 'object' && (step as any).step === 'importFile') {
93+
(step as any).step = 'importWxr';
94+
console.warn(
95+
`The "importFile" step is deprecated. Use "importWxr" instead.`
96+
);
97+
}
98+
}
99+
89100
// Experimental declarative syntax {{{
90101
if (blueprint.constants) {
91102
blueprint.steps!.unshift({
@@ -133,6 +144,9 @@ export function compileBlueprint(
133144
: blueprint.login),
134145
});
135146
}
147+
if (!blueprint.phpExtensionBundles) {
148+
blueprint.phpExtensionBundles = [];
149+
}
136150

137151
if (!blueprint.phpExtensionBundles) {
138152
blueprint.phpExtensionBundles = [];
@@ -145,7 +159,7 @@ export function compileBlueprint(
145159

146160
/**
147161
* Download WP-CLI. {{{
148-
* Hardcoding this in the compilt() function is a temporary solution
162+
* Hardcoding this in the compile() function is a temporary solution
149163
* to provide the wpCLI step with the wp-cli.phar file it needs. Eventually,
150164
* each Blueprint step may be able to specify any pre-requisite resources.
151165
* Also, wp-cli should only be downloaded if it's not already present.
@@ -154,10 +168,13 @@ export function compileBlueprint(
154168
(step) => typeof step === 'object' && step?.step === 'wp-cli'
155169
);
156170
if (wpCliStepIndex !== undefined && wpCliStepIndex > -1) {
157-
if (!blueprint.phpExtensionBundles.includes('kitchen-sink')) {
158-
blueprint.phpExtensionBundles.push('kitchen-sink');
171+
if (blueprint.phpExtensionBundles.includes('light')) {
172+
blueprint.phpExtensionBundles =
173+
blueprint.phpExtensionBundles.filter(
174+
(bundle) => bundle !== 'light'
175+
);
159176
console.warn(
160-
`The WP-CLI step used in your Blueprint requires the iconv and mbstring PHP extensions. ` +
177+
`The wpCli step used in your Blueprint requires the iconv and mbstring PHP extensions. ` +
161178
`However, you did not specify the kitchen-sink extension bundle. Playground will override your ` +
162179
`choice and load the kitchen-sink PHP extensions bundle to prevent the WP-CLI step from failing. `
163180
);
@@ -183,6 +200,35 @@ export function compileBlueprint(
183200
}
184201
// }}}
185202

203+
/**
204+
* Download the WordPress-importer plugin. {{{
205+
* Hardcoding this in the compile() function is a temporary solution
206+
*/
207+
const importWxrStepIndex = blueprint.steps?.findIndex(
208+
(step) => typeof step === 'object' && step?.step === 'importWxr'
209+
);
210+
if (importWxrStepIndex !== undefined && importWxrStepIndex > -1) {
211+
if (blueprint.phpExtensionBundles.includes('light')) {
212+
blueprint.phpExtensionBundles =
213+
blueprint.phpExtensionBundles.filter(
214+
(bundle) => bundle !== 'light'
215+
);
216+
console.warn(
217+
`The importWxr step used in your Blueprint requires the iconv and mbstring PHP extensions. ` +
218+
`However, you did not specify the kitchen-sink extension bundle. Playground will override your ` +
219+
`choice and load the kitchen-sink PHP extensions bundle to prevent the WP-CLI step from failing. `
220+
);
221+
}
222+
blueprint.steps?.splice(importWxrStepIndex, 0, {
223+
step: 'installPlugin',
224+
pluginZipFile: {
225+
resource: 'url',
226+
url: 'https://playground.wordpress.net/wordpress-importer.zip',
227+
caption: 'Downloading the WordPress Importer plugin',
228+
},
229+
});
230+
}
231+
186232
const { valid, errors } = validateBlueprint(blueprint);
187233
if (!valid) {
188234
const e = new Error(

packages/playground/blueprints/src/lib/steps/export-wxz.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

packages/playground/blueprints/src/lib/steps/handlers.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ export { mkdir } from './mkdir';
1313
export { rmdir } from './rmdir';
1414
export { writeFile } from './write-file';
1515
export { defineSiteUrl } from './define-site-url';
16-
export { importFile } from './import-file';
16+
export { importWxr as importWxr } from './import-wxr';
1717
export { importWordPressFiles } from './import-wordpress-files';
1818
export { exportWXR } from './export-wxr';
19-
export { exportWXZ } from './export-wxz';
2019
export { unzip } from './unzip';
2120
export { installPlugin } from './install-plugin';
2221
export { installTheme } from './install-theme';

packages/playground/blueprints/src/lib/steps/import-file.ts

Lines changed: 0 additions & 93 deletions
This file was deleted.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { StepHandler } from '.';
2+
import { writeFile } from './write-file';
3+
import { phpVar } from '@php-wasm/util';
4+
5+
/**
6+
* @inheritDoc importWxr
7+
* @example
8+
*
9+
* <code>
10+
* {
11+
* "step": "importWxr",
12+
* "file": {
13+
* "resource": "url",
14+
* "url": "https://your-site.com/starter-content.wxr"
15+
* }
16+
* }
17+
* </code>
18+
*/
19+
export interface ImportWxrStep<ResourceType> {
20+
step: 'importWxr';
21+
/** The file to import */
22+
file: ResourceType;
23+
}
24+
25+
/**
26+
* Imports a WXR file into WordPress.
27+
*
28+
* @param playground Playground client.
29+
* @param file The file to import.
30+
*/
31+
export const importWxr: StepHandler<ImportWxrStep<File>> = async (
32+
playground,
33+
{ file },
34+
progress?
35+
) => {
36+
progress?.tracker?.setCaption('Importing content');
37+
await writeFile(playground, {
38+
path: '/tmp/import.wxr',
39+
data: file,
40+
});
41+
const docroot = await playground.documentRoot;
42+
await playground.run({
43+
code: `<?php
44+
require ${phpVar(docroot)} . '/wp-load.php';
45+
$admin_id = get_users(array('role' => 'Administrator') )[0];
46+
$importer = new WXR_Importer( array(
47+
'fetch_attachments' => true,
48+
'default_author' => $admin_id
49+
) );
50+
$logger = new WP_Importer_Logger_CLI();
51+
$importer->set_logger( $logger );
52+
$result = $importer->import( '/tmp/import.wxr' );
53+
`,
54+
});
55+
};

0 commit comments

Comments
 (0)