Translation Queue
Dieses Dokument beschreibt die Verwendung / Implementierung der Translation Queue in Pimcore-Projekten.
Configuration
Cronjob
*/5 * * * * php bin/console messenger:consume twocream_deepl_object_translation --time-limit 300
Object Translation
Beschreibt wie ein Objekt an die Translation Queue übergeben werden muss, damit dieses übersetzt werden kann. Es können alle lokalisierten Felder innerhalb eines Objektes übersetzt werden, die direkte Felder sind, sich in Blöcken befinden und die teil eines ObjectBricks sind. Damit die unterschiedlichen Felder übersetzt werden können, müssen diese auf eine bestimmte Weise an die Queue übergeben werden.
TranslateObjectMessage
<?php
public function __construct(
// Die ID des Objektes, die übersetzt werden soll
int $objectId,
// Die Sprache (Pimcore) von der übersetzt werden soll
string $pimcoreSourceLanguage,
// Die Sprachen (Pimcore) in die übersetzt werden soll,
// Werden keine Sprachen angegeben, werden ALLE Sprachen die in Pimcore konfiguriert sind übersetzt
?array $pimcoreTargetLanguages = null,
// Die Felder, die in lokalisierten Feld-containern direkt definiert werden.
// Wird kein Feld angegeben, Wird auch kein Feld übersetzt.
?array $localizedFields = null,
// Die Block-Felder innerhalb des Objektes die übersetzt werden sollen.
// Verschachtelt mit den Feldern innerhalb der Blöcke die übersetzt werden sollen.
// Wird kein Block oder Feld angegeben, wird nichts übersetzt.
?array $blockFields = null,
// Die Object-Brick Felder innerhalb eines Objektes die übersetzt werden sollen.
// In diese müssen als erstes die Bricks verschachtelt werden die übersetzt werden sollen
// und im Anschluss daran die Felder innerhalb eines Bricks, die übersetzt werden sollen.
// Wird kein Brick-Feld, Brick, oder Feld im Brick angegeben, findet keine Übersetzung statt.
?array $bricks = null,
// Aufzählung der Field-Collections-Felder und deren ausgewählten Field-Collection-Typen mit den zu übersetzenden Feldern.
// Aufbau des Array kann in dem unteren Beispiel entnommen werden.
?array $fieldCollections = null,
// Aufzählung der Objekt-Relations-Felder innerhalb des Objekts, die übersetzt werden sollen.
// Welche Felder innerhalb der Objekt-Relation übersetzt werden sollen, wird anhand der DeepL-Objekt-Konfiguration ermittelt.
// Aufbau des Array kann in dem unteren Beispiel entnommen werden.
?array $objectRelations = null,
// Die Glossar IDs, die zur Übersetzung des Objektes verwendet werden sollen
// Verschachtelt von Quellsprache zu Zielsprachen und Glossar IDs
?array $glossaries = null,
// Überspringt deine Übersetzung, sofern bereits Inhalt im Feld der jeweiligen Zielsprache vorhanden ist
bool $skipExistingTranslations = false,
// Wenn aktiv werden Texte aus der Quell-Sprache bei der Übersetzung berücksichtigt die vererbt werden.
// Diese werden dann aber in der Ziel-Sprache lokal geschrieben.
bool $allowInheritedValues = false
)
Beispiel
<?php
$localizedFields = [
'FeldInnerhalbEinesLokalisiertenFeldContainersImObjekt',
'input',
];
$blockFields = [
'BlockFeldImObjekt' => [
'FeldInnerhalbEinesLokalisiertenFeldContainer',
],
'block' => [
'blockInput',
],
];
$bricks = [
'BrickFeldImObjekt' => [
'NameDesBricksInnerhalbDesBrickFeldes' => [
'FeldInnerhalbDesBricksInnerhalbEinesLokalisiertenFeldContainer',
],
'test2' => [
'input'
],
],
];
$fieldCollections = [
'FieldCollectionFeldImObjekt' => [
'NameDerAusgewähltenFieldCollection' => [
'FeldInnerhalbDerFieldCollectionA',
'FeldInnerhalbDerFieldCollectionB',
],
],
];
$objectRelations = [
'RelationsFeldA',
'RelationsFeldB',
'RelationsFeldC',
];
$deepLGlossaryIds = [
'de' => [
'pl_PL' => 'f31ee103-a555-4085-8864-86894d506d27',
],
];
new TranslateObjectMessage(
61,
'de',
['en', 'pl_PL'],
$localizedFields,
$blockFields,
$bricks,
$fieldCollections,
$relations,
$deepLGlossaryIds
);
Verwenden der Message Queue
Wir benötigen den Symfony Message Bus innerhalb des Controllers, EventListeners, usw. um eine Nachricht zu abzusenden. Über den TranslationConfigurationLoader erhalten wir die DeepL-Objekt-Konfiguration zu der jeweiligen Objekt-Klasse.
<?php
use Pimcore\Controller\FrontendController;
use Pimcore\Model\DataObject;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
use Twocream\CoreBundle\Helper\EditLockHelper;
use Twocream\DeepLBundle\Exception\DeepLConfigurationNotFoundException;
use Twocream\DeepLBundle\Helper\TranslationConfigurationLoader;
use Twocream\DeepLBundle\MessageQueue\TranslateObjectMessage;
class DefaultController extends FrontendController
{
public function defaultAction(
Request $request,
// Der MessageBus ist ein Service und kann (sollte)
// über den Constructor injected werden.
MessageBusInterface $messageBus
): Response {
$object = DataObject::getById($request->get('objectId'));
// Über den TranslationConfigurationLoader können wir die Yaml-Konfiguration der DeepL-Objekt-Konfiguration anfragen.
$configuration = TranslationConfigurationLoader::getDataObjectConfiguration($object::class);
if ($configuration === null) {
throw new DeepLConfigurationNotFoundException(
sprintf('No configuration found for %s', $object::class)
);
}
$sourceLanguage = $request->get('sourceLanguage');
$targetLanguage = $request->get('targetLanguage');
$glossaryId = $request->get('glossaryId') ?? null;
$skipExistingTranslation = $request->get('skipExistingTranslation') ?? false;
$allowInheritedValues = $request->get('allowInheritedValues') ?? false;
$fields = $configuration['fields'] ?? null;
$blocks = $configuration['blocks'] ?? null;
$bricks = $configuration['bricks'] ?? null;
$fieldCollections = $configuration['fieldCollections'] ?? null;
$objectRelations = $configuration['relations'] ?? null;
$deeplGlossaryId[$sourceLanguage][$targetLanguage] = $glossaryId;
// OPTIONAL (DRINGEND EMPFOHLEN)
// Die Translation Queue führt immer ein "Release" aus.
// Damit das Objekt während der Verarbeitung im Backend
// nicht geöffnet werden kann / eine "wird Bearbeitet"
// Nachricht erscheint.
// Mehr dazu in der Doku des Core-Bundle.
EditLockHelper::lock(
$object->getId(),
'object',
'translation'
);
// Der MessageBus hat eine Methode. Mittels dispatch()
// wird die Message der Queue hinzugefügt und verarbeitet
$messageBus->dispatch(new TranslateObjectMessage(
$object->getId(),
$sourceLanguage,
[$targetLanguage],
$fields,
$blocks,
$bricks,
$fieldCollections,
$relations,
$deepLGlossaryId,
$skipExistingTranslation,
$allowInheritedValues
));
// ...
}
}