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

The term controller is currently used inconsistently in Drupal 8 core. In particular, routing "controllers" and entity "controllers" are actually very different concepts. For this reason, the entity "controllers" will be referred to as handlers going forward, and the classes are being renamed as follows:

  • EntityRenderController renamed to EntityViewBuilder
    The annotation key has been renamed from render to view_builder.
  • EntityListController renamed to EntityListBuilder
    Note: There is an actual route controller named \Drupal\Core\Entity\Controller\EntityListController that is not renamed. This is a great example for why this rename helps to understand the difference between those two classes.
  • EntityStorageControllerInterface renamed to EntityStorageInterface
    Also:
    • EntityStorageControllerBase => EntityStorageBase
    • ConfigStorageController => ConfigEntityStorage
    • FieldableEntityStorageControllerInterface => FieldableEntityStorageInterface
    • FieldableEntityStorageControllerBase => ContentEntityStorageBase
    • FieldableDatabaseStorageController => ContentEntityDatabaseStorage (later renamed to Sql\SqlContentEntityStorage)
  • EntityAccessController renamed to EntityAccessControlHandler
  • EntityFormController renamed to EntityForm
    EntityManagerInterface::getFormController() is renamed to EntityManagerInterface::getFormObject() but that is almost never used directly, use EntityFormBuilder::getForm() (entity.form_builder service) instead.
  • EntityManager::getController() and EntityManager::hasController() renamed to EntityManager::getHandler() and EntityManager::hasHandler()

Note that all renames are accompanied by the corresponding renames of the methods on the EntityManager and EntityType classes.

A complete example:

/**
 * @ContentEntityType(
 *   id = "user",
 *   label = @Translation("User"),
 *   handlers = {
 *     "storage" = "Drupal\user\UserStorage",
 *     "access" = "Drupal\user\UserAccessControlHandler",
 *     "list_builder" = "Drupal\user\UserListBuilder",
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 *     "form" = {
 *       "default" = "Drupal\user\ProfileForm",
 *       "cancel" = "Drupal\user\Form\UserCancelForm",
 *       "register" = "Drupal\user\RegisterForm"
 *     },
 *     "translation" = "Drupal\user\ProfileTranslationHandler"
 *   },
 *   [...]
 * )
 */
class User extends ContentEntityBase implements UserInterface { }

See also the documentation that is being written for entity handlers: https://drupal.org/node/2143497

Impacts: 
Module developers