adva-8.x-1.0-rc9/adva.module

adva.module
<?php

/**
 * @file
 * Defines an extensive api for Entity Access Plugins.
 */

use Drupal\Core\Entity\EntityInterface;
use Drupal\adva\Plugin\adva\OverridingAccessConsumerInterface;
use Drupal\Core\Database\Query\AlterableInterface;

/**
 * Implements hook_entity_type_build().
 *
 * Alter the access handlers for any entity types with an Overriding Access
 * Consumer plugin.
 */
function adva_entity_type_build(array &$entity_types) {
  $consumerManager = \Drupal::service("plugin.manager.adva.consumer");
  $overridingConsumers = $consumerManager->getOverrideConsumers();

  foreach ($overridingConsumers as $consumer) {
    $entityTypeId = $consumer->getEntityTypeId();
    if (isset($entity_types[$entityTypeId])) {
      $consumer->overrideAccessControlHandler($entity_types[$entityTypeId]);
    }
  }
}

/**
 * Implements hook_entity_insert().
 *
 * When an entity is updated, update the access records.
 */
function adva_entity_insert(EntityInterface $entity) {
  $consumerManager = \Drupal::service('plugin.manager.adva.consumer');
  $consumer = $consumerManager->getConsumerForEntityTypeId($entity->getEntityTypeId());
  if ($consumer && $consumer instanceof OverridingAccessConsumerInterface) {
    \Drupal::service('adva.access_storage')->updateRecordsFor($consumer, $entity);
  }
}

/**
 * Implements hook_entity_update().
 *
 * When an entity is updated, update the access records.
 */
function adva_entity_update(EntityInterface $entity) {
  $consumerManager = \Drupal::service('plugin.manager.adva.consumer');
  $consumer = $consumerManager->getConsumerForEntityTypeId($entity->getEntityTypeId());
  if ($consumer && $consumer instanceof OverridingAccessConsumerInterface) {
    \Drupal::service('adva.access_storage')->updateRecordsFor($consumer, $entity);
  }
}

/**
 * Implements hook_entity_delete().
 *
 * When an entity is updated, update the access records.
 */
function adva_entity_delete(EntityInterface $entity) {
  $consumerManager = \Drupal::service('plugin.manager.adva.consumer');
  $consumer = $consumerManager->getConsumerForEntityTypeId($entity->getEntityTypeId());
  if ($consumer && $consumer instanceof OverridingAccessConsumerInterface) {
    \Drupal::service('adva.access_storage')->deleteRecordsFor($entity);
  }
}

/**
 * Implements hook_query_alter().
 *
 * This adds Advanced Access checks for the user account given by the 'account'
 * meta-data (or current user if not provided), for an operation given by the
 * 'op' meta-data (or 'view' if not provided; other possible values are 'update'
 * and 'delete').
 *
 * Queries with the ENTITY_TYPE_access tag that are not against an entity's base
 * table must add the entity's base table as metadata. For example:
 * @code
 *   $query
 *     ->addTag('ENTITY_TYPE_access')
 *     ->addMetaData('base_table', 'taxonomy_index');
 * @endcode
 */
function adva_query_alter(AlterableInterface $query) {
  $op = $query->getMetaData('op');
  if (!$op) {
    $op = 'view';
  }

  // Only the view, update and delete operations are supported.
  if (!in_array($op, ['view', 'update', 'delete'])) {
    return;
  }

  $should_alter_query = FALSE;
  $view = $query->getMetaData('view');
  if ($view && $base_entity_type = $view->getBaseEntityType()) {
    $entity_type_id = $base_entity_type->id();
    $consumer = \Drupal::service('plugin.manager.adva.consumer')->getConsumerForEntityTypeId($entity_type_id);
    if ($consumer instanceof OverridingAccessConsumerInterface) {
      $should_alter_query = TRUE;
    }
  }

  if (!$should_alter_query) {
    // Get all Advanced Access Consumers.
    $consumers = \Drupal::service('plugin.manager.adva.consumer')
      ->getOverrideConsumers();
    if (!count($consumers)) {
      return;
    }

    /** @var \Drupal\adva\Entity\AccessConsumerInterface $consumer */
    foreach ($consumers as $consumer) {
      $entity_type_id = $consumer->getEntityTypeId();
      if ($query->hasTag($entity_type_id . '_access')) {
        $should_alter_query = TRUE;
        break;
      }
    }
  }

  if (!$should_alter_query) {
    return;
  }

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

  // If $account can bypass Advanced Access, we don't need to alter the query.
  if ($account->hasPermission('bypass adva access') || $account->hasPermission("bypass adva $entity_type_id access")) {
    return;
  }

  $tables = $query->getTables();
  $base_table = $query->getMetaData('base_table');
  // If the base table is not given, default to the entity's base table.
  if (!$base_table) {
    $entity_storage = \Drupal::entityTypeManager()->getStorage($entity_type_id);

    /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
    $table_mapping = $entity_storage->getTableMapping();
    $entity_base_tables = $table_mapping->getTableNames();

    foreach ($tables as $table_info) {
      if (!($table_info instanceof SelectInterface)) {
        $table = $table_info['table'];
        // Ensure that base and data tables are always preferred over the
        // revision tables.
        if ($table == $entity_storage->getBaseTable() || $table == $entity_storage->getDataTable()) {
          $base_table = $table;
          break;
        }
        // If one of the base tables is in the query, add it to the list of
        // possible base tables to join against.
        elseif (in_array($table, $entity_base_tables)) {
          $base_table = $table;
        }
      }
    }
  }

  // Bail out if the base table is missing.
  if (!$base_table) {
    throw new Exception(t("Query tagged for entity access but there is no base table, specify the base_table using meta data."));
  }

  // Update the query for the given storage method.
  \Drupal::service('adva.access_storage')->alterQuery($query, $tables, $op, $account, $base_table, $entity_type_id);
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc