summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2017-10-23 12:53:06 (GMT)
committerNathaniel Catchpole2017-10-23 12:53:06 (GMT)
commit66cbd7c9e5540611918b378592ba775ac4756741 (patch)
tree8cabd3b475ed7e0196f3eac6160b281a9b66e7d4
parentdf1dd607adac2634d91e2894107b9ae2513b6a90 (diff)
Issue #2864995 by amateescu, Dinesh18, Sam152: Allow entity query to query the latest revision
-rw-r--r--core/lib/Drupal/Core/Entity/Query/QueryBase.php18
-rw-r--r--core/lib/Drupal/Core/Entity/Query/QueryInterface.php11
-rw-r--r--core/lib/Drupal/Core/Entity/Query/Sql/Query.php8
-rw-r--r--core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php58
4 files changed, 95 insertions, 0 deletions
diff --git a/core/lib/Drupal/Core/Entity/Query/QueryBase.php b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
index 38deabd..d84a266 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryBase.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
@@ -109,6 +109,13 @@ abstract class QueryBase implements QueryInterface {
protected $allRevisions = FALSE;
/**
+ * Flag indicating whether to query the latest revision.
+ *
+ * @var bool
+ */
+ protected $latestRevision = FALSE;
+
+ /**
* The query pager data.
*
* @var array
@@ -252,6 +259,16 @@ abstract class QueryBase implements QueryInterface {
*/
public function currentRevision() {
$this->allRevisions = FALSE;
+ $this->latestRevision = FALSE;
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function latestRevision() {
+ $this->allRevisions = TRUE;
+ $this->latestRevision = TRUE;
return $this;
}
@@ -260,6 +277,7 @@ abstract class QueryBase implements QueryInterface {
*/
public function allRevisions() {
$this->allRevisions = TRUE;
+ $this->latestRevision = FALSE;
return $this;
}
diff --git a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
index df37520..d4b0608 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
@@ -255,6 +255,17 @@ interface QueryInterface extends AlterableInterface {
public function currentRevision();
/**
+ * Queries the latest revision.
+ *
+ * The latest revision is the most recent revision of an entity. This will be
+ * either the default revision, or a pending revision if one exists and it is
+ * newer than the default.
+ *
+ * @return $this
+ */
+ public function latestRevision();
+
+ /**
* Queries all the revisions.
*
* @return $this
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
index cd245ef..50b81bb 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
@@ -119,6 +119,14 @@ class Query extends QueryBase implements QueryInterface {
// entity id.
$this->sqlFields["base_table.$id_field"] = ['base_table', $id_field];
}
+
+ // Add a self-join to the base revision table if we're querying only the
+ // latest revisions.
+ if ($this->latestRevision && $revision_field) {
+ $this->sqlQuery->leftJoin($base_table, 'base_table_2', "base_table.$id_field = base_table_2.$id_field AND base_table.$revision_field < base_table_2.$revision_field");
+ $this->sqlQuery->isNull("base_table_2.$id_field");
+ }
+
if ($this->accessCheck) {
$this->sqlQuery->addTag($this->entityTypeId . '_access');
}
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
index ec33f67..ebb3072 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
@@ -318,6 +318,16 @@ class EntityQueryTest extends EntityKernelTestBase {
// Now we get everything.
$assert = [4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15'];
$this->assertIdentical($results, $assert);
+
+ // Check that a query on the latest revisions without any condition returns
+ // the correct results.
+ $results = $this->factory->get('entity_test_mulrev')
+ ->latestRevision()
+ ->sort('id')
+ ->sort('revision_id')
+ ->execute();
+ $expected = [1 => '1', 2 => '2', 3 => '3', 16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15'];
+ $this->assertSame($expected, $results);
}
/**
@@ -936,6 +946,54 @@ class EntityQueryTest extends EntityKernelTestBase {
->allRevisions()
->execute();
$this->assertEqual($result, [16 => '14']);
+
+ // Add another pending revision on the same entity and repeat the checks.
+ $entity->setNewRevision(TRUE);
+ $entity->isDefaultRevision(FALSE);
+ $entity->{$this->figures}->setValue([
+ 'color' => 'red',
+ 'shape' => 'square'
+ ]);
+ $entity->save();
+
+ // A non-revisioned entity query should still return entity 14.
+ $result = $this->factory->get('entity_test_mulrev')
+ ->condition('id', [14], 'IN')
+ ->execute();
+ $this->assertCount(1, $result);
+ $this->assertSame([14 => '14'], $result);
+
+ // Now check an entity query on the latest revision.
+ $result = $this->factory->get('entity_test_mulrev')
+ ->condition('id', [14], 'IN')
+ ->latestRevision()
+ ->execute();
+ $this->assertCount(1, $result);
+ $this->assertSame([17 => '14'], $result);
+
+ // Verify that field conditions on the default and pending revision still
+ // work as expected.
+ $result = $this->factory->get('entity_test_mulrev')
+ ->condition('id', [14], 'IN')
+ ->condition("$this->figures.color", $current_values[0]['color'])
+ ->execute();
+ $this->assertSame([14 => '14'], $result);
+
+ // Now there are two revisions with same value for the figure color.
+ $result = $this->factory->get('entity_test_mulrev')
+ ->condition('id', [14], 'IN')
+ ->condition("$this->figures.color", 'red')
+ ->allRevisions()
+ ->execute();
+ $this->assertSame([16 => '14', 17 => '14'], $result);
+
+ // Check that querying for the latest revision returns the correct one.
+ $result = $this->factory->get('entity_test_mulrev')
+ ->condition('id', [14], 'IN')
+ ->condition("$this->figures.color", 'red')
+ ->latestRevision()
+ ->execute();
+ $this->assertSame([17 => '14'], $result);
}
/**