forum_access-8.x-1.0-alpha2/includes/forum_access.admin.inc

includes/forum_access.admin.inc
<?php

/**
 * @file
 * Contains integrations with forms.
 */

use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\user\Entity\Role;

/**
 * Create moderators list of users.
 */
function _forum_access_forum_moderators_form($form_state, $tid) {
  // Find our moderator ACL. If tid exists it means that term isn't new
  // and is edited now.
  if (isset($tid)) {
    $acl_id = forum_access_get_acl($tid, 'moderate');
    $form = acl_edit_form($form_state, $acl_id, t('Moderators'));
  }
  else {
    $form = acl_edit_form($form_state, 0, t('Moderators'), TRUE);
  }
  $form['warning'] = [
    '#type' => 'item',
    '#markup' => t('Moderators receive all grants above.'),
  ];
  $form['note'] = [
    '#type' => 'item',
    '#markup' => t('Note: Changes to moderators are not saved until you click Save below.'),
  ];
  return $form;
}

/**
 * Save ACL configuration.
 *
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The state of the forum/forum container form.
 */
function _forum_access_form_moderators_save(FormStateInterface $form_state) {
  if ($data = $form_state->getValue(['forum_access', 'moderators'])) {
    if ($data['acl_id'] == 0) {
      $tid = $form_state->getValue(['tid']);
      \Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.acl');
      $data['acl_id'] = forum_access_get_acl($tid, "moderate");
    }
    acl_save_form($data, 0);
  }
}

/**
 * Save roles permissions.
 */
function _forum_access_form_roles_permissions_save(FormStateInterface $form_state) {
  $access = $form_state->getValue(['forum_access', 'grants', 'checkboxes']);
  $tid = $form_state->getValue('tid');
  // Remove and re-create records.
  forum_access_set_settings($tid, $access);
}

/**
 * Update access records.
 */
function _forum_access_update_access_records($form, $form_state) {
  $tid = $form_state->getValue('tid');
  $fa_values = $form_state->getValue('forum_access');
  $access = $fa_values['grants']['checkboxes'];
  $form = $form['forum_access'];

  if (empty($fa_values['force_update'])) {
    $is_changed = FALSE;
    foreach (array_keys($fa_values['grants']['checkboxes']) as $grant_type) {
      $defaults = $form['grants']['checkboxes'][$grant_type]['#default_value'];
      $defaults = array_flip($defaults);
      foreach ($access[$grant_type] as $rid => $checked) {
        $is_changed = $is_changed || (empty($form['grants']['checkboxes'][$grant_type][$rid]['#disabled']) && (!empty($checked) != isset($defaults[$rid])));
      }
    }
    if (!$is_changed && !acl_edit_form_get_user_list_changed($form['moderators']) && (empty($fa_values['interference']) || $fa_values['interference']['advanced']['priority'] == $form['interference']['advanced']['priority']['#default_value'])) {
      \Drupal::messenger()->addMessage(t('The content access permissions are unchanged.'));
      return;
    }
  }

  if (isset($fa_values['update_choice'])) {
    switch ($fa_values['update_choice']) {
      case 'this_tid_now':
        // This should update the nodes in this forum only, not yet implemented.
        break;

      case 'all_now':
        node_access_rebuild(TRUE);
        break;

      case 'batch':
        // Mass update in batch mode, modeled after node.module.
        $limit = $fa_values['update_limit'];
        $count = Drupal::database()
          ->select('node__taxonomy_forums')
          ->condition('taxonomy_forums_target_id', $tid)
          ->countQuery()
          ->distinct()
          ->execute()
          ->fetchField();
        $batch = [
          'title' => t('Updating content access permissions'),
          'file' => \Drupal::service('extension.list.module')->getPath('forum_access') . '/includes/forum_access.admin.inc',
          'operations' => [
            ['_forum_access_update_batch_operation', [$tid, $limit, $count]],
          ],
          'finished' => '_forum_access_update_batch_finished',
        ];
        batch_set($batch);
        break;

      case 'all_later':
        node_access_needs_rebuild(TRUE);
        break;
    }
  }
}

/**
 * Operations for batch.
 */
