Bundle specific BaseField overrides are ignored

Created on 16 June 2021, over 3 years ago
Updated 2 October 2023, about 1 year ago

Problem/Motivation

It appears bundle specific overrides to entity base fields are being ignored/overwritten when building the list of available fields for an index.

This is a particularly troublesome when using Search API in conjunction with something like the Comment, Group and Commerce modules which uses this method (see this issue ). In the Group module it is used to provide a relationship between a Group Content bundle and specific Entity Type, by overriding the 'target_type' setting (among others) of the base Entity Relationship field for each Group Content bundle.

I've narrowed the issue down to the following method in the ContentEntity datasource plugin:

  public function getPropertyDefinitions() {
    $type = $this->getEntityTypeId();
    $properties = $this->getEntityFieldManager()->getBaseFieldDefinitions($type);
    if ($bundles = array_keys($this->getBundles())) {
      foreach ($bundles as $bundle_id) {
        $properties += $this->getEntityFieldManager()->getFieldDefinitions($type, $bundle_id);
      }
    }

  //...
}

This code assumes that there are only ever going to be field additions for each bundle, and all field overrides are swallowed by the array merge.

Steps to reproduce

The issue can be reproduced by using hook_entity_bundle_field_info to override the Author field for the Article bundle to point at Nodes instead of Users as shown below. Then when trying to access a property of a Page via the Index Add Field interface, you will still receive fields for the User Entity rather than Node entities.

/**
 * Implements hook_entity_bundle_field_info().
 */
function hook_entity_bundle_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
  $fields = [];

  if ($entity_type->id() == 'node' && $bundle == 'article') {
    /** @var $base_field_definition \Drupal\Core\Field\BaseFieldDefinition */
    $fields['uid'] = $base_field_definitions['uid'];

    $fields['uid']->setSetting('target_type','node');

    $handler_settings = ['target_bundles' => ['page']] + $fields['uid']->getSetting('handler_settings');
    $fields['uid']->setSetting('handler_settings',$handler_settings);
  }

  return $fields;
}

Obviously the above example is never how you would do this, but it demonstrates the issue for consideration when being legitimately used in the example of the Group module.

Proposed resolution

This is a bit tricky as far as I can see as the Search API isn't dealing with an Entity/Bundle combo in isolation, it could have to deal with many bundles of the same Entity, all with their own valid overrides and try to consolidate them into a single field in the Index document. Plus the UI isn't setup to display field variants.

Has anyone else come across this issue and found a workaround?

🐛 Bug report
Status

Active

Version

1.19

Component

Framework

Created by

🇬🇧United Kingdom lind101

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024