localgov_microsites_group-4.1.0/src/Access/MicrositeContentTypesAccessPolicy.php

src/Access/MicrositeContentTypesAccessPolicy.php
<?php

namespace Drupal\localgov_microsites_group\Access;

use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\flexible_permissions\CalculatedPermissionsItem;
use Drupal\flexible_permissions\ChainPermissionCalculatorInterface;
use Drupal\flexible_permissions\RefinableCalculatedPermissionsInterface;
use Drupal\group\Entity\GroupInterface;
use Drupal\group\PermissionScopeInterface;
use Drupal\group_sites\Access\GroupSitesSiteAccessPolicyInterface;
use Drupal\group_sites\GroupSitesAdminModeInterface;

/**
 * Access policy for content types in microsite groups.
 */
class MicrositeContentTypesAccessPolicy implements GroupSitesSiteAccessPolicyInterface {

  use StringTranslationTrait;

  /**
   * Constructs a SingleSiteAccessPolicy object.
   *
   * @param \Drupal\group_sites\GroupSitesAdminModeInterface $adminMode
   *   The admin mode service.
   * @param \Drupal\flexible_permissions\ChainPermissionCalculatorInterface $chainCalculator
   *   The chain permission calculator.
   * @param Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The ModuleHandlerInterface.
   */
  public function __construct(
    protected GroupSitesAdminModeInterface $adminMode,
    protected ChainPermissionCalculatorInterface $chainCalculator,
    protected ModuleHandlerInterface $moduleHandler,
  ) {}

  /**
   * {@inheritdoc}
   */
  public function getLabel(): string {
    return $this->t('LocalGov Microsite');
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription(): string {
    return $this->t('Single group permissions, with ability to disable specific module content types.');
  }

  /**
   * {@inheritdoc}
   */
  public function alterPermissions(GroupInterface $group, AccountInterface $account, string $scope, RefinableCalculatedPermissionsInterface $calculated_permissions): void {
    if ($scope === PermissionScopeInterface::INDIVIDUAL_ID) {
      // We only keep the item of the active group.
      $individual_item = $calculated_permissions->getItem($scope, $group->id());

      // The member check below varies based on membership of the group.
      $calculated_permissions->addCacheContexts(['user.is_group_member:' . $group->id()]);

      // Temporarily activate admin mode so we can calculate the actual insider
      // or outsider permissions and then flatten those into an individual item.
      $this->adminMode->setAdminModeOverride(TRUE);
      $bundle_permissions_scope = $group->getMember($account) ? PermissionScopeInterface::INSIDER_ID : PermissionScopeInterface::OUTSIDER_ID;
      $bundle_permissions = $this->chainCalculator->calculatePermissions($account, $bundle_permissions_scope);
      $this->adminMode->setAdminModeOverride(FALSE);

      if ($bundle_item = $bundle_permissions->getItem($bundle_permissions_scope, $group->bundle())) {
        if ($individual_item) {
          $permissions = array_merge($bundle_item->getPermissions(), $individual_item->getPermissions());
          $is_admin = $bundle_item->isAdmin() || $individual_item->isAdmin();
        }
        else {
          $permissions = $bundle_item->getPermissions();
          $is_admin = $bundle_item->isAdmin();
        }

        // All permissions granted by any modules.
        $all_module_permissions = $this->allModulePermissions();
        // Permissions the user has that are not granted by those modules.
        $non_module_permissions = array_diff($permissions, $all_module_permissions);
        // All permissions granted by modules, with disabled modules excluded.
        $enabled_module_permissions = $this->enabledModulePermissions($group);
        // All the permissions the user has that are granted by enabled modules.
        $include_module_permissions = array_intersect($permissions, $enabled_module_permissions);
        // Permissions granted by enabled modules, and permissions granted to
        // the user that are not covered by any of the modules.
        $permissions = array_merge($include_module_permissions, $non_module_permissions);

        $item = new CalculatedPermissionsItem(
          $scope,
          $group->id(),
          $permissions,
          $is_admin
        );
      }
      else {
        // If we're here we're being applied to the wrong group type.
        $item = $individual_item;
      }
    }

    // Remove all items, regardless of scope.
    $calculated_permissions->removeItemsByScope($scope);

    // Add back the individual item, along with merged synchronized item.
    if (!empty($item)) {
      $calculated_permissions->addItem($item);
    }
  }

  /**
   * Move below to the content type helper service?
   */
  private function allModulePermissions(): array {
    $default_permissions = $this->moduleHandler->invokeAll('localgov_microsites_roles_default');
    if (isset($default_permissions['group'])) {
      return array_merge(... array_values($default_permissions['group']));
    }
    return [];
  }

  /**
   * Enable permissions in the group.
   */
  private function enabledModulePermissions(GroupInterface $group): array {
    $disabled_modules = [];
    if ($group->hasField('lgms_modules_disabled')) {
      $disabled_modules = array_column($group->lgms_modules_disabled->getValue(), 'value');
    }
    $permissions = [];

    // Gather all permissions from modules that are not disabled.
    $this->moduleHandler->invokeAllWith('localgov_microsites_roles_default', function ($hook, $module) use ($disabled_modules, &$permissions) {
      if (!in_array($module, $disabled_modules, TRUE)) {
        $result = $hook();
        $permissions = array_merge_recursive($permissions, $result);
      }
    });
    if (isset($permissions['group'])) {
      return array_merge(... array_values($permissions['group']));
    }
    return [];
  }

}

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

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