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

Add import and export logic #110

Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d9543b9
Add rough import / export logic and debug input fields
artemiomorales Jan 12, 2023
53f2ea7
Move export logic to PHP
artemiomorales Jan 17, 2023
c4bdd8f
Migrate import logic to PHP
artemiomorales Jan 20, 2023
4e7813e
Add support for exporting/importing database; remove export of 'wp-in…
artemiomorales Jan 23, 2023
502271d
Remove extra spaces around PHP declarations and extraneous closing tags
artemiomorales Jan 23, 2023
3064736
Move DOCROOT const to config file
artemiomorales Jan 23, 2023
1dcdd0e
Add error handling to custom PHP run() code; rename variables
artemiomorales Jan 23, 2023
03a0a96
Install WordPress Importer by default in WP bundle
artemiomorales Jan 31, 2023
00457a5
Rebuild WordPress versions
artemiomorales Jan 31, 2023
cd720c1
Fix full site editing
artemiomorales Feb 8, 2023
9c997bb
Add UI for migration logic
artemiomorales Feb 10, 2023
fe837c0
Reset build/ folder to HEAD
artemiomorales Feb 11, 2023
e48b217
Rebuild WP bundles to include WordPress Importer
artemiomorales Feb 11, 2023
b505cf5
Add descriptive text for modal
artemiomorales Feb 11, 2023
e9c1400
Add WordPress version to export filename
artemiomorales Feb 11, 2023
6e62b40
Fix bug when using PHP 7.0-7.3
artemiomorales Feb 14, 2023
f92cb88
Move generateZipFile() code to separate PHP file; begin adding tests
artemiomorales Feb 24, 2023
6f9a3b6
Begin moving import code to separate file; add tests
artemiomorales Feb 24, 2023
5333bbd
Move import overwrite logic to separate file; add tests; fix a bug
artemiomorales Feb 24, 2023
0badcd2
Add known limitations regarding media, options/users, and plugins to …
artemiomorales Feb 24, 2023
429f07b
Replace rmSync calls with rmdirSync to remove Typscript warnings
artemiomorales Feb 24, 2023
a969224
Fix code formatting and spacing issues
artemiomorales Feb 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,706 changes: 2,686 additions & 20 deletions build/wp-5.9.data
100755 → 100644

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions build/wp-5.9.js
100755 → 100644

Large diffs are not rendered by default.

2,705 changes: 2,685 additions & 20 deletions build/wp-6.0.data
100755 → 100644

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions build/wp-6.0.js
100755 → 100644

Large diffs are not rendered by default.

2,703 changes: 2,684 additions & 19 deletions build/wp-6.1.data
100755 → 100644

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions build/wp-6.1.js
100755 → 100644

Large diffs are not rendered by default.

