Extracts translatable data from an entity.
\Drupal\Core\Entity\ContentEntityInterface $entity: The entity to get the translatable data from.
array $data Translatable data.
public function extractTranslatableData(ContentEntityInterface $entity) {
$field_definitions = $entity
->getFieldDefinitions();
$exclude_field_types = [
'language',
'metatag_computed',
];
$exclude_field_names = [
'moderation_state',
];
/** @var \Drupal\content_translation\ContentTranslationManagerInterface $content_translation_manager */
$content_translation_manager = \Drupal::service('content_translation.manager');
$is_bundle_translatable = $content_translation_manager
->isEnabled($entity
->getEntityTypeId(), $entity
->bundle());
// Exclude field types from translation.
$translatable_fields = array_filter($field_definitions, function (FieldDefinitionInterface $field_definition) use ($exclude_field_types, $exclude_field_names, $is_bundle_translatable) {
if ($is_bundle_translatable) {
// Field is not translatable.
if (!$field_definition
->isTranslatable()) {
return FALSE;
}
}
elseif (!$field_definition
->getFieldStorageDefinition()
->isTranslatable()) {
return FALSE;
}
// Field type matches field types to exclude.
if (in_array($field_definition
->getType(), $exclude_field_types)) {
return FALSE;
}
// Field name matches field names to exclude.
if (in_array($field_definition
->getName(), $exclude_field_names)) {
return FALSE;
}
// User marked the field to be excluded.
if ($field_definition instanceof ThirdPartySettingsInterface) {
$is_excluded = $field_definition
->getThirdPartySetting('tmgmt_content', 'excluded', FALSE);
if ($is_excluded) {
return FALSE;
}
}
return TRUE;
});
\Drupal::moduleHandler()
->alter('tmgmt_translatable_fields', $entity, $translatable_fields);
$data = array();
foreach ($translatable_fields as $field_name => $field_definition) {
$field = $entity
->get($field_name);
$data[$field_name] = $this
->getFieldProcessor($field_definition
->getType())
->extractTranslatableData($field);
}
$embeddable_fields = static::getEmbeddableFields($entity);
foreach ($embeddable_fields as $field_name => $field_definition) {
$field = $entity
->get($field_name);
/* @var \Drupal\Core\Field\FieldItemInterface $field_item */
foreach ($field as $delta => $field_item) {
foreach ($field_item
->getProperties(TRUE) as $property_key => $property) {
// If the property is a content entity reference and it's value is
// defined, than we call this method again to get all the data.
if ($property instanceof EntityReference && $property
->getValue() instanceof ContentEntityInterface) {
// All the labels are here, to make sure we don't have empty
// labels in the UI because of no data.
$data[$field_name]['#label'] = $field_definition
->getLabel();
if (count($field) > 1) {
// More than one item, add a label for the delta.
$data[$field_name][$delta]['#label'] = t('Delta #@delta', array(
'@delta' => $delta,
));
}
// Get the referenced entity.
$referenced_entity = $property
->getValue();
// Get the source language code.
$langcode = $entity
->language()
->getId();
// If the referenced entity is translatable and has a translation
// use it instead of the default entity translation.
if ($content_translation_manager
->isEnabled($referenced_entity
->getEntityTypeId(), $referenced_entity
->bundle()) && $referenced_entity
->hasTranslation($langcode)) {
$referenced_entity = $referenced_entity
->getTranslation($langcode);
}
$data[$field_name][$delta][$property_key] = $this
->extractTranslatableData($referenced_entity);
// Use the ID of the entity to identify it later, do not rely on the
// UUID as content entities are not required to have one.
$data[$field_name][$delta][$property_key]['#id'] = $property
->getValue()
->id();
}
}
}
}
return $data;
}