Currently the entity query has no methods that would provide information about applied conditions, sorts,.. to the query. This does not follow the typical \Drupal\Core\Database\Query\Select in any way.
For example, if someone wants to retrieve the conditions, the only way to do it is a bit dirty:
$reflection = new \ReflectionClass($query);
$property = $reflection->getProperty('condition');
$property->setAccessible(TRUE);
$conditions = $property->getValue($query);
$values = $conditions->conditions();
or sorting:
$reflection = new \ReflectionClass($query);
$property = $reflection->getProperty('sort');
$property->setAccessible(TRUE);
$values = $property->getValue($query);
I have various filter forms that apply filters to entity queries and I need to know which filters were already applied so I can proceed accordingly(ie. add additional conditions or remove certain conditions to figure out ranges or available options ...).
The EQ was created so we won't have to write "manual" queries anymore but it looks like no one expected that someone would like to retrieve any data from these queries, just like we can/do from the good old Drupal\Core\Database\Query\Select.
Additionally there is no way to reset any of the parameters since there are no referenced getters. So if I want to completely change the order/sort of the results I cannot just unset the already applied sorts or conditions like I can do in the simple query where there are the &conditions() or &getOrderBy() methods.
For me, this is critical for my application and without this I have to use simple query instead because even though I can get the protected data via reflection I cannot unset it, only add to it or alter it.
Implemented:
- &getConditions()
- &getSorts()
&getAggregate()- &getRange()
- ...
| Comment | File | Size | Author |
|---|---|---|---|
| #55 | 2502363-55.patch | 2.62 KB | patrick r. |
| #27 | 2502363-27.patch | 2.61 KB | googletorp |
Comments
Comment #1
Anonymous (not verified) commentedComment #2
Anonymous (not verified) commentedComment #3
Anonymous (not verified) commentedComment #4
jmolivas commentedivanjaros: Any idea how to implement this ?
Comment #5
Anonymous (not verified) commentedThe
\Drupal\Core\Entity\Query\QueryInterfaceand\Drupal\Core\Entity\Query\QueryBaseneeds those new methods. I'll probably have a look at this later today.Comment #6
Anonymous (not verified) commentedI have used names from other interfaces to make it more universal and intuitive.
Comment #7
Anonymous (not verified) commentedThe query could probably also use getters for aggregation, groupBy, ... tags?
Comment #8
googletorp commentedStreamlined comments and function naming, to use Gets and getFoo.
Also added more documentation about the return value for getConditions.
Comment #9
Anonymous (not verified) commentedComment #10
daffie commentedLooks good to me. My observations:
Should this not be:
return $this->condition->&conditions();Why is there a "&" in the function name? Nothing is returned by reference. And the class variable you are getting is called "sort". So why not call the getter function getSort().
Comment #11
tim.plunkett#10.3
$sorts = &$query->getSorts();
$sorts = 5;
var_dump($query->getSorts() === 5)
TRUE
That's why it has
function &getSorts()Comment #12
Anonymous (not verified) commentedbump
Comment #13
Anonymous (not verified) commentedbump
Comment #14
daffie commentedPoints 10.1 and 10.2 have not been addressed.
Comment #19
timodwhit commentedthis would be very helpful to get. Just ran into this with trying to change the autocomplete query and needing to override the whole buildEntityQuery method to just alter one condition.
Comment #20
googletorp commented10.1 and 10.2:
Short version, no - patch is correct.
We have examples of this already in core, fx
\Drupal\Core\Database\Query\SelectExtender
In this case query could also be SelectExtender class since it's same interface.
We are not testing this elsewhere - we would basically be testing PHP class features.
Maybe we can finally get patches approved and committed?
Comment #21
googletorp commentedComment #22
googletorp commentedResting patch from #7 to make sure that all is still green.
Comment #24
googletorp commentedRerolled patch
Comment #25
googletorp commentedComment #26
dawehnerOn
\Drupal\Core\Database\Query\Selectthis is calledgetConditions, maybe because its actually not just a getter.Comment #27
googletorp commentedChange getter name for conditions from getConditions to conditions since that's what core does various places for some reason.
Comment #29
joachim commentedLGTM.
Comment #30
dawehnerI'm curious why it is conditions by getRange an getSorts?
Comment #31
joachim commentedTo match the getters on https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Database%...
Comment #32
larowlanjust to comment that this is an allowed API change under the 1:1 base class rule
/me wonders if we could replace this magic array guff with a value object at some stage (follow up of course)
Comment #33
larowlanWe need a change record here
Comment #37
jonathanshawComment #38
jonathanshawChange record added: https://www.drupal.org/node/3157856
Anyone interested in this issue may also be interested in #3001496: Add an alter hook to EntityQuery where we now have a simple patch for review. The issues can be committed independently, but the significant DX win is from the synergy of the two.
Comment #39
jonathanshawThe current patch only provides getters for 3 properties, while we have setters for many for. I'm wondering if
(a) we should have getters for everything that has a setter here;
or
(b) we adopt a BC approach using metadata instead:
Comment #40
alexpottWe should be adding some test coverage to prove that our expectations of adding these methods are met.
Also going to ping subsystem maintainers for an opinion about whether we should be doing this.
Comment #41
beakerboyShould this tie into the issue of using the default core Condition class instead of the class provided by the driver?
Comment #42
jonathanshawRe #40 "whether we should be doing this":
#3001496: Add an alter hook to EntityQuery has a soft dependency on this, so arguments from bojanz in favour of that also apply here.
Comment #43
jonathanshawI doubt it, anything implementation related like that should be the responsibility of the entity queries prepare() method, which has the job of turning the relatively abstract entity query into something actually executable.
These getters would be about facilitating modification of the abstract entity query prior to preparation/execution being invoked.
Comment #44
alexpottRe #42 - Is the entity module is using reflection to expose this stuff? I'd be surprised if it is
Comment #45
berdirThe entity module does work around the missing alter hook, it actually alters the sql/database query builder but its own conditions are then kinda entity query conditions again which it translates using its own Tables object. Pretty wild stuff, but that's all it can do without this issue and the alter hook. See #3086409-30: Provide a default query_access handler for core (maybe all?) entity types, where I figured this out recently as I've been helping with entity.module maintenance.
I need to look at the patch more closely, but I think these two issues are a blocker for getting the entity query access system into core.
Comment #52
davidwbarratt commentedJust ran into this trying to access the
accessCheckproperty.Comment #53
rgpublicI don't know whether this is thought to be included with this issue here and I don't want to hijack this but IMHO there's also a method missing to get the raw sqlQuery. We have stuff like addTag and according hooks like hook_query_[tag]_alter to modify the query, but there's no way to get the additional results back. At the very least there should be an executeQuery() or sth. so we can get the full rows back on not just IDs.
Right now, we have to decide: Either create and use manual SQL queries - which is of course quite complicated due to all the JOINs, column names etc. or use the very comfortable entityQuery but then be forever restricted to what it provides. If there's just one thing we want to let the SQL server do or calculate, everything falls apart. This could be a whole lot easier if there was such a method.
Comment #55
patrick r. commentedRe-rolled patch from #27 for Drupal 10.6.3 - did no longer apply for me after updating cweagans/composer-patches to ^2.0