Draft: Refactor entity translation into a shared orchestrator service

Summary

This MR starts the ai_translate refactoring needed to support a shared translation workflow across multiple entrypoints. It introduces a shared EntityTranslationOrchestrator service and moves duplicated entity-translation logic out of the UI controller and Drush command into that service. The goal is to establish one reusable path for entity translation instead of maintaining separate orchestration in each entrypoint.

What changed

Added:

  • EntityTranslationOrchestratorInterface
  • EntityTranslationOrchestrator
  • EntityTranslationResult

Updated:

  • src/Controller/AiTranslateController.php
  • src/Drush/AiTranslateCommands.php
  • ai_translate.services.yml

Also added test coverage:

  • tests/src/Unit/EntityTranslationOrchestratorTest.php
  • tests/src/Kernel/EntityTranslationOrchestratorKernelTest.php

And added:

  • composer.json
  • phpunit.bootstrap.php
  • phpunit.xml

The PHPUnit bootstrap/config is needed because the default Drupal test bootstrap can resolve Drupal\ai_translate\... to the bundled ai_translate copy inside drupal/ai instead of this project checkout. These files ensure tests run against the code under review.

Behavior / parity notes

This first draft keeps a few cleanup improvements instead of preserving legacy behavior 1:1.

Drush field failure handling

Previously, Drush could partially translate a field if one column failed partway through. Now, failed fields are skipped rather than partially translated.

Drush now respects translation_status

Previously, the draft/unpublished translation-status behavior was only applied in the UI flow. Now, Drush uses the same shared save logic and also respects that configuration.

Drush messaging changed

Previously, Drush emitted generic translation errors during field/column failures. Now, successful entity saves still report success, with warnings when some fields could not be translated.

Language edge cases

Language handling is now more explicit in the shared orchestrator, so invalid/unknown language edge cases may behave slightly differently than before. For this first review draft, I am intentionally keeping these cleanups unless reviewers prefer Phase 1 to preserve behavior 1:1.

Testing

Tested locally with:

  • ddev phpunit tests/src/Unit/EntityTranslationOrchestratorTest.php
  • ddev phpunit tests/src/Kernel/EntityTranslationOrchestratorKernelTest.php Both pass.
Edited by Sven Decabooter

Merge request reports

Loading