EntityRouteEnhancer and HtmlEntityFormController should document requirements for the _entity_form property

Created on 25 March 2021, over 4 years ago
Updated 1 October 2023, almost 2 years ago

Problem/Motivation

A form used for the _entity_form route property must inherit from EntityForm, not FormBase.

This should be documented.

Steps to reproduce

Try it.
You get:

Error: Call to undefined method MyEntityForm::setModuleHandler() in Drupal\Core\Entity\EntityTypeManager->getFormObject() (line 230 of core/lib/Drupal/Core/Entity/EntityTypeManager.php).

Drupal\Core\Entity\EntityTypeManager->getFormObject('group', 'member-bulk-edit') (Line: 82)
Drupal\Core\Entity\HtmlEntityFormController->getFormObject(Object, 'group.member-bulk-edit.default') (Line: 76)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

๐Ÿ› Bug report
Status

Active

Version

11.0 ๐Ÿ”ฅ

Component
Documentationย  โ†’

Last updated about 20 hours ago

No maintainer
Created by

๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom joachim

Live updates comments and jobs are added and updated live.
  • Novice

    It would make a good project for someone who is new to the Drupal contribution process. It's preferred over Newbie.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

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

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom joachim
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia aditi saraf

    Aditi Saraf โ†’ made their first commit to this issueโ€™s fork.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom longwave UK

    Should we add a runtime assertion so anyone who makes this mistake gets a better error message?

  • Assigned to aditi saraf
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia aditi saraf

    i will work on this ..

  • Issue was unassigned.
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia aditi saraf

    @Joachim i am not able to reproduce this issue .

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom joachim

    I can still see the call to setModuleHandler in getFormObject(), which AFAICT isn't in FormBase.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium xdequinze Brussels

    @joachim, I am trying to understand the issue. Would you like to provide more details about it ? What are you trying to achieve ?

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom joachim

    If you define a route that uses an entity form, you use '_entity_form' in the route definition, and set a form class name as a value.

    If your form class inherits the standard form class base, it crashes.

    The docs for _entity_form in entity.api.php should say that you need to use a specific base class.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia anjali rathod India
  • First commit to issue fork.
  • Status changed to Needs review 3 months ago
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia acbramley

    Encountered this in โœจ Allow vocabulary overview form class to be overridden Active and I agree we should improve this by throwing an error. I don't think this is novice based on the test coverage required.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia acbramley
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom joachim

    The check in core/lib/Drupal/Core/Entity/EntityTypeManager.php is not what I was expecting, and it's a good idea because it'll give a better error for people who use the wrong sort of form class as an entity handler.

    But it won't catch the case where you use _entity_form directly in a route definition.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia acbramley

    It does catch it, try adding this (mimics VocabularyRouteProvider::getOverviewPageRoute)

    entity.vocab.overview:
      path: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}/overview2'
      defaults:
        _entity_form: 'taxonomy_vocabulary.overview'
        _title: 'Test'
      requirements:
        _entity_access: 'taxonomy_vocabulary.access taxonomy overview'
      options:
        _admin_route: TRUE
      parameters:
        taxonomy_vocabulary:
          with_config_overrides: TRUE
    

    EntityRouteEnhancer::enhanceEntityForm sets the controller to controller.entity_form:getContentResult based on the _entity_form default. That calls HtmlEntityFormController::getFormObject which calls EntityTypeManager::getFormObject

    The _entity_form route default is tied directly to the form handler class.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom joachim

    Ah, I hadn't spotted that!

    The exception message will be wrong in that scenario though:

    > 'The "%s" form handler of the "%s" entity type specifies a class "%s" that does not extend "%s".'

    because it's not been caused by a form handler.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia acbramley

    because it's not been caused by a form handler.

    The form handler is the second part of the _entity_form string, e.g the example above maps to the overview form handler of the Vocabulary entity type.
    I also wondered if we should just through the error when the entity type is parsed, but technically at the moment you can have form handlers that aren't tied to routes and therefore don't need to implement the interface.
    In Vocabulary's case it had the form handler but the route for it isn't using the _entity_form method and afaik form handlers aren't used in many other ways?
    We also might need to throw a deprecation first before a full exception so sites don't blow up?

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom joachim

    > I also wondered if we should just through the error when the entity type is parsed, but technically at the moment you can have form handlers that aren't tied to routes and therefore don't need to implement the interface.

    In that scenario, is there something like DefaultHtmlRouteProvider setting up the route?

    Or are there entity types that specify a form handler for a form that's only shown embedded in something else?

Production build 0.71.5 2024