Follow up from #2283977: Create a new ConfigEntity type for storing bundle-specific customizations of base fields. That issue introduces the ability to have config-based overrides of base fields via 'base_field_override' config entities. However, it retains HEAD's prior ability to also have code-based overrides via ContentEntityInterface::bundleFieldDefinitions(). If both approaches get used on the same base field for the same bundle, various problems can arise (see comments #142-#146 of that issue). So, to ensure robustness, let's either explicitly remove support for that (i.e., throw an exception when someone tries to add a config-based override of a code-overridden field), or else if we think it's important to support this possibility, then add tests for it and fix what we find.

Comments

effulgentsia’s picture

Issue summary: View changes
fago’s picture

Issue tags: +beta deadline

From #2283977-152: Create a new ConfigEntity type for storing bundle-specific customizations of base fields:

My opinion is we should change the name from core.base_field_override.*.yml to core.field_override.*.yml, so that contrib could use the exact same entity type for overriding non-base fields.

Implementation wise, it's overriding base fields only now - so having config that implies something that is not happening seems confusing to me.

So, actually the implemenation could be easily improved to handle all fields by using getStorageFieldDefinition() instead of getBaseFieldDefinitions() to fetch the storage field. Given that, I'd actually agree with effulgentsia that the config (+ entity type) should be core.field_override.*.yml then. I don't think the possible confusion around overriding field instances with config is not an issue - technically, you could do it, but there is no point in overriding a config field with config, so that's why we don't ;-)

So depending on what we decide here, we might want to this rename or not. But anyway, I think we shoud have this clarified before beta.

fago’s picture

@topic:

We've got one usage of code based bundle field overrides left in core after [#9058387]: comment module. It could be moved to config by generating the config overridde upon bundle creation. That's a bit more work to do and maybe not so easy to follow as now, but it should work fine.

Personally, I think it makes sense to keep code-based bundle field overrides for the following reasons:

  • Consistency. We've got code based base fields, so disallowing code based bundle fields seems arbitrary to me.
  • Code based fields bundle fields offer more control, e.g. to remove display configurability. Thus, they are the only mechanism right now for making use of entity storage by bundle without having to expose configurability. We do not have code based FieldStorageDefinition and FieldDefinition (for bundles) yet, but that would be simple to add and could be even done by contrib (interfaces!).
  • Easier handling / maintenance of code based overrides as thanks to the shallow-override of the code based bundle field you do not have to duplicate the common base field properties in your code. Not a biggie, but still.

When keeping it I think we should:

  • Rename BaseFieldOverride to FieldOverrideConfig and core.field_override.*.yml + remove its coupling to base fields.
  • Fix base field override DX by adding a *new* BaseFieldOverride class for code based overrides, which internally can defer to the real base field object and thus has an improved memory footprint.
  • Provide code based FieldStorageDefinition and FieldDefinition and test coverage (just an addition, follow-up) ?
fago’s picture

I gave this more thought on whether this is really necessary or it makes sense to work on simplifying things more.

Code based fields bundle fields offer more control, e.g. to remove display configurability. Thus, they are the only mechanism right now for making use of entity storage by bundle without having to expose configurability. We do not have code based FieldStorageDefinition and FieldDefinition (for bundles) yet, but that would be simple to add and could be even done by contrib (interfaces!).

We could achieve that as well by making sure BaseFieldOverrides and FieldInstanceConfigs support varying display configurability setting as well, what means bringing at least default-display settings back to the field instance config (API only). That way, modules could create field instances and or overrides with full display configurability flexibility.
I think for base field overrides that makes much sense anyway, for field instances it depends on whether we have code fields as alternative.

