Commit a53a00ba authored by Nikolay Lobachev's avatar Nikolay Lobachev
Browse files

Issue #3304797 by LOBsTerr: Update module structure for Group 2.0

parent 69bc7133
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -17,9 +17,9 @@
  "license": "GPL-2.0-or-later",
  "minimum-stability": "dev",
  "require": {
    "drupal/group": "^1.0",
    "drupal/group": "^2.0",
    "drupal/state_machine": "^1.0",
    "drupal/core": "^8.8 || ^9 || ^10"
    "drupal/core": "^9 || ^10"
  },
  "repositories": [
    {
+162 −161
Original line number Diff line number Diff line
langcode: en
status: true
dependencies:
  enforced:
    module:
      - group
      - grequest
  module:
    - grequest
    - group
    - state_machine
    - user
  enforced:
    module:
      - group
      - grequest
id: group_pending_members
label: 'Group pending members'
module: views
description: ''
tag: ''
base_table: group_content_field_data
base_table: group_relationship_field_data
base_field: id
display:
  default:
    display_plugin: default
    id: default
    display_title: Master
    display_plugin: default
    position: 0
    display_options:
      access:
        type: group_permission
        options:
          group_permission: 'administer membership requests'
      cache:
        type: tag
        options: {  }
      query:
        type: views_query
        options:
          disable_sql_rewrite: false
          distinct: false
          replica: false
          query_comment: ''
          query_tags: {  }
      exposed_form:
        type: basic
        options:
          submit_button: Apply
          reset_button: false
          reset_button_label: Reset
          exposed_sorts_label: 'Sort by'
          expose_sort_order: true
          sort_asc_label: Asc
          sort_desc_label: Desc
      pager:
        type: mini
        options:
          items_per_page: 10
          offset: 0
          id: 0
          total_pages: null
          expose:
            items_per_page: false
            items_per_page_label: 'Items per page'
            items_per_page_options: '5, 10, 25, 50'
            items_per_page_options_all: false
            items_per_page_options_all_label: '- All -'
            offset: false
            offset_label: Offset
          tags:
            previous: ‹‹
            next: ››
      style:
        type: table
        options:
          grouping: {  }
          row_class: ''
          default_row_class: true
          override: true
          sticky: false
          caption: ''
          summary: ''
          description: ''
          columns:
            label: label
          info:
            label:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
          default: '-1'
          empty_table: false
      row:
        type: fields
      title: 'Group pending members'
      fields:
        approve_membership_request:
          id: approve_membership_request
          table: group_content
          table: group_relationship
          field: approve_membership_request
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: group_content
          plugin_id: approve_membership_request
          label: 'Approve membership'
          exclude: true
          alter:
@@ -143,15 +79,15 @@ display:
          text: 'Approve membership'
          output_url_as_text: false
          absolute: false
          entity_type: group_content
          plugin_id: approve_membership_request
        reject_membership_request:
          id: reject_membership_request
          table: group_content
          table: group_relationship
          field: reject_membership_request
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: group_content
          plugin_id: reject_membership_request
          label: 'Reject membership '
          exclude: true
          alter:
@@ -196,8 +132,6 @@ display:
          text: 'Reject membership'
          output_url_as_text: false
          absolute: false
          entity_type: group_content
          plugin_id: reject_membership_request
        name:
          id: name
          table: users_field_data
@@ -205,6 +139,9 @@ display:
          relationship: gc__user
          group_type: group
          admin_label: ''
          entity_type: user
          entity_field: name
          plugin_id: field
          label: Name
          exclude: false
          alter:
@@ -260,16 +197,16 @@ display:
          multi_type: separator
          separator: ', '
          field_api_classes: false
          entity_type: user
          entity_field: name
          plugin_id: field
        created:
          id: created
          table: group_content_field_data
          table: group_relationship_field_data
          field: created
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: group_content
          entity_field: created
          plugin_id: field
          label: 'Requested on'
          exclude: false
          alter:
@@ -327,16 +264,16 @@ display:
          multi_type: separator
          separator: ', '
          field_api_classes: false
          entity_type: group_content
          entity_field: created
          plugin_id: field
        gid:
          id: gid
          table: group_content_field_data
          table: group_relationship_field_data
          field: gid
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: group_content
          entity_field: gid
          plugin_id: field
          label: 'Parent group'
          exclude: true
          alter:
@@ -391,16 +328,16 @@ display:
          multi_type: separator
          separator: ', '
          field_api_classes: false
          entity_type: group_content
          entity_field: gid
          plugin_id: field
        id:
          id: id
          table: group_content_field_data
          table: group_relationship_field_data
          field: id
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: group_content
          entity_field: id
          plugin_id: field
          label: ID
          exclude: true
          alter:
@@ -457,9 +394,6 @@ display:
          multi_type: separator
          separator: ', '
          field_api_classes: false
          entity_type: group_content
          entity_field: id
          plugin_id: field
        dropbutton:
          id: dropbutton
          table: views
@@ -467,6 +401,7 @@ display:
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: dropbutton
          label: Operations
          exclude: false
          alter:
@@ -508,6 +443,7 @@ display:
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          destination: true
          fields:
            approve_membership_request: approve_membership_request
            reject_membership_request: reject_membership_request
@@ -515,8 +451,92 @@ display:
            created: '0'
            gid: '0'
            id: '0'
          destination: true
          plugin_id: dropbutton
      pager:
        type: mini
        options:
          offset: 0
          items_per_page: 10
          total_pages: null
          id: 0
          tags:
            next: ››
            previous: ‹‹
          expose:
            items_per_page: false
            items_per_page_label: 'Items per page'
            items_per_page_options: '5, 10, 25, 50'
            items_per_page_options_all: false
            items_per_page_options_all_label: '- All -'
            offset: false
            offset_label: Offset
      exposed_form:
        type: basic
        options:
          submit_button: Apply
          reset_button: false
          reset_button_label: Reset
          exposed_sorts_label: 'Sort by'
          expose_sort_order: true
          sort_asc_label: Asc
          sort_desc_label: Desc
      access:
        type: group_permission
        options:
          group_permission: 'administer membership requests'
      cache:
        type: tag
        options: {  }
      empty:
        area_text_custom:
          id: area_text_custom
          table: views
          field: area_text_custom
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: text_custom
          empty: true
          content: 'No membership requests available.'
          tokenize: false
      sorts: {  }
      arguments:
        gid:
          id: gid
          table: group_relationship_field_data
          field: gid
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: group_content
          entity_field: gid
          plugin_id: group_id
          default_action: 'access denied'
          exception:
            value: all
            title_enable: false
            title: All
          title_enable: true
          title: '{{ arguments.gid|placeholder }} pending members'
          default_argument_type: fixed
          default_argument_options:
            argument: '3'
          default_argument_skip_url: false
          summary_options:
            base_path: ''
            count: true
            override: false
            items_per_page: 25
          summary:
            sort_order: asc
            number_of_records: 0
            format: default_summary
          specify_validation: false
          validate:
            type: none
            fail: 'not found'
          validate_options: {  }
          break_phrase: false
          not: false
      filters:
        grequest_status_value:
          id: grequest_status_value
@@ -525,6 +545,7 @@ display:
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: state_machine_state
          operator: in
          value:
            pending: pending
@@ -557,75 +578,55 @@ display:
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
          plugin_id: state_machine_state
      sorts: {  }
      title: 'Group pending members'
      header: {  }
      footer: {  }
      empty:
        area_text_custom:
          id: area_text_custom
          table: views
          field: area_text_custom
          relationship: none
          group_type: group
          admin_label: ''
          empty: true
          tokenize: false
          content: 'No membership requests available.'
          plugin_id: text_custom
      style:
        type: table
        options:
          grouping: {  }
          row_class: ''
          default_row_class: true
          columns:
            label: label
          default: '-1'
          info:
            label:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
          override: true
          sticky: false
          summary: ''
          empty_table: false
          caption: ''
          description: ''
      row:
        type: fields
      query:
        type: views_query
        options:
          query_comment: ''
          disable_sql_rewrite: false
          distinct: false
          replica: false
          query_tags: {  }
      relationships:
        gc__user:
          id: gc__user
          table: group_content_field_data
          table: group_relationship_field_data
          field: gc__user
          relationship: none
          group_type: group
          admin_label: 'Group content User'
          entity_type: group_content
          plugin_id: group_content_to_entity
          required: true
          group_content_plugins:
            group_membership_request: group_membership_request
            group_membership: '0'
          entity_type: group_content
          plugin_id: group_content_to_entity
      arguments:
        gid:
          id: gid
          table: group_content_field_data
          field: gid
          relationship: none
          group_type: group
          admin_label: ''
          default_action: 'access denied'
          exception:
            value: all
            title_enable: false
            title: All
          title_enable: true
          title: '{{ arguments.gid|placeholder }} pending members'
          default_argument_type: fixed
          default_argument_options:
            argument: '3'
          default_argument_skip_url: false
          summary_options:
            base_path: ''
            count: true
            items_per_page: 25
            override: false
          summary:
            sort_order: asc
            number_of_records: 0
            format: default_summary
          specify_validation: false
          validate:
            type: none
            fail: 'not found'
          validate_options: {  }
          break_phrase: false
          not: false
          entity_type: group_content
          entity_field: gid
          plugin_id: group_id
      header: {  }
      footer: {  }
      display_extenders: {  }
    cache_metadata:
      max-age: -1
@@ -638,9 +639,9 @@ display:
        - user.group_permissions
      tags: {  }
  page_1:
    display_plugin: page
    id: page_1
    display_title: Page
    display_plugin: page
    position: 1
    display_options:
      display_extenders: {  }
@@ -649,11 +650,11 @@ display:
        type: tab
        title: 'Membership requests'
        description: ''
        weight: 21
        expanded: false
        menu_name: main
        parent: ''
        weight: 21
        context: '0'
        menu_name: main
    cache_metadata:
      max-age: -1
      contexts:
+3 −320
Original line number Diff line number Diff line
@@ -5,326 +5,9 @@
 * Install, update and uninstall functions for the grequest module.
 */

use Drupal\Core\Config\ExtensionInstallStorage;
use Drupal\Core\Config\InstallStorage;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\grequest\GroupMembershipRequestInstallHelper;
use Drupal\grequest\Plugin\GroupContentEnabler\GroupMembershipRequest;
use Drupal\group\Entity\GroupContentType;

/**
 * Make sure the views.view.group_pending_members is updated.
 */
function grequest_update_8001() {
  $message = NULL;

  $name = 'views.view.group_pending_members';
  $view = \Drupal::configFactory()->getEditable($name);

  // Only update or insert the view if the views module is enabled.
  if (\Drupal::moduleHandler()->moduleExists('views')) {
    // Get the storage for optional extension configuration.
    $optional_storage = new ExtensionInstallStorage(
      \Drupal::service('config.storage'),
      InstallStorage::CONFIG_OPTIONAL_DIRECTORY,
      InstallStorage::DEFAULT_COLLECTION,
      TRUE,
      NULL
    );
    $new_view = $optional_storage->read($name);
    $old_view = \Drupal::configFactory()->getEditable($name);

    // Update dependencies.
    $old_fields = $old_view->get('display.default.display_options.fields');
    $dependencies = $old_view->get('dependencies.module');
    $dependencies[] = 'grequest';
    $old_view->set('dependencies.module', $dependencies);

    // Remove old fields.
    if (!empty($old_fields['dropbutton'])) {
      foreach ($old_fields['dropbutton']['fields'] as $field_value) {
        if (!empty($field_value)) {
          unset($old_fields[$field_value]);
          unset($old_fields['dropbutton']['fields'][$field_value]);
        }
      }
    }

    // Set new fields.
    $operation_fields = [
      'approve_membership_request',
      'reject_membership_request',
    ];

    foreach ($operation_fields as $operation_field) {
      if (!empty($new_view['display']['default']['display_options']['fields'][$operation_field])) {
        $old_fields['dropbutton']['fields'][$operation_field] = $operation_field;
        $old_fields = array_merge([$operation_field => $new_view['display']['default']['display_options']['fields'][$operation_field]], $old_fields);
      }
    }

    $old_view->set('display.default.display_options.fields', $old_fields);
    $old_view->save(TRUE);
  }
  // Otherwise delete the view if it exists in the storage.
  elseif (!$view->isNew()) {
    $view->delete();
    $message = 'The view had been added even though the Views module is not installed. Removed the view.';
  }

  return $message;
}

/**
 * Install state machine.
 */
function grequest_update_8002() {
  if (!\Drupal::moduleHandler()->moduleExists('state_machine')) {
    \Drupal::service('module_installer')->install(['state_machine']);
    return t('The "State machine" module has been installed.');
  }
}

/**
 * Switch to state machine field.
 */
function grequest_update_8003() {
  drupal_flush_all_caches();

  $group_content_types = GroupContentType::loadByContentPluginId('group_membership_request');
  if (empty($group_content_types)) {
    return;
  }

  $table = 'group_content__grequest_status';
  $field_name = GroupMembershipRequest::STATUS_FIELD;
  $entity_type = 'group_content';

  // Backup data.
  $rows = [];
  $database = \Drupal::database();
  if ($database->schema()->tableExists($table)) {
    // The table data to restore after the update is completed.
    $rows = $database->select($table, 'n')
      ->fields('n')
      ->execute()
      ->fetchAll();
  }

  $field_storage = FieldStorageConfig::loadByName($entity_type, $field_name);
  if (empty($field_storage)) {
    return;
  }
  $field_storage->delete();

  // Maybe we need more items here.
  field_purge_batch(1000);

  // Get field storage from config.
  $install_storage = new ExtensionInstallStorage(
    \Drupal::service('config.storage'),
    InstallStorage::CONFIG_INSTALL_DIRECTORY
  );
  $field_storage_config = $install_storage->read("field.storage.$entity_type.$field_name");

  // Create new field storage.
  $new_field_storage = FieldStorageConfig::create($field_storage_config);
  $new_field_storage->save();

  foreach ($group_content_types as $group_content_type_id => $group_content_type) {
    FieldConfig::create([
      'field_storage' => FieldStorageConfig::loadByName($entity_type, $field_name),
      'bundle' => $group_content_type_id,
      'label' => t('Request status'),
      'required' => TRUE,
      'settings' => [
        'workflow' => 'request',
        'workflow_callback' => '',
      ],
    ])->save();
  }

  // Restore existing data in the same table.
  if (!empty($rows)) {
    $install_helper = \Drupal::classResolver(GroupMembershipRequestInstallHelper::class);
    foreach ($rows as $row) {
      $row->grequest_status_value = $install_helper->getStatus($row->grequest_status_value);
      $database->insert($table)
        ->fields((array) $row)
        ->execute();
    }
  }
}

/**
 * Make sure the views.view.group_pending_members is switched to state machine.
 * Implements hook_update_last_removed().
 */
function grequest_update_8004() {
  $message = NULL;

  $name = 'views.view.group_pending_members';
  $view = \Drupal::configFactory()->getEditable($name);

  // Only update or insert the view if the views module is enabled.
  if (\Drupal::moduleHandler()->moduleExists('views')) {
    // Get the storage for optional extension configuration.
    $optional_storage = new ExtensionInstallStorage(
      \Drupal::service('config.storage'),
      InstallStorage::CONFIG_OPTIONAL_DIRECTORY,
      InstallStorage::DEFAULT_COLLECTION,
      TRUE,
      NULL
    );

    $new_view = $optional_storage->read($name);
    $old_view = \Drupal::configFactory()->getEditable($name);

    // Update dependencies.
    $dependencies = $old_view->get('dependencies.module');
    $dependencies[] = 'state_machine';
    $old_view->set('dependencies.module', $dependencies);

    // Update filters.
    $old_view->set('display.default.display_options.filters', $new_view['display']['default']['display_options']['filters']);
    $old_view->save(TRUE);
  }
  // Otherwise delete the view if it exists in the storage.
  elseif (!$view->isNew()) {
    $view->delete();
    $message = 'The view had been added even though the Views module is not installed. Removed the view.';
  }

  return $message;
}

/**
 * Switch to 'administer membership requests'.
 */
function grequest_update_8005() {
  $group_type_roles = [];
  $administer_members_permission = 'administer members';
  $administer_membership_request_permission = 'administer membership requests';
  $entity_type_manager = \Drupal::entityTypeManager();
  $group_types = $entity_type_manager->getStorage('group_type')->loadMultiple();
  $install_helper = \Drupal::classResolver(GroupMembershipRequestInstallHelper::class);
  foreach ($group_types as $group_type) {
    $roles = $install_helper->getRoles($group_type);
    $group_type_roles[$group_type->id()] = $roles;
    /** @var \Drupal\group\Entity\GroupRole $role */
    foreach ($roles as $role) {
      if ($role->hasPermission($administer_membership_request_permission)) {
        continue;
      }
      if ($role->hasPermission($administer_members_permission)) {
        $role->grantPermission($administer_membership_request_permission);
        $role->save();
      }
    }
  }

  if (\Drupal::moduleHandler()->moduleExists('group_permissions')) {
    $group_permissions = $entity_type_manager->getStorage('group_permission')->loadMultiple();

    /** @var \Drupal\group_permissions\Entity\GroupPermission $group_permission */
    foreach ($group_permissions as $group_permission) {
      $group_type_id = $group_permission->getGroup()->getGroupType()->id();
      if (!empty($group_type_roles[$group_type_id])) {
        $roles = $group_type_roles[$group_type_id];
      }
      else {
        $roles = $install_helper->getRoles($group_type);
        $group_type_roles[$group_type_id] = $roles;
      }
      $custom_permissions = $group_permission->getPermissions();
      /** @var \Drupal\group\Entity\GroupRole $role */
      foreach ($roles as $role) {
        if (!empty($custom_permissions[$role->id()]) && in_array($administer_members_permission, $custom_permissions[$role->id()])) {
          $custom_permissions[$role->id()][] = $administer_membership_request_permission;
        }
      }

      $violations = $group_permission->validate();
      if (count($violations) == 0) {
        $group_permission->save();
      }
    }
  }
}

/**
 * Make sure the views.view.group_pending_members has right permission.
 */
function grequest_update_8006() {
  $message = NULL;

  $name = 'views.view.group_pending_members';
  $view = \Drupal::configFactory()->getEditable($name);

  // Only update or insert the view if the views module is enabled.
  if (\Drupal::moduleHandler()->moduleExists('views')) {
    // Get the storage for optional extension configuration.
    $optional_storage = new ExtensionInstallStorage(
      \Drupal::service('config.storage'),
      InstallStorage::CONFIG_OPTIONAL_DIRECTORY,
      InstallStorage::DEFAULT_COLLECTION,
      TRUE,
      NULL
    );

    $new_view = $optional_storage->read($name);
    $old_view = \Drupal::configFactory()->getEditable($name);

    // Update permissions.
    $old_view->set('display.default.display_options.access.options.group_permission', $new_view['display']['default']['display_options']['access']['options']['group_permission']);
    $old_view->save(TRUE);
  }
  // Otherwise delete the view if it exists in the storage.
  elseif (!$view->isNew()) {
    $view->delete();
    $message = 'The view had been added even though the Views module is not installed. Removed the view.';
  }

  return $message;
}

/**
 * Clean roles with 0 target_id.
 */
function grequest_update_8007() {
  \Drupal::database()->delete('group_content__group_roles')
    ->condition('group_roles_target_id', '0')
    ->execute();
}

/**
 * Make field storages persistable.
 */
function grequest_update_8008() {
  $fields = [
    'grequest_status',
    'grequest_updated_by'
  ];
  foreach ($fields as $field) {
    $storage_config_name = "field.storage.group_content.{$field}";
    $storage_config = \Drupal::configFactory()->getEditable($storage_config_name);
    $storage_config->set('persist_with_no_fields', TRUE);
    $storage_config->save();
  }
}

/**
 * Re-do grequest_update_8008() using the config entity API.
 */
function grequest_update_8009() {
  $storage = \Drupal::entityTypeManager()->getStorage('field_storage_config');
  $fields = [
    'grequest_status',
    'grequest_updated_by'
  ];
  foreach ($fields as $field) {
    $field_storage = $storage->load('group_content.' .  $field);
    $field_storage->set('persist_with_no_fields', TRUE);
    $field_storage->save();
  }
function grequest_update_last_removed() {
  return 8700;
}
+5 −5

File changed.

Preview size limit exceeded, changes collapsed.

+21 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading