1<?php
2
3/**
4 * @file
5 * Module to test entity query access in Views.
6 */
7
8use Drupal\Core\Database\Query\AlterableInterface;
9use Drupal\Core\Database\Query\SelectInterface;
10use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
11use Drupal\Core\Entity\Sql\DefaultTableMapping;
12
13/**
14 * Implements hook_query_TAG_alter() for the 'media_access' query tag.
15 */
16function views_test_query_access_query_media_access_alter(AlterableInterface $query) {
17  _views_test_query_access_restrict_by_uuid($query);
18}
19
20/**
21 * Implements hook_query_TAG_alter() for the 'block_content_access' query tag.
22 */
23function views_test_query_access_query_block_content_access_alter(AlterableInterface $query) {
24  _views_test_query_access_restrict_by_uuid($query);
25}
26
27/**
28 * Excludes entities with the 'hidden-ENTITY_TYPE_ID' UUID from a query.
29 *
30 * @param \Drupal\Core\Database\Query\AlterableInterface $query
31 *   The Views select query to alter.
32 */
33function _views_test_query_access_restrict_by_uuid(AlterableInterface $query) {
34  if (!($query instanceof SelectInterface)) {
35    return;
36  }
37
38  /** @var \Drupal\views\ViewExecutable $view */
39  $view = $query->getMetaData('view');
40  $entity_type = $view->getBaseEntityType();
41
42  $storage = \Drupal::entityTypeManager()->getStorage($entity_type->id());
43  if (!($storage instanceof SqlEntityStorageInterface)) {
44    return;
45  }
46
47  $table_mapping = $storage->getTableMapping();
48  if (!($table_mapping instanceof DefaultTableMapping)) {
49    return;
50  }
51
52  $base_table = $table_mapping->getBaseTable();
53  $data_table = $table_mapping->getDataTable();
54
55  // We are excluding entities by UUID, which means we need to be certain the
56  // base table is joined in the query.
57  $tables = $query->getTables();
58  if (isset($tables[$data_table]) && !isset($tables[$base_table])) {
59    $data_table_alias = $tables[$data_table]['alias'];
60    $id_key = $entity_type->getKey('id');
61    $base_table = $query->innerJoin($base_table, NULL, "$data_table_alias.$id_key = $base_table.$id_key");
62  }
63
64  // Figure out the column name of the UUID field and add a condition on that.
65  $base_field_definitions = \Drupal::service('entity_field.manager')
66    ->getBaseFieldDefinitions($entity_type->id());
67  $uuid_key = $entity_type->getKey('uuid');
68  $uuid_column_name = $table_mapping->getFieldColumnName($base_field_definitions[$uuid_key], NULL);
69  $query->condition("$base_table.$uuid_column_name", 'hidden-' . $entity_type->id(), '<>');
70}
71