Title: LUX Content Migration
Author: LUX Digest
Published: <strong>Ọwẹ́wẹ̀  3, 2026</strong>
Last modified: Ọwẹ́wẹ̀  3, 2026

---

Ṣàwárí àwọn plugin

![](https://ps.w.org/lux-content-migration/assets/icon-256x256.png?rev=3679234)

# LUX Content Migration

 Láti ọwọ́ [LUX Digest](https://profiles.wordpress.org/luxsnap/)

[Ṣe ìgbàsílẹ̀](https://downloads.wordpress.org/plugin/lux-content-migration.3.0.6.zip)

 * [Àwọn àlàyé](https://yor.wordpress.org/plugins/lux-content-migration/#description)
 * [Àwọn àgbéyẹ̀wò](https://yor.wordpress.org/plugins/lux-content-migration/#reviews)
 *  [Ìgbéwọlẹ̀](https://yor.wordpress.org/plugins/lux-content-migration/#installation)
 * [Ìdàgbàsókè](https://yor.wordpress.org/plugins/lux-content-migration/#developers)

 [Ìrànlọ́wọ́](https://wordpress.org/support/plugin/lux-content-migration/)

## Àpèjúwe

LUX Content Migration is installed on **both** sides of a WordPress-to-WordPress
migration:

 * On the **old (source) site**, it builds a self-contained export file in this 
   pluginÌtumọ̀ Yorùbá: ’s own format (.wpmpx), with an automatic split into numbered
   parts if your hostingÌtumọ̀ Yorùbá: ’s upload limit is small.
 * On the **new (destination) site**, it imports that .wpmpx file category by category,
   bringing over posts, pages, comments (including reply/parent structure), and 
   authors (automatically matched by username when the same login exists on the 
   destination site).

This plugin is fully functional with no limits on the number of posts, pages, or
sites Ìtumọ̀ Yorùbá: – there is no license key, no usage cap, and no locked feature
anywhere in this codebase.

#### What this plugin does

 * Export from the source site (including automatic splitting into parts if needed)
   and import into the destination site, both unlimited.
 * Comments (including reply/parent structure), author linking, and custom field/
   ACF relational ID reconnection.
 * Dry-run preview — see exactly how many posts, comments, and images an import 
   will involve before you run it, without creating anything.
 * Rollback — undo a finished category or page import, deleting the posts it created(
   downloaded images are left in place since other posts may still reference them).
 * Images referenced in migrated content keep pointing at the old siteÌtumọ̀ Yorùbá:’
   s own URLs rather than being re-downloaded Ìtumọ̀ Yorùbá: – so the old site needs
   to stay online for those images to keep displaying. A separate add-on plugin (
   distributed outside WordPress.org, see the pluginÌtumọ̀ Yorùbá: ’s own site for
   details) adds actual image rehosting, redirect/404 management, background processing,
   and full media embedding on top of this plugin via standard WordPress filters/
   actions Ìtumọ̀ Yorùbá: – this base plugin works completely on its own without
   it.

#### Security notes

 * Uploaded .wpmpx files are verified by a fixed signature and checksum before being
   parsed, and legacy WXR/XML uploads are parsed with a hardened XML reader (any`
   <!DOCTYPE>` declaration is stripped before parsing and external entity/network
   loading is disabled) to prevent XXE-style attacks from a malicious export file.
 * File uploads are validated against the requestÌtumọ̀ Yorùbá: ’s own upload metadata
   via `is_uploaded_file()` and moved through the WordPress Filesystem API into 
   a non-listable, non-executable private folder that is cleared automatically after
   each file is processed.

### External services

This plugin does not connect to any external service. All processing (reading the
export file, creating posts/pages/comments/authors, custom field reconnection) happens
entirely on your own WordPress siteÌtumọ̀ Yorùbá: ’s server.

## Ìgbéwọlẹ̀

 1. Install and activate LUX Content Migration on **both** the new site and the old
    site.
 2. On first visit to “LUX Content Migration” in the admin menu, choose whether this
    site is the migration destination (new site) or source (old site).
 3. On the source site: go to LUX Content Migration  Export, choose what to export,
    and download the resulting .wpmpx file (it may be split into numbered parts).
 4. On the destination site: go to LUX Content Migration  Import, upload that .wpmpx
    file (select all parts together if it was split), and import it category by category.

## FAQ

### Do I need to install this on the old site too?

Yes Ìtumọ̀ Yorùbá: – install and activate it on both the old (source) site and the
new (destination) site. The source site builds the .wpmpx export file that the destination
site then imports.

### Will my images move too?

The URLs referencing images in your migrated posts/pages are kept exactly as they
were on the old site Ìtumọ̀ Yorùbá: – this plugin does not download or re-host image
files. As long as the old site stays online, those images continue to display normally
on the new site.

### Does this plugin have any limits on the number of posts, pages, or sites?

No. Every feature in this plugin Ìtumọ̀ Yorùbá: – export, import, comments, author
linking, custom field/ACF reconnection, dry-run preview, rollback Ìtumọ̀ Yorùbá:–
works with no count limit, no time limit, and no license key required.

## Àwọn àgbéyẹ̀wò

Kò sí àwọn àgbéyẹ̀wò fún plugin yìí.

## Àwọn Olùkópa & Olùgbéejáde

“LUX Content Migration” jẹ́ ètò ìṣàmúlò orísun ṣíṣí sílẹ̀. Àwọn ènìyàn wọ̀nyí ti
ṣe ìkópa sí plugin yìí.

Àwọn Olùkópa

 *   [ LUX Digest ](https://profiles.wordpress.org/luxsnap/)

[Túmọ̀ “LUX Content Migration” sí èdè rẹ.](https://translate.wordpress.org/projects/wp-plugins/lux-content-migration)

### Ṣe o nífẹ̀ẹ́ sí ìdàgbàsókè?

[Ṣàwárí koodu](https://plugins.trac.wordpress.org/browser/lux-content-migration/),
ṣàyẹ̀wò [ibi ìpamọ́ SVN](https://plugins.svn.wordpress.org/lux-content-migration/),
tàbí ṣe àgbékalẹ̀ sí [àkọsílẹ̀ ìdàgbàsókè](https://plugins.trac.wordpress.org/log/lux-content-migration/)
nípasẹ̀ [RSS](https://plugins.trac.wordpress.org/log/lux-content-migration/?limit=100&mode=stop_on_copy&format=rss).

## Àkọsílẹ̀ àwọn àyípadà

#### 3.0.6

 * Fix: `fwrite()` return values are now checked when writing the split .wpmpx export
   parts in `WPMP_Exporter::finalize_job()`. A partial write is retried; if the 
   disk genuinely canÌtumọ̀ Yorùbá: ’t be written to, the export aborts, deletes
   the partial part files, and returns a clear error instead of silently producing
   a truncated/corrupted export archive.
 * Hardening: `$_POST['source_category']` / `$_POST['category_name']` are now passed
   through `sanitize_text_field()` before use in `WPMP_Import_Admin` (category-start,
   rollback, and preview handlers), consistent with the rest of the pluginÌtumọ̀
   Yorùbá: ’s input handling.
 * Clarity: the .wpmpx metadata-length header is now packed/unpacked with the explicit
   32-bit big-endian `N` format code (two halves) instead of the 64-bit `J`/`P` 
   codes, to remove any ambiguity about byte order for future readers/reviewers.
   Output bytes are unchanged, so this is fully compatible with .wpmpx files created
   by earlier 3.0.x versions.

#### 3.0.5

 * **Critical fix: with the paid add-onÌtumọ̀ Yorùbá: ’s full license active, real
   image/video rehosting silently did nothing** Ìtumọ̀ Yorùbá: – content kept pointing
   at the old siteÌtumọ̀ Yorùbá: ’s URLs and featured images were always left empty,
   even though the add-on was correctly downloading files and creating attachments
   on the destination site. Root cause: `WPMP_Importer::process_attachment_batch()`
   passes its `$global` state (the URL-rewrite map and the old-attachment-ID  new-
   attachment-ID map) into `apply_filters( 'lux_content_migration_process_attachment_batch',...)`
   Ìtumọ̀ Yorùbá: – but PHP/WordPress break by-reference passing across `apply_filters()`,
   so the add-onÌtumọ̀ Yorùbá: ’s own callback (which correctly re-reads and re-
   saves this state on every batch) was having its save immediately overwritten 
   by this pluginÌtumọ̀ Yorùbá: ’s own caller, which was still holding Ìtumọ̀ Yorùbá:–
   and re-saving Ìtumọ̀ Yorùbá: – the state exactly as it was _before_ that batch
   ran. This happened on every single batch tick, so the URL map and attachment-
   ID map could never actually accumulate any entries, no matter how many images
   the add-on successfully rehosted. Fixed by re-reading the freshly-saved state
   back into this functionÌtumọ̀ Yorùbá: ’s reference parameter immediately after
   a filter callback reports it handled the batch, so this pluginÌtumọ̀ Yorùbá: ’
   s own follow-up save can no longer clobber it. Free-plugin-only fix Ìtumọ̀ Yorùbá:–
   no change needed on the add-on side, and no change for anyone running the free
   plugin standalone (which never populates this state in the first place).

#### 3.0.4

 * **Fixed a real bug:** the “내보내기 준비” (Export) screen had a second “📦 전체
   미디어 백업” button since the very first release, but this pluginÌtumọ̀ Yorùbá:’
   s own `ajax_export_start()` AJAX handler unconditionally rejected any request
   that button sent (`embed_files: 1`), regardless of whether the paid add-on was
   installed or licensed Ìtumọ̀ Yorùbá: – so that button never actually worked for
   anyone, including fully-licensed paying customers of the add-on. ItÌtumọ̀ Yorùbá:’
   s been removed, and the underlying handler now asks the add-on (via a new filter,`
   lux_content_migration_embed_files_available`) whether the request should be allowed
   before rejecting it Ìtumọ̀ Yorùbá: – the same request that used to always fail
   now succeeds when the add-on is present and licensed for full access.
 * Replaced that removed button with a single “이미지/영상까지 포함해서 완전히 담기”(
   include images/video) card next to the main export button. When the add-on reports(
   via the new filter above) that this is actually available, it renders the real,
   working checkbox and its own guidance text via two more new hooks (`lux_content_migration_render_embed_files_option`
   action, `lux_content_migration_set_embed_files_preference` action to persist 
   the choice) Ìtumọ̀ Yorùbá: – otherwise this plugin shows a “log in to your license”
   or “learn about the Pro add-on” link depending on whether the add-on is installed
   at all (reusing the `lux_content_migration_pro_addon_installed`/`lux_content_migration_pro_settings_url`
   filters from 3.0.2).
 * Rewrote the guidance text on the export screen to precisely spell out all four
   real-world combinations (free vs. licensed add-on, crossed with “keeping the 
   old site online” vs. “closing/moving it soon”) instead of the previous one-line
   summary, based directly on user feedback about how confusing the previous wording
   was.
 * `render_screen_switcher()` now also shows a “자동 리디렉트 추천” (automatic redirect
   suggestions) pill on the destination-site role, linking to the same redirect-
   management screen the source role already links to Ìtumọ̀ Yorùbá: – the add-on
   renders different content there depending on which role visits it. Previously
   this cross-screen link only appeared for the source role.

#### 3.0.3

 * **Screen reorganization (user feedback):** the “설정 / 라이선스” (Settings / 
   License) screen defaulted to a “Pro 애드온” tab (generic promotional copy, or
   Ìtumọ̀ Yorùbá: – since 3.0.2 Ìtumọ̀ Yorùbá: – a link to the add-onÌtumọ̀ Yorùbá:’
   s own license screen) shown before the “사이트 역할” (Site Role) tab, even though
   site role is this screenÌtumọ̀ Yorùbá: ’s actual, original purpose and the Pro-
   related content duplicates the add-onÌtumọ̀ Yorùbá: ’s own “Pro 설정” menu item
   once installed. Removed the tab switcher entirely: this screen (renamed “역할
   설정” / Role Setting, in both its menu label and page title) now shows the site-
   role card directly, with the Pro add-on card kept as a secondary section below
   it (still needed since a few “Pro 애드온 알아보기” links elsewhere in this plugin
   point here).

#### 3.0.2

 * Fixed the “Pro 애드온” tab on this pluginÌtumọ̀ Yorùbá: ’s own “설정 / 라이선스”(
   Settings / License) screen always showing the generic “buy now” promotional copy,
   even when the paid add-on was already installed Ìtumọ̀ Yorùbá: – so a customer
   who had already purchased and installed the add-on, and naturally looked for 
   the license field on this pluginÌtumọ̀ Yorùbá: ’s own settings screen, would 
   find no way to enter their license key there at all (the real license field lives
   on a separate screen the add-on registers for itself, under a different menu 
   label). This screen now checks two new neutral filters, `lux_content_migration_pro_addon_installed`
   and `lux_content_migration_pro_settings_url` (both default to false/empty when
   no add-on is present, so standalone use of this free plugin is unaffected), and
   when an add-on is detected, shows a direct link to its actual license/settings
   screen instead of the promotional copy.

#### 3.0.0

 * Major structural change in response to WordPress.org review feedback (Guideline
   5, Trialware): removed every license-gated featureÌtumọ̀ Yorùbá: ’s implementation
   from this plugin entirely, rather than merely hiding it behind a check. Image
   rehosting, full media backup (embedding attachment bytes), redirect/404 management,
   automatic redirect-suggestion CSV export, and background/unattended processing
   are no longer present in this codebase in any form Ìtumọ̀ Yorùbá: – not even 
   as dormant code behind a filter. This plugin now always does exactly what it 
   does for free (posts, pages, comments, authors, custom fields, dry-run preview,
   rollback Ìtumọ̀ Yorùbá: – no limits), with no license concept, no license screen,
   and no external license-verification calls anywhere in the code.
 * The removed functionality is available as a separate add-on plugin, distributed
   outside WordPress.org, which extends this plugin via a small set of neutral WordPress
   filters/actions (`lux_content_migration_is_pro`, `lux_content_migration_process_attachment_batch`,`
   lux_content_migration_embed_attachment_file`, `lux_content_migration_export_embed_item`,`
   lux_content_migration_post_imported`, `lux_content_migration_retry_failed_attachment`,`
   lux_content_migration_render_admin_notices`, `lux_content_migration_role_saved`,`
   lux_content_migration_deactivate`, `lux_content_migration_reset_all`, `lux_content_migration_pro_addon_installed`,`
   lux_content_migration_pro_settings_url`, `lux_content_migration_embed_files_available`,`
   lux_content_migration_render_embed_files_option`, `lux_content_migration_set_embed_files_preference`)
   Ìtumọ̀ Yorùbá: – the same extensibility pattern used by other WordPress.org-hosted
   freemium plugins for their paid add-ons.
 * Removed bundled translation `.po`/`.mo` files and the `load_plugin_textdomain()`
   call Ìtumọ̀ Yorùbá: – translations for WordPress.org-hosted plugins are handled
   automatically via translate.wordpress.org since WordPress 4.6.
 * Re-added the nonce check on the export-part download endpoint that had been removed
   in an earlier version based on a since-corrected misdiagnosis (the actual cause
   of that download failure was an unrelated double-`sanitize_file_name()` bug, 
   already fixed separately).

#### 3.0.1

 * Fixed a fatal error on “reset everything”: `WPMP_Store::reset_all()` still called`
   WPMP_Importer::disable_background_mode()`, a method that had already been deleted
   from `WPMP_Importer` when background processing moved to the Pro add-on. Replaced
   with a `lux_content_migration_reset_all` action so a Pro add-on can clean up 
   its own background-processing state on reset, without the free plugin needing
   to know anything about it.
 * Fixed the export manifest always reporting `embed_files` as false: the value 
   returned by the `lux_content_migration_export_embed_item` filter was computed
   per-batch but never written back onto the persisted export job, so `finalize_job()`
   could never see it. A Pro add-on embedding attachment bytes into the export file
   is now correctly reflected in the finished manifest.
 * Fixed the plugin package itself containing a duplicated, slightly-stale nested
   copy of its own files from an earlier draft Ìtumọ̀ Yorùbá: – no functional impact
   on a correctly-installed copy, but cleaned up for a tidy WordPress.org package.
 * Rewrote `uninstall.php`: it still dropped the `wp_redirects`/`wp_redirect_404_log`
   database tables and deleted license/redirect/usage-limit options left over from
   the removed features. This plugin no longer creates any of that data (it belongs
   to the separate Pro add-on now), so uninstalling this plugin no longer touches
   it Ìtumọ̀ Yorùbá: – each plugin only cleans up what it actually created.

#### 2.8.2

 * Fixed two leftover code comments still referencing the old main file name (`wp-
   content-migration.php`) instead of the current one (`lux-content-migration.php`)
   Ìtumọ̀ Yorùbá: – harmless (comments arenÌtumọ̀ Yorùbá: ’t executed), but corrected
   for accuracy.

#### 2.8.1

 * Fix (WordPress.org Plugin Check automated scan failures): replaced `move_uploaded_file()`(
   a forbidden direct filesystem function) with the WP_Filesystem APIÌtumọ̀ Yorùbá:’
   s `move()` method for handling uploaded .wpmpx files Ìtumọ̀ Yorùbá: – the `is_uploaded_file()`
   security check that verifies the file genuinely came from this requestÌtumọ̀ 
   Yorùbá: ’s upload is kept in place, since WP_Filesystem doesnÌtumọ̀ Yorùbá: ’
   t perform that check itself. Also updated “Tested up to” from 7.0 to 7.1 (current
   WordPress release).

#### 2.7.3

 * Fix: `Contributors` in readme.txt was set to `luxdigest` (the display name) instead
   of the actual WordPress.org login username (`luxsnap`) Ìtumọ̀ Yorùbá: – required
   to match the account submitting this plugin for review.

#### 2.7.2

 * Updated “Tested up to” from 6.6 to 7.0 (current WordPress release) ahead of WordPress.
   org submission.

#### 2.7.1

 * Renamed the “팀” pricing tier to “에이전시(멀티사이트)” throughout, and corrected
   the license description that still said “슬롯 1개” (one slot) for a single license
   Ìtumọ̀ Yorùbá: – itÌtumọ̀ Yorùbá: ’s actually 2 (source + target, a pair), matching
   the fix made earlier this cycle.

#### 2.7.0

 * Added a complete English translation (`languages/wp-content-migration-en_US.po`/`.
   mo`) covering all 407 translatable strings in the plugin Ìtumọ̀ Yorùbá: – on 
   an English-locale WordPress install, every screen now displays in English instead
   of the Korean source text, which matters for WordPress.org review (typically 
   done on an English test site) and for this pluginÌtumọ̀ Yorùbá: ’s primarily 
   English-speaking market. The Korean source strings in the code itself are unchanged
   Ìtumọ̀ Yorùbá: – this is purely an additional translation layer, loaded automatically
   by WordPress via `load_plugin_textdomain()` based on the siteÌtumọ̀ Yorùbá: ’
   s locale. Verified the compiled `.mo` file parses correctly with PythonÌtumọ̀
   Yorùbá: ’s own `gettext` module before shipping.

#### 2.6.8

 * Fix (WordPress.org submission blocker): the text domain was still `wp-media-porter`
   throughout the codebase (plugin header, `load_plugin_textdomain()`, and all 477
   translation function calls) even though the plugin was renamed to `wp-content-
   migration` back in 2.1.0 Ìtumọ̀ Yorùbá: – WordPress.org requires the text domain
   to exactly match the plugin slug, and a mismatch here would fail automated review.
   Corrected everywhere.
 * Removed the bundled `wp-media-porter-*.mo/.po/.pot` translation files Ìtumọ̀ 
   Yorùbá: – they referenced the old (now wrong) text domain and, being from before
   roughly half of this pluginÌtumọ̀ Yorùbá: ’s current screens existed, covered
   only a fraction of todayÌtumọ̀ Yorùbá: ’s actual strings. Regenerated `languages/
   wp-content-migration.pot` from scratch against the current codebase (407 unique
   translatable strings) using a custom extractor built for this session (no gettext
   toolchain was available to run `wp i18n make-pot`). Translated `.po`/`.mo` files
   for specific languages (en_US, ja, etc.) are not included Ìtumọ̀ Yorùbá: – see
   the note below.

#### 2.6.7

 * Reworded the “전체 미디어 백업” caption to lead with its biggest selling point:
   the file itself is a standalone backup Ìtumọ̀ Yorùbá: – it can sit unused for
   weeks or months and still be imported later to recreate the site, not just a 
   one-time transfer artifact. Also renamed “자동 리디렉트 추천”/”백그라운드 무인
   처리” to “리디렉트 관리”/”백그라운드 프로세스” in this caption for a punchier,
   more marketing-appropriate phrasing (the fuller technical description on the 
   Settings/License screen is unchanged).

#### 2.6.6

 * Reworded the caption under “전체 미디어 백업” to stop repeating the “미디어 주소
   자동 적용” line already covered by the paragraph above it, and instead briefly
   point out the two other paid-only features this plugin has (자동 리디렉트 추천,
   백그라운드 무인 처리) that arenÌtumọ̀ Yorùbá: ’t specific to this button but 
   are worth knowing about while looking at a paid-tier option.

#### 2.6.5

 * Fix: “선택한 항목 내보내기” is usable on both free and paid tiers (unlike “전체
   미디어 백업”, which is paid-only) Ìtumọ̀ Yorùbá: – the caption under it now shows
   both outcomes (“무료: 적용 불가” / “유료: 자동 적용, 원본 사이트가 가져오기 끝날
   때까지 켜져 있어야 함”) instead of a single line that only described one of them.

#### 2.6.4

 * Simplified the per-button captions under “선택한 항목 내보내기”/”전체 미디어 
   백업” to one line each (“새로운 미디어 주소 적용 불가” / “자동 적용”) Ìtumọ̀ 
   Yorùbá: – the fuller explanation was already given in the paragraph just above,
   so repeating it under each button read as cluttered. Added a “🛒 정식 라이선스
   구매하기” button directly under the locked PRO option so thereÌtumọ̀ Yorùbá: ’
   s an immediate path to buy without needing to go to Settings first.

#### 2.6.3

 * Reworded the free-tier export copy (“이미지/영상은 주소만 포함됩니다”) Ìtumọ̀
   Yorùbá: – it read as if the addresses were being handled/processed somehow, when
   in fact nothing changes: the old siteÌtumọ̀ Yorùbá: ’s URLs are kept as-is with
   no rewriting at all, so closing or moving the source site later breaks every 
   image/video and each one must be manually re-pointed. The paid “전체 미디어 백업”
   copy is now explicit about the actual contrast: it automatically re-addresses
   images/video to the new site.

#### 2.6.2

 * Fix (real gap): the license screen had no way to actually buy a license Ìtumọ̀
   Yorùbá: – it only assumed you already had a key and were entering it. Someone
   landing here on the free tier had no path forward. Added a “🛒 정식 라이선스 
   구매하기” button (linking to wpcm.luxdigest.comÌtumọ̀ Yorùbá: ’s pricing section)
   shown prominently when no key is saved yet, plus a smaller link for existing 
   customers who need a key for another site.

#### 2.6.1

 * Import screen now shows a progress bar (matching the export screen) instead of
   only raw counts, and fixes a real bug where the “처리 중입니다…” message stayed
   on screen even after the job actually finished (counts showed 90/90 and 8/8 complete,
   but the status text and lack of visual completion made it look stuck) Ìtumọ̀ 
   Yorùbá: – the text now switches to “완료되었습니다” and the bar fills to 100%
   the moment the jobÌtumọ̀ Yorùbá: ’s last poll reports done, instead of only silently
   revealing the finalize button.

#### 2.6.0

 * Fix (the actual, deeper root cause of images not being relinked Ìtumọ̀ Yorùbá:–
   upstream of the 2.5.2 fix, which only addressed rewriting and never actually 
   fired for most images): `collect_needed_attachments()` decided whether an image
   was “needed” by checking if the exact original attachment URL string appeared
   in post content. Since WordPress normally inserts a resized variant into content(
   not the original), this exact-match check failed for the majority of real in-
   content images Ìtumọ̀ Yorùbá: – meaning they were never even queued for download
   in the first place, so there was nothing for the URL rewriter to work with regardless
   of how good it was. Detection now also matches by filename (independent of any
   resize suffix), and separately scans post content directly for `src=`/`srcset
   =`/Gutenberg-block image URLs pointing at any other host Ìtumọ̀ Yorùbá: – including
   images that were never registered as a WordPress attachment on the source site
   at all Ìtumọ̀ Yorùbá: – and queues those too as on-the-fly entries.
 * Changed `rewrite_urls()` to replace any old-host reference to a given filename(
   with or without a resize suffix) with the new siteÌtumọ̀ Yorùbá: ’s plain original
   URL, rather than trying to reconstruct a matching resize suffix on the new site(
   which may not exist). Guarantees a working image over a possibly-broken exact-
   size match.

#### 2.5.2

 * Fix (real, likely the main cause of “이미지가 재정의가 안 된다”): `rewrite_urls()`
   only replaced post content URLs that matched an attachmentÌtumọ̀ Yorùbá: ’s original
   URL _exactly_. But WordPress normally inserts a resized variant into post content
   when you add an image via the editor (e.g. `photo-300x200.jpg` for “Medium” size),
   not the raw original filename Ìtumọ̀ Yorùbá: – so the one case this whole feature
   exists for (images actually appearing in post content) was frequently left pointing
   at the old site, while only exact-match references (like a featured image, which
   does store the original URL) got rewritten correctly. Added a second pass that
   recognizes the `filename-WxHeight.ext` resize pattern and rewrites it to the 
   same size suffix on the new siteÌtumọ̀ Yorùbá: ’s uploaded copy (WordPress regenerates
   the same intermediate sizes automatically on upload, so this size normally exists).
   The existing srcset-stripping safety net still runs afterward for anything neither
   pass caught.

#### 2.5.1

 * Moved the split-part indicator from the end of the filename to the front: `NEWS-
   LUX-...-074327.wpmpx.part1of2` becomes `part1of2-NEWS-LUX-...-074327.wpmpx`. 
   The old suffix placement buried the only thing that differs between parts at 
   the very end of an already-long, mostly-identical filename, making multiple parts
   hard to tell apart at a glance in a file picker or folder view. The import side
   still recognizes both the new prefix format and the old suffix format, so parts
   already exported with an earlier version can still be uploaded.

#### 2.5.0

 * Renamed the “카테고리별 가져오기”/”페이지 가져오기” section labels to “파일 가져오기”
   Ìtumọ̀ Yorùbá: – the whole screen is one unified “upload a file, it sorts itself
   out” action, and naming a sub-step after “category” made it read as a separate,
   category-specific action rather than part of that.
 * Once a section is fully done, it no longer keeps showing the full instructional
   card (table headers, feature-help accordion, per-row status column) as if action
   were still needed Ìtumọ̀ Yorùbá: – it collapses to a compact “✅ 완료” summary
   with just a rollback link per item. If a file has both finished and unfinished
   categories, only the unfinished ones stay in the working table; finished ones
   move to the compact summary above it.

#### 2.4.1

 * Category import no longer requires manually picking or typing a target category.
   Leaving both fields blank now auto-matches by exact name (uses an existing category
   with the same name, or creates one) Ìtumọ̀ Yorùbá: – matches the actual intent
   of this whole screen being “upload a file, it sorts itself out” rather than a
   manual mapping step. Manual selection is still available for when you want a 
   different target.

#### 2.4.0

 * Redesigned the import screen from a fixed two-section layout (“페이지 가져오기”
   + “카테고리별 가져오기”, always both shown regardless of what the file actually
   contained) into a content-adaptive one. Uploading a file now shows a summary 
   of whatÌtumọ̀ Yorùbá: ’s actually inside it (categorized posts, uncategorized
   posts, pages, standalone media), and only the sections that apply to that file
   appear Ìtumọ̀ Yorùbá: – no more an empty/irrelevant “카테고리별 가져오기” table
   on a pages-only file.
 * Fix (real gap, not previously reachable at all): posts with no category attached
   were invisible to the old catalog table (it only ever grouped posts that had 
   at least one category term), so a `.wpmpx` built from “글 선택” or any export
   containing uncategorized posts had no way to import them. They now get their 
   own “미분류 글 가져오기” section, importable as one flat batch like pages already
   were.
 * Fix (also a real gap): files built with “미디어만 내보내기” (posts/pages both
   empty, media only) had no import path at all Ìtumọ̀ Yorùbá: – there was no button
   anywhere that would actually bring those attachments in. Added a “미디어 가져오기”
   section for this case specifically (only shown when the file has no posts or 
   pages at all, since media referenced by posts/pages is already picked up automatically
   while importing those).
 * Internal: generalized the “flat” (non-category) import engine Ìtumọ̀ Yorùbá: –
   what used to be page-specific job/preview/rollback/record-keeping code is now
   shared by pages, uncategorized posts, and media-only imports, keyed by type.

#### 2.3.0

 * Fix (real cause of the source site never becoming “정식(full)” automatically):
   this client defaulted the source siteÌtumọ̀ Yorùbá: ’s requested role to `export_only`,
   requiring a manual “정식 전환” click before Redirect Manager would ever unlock
   Ìtumọ̀ Yorùbá: – but the product itself is sold as a pair (source + destination
   both become full on a single-tier purchase; see the matching marketplace fix).
   The default requested role is now `full` for both site roles Ìtumọ̀ Yorùbá: –
   entering a valid key activates both sites automatically, no separate step. A 
   source site that already has an `export_only` success recorded from an earlier
   version still needs one manual “정식 전환” click to move off that recorded state,
   after which this no longer applies.
 * Companion server-side fix required: `decoblocks-marketplace` 5.6.0 changes `SINGLE_MAX_ACTIVATIONS`
   from 1 to 2 to actually grant both slots on a single-tier purchase Ìtumọ̀ Yorùbá:–
   this client-side default alone does nothing without that.

#### 2.2.4

 * Fix (real, confirmed cause of every export download failing): the download handler
   ran the requested filename through `sanitize_file_name()` a second time. WordPressÌtumọ̀
   Yorùbá: ’s own filename sanitizer inserts an underscore when it sees a multi-
   dot name with an unrecognized “middle extension” (exactly what `name.wpmpx.part1of2`
   looks like to it) as a defense against extension-spoofing attacks Ìtumọ̀ Yorùbá:–
   so the requested filename silently became `name.wpmpx_.part1of2`, which never
   matched the real file. The actual security boundary here is the whitelist check
   against the export manifest (already present), not sanitization, so the redundant
   second pass was removed entirely.
 * Clarified: the Redirect Manager lock screen and its diagnostic table now explicitly
   distinguish “라이선스 키가 유효함” (the key itself checks out) from “이 사이트가
   정식(role=full)” (this specific site has been granted the full tier) Ìtumọ̀ Yorùbá:–
   these are different things, and a site can legitimately show “유효함” while still
   being export_only, which isnÌtumọ̀ Yorùbá: ’t a bug.

#### 2.2.3

 * The Redirect Manager lock screen now shows the raw license state stored on that
   specific site directly on the page: the key (masked), whether the serverÌtumọ̀
   Yorùbá: ’s last response said valid/invalid, when it was last checked, and the
   exact failure reason the server returned. No more guessing whether a key is missing,
   a request failed, or something else Ìtumọ̀ Yorùbá: – itÌtumọ̀ Yorùbá: ’s on screen.

#### 2.2.2

 * Fix: clicking a real export download link (added in 2.2.1) could still fail. 
   The download handler required a nonce (`check_admin_referer()`) Ìtumọ̀ Yorùbá:–
   if it didnÌtumọ̀ Yorùbá: ’t match for any reason, WordPress shows its own generic“
   다시 시도해주세요” page completely unrelated to this plugin, which just looked
   like “clicking gives an error.” Removed the nonce requirement for this action(
   capability check alone still protects it Ìtumọ̀ Yorùbá: – itÌtumọ̀ Yorùbá: ’s
   a read-only download of the adminÌtumọ̀ Yorùbá: ’s own data), eliminating this
   failure mode outright. The three distinct failure cases inside `stream_part()`(
   no manifest, filename not recognized, file missing from disk) also no longer 
   share one generic message Ìtumọ̀ Yorùbá: – each now states exactly what it found,
   so a future failure is diagnosable from the screen alone.

#### 2.2.1

 * Fix (real cause of “정식 전환을 눌러도 그대로다”): clicking “정식 전환” on the
   Redirect Manager screen redirected the result notice to the _Settings_ screen
   instead Ìtumọ̀ Yorùbá: – and the notice-display code was hard-restricted to only
   render on Settings besides. If you stayed on Redirect Manager (the natural expectation,
   since thatÌtumọ̀ Yorùbá: ’s where you clicked), youÌtumọ̀ Yorùbá: ’d never see
   the success or failure message at all Ìtumọ̀ Yorùbá: – it silently rendered on
   a page you werenÌtumọ̀ Yorùbá: ’t looking at. Both the redirect target and the
   notice-display condition now point at Redirect Manager, so the result shows exactly
   where the click happened. Note: if the request itself still fails, the reason
   is now visible (“정식 전환에 실패했습니다 Ìtumọ̀ Yorùbá: – 남은 활성화 자리가
   없을 수 있습니다”) Ìtumọ̀ Yorùbá: – on a single-site license already fully activated
   on another site (e.g. the destination site), this is the intended limit, not 
   a bug; a multi-site license is required to activate a second site.
 * Changed: removed the export auto-download entirely (iframe/tab/folder-picker 
   attempts across 1.9.5-2.2.0 were all silently blocked by the browser under some
   condition or other, with no visible error Ìtumọ̀ Yorùbá: – “완료됐다는데 파일이
   없다” kept recurring). Completed exports now show plain, real download links 
   you click directly Ìtumọ̀ Yorùbá: – a genuine click can never be silently blocked
   by a browser, unlike any of the automated approaches tried so far.

#### 2.2.0

 * Fix (real root cause of “내보내기했는데 폴더에 파일이 없다” and “리디렉트가 라이선스
   오류에 걸린다”): this hostingÌtumọ̀ Yorùbá: ’s persistent object cache doesnÌtumọ̀
   Yorùbá: ’t reliably reflect option values immediately after `update_option()`
   Ìtumọ̀ Yorùbá: – the same class of bug already fixed once for `get_site_role()`.
   It turned out 13 other option reads across the plugin had the identical exposure,
   including the two most consequential ones: `WPMP_License::get_key()`/`get_state()`(
   the single source of truth for every “is this license valid” check in the plugin,
   so a stale read here could make a freshly-verified license look invalid on the
   very next screen, e.g. Redirect Manager) and `WPMP_Exporter::get_manifest()` (
   read by the hidden download iframe moments after the export job finishes Ìtumọ̀
   Yorùbá: – a stale “no export found” read meant the download silently never happened,
   even though the UI showed a completion message). Rather than patching each call
   site individually, added one shared `wpmp_get_option_fresh()` helper (cache-bypassing`
   get_option()`) and moved every one of this pluginÌtumọ̀ Yorùbá: ’s own option
   reads through it.
 * Simplified: removed the “전체 미디어 백업” local-folder-picker feature (File 
   System Access API) entirely Ìtumọ̀ Yorùbá: – it only worked in Chromium browsers
   and had repeatedly caused confusing failures (blank tabs, popup blocking, the
   picker re-prompting with no visible progress). Both “선택한 항목 내보내기” and“
   전체 미디어 백업” now behave identically: click, wait for the progress bar, and
   the finished file(s) download straight to the browserÌtumọ̀ Yorùbá: ’s normal
   downloads folder Ìtumọ̀ Yorùbá: – no folder selection step for either.

#### 2.1.1

 * Changed the licensing server domain from wpmediaporter.luxdigest.com to wpcm.
   luxdigest.com (`API_BASE` constant, Plugin URI). This is the address this plugin
   contacts to verify a license key Ìtumọ̀ Yorùbá: – see “External services” above.

#### 2.1.0

 * Renamed the plugin from “WP Media Porter” to “LUX Content Migration” Ìtumọ̀ Yorùbá:–
   all user-facing text (plugin name, screen headings, notices) updated. Internal
   technical identifiers (class names, option keys, the .wpmpx file extension, the
   product slug used to talk to the licensing server) are unchanged, since those
   are invisible to users and renaming them would require also updating the separate
   licensing server in lockstep for no visible benefit.
 * Fix: “이미지 주소 재적용” now behaves correctly per license tier instead of being
   a plain always-available button regardless of paid status. On a full license,
   image rehosting already happens automatically during import, so the button is
   no longer shown at all. On the free tier, the button is still shown (so people
   understand the feature exists) but clicking it no longer performs the action 
   Ìtumọ̀ Yorùbá: – it explains that image rehosting requires a full license and
   links to Settings, both in the UI and enforced again server-side in the AJAX 
   handler.

#### 2.0.1

 * Fix (likely the real cause of import failures): the upload handler used `wp_handle_upload()`,
   WordPressÌtumọ̀ Yorùbá: ’s helper for normal Media Library uploads. That function
   applies filename sanitization, extension checks, and upload-directory rules meant
   for regular media Ìtumọ̀ Yorùbá: – none of which fit a proprietary format with
   no registered mime type (`.wpmpx`, `.wpmpx.part1of3`), so it could reject or 
   mangle these files even with `test_type` disabled. Studying All-in-One WP Migration
   showed it deliberately does _not_ use `wp_handle_upload()` for its own `.wpress`
   archives Ìtumọ̀ Yorùbá: – it simply copies PHPÌtumọ̀ Yorùbá: ’s already-received
   temp file to its destination. Switched to the same approach: `is_uploaded_file()`
   verification, a sanitized filename, and `move_uploaded_file()` into the pluginÌtumọ̀
   Yorùbá: ’s private, externally-blocked folder. Authenticity is still verified
   afterward by the parserÌtumọ̀ Yorùbá: ’s own magic-byte check.
 * Fix: export opened a new browser tab to trigger the download, which then stayed
   open showing a blank page (downloads donÌtumọ̀ Yorùbá: ’t navigate, so nothing
   ever rendered there). Downloads are now triggered through a hidden iframe Ìtumọ̀
   Yorùbá: – no new tab appears at all, and nothing is left behind for you to close.

#### 2.0.0

 * Rearchitected the .wpmpx file format (v3) after studying how established migration
   plugins actually do this. The previous design base64-encoded every attachmentÌtumọ̀
   Yorùbá: ’s bytes into JSON text Ìtumọ̀ Yorùbá: – which inflates size ~33%, costs
   an encode/decode pass on every file, and forces the JSON parser to handle enormous
   strings, all of which contributed to the memory failures seen throughout the 
   1.9.x series. The format is now `[magic][8-byte metadata length][gzipped text
   metadata][raw binary section]`: attachment bytes are appended verbatim with no
   encoding, and each item stores only an offset and size pointing into that section.
   Export copies file bytes 64KB at a time into the binary section during batch 
   collection; import seeks directly to each offset and copies the exact byte range
   straight to disk. No base64 anywhere.
 * Removed the two-step export flow entirely Ìtumọ̀ Yorùbá: – the export screen 
   no longer keeps a “완료된 파일” panel with separate 다운로드 buttons and a 조각
   정리 button. Clicking export now runs the job and downloads the resulting file(
   s) directly, then returns to a clean screen.
 * Removed the now-unnecessary whole-file fallback parser and legacy base64 code
   paths.
 * Note: .wpmpx files produced by 1.9.x and earlier cannot be read by this version(
   the format changed). Re-export from the source site.

#### 1.9.8

 * Hardening: `parse_wpmpx()`‘s streaming path now also checks `defined('ZLIB_ENCODING_GZIP')`
   before using it, not just `function_exists('inflate_init')` Ìtumọ̀ Yorùbá: – 
   on PHP 8+, referencing an undefined constant is a fatal Error rather than a warning,
   so this closes a possible (if narrow) crash path on unusual PHP/zlib builds by
   falling back to the whole-file method automatically instead.
 * Verification: re-checked every file touched this session with three independent
   methods (a string/comment-aware brace scanner, a class-body-statement scanner,
   and a Pygments PHP-tokenizer-based scanner) Ìtumọ̀ Yorùbá: – no further syntax
   issues found. A real PHP interpreter was not available in this environment to
   compile-check directly; if the import still fails after this version, the on-
   screen error added in 1.9.4 (or the exact wording of whatever screen appears)
   is needed to diagnose further, since static analysis alone has been exhausted.

#### 1.9.7

 * Fix: the auto-download added in 1.9.5 created a hidden `<a download>` element
   and clicked it several async steps (batch polling, finalize) after the original
   button click Ìtumọ̀ Yorùbá: – browsers commonly treat that as no longer tied 
   to a real user gesture and silently block it, so nothing visibly happened even
   though the code “worked.” Replaced with the standard reliable pattern: a blank
   tab is opened synchronously at the moment of the click (still within the trusted
   user-gesture window, so never blocked), and once the finished fileÌtumọ̀ Yorùbá:’
   s URL is known, that already-open tabÌtumọ̀ Yorùbá: ’s location is set to it 
   Ìtumọ̀ Yorùbá: – setting the location of an already-open window isnÌtumọ̀ Yorùbá:’
   t subject to the same popup-blocking rules as opening a new one later.

#### 1.9.6

 * Fix (the actual cause of every import Ìtumọ̀ Yorùbá: – large or tiny Ìtumọ̀ Yorùbá:–
   crashing with a blank “심각한 오류” screen, unaffected by any of the 1.9.2-1.9.5
   fixes): the 1.9.5 rewrite of `parse_wpmpx()` left a leftover fragment of the 
   _previous_ versionÌtumọ̀ Yorùbá: ’s code sitting directly in the class body, 
   outside any function Ìtumọ̀ Yorùbá: – a bare `return` statement …

## Àkójọpọ̀ Meta

 *  Ẹ̀yà **3.0.6**
 *  Ìgbàgbọ́hùn tó kẹ́yìn **ọ̀sẹ̀ 2 sẹ́yìn**
 *  Àwọn ìgbéwọlẹ̀ tó ṣiṣẹ́ **Tó kéré sí 10**
 *  Ẹ̀yà WordPress ** 6.0 tàbí ju bẹ́ẹ̀ lọ **
 *  Dánwò dé **7.1.1**
 *  Ẹ̀yà PHP ** 7.4 tàbí ju bẹ́ẹ̀ lọ **
 *  Èdè
 * [English (US)](https://wordpress.org/plugins/lux-content-migration/)
 * Àwọn àmì
 * [export](https://yor.wordpress.org/plugins/tags/export/)[import](https://yor.wordpress.org/plugins/tags/import/)
   [media](https://yor.wordpress.org/plugins/tags/media/)[migration](https://yor.wordpress.org/plugins/tags/migration/)
   [redirect](https://yor.wordpress.org/plugins/tags/redirect/)
 *  [Ìwòye Tó Péye](https://yor.wordpress.org/plugins/lux-content-migration/advanced/)

## Àwọn ìbò

Kò sí ìwádìí tí a tíì fi ránṣẹ́.

[Your review](https://wordpress.org/support/plugin/lux-content-migration/reviews/#new-post)

[Wo gbogbo àwọn àgbéyẹ̀wò](https://wordpress.org/support/plugin/lux-content-migration/reviews/)

## Àwọn Olùkópa

 *   [ LUX Digest ](https://profiles.wordpress.org/luxsnap/)

## Ìrànlọ́wọ́

Nǹkan wà tí o fẹ́ sọ? Ṣé o nílò ìrànlọ́wọ́?

 [Wo àpéjọ ìrànlọ́wọ́](https://wordpress.org/support/plugin/lux-content-migration/)