public function ContentEntityHandler::onParseCdf in Acquia Content Hub 8.2
Parses the CDF representation of Content Entities.
Parameters
\Drupal\acquia_contenthub\Event\ParseCdfEntityEvent $event: Event.
Throws
\Exception
File
- src/
EventSubscriber/ Cdf/ ContentEntityHandler.php, line 152
Class
- ContentEntityHandler
- The Content entity CDF creator.
Namespace
Drupal\acquia_contenthub\EventSubscriber\CdfCode
public function onParseCdf(ParseCdfEntityEvent $event) {
$cdf = $event
->getCdf();
if ($cdf
->getType() !== 'drupal8_content_entity') {
// Bail early if this isn't a content entity.
return;
}
$default_language = $cdf
->getMetadata()['default_language'];
// If entity doesn't have any language available, throw an error.
if (empty($default_language)) {
throw new \Exception(sprintf("No language available for entity with UUID %s.", $cdf
->getUuid()));
}
$langcodes = $cdf
->getMetadata()['languages'];
$entity_values = [];
$entity_type_id = $cdf
->getAttribute('entity_type')
->getValue()['und'];
$entity_type = $this
->getEntityTypeManager()
->getDefinition($entity_type_id);
$langcode_key = $entity_type
->hasKey('langcode') ? $entity_type
->getKey('langcode') : 'langcode';
$bundle_id = $cdf
->getAttribute('bundle')
->getValue()['und'];
foreach (json_decode(base64_decode($cdf
->getMetadata()['data']), TRUE) as $field_name => $field) {
if ($field_name === 'uuid' && $event
->hasEntity() && $cdf
->getUuid() !== $event
->getEntity()
->uuid()) {
// Make sure we do not override the uuid of an existing local entity.
continue;
}
$unserialize_event = new UnserializeCdfEntityFieldEvent($entity_type, $bundle_id, $field_name, $field, $cdf
->getMetadata()['field'][$field_name], $event
->getStack());
$this->dispatcher
->dispatch(AcquiaContentHubEvents::UNSERIALIZE_CONTENT_ENTITY_FIELD, $unserialize_event);
$value = $unserialize_event
->getValue();
$entity_values = NestedArray::mergeDeep($entity_values, $value);
}
if (!$event
->isMutable()) {
return;
}
if (!$event
->hasEntity()) {
// Entities like redirect don't have default_language field
// which makes the langcode field missing in the actual values
// for entity creation leading to incorrect default language.
if (!array_key_exists($langcode_key, $entity_values[$default_language])) {
$entity_values[$default_language][$langcode_key] = $default_language;
}
// If formatted language is different from default language, change it.
$formatted_default_language = $this
->removeChannelId($default_language);
if ($formatted_default_language !== $default_language) {
$entity_values[$formatted_default_language] = $entity_values[$default_language];
$entity_values[$formatted_default_language][$langcode_key] = $formatted_default_language;
unset($entity_values[$default_language]);
}
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = $this
->getEntityTypeManager()
->getStorage($entity_type_id)
->create($entity_values[$formatted_default_language]);
unset($entity_values[$formatted_default_language]);
}
else {
$entity = $event
->getEntity();
}
foreach ($entity_values as $langcode => $values) {
if (!in_array($langcode, $langcodes)) {
continue;
}
$langcode = $this
->removeChannelId($langcode);
$values[$langcode_key] = $langcode;
if (isset($values['content_translation_source'])) {
$values['content_translation_source'] = $this
->removeChannelId($values['content_translation_source']);
}
if (!$entity
->hasTranslation($langcode)) {
try {
$entity
->addTranslation($langcode, $values);
} catch (\InvalidArgumentException $ex) {
// Still fail but provide information to locate the failing entity.
throw new \Exception(sprintf("Cannot add translation '%s' for Entity (%s, %s): %s.", $langcode, $entity
->getEntityTypeId(), $entity
->uuid(), $ex
->getMessage()));
}
}
else {
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = $entity
->getTranslation($langcode);
foreach ($entity as $field_name => $field) {
if (isset($values[$field_name])) {
$entity
->set($field_name, $values[$field_name]);
}
}
}
}
// Dispatch an event for final alteration
// if we want to add additional data from the CDF to the entity.
$unserialize_additional_metadata_event = new UnserializeAdditionalMetadataEvent($entity, $cdf);
$this->dispatcher
->dispatch(AcquiaContentHubEvents::UNSERIALIZE_ADDITIONAL_METADATA, $unserialize_additional_metadata_event);
$entity = $unserialize_additional_metadata_event
->getEntity();
$event
->setEntity($entity);
}