fix(translations): backfill post_parent on child translations created before their parent - #244
Conversation
… before their parent The draft-creation paths (translate, translate-all, deploy-translation) copy post_parent onto a new translation only when the parent's translation already exists at creation time — a child translated before its parent came out parentless and was never healed. The /governance/research papers shipped root-level in 5 languages this way, so the translated research section pages rendered 0-1 cards instead of 3 (children are listed by post_parent). Add cdcf_reparent_orphaned_child_translations(): after a translation post is created, adopt any existing target-language translations of the source's children that are still orphaned (post_parent = 0). Only hierarchical post types are swept — flat types have no child pages, and their post_parent children are attachments, which must not be re-parented. Child translations that already have a parent are left untouched. Wired into all three creation paths. The 17 affected production pages (12 research papers + 5 logo-symbolism translations) were re-parented directly; this prevents recurrence regardless of translation order. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 39 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughChangesTranslation reparenting
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant TranslationHandler
participant WordPress
participant Polylang
TranslationHandler->>WordPress: Find source post children
TranslationHandler->>Polylang: Resolve target-language child translations
TranslationHandler->>WordPress: Update orphaned child post_parent values
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 9 |
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.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
wordpress/themes/cdcf-headless/includes/handlers/translate.php (1)
79-107: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReparenting results are computed but never surfaced.
$reparentedis returned but discarded at every production call site (here, and indeploy-translation.php/translate-all.php). Given this backfill exists specifically because 17 pages silently shipped root-level for months, logging or folding the reparented count/IDs into the handler'serrors/response payload (the same pattern already used for attachment-meta copy failures) would give visibility if the sweep ever silently fails to find/fix an orphan going forward.♻️ Example: surface the count via error_log or response payload
- cdcf_reparent_orphaned_child_translations($source, (int) $post_id, $target_lang); + $reparented = cdcf_reparent_orphaned_child_translations($source, (int) $post_id, $target_lang); + if ($reparented) { + error_log(sprintf('cdcf_reparent_orphaned_child_translations: reparented %d children under post %d (%s)', count($reparented), $post_id, $target_lang)); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@wordpress/themes/cdcf-headless/includes/handlers/translate.php` around lines 79 - 107, Surface the results returned by cdcf_reparent_orphaned_child_translations at every production call site, including the handlers in deploy-translation.php and translate-all.php. Log the reparented count or IDs, or incorporate them into the existing errors/response payload using the same pattern as attachment-meta copy failures, so unsuccessful or empty orphan-repair sweeps are observable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@wordpress/themes/cdcf-headless/includes/handlers/translate.php`:
- Around line 79-107: Surface the results returned by
cdcf_reparent_orphaned_child_translations at every production call site,
including the handlers in deploy-translation.php and translate-all.php. Log the
reparented count or IDs, or incorporate them into the existing errors/response
payload using the same pattern as attachment-meta copy failures, so unsuccessful
or empty orphan-repair sweeps are observable.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 673a41e6-2d84-4919-bf2b-3995bb6bfb82
📒 Files selected for processing (7)
wordpress/themes/cdcf-headless/includes/handlers/deploy-translation.phpwordpress/themes/cdcf-headless/includes/handlers/translate-all.phpwordpress/themes/cdcf-headless/includes/handlers/translate.phpwordpress/themes/cdcf-headless/tests/DeployTranslationHandlerTest.phpwordpress/themes/cdcf-headless/tests/ReparentOrphanedChildTranslationsTest.phpwordpress/themes/cdcf-headless/tests/TranslateAllHandlerTest.phpwordpress/themes/cdcf-headless/tests/TranslateHandlerTest.php
…esponses
Per review: the reparent helper's result was discarded at every call site, so
a failed wp_update_post inside the sweep was silently swallowed. The helper
now returns {reparented, errors}; translate and translate-all merge the
errors into their existing best-effort errors array (same pattern as the
attachment-meta copy failures), and deploy-translation gains an errors field
in its response carrying them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Problem
The translated
/governance/researchsection pages rendered 0–1 research cards instead of 3 (IT/ES: none; FR/PT/DE: one). The section template lists child pages bypost_parent— and 12 of the 15 translated research papers were parentless root-level pages (e.g./it/infrastruttura-dati-affidabile-…instead of/it/governance-2/ricerca/…). The 5 logo-symbolism translations had the same defect (17 orphaned pages total).Root cause
All three draft-creation paths (
translate.php,translate-all.php,deploy-translation.php) propagatepost_parentonly when the parent's translation already exists at draft-creation time:A child translated before its parent is created parentless — and nothing ever healed it afterwards. That's why exactly one FR/PT/DE paper had a parent: it happened to be translated after the section pages.
Fix
New helper
cdcf_reparent_orphaned_child_translations()inincludes/handlers/translate.php, called from all three creation paths right after the new translation exists: every existing target-language translation of the source's children that is still orphaned (post_parent = 0) is adopted under the new post.Guards:
post_parentchildren are attachments, which must not be re-parentedwp_update_postcalls are not reported as re-parentedProduction data
The 17 affected pages were re-parented directly via the REST API (research papers → their language's research section page; logo pages → their language's About page) and all affected paths + sitemaps revalidated. All 5 translated research pages now render 3 cards. This PR prevents recurrence regardless of translation order.
Tests
ReparentOrphanedChildTranslationsTest(6 cases: happy path, already-parented skip, untranslated-child skip, non-hierarchical no-op, Polylang-missing no-op, failed-update not reported)TranslateHandlerTestpinning that the creation path actually invokes the sweepis_post_type_hierarchicalstubbedfalsein the three existing handler test classes (they exercise flat posts)composer test: 595 tests, 1370 assertions, OK🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests