Commit c5471f4a authored by Kristiaan Van den Eynde's avatar Kristiaan Van den Eynde
Browse files

Issue #3254311: Denormalize group_type and plugin_id for GroupContent entity and add indexes

parent 92cbed73
Loading
Loading
Loading
Loading
+61 −0
Changes for group.install: 61 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -5,9 +5,70 @@
 * Install, update and uninstall functions for the group module.
 */

use Drupal\Core\Field\BaseFieldDefinition;

/**
 * Implements hook_update_last_removed().
 */
function group_update_last_removed() {
  return 8023;
}

/**
 * Add plugin_id and group_type fields and update indexes for group content.
 */
function group_update_9201() {
  $manager = \Drupal::entityDefinitionUpdateManager();

  // Add the plugin_id and group_type field.
  $plugin_id = BaseFieldDefinition::create('string')
    ->setLabel(t('Plugin ID'))
    ->setRequired(TRUE)
    ->setReadOnly(TRUE)
    ->setInitialValue('TEMP');

  $group_type = BaseFieldDefinition::create('entity_reference')
    ->setLabel(t('Group type'))
    ->setSetting('target_type', 'group_type')
    ->setRequired(TRUE)
    ->setReadOnly(TRUE)
    ->setInitialValue('TEMP');

  $manager->installFieldStorageDefinition('plugin_id', 'group_content', 'group', $plugin_id);
  $manager->installFieldStorageDefinition('group_type', 'group_content', 'group', $group_type);

  // Regenerate entity type indexes.
  $manager->updateEntityType($manager->getEntityType('group_content'));

  // Map group content types to plugin IDs and group types.
  $config_factory = \Drupal::configFactory();

  $map = ['group_type' => [], 'plugin_id' => []];
  foreach ($config_factory->listAll('group.content_type.') as $config_name) {
    $group_content_type = $config_factory->get($config_name);

    $id = $group_content_type->get('id');
    $map['group_type'][$group_content_type->get('group_type')][] = $id;
    $map['plugin_id'][$group_content_type->get('content_plugin')][] = $id;
  }

  // Populate the actual values based on the group content types.
  $data_table = \Drupal::entityTypeManager()->getDefinition('group_content')->getDataTable();

  /** @var \Drupal\Core\Database\Connection $database */
  $database = \Drupal::getContainer()->get('database');

  foreach ($map['group_type'] as $group_type_id => $group_content_type_ids) {
    $database->update($data_table)
      ->fields(['group_type' => $group_type_id])
      ->condition('type', $group_content_type_ids, 'IN')
      ->execute();
  }

  foreach ($map['plugin_id'] as $plugin_id => $group_content_type_ids) {
    $database->update($data_table)
      ->fields(['plugin_id' => $plugin_id])
      ->condition('type', $group_content_type_ids, 'IN')
      ->execute();
  }
}
+1 −1
Changes for group.module: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -387,7 +387,7 @@ function group_entity_field_access($operation, FieldDefinitionInterface $field_d
  $group_content = $items->getEntity();

  // We only care if the group content entity is a group membership.
  if ($group_content->getRelationPlugin()->getRelationTypeId() != 'group_membership') {
  if ($group_content->getRelationPluginId() != 'group_membership') {
    return AccessResult::neutral();
  }

+1 −1
Changes for src/Entity/Access/GroupContentAccessControlHandler.php: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ class GroupContentAccessControlHandler extends EntityAccessControlHandler implem
   */
  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
    /** @var \Drupal\group\Entity\GroupContentInterface $entity */
    $access_control = $this->groupRelationTypeManager->getAccessControlHandler($entity->getRelationPlugin()->getRelationTypeId());
    $access_control = $this->groupRelationTypeManager->getAccessControlHandler($entity->getRelationPluginId());
    return $access_control->relationAccess($entity, $operation, $account, TRUE);
  }

+42 −3
Changes for src/Entity/GroupContent.php: 42 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -98,6 +98,20 @@ class GroupContent extends ContentEntityBase implements GroupContentInterface {
    return $this->get('gid')->target_id;
  }

  /**
   * {@inheritdoc}
   */
  public function getGroupType() {
    return $this->get('group_type')->entity;
  }

  /**
   * {@inheritdoc}
   */
  public function getGroupTypeId() {
    return $this->get('group_type')->target_id;
  }

  /**
   * {@inheritdoc}
   */
@@ -112,6 +126,13 @@ class GroupContent extends ContentEntityBase implements GroupContentInterface {
    return $this->getGroupContentType()->getRelationPlugin();
  }

  /**
   * {@inheritdoc}
   */
  public function getRelationPluginId() {
    return $this->get('plugin_id')->value;
  }

  /**
   * {@inheritdoc}
   */
@@ -145,7 +166,7 @@ class GroupContent extends ContentEntityBase implements GroupContentInterface {
    $uri_route_parameters['group'] = $this->getGroupId();
    // These routes depend on the plugin ID.
    if (in_array($rel, ['add-form', 'create-form'])) {
      $uri_route_parameters['plugin_id'] = $this->getRelationPlugin()->getRelationTypeId();
      $uri_route_parameters['plugin_id'] = $this->getRelationPluginId();
    }
    return $uri_route_parameters;
  }
@@ -172,6 +193,10 @@ class GroupContent extends ContentEntityBase implements GroupContentInterface {

    // Set the label so the DB also reflects it.
    $this->set('label', $this->label());

    // Set the denormalized data from the bundle entity.
    $this->set('plugin_id', $this->getGroupContentType()->getRelationPluginId());
    $this->set('group_type', $this->getGroupContentType()->getGroupTypeId());
  }

  /**
@@ -182,7 +207,7 @@ class GroupContent extends ContentEntityBase implements GroupContentInterface {

    // For memberships, we generally need to rebuild the group role cache for
    // the member's user account in the target group.
    $rebuild_group_role_cache = $this->getRelationPlugin()->getRelationTypeId() == 'group_membership';
    $rebuild_group_role_cache = $this->getRelationPluginId() == 'group_membership';

    if ($update === FALSE) {
      // We want to make sure that the entity we just added to the group behaves
@@ -230,7 +255,7 @@ class GroupContent extends ContentEntityBase implements GroupContentInterface {
        // If a membership gets deleted, we need to reset the internal group
        // roles cache for the member in that group, but only if the user still
        // exists. Otherwise, it doesn't matter as the user ID will become void.
        if ($group_content->getRelationPlugin()->getRelationTypeId() == 'group_membership') {
        if ($group_content->getRelationPluginId() == 'group_membership') {
          /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $role_storage */
          $role_storage = \Drupal::entityTypeManager()->getStorage('group_role');
          $role_storage->resetUserGroupRoleCache($group_content->getEntity(), $group_content->getGroup());
@@ -331,6 +356,20 @@ class GroupContent extends ContentEntityBase implements GroupContentInterface {
      ->setDescription(t('The time that the group content was last edited.'))
      ->setTranslatable(TRUE);

    // The following fields are denormalizations of info found on the bundle,
    // but often necessary to write performant joins. As we can't join config
    // entity tables, we explicitly store the info again on this entity type.
    $fields['plugin_id'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Plugin ID'))
      ->setRequired(TRUE)
      ->setReadOnly(TRUE);

    $fields['group_type'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Group type'))
      ->setSetting('target_type', 'group_type')
      ->setRequired(TRUE)
      ->setReadOnly(TRUE);

    if (\Drupal::moduleHandler()->moduleExists('path')) {
      $fields['path'] = BaseFieldDefinition::create('path')
        ->setLabel(t('URL alias'))
+24 −0
Changes for src/Entity/GroupContentInterface.php: 24 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -37,6 +37,22 @@ interface GroupContentInterface extends ContentEntityInterface, EntityOwnerInter
   */
  public function getGroupId();

  /**
   * Returns the group type the group content belongs to.
   *
   * @return \Drupal\group\Entity\GroupTypeInterface
   *   The group type the group content belongs to.
   */
  public function getGroupType();

  /**
   * Returns the group type ID the group content belongs to.
   *
   * @return string
   *   The group type ID the group content belongs to.
   */
  public function getGroupTypeId();

  /**
   * Returns the entity that was added as group content.
   *
@@ -53,6 +69,14 @@ interface GroupContentInterface extends ContentEntityInterface, EntityOwnerInter
   */
  public function getRelationPlugin();

  /**
   * Gets the group relation type ID the group content uses.
   *
   * @return string
   *   The group relation type ID the group content uses.
   */
  public function getRelationPluginId();

  /**
   * Loads group content entities by their responsible plugin ID.
   *
Loading