function _forum_access_update_batch_operation($tid, $limit, $count, &$context) {
  $node_storage = \Drupal::entityTypeManager()->getStorage('node');
  if (empty($context['sandbox'])) {
    // Initiate multistep processing.
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['current_node'] = 0;
    $context['sandbox']['max'] = $count;
  }
  $nids = \Drupal::entityQuery('node')
    ->condition('nid', $context['sandbox']['current_node'], '>')
    ->sort('nid', 'ASC')
    // Disable access checking since all nodes must be processed even if the
    // user does not have access. And unless the current user has the bypass
    // node access permission, no nodes are accessible since the grants have
    // just been deleted.
    ->accessCheck(FALSE)
    ->condition("taxonomy_forums.target_id", $tid, '=')
    ->execute();
  $node_storage->resetCache($nids);
  $nodes = Node::loadMultiple($nids);
  foreach ($nodes as $nid => $node) {
    // To preserve database integrity, only write grants if the node
    // loads successfully.
    if (!empty($node)) {
      /** @var \Drupal\node\NodeAccessControlHandlerInterface $access_control_handler */
      $access_control_handler = \Drupal::entityTypeManager()
        ->getAccessControlHandler('node');
      $grants = $access_control_handler->acquireGrants($node);
      \Drupal::service('node.grant_storage')->write($node, $grants);
    }
    $context['sandbox']['progress']++;
    $context['sandbox']['current_node'] = $nid;
  }
  // Multistep processing : report progress.
  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }
}

/**
 * Post-processing for forum_access_form_submit().
 */
function _forum_access_update_batch_finished($success, $results, $operations) {
  if ($success) {
    \Drupal::messenger()->addMessage(t('The content access permissions have been updated.'));
    node_access_needs_rebuild(FALSE);
  }
  else {
    \Drupal::messenger()->addError(t('The content access permissions have not been properly updated.'));
  }
}

/**
 * List of permissions.
 */
