Drupal 8: Custom Base Field Definitions and Content Types

  • henok_mikre

    Henok Mikre

The puzzler of the week was trying to limit access to a custom field definition for a specific content type. We were working on a project that was using an old version of scheduler_content_moderation_integration module, which defines a couple of fields using hook_entity_base_field_info(). The field definition looked as follows:

/**
 * Implements hook_entity_base_field_info().
 */
function scheduler_content_moderation_integration_entity_base_field_info(EntityTypeInterface $entity_type) {
  $fields = [];

  if ($entity_type->id() === 'node') {
    $fields['publish_state'] = BaseFieldDefinition::create('list_string')
      ->setSetting('allowed_values_function', '_scheduler_content_moderation_integration_states_values')
      ->setLabel(t('Publish state'))
      ->setDisplayOptions('view', [
        'label' => 'hidden',
        'region' => 'hidden',
        'weight' => -5,
      ])
      ->setDisplayOptions('form', [
        'type' => 'scheduler_moderation',
        'weight' => 30,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', FALSE)
      ->setTranslatable(TRUE)
      ->setRevisionable(TRUE)
      ->addConstraint('SchedulerPublishState');

As can be seen in the first few lines, the field attaches to any node entity. There was an issue with this in one specific content type in our project, so we needed to identify the content type while debugging. After searching for a while, it turned-out hook_entity_field_access() is one good place.

/**
 * Implements hook_entity_field_access().
 */
function mymodule_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
  if ($field_definition->getName() === 'publish_state') {
    $content_type = $items->getEntity()->getType(); // the machine name of the content type.

    // TODO: Add logic here.
  }

  // No opinion.
  return AccessResult::neutral();
}