Problem/Motivation

When Entity Form Controllers were introduced, it came with the concept of a "default" form, where you could just call entity_get_form($entity), with no specified operation.

This has led to reuse of entity forms for both add and edit, with odd and inconsistent hacks spread through them (like $entity->isNew()) to differentiate between them.

Proposed resolution

Encourage use of separate form controllers that share a base class.
In the meantime, just duplicate the form declaration in the annotation to reuse the single class for each operation:

diff --git a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php
index 5a288c8..1bfcd02 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php
@@ -24,7 +24,8 @@
  *     "access" = "Drupal\user\RoleAccessController",
  *     "list" = "Drupal\user\RoleListController",
  *     "form" = {
- *       "default" = "Drupal\user\RoleFormController"
+ *       "add" = "Drupal\user\RoleFormController",
+ *       "edit" = "Drupal\user\RoleFormController"
  *     }
  *   },
  *   config_prefix = "user.role",

Remaining tasks

N/A

User interface changes

N/A

API changes

$operation is no longer optional when calling entity_get_form() et al.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tim.plunkett’s picture

Assigned: Unassigned » tim.plunkett
Status: Active » Needs review
FileSize
37.63 KB

First pass. Will likely need to be rerolled as conversions go in, but worth getting some feedback.

Status: Needs review » Needs work

The last submitted patch, entity-form-default-2006348-1.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review

#1: entity-form-default-2006348-1.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, entity-form-default-2006348-1.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review

#1: entity-form-default-2006348-1.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, entity-form-default-2006348-1.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
4.95 KB
41.21 KB

Missed a couple tweaks.

Status: Needs review » Needs work

The last submitted patch, entity-form-2006348-8.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
3.49 KB
44.7 KB

The taxonomy test I deleted was BS. It didn't actually assert anything and is broken in HEAD. It's also not how the menu system works.
It is, however, how the route system works, so it's a moot point.

This should be done now.

tim.plunkett’s picture

Okay, I went back and looked into that test more. It never actually asserted anything, as I said. But its fix was removed by the entity_form conversion for no apparent reason.

Here's the correct fix, as it was in #1359710: taxonomy_menu passes invalid arguments into taxonomy_form_term() but with an array.

Interdiff is against #8.

fago’s picture

I think this is a good improvement and makes $operation to work inline with the usual edit|add|delete, .. use - however, we miss implementation of deletion forms here as well. Maybe we could do that as a follow-up?

tim.plunkett’s picture

plach’s picture

Despite being the one that introduced the default operation, I'm definitely +1 on this :)

andypost’s picture

#11: entity-form-2006348-11.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, entity-form-2006348-11.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
48.3 KB

Reroll because some routes were converted, interdiff pretty much impossible.

#1987668: Convert config_test module to routes
#1992428: Convert Roles management to a Controller

Status: Needs review » Needs work

The last submitted patch, entity-form-2006348-17.patch, failed testing.

tim.plunkett’s picture

Status: Needs review » Needs work

The last submitted patch, entity-form-2006348-19.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Postponed

Okay I just realized I'm going in circles with #2010290: Editing a config entity from a listing page results in a 'page not found' and fixing the same damn bugs. So I'm just waiting on that.

andypost’s picture

Status: Postponed » Needs work

#21 is in, let's get this in now

amateescu’s picture

Can we please take #2014821: Introduce form modes UI and their configuration entity into consideration before rushing this in?

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
49.57 KB

Rerolled for the getForm().

I'm not ignoring that issue, I just don't see how this gets in the way.
I'm reasonably sure for every entity type with a form, it has one with the operation of 'edit'.
Why not make that the default?

amateescu’s picture

Because "reasonably sure" != "enforced policy/requirement"? :)

tim.plunkett’s picture

Then let's enforce it. Or provide 'edit' => EntityFormController as a default.

Whatever it takes to not have this in routes:
_entity_form: node.default
And this in the form class:
$this->operation == 'default'

Because that means nothing.

amateescu’s picture

