- Issue created by @jweowu
I need help to understand how to get a contextual View argument through to the View when IEF is involved, as there appear to be significant complications.
I have an entity reference field using IEF and an entity reference View display as the source for available entities.
When editing a node, this View display needs to filter thousands of entities down to only the handful which are related to that particular node. The View therefore has a contextual argument, and normally I could set that to take a default value from the content ID in the URL and everything would be happy, but that's not the case when IEF is involved...
IEF doesn't pick up that default argument value from the URL because (AFAICS) the current path at the time IEF executes the View is not /node/<nid>/edit
but rather something like /entity_reference_autocomplete/node/views/09qwy9D_MllcMCWndq8xDmxarqmw2HUa37D9f-LmB_I
. The Views hooks then do not get fired for the actual execution that IEF performs (I suspect Views bails out when it can't find a content ID in the URL, and simply isn't running at all).
To confuse matters, though, the View also gets executed prior to this under the regular /node/<nid>/edit
URL (and therefore successfully picking up the node ID argument from the URL) when we click the IEF "Add" button. As the View was failing to execute later, this successful run was the only visible execution of the View when I was trying to debug this, and it contained the expected arg! -- but that is the wrong time for obtaining completion results, and the View simply wasn't running at all when it was the right time.
The upshot was that I had no View results at all in IEF -- not until I used hook_inline_entity_form_reference_form_alter()
and tracked down the particular value $reference_form['entity_id']['#selection_settings']['view']['arguments']
.
Setting the argument value here in the IEF form_alter hook seemingly did the trick, provided that I also removed the URL-based default argument value from the View configuration. So by default my View wants to list all of those thousands of entities, but in practice, with that hook in place, the IEF UI sees only the handful of filtered options. This had seemed to do the trick, and I've been running that code for some time.
Then I updated to 8.x-1.0-rc15 and ran into
🐛
Memory leak by trying to load ALL entities at once for a simple count
Closed: works as designed
, which reliably gave me a server error every time I attempted to edit one of these nodes. The summary of that issue is that since rc15 IEF uses EntityReferenceSelection\SelectionInterface::countReferenceableEntities()
, and it turns out that several implementations of that are fully-loading all of the entities just to count how many of them there are(!), and one such implementation is the one for Views...
In the case of a View source for an IEF-controlled entity reference field, \Drupal\views\Plugin\EntityReferenceSelection\ViewsSelection
has a countReferenceableEntities()
method which will typically use \Drupal\views\Plugin\views\query\Sql::execute()
and from there call loadEntities()
to load all entities, rather than only executing a count query.
Hence my web server running out of memory, as countReferenceableEntities()
was trying to load thousands of entities (to find out if there was "more than one" of them!).
Notwithstanding that there are upstream core bugs with a bunch of countReferenceableEntities()
implementations, I've realised that this result means that with my current View configuration, IEF isn't actually getting the result is needs from countReferenceableEntities()
-- the number it obtains is in the thousands, when the number it needs to obtain might be five (i.e. however many are associated with the argument). Or indeed zero-or-one (which is the case it's interested in). But the View argument isn't in play when the count happens, so it's just getting the grand total number of entities of the type in question.
So even if the core bugs were fixed (and hence the server errors no longer a going concern), IEF just isn't getting the right value with my current approach.
How can I arrange things so that my View receives the node ID argument value every time it's executed, when the user is visiting the edit form for that node?
Active
User interface