protected function EntityFieldManager::buildBaseFieldDefinitions in Drupal 8
Same name and namespace in other branches
- 9 core/lib/Drupal/Core/Entity/EntityFieldManager.php \Drupal\Core\Entity\EntityFieldManager::buildBaseFieldDefinitions()
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.
1 call to EntityFieldManager::buildBaseFieldDefinitions()
- EntityFieldManager::getBaseFieldDefinitions in core/
lib/ Drupal/ Core/ Entity/ EntityFieldManager.php - Gets the base field definitions for a content entity type.
File
- core/
lib/ Drupal/ Core/ Entity/ EntityFieldManager.php, line 200
Class
- EntityFieldManager
- Manages the discovery of entity fields.
Namespace
Drupal\Core\EntityCode
protected function buildBaseFieldDefinitions($entity_type_id) {
/** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
$class = $entity_type
->getClass();
/** @var string[] $keys */
$keys = array_filter($entity_type
->getKeys());
// Fail with an exception for non-fieldable entity types.
if (!$entity_type
->entityClassImplements(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);
}
}
// Make sure that revisionable entity types are correctly defined.
if ($entity_type
->isRevisionable()) {
// Disable the BC layer to prevent a recursion, this only needs the
// revision_default key that is always set.
$field_name = $entity_type
->getRevisionMetadataKeys(FALSE)['revision_default'];
$base_field_definitions[$field_name] = BaseFieldDefinition::create('boolean')
->setLabel($this
->t('Default revision'))
->setDescription($this
->t('A flag indicating whether this was a default revision when it was saved.'))
->setStorageRequired(TRUE)
->setInternal(TRUE)
->setTranslatable(FALSE)
->setRevisionable(TRUE);
}
// Make sure that revisionable and translatable entity types are correctly
// defined.
if ($entity_type
->isRevisionable() && $entity_type
->isTranslatable()) {
// The 'revision_translation_affected' field should always be defined.
// This field has been added unconditionally in Drupal 8.4.0 and it is
// overriding any pre-existing definition on purpose so that any
// differences are immediately available in the status report.
$base_field_definitions[$keys['revision_translation_affected']] = BaseFieldDefinition::create('boolean')
->setLabel($this
->t('Revision translation affected'))
->setDescription($this
->t('Indicates if the last edit of a translation belongs to current revision.'))
->setReadOnly(TRUE)
->setRevisionable(TRUE)
->setTranslatable(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;
}