Using the service
The module is one service, entity_change_default_language. The operation, the Drush commands and the queue worker all call it, and you can call it from your own code. Code can also inject it by its interface, EntityChangeDefaultLanguageInterface.
Get the service and call it
Section titled “Get the service and call it”/** @var \Drupal\entity_change_default_language\EntityChangeDefaultLanguageInterface $service */$service = \Drupal::service('entity_change_default_language');$node = \Drupal\node\Entity\Node::load(2);
// Make Spanish the default language, keeping every translation.$changed = $service->update($node, 'es');
// Make French the default, creating it if missing, keep only English// besides it, and follow the tags field.$changed = $service->update($node, 'fr', TRUE, ['en'], [ 'follow_fields' => ['field_tags'],]);The method signature is update($entity, $default_langcode, $create = FALSE, ?array $langcodes = NULL, array $options = []). It returns TRUE on success and FALSE otherwise. An exception or error is logged to the entity_change_default_language channel and is not thrown. The other cases that return FALSE are listed below.
Arguments
Section titled “Arguments”| Argument | Meaning |
|---|---|
$entity |
The content entity to change. It must be translatable, and its entity type must be enabled in the settings. |
$default_langcode |
The language that becomes the default, for example es. |
$create |
When TRUE and the entity has no translation in the target language, the current default values are copied into a new translation first. When FALSE, a missing translation makes the call return FALSE. |
$langcodes |
The translations to keep. NULL, the default, keeps every translation, the old default included. An empty array removes every translation except the new default. A list keeps those translations, and the old default only if it is listed. |
$options['follow_fields'] |
Names of reference fields whose referenced entities change their default language too. Paragraphs and other entity reference revisions fields are always followed. Other references keep their own language unless named here. |
What happens, in order
Section titled “What happens, in order”- The call returns
FALSE, and logs a warning, when the settings do not enable the entity type of the entity passed in. Composites reached on the way follow their host whatever their type. - The call returns
FALSEwhen the entity is not translatable, andTRUEat once when it is already in the target language. - The call returns
FALSEwhen the target translation is missing and$createisFALSE. - The service follows the composite fields and the fields named in
follow_fields, and calls itself on each referenced content entity with the same arguments. A field infollow_fieldswhose target entity type is not enabled is skipped with a warning, and the rest of the change goes on. - The target translation is removed and the entity is saved, then its values are written onto the original translation, which becomes the new default.
- The old default language is added back as a translation when
$langcodesisNULLor lists it. - Every translation not kept is removed, and the entity is saved again without a new revision.
Failures and transactions
Section titled “Failures and transactions”The whole change, referenced entities included, runs in one database transaction. Any exception or error rolls it all back, is logged, and makes the call return FALSE.
- A referenced entity that throws stops the change of its host.
- Inside a transaction of your own, the change is a savepoint, and it becomes permanent only when your transaction commits.
- After a failed call, reload the entity you passed in, since the object may still hold the unsaved values.
- Each call follows a cycle of references only once, and the next call starts afresh.
Things to know
Section titled “Things to know”- The path alias moves to the new default language. When the old default is dropped and the new default translation has no alias, it takes the alias of the old default. A language neutral alias is left as it is.
- The current revision is overwritten in place. Older revisions keep the old language and nothing is written to a revision log.
- The saves mark the entity as syncing, so code that skips work while an entity is syncing skips it here too.