Skip to content

Commit

Permalink
[WIP] Add proper entity query support
Browse files Browse the repository at this point in the history
  • Loading branch information
mxr576 committed Jan 12, 2023
1 parent c446600 commit 0697d17
Showing 1 changed file with 62 additions and 1 deletion.
63 changes: 62 additions & 1 deletion src/Entity/Query/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace Drupal\apigee_edge\Entity\Query;

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

// 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.
$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')) {
$account = \Drupal::currentUser();
}

$cacheability = CacheableMetadata::createFromRenderArray([]);
$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);
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');
if ($request->isMethodCacheable() && $renderer->hasRenderContext()) {
$build = [];
$cacheability->applyTo($build);
$renderer->render($build);
}
}

$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);

if ($this->count) {
return count($result);
}
Expand Down

0 comments on commit 0697d17

Please sign in to comment.