Problem/Motivation
Surprisingly I did not found a pre-existing issue for this: https://www.drupal.org/project/issues/drupal?text=parent+target_bundles&....
Quoting #2977879: Regression in #2940339: when multiple vocabularies exist, normalization of Terms fails:
Discovered via #2977848: Update to JSON API 1.20.
if ($target_entity === NULL) { $host_entity = $parent->getHostEntity(); $relatable_resource_types = $resource_type_repository->get( $host_entity->getEntityTypeId(), $host_entity->bundle() )->getRelatableResourceTypes()[$parent->getPropertyName()]; if (count($relatable_resource_types) !== 1) { throw new \RuntimeException('Relationships to virtual resources are possible only if a single resource type is relatable.'); }Having multiple vocabularies causes
$relatable_resource_types['parent']to have multiple resource types. But why?Turns out that the
parentfield definition does NOT restrict the parent to be in the same bundle. That means that thePoliticsterm from theTagsvocabulary could haveBMWfrom theCarsvocabulary as its parent term. This of course makes zero sense.
Proposed resolution
Implement \Drupal\taxonomy\Entity\Term::bundleFieldDefinitions(), much like \Drupal\comment\Entity\Comment::bundleFieldDefinitions().
Remaining tasks
None.
User interface changes
None.
API changes
None.
Data model changes
None. Except that Term entity type's parent field definition is now more precise, and doesn't allow nonsensical/forbidden values anymore!
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | 2977882-25.patch | 586 bytes | jibran |
Comments
Comment #2
wim leersComment #3
wim leersThis inaccuracy in Typed Data metadata results in the latest JSON API release being unable to normalize terms when there are multiple vocabularies on a site. So I ported #2 over to JSON API as a work-around until this lands: #2977879-5: Regression in #2940339: when multiple vocabularies exist, normalization of Terms fails.
Comment #5
wim leersThis must be one of the most obscure failures I've ever seen, along with one of the silliest fixes.
This is why I like having
assert()s all over, along with strictly typed objects. This is super painful to debug.Comment #6
wim leersThe #5 interdiff is wrong. This is the interdiff:
Comment #7
jibranFix looks fine to me. Let's add some test if possible.
Comment #8
wim leersDone! Failing test-only patch is also the interdiff.
Comment #9
jibranThanks, for updating the patch
Comment #12
catchCommitted e60979f and pushed to 8.6.x. Thanks!
Comment #13
wim leers🎉
Comment #14
jibranSorry, I forgot about it.
::bundleFieldDefinitionsis only called when a bundle is created so we need an upgrade path, to add this setting, and upgrade path test, to verify this setting, for the existing parent field for all the existing vocabularies.Comment #15
jibranI think we should revert the commit because we are fixing the bug for new vocabularies not for all existing vocabularies. Sorry, @Wim Leers!
Comment #16
wim leers@jibran AFAICT that's not true. I could reproduce the bug with Drupal core's
tagsvocabulary and simply applying this patch and clearing caches fixed it.Looking at the caller of
::bundleFieldDefinitions()seems to confirm this —\Drupal\Core\Entity\EntityFieldManager::getFieldDefinitions()does this:And
$this->buildBundleDefinitions()does this:Comment #17
jibranLet's ask @Berdir.
Comment #18
amateescu commented@Wim Leers is right in #16, bundle fields are computed on demand and cached, they are not only added when a new bundle is created.
Comment #19
jibranAt least we need an update hook to clear the cache.
So I think moral here is as long as you are updating the field definition or settings of an existing bundle field in either
hook_entity_bundle_field_infoor $class::bundleFieldDefinitions clear the cache will update the FieldDefinitions but if you are creating a new field(computed or otherwise) in eitherhook_entity_bundle_field_infoor $class::bundleFieldDefinitions you need to either implementhook_entity_bundle_createor update hook to fire\Drupal\Core\Field\FieldDefinitionListener::onFieldDefinitionCreatefor example whatentity_schema_test_entity_bundle_createis doing.Comment #20
wim leersThanks, @amateescu! But also thanks, @jibran, for asking the right critical questions :)
Hm, do we? I forget, but I thought that every update of Drupal core already would invalidate all caches.
Comment #21
jibranif that is true then why do we have so many empty update hooks :D
Comment #22
jibranWe do need an update hook to clear the
entity_bundle_field_definitions:*cache.Comment #23
jibranHere we go.
Comment #24
jibranBetter docs.
Comment #25
jibranReroll after #2658956: Taxonomy vocabulary data not available as views fields
Comment #26
wim leersComment #28
catchCommitted bc2d4bf and pushed to 8.6.x. Thanks!
Comment #29
jibranAs per https://www.drupal.org/core/backport-policy, @catch can you please state your reason to not backport this to 8.5.x? I don't think this is disruptive at all.
Comment #31
pwolanin commentedShould be backported since it breaks jsonapi
Comment #33
larowlan8.5 is now security only
Comment #34
wim leersBesides, JSON API already backported this:
That's why I forgot this was even still open. Thanks for the attempt though, @pwolanin :)
@larowlan++