Change record status: 
Project: 
Introduced in branch: 
8.0.x
Description: 

fieldable/isFieldable() in the entity type annotation/on EntityTypeInteface was misleading. It was not about having fields, it was being able to add/update/remove fields, like field.module does.

Same for the FieldableEntityStorageInterface and FieldableEntityStorageSchemaInterface.

The flag has been removed and can be removed from the entity type annotations. All content entities are supposed to support it if the storage supports it.

The only thing that has to be specified is field_ui_base_route, that tells field_ui where the integration point is for the Manage fields and related local tasks. The interface is renamed to DynamicallyFieldableEntityStorageInterface and also rename the corresponding FieldableEntityStorageSchemaInterface to DynamicallyFieldableEntityStorageSchemaInterface.

There are now 3 different checks instead of isFieldable(), depending on what the code is doing/needs to know:

1. Can have fields/is a content entity:

// On the entity.
$entity instanceof ContentEntityInterface.
// On the entity type.
$entity_type->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')

Use case: Check if an entity type can have fields. Every content entity type has at least one base field, and config entity types do not have any fields.

2. Check if the storage allows for field (storages) to be added, removed, or updated.

$entity_manager->getStorage($entity_type_id) instanceof DynamicallyFieldableEntityStorageInterface

Use case: As a module storing data for other/all entity types, check which entity types that can be done for.

3. Check if field UI is enabled for a given entity type.

\Drupal::moduleHandler()->moduleExists('field_ui') && $entity_type->get('field_ui_base_route')

Use case: Extend/integrate with field UI.

Additionally, the onBundleCreate() and onBundleDelete() methods are moved from DynamicallyFieldableEntityStorageInterface to a new EntityBundleListenerInterface, similar to EntityTypeListenerInterface. The entity manager now also implements the same interface instead of slightly different methods. The order of arguments has been adapted and changed ($entity_type_id is now the last argument).

Before:

// Calling it.
\Drupal::entityManager()->onBundleCreate($entity_type_id, $bundle);
// On a storage implementation.
public function onBundleCreate($bundle);

After:

// Calling it.
\Drupal::entityManager()->onBundleCreate($bundle, $entity_type_id);
// On a storage implementation.
public function onBundleCreate($bundle, $entity_type_id);

The UI for view modes, form modes and comment type creation is limited to entity types that specify a field UI base route. This is done because those all require the field UI to be used (manage displays, create comment fields).

Impacts: 
Module developers