function _forum_access_forum_permissions_form() {
  $variables = [];
  $permissions = [
    'access content' => 'system',
    'access comments' => 'comment',
    'create forum content' => 'node',
    'post comments' => 'comment',
    'skip comment approval' => 'comment',
    'edit own forum content' => 'node',
    'edit any forum content' => 'node',
    'delete own forum content' => 'node',
    'delete any forum content' => 'node',
    'administer comments' => 'comment',
    'administer forums' => 'forum',
    'administer nodes' => 'node',
    'access content overview' => 'node',
    'view own unpublished content' => 'node',
    'edit own comments' => 'comment',
  ];
  foreach ($permissions as $perm => $module) {
    $key = '@' . str_replace(' ', '_', $perm);
    $variables[$key] = _forum_access_permission_link($module, $perm);
  }
  $form = [
    '#type' => 'details',
    '#title' => t('Permissions information'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  ];
  $form['list'] = [
    '#theme' => 'item_list',
    '#title' => t('Note that users need'),
    '#items' => [
      t('the <strong>@access_content</strong> and <strong>@access_comments</strong> permissions <strong>AND <em>View</em></strong> to be able to see this forum and its content at all,', $variables),
      t('the <strong>@create_forum_content</strong> (and similar) permissions <strong>AND <em>Post</em></strong> to be able to create forum content, and', $variables),
      t('the <strong>@post_comments</strong> (and optionally <strong>@skip_comment_approval</strong>) permission AND <em>Post</em> to be able to post comments/replies;', $variables),
      t('the <strong>@edit_own_forum_content</strong> or <strong>@edit_any_forum_content</strong> (and similar) permissions (<strong>OR <em>Edit</em></strong>) can be added if desired, <strong>plus</strong>', $variables),
      t('the <strong>@delete_own_forum_content</strong> or <strong>@delete_any_forum_content</strong> (and similar) permissions (<strong>OR <em>Delete</em></strong>) if desired;', $variables),
      t('the <strong>@administer_comments</strong> (global!) permission <strong>OR <em>Edit</em>/<em>Delete</em></strong> to be able to edit/delete comments;', $variables),
      t('the <strong>@administer_forums</strong> permission <strong>AND <em>View</em></strong> to be able to administer forums (and change access!).', $variables),
      t('Furthermore note that content which is not published is treated in a different way by Drupal: it can be viewed only by its author
        (with the <strong>@view_own_unpublished_content</strong> permission) or by users with the <strong>@administer_nodes</strong> permission. Unpublished comments and
        replies are accessible to users with <strong><em>Edit</em> OR <em>Delete</em></strong>, <strong>OR</strong> with the <strong>@administer_comments</strong> permission,
        but they are never counted on the forum page.', $variables),
      t('The global <strong>@edit_own_comments</strong> permission is ignored, but the edit/delete forum content permissions are extended to comments;
        the per-forum <strong><em>Edit</em></strong> and <strong><em>Delete</em></strong> apply to both nodes and comments, too.', $variables),
    ],
  ];
  return $form;
}

/**
 * Generate permissions link.
 */
function _forum_access_permission_link($module, $permission) {
  $permissions = &drupal_static(__FUNCTION__, []);
  if (empty($permissions)) {
    $permission_handler = \Drupal::service('user.permissions');
    $permissions_data = $permission_handler->getPermissions();
    foreach ($permissions_data as $perm => $perm_item) {
      $provider = $perm_item['provider'];
      $permissions[$provider][$perm] = strip_tags($perm_item['title']);
    }
  }
  return $permissions[$module][$permission];
}

/**
 * Get form table with roles grants.
 */
function _forum_access_forum_grants_form($form_state, $settings) {
  $roles = Role::loadMultiple();
  $administer_forums_permission = 'administer forums';
  $administer_forums_roles = array_filter($roles, function ($role) use ($administer_forums_permission) {
    return $role->hasPermission($administer_forums_permission);
  });
  $bypass_node_access_permission = 'bypass node access';
  $bypass_node_access_roles = array_filter($roles, function ($role) use ($bypass_node_access_permission) {
    return $role->hasPermission($bypass_node_access_permission);
  });
  $vid = \Drupal::config('forum.settings')->get('vocabulary');
  $cols = [
    'view' => t('View this forum'),
    'create' => t('Post in this forum'),
    'update' => t('Edit posts'),
    'delete' => t('Delete posts'),
  ];
  _forum_access_grants_form_elements($form, $roles, $administer_forums_roles, $bypass_node_access_roles, $cols, $settings);
  $form['info'] = [
    '#type' => 'item',
    '#description' => t('For explanations of <em class="placeholder">special cases</em>, hover your mouse over role names.'),
  ];
  return $form;
}

/**
 * Get roles permissions form for container.
 */
function _forum_access_container_grants_form($form_state, $settings) {
  $roles = Role::loadMultiple();
  $administer_forums_permission = 'administer forums';
  $administer_forums_roles = array_filter($roles, function ($role) use ($administer_forums_permission) {
    return $role->hasPermission($administer_forums_permission);
  });
  $bypass_node_access_permission = 'bypass node access';
  $bypass_node_access_roles = array_filter($roles, function ($role) use ($bypass_node_access_permission) {
    return $role->hasPermission($bypass_node_access_permission);
  });
  $vid = \Drupal::config('forum.settings')->get('vocabulary');
  $vocabulary = Vocabulary::load($vid);
  $cols = [
    'view' => t('View this container'),
    'create' => t('See this container in the forums selection list'),
  ];
  _forum_access_grants_form_elements($form, $roles, $administer_forums_roles, $bypass_node_access_roles, $cols, $settings);
  $form['info'] = [
    '#type' => 'item',
    '#description' => t('Users who can see any forum or container within this one should get the <strong><em>View</em></strong> grant. <br />
      Users who can post to a forum within this container should get the <strong><em>See</em></strong> grant, so that the forum appears in the proper context in the %Forums selection list.',
      ['%Forums' => $vocabulary->label()]),
  ];
  return $form;
}

/**
 * Common grants form elements for forum and container.
 */
function _forum_access_grants_form_elements(&$form, $roles, $administer_forums_roles, $bypass_node_access_roles, $cols, $settings) {
  $form = [
    '#theme' => 'forum_access_table',
    'rows' => [],
  ];
  // Build table rows.
  foreach ($roles as $rid => $role) {
    $form['rows'][$rid]['label'] = [
      '#type' => 'item',
      '#markup' => Html::escape($role->label()),
    ];
    $special = NULL;
    if (isset($administer_forums_roles[$rid])) {
      $special = t("This role has the '@administer_forums' permission, and granting 'View' enables the role holders to change the settings on this page, including Access Control!",
        [
          '@administer_forums' => t('administer forums'),
        ]);
      if (isset($bypass_node_access_roles[$rid])) {
        $special .= ' ' . t("Because the role also has the '@bypass_node_access' permission, it has full access to all nodes either way.",
            [
              '@bypass_node_access' => t('bypass node access'),
            ]);
      }
    }
    elseif (isset($bypass_node_access_roles[$rid])) {
      $special = t("This role has the '@bypass_node_access' permission and thus full access to all nodes.",
        [
          '@bypass_node_access' => t('bypass node access'),
        ]);
    }
    if (isset($special)) {
      $form['rows'][$rid] += [
        '#prefix' => '<em><span title="' . $special . '" class="forum-access-special-role">',
        '#suffix' => '</span></em>',
        '#disabled' => TRUE,
      ];
    }
    $roles[$rid] = '';
  }
  $form['header']['roles'] = [
    '#markup' => t('Roles'),
    '#tree' => TRUE,
  ];
  // Add checkboxes.
  foreach ($cols as $cid => $ctitle) {
    $form['checkboxes'][$cid] = [
      '#type' => 'checkboxes',
      '#options' => $roles,
      '#default_value' => $settings[$cid],
    ];
    $form['header'][$cid] = [
      '#markup' => $ctitle,
      '#tree' => TRUE,
    ];
  }
}

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

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