protected function ContentEntityCdfNormalizer::addFieldsToContentHubEntity in Acquia Content Hub 8
Get fields from given entity.
Get the fields from a given entity and add them to the given content hub entity object.
Parameters
\Acquia\ContentHubClient\Entity $contenthub_entity: The Content Hub Entity that will contain all the Drupal entity fields.
\Drupal\Core\Entity\ContentEntityInterface $entity: The Drupal Entity.
string $langcode: The language that we are parsing.
array $context: Additional Context such as the account.
Return value
\Acquia\ContentHubClient\Entity The Content Hub Entity with all the data in it.
Throws
\Drupal\acquia_contenthub\ContentHubException The Exception will be thrown if something is going awol.
1 call to ContentEntityCdfNormalizer::addFieldsToContentHubEntity()
- ContentEntityCdfNormalizer::normalize in src/
Normalizer/ ContentEntityCdfNormalizer.php - Normalizes an object into a set of arrays/scalars.
File
- src/
Normalizer/ ContentEntityCdfNormalizer.php, line 398
Class
- ContentEntityCdfNormalizer
- Converts the Drupal entity object to a Acquia Content Hub CDF array.
Namespace
Drupal\acquia_contenthub\NormalizerCode
protected function addFieldsToContentHubEntity(ContentHubEntity $contenthub_entity, ContentEntityInterface $entity, $langcode = 'und', array $context = []) {
/** @var \Drupal\Core\Field\FieldItemListInterface[] $fields */
$fields = $entity
->getFields();
// Get our field mapping. This maps drupal field types to Content Hub
// attribute types.
$type_mapping = $this
->getFieldTypeMapping($entity);
// Ignore the entity ID and revision ID.
// Excluded comes here.
$excluded_fields = $this
->excludedProperties($entity);
foreach ($fields as $name => $field) {
// Continue if this is an excluded field or the current user does not
// have access to view it.
if (in_array($field
->getFieldDefinition()
->getName(), $excluded_fields) || !$field
->access('view', $context['account'])) {
continue;
}
// Get the plain version of the field in regular json.
if ($name === 'metatag') {
$serialized_field = $this
->getSerializer()
->normalize($field, 'json', $context);
}
else {
$serialized_field = $field
->getValue();
}
$items = $serialized_field;
// Given that vocabularies are configuration entities, they are not
// supported in Content Hub. Instead we use the vocabulary machine name
// as mechanism to syndicate and import them in the right vocabulary.
if ($name === 'vid' && $entity
->getEntityTypeId() === 'taxonomy_term') {
// Initialize vocabulary attribute if it doesn't exist yet.
if (!$contenthub_entity
->getAttribute('vocabulary')) {
$attribute = new Attribute(Attribute::TYPE_STRING);
$attribute
->setValue($items[0]['target_id'], $langcode);
$contenthub_entity
->setAttribute('vocabulary', $attribute);
}
else {
$contenthub_entity
->setAttributeValue('vocabulary', $items[0]['target_id'], $langcode);
}
continue;
}
if ($entity
->get($name)
->getFieldDefinition()
->getType() === 'path' && version_compare(\Drupal::VERSION, '8.8.0', '>=')) {
$storage = $this->entityTypeManager
->getStorage('path_alias');
$aliases = $storage
->loadByProperties([
'path' => "/{$entity->toUrl()->getInternalPath()}",
]);
if ($aliases) {
$alias_uuid_attribute = new Attribute(Attribute::TYPE_ARRAY_REFERENCE);
$uuids = [];
foreach ($aliases as $alias) {
$uuids[$alias
->language()
->getId()][] = $alias
->uuid();
}
foreach ($uuids as $uuid_langcode => $values) {
$alias_uuid_attribute
->setValue($values, $uuid_langcode);
}
$contenthub_entity
->setAttribute('path_uuid', $alias_uuid_attribute);
}
}
// For path-aliases adding a UUID of the target entity.
/** @var \Drupal\path_alias\Entity\PathAlias $entity */
if ($name === 'path' && $entity
->getEntityTypeId() === 'path_alias') {
// Extracting entities from route.
$route_params = Url::fromUserInput($entity
->getPath())
->getRouteParameters();
$target_entity_uuid_attribute = new Attribute(Attribute::TYPE_ARRAY_REFERENCE);
$target_entity_type_attribute = new Attribute(Attribute::TYPE_STRING);
foreach ($route_params as $entity_type_id => $entity_id) {
if (!$this->entityTypeManager
->hasDefinition($entity_type_id)) {
// Skip in case of unknown entity type.
continue;
}
$entity_from_route = $this->entityTypeManager
->getStorage($entity_type_id)
->load($entity_id);
if ($entity
->getPath() !== "/{$entity_from_route->toUrl()->getInternalPath()}") {
// Skip mismatched entities.
continue;
}
$target_entity_uuid_attribute
->setValue([
$entity_from_route
->uuid(),
], $langcode);
$target_entity_type_attribute
->setValue($entity_type_id, $langcode);
}
$contenthub_entity
->setAttribute('title', (new Attribute(Attribute::TYPE_STRING))
->setValue($entity
->getAlias(), $langcode));
$contenthub_entity
->setAttribute('path_uuid', $target_entity_uuid_attribute);
$contenthub_entity
->setAttribute('target_entity_type', $target_entity_type_attribute);
}
// To make it work with Paragraphs, we are converting the field
// 'parent_id' to 'parent_uuid' because Content Hub cannot deal with
// entity_id information.
if ($name === 'parent_id' && $entity
->getEntityTypeId() === 'paragraph') {
$attribute = new Attribute(Attribute::TYPE_STRING);
$parent_id = $items[0]['value'];
$parent_type = $fields['parent_type']
->getValue()[0]['value'];
$parent = $this->entityTypeManager
->getStorage($parent_type)
->load($parent_id);
$parent_uuid = $parent
->uuid();
$attribute
->setValue($parent_uuid, $langcode);
$contenthub_entity
->setAttribute('parent_uuid', $attribute);
continue;
}
if ($name == 'bundle' && $entity
->getEntityTypeId() === 'media') {
$attribute = new Attribute(Attribute::TYPE_ARRAY_STRING);
$attribute
->setValue([
$entity
->bundle(),
], $langcode);
$contenthub_entity
->setAttribute('bundle', $attribute);
continue;
}
// Try to map it to a known field type.
$field_type = $field
->getFieldDefinition()
->getType();
// Go to the fallback data type when the field type is not known.
$type = $type_mapping['fallback'];
if (isset($type_mapping[$name])) {
$type = $type_mapping[$name];
}
elseif (isset($type_mapping[$field_type])) {
// Set it to the fallback type which is string.
$type = $type_mapping[$field_type];
}
if ($type == NULL) {
continue;
}
$values = [];
if ($field instanceof EntityReferenceFieldItemListInterface) {
// Get taxonomy parent terms.
if ($name === 'parent' && $entity
->getEntityTypeId() === 'taxonomy_term') {
$storage = $this->entityTypeManager
->getStorage('taxonomy_term');
$referenced_entities = $storage
->loadParents($entity
->id());
}
else {
/** @var \Drupal\Core\Entity\EntityInterface[] $referenced_entities */
$referenced_entities = $field
->referencedEntities();
}
$values[$langcode] = [];
foreach ($referenced_entities as $key => $referenced_entity) {
// In the case of images/files, etc... we need to add the assets.
$file_types = [
'image',
'file',
'video',
];
$type_names = [
'type',
'bundle',
];
// Special case for type as we do not want the reference for the
// bundle. In additional to the type field a media entity has a
// bundle field which stores a media bundle configuration entity UUID.
if (in_array($name, $type_names, TRUE) && $referenced_entity instanceof ConfigEntityBase) {
$values[$langcode][] = $referenced_entity
->id();
}
elseif (in_array($field_type, $file_types)) {
// If this is a file type, then add the asset to the CDF.
$uuid_token = '[' . $referenced_entity
->uuid() . ']';
$asset_url = file_create_url($referenced_entity
->getFileUri());
$asset = new Asset();
$asset
->setUrl($asset_url);
$asset
->setReplaceToken($uuid_token);
$contenthub_entity
->addAsset($asset);
// Now add the value.
// Notice that we are including the "alt" and "title" attributes
// from the file entity in the field data.
$data = [
'alt' => isset($items[$key]['alt']) ? $items[$key]['alt'] : '',
'title' => isset($items[$key]['title']) ? $items[$key]['title'] : '',
'target_uuid' => $uuid_token,
];
$values[$langcode][] = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
}
else {
$values[$langcode][] = $referenced_entity
->uuid();
}
}
}
else {
// If there's nothing in this field, just set it to NULL.
if ($items == NULL) {
$values[$langcode] = NULL;
}
else {
// Only if it is a link type.
if ($link_field = ContentHubEntityLinkFieldHandler::load($field)
->validate()) {
$items = $link_field
->normalizeItems($items);
}
// Loop over the items to get the values for each field.
foreach ($items as $item) {
// Hotfix.
// @todo Find a better solution for this.
if (isset($item['_attributes'])) {
unset($item['_attributes']);
}
$keys = is_array($item) ? array_keys($item) : [];
if (count($keys) == 1 && isset($item['value'])) {
$value = $item['value'];
}
else {
if ($field instanceof PathFieldItemList) {
$item = $field
->first()
->getValue();
$item['pid'] = "";
$item['source'] = "";
}
$value = json_encode($item, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
}
$values[$langcode][] = $value;
}
}
}
try {
$attribute = new Attribute($type);
} catch (\Exception $e) {
$args['%type'] = $type;
$message = new FormattableMarkup('No type could be registered for %type.', $args);
throw new ContentHubException($message);
}
if (strstr($type, 'array')) {
$attribute
->setValues($values);
}
else {
$value = array_pop($values[$langcode]);
$attribute
->setValue($value, $langcode);
}
// If attribute exists already, append to the existing values.
if (!empty($contenthub_entity
->getAttribute($name))) {
$existing_attribute = $contenthub_entity
->getAttribute($name);
$this
->appendToAttribute($existing_attribute, $attribute
->getValues());
$attribute = $existing_attribute;
}
// Add it to our contenthub entity.
$contenthub_entity
->setAttribute($name, $attribute);
}
// Allow alterations of the CDF to happen.
$context['entity'] = $entity;
$context['langcode'] = $langcode;
$this->moduleHandler
->alter('acquia_contenthub_cdf', $contenthub_entity, $context);
// Adds the entity URL to CDF.
$value = NULL;
if (empty($contenthub_entity
->getAttribute('url'))) {
switch ($entity
->getEntityTypeId()) {
case 'file':
$value = file_create_url($entity
->getFileUri());
$filepath_attribute = new Attribute(Attribute::TYPE_STRING);
$contenthub_entity
->setAttribute('_filepath', $filepath_attribute
->setValue($entity
->getFileUri()));
break;
default:
// Get entity URL.
if (!$entity
->isNew() && $entity
->hasLinkTemplate('canonical')) {
$url = $entity
->toUrl();
$url
->setAbsolute(TRUE);
$value = $url
->toString();
}
break;
}
if (isset($value)) {
$url_attribute = new Attribute(Attribute::TYPE_STRING);
$contenthub_entity
->setAttribute('url', $url_attribute
->setValue($value, $langcode));
}
}
return $contenthub_entity;
}