Commit add84037 authored by Marcin Grabias's avatar Marcin Grabias
Browse files

Issue #3299780: Add option to add group membership when user registers on its domain

parent d5c3dfee
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -5,3 +5,25 @@ group_domain.settings:
    main_domain:
      label: Main domain
      type: string

group_domain.*:
  type: config_entity
  label: Group type domain settings
  mapping:
    id:
      type: string
      label: Group type ID
    status:
      type: boolean
      label: 'Is group domain mapping enabled for this group type?'
    outbound_behavior:
      type: string
      label: 'Outbound links behavior'
    add_membership_on_registration:
      type: boolean
      label: 'Should membership be added when user is registered on a group domain?'
    registration_membership_roles:
      type: sequence
      label: 'Domain group roles to assign on registration'
      sequence:
        type: string
+29 −1
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ declare(strict_types=1);
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\group\Entity\GroupInterface;
use Drupal\group_domain\GroupDomainInfo;
use Drupal\user\UserInterface;

/**
 * Implements hook_ENTITY_TYPE_presave().
@@ -29,8 +30,35 @@ function group_domain_group_presave(GroupInterface $group): void {
    }
  }

  // If still here, we need to clear the domain info cache.
  // If still here, we need to clear the domain info cache
  // and invalidate the render cache.
  \Drupal::cache('data')->delete(GroupDomainInfo::DOMAIN_FIELD_NAME);
  \Drupal::cache('render')->invalidateAll();
}

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function group_domain_user_insert(UserInterface $user): void {
  // Add newly registered users to domain group if applicable.
  $group_domain_info = \Drupal::service('group_domain.info');

  $domain_group = $group_domain_info->getCurrentDomainGroup();
  if ($domain_group === NULL) {
    return;
  }
  $config_entity = $group_domain_info->getConfigEntityForCurrentDomain($domain_group->bundle());
  if (
    $config_entity === NULL ||
    $config_entity->get('status') === FALSE ||
    $config_entity->get('add_membership_on_registration') !== TRUE
  ) {
    return;
  }

  $domain_group->addMember($user, [
    'group_roles' => $config_entity->get('registration_membership_roles'),
  ]);
}

/**
+100 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\group_domain\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\group\Entity\GroupRoleInterface;
use Drupal\group_domain\GroupDomainInfo;

/**
 * Defines the group_domain_settings config entity type.
 *
 * @ConfigEntityType(
 *   id = "group_domain_settings",
 *   label = @Translation("Group domain settings"),
 *   config_prefix = "group_domain",
 *   admin_permission = "administer group",
 *   entity_keys = {
 *     "id" = "id",
 *     "uuid" = "uuid",
 *   },
 *   config_export = {
 *     "id",
 *     "status",
 *     "outbound_behavior",
 *     "add_membership_on_registration",
 *     "registration_membership_roles",
 *   },
 * )
 */
final class GroupDomainSettings extends ConfigEntityBase {

  /**
   * The group type ID.
   */
  protected ?string $id;

  /**
   * Behavior of outbound links to other group domains.
   */
  protected string $outbound_behavior = GroupDomainInfo::IGNORE_MAIN_DOMAIN_OUTBOUND;

  /**
   * Should membership be added when user is registered on a group domain?
   */
  protected bool $add_membership_on_registration = FALSE;

  /**
   * Group membership roles to assign upon registration.
   *
   * @var string[]
   */
  protected array $registration_membership_roles = [];

  /**
   * {@inheritdoc}
   */
  public function calculateDependencies(): self {
    parent::calculateDependencies();

    $group_type = $this->entityTypeManager()
      ->getStorage('group_type')
      ->load($this->id);
    $this->addDependency('config', $group_type->getConfigDependencyName());

    foreach ($this->registration_membership_roles as $role_id) {
      $group_role = $this->entityTypeManager()
        ->getStorage('group_role')
        ->load($role_id);
      if ($group_role instanceof GroupRoleInterface) {
        $this->addDependency('config', $group_role->getConfigDependencyName());
      }
    }

    return $this;
  }

