Skip to content

fix(polylang): repair single-post machine translation#27

Merged
oxyc merged 1 commit into
masterfrom
fix/machine-translate-single-post
Jun 15, 2026
Merged

fix(polylang): repair single-post machine translation#27
oxyc merged 1 commit into
masterfrom
fix/machine-translate-single-post

Conversation

@oxyc

@oxyc oxyc commented Jun 15, 2026

Copy link
Copy Markdown
Member

Problem

gds/translations-machine failed on the single-post path while the bulk string path worked fine. Two separate bugs in MachineTranslateAbility::translatePost():

  1. Blocks::__construct(): Argument #1 ($id) must be of type int, null given
    PLL_Export_Data_From_Posts::send_to_export() expects WP_Post[], but we passed [$postId] (an int). Inside Polylang Pro the int reaches the ACF block dispatcher as new Blocks($post->ID)->ID on an int is null, so it throws a TypeError.

  2. Call to undefined function get_default_post_to_edit()
    Polylang's save path calls get_default_post_to_edit(), which lives in wp-admin/includes/post.php and isn't loaded in the REST/MCP/CLI context this ability runs in.

Fix

  1. Pass the $post WP_Post object we already fetched, instead of the int ID.
  2. Guarded require_once ABSPATH.'wp-admin/includes/post.php' — the same pattern already used in ManageRevisionsAbility and MediaUploadAbility.

Tests

Adds test_machine_translate_export_accepts_post_object, which drives the same export path the ability uses with a block post. It reproduces bug 1 without needing DeepL. It skips when Polylang Pro is absent (e.g. wp-env's free Polylang) and runs under DDEV where Pro is installed.

Verification

Confirmed end-to-end against real DeepL:

Path Result
New translation (EN page w/ ACF blocks → FI) ✅ created
Re-translate existing target (overwrite branch) ✅ updated in place, no duplicate
Different target language (SV) ✅ created
Custom post type with ACF meta (Case → FI) ✅ created (other dispatcher hook)
Undo / revert ✅ clean restore

🤖 Generated with Claude Code

gds/translations-machine crashed on the single-post path (string and
post-collection paths were unaffected) due to two bugs in
MachineTranslateAbility::translatePost():

1. send_to_export() expects WP_Post[], but we passed [$postId] (int).
   The int reached Polylang Pro's ACF block dispatcher as
   `new Blocks($post->ID)` where `->ID` on an int is null, throwing a
   TypeError. Pass the WP_Post object we already fetched.

2. Polylang's save path calls get_default_post_to_edit(), a
   wp-admin/includes/post.php function not loaded in the REST/MCP/CLI
   context. Guarded require_once, matching ManageRevisionsAbility and
   MediaUploadAbility.

Adds a regression test driving the export path with a block post; it
reproduces bug 1 without needing DeepL (skips when Polylang Pro is
absent, e.g. under wp-env's free Polylang; runs under DDEV).

Verified end-to-end against DeepL: new translation, overwrite of an
existing translation, a second target language, a custom post type with
ACF meta, and undo/revert all succeed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@oxyc oxyc merged commit dc585f5 into master Jun 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant