Skip to content

Commit 0697d17

Browse files
committed
[WIP] Add proper entity query support
1 parent c446600 commit 0697d17

File tree

1 file changed

+62
-1
lines changed

1 file changed

+62
-1
lines changed

src/Entity/Query/Query.php

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
namespace Drupal\apigee_edge\Entity\Query;
2121

22+
use Drupal\Core\Cache\CacheableMetadata;
2223
use Drupal\Core\Entity\EntityInterface;
2324
use Drupal\Core\Entity\EntityTypeInterface;
2425
use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -84,9 +85,69 @@ public function execute() {
8485
// Basically, DeveloperAppQuery already applies a condition on the returned
8586
// result because this function gets called.
8687
$all_records = $this->getFromStorage();
87-
$filter = $this->condition->compile($this);
8888

89+
// Be consistent with \Drupal\Core\Entity\Query\Sql\Query::prepare().
90+
// Add and fire special entity query tags.
91+
// @todo This fix can be only merged after the fix in the following issue
92+
// is available in a tagged release of entity.module.
93+
// https://www.drupal.org/project/entity/issues/3332956
94+
// The minimum required entity.module version also MUST be bumped as part
95+
// of this fix.
96+
$this->addTag('entity_query');
97+
$this->addTag('entity_query_' . $this->entityTypeId);
98+
99+
if ($this->accessCheck) {
100+
// We do not just add a tag but ensure that only those Apigee entities
101+
// are returned that the entity access API grants view access.
102+
// (Storage level filtering is not available or way too limited.)
103+
$this->addTag($this->entityTypeId . '_access');
104+
105+
// Read meta-data from query, if provided.
106+
if (!$account = $this->getMetaData('account')) {
107+
$account = \Drupal::currentUser();
108+
}
109+
110+
$cacheability = CacheableMetadata::createFromRenderArray([]);
111+
$viewable_entity_ids = array_reduce($all_records, static function (array $carry, EntityInterface $entity) use ($cacheability, $account) {
112+
// Bubble up cacheability information even from a revoked access result.
113+
$result = $entity->access('view', $account, TRUE);
114+
$cacheability->addCacheableDependency($result);
115+
if ($result->isAllowed()) {
116+
$carry[] = $entity->id();
117+
}
118+
return $carry;
119+
}, []);
120+
121+
// We deliberately add conditions to the original entity query instead
122+
// of pre-filtering all records because query conditions are visible
123+
// in hook_query_TAG_alter() implementations for downstream developers.
124+
if (empty($viewable_entity_ids)) {
125+
// Add an always false condition. A persisted entity's primary id
126+
// cannot be null.
127+
$this->condition->notExists($this->entityType->getKey('id'));
128+
}
129+
else {
130+
$this->condition->condition($this->entityType->getKey('id'), $viewable_entity_ids, 'IN');
131+
}
132+
/** @var \Symfony\Component\HttpFoundation\Request $request */
133+
$request = \Drupal::requestStack()->getCurrentRequest();
134+
$renderer = \Drupal::service('renderer');
135+
if ($request->isMethodCacheable() && $renderer->hasRenderContext()) {
136+
$build = [];
137+
$cacheability->applyTo($build);
138+
$renderer->render($build);
139+
}
140+
}
141+
142+
$hooks = ['query'];
143+
foreach ($this->alterTags as $tag => $value) {
144+
$hooks[] = 'query_' . $tag;
145+
}
146+
\Drupal::moduleHandler()->alter($hooks, $this);
147+
148+
$filter = $this->condition->compile($this);
89149
$result = array_filter($all_records, $filter);
150+
90151
if ($this->count) {
91152
return count($result);
92153
}

0 commit comments

Comments
 (0)