WP Manifestindependent plugin directory
manifest / multisite / multisite-exporter

Multisite Exporter WP Registry grade D+. High-severity findings · 2 findingsWP RegistryHigh-severity findings · 2 findingsOpen the reportD+

Multisite Exporter is a WordPress plugin that allows you to export content from all subsites in a WordPress multisite installation. The plugin generates WordPress XML (WXR) files by running the WordPress exporter on each subsite in the background using the Action Scheduler library, making it efficient even for large multisite networks.

★ 7stars
64release downloads
1composer installs
1.2.1latest · 1 year ago

Install

Download multisite-exporter.zip From the 1.2.1 release on GitHub, Jun 13, 2025

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/soderlind/multisite-exporter/releases/download/1.2.1/multisite-exporter.zip

On Packagist as soderlind/multisite-exporter:

composer require soderlind/multisite-exporter
Updates itself. It ships its own updater (Plugin Update Checker), so new versions appear under Dashboard → Updates.

Multisite Exporter is a WordPress plugin that allows you to export content from all subsites in a WordPress multisite installation. The plugin generates WordPress XML (WXR) files by running the WordPress exporter on each subsite in the background using the Action Scheduler library, making it efficient even for large multisite networks.

Features | Requirements | Installation | Usage | Action Scheduler | Export File Storage | Translation | Debugging

https://github.com/user-attachments/assets/172e2f69-3ea1-443d-b46f-fcdc82e11db4

Features

  • Export content from all subsites in a WordPress multisite network as XML (WXR) files.
  • Background processing using Action Scheduler to handle large networks efficiently
  • Filter exports by content type, post type, and date range
  • Centralized export file storage for easy access to all exports
  • Select and download multiple export files as a zip archive
  • Powerful WP CLI commands for automated/scripted exports
  • Fully translatable with .pot file included
  • Customizable export directory location via filter

Requirements

  • WordPress Multisite installation
  • PHP 8.2 or higher
  • Action Scheduler library (included with the plugin)

Installation

  • Quick Install

    • Download multisite-exporter.zip
    • Upload via WordPress Network > Plugins > Add New > Upload Plugin
    • Network activate the plugin.
  • Composer Install

     composer require soderlind/multisite-exporter
  • Updates

Usage

Running an Export (UI Method)

  1. Log in to your WordPress Network Admin dashboard
  2. Navigate to MS Exporter → Multisite Exporter
  3. Configure your export settings:
    • Content: Choose to export all content, posts, pages, or media
    • Post Type: Optionally specify a custom post type
    • Date Range: Optionally filter by start and end date
  4. Click "Run Export for All Subsites"
  5. Exports will be processed in the background using Action Scheduler

Running an Export

Accessing Export Files (UI Method)

  1. Navigate to MS Exporter → Exports
  2. View a list of all completed exports from all subsites
  3. Download options:
    • Click the "Download" button next to an individual export
    • Select multiple exports using checkboxes and click "Download Selected" to get a zip file
    • Use "Select All" and "Download Selected" to download all exports at once in a zip file.

Accessing Export Files

WP CLI Method

The plugin includes a WP CLI command to export content directly from the command line.

Basic Export (All Sites, All Content)

wp multisite-exporter export

This will export all content from all sites in your multisite network.

Exporting Specific Content Types

wp multisite-exporter export --content=posts,pages

Valid content types are: all, posts, pages, media

Exporting Specific Sites

wp multisite-exporter export --site_ids=1,2,3

This will export only the sites with the specified IDs.

Filtering by Date Range

wp multisite-exporter export --start_date=2023-01-01 --end_date=2023-12-31

Full Example

wp multisite-exporter export --site_ids=1,2,3 --content=posts,pages --start_date=2023-01-01

The command will display a progress bar during export. When completed:

  • For a single site, the export file will be saved in your current directory
  • For multiple sites, a zip file containing all exports will be created in your current directory

How Action Scheduler Works

The Multisite Exporter plugin uses Action Scheduler, a robust background processing library for WordPress, to handle export operations efficiently across multiple sites. Here's how it works:

