When entities are prepared for viewing by field_attach_prepare_view() and entity_prepare_view(), flags are set on them, to avoid unnecessarily preparing again, for good performance reasons. This makes good sense, except for the following reason: fields that are hidden in the view mode being prepared are not themselves prepared.

If there are entityreference fields on a previously-prepared entity (for example, if the entity references itself, it will be marked as prepared before actually doing the preparing), where one field is hidden but the other is not, only the visible field is prepared. If the visible field is using the 'Rendered entity' formatter, for a view mode in which the other field is now visible, because that field was not prepared, and those flags I mentioned above are set, that field will not be prepared. Which sadly results in a fatal error because the 'entity' property in the field is not set as it would have been by entityreference_field_formatter_prepare_view().

So... this all means that the Rendered Entity formatter needs to unset those flags in order for the entity to get prepared again. Unfortunately, this could be a performance hit, since the referenced entities will all need to be loaded when some of them may have already been loaded before when the 'parent' entity was prepared.

I attach a patch which does this, but I suggest that perhaps it may be better to make this configurable in some way, as it I *think* this is only necessary when an entity references another that is rendered in the same page request, such as itself, which won't always be possible.

Comments

james.williams’s picture

Alternatively, perhaps entityreference should just load up the entity in entityreference_field_formatter_view() if it is not there, just in case of strange cases like this where the prepare hooks cannot or do not run.

lsolesen’s picture

Status: Needs work » Needs review
kscheirer’s picture

The patch seems ok, but I'm not sure I understand the case when this problem can occur. When would entities need to reference themselves?

james.williams’s picture

My use case is that I have nodes that can represent full pages, or 'tabs' of pages. 'Tabs' are achieved using entity reference fields - so a parent node references each of its 'child' pages, and the child pages reference their parent. The 'tabs' themselves are produced by simply listing the child pages of a parent as links to each node (as their titles), themed to look like tabs. The content above the tabs is meant to be shared, so all child pages simply render their parent node (i.e. the entity in the 'parent' entity reference field) in a specific view mode. This was all done because it was important for us that each tab had its own unique URL, and that each could be managed as separate nodes. But also importantly, one of the tabs was to be that parent node itself (normally the first tab).

So for example, nodes 1, 2 and 3 could be the tabs. Node 1 should be the parent, so nodes 2 and 3 should show node 1 (in a different view mode) above their tabs.

This all means that entities needed to be able to reference themselves.

I'm sure there could be other use cases - for example, perhaps a node could be a listing of other nodes, and that initial node should itself be part of that listing.

To be honest, my suggestion in comment 1 may be a better way forward anyway, as that effectively 'lazy loads' entities rather than forcing all entities to be re-prepared.

timfernihough’s picture

StatusFileSize
new775 bytes

I had to re-roll this patch for use in 7.x-1.2 because a client whose site I have inherited is using this patch. Attached it here for anyone who might find themselves in a situation like mine.

das-peter’s picture

das-peter’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new744 bytes

Patch sees to do the trick. I'd say it's sensible to re-run all pre-render steps when an entity is rendered in a different context.
Re-rolled for latest 7.x-dev.