5

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.

4

The entity storage internally handles the schema. You do not need to do anything about that.

7

As 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);
}
?>
  • 3
    Since the time of this answer, a few things have changed in drupal core services. This worked for me: <?php $field_manager = \Drupal::service('entity_field.manager'); $field_storage_manager = \Drupal::service('field_storage_definition.listener'); $definition = $field_manager->getFieldStorageDefinitions('menu_link_content')['is_main_item']; $field_storage_manager->onFieldStorageDefinitionCreate($definition); ?> – SpadXIII Feb 9 '17 at 13:07
1

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);
}
0

Deleting field definitions in hook_uninstall like suggested leads to conflicts. My working solution in Drupal 8.7

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::service('entity_type.manager')->getDefinition('my_entity');
  \Drupal::service('entity.definition_update_manager')->updateEntityType($entity_type);
}

/**
 * Implements hook_uninstall().
 */
function mymodule_uninstall() {
  $entity_type = \Drupal::service('entity_type.manager')->getDefinition('my_entity'):
  \Drupal::service('entity.definition_update_manager')->updateEntityType($entity_type);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.