Entity API recommends using hook_entity_info_alter to add information for an entity's bundles. However, for some reason, using hook_entity_info_alter to add the bundles results in a notice when 'manage fields' is accessed for the first time for the first bundle. And until a field is added to one of the bundles of the entity type, clearing the entity cache will result in the same notice.
Notice: Undefined index: sparql_views_resource in field_info_instances() (line 685 of /Users/clark/Documents/sites/sparql-views-beta/modules/field/field.info.inc).
If the logic is moved to hook_entity_info, the problem goes away. The reason why it isn't using hook_entity_info is because using entity_load results in a recursion error. However, does the full entity really need to be loaded? It seems that we only need the bundle key and the label. Presumably, those are things that could be hard coded in the module using the API -- the module author can be expected to know which table to access and which fields are the key and label, so it could be a direct database query rather than a function call.
This would also fix #1092192: Using hook_entity_info_alter to add the bundles prevents some modules from altering entities.
Other issues pointing out the notice:
core: #1121468: Notice when managing fields for entities with no fields attached
SPARQL Views: #1119516: Notice on managing fields of a SPARQL Views resource type
Field Collection: #1069318: Notice: Undefined index: field_collection_item in field_info_instances()
OG Membership: [##1097766]
It also happens in Message, but no issue has been posted AFAIK.
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | entity_bundle_notice.patch | 1.75 KB | fago |
| #11 | entity_bundle_notice.patch | 1.76 KB | fago |
| #7 | field_cache_entity.patch | 2.07 KB | fago |
| #7 | field_cache_profile2.patch | 1.49 KB | fago |
| #7 | field_cache_field_collection.patch | 1.06 KB | fago |
Comments
Comment #1
TripX commentedSubscribe
Happens here with Redirect module for D7.
Comment #2
fagoI remember that I've seen that issue sometimes myself, but wasn't able to reproduce it right now.
Anyway, thanks for all the investigation. Sounds like a weird cache-rebuilding issue, i.e. entity load triggers the field API info to be rebuilt, which in affect is rebuilt with an incomplete hook-entity-info?
Howsoever, I agree with you that the current workaround is not optimal and might cause problems like this, so we should change that.
Yep, it's unfortunate but perhaps the only way to go. I'm unsure whether the label is used at all, but it's documented. Anyway, as in our case the bundle is an entity type we have most of the information anyway but can't read it is it sits in hook-entity-info too.
While thinking about that, I've come up with another idea. So what about this:
* Let's implement an entity-info-alter hook by the entity API which cares about writing all the necessary bundle information. We can use hook_module_implements_alter() to make sure we are the last alter hook that runs and complete the entity information as necessary.
* At this point the static cache from entity_get_info() should equal the usual, completed entity info. This should fix any cache-rebuilding issues, though doesn't help the RDF module issue.
* Having the entity API caring about the bundle-entity info should not only make it easier for devs, moreover we have to do all the module_implements_alter trickery only once and don't have to burden each dev making use of the API doing so.
@RDF issue:
The problem is basically the same as the entity API faces here. The module assumes during entity-info-alter that the information there is complete and works with that, but that's not the case. If we implement the above work-a-round for the entity API though, we can easily care about the RDF module by ensuring it is the last one called. Actually it should try to enforce this on its own though.
Comment #3
fagoA non-generic fix for testing this approach for profile2 should be that:
Maybe, you could test whether this fixes this issue with a module causing the notice? If so, we just need to make sure RDF module comes even later and we should be fine.
Comment #4
Anonymous (not verified) commentedI'm confused, would you still register the bundle info using hook_entity_info_alter? Because if so, this problem will still be an issue.
What you posted using profile2 is what I had originally done in SPARQL Views. However, that only fixed the RDF mapping issue. It did not solve this notice issue.
Here is an issue I posted against core when I was investigating it #1121468: Notice when managing fields for entities with no fields attached. This might give some more ideas for other ways to fix this problem.
Comment #5
Anonymous (not verified) commentedJust for reference, including the following in
sparql_views_entity_infodid solve this problem in sparql_views:Comment #6
fagook, found the problem. See #1069318-5: Notice: Undefined index: field_collection_item in field_info_instances().
Let's implement the fix from here in a generic function inside the entity API.
Comment #7
fagook, I took first stab on implementing that.
As not only entity_load() calls but also field collection itself trigger field-info rebuilding during info-alter, a generic entity-bundle-info routine doesn't suffice. We also need to ensure the field-info cache is cleared after field-collection has added its bundles.
Attached patches work for me.
TODO:
* update the 'entity_test' module and add in admin bundle-info as example
* update the docs and point to 'entity_test' as example implemenation without entity admin ui
* auto-generate the admin bundle-info for modules using the entity API admin ui -> makes the profile2 patch obsolete
Comment #8
Anonymous (not verified) commentedShould Entity use a "private" function from the Field module? My understanding is that it goes against coding convention to use "private" functions defined by other modules, even though these aren't really private.
Comment #9
dave reidLooks like this fix for the other contrib modules could break modules that actually use data from entity_get_info() but don't want to depend on Entity API.
Comment #10
fago>Should Entity use a "private" function from the Field module? My understanding is that it goes against coding convention to use "private" functions defined by other modules, even though these aren't really private.
Yep, we shouldn't. But we cannot use the public function field_info_cache_clear() as it clears the entity cache, what is obviously not a good idea to do during entity-cache-building.
>Looks like this fix for the other contrib modules could break modules that actually use data from entity_get_info() but don't want to depend on Entity API.
Why should they break!? Could you elaborate on that?
Comment #11
fagook, I came up with a simpler fix, which doesn't unnecessarily change the API.
Attached patch fixes the problems for me with field-collection + should do it generally.
Comment #12
fagofago: @ http://drupal.org/files/issues/entity_bundle_notice.patch
+ // Move the our hook implementation to the bottom.
fixed that
Comment #13
Anonymous (not verified) commentedI'm still confused, moving the entity hook to the bottom seems like the opposite of what needs to happen.
Entity needs to attach the bundles before anyone else can attach anything to those bundles. Doesn't that mean that entity should be first?
Comment #14
fagoin the above patch, modules keep attaching their bundles on their own as they do now.
Comment #15
fago@linclark: ah I see, you are referring to the rdf-module issue, being #1092192: Using hook_entity_info_alter to add the bundles prevents some modules from altering entities.
Yep, this patch only fixes this issue, but not the rdf-module issue. Let's deal with that issue over there.
As #12 worked fine for me, I've committed it.