=== Translation Cleaner for WPML ===
Contributors: klemensh
Tags: wpml, translation, multilingual, cleanup, maintenance
Slug: translation-cleaner-for-wpml
Requires at least: 5.9
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Find and fix WPML data issues — orphaned translations, misplaced originals, and swapped original flags.

== Description ==

Translation Cleaner for WPML helps you keep your multilingual WordPress site clean by identifying and fixing three common categories of WPML data corruption, all from a single admin tool under **Tools → Translation Cleaner for WPML**.

**Module 1 — Orphan Translations**

Finds translated posts whose main-language counterpart no longer exists (deleted or trashed). These orphaned records consume storage, clutter your admin, and break WPML's translation groups.

* Bulk action: Move to Trash (reversible) or Permanently Delete
* Reason codes per row: *Missing original*, *Original deleted*, *Original trashed*
* Every deletion is re-validated immediately before execution — if the original was restored since the scan, the item is skipped

**Module 2 — Misplaced Originals**

Finds posts that WPML treats as originals (`source_language_code = NULL`) but are registered under a language that is not your main language — with no main-language version in that translation group at all.

This typically happens when content is created directly in a secondary language without going through the main language first. Left uncorrected, these posts can cause translation workflow issues and incorrect language flags.

* Per-row fix: select the post's actual language from a dropdown and reassign it — no bulk guessing

**Module 3 — Swapped Originals**

Finds cases where a secondary-language post carries the "original" flag while a live main-language version exists in the same translation group. WPML incorrectly treats the secondary post as the source, which inverts the translation relationship for both posts.

* Per-row fix: one click to promote the main-language post to original and demote the secondary to a translation — the trid (translation group) is preserved

**Common features across all modules**

* Scan all WPML-tracked post types, including non-public types like `nav_menu_item`
* Filter by post type and main language
* Detailed results table with sort, search, and pagination
* Export results to CSV before taking any action
* Developer hooks: `wmtc_protected_post_ids`, `wmtc_orphan_results`, `wmtc_before_delete`, `wmtc_after_delete`

**Requirements**

* WPML must be installed and active

== Installation ==

1. Upload the `wpml-translation-cleaner` folder to `/wp-content/plugins/`
2. Activate the plugin through **Plugins → Installed Plugins**
3. Navigate to **Tools → Translation Cleaner for WPML**
4. Select a module, choose your main language and post types, then click **Run Scan**

== Frequently Asked Questions ==

= Does this work with WooCommerce Multilingual (WCML)? =

Yes. The scanners detect issues regardless of how WPML or WCML registered the content, including products managed in WCML's independent mode.

= Will it delete or modify content incorrectly? =

For orphan deletions, every item is re-validated against a fresh database scan immediately before the action runs. For reassignment actions (Misplaced Originals, Swapped Originals), the fix is performed via WPML's own `wpml_set_element_language_details` API — no raw data is modified outside of WPML's own logic.

= Can I undo a deletion? =

Use **Move to Trash** for reversible cleanup. **Permanently Delete** is irreversible — always export a CSV and back up your database first.

= Can I undo a language reassignment? =

Not automatically. Before running fixes in bulk, export a CSV so you have a record of the original state. The CSV can be used as a reference to manually revert if needed.

= What post types are scanned? =

All post types that WPML is tracking in `icl_translations`, including `nav_menu_item` which is a common source of orphaned translations invisible to standard WordPress post type queries.

= How do I exclude specific posts from cleanup? =

Use the `wmtc_protected_post_ids` filter:

`add_filter( 'wmtc_protected_post_ids', function( $ids ) { $ids[] = 42; return $ids; } );`

= Is this plugin affiliated with WPML or OnTheGoSystems? =

No. This is an independent tool built to work alongside WPML. WPML is a trademark of OnTheGoSystems.

== Screenshots ==

1. Module overview — three cards for Orphan Translations, Misplaced Originals, and Swapped Originals
2. Orphan Translations scan results with reason codes and bulk actions
3. Misplaced Originals results with per-row language reassignment dropdown
4. Swapped Originals results with per-row Fix Original action

== Changelog ==

= 1.0.0 =
* Initial release
* Module: Orphan Translations — find and delete orphaned translation posts
* Module: Misplaced Originals — find and reassign posts flagged as originals in the wrong language
* Module: Swapped Originals — fix inverted original/translation relationships within a translation group

== Upgrade Notice ==

= 1.0.0 =
Initial release.
