Skip to content

Commit

Permalink
Finalize entity query support
Browse files Browse the repository at this point in the history
  • Loading branch information
mxr576 committed Feb 2, 2023
1 parent f828090 commit cb4b363
Showing 1 changed file with 39 additions and 8 deletions.
47 changes: 39 additions & 8 deletions src/Entity/Query/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,51 @@ public function execute() {
// result because this function gets called.
$all_records = $this->getFromStorage();

// @todo Proper entity query support that is aligned with the implementation
// in \Drupal\Core\Entity\Query\Sql\Query::prepare() can be only added
// if the following Entity API module issue is solved.
// Be consistent with \Drupal\Core\Entity\Query\Sql\Query::prepare().
// Add and fire special entity query tags.
// @todo This fix can be only merged after the fix in the following issue
// is available in a tagged release of entity.module.
// https://www.drupal.org/project/entity/issues/3332956
// The minimum required entity.module version also MUST be bumped as part
// of this fix.
// (Having a fix for a similar Group module issue is a nice to have,
// https://www.drupal.org/project/group/issues/3332963.)
$this->addTag('entity_query');
$this->addTag('entity_query_' . $this->entityTypeId);

if ($this->accessCheck) {
// We do not just add a tag but ensure that only those Apigee entities
// are returned that the entity access API grants view access.
// (Storage level filtering is not available or way too limited.)
$this->addTag($this->entityTypeId . '_access');

// Read meta-data from query, if provided.
if (!$account = $this->getMetaData('account')) {
// @todo DI dependency.
$account = \Drupal::currentUser();
}

$cacheability = CacheableMetadata::createFromRenderArray([]);
$all_records = array_filter($all_records, static function (EntityInterface $entity) use ($cacheability, $account) {
$viewable_entity_ids = array_reduce($all_records, static function (array $carry, EntityInterface $entity) use ($cacheability, $account) {
// Bubble up cacheability information even from a revoked access result.
$result = $entity->access('view', $account, TRUE);
$cacheability->addCacheableDependency($result);
return $result->isAllowed();
});
// @todo DI dependencies.
if ($result->isAllowed()) {
$carry[] = $entity->id();
}
return $carry;
}, []);

// We deliberately add conditions to the original entity query instead
// of pre-filtering all records because query conditions are visible
// in hook_query_TAG_alter() implementations for downstream developers.
if (empty($viewable_entity_ids)) {
// Add an always false condition. A persisted entity's primary id
// cannot be null.
$this->condition->notExists($this->entityType->getKey('id'));
}
else {
$this->condition->condition($this->entityType->getKey('id'), $viewable_entity_ids, 'IN');
}
/** @var \Symfony\Component\HttpFoundation\Request $request */
$request = \Drupal::requestStack()->getCurrentRequest();
$renderer = \Drupal::service('renderer');
Expand All @@ -116,6 +141,12 @@ public function execute() {
}
}

$hooks = ['query'];
foreach ($this->alterTags as $tag => $value) {
$hooks[] = 'query_' . $tag;
}
\Drupal::moduleHandler()->alter($hooks, $this);

$filter = $this->condition->compile($this);
$result = array_filter($all_records, $filter);

Expand Down

0 comments on commit cb4b363

Please sign in to comment.