Is it fine to implement hook_entity_base_field_info
to add a new field to the advanced group in each node?
If so, how is the storage handled by default for base fields? Should I need to create a schema to store the field value.
Drupal Answers is a question and answer site for Drupal developers and administrators. It only takes a minute to sign up.
Sign up to join this communityAs said in the other answer, the entity storage internally handles the schema.
Here is an explanation for it, taken from the documentation
If your field doesn't have any special requirements Entity Field API can take care of the database storage and update the database schemas accordingly. This is the default for fields that are not marked as being a computed field (setComputed(TRUE)), or has specifically indicated to provide its own field storage (setCustomStorage(TRUE)).
Say you want to add a new base field to all Node entities that contains a simple boolean value to indicate whether the content is "highlighted".
<?php
/**
* Implements hook_entity_base_field_info().
*/
function MYMODULE_entity_base_field_info(EntityTypeInterface $entity_type) {
$fields = array();
// Add a 'Highlight' base field to all node types.
if ($entity_type->id() === 'node') {
$fields['highlight'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Highlight'))
->setDescription(t('Whether or not the node is highlighted.'))
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDisplayOptions('form', array(
'type' => 'boolean_checkbox',
'settings' => array(
'display_label' => TRUE,
),
))
->setDisplayConfigurable('form', TRUE);
}
return $fields;
}
?>
Now all it takes is to visit update.php to run the database updates, and an additional 'highlight' column will be added to the tables holding the node data.
To run this database update automatically when your custom module is enabled or disabled, you can trigger it by executing the event listeners that are responsible for performing these updates in your hook_install() and hook_uninstall() implementations:
<?php
/**
* Implements hook_install().
*/
function MYMODULE_install() {
// Create field storage for the 'Highlight' base field.
$entity_manager = \Drupal::entityManager();
$definition = $entity_manager->getFieldStorageDefinitions('node')['highlight'];
$entity_manager->onFieldStorageDefinitionCreate($definition);
}
/**
* Implements hook_uninstall().
*/
function MYMODULE_uninstall() {
$entity_manager = \Drupal::entityManager();
$definition = $entity_manager->getLastInstalledFieldStorageDefinitions('node')['highlight'];
$entity_manager->onFieldStorageDefinitionDelete($definition);
}
?>
Deleting field definitions in hook_uninstall
like suggested leads to conflicts.
My working solution in Drupal 8.7 (can also be used for drupal 9)
mymodule.module:
/**
* Implements hook_entity_base_field_info().
*/
function mymodule_entity_base_field_info(EntityTypeInterface $entity_type) {
$fields = [];
if ($entity_type->id() === 'my_entity') {
$fields['newfield'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('New field'))
->setSetting('target_type', 'node')
->setSetting('handler', 'default')
->setRequired(FALSE);
}
return $fields;
}
mymodule.install:
<?php
/**
* Implements hook_install().
*/
function mymodule_install() {
$entity_type = \Drupal::entityTypeManager()->getDefinition('my_entity');
\Drupal::entityDefinitionUpdateManager()->updateEntityType($entity_type);
}
/**
* Implements hook_uninstall().
*/
function mymodule_uninstall() {
$entity_type = \Drupal::entityTypeManager()->getDefinition('my_entity');
\Drupal::entityDefinitionUpdateManager()->updateEntityType($entity_type);
}
I did as SpadXIII's comment suggested, and it worked for me with Drupal 8.5.1.
In my custom module, I added the mymodule_update.php file, with the following code.
function mymodule_post_update_someName() {
$field_manager = \Drupal::service('entity_field.manager');
$field_storage_manager = \Drupal::service('field_storage_definition.listener');
$definition = $field_manager->getFieldStorageDefinitions('table_name')['field_name'];
$field_storage_manager->onFieldStorageDefinitionCreate($definition);
}