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()
  • ...

Comments

Anonymous’s picture

Title: Add method to get conditions from EntityQuery » Add getters to EntityQuery
Issue summary: View changes
Anonymous’s picture

Issue summary: View changes
Anonymous’s picture

Issue summary: View changes
jmolivas’s picture

ivanjaros: Any idea how to implement this ?

Anonymous’s picture

The \Drupal\Core\Entity\Query\QueryInterface and \Drupal\Core\Entity\Query\QueryBase needs those new methods. I'll probably have a look at this later today.

Anonymous’s picture

Status: Active » Needs review
StatusFileSize
new2.13 KB

I have used names from other interfaces to make it more universal and intuitive.

Anonymous’s picture

The query could probably also use getters for aggregation, groupBy, ... tags?

googletorp’s picture

StatusFileSize
new3.44 KB
new2.67 KB

Streamlined comments and function naming, to use Gets and getFoo.

Also added more documentation about the return value for getConditions.

Anonymous’s picture

Issue summary: View changes
daffie’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Looks good to me. My observations:

  1. +++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
    @@ -167,6 +167,13 @@ public function condition($property, $value = NULL, $operator = NULL, $langcode
    +    return $this->condition->conditions();
    

    Should this not be: return $this->condition->&conditions();

  2. Can you add a test for the &getConditions(). Just a simple one with ReflectionClass. To make sure that the function work as it should and to make sure it keeps on works in future.
  3. +++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
    @@ -237,6 +251,13 @@ public function sort($field, $direction = 'ASC', $langcode = NULL) {
    +  public function &getSorts() {
    
    +++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
    @@ -135,6 +168,14 @@ public function range($start = NULL, $length = NULL);
    +  public function &getSorts();
    

    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().

tim.plunkett’s picture

#10.3

$sorts = &$query->getSorts();
$sorts = 5;
var_dump($query->getSorts() === 5)

TRUE

That's why it has function &getSorts()

Anonymous’s picture

bump

Anonymous’s picture

bump

daffie’s picture

Points 10.1 and 10.2 have not been addressed.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

timodwhit’s picture

this 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.

googletorp’s picture

Status: Needs work » Needs review

10.1 and 10.2:

Short version, no - patch is correct.

We have examples of this already in core, fx

\Drupal\Core\Database\Query\SelectExtender

public function &conditions() {
  return $this->query->conditions();
}

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?

googletorp’s picture

Issue tags: -Needs tests
googletorp’s picture

Resting patch from #7 to make sure that all is still green.

Status: Needs review » Needs work

The last submitted patch, 8: add_getters_to-2502363-7.patch, failed testing. View results

googletorp’s picture

StatusFileSize
new2.62 KB

Rerolled patch

googletorp’s picture

Status: Needs work » Needs review
dawehner’s picture

+++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
@@ -156,6 +156,27 @@ public function getEntityTypeId() {
    * {@inheritdoc}
    */
+   public function &getConditions() {
+     return $this->condition->conditions();
+   }
...
+
+   /**
+    * {@inheritdoc}
+    */
+   public function &getSorts() {
+     return $this->sort;
+   }

On \Drupal\Core\Database\Query\Select this is called getConditions, maybe because its actually not just a getter.

googletorp’s picture

StatusFileSize
new2.61 KB
new1.09 KB

Change getter name for conditions from getConditions to conditions since that's what core does various places for some reason.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

joachim’s picture

Status: Needs review » Reviewed & tested by the community

LGTM.

dawehner’s picture

+++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
@@ -163,6 +163,27 @@ public function getEntityTypeId() {
+   public function &conditions() {
...
+   public function getRange() {
...
+   public function &getSorts() {

I'm curious why it is conditions by getRange an getSorts?

joachim’s picture

larowlan’s picture

  1. +++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
    --- a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
    +++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
    
    +++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
    +++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
    @@ -112,6 +112,47 @@ public function condition($field, $value = NULL, $operator = NULL, $langcode = N
    
    @@ -112,6 +112,47 @@ public function condition($field, $value = NULL, $operator = NULL, $langcode = N
       public function exists($field, $langcode = NULL);
     
       /**
    

    just to comment that this is an allowed API change under the 1:1 base class rule

  2. +++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
    @@ -112,6 +112,47 @@ public function condition($field, $value = NULL, $operator = NULL, $langcode = N
    +   * array(
    +   *   'field' => $field,
    +   *   'value' => $value,
    +   *   'operator' => $operator,
    +   * );
    ...
    +   * There will also be a single array entry of #conjunction, which is the
    

    /me wonders if we could replace this magic array guff with a value object at some stage (follow up of course)

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: +Needs change record

We need a change record here

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

jonathanshaw’s picture

Version: 8.9.x-dev » 9.1.x-dev
jonathanshaw’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs change record

Change 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.

jonathanshaw’s picture

The 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:

  /**
   * {@inheritdoc}
   */
  public function &getMetaData($key) {
    $propertyData = [
      'sort' => $this->sort,
      'count' => $this->count,
      'condition' => $this->condition,
      'aggregate' => $this->aggregate,
      'groupBy' => $this->groupBy,
      'condition_aggregate' => $this->aggregate,
      'sort_aggregate' => $this->aggregate,
      'range' => $this->range,
      'all_revisions' => $this->allRevisions,
      'latest_revisions' => $this->latestRevision,
      'access_check' => $this->accessCheck,
      'pager' => $this->pager,
    ];
    if (!isset($this->alterMetaData[$key]) && isset($propertyData[$key])) {
      return $propertyData[$key];
    }

    return isset($this->alterMetaData[$key]) ? $this->alterMetaData[$key] : NULL;
  }
alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests, +Needs subsystem maintainer review

We 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.

beakerboy’s picture

Should this tie into the issue of using the default core Condition class instead of the class provided by the driver?

jonathanshaw’s picture

Re #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.

jonathanshaw’s picture

Should this tie into the issue of using the default core Condition class instead of the class provided by the driver

I 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.

alexpott’s picture

Re #42 - Is the entity module is using reflection to expose this stuff? I'd be surprised if it is

berdir’s picture

The 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.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

davidwbarratt’s picture

Just ran into this trying to access the accessCheck property.

rgpublic’s picture

I 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.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

patrick r.’s picture

StatusFileSize
new2.62 KB

Re-rolled patch from #27 for Drupal 10.6.3 - did no longer apply for me after updating cweagans/composer-patches to ^2.0