WordPress / wordpress-playground

Run WordPress in the browser via WebAssembly PHP
https://w.org/playground/
GNU General Public License v2.0
1.65k stars 261 forks source link

[Data Liberation] Add import script #2012

Open zaerl opened 1 day ago

zaerl commented 1 day ago

Add Data Liberation import script. The script lets you import a folder with WXRs inside WordPress.

cd packages/playground/data-liberation/bin/import
bash import-wxr.sh /a-folder/with-the/wxr-files-to-import-inside

The import CLI is also registered as a WP-CLI command in the init action if WP-CLI is included. So it can also be run as wp data-liberation your-wrx-file-you-want-to-import.xml

Motivation for the change, related issues

There's no good entry point to running that import right now; we use an ad-hoc code snippet inside the Data Liberation WordPress plugin. This new CLI command will make testing the import easy.

  1. New CLI script
  2. Fix: missing require_once
  3. Fix: wrong method name
  4. Fix: endless loop

Implementation details

This script consists of three major parts.

A bash script

This script accepts a folder path. You can create one and put all the WXR you want to import inside it. It starts the cli.ts server, mounts the folder specified in /wordpress/wp-content/uploads/import-wxr.

A blueprint

The bluescript enables the Data Liberation plugin. Enumerate all the files with .xml extension inside the mounted folder and import them all using a new function created.

The PHP snippet run in the runPHP step uses the wp_visit_file_tree provided by the plugin:

<?PHP

require_once 'wordpress/wp-load.php';

$upload_dir = wp_upload_dir();

foreach ( wp_visit_file_tree( $upload_dir['basedir'] . '/import-wxr' ) as $event ) {
  foreach ( $event->files as $file ) {
    if ( $file->isFile() && pathinfo( $file->getPathname(), PATHINFO_EXTENSION ) === 'xml' ) {
      data_liberation_import( $file->getPathname() ); // Import the WXR.
    }
  }
};

A new data_liberation_import function

The new simple import function in the plugin runs WP_Stream_Importer and not much more.

Testing Instructions (or ideally a Blueprint)

Example with one of the preexisting XML files:

cd packages/playground/data-liberation/bin/import
mkdir tmp
cp ../../tests/wxr/small-export.xml tmp
bash import-wxr.sh ./tmp

Then check http://127.0.0.1:9400/wp-admin/edit.php. All the WXR posts should be there.

adamziel commented 5 hours ago

This is a great start Francesco, thank you! What would it take to expand this to run the actual PHPunit test in context of WordPress — similarly to what WordPress core tests do? I'm not saying this would actually be useful at this early stage, but I'm just curious maybe it wouldn't be that heavy of a lift? There's some prior art in this repo if you search for PHPUnit

zaerl commented 1 hour ago

This is a great start Francesco, thank you! What would it take to expand this to run the actual PHPunit test in context of WordPress — similarly to what WordPress core tests do? I'm not saying this would actually be useful at this early stage, but I'm just curious maybe it wouldn't be that heavy of a lift? There's some prior art in this repo if you search for PHPUnit

The phpunit.xml tests can potentially be run from within Playground without problems:

$base = '/wordpress/wp-content/plugins/data-liberation/';
require $base . 'vendor/autoload.php';

try {
    $arguments = [
        '--configuration', $base . 'phpunit.xml'
    ];

    (new PHPUnit\TextUI\Application())->run($arguments);
} catch (Throwable $e) {
    echo "Error running PHPUnit: " . $e->getMessage();
    throw $e;
}
{
    "$schema": "../../../blueprints/public/blueprint-schema.json",
    "constants": {
        "WP_DEBUG": true,
        "WP_DEBUG_DISPLAY": true,
        "WP_DEBUG_LOG": true
    },
    "login": true,
    "steps": [
        {
            "step": "activatePlugin",
            "pluginPath": "data-liberation/plugin.php"
        },
        {
            "step": "runPHP",
            "code": "<?php require_once 'wordpress/wp-load.php'; $base = '/wordpress/wp-content/plugins/data-liberation/';\nrequire $base . 'vendor/autoload.php';\ntry {\n$arguments = [\n'--configuration', $base . 'phpunit.xml'\n];\nupdate_option( 'hey', (new PHPUnit\\TextUI\\Application())->run($arguments) );\n} catch (Throwable $e) {\necho \"Error running PHPUnit: \" . $e->getMessage();\nthrow $e;\n}\n;"
        }
    ]
}

But let's see if it is something we want here 🙂.