protected function EntityFieldManager::buildBaseFieldDefinitions

protected EntityFieldManager::buildBaseFieldDefinitions($entity_type_id)

Builds base field definitions for an entity type.

Parameters

string $entity_type_id: The entity type ID. Only entity types that implement \Drupal\Core\Entity\FieldableEntityInterface are supported.

Return value

\Drupal\Core\Field\FieldDefinitionInterface[] An array of field definitions, keyed by field name.

Throws

\LogicException Thrown if a config entity type is given or if one of the entity keys is flagged as translatable.

File

core/lib/Drupal/Core/Entity/EntityFieldManager.php, line 192

Class

EntityFieldManager
Manages the discovery of entity fields.

Namespace

Drupal\Core\Entity

Code

protected function buildBaseFieldDefinitions($entity_type_id) {
  $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
  $class = $entity_type->getClass();
  $keys = array_filter($entity_type->getKeys());

  // Fail with an exception for non-fieldable entity types.
  if (!$entity_type->isSubclassOf(FieldableEntityInterface::class)) {
    throw new \LogicException("Getting the base fields is not supported for entity type {$entity_type->getLabel()}.");
  }

  // Retrieve base field definitions.
  /** @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] $base_field_definitions */
  $base_field_definitions = $class::baseFieldDefinitions($entity_type);

  // Make sure translatable entity types are correctly defined.
  if ($entity_type->isTranslatable()) {
    // The langcode field should always be translatable if the entity type is.
    if (isset($keys['langcode']) && isset($base_field_definitions[$keys['langcode']])) {
      $base_field_definitions[$keys['langcode']]->setTranslatable(TRUE);
    }
    // A default_langcode field should always be defined.
    if (!isset($base_field_definitions[$keys['default_langcode']])) {
      $base_field_definitions[$keys['default_langcode']] = BaseFieldDefinition::create('boolean')
        ->setLabel($this->t('Default translation'))
        ->setDescription($this->t('A flag indicating whether this is the default translation.'))
        ->setTranslatable(TRUE)
        ->setRevisionable(TRUE)
        ->setDefaultValue(TRUE);
    }
  }

  // Assign base field definitions the entity type provider.
  $provider = $entity_type->getProvider();
  foreach ($base_field_definitions as $definition) {
    // @todo Remove this check once FieldDefinitionInterface exposes a proper
    //  provider setter. See https://www.drupal.org/node/2225961.
    if ($definition instanceof BaseFieldDefinition) {
      $definition->setProvider($provider);
    }
  }

  // Retrieve base field definitions from modules.
  foreach ($this->moduleHandler->getImplementations('entity_base_field_info') as $module) {
    $module_definitions = $this->moduleHandler->invoke($module, 'entity_base_field_info', [$entity_type]);
    if (!empty($module_definitions)) {
      // Ensure the provider key actually matches the name of the provider
      // defining the field.
      foreach ($module_definitions as $field_name => $definition) {
        // @todo Remove this check once FieldDefinitionInterface exposes a
        //  proper provider setter. See https://www.drupal.org/node/2225961.
        if ($definition instanceof BaseFieldDefinition && $definition->getProvider() == NULL) {
          $definition->setProvider($module);
        }
        $base_field_definitions[$field_name] = $definition;
      }
    }
  }

  // Automatically set the field name, target entity type and bundle
  // for non-configurable fields.
  foreach ($base_field_definitions as $field_name => $base_field_definition) {
    if ($base_field_definition instanceof BaseFieldDefinition) {
      $base_field_definition->setName($field_name);
      $base_field_definition->setTargetEntityTypeId($entity_type_id);
      $base_field_definition->setTargetBundle(NULL);
    }
  }

  // Invoke alter hook.
  $this->moduleHandler->alter('entity_base_field_info', $base_field_definitions, $entity_type);

  // Ensure defined entity keys are there and have proper revisionable and
  // translatable values.
  foreach (array_intersect_key($keys, array_flip(['id', 'revision', 'uuid', 'bundle'])) as $key => $field_name) {
    if (!isset($base_field_definitions[$field_name])) {
      throw new \LogicException("The $field_name field definition does not exist and it is used as $key entity key.");
    }
    if ($base_field_definitions[$field_name]->isRevisionable()) {
      throw new \LogicException("The {$base_field_definitions[$field_name]->getLabel()} field cannot be revisionable as it is used as $key entity key.");
    }
    if ($base_field_definitions[$field_name]->isTranslatable()) {
      throw new \LogicException("The {$base_field_definitions[$field_name]->getLabel()} field cannot be translatable as it is used as $key entity key.");
    }
  }

  // Make sure translatable entity types define the "langcode" field properly.
  if ($entity_type->isTranslatable() && (!isset($keys['langcode']) || !isset($base_field_definitions[$keys['langcode']]) || !$base_field_definitions[$keys['langcode']]->isTranslatable())) {
    throw new \LogicException("The {$entity_type->getLabel()} entity type cannot be translatable as it does not define a translatable \"langcode\" field.");
  }

  return $base_field_definitions;
}

© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Entity!EntityFieldManager.php/function/EntityFieldManager::buildBaseFieldDefinitions/8.1.x