About this plugin
wpbkp archives. Each bundle contains a manifest, checksum, database segments, media, selected files, and user decisions, so imports stay predictable.
Why MksDdn Migrate Content?
- Three export modes – Full Site (database + uploads/plugins/mu-plugins/themes), Selected Content (grid of multi-selects for posts/pages/CPTs with title search, scroll lazy load, and Load more, plus ACF Options Pages, with or without referenced media), or Theme Export (individual themes as.wpbkp ).
- Chunked pipeline – large archives stream through REST API endpoints with resume tokens, so multi‑GB transfers survive flaky networks.
- User merge control – compare archive vs current users and decide how to merge conflicts.
- Theme import mode – when a theme archive is detected, choose replace vs merge before applying changes.
- Integrity & safety –.wpbkp archives ship with manifests and checksums; imports verify capabilities, nonces, and disk space before touching data.
- Import preflight – unified import is a two-step flow: run preflight (read-only report with field/media/theme path details), then start the real import from the report without uploading the file again (browser uploads are staged server-side between steps). Full-site and theme preflight warn when archive PHP/WordPress major.minor versions differ from the target site.
Feature Highlights
- Archive format with manifest, checksum, and payload folders ( content.json, media/, options/, filesystem slices).
- Media scanner that collects featured images, galleries, attachments referenced inside blocks or shortcodes.
- File-system coverage for wp-content/uploads, wp-content/plugins, wp-content/mu-plugins, wp-content/themes with filters to skip VCS/system files.
- Chunked upload/download JS client with live progress, auto-resume, and graceful fallback to direct transfer.
- Server file import — select backup files from wp-content/uploads/mksddn-mc/imports/ without browser uploads; delete unused server backups (including bulk delete) from the import UI.
- Theme export and import with replace vs merge preview before applying changes.
- Export preflight — disk space and memory checks before full-site export starts.
- Drag-and-drop.wpbkp /.json uploader with MIME validation and checksum guardrails ( file-dropzone.js ).
- Centralized PluginLogger — dedicated log file with rotation; disable via MKSDDN_MC_DISABLE_LOGGING in wp-config.php.
Architecture
The plugin follows SOLID principles and WordPress Coding Standards with a clean, modular architecture:
Service Container & Dependency Injection
- Centralized ServiceContainer manages all dependencies
- Service Providers ( CoreServiceProvider, AdminServiceProvider, ExportServiceProvider, ImportServiceProvider, ChunkServiceProvider ) register services
- All dependencies resolved through container, eliminating direct instantiation
- Full support for interface-based dependency injection
Request Handlers
- ExportRequestHandler – handles export requests
- ImportRequestHandler – delegates to specialized import services (supports unified import via UnifiedImportOrchestrator )
- UserMergeRequestHandler – processes user merge operations
- ThemePreviewRequestHandler – handles theme preview cancel operations
- ChunkRestController – REST API controller for chunked upload/download operations
- All handlers implement corresponding interfaces for testability
Admin UI
- Top-level Migrate Content menu with Export and Import subpages
- Export tabs: Full Site, Selected Content, Theme Export ( AdminPageView, views/admin/* )
- Selected Content picker: shared multi-select grid for post types and ACF Options Pages ( content-picker.js ) with title-only search, scroll lazy load, and a Load more button on post-type columns; selected options stay pinned in each list
- Unified import form with preflight report, user preview, and theme preview screens
- Admin assets: file-dropzone.js, server-file-selector.js (server file list with bulk delete), chunk-transfer.js, content-picker.js, admin-scripts.js, admin-styles.css
Export & Import Core
- ExportHandler — selected content export (slug-based identifiers, media, taxonomies, ACF, ACF Options Pages)
- ImportHandler — selected content import (parent-child ordering, slug lookup, Polylang/ACF, ACF Options Pages). For post ACF/SCF fields: update_field() when a local field object exists; scoped meta fallback when the field group is missing or nested structural meta is incomplete; cleanup of non-scalar root “blob” meta left by a failed expand so leaf repeater/group keys remain authoritative
- SelectionBuilder, ContentSelection — build export selections from admin input (posts/CPTs and Options Page menu_slug s)
- FullContentExporter, FullContentImporter — full-site archive assembly and restore
- DumpTableResolver — picks the real {prefix}users / {prefix}usermeta tables from a dump using the dump’s table_prefix (ignores foreign sets such as Plugin Check wppc_* )
- FullDatabaseExporter, FullDatabaseImporter, SwapTableNames — streaming database export/import; schema recreate uses a swap table then atomic RENAME
- ThemeExporter, ThemeImporter — theme archive export and filesystem apply
- OptionsExporter, OptionsImporter — raw WordPress options / widget slices
- OptionsHelper — discovers ACF Options Pages and exports only field groups located on the selected menu_slug (avoids shared post_id leakage), plus a field-type schema so image/file/gallery IDs are not confused with number fields
- AttachmentCollector, AttachmentRestorer, AttachmentCollection — media pipeline (posts and ACF Options Page image/file/gallery values)
- ExportPreflight, ExportMemoryHelper — pre-export disk/memory checks and memory budgeting
- FilenameBuilder — deterministic archive filenames
Service Layer (Admin)
- SelectedContentImportService — handles selected content imports
- FullSiteImportService — manages full site imports
- ThemeImportService — handles theme archive imports
- UnifiedImportOrchestrator — orchestrates unified import with automatic type detection; step 1 is always preflight, step 2 runs the real import using a stored file reference
- ImportPreflightService — read-only analysis for unified import preflight (including PHP/WordPress version mismatch warnings for full-site and theme archives, Selected Content field/media diffs via SelectedContentDiffBuilder, theme path diffs via ThemeFileDiffBuilder, and warnings when Selected Content ACF/SCF field names are not registered locally)
- SelectedContentDiffBuilder ( Import\SelectedContentDiffBuilder ) — field-name + status inventory for selected-content preflight (core/ACF/meta/taxonomies/media; URL-rewrite awareness; ACF image/file/gallery compared by attachment filename fingerprints to avoid cross-site ID false positives; skips Polylang post_translations and empty archive term lists that the importer would not clear; no before → after value previews)
- ThemeFileDiffBuilder ( Filesystem\ThemeFileDiffBuilder ) — theme archive path inventory (add/changed/identical/unverified buckets, ACF JSON without modified, Replace delete samples with a per-theme filesystem walk cap, hash budget); slim_for_preview_store() drops path samples before the theme-preview transient (theme preview keeps a link back to the preflight report for samples)
- PreflightReportStore — short-lived preflight session index in a transient (900s); report body stored as JSON under wp-content/uploads/mksddn-mc/preflight/ (avoids oversized transient/object-cache failures for Selected Content field diffs; report JSON purged on the same TTL), plus follow-up import handles (staged browser uploads, or chunk/server identifiers)
- ImportTypeDetector — detects import type (full site, selected content, or theme) from archive file
- ImportFileValidator — validates uploaded files
- ImportPayloadPreparer — prepares import payloads
- ContentPickerQueryService — WP_Query helper for the Selected Content picker (exportable post-type allowlist, title-only search scoped to that query, paginated published posts)
- ServerBackupScanner — scans, validates, and deletes backup files on the server (single and bulk delete)
- ResponseHandler — manages redirects and status messages
- NotificationService — handles user notifications
- ProgressService — tracks operation progress
- ErrorHandler, PluginLogger — centralized error handling and file logging
- UserDiffBuilder, UserMergeApplier, UserPreviewStore — user merge workflow
- ThemePreviewStore ( Themes\ThemePreviewStore ) — stores pending theme import previews (counts-only theme file inventory to avoid oversized transients; fails loudly if the session cannot be stored)
Support & Maintenance
- ImportArtifactCleanup — stages browser uploads into preflight/; after success or abort (dismiss preflight / cancel user or theme preview) renames ephemeral archives into imports/ (no second multi-GB copy) and clears chunk job metadata; purges expired preflight files (report report-*.json bodies use the 900s session TTL; staged archives keep the longer default)
- DeactivationCleanup — clears temporary upload state and service directories when the plugin is deactivated
- PostImportMaintenance — cache/rewrite cleanup after full import and emergency purge if the database was partially updated; global flush plus targeted wp_cache_flush_group() when supported; filter mksddn_mc_post_import_object_cache_flush_groups. WooCommerce maintenance is not called in the import request that replaced wp-content/plugins (that process may still have WooCommerce 10.9 classes in memory while 11.x files are on disk). The import request only deletes wc_products_onsale, wc_featured_products, wc_outofstock_count, and wc_low_stock_count, and calls WC_Cache_Helper::get_transient_version( 'product', true ) when that method is already loaded. run_woocommerce_maintenance() runs on the next fresh request via a single WP-Cron event, or an admin-post loopback when cron cannot start. Core.maintenance is removed just before that request is spawned; the plugin runtime lock stays until import shutdown. The one-time token is saved with update_option() so the next process can read it after object-cache.php changes. wc_delete_product_transients() runs only if the loaded Automattic\WooCommerce\Internal\Utilities\ProductUtil has delete_product_transients_for_products. Maintenance failures are logged and do not fail the import.
- FullImportMaintenance — file-based runtime lock and early 503 gate while a full-site import is running (admin, CLI, cron exempt; REST blocked unless explicitly allowed)
- ImportLock — prevents concurrent import operations
- PreflightStagingPath — validates staged preflight file paths
- ThemeArchivePathHelper — normalizes theme archive entry paths
- EnvironmentVersionComparator — compares archive vs target PHP/WordPress major.minor versions for import preflight warnings
- DomainReplacer, SiteUrlGuard, FilesystemHelper, MimeTypeHelper
Archive Layer
- Packer, Extractor —.wpbkp archive pack/unpack
- FullArchivePayload — memory-efficient JSON payload handling; read_with_manifest() loads payload and manifest.json in one archive open
- ContentCollector — filesystem content collection for exports
- ArchiveValidator, ValidationResult — manifest and checksum validation
Contracts (Interfaces)
All key components implement interfaces:
* ExporterInterface, ImporterInterface
* MediaCollectorInterface, ChunkJobRepositoryInterface
* UserPreviewStoreInterface, ThemePreviewStoreInterface, UserDiffBuilderInterface, UserMergeApplierInterface
* NotificationServiceInterface, ProgressServiceInterface
* ArchiveHandlerInterface, ValidatorInterface
* Request handler interfaces for all handlers
Error Handling
- Specialized exceptions: ValidationException, FileOperationException, DatabaseOperationException, ImportException, ExportException
- Centralized ErrorHandler for consistent error processing
- Proper logging and user-friendly error messages
- Validation classes: ArchiveValidator, ImportDataValidator, ExportDataValidator, FileValidator
Performance
- BatchLoader for optimized database queries (prevents N+1 problems)
- Efficient media collection with batch processing ( AttachmentCollector, AttachmentRestorer )
- Chunked transfer for large files via REST API ( ChunkRestController, ChunkJobRepository )
- Memory-efficient streaming for large archives ( FullArchivePayload, ExportMemoryHelper )
- ContentCollector for filesystem content collection
- Streaming FullDatabaseExporter with adaptive batch sizes
Security
- All admin operations check current_user_can('manage_options')
- Nonce verification for all forms and AJAX requests
- REST API endpoints protected with permission callbacks
- Input sanitization using WordPress sanitization functions
- Output escaping with esc_html(), esc_attr(), esc_url()
- File upload validation with MIME type checking
- Path traversal protection for server file access and deletion ( ServerBackupScanner )
- Path traversal protection for archive extraction (full site + theme import)
- SiteUrlGuard prevents accidental site URL changes during import
- ImportLock prevents concurrent import operations
- DomainReplacer safely handles URL replacement during migrations