Entity Metadata API allows for an options list callback:

 *     - options list: (optional) A callback that returns a list of possible
 *       values for the property. The callback has to return an array as
 *       used by hook_options_list().

Entity API also provides a standard callback for FieldAPI, entity_metadata_field_options_list(), which is pretty much a wrapper around a invocation of hook_options_list().

If our selection handler uses options widgets, then we should set this too.

Comments

joachim’s picture

Status: Active » Needs review
StatusFileSize
new3.55 KB

Here's a patch which:

- adds the ability for the current field's selection handler to change the metadata properties
- adds EntityReference_SelectionHandler_Generic setting the 'options list' callback to the Entity API generic callback, entity_metadata_field_options_list(). That callback will then (eventually!) work its way back to getReferencableEntities()

What I'm not sure about is adding a function to the interface for selection handlers, as other contrib modules may already be implementing this! The only one I know of is OG: its selection handler subclasses ours so that's okay.

The alternative I suppose would be to not add it to the interface, and do a method_exists() in entityreference_field_property_callback().

brockfanning’s picture

I stumbled upon this issue because I was about to post the same problem. For me, it comes up when using an exposed filter of an entityreference field in a View of content indexed by Search API. Even with the "Render Views filters as select list" box checked in the field settings, Views was still not giving me a select list of entities. (only a text box)

I tested #1 and it works for me! It produced a select list in Views. In addition I didn't even have to check the "Render Views filters as select list" checkbox in the field settings. I wonder if this patch makes that checkbox unnecessary?

Finally I'll post my own patch, which I was going to put up before I tried #1. (need to search issue queue before making patches...) I'd defer to #1 over mine, since I know nothing about the workings of entityreference, and Joachim clearly does, but what the hell, it might be useful in some way. :) Anyway, my approach was to bundle the alteration onto the EntityReferenceBehavior_ViewsFilterSelect class.

joachim’s picture

Glad to hear it works :)

Adding it to EntityReferenceBehavior_ViewsFilterSelect isn't the right way IMO, as this should definitely be also available for the simple selection too.

Though I suppose your approach raises the possibility of doing it in *both* the selection behaviour classes.

brockfanning’s picture

Ah, I thought the EntityReferenceBehavior_ViewsFilterSelect class isn't used unless you've checked the "Render Views filters as select list" box in the field settings. I didn't think it was connected to the Simple vs. Views-based stuff. (believe I always used "simple" when testing) Am I wrong about that?

joachim’s picture

No, I think it's me who's wrong -- I am mixing up my behaviour classes.

In which case, doing this in EntityReferenceBehavior_ViewsFilterSelect is probably okay. It's a bit of a DX WTF, because you would expect the Entity metadata options list callback to always be there, irrespective of whether you asked for that handling for Views. But the maintainer may find it more palatable than my patch which adds a method to the interface, and as such, is an API change.

brockfanning’s picture

I definitely agree about the DX. Surely there are other reasons that callback needs to be there, besides Views filters. I only put it there because a Views filter was the place I was seeing the bug, and I don't know much about entity API. Your approach seems like the "correct" way, which is why I'm using yours for now. :)

(to clarify, I'm using the patch in #1, and it has been working fine for me)

brockfanning’s picture

Hmm, neither of our fixes are working for me anymore. Is this still working for you, Joachim? It may be an interaction with Search API that is causing the problem for me.

jags880’s picture

brockfanning, I'm having the same issue. Search API was updated in July to 1.7 what version are you using?

brockfanning’s picture

I actually use the dev version. In regards to my problem I've resorted to using hook_form_alter to change the text input into a select input and doing my own query to populate the options.

sammys’s picture

Just started using this patch with a search_api/views build and there's an infinite loop happening when caches are cleared. Looks like it's starting with views_fetch_plugin_data() when it's going through search_api_views_views_data(). It's probably not the fault of this patch but I figured it's worth reporting. I'll dig a little deeper about it now.

sammys’s picture

When caches are flushed there is a potential for large stack depth. In my case it was regenerating views handler data using this stack of calls:

  • views_fetch_plugin_data() is called
  • Load user entity options
  • This calls realname module and that has token replacement
  • Token replacement results in a theme registry rebuild
  • The rebuild invokes views_theme() and then back to views_fetch_plugin_data()

The real issue is where we should limit the call stack. Looking at the call stack it all appears to revolve around the entity_load() call in EntityReference_SelectionHandler_Generic::getReferencableEntities(). Unfortunately, the function must return a list of options and the list contains the entity label. Labels can be constructed in any way (not necessarily from the entity type's base table). That makes it non-trivial to implement code that doesn't use entity_load().

I have patched views to limit call stack depth in views_discover_plugins(). It's looking quite good so far and there has been a performance boost for cache clears. In addition to that, views is now displaying the list of entities in the filter options.

I have posted a new issue in the views issue queue about this along with a patch to workaround the issue while the community figures out a solution (I predict it will be in the theme system): #2089535: Cyclic calls to views_discover_plugins()

jason.fisher’s picture

I have the Views patch applied and can't build a cache with this patch applied also . The recursion just churns.. but this is an extreme case with a dozen content types, 500 fields and 350k nodes with many potential recursion issues -- with the worst culprit possibly a "related_references' field that references other nodes of the same type? I will investigate further.. I need either this or a view alter work-around to enforce a "is one of" operation on an entity reference Search API Solr filter.

jason.fisher’s picture

@brockfanning, how are you altering the widget to be "in" instead of "="? When I select multiple, a result is only returned if it matches all instead of 'any.'

jason.fisher’s picture

@11 - is using Views-generated options a recommend potential workaround then? You get to provide the label and reference ID directly, bypassing entity_load?

fago’s picture

Issue summary: View changes

To me, adding it just as #2 does makes sense: I'd have expected it to happen that way as having an options list callbacks maps to having it available in Views. Indeed, it makes options available when used with search api also.

Maybe, the behaviour checkbox should mention it adds options in general then though?