Overview

  1. Task Scheduling: When you click "Run Export for All Subsites," the plugin creates an individual task for each subsite in your network.

  2. Background Processing: These tasks are processed in the background using WordPress cron, without blocking user interactions or causing timeout issues.

  3. Failure Handling: If an export fails, Action Scheduler will automatically retry it based on its built-in retry logic, ensuring robust operation even in challenging environments.

Technical Details

  • Storage: Action Scheduler stores tasks in a custom table, ensuring they don't get lost even in case of server interruptions.

  • Queue Processing: Tasks are executed in a controlled manner, with rate limiting to prevent server overload.

  • Admin Interface: The plugin provides a filtered view of Action Scheduler's interface under MS Exporter → Scheduled Actions, where you can monitor the progress of exports.

  • Scaling: The architecture can handle thousands of tasks, making it perfect for large multisite networks with hundreds of subsites.

Action Scheduler Location

The Action Scheduler library is included in this plugin via Composer and can be found at:

/vendor/woocommerce/action-scheduler/

All Action Scheduler related files are loaded automatically when the plugin initializes.

Benefits for Multisite Exports

  • No Timeout Issues: Export processes run in the background, avoiding PHP timeout restrictions.

  • Server-Friendly: Tasks are processed in batches, preventing server resource exhaustion.

  • Monitoring: You can track the progress of exports and identify any issues that may occur.

  • Reliability: The persistent storage mechanism ensures that even if a server restarts, your export tasks will continue where they left off.

Export File Storage

All export files are stored in a centralized location within your WordPress uploads directory:

wp-content/uploads/multisite-exports/

This makes it easy to find and manage exports from all your subsites in one place.

Customizing Export Directory

You can change the default export directory by using the multisite_exporter_directory filter:

/**
 * Change the directory where Multisite Exporter stores exported files
 */
add_filter( 'multisite_exporter_directory', 'my_custom_export_directory' );
function my_custom_export_directory( $default_export_dir ) {
    // Define a custom location for your export files
    return WP_CONTENT_DIR . '/my-custom-exports';
}

Add this code to your theme's functions.php file or a custom plugin.

Translation

The plugin is fully translatable. A POT file is included in the languages directory to help with translations.

To create a translation:

  1. Copy the languages/multisite-exporter.pot file
  2. Rename it to multisite-exporter-{locale}.po (e.g., multisite-exporter-fr_FR.po)
  3. Translate using a tool like Poedit
  4. Save both .po and .mo files to the languages directory

Debugging

Error Logging

Multisite Exporter follows WordPress best practices for error logging. All error messages are conditionally logged based on the WP_DEBUG constant setting:

if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
    error_log( 'Multisite Exporter: [error message]' );
}

This ensures that:

  • In development environments with WP_DEBUG enabled, you'll see detailed logs about the export process
  • In production environments with WP_DEBUG disabled, no error messages will be written to the log files

WXR Validation

Multisite Exporter includes a WXR (WordPress eXtended RSS) validator that checks the integrity of export files:

  • Automatic Validation: Each export file is automatically validated after creation
  • XML Structure Check: Ensures the export file has valid XML structure
  • WXR Schema Validation: Validates against WordPress WXR format requirements
  • Error Detection: Identifies and logs specific issues in malformed export files

The validator helps troubleshoot problematic exports and ensures your export files will be compatible with WordPress import tools.

Common Log Messages

When WP_DEBUG is enabled, you may see the following messages in your WordPress debug log:

  • Filesystem initialization: Messages about WordPress filesystem initialization
  • Export progress: Notifications when exports start and complete for each blog
  • File operations: Information about file cleanup and management
  • Error handling: Details about any issues encountered during the export process
  • WXR validation: Results of export file validation checks

Enabling Debug Mode

To enable debug logging for troubleshooting, add the following to your wp-config.php file:

// Enable WP_DEBUG mode
define( 'WP_DEBUG', true );

// Enable Debug logging to the /wp-content/debug.log file
define( 'WP_DEBUG_LOG', true );

// Disable display of errors and warnings
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

This configuration will log all errors to the debug.log file without displaying them on screen.

Multisite Exporter is copyright © 2025 Per Søderlind.

