Follow-up to #2302235: Set default property values in EntityType
Problem/Motivation
Currently \Drupal\Core\Entity\EntityType::getBundleEntityType()
simply returns a value of bundle_entity_type
protected property that initialized with "bundle" string.
The provided default "bundle" is wrong because hides absence of actual value parsed from entity annotation by returning "bundle" string that used only by internals of field ui module. That was done in #2302235: Set default property values in EntityType
This causes a field ui module route generation tricky because you need to check:
1) entity has bundle support EntityTypeInterface::hasKey('bundle')
2) entity bundles are managed by other entity EntityTypeInterface::getBundleEntityType()
should return entity machine name or NULL, currently returns "bundle" string.
Entity can have "bundle_entity_type" and no bundle key definition, so no documentation about using this properties right. Also there's "bundle_of" property that describes reverse relation from config entity to content entity.
This default value also introduces a limitation to use "bundle" as entity name because entity param converter will try to load an entity when field ui module forms and controllers need raw value of the bundle.
Proposed resolution
Change default value to NULL
Clean-up all checks in code for "bundle" by introducing a static helper FieldUI::getRouteBundleParameterName()
method
In changed places rename:
- $bundle_entity_type
to $bundle_entity_type_id
- sometimes called a "$field_entity_type
"
- use $entity_type
variable name for entity type definition for consistency.
Remaining tasks
Review patch approach
Fix, commit
User interface changes
no
API changes
Default value for \Drupal\Core\Entity\EntityType::$bundle_entity_type
changes from 'bundle' to NULL
.
A new method is added to \Drupal\Core\Entity\EntityTypeInterface
: getBundleConfigDependency()
Beta phase evaluation
Issue category | Bug because every caller of \Drupal\Core\Entity\EntityType::getBundleEntityType() needs to take into account a possible return value of 'bundle' which doesn't mean anything for them. Examples of this wrong behavior can be seen in (and are fixed by) the patch. |
---|---|
Issue priority | Normal because there's a known workaround (i.e. take the special 'bundle' return value into account). |
Prioritized changes | The main goal of this issue is to improve the developer experience for this method. It also improves maintainability because it removes special-casing code. |
Disruption | Little disruptive for contributed and custom modules because it will require a small code updates if they use the current workaround of checking the "bundle" return value as absence of bundle entity type. |
Comment | File | Size | Author |
---|---|---|---|
#99 | set_default_property-2346857-99.patch | 21.37 KB | claudiu.cristea |
#99 | interdiff.txt | 923 bytes | claudiu.cristea |
Comments
Comment #1
andypostThat was introduced in #2111823: Convert field_ui / Entity local tasks to YAML definitions
Comment #2
m1r1k CreditAttribution: m1r1k commentedComment #3
m1r1k CreditAttribution: m1r1k commentedComment #4
m1r1k CreditAttribution: m1r1k commentedComment #6
m1r1k CreditAttribution: m1r1k commentedComment #7
yched CreditAttribution: yched commentedNot a blocker, but
That could be shortened to "if ($bundle_entity_type_id = ...)"
& same for most of the other hunks in the patch :-)
Other than that, this looks good once it's green.
Comment #9
m1r1k CreditAttribution: m1r1k commentedHere are some improvements
Comment #11
andypostrepeated twice for no reason
Comment #12
jsobiecki CreditAttribution: jsobiecki commentedComment #13
rpayanmComment #15
andypost@yched what is a recommended way to make sure that entity has bundles? there's 2 keys:
1)
$entity_type->getBundleEntityType()
- simply means that there's no entity type that is a bundle for that entity.2)
$entity_type->hasKey('bundle')
- no bundle key so entity is not "bundlable", meaning thatgetBundleEntityType()
should returnNULL
Comment #16
BerdirDepends on what you want to know. If you want to know if an entity has bundles, use hasKey(). If you want to know if it has bundles that are stored as entities, use getBundleEntityType().
Comment #17
andypostComment #18
andypost"bundle" key is needed for entity_test that manages bundles by custom way, so here's workaround
Comment #19
andypostFix last test, suppose patch ready for review
Comment #20
andypostA bit of clean-up
Comment #22
andypost@Berdir maybe better to get rid of this "bundle" default in favour of route subscriber?
Comment #23
BerdirYeah not sure about this, lets try to get some feedback from yched on this.
To summarize the problem in one sentencene, the problem is that field_ui relies in a weird way on bundle_entity_type being "bundle" when it is actually no entity type, which makes checks for this more complicated in other parts of the code.
I think that we should not make the API weird to make it easier for field_ui, but not sure what the best way to fix that is.
Comment #24
BerdirUff.
We discussed this a bit. We're not sure what to do, but here is an idea:
Instead of supporting a dynamic parameter (which we do not understand works for FieldOverview), what if we always use {bundle} for our own routes:
Meaning, do $path = str_replace('{' . $bundle_entity_type . '}', '{bundle}', $path) in case we have a $bundle_entity_type. Then all the route parameters generation code can hardcode 'bundle'.
We don't know if anyything will break because of that, but it might be worth a try?
If it s not already documented, we should also expand the documentation for field_ui_base_route that you either have to put in the bundle entity type if you have one or bundle in there for field_ui to work.
Comment #25
yched CreditAttribution: yched commentedMight be woth pinging @tim.plunkett about this ? IIRC he's the one who was kind enough to take care of moving field_ui's callbacks to routes :-)
Comment #26
andypostThis breaks a lot of places in core that supposed to typed bundle, for example
So there's a lot of places needs to be cleaned-up to load bundle manually to get a label of bundle entity.
Is this change could be approved?
Comment #28
andypostI found that base route for field UI is defined by entity so too much code needs change.
So fallback to previous patch (interdiff against #20)
Comment #30
BerdirYeah, what I meant is to replace {node_type} to {bundle} in field_ui routes, but that breaks on the link templates, local tasks and so on.
Comment #31
BerdirComment #32
andypostjust a re-roll, looks configFieldMapper needs some clean-up
Comment #34
andypostContent translation now affected too
Comment #35
andypostRe-roll with some clean-up by using existing
FieldUI::getRouteBundleEntityType()
and introduction ofFieldUI::getRouteBundleParameterName()
to use for flip-flop entity types and "bundle"Suppose all fieldUI code should use the function to build a route names.
Patch ready for review/suggestions.
PS: updated issue summary a bit
Comment #36
jibranWe need beta evaluation in issue summary.
Comment #38
andypostadded beta and fixed IS
Comment #39
jibranChanges look good to me. Let's see what @Berdir or @yched thinks about it.
Comment #40
Berdir@amateescu wanted to work on field_ui to clean up how the bundle route parameter works, that would simplify this a lot I think.
Comment #41
andypostAnother clean-up, less noise
Comment #42
andyposta bit more fixes
Comment #44
andypostGreen again, waiting for reviews
Comment #45
amateescu CreditAttribution: amateescu commentedI remember someone (probably @Berdir) asked me to link here the issue for cleaning up Field UI routes, so here it is: #2428035: Bring some sanity into Field UI routes and forms
Comment #46
amateescu CreditAttribution: amateescu commentedRewritten this patch on top of #2428035: Bring some sanity into Field UI routes and forms. We can switch back to NR when that issue gets in.
Comment #47
andypostLet's test a patch, overall looks great!
Just few questions
should be added to IS
Suppose option should be applied only in case of bundle as entity
Comment #49
amateescu CreditAttribution: amateescu commented#47.1 Done.
#47.2 I think it should be there all the time so contrib can depend on it for all Field UI routes.
Comment #50
amateescu CreditAttribution: amateescu commented@andypost, do you have any other remarks or can we get this to RTBC? :)
Comment #51
andypostComment #52
alexpottI'm not sure that the beta evaluation is correct. Have we really justified the disruption here? Also some of the issue summary sounds like a bug.
Comment #53
amateescu CreditAttribution: amateescu commentedRerolled and updated the beta evaluation. I agree with #52 that the current behavior smells more like a bug.
Comment #54
claudiu.cristea#2412569: Allow setting the auto-create bundle on entity reference fields with multiple target bundles is post postponed on this.
Comment #55
claudiu.cristeaThis is minor. While we are using 'key' and 'name' for dependencies (
::getConfigDependencyKey()
and::getConfigDependencyName()
) why not be consistent here? I would rename'type'
to'key'
.Comment #57
amateescu CreditAttribution: amateescu commented#55:
Drupal\Core\Entity\DependencyTrait::addDependency()
has$type
and$name
as arguments, and the return array ofDrupal\Core\Entity\EntityTypeInterface::getBundleConfigDependency()
is always used to pass the dependency type and name to theaddDependency()
method mentioned above, so changingtype
tokey
would actually be very confusing IMO.Rerolled the patch.
Comment #59
amateescu CreditAttribution: amateescu commentedMissed a spot.
Comment #62
amateescu CreditAttribution: amateescu commentedBot fluke.
Comment #63
alexpottNeeds a reroll.
Comment #64
siva_epari CreditAttribution: siva_epari commentedPatch rerolled.
Comment #65
andypostthanx
Comment #66
alexpottWe need a change record to do this.
Comment #67
Mile23Needed a reroll.
Comment #68
Mile23Comment #70
Mile23And needs *another* reroll, 5 minutes later. :-)
Comment #71
Mile23More reroll.
Comment #72
Mile23Comment #74
andypostComment #75
hitesh-jain CreditAttribution: hitesh-jain at Acquia commentedComment #76
hitesh-jain CreditAttribution: hitesh-jain at Acquia commentedI could apply the patch, so no reroll is needed it seems.
Comment #77
hitesh-jain CreditAttribution: hitesh-jain at Acquia commentedComment #80
claudiu.cristeaLet's see.
Comment #82
claudiu.cristeause statement missed.
Comment #83
claudiu.cristeaCR https://www.drupal.org/node/2545280.
Comment #85
claudiu.cristeaComment #87
claudiu.cristeaBetter.
Comment #88
andypostCR is good
Comment #89
alexpottIt'd be nice to get a +1 on the final solution from @Berdir or @yched
Comment #90
Berdir+1 ;)
This is a small API change that will affect some modules, a quick grep showed DS and field_group. But the current behavior is really weird and exposes field UI internals in the entity type API.
Maybe give @yched some time to give his +1? He already confirmed almost a year ago that he is onboard with the general idea but the patch changed a lot since then.
Comment #93
amateescu CreditAttribution: amateescu commentedBack to rtbc.
Comment #94
alexpottThe fail in #91 was due to not be able to checkout code on testbot and nothing to do with the patch.
Comment #95
yched CreditAttribution: yched commented+1 indeed, minor remarks below :
Here and for other callers of the new getBundleConfigDependency() : the method either returns something or throws an exception, so not sure why we bother with the "if ($dep = getBundleConfigDependency())", it's always gonna be TRUE ?
Minor : the comment was copy/pasted along with the code from EntityDisplayBase to EntityType, but the notion of "target" entity type makes little sense in that new location (it's now about "this" EntityType)
Probably not for this issue to change since it is just being moved around, but isn't that the kind of stuff asserts are for now ?
Comment #96
claudiu.cristeaComment #97
claudiu.cristea@yched,
Please re-RTBC if looks OK for you
Comment #98
yched CreditAttribution: yched commentedThanks @claudiu.cristea. Looks good.
Minor, can be fixed on commit :
"The this" :-)
Comment #99
claudiu.cristeaOuch! Sorry :)
Comment #100
claudiu.cristeaSetting back to RTBC per #98.
Comment #101
alexpottI'm committing this under the maintainer discretion provision in the beta evaluation policy. This makes bundle behave like other entity values - when an entity does not have a bundle it is NULL. Committed 877fd18 and pushed to 8.0.x. Thanks!
Thanks for adding the beta evaluation to the issue summary.