Skip to content

fix(submissions): defer translation enqueue to shutdown action#227

Merged
JohnRDOrazio merged 1 commit into
mainfrom
fix/submission-publish-defer-translate-enqueue
Jun 16, 2026
Merged

fix(submissions): defer translation enqueue to shutdown action#227
JohnRDOrazio merged 1 commit into
mainfrom
fix/submission-publish-defer-translate-enqueue

Conversation

@JohnRDOrazio

@JohnRDOrazio JohnRDOrazio commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

  • Move cdcf_enqueue_translations_for_submission() out of the synchronous transition_post_status callback into a deferred shutdown handler so our pll_save_post_translations() call no longer runs inside Polylang's own save_post chain for the source post and each freshly-inserted draft, where the multi-post group save silently fails to persist.
  • Updated the existing publish-hook test to assert the new contract: cdcf_enqueue_translations_for_submission must NOT be invoked synchronously inside transition_post_status, the hook must register a shutdown callback, and driving that callback must dispatch with ($source_id, $post_type).

Production trigger

A public-submission project published 2026-06-16 created and worker-translated all 6 language siblings, but the Polylang translation group came out empty on every post and the Phase 0 attachment translation siblings were never created. Re-running the identical pll_save_post_translations() call from outside the save chain (via /cdcf/v1/link-translations) persisted on the first attempt — confirming this is a context bug, not a Polylang plugin defect. State on production was recovered manually via /cdcf/v1/link-translations + /cdcf/v1/translate-all on the attachment + per-translation featured_media reassignment + revalidation; this PR closes the underlying gap so the next public-submission publish doesn't repeat the same recovery dance.

Test plan

  • composer test --working-dir=wordpress/themes/cdcf-headless — 578/578 pass, including the updated test_publish_hook_defers_enqueue_to_shutdown_for_public_submission
  • composer test --working-dir=wordpress/plugins/cdcf-redis-translations — 30/30 pass
  • Verified RED first: the updated test fails against main at the "must NOT invoke synchronously" assertion before the fix is applied
  • After merge: deploy with gh workflow run deploy.yml -f environment=production, then publish a fresh public-submission project with a featured image and verify (a) the Polylang group is linked across all 6 siblings AND (b) the attachment has 5 language siblings linked

🤖 Generated with Claude Code

Summary by CodeRabbit

Bug Fixes

  • Fixed translation persistence during content publication. The system now reliably maintains translation group consistency and prevents loss of translation associations when publishing content. This is particularly important in scenarios involving complex or nested content operations that could previously result in incomplete translation groups or inconsistent translation state.

Move cdcf_enqueue_translations_for_submission() out of the synchronous
transition_post_status callback into a deferred shutdown handler.

Running the multi-post Polylang group save inline puts our nested
wp_insert_post + pll_save_post_translations calls inside Polylang's
own save_post chain for the source post and each freshly-inserted
draft, where the group save silently fails to persist — same call
shape from a REST endpoint outside any post-save chain persists on
the first try.

Production occurrence 2026-06-16: a public-submission project
publish created and worker-translated all 6 language siblings but
the Polylang translation group came out empty on every post and the
Phase 0 attachment translation siblings were never created.
Recovery used /cdcf/v1/link-translations and /cdcf/v1/translate-all,
both of which run outside the save chain.

Test updated to assert the new contract: the publish hook MUST
register a shutdown callback and MUST NOT invoke the enqueue
synchronously. Driving the registered callback continues to exercise
the (source_id, post_type) dispatch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bc0fc4e8-af97-4248-9a1d-f1759c8cc447

📥 Commits

Reviewing files that changed from the base of the PR and between bc06fcd and 51b7b16.

📒 Files selected for processing (2)
  • wordpress/themes/cdcf-headless/includes/admin/submission-lifecycle.php
  • wordpress/themes/cdcf-headless/tests/SubmissionLifecycleTest.php

📝 Walkthrough

Walkthrough

cdcf_enqueue_translations_on_publish() is changed to defer the call to cdcf_enqueue_translations_for_submission() from the synchronous transition_post_status callback to a shutdown-registered closure, capturing $post_type. The docblock is expanded to document the Polylang lost-update failure that motivated this. The corresponding test is renamed and rewritten to capture the shutdown callback, assert no synchronous enqueue, then drive the callback and verify the deferred call.

Changes

Defer translation enqueue to shutdown hook

Layer / File(s) Summary
Shutdown deferral in cdcf_enqueue_translations_on_publish
wordpress/themes/cdcf-headless/includes/admin/submission-lifecycle.php
Docblock extended to document the Polylang save-chain lost-update failure; immediate call to cdcf_enqueue_translations_for_submission replaced with a static closure registered on the shutdown action that captures $post_type.
Test verifies deferred shutdown behavior
wordpress/themes/cdcf-headless/tests/SubmissionLifecycleTest.php
Test renamed to test_publish_hook_defers_enqueue_to_shutdown_for_public_submission; stubs Polylang/meta, captures the add_action('shutdown', ...) callback, asserts no synchronous enqueue, then invokes the captured closure and validates the deferred [source_id, post_type] call.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • CatholicOS/cdcf-website#203: Changes how cdcf_enqueue_translations_for_submission() performs the Polylang atomic pll_save_post_translations—directly addresses the same translation-group persistence issue that motivated deferring the call to shutdown.
  • CatholicOS/cdcf-website#37: Originally added the transition_post_status hook and cdcf_enqueue_translations_for_submission() that this PR modifies the call timing of.
  • CatholicOS/cdcf-website#208: Adds Phase 0 featured-attachment helpers inside cdcf_enqueue_translations_for_submission(), the same function whose invocation point is deferred by this PR.

Poem

🐇 Hop, hop, not now dear friend,
Wait till the save chain finds its end.
At shutdown we'll call the enqueue right,
No Polylang group lost in the night.
Deferred with care, translations persist — delight! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'fix(submissions): defer translation enqueue to shutdown action' accurately describes the main change: moving translation enqueue logic to the shutdown hook to fix persistence issues.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/submission-publish-defer-translate-enqueue

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity

Metric Results
Complexity 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@JohnRDOrazio JohnRDOrazio merged commit a4eca45 into main Jun 16, 2026
13 checks passed
@JohnRDOrazio JohnRDOrazio deleted the fix/submission-publish-defer-translate-enqueue branch June 16, 2026 18:50
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.

2 participants