Multisite Exporter is open-source software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation.

Multisite Exporter is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE for more information.

Releases

12 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
1.2.1 latest
Jun 13, 2025 1 year ago
multisite-exporter.zip
54
May 14, 2025 1 year ago
multisite-exporter.zip
2
May 14, 2025 1 year ago
multisite-exporter.zip
1
May 13, 2025 1 year ago
multisite-exporter.zip
1
May 13, 2025 1 year ago
multisite-exporter.zip
1
May 8, 2025 1 year ago
multisite-exporter.zip
1
May 7, 2025 1 year ago
multisite-exporter.zip
2
May 7, 2025 1 year ago
multisite-exporter.zip
0
May 7, 2025 1 year ago
multisite-exporter.zip
2
May 7, 2025 1 year ago
tag only
—
May 7, 2025 1 year ago
tag only
—
May 7, 2025 1 year ago
tag only
—
D+ grade

Security

Multisite Exporter 1.2.1 · audited by WP Registry

High-severity findings.

1 high 1 medium
Audited release
1.2.1
Findings
2
Worst severity
high
Content hash
e1332dbaa8eac8ba7cb9b2aa…

Findings

  • high Unauthenticated WXR dump exposure via web-accessible uploads directory

    information_disclosure

    Exports are stored as XML under the main site's public uploads directory (wp-content/uploads/multisite-exports/ by default) using the predictable name export-blog-{blog_id}-{sanitize_title(site_name)}-{Ymd-His}.xml and filesystem mode FS_CHMOD_FILE (typically 0644). The only access control on that directory is an index.php plus an Apache 2.2 .htaccess (`Order Allow,Deny` / `Deny from all` for `*.xml`) that is created only when the directory first appears. Nginx, IIS, and Apache with AllowOverride None ignore that file; those stacks are the usual front end for WordPress multisite, which is this plugin's only supported environment. An unauthenticated client who knows or brute-forces the timestamp (86400 guesses per site per day; blog_id and site slug are public) can download the WXR, which generate_export() fills with author logins/emails, private and draft posts, plaintext wp:post_password values, every postmeta row, and comment author emails/IPs. Direct PHP download handlers (handle_export_download / download_selected_exports) are not involved. Files remain on disk until the next export run calls cleanup_old_exports(), independent of the week-long site transient.

    includes/core/class-init.php:55-144

    Recommendation

    Do not store WXR dumps under a web-reachable directory. Write them outside the document root (or to a randomized, non-guessable path) and serve only through a capability-checked PHP handler. If a web-accessible path is unavoidable, use a long random token in every filename, deny all HTTP access in nginx/IIS config as well as Apache 2.4 `Require all denied`, and delete files on a short TTL rather than only at the next export.

  • medium Path traversal in bulk export download (nonce-only AJAX, unsanitized file names)

    file_access

    ME_Export::download_export_file() builds $file_path as trailingslashit($export_dir) . $file_name with no basename(), realpath(), or prefix check, then echoes the file. wp_ajax_me_download_selected_exports (download_selected_exports) verifies nonce download_selected_exports but never calls current_user_can, and it passes $_POST['selected_exports'] through unsanitized. For a single selected name it calls download_export_file() directly; for multiple names it ZipArchive::addFile()s the concatenated paths. A caller who holds that nonce can therefore read arbitrary files the PHP user can read (e.g. selected_exports[]=../../../wp-config.php). The nonce is only printed on manage_network screens, so a Subscriber cannot obtain it through this plugin; the extra blast radius is for a network-admin session (including hosts with DISALLOW_FILE_EDIT/DISALLOW_FILE_MODS, where the WP file editor is unavailable). The sibling handler handle_export_download does check manage_network and binds the nonce to the file name, so it is not the vector.

    includes/admin/class-admin.php:242-272

    Recommendation

    In download_selected_exports add current_user_can('manage_network') next to the nonce check. In download_export_file, accept only a basename matching the plugin's export-blog-*.xml pattern, resolve realpath(), and require that the resolved path is inside the export directory. Do not pass raw $_POST['selected_exports'] into addFile().

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.