Another option would be to make the 'default_operation' property introduced by translation_entity.module an official property of the entity annotation, and default it to 'edit' instead of 'default'. We can either do it here (what I'd prefer) or open a new issue for it.

Status: Needs review » Needs work

The last submitted patch, form-2006348-24.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
1.6 KB
51.15 KB

Fixed custom block.

I like the idea of default_operation, I had no idea this undocumented one-off property existed!...

I'd prefer to do that in a follow-up, I'll open one. It needs to be added to EntityType and whatnot, and this patch is big enough.

tim.plunkett’s picture

tim.plunkett’s picture

FileSize
51.22 KB

Reroll.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

I like the fact that we remove some magic, which doesn't really actually help as you want to have a custom form controller anyway.

tim.plunkett’s picture

Status: Reviewed & tested by the community » Postponed
amateescu’s picture

Status: Postponed » Needs review
FileSize
8.93 KB
52.19 KB

This is my idea on how to marry the 'default' form mode/form display with the default form operation. Basically, I'm bringing #2022873: Turn default_operation into an actual thing into scope here because it's kinda late to have dependent issues.

Status: Needs review » Needs work

The last submitted patch, entity-form-2006348-34.patch, failed testing.

amateescu’s picture

Status: Needs work » Needs review
FileSize
1.02 KB
50.67 KB

Now with less broken logic.

Status: Needs review » Needs work

The last submitted patch, entity-form-2006348-36.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
693 bytes
51.39 KB

Keeping up with conversions.

I think the additions in the last two interdiffs are great, but the original patch is mine so I can't RTBC.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/includes/entity.incundefined
@@ -442,45 +442,17 @@ function entity_access_controller($entity_type) {
-function entity_form_state_defaults(EntityInterface $entity, $operation = 'default') {
+function entity_form_state_defaults(EntityInterface $entity, $operation) {

Is there a follow up already to move this function as well to some kind of object?

tim.plunkett’s picture

FileSize
51.19 KB

Rerolled.

I don't know of any follow-ups for that.

alexpott’s picture

Assigned: tim.plunkett » catch
Status: Reviewed & tested by the community » Needs work

I'm assigning to catch since he has expressed a feeling that this change is not necessary...

Also this needs a reroll...

git applyc https://drupal.org/files/entity-2006348-40.patch
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 52421  100 52421    0     0  29488      0  0:00:01  0:00:01 --:--:-- 32824
error: patch failed: core/modules/comment/comment.module:686
error: core/modules/comment/comment.module: patch does not apply
tim.plunkett’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
53.22 KB

Straight reroll, no changes

Status: Reviewed & tested by the community » Needs work

The last submitted patch, entity-2006348-42.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
53.6 KB

Didn't fetch enough.

catch’s picture

Status: Reviewed & tested by the community » Needs review

Yeah I'm not sure the API change is necessary, can we clean up the existing forms doing double duty without it?

tim.plunkett’s picture

FileSize
6.15 KB
49.37 KB

Here is it without the API change.

tstoeckler’s picture

I think it in this case it makes sense to do the API change, as otherwise contrib will be lazy and not care about about $operation at all. There's two implications of that:
1. Contrib simply doing all forms (e.g. add and edit) in one controller and putting conditions such as $entity->isNew() there. This is not optimal, but I don't consider this particularly problematic. It's a small amount of code smell and it's contained to the specific module.

2. Contrib modules that interact with entity forms might have the expectation that a 'default' $operation always exist and thus break modules that follow best practices. This point is arguable, as core modules already follow this best practice (assuming this patch goes in), but nevertheless this point is why I would advocate making the API change.

yched’s picture

Just wondering : if we remove the notion of a "default" form mode, what's the impact on the "create new field" UI ?
Does it mean newly created fields do not appear in any forms until the admin explicitly visits the "Manage form" tabs and configures the field he just created ?
That would be a net UX regression.

On the display side, the fact that we have a "default" view mode (and that all view modes by default fall back to this "default" mode unless explicitly stated) is important UX wise : a newly added field is automatically displayed in the "default" view mode using the default formatter.
In other words : newly added fields automatically appear in "full" mode, and stay hidden in "teaser", without the admin needing to visit "Manage Display" - aka "just works".

tstoeckler’s picture

Does it mean newly created fields do not appear in any forms until the admin explicitly visits the "Manage form" tabs and configures the field he just created ?
That would be a net UX regression.

The problem that we have is that there is no way to sort the fields. It used to be that the default view mode just took over the sorting from the "Manage fields" page. But that is now sorted alphabetically since the introduction of form modes UI. So how should such a default form mode be populated?

yched’s picture

On the "display" side, new fields are automatically added at the bottom (highest weight +1) of the "default" view mode.
That's just how EntityDisplay->setComponent() works if no 'weight' is specified.

tim.plunkett’s picture

@yched:

+++ b/core/includes/entity.incundefined
@@ -829,11 +829,18 @@ function entity_get_form_display($entity_type, $bundle, $form_mode) {
+  // Since form modes are also tied to entity form operations, we need to use
+  // the 'default' form display when the requested $form_mode is the default form
+  // operation.
+  if ($form_mode == $entity_info['default_operation']) {
+    $form_mode = 'default';
+  }
   $form_mode_settings = field_form_mode_settings($entity_type, $bundle);

+++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.phpundefined
@@ -28,11 +28,12 @@
- *       "default" = "Drupal\user\ProfileFormController",
+ *       "profile" = "Drupal\user\ProfileFormController",
...
+ *   default_operation = "profile",

This is how we solved that problem.

amateescu’s picture

Yes, I have the kept the 'default' form mode. It's just the default operation that we're dropping here. I agree that it makes this relationship a lot harder to understand though..

yched’s picture

Oh, OK, makes perfect sense :-)
Thanks !

tim.plunkett’s picture

The only reason this was not 100% finished before API freeze was so #2014821: Introduce form modes UI and their configuration entity could go in.
This took a couple attempts to reroll, but I had chosen to prioritize other issues that were truly API freeze sensitive.

Therefore, I really would like to see the original patch get in. I think its rather important, and the original author of the default fallback also wants it gone (#14).

So I've reuploaded both the full patch, and the watered down version. I leave it to the committers.

amateescu’s picture

Yes, I guess I can take the blame for that :/ Imo, the interdiff from #46 doesn't really make sense, because it's still allowing contrib to be sloppy, as @tstoeckler points out in the next comment.

So, given that both the original author of the 'default' controller concept, entity api and field api maintainers agree that this is a good change that will actually help contrib, I would also really like to see the full patch in.

dawehner’s picture

@@ -829,11 +801,18 @@ function entity_get_form_display($entity_type, $bundle, $form_mode) {
+  // Since form modes are also tied to entity form operations, we need to use
+  // the 'default' form display when the requested $form_mode is the default form
+  // operation.
+  if ($form_mode == $entity_info['default_operation']) {
+    $form_mode = 'default';
+  }

To be honest, I don't understand why it magically switches to 'default' no matter what is defined on the entity type, even there is quite some documentation.

There are some places like COnfigTest => ConfigTestInterface which could make the patch a bit smaller but nevermind.

The last submitted patch, 54: entity-2006348-54-no-api-change.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 54: entity-2006348-54-with-api-change.patch, failed testing.

stevector’s picture

It looks like the entity system has changed greatly since this thread started. There is a still an odd split between entities using "default" as form operation and entities using "add" and "edit" instead.

Independent of which names are used I would like custom form modes added by the UI to reuse existing classes. Right now calling a form mode added through the UI throws an error. See #2511720: Allow form modes to use default operation if a form operation is not explicitly set

andypost’s picture

so summary needs update and evaluation
@Tim, #54 shows that there's BC-compatible fix!

Also default operation changes a form name for entities so that affects contrib that uses node form alters at least

tim.plunkett’s picture

Assigned: tim.plunkett » Unassigned
Issue tags: -Needs beta evaluation

That code is 2.5 years old, I don't have the time or inclination to resurrect it.

I think we should just won't fix this now.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

kristiaanvandeneynde’s picture

I may be interested in getting this moving again, but for now I'll try to fix the (personally) most glaring offender: #2848120: Short term fix: Make ContentTranslationController recognize 'add' and 'edit' form handlers.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

woprrr’s picture

I think this change can be usefull !!! Actually we have re-designed FormModeManager to permit to enhance all entities routes to use natively form-modes. I'm free to help this to be tested/continued as soon as possible.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.