  /**
   * Check if settings are empty.
   */
  public function empty(): bool {
    if ($this->status) {
      return FALSE;
    }

    $empty = TRUE;

    if (
      $this->outbound_behavior !== GroupDomainInfo::IGNORE_MAIN_DOMAIN_OUTBOUND ||
      $this->add_membership_on_registration !== FALSE ||
      \count($this->registration_membership_roles) !== 0
    ) {
      $empty = FALSE;
    }

    return $empty;
  }

}
+70 −27
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 */
final class GroupDomainSettingsForm extends ConfigFormBase {

  /**
   * The group domain info service.
   */
  private GroupDomainInfo $groupDomainInfo;

  /**
   * The entity type manager.
   */
@@ -34,16 +39,23 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
  private CacheBackendInterface $cacheRender;

  /**
   * Constructs a new GroupCloneSettingsForm object.
   * Per group type config.
   */
  private array $groupTypeConfig = [];

  /**
   * Constructs a new GroupDomainSettingsForm object.
   */
  public function __construct(
    ConfigFactoryInterface $config_factory,
    GroupDomainInfo $group_domain_info,
    EntityTypeManagerInterface $entity_type_manager,
    EntityFieldManagerInterface $entity_field_manager,
    CacheBackendInterface $cache_render
  ) {
    parent::__construct($config_factory);

    $this->groupDomainInfo = $group_domain_info;
    $this->entityTypeManager = $entity_type_manager;
    $this->entityFieldManager = $entity_field_manager;
    $this->cacheRender = $cache_render;
@@ -55,6 +67,7 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
  public static function create(ContainerInterface $container): self {
    return new static(
      $container->get('config.factory'),
      $container->get('group_domain.info'),
      $container->get('entity_type.manager'),
      $container->get('entity_field.manager'),
      $container->get('cache.render')
@@ -74,7 +87,7 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'group_clone_settings';
    return 'group_domain_settings';
  }

  /**
@@ -84,10 +97,6 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    $config = $this->config(GroupDomainInfo::CONFIG_NAME);
    $group_type_config = $config->get('group_types_behaviour');
    if (!\is_array($group_type_config)) {
      $group_type_config = [];
    }
    $group_types = $this->entityTypeManager->getStorage('group_type')->loadMultiple();

    $form['main_domain'] = [
@@ -97,28 +106,27 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
      '#default_value' => $config->get('main_domain'),
    ];

    $form['group_types_behaviour'] = [
    $form['group_type_config'] = [
      '#type' => 'container',
      '#tree' => TRUE,
    ];

    foreach ($group_types as $group_type) {
      $bundle = $group_type->id();
      $bundle_config = \array_key_exists($bundle, $group_type_config) ? $group_type_config[$bundle] : [];
      $bundle_config += [
        'status' => FALSE,
        'outbound_behaviour' => GroupDomainInfo::IGNORE_MAIN_DOMAIN_OUTBOUND,
      ];
      $bundle_config = $this->groupDomainInfo->getConfigEntity($bundle);
      $this->groupTypeConfig[$bundle] = $bundle_config;

      $form['group_types_behaviour'][$bundle] = [
      $form['group_type_config'][$bundle] = [
        '#type' => 'fieldset',
        '#title' => $group_type->label(),
      ];
      $form['group_types_behaviour'][$bundle]['status'] = [

      $form['group_type_config'][$bundle]['status'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Enable'),
        '#default_value' => $bundle_config['status'],
        '#default_value' => $bundle_config->get('status'),
      ];
      $form['group_types_behaviour'][$bundle]['outbound_behaviour'] = [
      $form['group_type_config'][$bundle]['outbound_behavior'] = [
        '#type' => 'radios',
        '#title' => $this->t('Outbound links behavior'),
        '#description' => $this->t('Controls behavior of links on the main domain. If set to "Convert", and a group has custom domain set, links to that group will leac to that custom domain (for example https://custom-group-domain.com/content/1), otherwise user will stay on the main domain (links like https://main-domain.com/group/1/content/1).'),
@@ -126,8 +134,27 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
          GroupDomainInfo::IGNORE_MAIN_DOMAIN_OUTBOUND => $this->t("Don't convert"),
          GroupDomainInfo::CONVERT_MAIN_DOMAIN_OUTBOUND => $this->t("Convert"),
        ],
        '#default_value' => $bundle_config['outbound_behaviour'],
        '#default_value' => $bundle_config->get('outbound_behavior'),
      ];
      $form['group_type_config'][$bundle]['add_membership_on_registration'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Add group membership on domain registration'),
        '#default_value' => $bundle_config->get('add_membership_on_registration'),
      ];
      $form['group_type_config'][$bundle]['registration_membership_roles'] = [
        '#title' => $this->t('Membership roles to add'),
        '#type' => 'checkboxes',
        '#options' => [],
        '#default_value' => $bundle_config->get('registration_membership_roles') ?? [],
        '#states' => [
          'visible' => [
            ':input[name="group_type_config[' . $bundle . '][add_membership_on_registration]"]' => ['checked' => TRUE],
          ],
        ],
      ];
      foreach ($group_type->getRoles(FALSE) as $role) {
        $form['group_type_config'][$bundle]['registration_membership_roles']['#options'][$role->id()] = $role->label();
      }
    }

    $form['actions'] = ['#type' => 'actions'];
@@ -152,19 +179,34 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    parent::submitForm($form, $form_state);

    $config = $this->config(GroupDomainInfo::CONFIG_NAME);
    // Save general config.
    $config = $this->config(GroupDomainInfo::CONFIG_NAME);
    $config->set('main_domain', $form_state->getValue('main_domain'));
    $config->save();

    // Save group type config.
    $new_types = [];
    foreach ($form_state->getValue('group_types_behaviour') as $bundle => $values) {
    foreach ($form_state->getValue('group_type_config') as $group_type => $values) {
      $values['registration_membership_roles'] = \array_filter(\array_values($values['registration_membership_roles']));

      if ($values['status'] === 1) {
        $new_types[$bundle] = $bundle;
      }
        $new_types[$group_type] = $group_type;
      }

    // Save config.
    $config = $this->config(GroupDomainInfo::CONFIG_NAME);
    $config->set('main_domain', $form_state->getValue('main_domain'));
    $config->set('group_types_behaviour', $form_state->getValue('group_types_behaviour'));
    $config->save();
      $config_entity = $this->groupTypeConfig[$group_type];
      foreach ($values as $key => $value) {
        $config_entity->set($key, $value);
      }
      if (!$config_entity->empty()) {
        $config_entity->save();
      }
      elseif (!$config_entity->isNew()) {
        $config_entity->delete();
      }
    }

    $old_types = [];
    $group_types = $this->entityTypeManager->getStorage('group_type')->loadMultiple();
@@ -176,8 +218,6 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
      }
    }

    $this->cacheRender->invalidateAll();

    if ($new_types === $old_types) {
      return;
    }
@@ -247,6 +287,9 @@ final class GroupDomainSettingsForm extends ConfigFormBase {
        }
      }
    }

    // Finally clear render cache.
    $this->cacheRender->invalidateAll();
  }

}
+28 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ use Drupal\Core\Entity\Query\QueryException;
use Drupal\Core\Http\RequestStack;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\group\Entity\GroupInterface;
use Drupal\group_domain\Entity\GroupDomainSettings;
use Symfony\Component\HttpFoundation\Request;

/**
@@ -40,6 +41,33 @@ final class GroupDomainInfo extends CacheCollector {
    $this->requestStack = $request_stack;
  }

  /**
   * Get group type config.
   */
  public function getConfigEntity(string $group_type_id): GroupDomainSettings {
    $group_domain_settings_storage = $this->entityTypeManager->getStorage('group_domain_settings');
    $config_entity = $group_domain_settings_storage->load($group_type_id);
    if (!$config_entity instanceof GroupDomainSettings) {
      $config_entity = $group_domain_settings_storage->create([
        'id' => $group_type_id,
        'status' => FALSE,
      ]);
    }
    return $config_entity;
  }

  /**
   * Get current domain group config entity.
   */
  public function getConfigEntityForCurrentDomain(): ?GroupDomainSettings {
    $group = $this->getCurrentDomainGroup();
    if ($group === NULL) {
      return NULL;
    }

    return $this->getConfigEntity($group->bundle());
  }

  /**
   * Public base path by domain getter.
   */
Loading