Skip to content

Instantly share code, notes, and snippets.

@chx
Created December 6, 2018 19:04
Show Gist options
  • Save chx/8d401fb67ceccaf04a6cc9932cc90c66 to your computer and use it in GitHub Desktop.
Save chx/8d401fb67ceccaf04a6cc9932cc90c66 to your computer and use it in GitHub Desktop.
Helper for migrations with paragraphs
<?php
namespace Drupal\sd8;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
/**
* Convert an entity to an array and back.
*/
class EntityArrayHelper {
/**
* Convert an array to entity or entities.
*
* @param $entityTypeId
* The entity type id.
* @param array $data
* Similar to what can be passed ContentEntityStorageInterface::create()
* but entity references can be inlined and they will be autocreated. The
* reference entity type can be specified by an entity_type key.
* Run static::entity2array() for examples.
*
* @return \Drupal\Core\Entity\ContentEntityInterface
*/
public static function array2entity($entityTypeId, array $data) {
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = \Drupal::entityTypeManager()->getStorage($entityTypeId)->create($data);
foreach ($entity->getFieldDefinitions() as $fieldName => $fieldDefinition) {
$fieldItemList = $entity->get($fieldName);
if (isset($data[$fieldName]) && $fieldItemList instanceof EntityReferenceFieldItemListInterface) {
if (!isset($data[$fieldName][0])) {
$data[$fieldName] = [$data[$fieldName]];
}
foreach ($data[$fieldName] as $referencedData) {
if (!isset($referencedData['target_id'])) {
$referencedEntityTypeId = $referencedData['entity_type'] ?? $fieldDefinition->getSetting('target_type');
$fieldItemList->appendItem(static::array2entity($referencedEntityTypeId, $referencedData));
}
}
}
}
return $entity;
}
/**
* Convert an entity to an array, inlining referred entities.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* Entity to be converted.
* @param array $inline
* Entity type IDs to be inlined.
*
* @return array
* Similar to $entity->toArray() but the values for entity references are
* not target_id but the entire referenced $entity->toArray() for types in
* $expand. As the default value of $inline shows, this is very useful for
* paragraphs.
*/
public static function entity2array(ContentEntityInterface $entity, array $inline = ['paragraph']) {
$array = $entity->toArray();
foreach ($entity->getFields() as $fieldName => $fieldItemList) {
if ($fieldItemList instanceof EntityReferenceFieldItemListInterface) {
foreach ($fieldItemList->referencedEntities() as $delta => $referencedEntity) {
if ($referencedEntity instanceof ContentEntityInterface && array_search($referencedEntity->getEntityTypeId(), $inline) !== FALSE) {
$array[$fieldName][$delta] = static::inlineEntity($referencedEntity, $inline);
}
}
}
}
return $array;
}
/**
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
*
* @param array $inline
*
* @return array
*/
protected static function inlineEntity(ContentEntityInterface $entity, array $inline) {
$array = static::entity2array($entity, $inline);
$array['entity_type'] = $entity->getEntityTypeId();
$keys = $entity->getEntityType()->getKeys();
unset($array[$keys['id']], $array[$keys['revision']], $array[$keys['uuid']]);
return $array;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment