Right now core mainly supports bundles provided by config entities.
You create a config entity, then you click together the fields and the displays.
This works great for the use case where code doesn't care about particular bundles and their custom fields.
The other use case is the one where bundles have a purpose in code. Imagine a Payment entity where every Payment type
defines its own fields, that are handled by the relevant code. These payment types are provided by modules, and they shouldn't be created or deleted by the site builder. So it makes sense to define the bundles and the fields in code, but Core doesn't support that well. Here's a proposal to fix that, by moving the BundlePlugin API from Commerce.
1) You define an entity_type, let's call it payment. You then define a plugin type, let's call it payment_type.
2) The entity_type has an annotation key "bundle_plugin_type" => "payment_type". The plugin implements BundlePluginInterface, which has a single buildFieldDefinitions() method, allowing it to define bundle fields.
That's it! Modules can now define PaymentType plugins and safely rely on the declared fields.
Here's what Entity API does under the hood:
1) Defines a BundleFieldDefinition class that's missing from core, used in buildFieldDefinitions().
2) Detects entity types with the "bundle_plugin_type" key and sets a bundle_plugin handler class.
3) When a module that provides bundle plugins is installed or uninstalled, it calls BundlePluginInstaller to create/remove the declared fields (retrieved via the bundle_plugin handler class).
As you can see, most of the code is about Core's lack of proper bundle field support. This code can be decreased over time by improving Core.
Comments
Comment #2
bojanz CreditAttribution: bojanz commentedPR up at https://github.com/fago/entity/pull/49
Comment #3
joachim CreditAttribution: joachim commentedMaking plugins be bundles means you're tied to a 1-1 relationship between bundles and functionality: you can't have two different bundles that use the same plugin.
I think a better approach is what we've used for Flag: bundles are a config entity as in core, but use a plugin for their functionality.
Comment #4
bojanz CreditAttribution: bojanz commented@joachim
A 1-1 relationship is the whole point, the bundle plugin can (and usually does) provide bundle-specific fields, that's one of its main uses.
Comment #5
joachim CreditAttribution: joachim commentedHow can you be sure that a site builder won't want two bundles with the same functionality, for instance, because they want to add two different sets of additional fields?
Comment #6
bojanz CreditAttribution: bojanz commentedBundle plugins have no relation to site builders. They are a tool for code driven bundles and fields. The developer is free to use a base class or a trait to share functionality while keeping fields distinct.
Comment #7
Sam152 CreditAttribution: Sam152 commentedThis would be an awesome feature. The current hook that does this has quite some number of shortcomings.
Comment #8
benjy CreditAttribution: benjy commentedThis is a great feature, is there any specific reason the Github PR paused, there doesn't seem to be anything serious blocking it?
Comment #11
bojanz CreditAttribution: bojanz commentedMerged. Daniel made sure we prevent uninstallation of bundle plugin providing modules when there's content, and added a description key that can be used on the entity add page.
Comment #12
bojanz CreditAttribution: bojanz at Centarro commented