You are here

public function ContentLoader::populateField in YAML Content 8

Populate field content into the provided field.

@todo Handle field data types more dynamically with typed data.

Parameters

object $field: The entity field object.

array $field_data: The field data.

Throws

\Drupal\Core\Entity\EntityStorageException

1 call to ContentLoader::populateField()
ContentLoader::populateEntityFields in src/ContentLoader/ContentLoader.php
Populate entity field data into an entity object.

File

src/ContentLoader/ContentLoader.php, line 484

Class

ContentLoader
ContentLoader class for parsing and importing YAML content.

Namespace

Drupal\yaml_content\ContentLoader

Code

public function populateField($field, array &$field_data) {

  // Get the field cardinality to determine whether or not a value should be
  // 'set' or 'appended' to.
  $cardinality = $field
    ->getFieldDefinition()
    ->getFieldStorageDefinition()
    ->getCardinality();

  // Gets the count of the field data array.
  $field_data_count = count($field_data);

  // If the cardinality is 0, throw an exception.
  if (!$cardinality) {
    throw new \InvalidArgumentException("'{$field->getName()}' cannot hold any values.");
  }

  // If the number of field content is greater than allowed, throw exception.
  if ($cardinality > 0 && $field_data_count > $cardinality) {
    throw new \InvalidArgumentException("'{$field->getname()}' cannot hold more than {$cardinality} values. {$field_data_count} values were parsed from the YAML file.");
  }

  // If we're updating content in-place, empty the field before population.
  if ($this
    ->existenceCheck() && !$field
    ->isEmpty()) {

    // Get parent entity.
    $parent = $field
      ->getParent()
      ->getValue();

    // Skip deleting field if parent entity is new.
    if ($parent && !$parent
      ->isNew()) {

      // Trigger delete callbacks on each field item.
      $field
        ->delete();
    }

    // Special handling for non-reusable entity reference values.
    if ($field instanceof EntityReferenceFieldItemList) {

      // Test if this is a paragraph field.
      $target_type = $field
        ->getFieldDefinition()
        ->getSetting('target_type');
      if ($target_type == 'paragraph') {

        /** @var \Drupal\Core\Entity\EntityInterface[] $entities */
        $entities = $field
          ->referencedEntities();
        foreach ($entities as $entity) {
          $entity
            ->delete();
        }
      }
    }

    // Empty out the field's list of items.
    $field
      ->setValue([]);
  }

  // Iterate over each field data value and process it.
  foreach ($field_data as &$item_data) {
    if (isset($field_data['#process']['dependency'])) {
      $dependency = $field_data['#process']['dependency'];
      $this
        ->processDependency($dependency);
    }

    // Preprocess the field data.
    $context = new ProcessingContext();
    $context
      ->setField($field);
    $context
      ->setContentLoader($this);
    $this
      ->getProcessManager()
      ->preprocessFieldData($context, $item_data);

    // Check if the field is a reference field. If so, build the entity ref.
    $is_reference = isset($item_data['entity']);
    if ($is_reference) {

      // Build the reference entity.
      $field_item = $this
        ->buildEntity($item_data['entity'], $item_data);
    }
    else {
      $field_item = $item_data;
    }

    // If the cardinality is set to 1, set the field value directly.
    if ($cardinality == 1) {
      $field
        ->setValue($field_item);

      // @todo Warn if additional item data is available for population.
      break;
    }
    else {

      // Otherwise, append the item to the multi-value field.
      $field
        ->appendItem($field_item);
    }
  }
}