
| Current Path : /var/www/html/c12park/web/modules/contrib/webform/modules/webform_access/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/html/c12park/web/modules/contrib/webform/modules/webform_access/webform_access.module |
<?php
/**
* @file
* Provides webform access controls for webform nodes.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\webform\Utility\WebformElementHelper;
use Drupal\webform\WebformInterface;
use Drupal\webform\WebformSubmissionInterface;
use Drupal\webform_access\Entity\WebformAccessGroup;
/**
* Implements hook_webform_help_info().
*/
function webform_access_webform_help_info() {
$help = [];
// Access group.
$help['webform_access_group'] = [
'group' => 'access',
'title' => t('Webform Access: Group'),
'content' => t('The <strong>Access group</strong> page lists reusable groups used to access webform source entity and users.'),
'video_id' => 'access',
'routes' => [
// @see /admin/structure/webform/access/group/manage
'entity.webform_access_group.collection',
],
];
// Access type.
$help['webform_access_type'] = [
'type' => 'access',
'title' => t('Webform Access: Type'),
'content' => t('The <strong>Access type</strong> page lists types of groups used to send email notifications to users.'),
'video_id' => 'access',
'routes' => [
// @see /admin/structure/webform/access/type/manage
'entity.webform_access_type.collection',
],
];
return $help;
}
/* ************************************************************************** */
// Delete relationship hooks.
/* ************************************************************************** */
/**
* Implements hook_user_delete().
*/
function webform_access_user_delete(EntityInterface $entity) {
\Drupal::database()->delete('webform_access_group_user')
->condition('uid', $entity->id())
->execute();
}
/**
* Implements hook_node_delete().
*/
function webform_access_node_delete(EntityInterface $entity) {
\Drupal::database()->delete('webform_access_group_entity')
->condition('entity_type', 'node')
->condition('entity_id', $entity->id())
->execute();
}
/**
* Implements hook_field_config_delete().
*/
function webform_access_field_config_delete(EntityInterface $entity) {
/** @var \Drupal\field\Entity\FieldConfig $definition */
if ($entity->getType() === 'webform' && $entity->getEntityTypeId() === 'node') {
$entity_ids = \Drupal::entityQuery('webform_access_group')
->condition('type', $entity->getTargetBundle())
->execute();
if ($entity_ids) {
\Drupal::database()->delete('webform_access_group_entity')
->condition('entity_type', 'node')
->condition('entity_id', $entity_ids, 'IN')
->condition('field_name', $entity->getName())
->execute();
}
}
}
/**
* Implements hook_field_storage_config_delete().
*/
function webform_access_field_storage_config_delete(EntityInterface $entity) {
/** @var \Drupal\field\Entity\FieldStorageConfig $entity */
if ($entity->getType() === 'webform') {
\Drupal::database()->delete('webform_access_group_entity')
->condition('entity_type', $entity->getEntityTypeId())
->condition('field_name', $entity->getName())
->execute();
}
}
/* ************************************************************************** */
// Access checking.
/* ************************************************************************** */
/**
* Implements hook_menu_local_tasks_alter().
*
* Add webform access group to local task cacheability.
*
* @see \Drupal\Core\Menu\Plugin\Block\LocalTasksBlock::build
*/
function webform_access_menu_local_tasks_alter(&$data, $route_name) {
// Change config entities 'Translate *' tab to be just label 'Translate'.
$webform_entities = [
'webform_access_group',
'webform_access_type',
];
foreach ($webform_entities as $webform_entity) {
if (isset($data['tabs'][0]["config_translation.local_tasks:entity.$webform_entity.config_translation_overview"]['#link']['title'])) {
$data['tabs'][0]["config_translation.local_tasks:entity.$webform_entity.config_translation_overview"]['#link']['title'] = t('Translate');
}
}
$route_name = \Drupal::routeMatch()->getRouteName();
if ($route_name !== 'entity.node.canonical' && strpos($route_name, 'entity.node.webform.') !== 0) {
return;
}
/** @var \Drupal\webform\WebformRequestInterface $request_handler */
$request_handler = \Drupal::service('webform.request');
$account = \Drupal::currentUser();
$webform = $request_handler->getCurrentWebform();
$source_entity = $request_handler->getCurrentSourceEntity();
if (!$webform || $source_entity) {
return;
}
/** @var \Drupal\webform_access\WebformAccessGroupStorageInterface $webform_access_group */
$webform_access_group_storage = \Drupal::entityTypeManager()->getStorage('webform_access_group');
$webform_access_groups = $webform_access_group_storage->loadByEntities($webform, $source_entity, $account);
if (empty($webform_access_groups)) {
return;
}
/** @var \Drupal\Core\Cache\CacheableMetadata $cacheability */
$cacheability = $data['cacheability'];
foreach ($webform_access_groups as $webform_access_group) {
$cacheability->addCacheableDependency($webform_access_group);
}
}
/**
* Implements hook_ENTITY_TYPE_access() for webform entities.
*/
function webform_access_webform_access(WebformInterface $webform, $operation, AccountInterface $account) {
// Prevent recursion when a webform is being passed as the source entity
// via the URL.
// @see \Drupal\webform\Plugin\WebformSourceEntity\QueryStringWebformSourceEntity::getSourceEntity
if (\Drupal::request()->query->get('source_entity_type') === 'webform') {
return AccessResult::neutral();
}
/** @var \Drupal\webform\WebformRequestInterface $request_handler */
$request_handler = \Drupal::service('webform.request');
$source_entity = $request_handler->getCurrentSourceEntity(['webform_submission']);
if (!$source_entity) {
return AccessResult::neutral();
}
/** @var \Drupal\webform_access\WebformAccessGroupStorageInterface $webform_access_group */
$webform_access_group_storage = \Drupal::entityTypeManager()->getStorage('webform_access_group');
$webform_access_groups = $webform_access_group_storage->loadByEntities($webform, $source_entity, $account);
if (empty($webform_access_groups)) {
return AccessResult::neutral();
}
$permission = str_replace('submission_', '', $operation);
foreach ($webform_access_groups as $webform_access_group) {
$permissions = $webform_access_group->get('permissions');
if (
// Is admin.
in_array('administer', $permissions)
// Is operation any.
|| in_array($permission, $permissions)) {
return AccessResult::allowed()
->cachePerUser()
->addCacheableDependency($webform_access_group);
}
}
// No opinion.
return AccessResult::neutral();
}
/**
* Implements hook_ENTITY_TYPE_access() for webform_submission entities.
*/
function webform_access_webform_submission_access(WebformSubmissionInterface $webform_submission, $operation, AccountInterface $account) {
if (!in_array($operation, ['view', 'update', 'delete'])) {
return AccessResult::neutral();
}
$webform = $webform_submission->getWebform();
$source_entity = $webform_submission->getSourceEntity();
if (!$source_entity) {
return AccessResult::neutral();
}
/** @var \Drupal\webform_access\WebformAccessGroupStorageInterface $webform_access_group */
$webform_access_group_storage = \Drupal::entityTypeManager()->getStorage('webform_access_group');
$webform_access_groups = $webform_access_group_storage->loadByEntities($webform, $source_entity, $account);
if (empty($webform_access_groups)) {
return AccessResult::neutral();
}
foreach ($webform_access_groups as $webform_access_group) {
$permissions = $webform_access_group->get('permissions');
if (
// Is admin.
(in_array('administer', $permissions)) ||
// Is operation any.
(in_array($operation . '_any', $permissions)) ||
// Is operation own.
(in_array($operation . '_own', $permissions) && $webform_submission->getOwnerId() === $account->id())
) {
return AccessResult::allowed()
->cachePerUser()
->addCacheableDependency($webform_access_group);
}
}
// No opinion.
return AccessResult::neutral();
}
/**
* Implements hook_webform_submission_query_access_alter().
*/
function webform_access_webform_submission_query_access_alter(AlterableInterface $query, array $webform_submission_tables) {
$account = $query->getMetaData('account') ?: \Drupal::currentUser();
// Collect access group ids with 'view_any' or 'administer' permissions.
/** @var \Drupal\webform_access\WebformAccessGroupStorageInterface $access_group_storage */
$access_group_storage = \Drupal::entityTypeManager()->getStorage('webform_access_group');
/** @var \Drupal\webform_access\WebformAccessGroupInterface $access_group */
$access_groups = $access_group_storage->loadByEntities(NULL, NULL, $account);
$access_any_group_ids = [];
$access_own_group_ids = [];
foreach ($access_groups as $access_group) {
$access_group_permissions = $access_group->get('permissions');
$access_group_permissions = array_combine($access_group_permissions, $access_group_permissions);
if (isset($access_group_permissions['view_any']) || isset($access_group_permissions['administer'])) {
$access_any_group_ids[] = $access_group->id();
}
elseif (isset($access_group_permissions['view_own'])) {
$access_own_group_ids[] = $access_group->id();
}
}
if ($access_any_group_ids) {
// Add access group entity type, entity id, and webform id to the query.
$result = \Drupal::database()->select('webform_access_group_entity', 'ge')
->fields('ge', ['entity_type', 'entity_id', 'webform_id'])
->condition('group_id', $access_any_group_ids, 'IN')
->execute();
while ($record = $result->fetchAssoc()) {
foreach ($webform_submission_tables as $table) {
/** @var \Drupal\Core\Database\Query\SelectInterface $query */
$condition = $query->andConditionGroup();
$condition->condition($table['alias'] . '.entity_type', $record['entity_type']);
$condition->condition($table['alias'] . '.entity_id', (string) $record['entity_id']);
$condition->condition($table['alias'] . '.webform_id', $record['webform_id']);
$table['condition']->condition($condition);
}
}
}
if ($access_own_group_ids) {
// Add access group entity type, entity id, and webform id to the query.
$result = \Drupal::database()->select('webform_access_group_entity', 'ge')
->fields('ge', ['entity_type', 'entity_id', 'webform_id'])
->condition('group_id', $access_own_group_ids, 'IN')
->execute();
while ($record = $result->fetchAssoc()) {
foreach ($webform_submission_tables as $table) {
/** @var \Drupal\Core\Database\Query\SelectInterface $query */
$condition = $query->andConditionGroup();
$condition->condition($table['alias'] . '.uid', $account->id());
$condition->condition($table['alias'] . '.entity_type', $record['entity_type']);
$condition->condition($table['alias'] . '.entity_id', (string) $record['entity_id']);
$condition->condition($table['alias'] . '.webform_id', $record['webform_id']);
$table['condition']->condition($condition);
}
}
}
}
/* ************************************************************************** */
// Webform access groups (node) entity.
/* ************************************************************************** */
/**
* Implements hook_field_widget_single_element_form_alter().
*/
function webform_access_field_widget_single_element_form_alter(&$element, FormStateInterface $form_state, $context) {
/** @var \Drupal\Core\Field\FieldItemListInterface $items */
$items = $context['items'];
$field_definition = $items->getFieldDefinition();
if ($field_definition->getType() !== 'webform') {
return;
}
// Get the target entity.
$entity = $items->getEntity();
// Only nodes are currently supported.
if ($entity->getEntityTypeId() !== 'node') {
return;
}
$default_value = $entity->id() ? \Drupal::database()->select('webform_access_group_entity', 'ge')
->fields('ge', ['group_id'])
->condition('entity_type', $entity->getEntityTypeId())
->condition('entity_id', $entity->id())
->condition('webform_id', $element['target_id']['#default_value'])
->condition('field_name', $field_definition->getName())
->execute()->fetchCol() : ($items->webform_access_group ?: []);
$element['settings']['webform_access_group'] = _webform_access_group_build_element(
$default_value,
[],
$form_state
);
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/
function webform_access_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
/** @var \Drupal\webform\WebformEntityReferenceManagerInterface $entity_reference_manager */
$entity_reference_manager = \Drupal::service('webform.entity_reference_manager');
$node = $form_state->getFormObject()->getEntity();
$field_names = $entity_reference_manager->getFieldNames($node);
if ($field_names) {
$form['actions']['submit']['#submit'][] = '_webform_access_form_node_form_submit';
}
}
/**
* Webform access group submit handler.
*/
function _webform_access_form_node_form_submit(&$form, FormStateInterface $form_state) {
/** @var \Drupal\webform\WebformEntityReferenceManagerInterface $entity_reference_manager */
$entity_reference_manager = \Drupal::service('webform.entity_reference_manager');
$node = $form_state->getFormObject()->getEntity();
$field_names = $entity_reference_manager->getFieldNames($node);
$record = [
'entity_type' => 'node',
'entity_id' => $node->id(),
];
foreach ($field_names as $field_name) {
$value = $form_state->getValue($field_name);
// Handle hidden webform fields.
if ($value === NULL) {
continue;
}
$record['field_name'] = $field_name;
// Delete all existing records.
\Drupal::database()->delete('webform_access_group_entity')
->condition('entity_type', $record['entity_type'])
->condition('entity_id', $record['entity_id'])
->condition('field_name', $record['field_name'])
->execute();
foreach ($value as $item) {
$record['webform_id'] = $item['target_id'];
foreach ($item['settings']['webform_access_group'] as $group_id) {
$record['group_id'] = $group_id;
// Insert new record.
\Drupal::database()->insert('webform_access_group_entity')
->fields(['group_id', 'entity_type', 'entity_id', 'field_name', 'webform_id'])
->values($record)
->execute();
// Invalidate cache tags.
WebformAccessGroup::load($group_id)->invalidateTags();
}
}
}
}
/* ************************************************************************** */
// Webform access group users.
/* ************************************************************************** */
/**
* Implements hook_form_FORM_ID_alter() for user form.
*
* Add the webform access group to an individual user's account page.
*/
function webform_access_form_user_form_alter(&$form, FormStateInterface $form_state) {
// Make sure some webform access groups exist before displaying
// the webform access details widget.
if (!WebformAccessGroup::loadMultiple()) {
return;
}
// Only display the webform access detail widget if the current user can
// administer webform and users.
if (!\Drupal::currentUser()->hasPermission('administer webform')
|| !\Drupal::currentUser()->hasPermission('administer users')) {
return;
}
$account = $form_state->getFormObject()->getEntity();
$default_value = \Drupal::database()->select('webform_access_group_user', 'gu')
->fields('gu', ['group_id'])
->condition('uid', $account->id())
->execute()->fetchCol();
$form['webform_access'] = [
'#type' => 'details',
'#title' => t('Webform access'),
'#open' => TRUE,
'#weight' => 5,
];
$form['webform_access']['webform_access_group'] = _webform_access_group_build_element(
$default_value,
$form,
$form_state
);
$form['actions']['submit']['#submit'][] = '_webform_access_user_profile_form_submit';
}
/**
* Submit callback for the user profile form to save the webform_access user setting.
*/
function _webform_access_user_profile_form_submit($form, FormStateInterface $form_state) {
$account = $form_state->getFormObject()->getEntity();
// Delete all existing records.
\Drupal::database()->delete('webform_access_group_user')
->condition('uid', $account->id())
->execute();
$record = ['uid' => $account->id()];
$value = $form_state->getValue('webform_access_group');
foreach ($value as $group_id) {
$record['group_id'] = $group_id;
// Insert new record.
\Drupal::database()->insert('webform_access_group_user')
->fields(['group_id', 'uid'])
->values($record)
->execute();
WebformAccessGroup::load($group_id)->invalidateTags();
}
// Invalidate 'webform_submission_list' cache tag when user is updated.
// @see _webform_clear_webform_submission_list_cache_tag()
Cache::invalidateTags(['webform_submission_list']);
}
/* ************************************************************************** */
// Webform access group helper functions.
/* ************************************************************************** */
/**
* Build element used to select webform access groups.
*
* @param array $default_value
* Array of default group ids.
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return array
* Element used to select webform access groups.
*/
function _webform_access_group_build_element(array $default_value, array $form, FormStateInterface $form_state) {
$element = [
'#type' => 'webform_entity_select',
'#title' => 'Access group',
'#target_type' => 'webform_access_group',
'#selection_handler' => 'default:webform_access_group',
'#multiple' => TRUE,
'#select2' => TRUE,
'#default_value' => $default_value,
'#access' => \Drupal::currentUser()->hasPermission('administer webform'),
];
return WebformElementHelper::process($element);
}