Thinking more about possible use-cases for code fields, I came up with another one:

  • Implementing an entity type with remote storage and many different bundles. When e.g. you expose web service resources as entities (as done by https://www.drupal.org/project/fluxservice), you often have many similar ressources with some varying fields for which you'd provide different bundles. So while the shared fields would be base fields and thus defined in code, you'd have to add storage+instance config for the bundle fields in world without coded-bundle fields. It wouldb e quite weird if the system forces you to add config for bundle fields, while it doesn't for base fields. Also, while I see no real technical reason I must say it feels more natural / suiting to have code fields for that use-case.
tstoeckler’s picture

First off, sorry for being a bit late to the party...

I (re-)read this issue as well as (re-)reading most of #2283977: Create a new ConfigEntity type for storing bundle-specific customizations of base fields as well the committed patch.

As I didn't get involved with that issue I'm aware that I can't complain about how it turned out, but since this issue is very much based on that, there's no around taking it into account.

Some background:
I am very adament about our current ability to provide code-based (base) fields via ContentEntityInterface::baseFieldDefinitions(). Additionally, I very much like the pattern of field.module not participating at all in the architectural decisions of the concept but instead simply adding its storage fields in hook_entity_field_storage_info().*

I think that pattern is something that we should utilize for more of the Entity API and I think it can perfectly address the problem of this issue and #2283977: Create a new ConfigEntity type for storing bundle-specific customizations of base fields, as well.

The problem with #2283977: Create a new ConfigEntity type for storing bundle-specific customizations of base fields:
#2283977: Create a new ConfigEntity type for storing bundle-specific customizations of base fields raised one issue with our current base-field/bundle-field architecture but instead of fixing at its root, it implemented a workaround, in my opinion.

The root problem, which was also discussed there, is that bundle fields are (and after #2283977: Create a new ConfigEntity type for storing bundle-specific customizations of base fields mostly were) used for two different things:

  • Overriding properties of base fields: This was used e.g. by nodes to override the title label
  • Adding additional fields: This is what field.module did to add its FieldInstanceConfig. To be able to add fields for a specific bundle and being able to store the data somewhere, the concept of storage fields had to be invented.

We already had a pattern for the different steps that would happen during the collection of base/storage/bundle fields. That is why I do not understand why we did not implement that in the usual way. The precedent we already had for content entities was:

  • Base/Storage fields are provided by a method on the entity type baseFieldDefinitions() and then extended by a hook (hook_entity_(base_)field_(storage_)info())
  • Bundle fields are provided by a method on the entity type bundleFieldDefinitions() and then extended by a hook (hook_entity_bundle_field_info())

So if we realize we need to introduce a third logical step the most logical thing to do, in my opinion, would have been: 1. Introduce a new method for entity types to provide bundle-specific overrides of base fields. For example Node's bundleFieldDefinitions() would be moved to this method. 2. Introduce a new hook so that modules can extend these overrides. content_translation.module could then use that hook to override translatability of base fields on a bundle level.
Some additional notes:

As this approach is the most consistent with our current architecture I think it would be the best for DX (in addition to the DX gain mentioned above). The code that #2283977: Create a new ConfigEntity type for storing bundle-specific customizations of base fields introduced to EntityManager is just alien to that class when looking at how any other types of fields are collected.

* Yes, I know that base field != storage field. Proceed. :-)

alexpott’s picture

Status: Postponed » Active

Can be active

catch’s picture

The tests/fixes part of this needs to happen after beta if the 'remove support for' doesn't - so only half the issue is beta deadline I guess.

effulgentsia’s picture

Title: Remove support for, or add tests+fixes for, base fields having simultaneous code-based and config-based overrides » Check if there's sufficient test coverage for base fields with simultaneous code-based and config-based overrides
Issue tags: -beta deadline

I think what ended up landing works, and even has a test, but don't know if there's enough coverage for various events that can happen along the way.

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.

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.

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.

smustgrave’s picture

Status: Active » Postponed (maintainer needs more info)
Issue tags: +stale-issue-cleanup

Thank you for creating this issue to improve Drupal.

We are working to decide if this task is still relevant to a currently supported version of Drupal. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or is no longer relevant. Your thoughts on this will allow a decision to be made.

Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.

Thanks!

smustgrave’s picture

Wanted to bump this one more time.

smustgrave’s picture

Status: Postponed (maintainer needs more info) » Active

Don't feel comfortable closing so will put back into active.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.