3,011 changes: 2,849 additions & 162 deletions build/wp-nightly.data
100755 → 100644

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions build/wp-nightly.js
100755 → 100644

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ module.exports = {
// globalTeardown: undefined,

// A set of global variables that need to be available in all test environments
// globals: {},
globals: {
PHP_JS_HASH: '',
},

// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"eslint-plugin-react": "^7.31.1",
"eslint-plugin-react-hooks": "^4.6.0",
"estree-walker": "^3.0.1",
"file-saver": "^2.0.5",
"glob": "^8.0.3",
"gulp": "^4.0.2",
"gulp-rename": "^2.0.0",
Expand Down
8 changes: 8 additions & 0 deletions src/php-wasm-browser/worker-thread/window-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,14 @@ export class SpawnedWorkerThread {
return await this.#rpc('readFile', { path });
}

/**
* @param path
* @see {PHP.readFile}
*/
async readFileAsBuffer(path: string): Promise<string> {
return await this.#rpc('readFileAsBuffer', { path });
}

/**
* @param path
* @param contents
Expand Down
2 changes: 2 additions & 0 deletions src/php-wasm-browser/worker-thread/worker-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ export async function initializeWorkerThread(
return scope;
} else if (message.type === 'readFile') {
return phpBrowser.server.php.readFileAsText(message.path);
} else if (message.type === 'readFileAsBuffer') {
return phpBrowser.server.php.readFileAsBuffer(message.path);
} else if (message.type === 'listFiles') {
return phpBrowser.server.php.listFiles(message.path);
} else if (message.type === 'unlink') {
Expand Down
312 changes: 312 additions & 0 deletions src/wordpress-playground/__tests__/migration-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
import * as phpLoaderModule from '../../../build/php-7.4.node.js';
import { startPHP } from '../../php-wasm/php-node';
import { existsSync, rmSync, readFileSync } from 'fs';
artemiomorales marked this conversation as resolved.
Show resolved Hide resolved

const { TextDecoder } = require('util');

// Code to test
const migration = readFileSync(__dirname + '/../migration.php');

// Mock files
const testDirPath = __dirname + '/__test39024';
const fileSystemPath = testDirPath + '/filesystem';
const wpImporterOutputPath = fileSystemPath + '/databaseExport.xml';
const wpImporterOutputValue = 'Mock WordPress Importer migration file';

const exportName = `wordpress-playground-export.zip`;
const exportPath = `${testDirPath}/${exportName}`;

// ------------------------
// Mock WordPress Directory
// ------------------------

// Root
const wpDir = fileSystemPath + '/wordpress';
const wpDirFilePath = wpDir + '/test-wp-root.php';
const wpDirFileValue = 'Mock WP root file';

// WP Admin
const wpAdminDir = wpDir + '/wp-admin';
const wpAdminFilePath = wpAdminDir + '/test-admin.php';
const wpAdminFileValue = 'Mock WP admin file';

// WP Content
const wpContentDir = wpDir + '/wp-content';
const wpContentFilePath = wpContentDir + '/test-content.php';
const wpContentFileValue = 'Mock WP content file';

// WP Content - SQL DB
const wpSqlDbDir = wpContentDir + '/database';
const wpSqlDbFilePath = wpSqlDbDir + '/test-database.php';
const wpSqlDbFileValue = 'Mock SQL content';

// WP Includes
const wpIncludesDir = wpDir + '/wp-includes';
const wpIncludesFilePath = wpIncludesDir + '/test-includes.php';
const wpIncludesFileValue = 'Mock WP includes';

function createMockStructure(phpRuntime) {
phpRuntime.mkdirTree(testDirPath);
phpRuntime.mkdirTree(fileSystemPath);
phpRuntime.mkdirTree(wpDir);

phpRuntime.writeFile(wpImporterOutputPath, wpImporterOutputValue);

// WP Root
phpRuntime.writeFile(wpDirFilePath, wpDirFileValue);

// WP Admin
phpRuntime.mkdirTree(wpAdminDir);
phpRuntime.writeFile(wpAdminFilePath, wpAdminFileValue);

// WP Content
phpRuntime.mkdirTree(wpContentDir);
phpRuntime.writeFile(wpContentFilePath, wpContentFileValue);

// WP Content - SQL DB
phpRuntime.mkdirTree(wpSqlDbDir);
phpRuntime.writeFile(wpSqlDbFilePath, wpSqlDbFileValue);

// WP Includes
phpRuntime.mkdirTree(wpIncludesDir);
phpRuntime.writeFile(wpIncludesFilePath, wpIncludesFileValue);

const exportWriteRequest = phpRuntime.run({
code:
migration +
` generateZipFile("${exportPath}", "${wpImporterOutputPath}", "${wpDir}");`,
});

if (exportWriteRequest.exitCode !== 0) {
throw exportWriteRequest.errors;
}
}

describe('generateZipFile()', () => {
let php;

beforeEach(async () => {
php = await startPHP(phpLoaderModule, 'NODE');
if (existsSync(testDirPath)) {
rmSync(testDirPath, { recursive: true });
}
createMockStructure(php);
});

afterAll(() => {
if (existsSync(testDirPath)) {
rmSync(testDirPath, { recursive: true });
}
});

it('should creata a ZIP file of specified WP Importer output file and WordPress files', () => {
const runTest = php.run({
code: `
<?php
$zip = new ZipArchive;
$res = $zip->open('${exportPath}');
if ($res === TRUE) {
if(
$zip->getFromName('${wpImporterOutputPath}') &&
$zip->getFromName('${wpDirFilePath}') &&
$zip->getFromName('${wpContentFilePath}')
) {
echo 'success';
} else {
echo 'failure';
}
}
`,
});

const runTestOutput = new TextDecoder().decode(runTest.body).trim();

expect(runTestOutput).toEqual('success');
});

it('should omit wp-content/database directory', () => {
const runTest = php.run({
code: `
<?php
$zip = new ZipArchive;
$res = $zip->open('${exportPath}');
if ($res === TRUE) {
if(
!$zip->getFromName('${wpSqlDbFilePath}')
) {
echo 'success';
} else {
echo 'failure';
}
}
`,
});

const runTestOutput = new TextDecoder().decode(runTest.body).trim();

expect(runTestOutput).toEqual('success');
});

it('should omit wp-includes directory', () => {
const runTest = php.run({
code: `
<?php
$zip = new ZipArchive;
$res = $zip->open('${exportPath}');
if ($res === TRUE) {
if(
!$zip->getFromName('${wpIncludesFilePath}')
) {
echo 'success';
} else {
echo 'failure';
}
}
`,
});

const runTestOutput = new TextDecoder().decode(runTest.body).trim();

expect(runTestOutput).toEqual('success');
});
});

describe('readFileFromZipArchive()', () => {
let php;

beforeEach(async () => {
php = await startPHP(phpLoaderModule, 'NODE');
if (existsSync(testDirPath)) {
rmSync(testDirPath, { recursive: true });
}
createMockStructure(php);
});

afterAll(() => {
if (existsSync(testDirPath)) {
rmSync(testDirPath, { recursive: true });
}
});

describe("given a path to a generateZipFile() output, it should return a specified file's contents", () => {
it('filesystem root file', () => {
const readFileRequest = php.run({
code:
migration +
` readFileFromZipArchive('${exportPath}', '${wpImporterOutputPath}');`,
});

if (readFileRequest.exitCode !== 0) {
throw readFileRequest.errors;
}

const readFileOutput = new TextDecoder()
.decode(readFileRequest.body)
.trim();

expect(readFileOutput).toEqual(wpImporterOutputValue);
});
it('wp root file', () => {
const readFileRequest = php.run({
code:
migration +
` readFileFromZipArchive('${exportPath}', '${wpDirFilePath}');`,
});

if (readFileRequest.exitCode !== 0) {
throw readFileRequest.errors;
}

const readFileOutput = new TextDecoder()
.decode(readFileRequest.body)
.trim();

expect(readFileOutput).toEqual(wpDirFileValue);
});
it('wp admin file', () => {
const readFileRequest = php.run({
code:
migration +
` readFileFromZipArchive('${exportPath}', '${wpAdminFilePath}');`,
});

if (readFileRequest.exitCode !== 0) {
throw readFileRequest.errors;
}

const readFileOutput = new TextDecoder()
.decode(readFileRequest.body)
.trim();

expect(readFileOutput).toEqual(wpAdminFileValue);
});
it('wp content file', () => {
const readFileRequest = php.run({
code:
migration +
` readFileFromZipArchive('${exportPath}', '${wpContentFilePath}');`,
});

if (readFileRequest.exitCode !== 0) {
throw readFileRequest.errors;
}

const readFileOutput = new TextDecoder()
.decode(readFileRequest.body)
.trim();

expect(readFileOutput).toEqual(wpContentFileValue);
});
});
});

describe('importZipFile()', () => {
let php;

beforeAll(async () => {
php = await startPHP(phpLoaderModule, 'NODE');
if (existsSync(testDirPath)) {
rmSync(testDirPath, { recursive: true });
}
createMockStructure(php);
});

beforeEach(() => {
if (existsSync(fileSystemPath)) {
rmSync(fileSystemPath, { recursive: true });
}
const writeFileRequest = php.run({
code: migration + ` importZipFile('${exportPath}');`,
});
if (writeFileRequest.exitCode !== 0) {
throw writeFileRequest.errors;
}
});

afterAll(() => {
if (existsSync(testDirPath)) {
rmSync(testDirPath, { recursive: true });
}
});

describe('given a path to a generateZipFile() output, it should write ZIP to filesystem', () => {
it('filesystem root file', () => {
expect(php.readFileAsText(wpImporterOutputPath)).toEqual(
wpImporterOutputValue
);
});
it('wp root file', () => {
expect(php.readFileAsText(wpDirFilePath)).toEqual(wpDirFileValue);
});
it('wp admin file', () => {
expect(php.readFileAsText(wpAdminFilePath)).toEqual(
wpAdminFileValue
);
});
it('wp content file', () => {
expect(php.readFileAsText(wpContentFilePath)).toEqual(
wpContentFileValue
);
});
});
});
3 changes: 3 additions & 0 deletions src/wordpress-playground/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/* eslint-disable no-undef */

// Hardcoded in wp.js:
export const DOCROOT = '/wordpress';

// Provided by esbuild – see build.js in the repo root.
declare let SERVICE_WORKER_URL: any;
export const serviceWorkerUrl = SERVICE_WORKER_URL;
Expand Down
Loading