Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove DOMParser from Blueprints: installPlugin and installTheme #427

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
815acec
Rough draft for installPlugin
eliot-akira May 24, 2023
61e33f3
Format
eliot-akira May 24, 2023
7eb0e26
Merge remote-tracking branch 'upstream/trunk'
eliot-akira May 24, 2023
304e256
Test zip package name different from extracted plugin folder name
eliot-akira May 24, 2023
9c34cf4
Remove test plugin after install
eliot-akira May 24, 2023
89a627d
Use unzip step and find extracted plugin folder name
eliot-akira May 24, 2023
d53a55a
Format
eliot-akira May 24, 2023
98cde65
playground.documentRoot getter returns a promise
eliot-akira May 24, 2023
bfaef98
Remove temporary zip file after extraction
eliot-akira May 24, 2023
3f8eb82
Format
eliot-akira May 24, 2023
f2ed29b
activatePlugin step: await playground.documentRoot because it can ret…
eliot-akira May 24, 2023
7840907
BasePHP: Use FS.rename for method mv
eliot-akira May 24, 2023
daf74b3
Improve error message when extracted plugin folder not found
eliot-akira May 24, 2023
82ad36e
Make server-side test pass: Create plugins folder; Patch VFSResource …
eliot-akira May 24, 2023
3520de3
Format
eliot-akira May 24, 2023
579c568
Add comment about Gutenberg patch becoming unnecessary as the issue h…
eliot-akira May 24, 2023
534d10f
Rewrite installTheme step
eliot-akira May 25, 2023
0615596
Format
eliot-akira May 25, 2023
11bee55
Find plugin entry file to pass to activatePlugin step
eliot-akira May 25, 2023
6080b0d
activateTheme step: await playground.documentRoot because it can retu…
eliot-akira May 25, 2023
fa4f559
VFSResource: Clean up workaround
eliot-akira May 25, 2023
3fce74e
Tests: Clarify comment about zip file names being different from extr…
eliot-akira May 25, 2023
2b8d31b
Remove asDOM helper function, which used DOMParser available only on …
eliot-akira May 25, 2023
e5ae9b5
Remove unnecessary timeout value for tests
eliot-akira May 26, 2023
3dbd17a
Create findPluginEntryFile function for reusable logic
eliot-akira May 26, 2023
ca7b8c1
Remove comment about using plugin/theme upload form, since it's no lo…
eliot-akira May 26, 2023
9eed478
Merge branch 'trunk' into remove-dom-parser-from-blueprints
eliot-akira May 26, 2023
56cb9d3
Extract common logic between install plugin/theme into installAsset f…
eliot-akira May 27, 2023
28f7163
Format
eliot-akira May 27, 2023
dc05730
Install asset: Clean up temporary folder before throwing an error
eliot-akira May 27, 2023
81bb68f
Clarify comment about JSDOM's `File` class missing `arrayBuffer` meth…
eliot-akira May 30, 2023
a368526
installAsset: Make generic by replacing assetType with targetPath; Us…
eliot-akira May 30, 2023
7d4f233
Format
eliot-akira May 30, 2023
30d5c9a
activatePlugin step: Accept path to plugin directory and find plugin …
eliot-akira May 30, 2023
9ed3d75
installAsset: Clean up temporary folder and zip file on success or an…
eliot-akira May 30, 2023
3b67796
Polyfill the File class in JSDOM which lacks arrayBuffer() method
eliot-akira May 31, 2023
c121866
Format
eliot-akira May 31, 2023
661eda9
activatePlugin: Simplify logic to find plugin entry file
eliot-akira May 31, 2023
3cbea6a
activatePlugin: Simplify logic to find plugin entry file
eliot-akira May 31, 2023
4487c3a
activatePlugin: Clarify accepted value for pluginPath option (absolut…
eliot-akira May 31, 2023
6b0f60f
Merge branch 'trunk' into remove-dom-parser-from-blueprints
eliot-akira May 31, 2023
1671b88
Clean up after merge from trunk
eliot-akira May 31, 2023
3526f57
Format
eliot-akira May 31, 2023
6f81a34
activatePlugin: Use error code for entry file not found; Rethrow any …
eliot-akira May 31, 2023
977230f
Format
eliot-akira May 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,52 @@
import { NodePHP } from '@php-wasm/node';
import { compileBlueprint, runBlueprintSteps } from '../compile';

const phpVersion = '8.0';
describe('Blueprint step installPlugin', () => {
let php: NodePHP;
beforeEach(async () => {
php = await NodePHP.load(phpVersion, {
requestHandler: {
documentRoot: '/',
isStaticFilePath: (path) => !path.endsWith('.php'),
},
});
});

it('should install a plugin', async () => {
// Create test plugin

php.mkdir('/test-plugin');
php.writeFile(
'/test-plugin/index.php',
`/**\n * Plugin Name: Test Plugin`
);

await php.run({
code: `<?php $zip = new ZipArchive(); $zip->open("test-plugin.zip", ZIPARCHIVE::CREATE); $zip->addFile("/test-plugin/index.php"); $zip->close();`,
});

php.rmdir('/test-plugin');

expect(php.fileExists('/test-plugin.zip')).toBe(true);

await runBlueprintSteps(
compileBlueprint({
steps: [
{
step: 'installPlugin',
pluginZipFile: {
resource: 'vfs',
path: '/test-plugin.zip',
},
},
],
}),
php
);

expect(
php.fileExists(`${php.documentRoot}/wp-content/test-plugin`)
).toBe(true);
}, 30000);
});
58 changes: 28 additions & 30 deletions packages/playground/blueprints/src/lib/steps/install-plugin.ts
@@ -1,6 +1,8 @@
import { UniversalPHP } from '@php-wasm/universal';
import { StepHandler } from '.';
import { asDOM, zipNameToHumanName } from './common';
import { zipNameToHumanName } from './common';
import { writeFile } from './client-methods';
import { activatePlugin } from './activate-plugin';

/**
* @inheritDoc installPlugin
Expand Down Expand Up @@ -64,39 +66,35 @@ export const installPlugin: StepHandler<InstallPluginStep<File>> = async (
try {
const activate = 'activate' in options ? options.activate : true;

// Upload it to WordPress
const pluginForm = await playground.request({
url: '/wp-admin/plugin-install.php?tab=upload',
const pluginsPath = `${playground.documentRoot}/wp-content/plugins`;
const pluginZipPath = `${pluginsPath}/${pluginZipFile.name}`;

await writeFile(playground, {
path: pluginZipPath,
data: pluginZipFile,
});
const pluginFormPage = asDOM(pluginForm);
const pluginFormData = new FormData(
pluginFormPage.querySelector('.wp-upload-form')! as HTMLFormElement
) as any;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { pluginzip, ...postData } = Object.fromEntries(
pluginFormData.entries()
);

const pluginInstalledResponse = await playground.request({
url: '/wp-admin/update.php?action=upload-plugin',
method: 'POST',
formData: postData,
files: { pluginzip: pluginZipFile },
await playground.run({
eliot-akira marked this conversation as resolved.
Show resolved Hide resolved
code: `<?php
$zip = new ZipArchive;
$res = $zip->open('${pluginZipPath}');
if ($res) {
$zip->extractTo('${pluginsPath}');
$zip->close();
}
`,
});

// Activate if needed
const pluginPath = pluginZipPath.replace('.zip', '');

if (activate) {
const pluginInstalledPage = asDOM(pluginInstalledResponse);
const activateButtonHref = pluginInstalledPage
.querySelector('#wpbody-content .button.button-primary')!
.attributes.getNamedItem('href')!.value;
const activatePluginUrl = new URL(
activateButtonHref,
await playground.pathToInternalUrl('/wp-admin/')
).toString();
await playground.request({
url: activatePluginUrl,
});
await activatePlugin(
eliot-akira marked this conversation as resolved.
Show resolved Hide resolved
playground,
{
pluginPath,
},
progress
);
}

/**
Expand Down Expand Up @@ -155,7 +153,7 @@ export const installPlugin: StepHandler<InstallPluginStep<File>> = async (
}
} catch (error) {
console.error(
`Proceeding without the ${pluginZipFile.name} theme. Could not install it in wp-admin. ` +
`Proceeding without the ${pluginZipFile.name} plugin. Could not install it in wp-admin. ` +
`The original error was: ${error}`
);
console.error(error);
Expand Down